Information Security Study

240702 webhooks로 자동 배포하기(이어서), 아틸러리로 스트레스 테스트하기, Nginx로 무중단배포 스크립트 작성하기 본문

네트워크 캠퍼스/NHN클라우드-Jenkins

240702 webhooks로 자동 배포하기(이어서), 아틸러리로 스트레스 테스트하기, Nginx로 무중단배포 스크립트 작성하기

gayeon_ 2024. 7. 2. 15:53

webhooks로 자동 배포하기

 

 

두 인스턴스가 프로세스를 실행할 때 같은 포트를 사용해서

배포를 하게 되면 포트 충돌이 난다.

위 명령어는 nohup.out 파일의 끝 부분에 추가되는 내용만 출력한다.

 

 

 

.jar 파일이 실행되고 있는지 (배포 중인 프로세스 조회) 프로세스 조회 명령어

 

 

 

프로세스 종료 명령어

8080 포트를 점유하고 있는 애플리케이션을 종료시키는 명령어이다.

 

 

 

프로세스 종료 명령어를 사용하면 위와 같이 접속되지 않는다.

 

 

 

 

포트 충돌이 나지 않고 정상적으로 실행될 수 있도록 각 instance Exec command 창에 위와 같이 프로세스 종료 명령어를 추가로 작성했다.

 

+) 이때 딜레이 배포를 하기 위해서는 2번 pc부터 exec command 맨 위에

sleep 60과 같이 대기시키는 명령어를 작성하면 롤링방식 무중단 배포를 구현할 수 있다.

이 실습에서는 딜레이 배포 방식을 사용하지 않았다.

 

 

 

tail -f nohup.out

으로 확인하면 이전과 달리 8080 포트 충돌 로그가 뜨지 않는다.

 

 

 

이제 Webhooks 설정을 해볼 것이다.

깃허브 -> 젠킨스 서버에 사용한 깃허브 레포지토리 -> Settings -> Webhooks

에서 Payload에 

http://젠킨스서버플로팅ip:포트번호/github-webhook/

을 입력하고

Content type에는 json을 선택한다.

 

 

 

그러고 나서 push를 감지하나 확인하기 위해 hello 페이지에 출력할 내용을 변경했다.

그러고 나서 commit change를 하고 젠킨스에서 확인하면

 

 

 

commit change만 했을 뿐인데 빌드가 시작되었다.

 

 

 

변경 내역도 잘 반영되었다.

 

 

깃허브에 commit, push 등 변경 사항이 생겨 젠킨스가 다시 빌드를 시작하면 

프로세스를 종료했다가 시작하는 준비 시간이 필요한데 이때 서비스가 중단된다.

이와 같은 배포 방식을 중단배포라고 한다.

이때까지 실습한 배포 방식은 중단배포이다.

 

 

 

딜레이 배포를 하기 위해서는 2번 pc부터 exec command 맨 위에

sleep 60과 같이 대기시키는 명령어를 작성하면 롤링방식 무중단 배포를 구현할 수 있다.

 


아틸러리로 스트레스 테스트하기

 

vscode를 관리자 권한으로 실행한 뒤 터미널 창에

artillery run --output report.json script.yaml

로 부하테스트를 실행한다.

 

타깃에는 instance-1의 플로팅 ip를 적어뒀다.

 

 

 

실행하고 나면 report.json 파일이 생성된다.

 

 

 

artillery.cmd report .\report.json

그러고 나서 위 명령어로 리포트를 생성한다.

 

 

 

해당 경로에 .html 파일이 생성된 것을 확인할 수 있다.

 

 

 

들어가 보면 리포트를 확인할 수 있다.

여기서 thhp.response_time이 중요하다.

백엔드 개발 시 응답시간을 최대한 안정적으로 유지해야 한다.

중앙값과 95번째 백분위 값이 큰 차이가 나지 않으면 안정적인 서버이다.

 

 

 

cpuBound를 발생시키는 애플리케이션으로 부하테스트를 실행했기 때문에 중앙값과 95번째 백분위 값이 크게 차이 났다.

 

인스턴스 하나하나 성능을 높여 다시 부하테스트를 하면 서버가 좀 더 버틴다.

이것을 수직 스케일링이라고 한다.


Nginx로 무중단배포 스크립트 작성하기

nginx를 사용해 수평 스케일링을 할 수 있다.

instance-1, instance-2 이 두 개의 서버의 앞단에서 nginx가 모든 요청을 받을 수 있도록 변경할 것이다.

 

 

nginx-instance를 생성했다.

 

 

 

nginx를 사용해야 하기 때문에 보안 규칙도 추가로 생성한다.

 

 

 

여러 설정 후 (노션 참고)

nginx 설치를 하고 버전 확인한 후에 엔진엑스를 가동했다.

 

 

 

그다음 해당 가상 pc의 공개 아이피로 포트번호 없이 접속하면 된다.

이제 로드밸런싱을 할 수 있도록 nginx의 설정을 변경할 것이다.

 

 

 

sudo vi /etc/nginx/nginx.conf

위 명령어로 설정창을 연다.

 

 

worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"'
                      'backend_server=$upstream_addr';

        upstream cpu-bound-app {
          server {인스턴스 ip:포트} weight=100 max_fails=3 fail_timeout=3s;
          server {인스턴스 ip:포트} weight=100 max_fails=3 fail_timeout=3s;
          server {인스턴스 ip:포트} weight=100 max_fails=3 fail_timeout=3s;
        }

        server {
                location / {
                  proxy_pass http://cpu-bound-app;
                  proxy_http_version 1.1;
                  proxy_set_header Upgrade $http_upgrade;
                  proxy_set_header Connection 'upgrade';
                  proxy_set_header Host $host;
                  proxy_cache_bypass $http_upgrade;
                }
        }



    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
}

 

include 밑에 위와 같이 작성한다.

ip는 중괄호를 빼고 작성한다.

 

 

 

수정 후 nginx 설정 파일을 재입력해 줘야 한다.

 

 

 

nginx-instance의플로팅ip/hash/아무입력값

을 입력하면 instance-1이나 instance-2에 직접 접속했을 때처럼 hash 값을 볼 수 있다.

 

 

 

로그 끝자락에 보면 backend_server의 주소가 바뀌고 있다.

로드밸런싱이 되고 있는 것을 볼 수 있다.

 

 

위에서 instance-1로 스트레스 테스트를 했을 때 timeout이 많이 나왔었다. 시간이 증가할수록 대부분의 요청이 실패했었다. (서비스가 터짐)

이제는 instance들 앞단에서 nginx가 요청을 받고 있기 때문에 스트레스 테스트 시

terget에 nginx의 플로팅 ip를 입력해야 한다.

nginx는 80 포트를 사용하기 때문에 target 입력 시 포트 번호를 적지 않아도 된다.

 

 

 

리포트까지 생성한 후 확인해 보면 error가 0인 것을 확인할 수 있다.

수평 스케일링으로 몰리는 트래픽을 분배해 에러를 줄인 것이다.

 

 

 

수직 스케일링 방법을 사용했을 때보다 중앙값과 95번째 백분위 값의 차이가 덜 난다.

 

 

 

잠시 sleep 60을 지워 중단 배포 방식으로 변경하고

깃허브에서 hello 페이지의 출력 문자열을 변경한 뒤 commit을 하면 webhook으로 인해 자동으로 배포된다.

 

 

 

instance-2의 sleep 60 명령을 지웠기 때문에 빌드가 완료되기 전까지 서비스를 사용하지 못하는 상황이 발생한다. (중단 배포)

 

 

instance-2에 sleep 30을 추가한 뒤 github에다 출력 문자열을 변경하고 commit 해서 무중단 배포 시 

버전이 변경되는 과정을 볼 것이다.

 

우선 기존 버전은 hello 페이지에 접속 시

hello hello

가 출력된다.

 

기존 버전과 구분하기 위해 새 버전은 

Hi

문자열을 출력하도록 했다.

 

빌드가 시작된 후 서비스 페이지를 계속 새로고침 하다 보면

새 버전인 Hi와 기존 버전인 hello hello가 번갈아서 출력되다가

시간이 지나 instance-1과 instance-2가 모두 업데이트가 되면 Hi만 출력이 된다.