Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨Feat: CI/CD 관련 파일 추가 #10

Merged
merged 4 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# 🦁 Team Backend 🦁
🙋 모여톤 백엔드 레포지토리

⚠️ 푸쉬했다면 꼭 말해주기

## 🧑‍💻 멤버
|이름|[이예은](https://github.com/eunxeum)|[송성민](https://github.com/tjdals4716)|[박제영](https://github.com/Zero982)|
|:---:|:---:|:---:|:---:|
Expand All @@ -21,7 +23,7 @@

### 🚀 Deployment
<p align="center">
<img src="https://skillicons.dev/icons?i=aws"><img src="https://skillicons.dev/icons?i=jenkins"><img src="https://skillicons.dev/icons?i=firebase">
<img src="https://skillicons.dev/icons?i=aws"><img src="https://skillicons.dev/icons?i=jenkins"><img src="https://skillicons.dev/icons?i=flask">
</p>

### 🗣️ Communication
Expand All @@ -32,7 +34,4 @@
## 서버 플로우 동작
<p align="center">
<img src="image/모여톤 플로우.jpeg" alt="카카오 로그인">
</p>

## API 동작
- 추가 예정
</p>
26 changes: 26 additions & 0 deletions appspec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
version: 0.0 #CodeDeploy 버전을(무조건 0.0으로 고정)
os: linux
files:
- source: / #destination으로 이동시킬 파일. 여기서는 전체 파일을 의미.
destination: /home/ec2-user/app/zip/ #source에서 지정된 파일을 받는 위치
overwrite: yes #기존 파일들을 덮어쓸지 여부

permissions: #CodeDeploy에서 EC2 서버로 넘겨준 파일들을 모두 ec2-user 권한을 갖도록 함
- object: /
pattern: "**"
owner: ec2-user
group: ec2-user

hooks:
AfterInstall:
- location: stop.sh #엔진엑스와 연결되어 있지 않은 스프링 부트를 종료
timeout: 60
runas: ec2-user #stop.sh를 ec2-user 권한으로 실행
ApplicationStart:
- location: start.sh #엔진엑스와 연결되어 있지 않은 Port로 새 버전의 스프링 부트를 시작
timeout: 60
runas: ec2-user
ValidateService:
- location: health.sh #새 스프링 부트가 정상적으로 실행됐는지 확인
timeout: 60
runas: ec2-user
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,7 @@ dependencies {
tasks.named('test') {
useJUnitPlatform()
}

jar{
enabled = false
}
39 changes: 39 additions & 0 deletions scripts/health.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash

ABSPATH=$(readlink -f $0)
ABSDIR=$(dirname $ABSPATH)
source ${ABSDIR}/profile.sh
source ${ABSDIR}/switch.sh

IDLE_PORT=$(find_idle_port)

echo "> Health Check Start!"
echo "> IDLE_PORT: $IDLE_PORT"
echo "> curl -s http://127.0.0.1:$IDLE_PORT/profile"
sleep 10

for RETRY_COUNT in {1..10}
do
RESPONSE=$(curl -s http://127.0.0.1:${IDLE_PORT}/profile)
UP_COUNT=$(echo ${RESPONSE} | grep 'real' | wc -l)

if [ ${UP_COUNT} -ge 1 ] # Nginx와 연결되지 않은 포트로 스프링 부트가 잘 실행되었는지 체크
then # $up_count >= 1 ("real" 문자열이 있는지 검증)
echo "> Health Check 성공"
switch_proxy # 잘 실행되어 있다면 프록시 설정을 변경
break
else
echo "> Health Check의 응답을 알 수 없거나 혹은 실행 상태가 아닙니다."
echo "> Health Check: ${RESPONSE}"
fi

if [ ${RETRY_COUNT} -eq 10 ]
then
echo "> Health check 실패. "
echo "> 엔진엑스에 연결하지 않고 배포를 종료합니다."
exit 1
fi

echo "> Health check 연결 실패. 재시도..."
sleep 10
done
36 changes: 36 additions & 0 deletions scripts/profile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash

# 쉬고 있는 profile 찾기
# real1이 사용 중이면 real2가 쉬고 있고 반대면 real1이 쉬고 있음

function find_idle_profile() {
RESPONSE_CODE=$(curl -s -o /dev/null -w "%{http_code}" https://newteamsgoody.shop/profile) # 현재 Nginx가 바라보고 있는 스프링 부트가 정상적으로 수행 중인지 확인하고 응답값으로 상태코드를 전달받음

if [ ${RESPONSE_CODE} -ge 400 ] # 400번대 이상의 오류일 경우 real2를 사용
then
CURRENT_PROFILE=real2
else
CURRENT_PROFILE=$(curl -s https://newteamsgoody.shop/profile)
fi

if [ ${CURRENT_PROFILE} == real1 ]
then
IDLE_PROFILE=real2
else
IDLE_PROFILE=real1
fi

echo "${IDLE_PROFILE}" # bash 스크립트는 반환 기능이 없기 때문에 echo로 값을 출력하고 클라이언트에서 그 값을 잡아서 사용
}

# 쉬고 있는 profile의 port 찾기
function find_idle_port() {
IDLE_PROFILE=$(find_idle_profile)

if [ ${IDLE_PROFILE} == real1 ]
then
echo "8081"
else
echo "8082"
fi
}
32 changes: 32 additions & 0 deletions scripts/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash

ABSPATH=$(readlink -f $0)
ABSDIR=$(dirname $ABSPATH)
source ${ABSDIR}/profile.sh

REPOSITORY=/home/ec2-user/app

echo "> Build 파일을 복사합니다."

cp $REPOSITORY/zip/*.jar $REPOSITORY/

echo "> 새 애플리케이션 배포"
JAR_NAME=$(ls -tr $REPOSITORY/*.jar | tail -n 1)

echo "> JAR NAME: $JAR_NAME"

echo "> $JAR_NAME 에 실행 권한을 부여합니다."

chmod +x $JAR_NAME

IDLE_PROFILE=$(find_idle_profile)

echo "> 새 애플리케이션을 $IDLE_PROFILE 로 실행합니다."

# 설정 파일의 위치를 지정하고 active profile을 통해 구동될 포트를 지정
nohup java -jar \
-Dspring.config.location=$REPOSITORY/config/application.yml,\
$REPOSITORY/config/application-prod.yml,\
$REPOSITORY/config/application-$IDLE_PROFILE.yml \
-Dspring.profiles.active=$IDLE_PROFILE,prod \
$JAR_NAME > $REPOSITORY/nohup.out 2>&1 &
20 changes: 20 additions & 0 deletions scripts/stop.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash

ABSPATH=$(readlink -f $0) # 현재 stop.sh가 속해 있는 경로를 찾음

ABSDIR=$(dirname $ABSPATH)
source ${ABSDIR}/profile.sh # 일종의 import 구문으로 stop.sh에서도 profile.sh의 function을 사용할 수 있게 함

IDLE_PORT=$(find_idle_port)

echo "> $IDLE_PORT 에서 구동 중인 애플리케이션 pid 확인"
IDLE_PID=$(lsof -ti tcp:${IDLE_PORT})

if [ -z ${IDLE_PID} ]
then
echo "> 현재 구동 중인 애플리케이션이 없으므로 종료하지 않습니다."
else
echo "> kill -9 $IDLE_PID"
kill -9 ${IDLE_PID}
sleep 5
fi
16 changes: 16 additions & 0 deletions scripts/switch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash

ABSPATH=$(readlink -f $0)
ABSDIR=$(dirname $ABSPATH)
source $ABSDIR/profile.sh

function switch_proxy() {
IDLE_PORT=$(find_idle_port)

echo "> 전환할 port: $IDLE_PORT"
echo "> Port 전환"
echo "set \$service_url http://127.0.0.1:${IDLE_PORT};" | sudo tee /etc/nginx/conf.d/service-url.inc # 엔진엑스가 변경할 프록시 주소를 생성하여 service-url.inc로 덮어 씀

echo "> 엔진엑스 Reload"
sudo systemctl reload nginx
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

Expand All @@ -14,6 +15,9 @@
@Configuration
public class SwaggerConfig {

@Value("${swagger.server-url}")
private String serverUrl;

@Bean
public OpenAPI openAPI() {
String securitySchemeName = "로그인 후 발급받은 JWT 적용하기";
Expand All @@ -28,13 +32,13 @@ public OpenAPI openAPI() {
))
.addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
.info(apiInfo())
.servers(List.of(new Server().url("https://newteamsgoody.com"))); // HTTPS 서버 설정
.servers(List.of(new Server().url(serverUrl)));
}

private Info apiInfo() {
return new Info()
.title("\uD83E\uDD81 멋사 모여톤 10팀 스웨거 \uD83D\uDC8E")
.description("모여톤 10팀의 스웨거입니다.")
.description("모여톤 10팀의 스웨거입니다")
.version("1.0.0");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public ResponseEntity<MessageDTO> deleteMessage(@PathVariable Long messageId, @P
return ResponseEntity.ok(messageService.deleteMessage(messageId, uid, userDetails));
}

// 해당 유저 쪽지 전체 조회
@Operation(summary = "해당 유저 쪽지 전체 조회")
// 해당 유저 송수신 쪽지 전체 조회
@Operation(summary = "해당 유저 송수신 쪽지 전체 조회")
@GetMapping("/user/{uid}")
public ResponseEntity<List<MessageDTO>> getAllMessagesForUser(@PathVariable String uid, @AuthenticationPrincipal UserDetails userDetails) {
return ResponseEntity.ok(messageService.getAllMessagesForUser(uid, userDetails));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import java.util.List;

public interface MessageRepository extends JpaRepository<MessageEntity, Long> {
List<MessageEntity> findAllBySenderUidAndReceiverUid(String senderId, String receiverId);
List<MessageEntity> findAllBySenderUidOrReceiverUid(String senderId, String receiverId);
List<MessageEntity> findBySenderUid(String senderId);
List<MessageEntity> findByReceiverUid(String receiverId);
List<MessageEntity> findByContentContainingIgnoreCase(String keyword);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ public MessageDTO deleteMessage(Long messageId, String uid, UserDetails userDeta
return MessageDTO.entityToDTO(messageEntity);
}

// 해당 유저 쪽지 전체 조회
// 해당 유저 송수신 쪽지 전체 조회
public List<MessageDTO> getAllMessagesForUser(String uid, UserDetails userDetails) {
if (!userDetails.getUsername().equals(uid)) {
throw new RuntimeException("인증되지 않은 유저입니다.");
}
return messageRepository.findAllBySenderUidAndReceiverUid(uid, uid)
return messageRepository.findAllBySenderUidOrReceiverUid(uid, uid)
.stream()
.map(MessageDTO::entityToDTO)
.collect(Collectors.toList());
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/application-real1.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
server:
port: 8081
2 changes: 2 additions & 0 deletions src/main/resources/application-real2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
server:
port: 8082