skarltjr / Memory_Write_Record

나의 모든 학습 기록
0 stars 0 forks source link

대용량트래픽과 무중단배포 절차 / GCP . DOCKER . JENKINS . NGINX . RABBITMQ . ELASTICSEARCH #15

Open skarltjr opened 3 years ago

skarltjr commented 3 years ago

화면 캡처 2021-02-10 005241

vm을 통해 배포하기

1. gcp에서 vm인스턴스 생성

2. gcp vm인스턴스에서 ssh를 사용하여 명령

3. 배포하고자하는 프로그램 jar파일로 패키징 후 깃허브에 업로드

4. 깃허브에 올려둔 jar파일을 gcp인스턴스에서 다운로드


Dockerized 애플리케이션 배포

  1. 도커이미지를 도커허브에 푸쉬하여 이미지를 저장소에 저장/업로드

    • 인텔리제이에서 docker push skarltjr/spring-boot-cpu-bound:tagname
    • 여기서는 tagname을 지정하지않았으니 docker push skarltjr/spring-boot-cpu-bound을 수행
    • denied: requested access to the resource is denied / 도커허브에 로그인필요 화면 캡처 2021-02-06 144916
    • 다시 push
    • 확인 화면 캡처 2021-02-06 145413
  2. GCP인스턴스에서 저장소에있는 이미지를 풀로 다운로드

    • ssh를 통해 인스턴스에 docker다운로드
    • sudo yum install docker
    • sudo systemctl start docker로 도커 실행하기
    • sudo docker pull skarltjr/spring-boot-cpu-bound로 인스턴스에서 pull하기
    • sudo docker run -p 80:80 skarltjr/spring-boot-cpu-bound 를통해 80번 포트를 사용하기 때문에 내부외부 연결 후 실행
  3. 다운로드된 이미지를 run하면 컨테이너가 되어 애플리케이션이 실행된다.

    • artillery를 통해 vm과 비교해보기 화면 캡처 2021-02-06 151422



Jenkins

// sudo yum install jenkins를 하면 패키지가 없다고 뜬다. -> 따로 패키지를 추가해줘야한다 sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key sudo yum install jenkins // 이 후 젠킨스 다운로드 sudo systemctl start jenkins // jenkins 데몬 실행 sudo systemctl status jenkins // 데몬 실행 확인

![화면 캡처 2021-02-06 162644](https://user-images.githubusercontent.com/62214428/107112068-203b3180-6898-11eb-855a-622602bdfcd0.png)
- 이렇게 젠킨스가 활성화되면 웹으로 접근할 수 있다
- 그러나 이 떄 젠킨스는 8080포트로 열려있는데 지금 애플리케이션은 80번포트로 지정해놨기 때문에 8080포트도 열어줘야한다.
- 인스턴스 생성시 http,https는 허용했기 때문에 지정한 80포트와 https 443포트는 열려있다
- gcp 방화벽 규칙설정에서  대상 : 네트워크 모든 인스턴스에 대해 모든 IP범위 0.0.0.0/0   TCP포트8080으로 설정
![화면 캡처 2021-02-06 163218](https://user-images.githubusercontent.com/62214428/107112189-05b58800-6899-11eb-8085-ee64bd62aa19.png)
- 확인
![화면 캡처 2021-02-06 163415](https://user-images.githubusercontent.com/62214428/107112201-2bdb2800-6899-11eb-9b57-bc6dd56020cb.png)
- 이 후 인스턴스 IP:8080을 통해 웹에서 jenkins getting started접근가능
- ssh에서 `sudo cat /var/lib/jenkins/secrets/initialAdminPassword`를 통해 초기 비밀번호확인 후 인스턴스 IP:8080에 접속
- 이 후 플러그인 (ssh)설치하고 젠킨스 계정 다시 설정
![화면 캡처 2021-02-06 164407](https://user-images.githubusercontent.com/62214428/107112382-8c1e9980-689a-11eb-87b6-57d5892cd927.png)

설정
- gcp에 2개의 인스턴스 : jenkins instance / worker instance를 만들었는데
- 젠킨스가 워커로 접속하여 도커이미지를 pull받고 이를 run시키는것
- 이 때 젠킨스만 워커에 ssh로 접근하도록 설정해줘야한다 . 해커의 접근방지
- 따라서 젠킨스 인스턴스만 워커인스턴스에 접근하도록 설정해줘야한다
#### 중요 : 어떻게 이러한 설정이 가능한가?
- 기본적으로 평문을 암호문으로 encode(암호화)  / 반대는 decode복호화
- 대칭키 : 암호화 -복호화 에서 사용하는 키가 동일
- 비대칭키 : 암호화 -복호화 에서 사용하는 키가  다른것 
- 비대칭키에서 두 개의 키는 분명 관계가 있다. 그러나 같지않다.
![화면 캡처 2021-02-06 165753](https://user-images.githubusercontent.com/62214428/107112641-79a55f80-689c-11eb-838e-d7060a3772d4.png)
#### 결론적으로 jenkins인스턴스에서 개인키와 공개키를 만들고  공개키를 worker인스턴스에 등록해주면 오직 젠킨스만 워커인스턴스에 ssh로 접속가능 
- 이를위해 젠킨스 인스턴스에서  `ssh-keygen -t rsa -f ~/.ssh/id_rsa` 를 통해 공개키 개인키 쌍을 만들고
- .ssh 폴더로 이동하여 생성된것을 확인
![화면 캡처 2021-02-06 171251](https://user-images.githubusercontent.com/62214428/107112931-9478d380-689e-11eb-8798-aabcb4f4e6b6.png)
- 이 후`[kisa0828@jenkins-instance-1 .ssh]$ vi id_rsa.pub` vi id_rsa.pub명령어를 통해 확인한 공개키를 복사한 후 워커인스턴스 ssh로 접속한 후` vi ~/.ssh/authorized_keys`로 파일을 수정하여 젠킨스 인스턴스에서 복사한 공개키를 워커인스턴스 키 파일에 붙여넣기로 등록
- 이때!!!! 주의할점 공개키를 붙여넣을 때 엔터키가 포함된채로 - 에러 창늘려서 확인해보기
- 추가적으로 이 폴더들의 권한을 변경해줘야한다. 워커인스턴스 ssh에서 폴더권한 변경

[kisa0828@cpu-worker-instance-1 .ssh]$ chmod 700 ~/.ssh [kisa0828@cpu-worker-instance-1 .ssh]$ chmod 600 ~/.ssh/authorized_keys

- 젠킨스 환경설정에서 개인키등록 + ssh 서버 등록(워커인스턴스 등록) : 젠킨스 인스턴스 개인키를 등록하고 (ssh server = )연결할 인스턴스정보 
![화면 캡처 2021-02-06 194336](https://user-images.githubusercontent.com/62214428/107115983-b4ff5880-68b3-11eb-8c6e-3e45c5dc458f.png)
- 이 후 새로운ITEM등록 = 스크립트 작성 - freestyle
- 빌드 후 조치에서 동작할 명령어를 작성 - run명령어 // send build artifacts
- build now를 통해 빌드 후 빌드히스토리에서 생성된 파일 console output 으로 빌드/배포 로그확인해보면 ?
- 안된다. 왜냐?  앞에서 sudo명령어를 사용했는데 8080포트를 열고 변경했기 때문에 sudo가 필요가없다. 어차피 nginx가 앞에서 요청을 받아줄거기 때문에 nginx만 80번포트면 문제가없다.  -> 구성에서 `docker run -p 8080:80 skarltjr/spring-boot-cpu-bound` 변경
- 다시 빌드 후 로그확인 
- 그럼 되는가? 당연히안된다.  워크인스턴스에 도커를 깐적이없기 때문에
- 삽질하면서 배우기  :  젠킨스 인스턴스 ssh에서 공개키 swp파일꺼 복사붙여넣기하다 삽질한것도 기억
- 워크인스턴스에서 도커 다운로드 sudo yum install docker
- 도커데몬 실행 sudo systemctl start docker
  1. 결론적으로 명령어는nohup docker run -p 8080:80 skarltjr/spring-boot-cpu-bound > /dev/null 2>&1 & 설정 nohup과 맨 뒤& = 이 명령을 백그라운드로 동작시키겠다.

    /dev/null 2>&1 = 표준에러를 표준출력으로 리다이렉션

  2. 워커인스턴스 authorized_keys에 젠킨스인스턴스 공개키 추가
  3. 권한설정 [kisa0828@cpu-worker-instance-1 .ssh]$ chmod 700 ~/.ssh [kisa0828@cpu-worker-instance-1 .ssh]$ chmod 600 ~/.ssh/authorized_keys
  4. 워커인스턴스에 도커가 없다면 install
  5. sudo systemctl start docker
  6. sudo chmod 666 /var/run/docker.sock
    
    ![화면 캡처 2021-02-06 230843](https://user-images.githubusercontent.com/62214428/107120315-50062b80-68d0-11eb-85e1-f423a5476a18.png)
skarltjr commented 3 years ago

스트레스 테스트 툴로 성능테스트하기

화면 캡처 2021-02-06 005230

// cpu-test.yaml
config:
  target: "http://34.64.70.44"
  phases:
    - duration: 60
      arrivalRate: 1
      name: Warm up
scenarios:
  # We define one scenario:
  - name: "just get hash"
    flow:
      - get:
          url: "/hash/123"
skarltjr commented 3 years ago

Nginx 로드밸런싱을 통한 무중단 배포

3개의 워커인스턴스에 젠킨스를 통해 배포 자동화를 하기 위해 젠킨스 설정

Nginx를 위해 인스턴스 추가

결과적으로 nginx에 요청을 했는데 마치 nginx 뒤 설정해둔 서버에서 동작하는 것처럼 작동

artillery를 통해 인스턴스3개일때와 1개일때 비교하기

실행중인 도커 컨테이너 중 spring-boot-cpu-bound 애플리케이션이 포함된 줄 찾기

docker ps | grep spring-boot-cpu-bound // 이 후 맨 앞 컨테이너 아이디필요없이 찾아낼 수 있다

도커 컨테이너 종료시키기

docker container kill -s 15 {컨테이너 id} // 이를통해 애플리케이션이 스스로 모든 로직을 처리한 후에 잘 종료하도록해준다.


- 이렇게 2,3번 두개의 인스턴스를 종료하고 1번 하나로만 성능측정해보기 : 502 에러 - 처리불가
![화면 캡처 2021-02-07 183455](https://user-images.githubusercontent.com/62214428/107142546-31a53c00-6973-11eb-8ddf-e49d6d93fd92.png)

- 이로써 cpu-bound 애플리케이션을 nginx의 로드밸런싱을 통해 분산처리했을 때 훨씬 안정적인 트래픽을 유지할 수 있는것을 확인했다.

- 다시 젠킨스에 접속해서 build now를 통해 배포를 하여 종료했던 2,3도 다시 동작시키고
- nginxIp/hello로 접속해서 동작을 확인하고 + 개별 인스턴스도 동작하나 확인해보고

#### 그렇다면 로드밸런싱으로 무중단 배포가 정말 이뤄지고 있는가?
- 확인을 위해 artillery스트레스 테스트를 동작시키는 도중에 1,2번 인스턴스를 하나씩 종료해보면
- 그래도 동작이 진행된다는 것은 - 여전히 3번 인스턴스를 통해 처리중이고 즉 무중단 배포가 진행되는것을 알 수 있다.
-  실행해본 결과 artillery test중에 2,3번을 내리고 다시 배포를 했음에도 중단없이 요청이 처리가 되는것을 확인할 수 있었고 결과적으로 무중단 배포가 실행 + 도중에 다시 젠킨스에서 build now를 통해 배포하여 2,3번을 살렸다. 만약 중간에 튀는 부분이 있다면 그것은 2,3번을 내리고 다시 배포하는 동안 1번 혼자서 모든 요청을 처리했기 때문이라고 추측 - 결과보기
![화면 캡처 2021-02-07 185013](https://user-images.githubusercontent.com/62214428/107142912-569aae80-6975-11eb-8784-40d8efe3af08.png)
skarltjr commented 3 years ago

GithubWebhook과 jenkins를 통한 배포자동화

즉 지금 애플리케이션은 docker를 통해서가 아니라 jar파일을 직접 실행 중

  1. 우선 자동화를 위해 실행중인 애플리케이션 모두 종료 -워커인스턴스 ssh로 접속해서 -ps -aux | grep java 실행중인 프로자바 프로세스 검색 화면 캡처 2021-02-08 172908 -3개의 프로세스 실행중인 걸 확인 후 모두 죽임 화면 캡처 2021-02-08 173131

  2. 깃허브 저장소에서 setting - webhook -add webhook에서 payload를 등록 -http://34.64.101.145:8080/github-webhook/ 젠킨스 외부ip:8080 -contentType : json으로변경 화면 캡처 2021-02-08 173800

헷갈렸던게 여기서 jar배포파일을 끌어오는게 아니라 이cpu-bound 레퍼지토리에 있는 코드들을 packing해서 자르파일로 만들어서 실행

  1. source tree에서 레퍼지토리 클론받기 -클론받은 파일을 인텔리제이로 다시열면 (여기서는 document에 저장해뒀음 ) -여기서 properties에서 포트 8080로 변경후 소스트리에서 변경사항 커밋해주고 마스터에서 push해주기 -젠킨스에서 자동으로 다시 배포가 일어난것을 확인할 수 있다. -인스턴스 ip:8080으로 접속이 잘 되는지 확인 👍 -추가적 확인을 위해 hello request에 응답으로 hello kiseok으로 변경해서 push한 후 살펴보기 -push 후 다시 배포가 일어나는것을 확인했는데 변경이 안된다??? -1번인스턴스 ssh를 통해 tail -f nohup.out으로 로그를 찍어보니
Description:
Web server failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on an
other port.

-이미 8080포트를 사용하고 있는 놈이 존재 -프로세스 확인하고 죽이기 위한 명령 lsof를 사용하기 위해 인스턴스 모두 lsof 다운로드 (L임) // ★ sudo yum install -y lsof -sudo kill -15 $(sudo lsof -t -i:8080) 명령어를 젠킨스에서 모든 ssh server 에 추가 화면 캡처 2021-02-08 183031 -다시 hello kiseok2로 변경 후 푸쉬하고 배포 후에 확인해보면 화면 캡처 2021-02-08 183300

그런데 만약 배포진행중에 이런 방식으로 자동화 배포를 한다면 3개의 인스턴스 모두가 재배포를 위해 내려갔다가 다시 올려질텐데 그럼 그동안 nginx를 거쳐 들어온 요청을 처리할 서버가 없다.

skarltjr commented 3 years ago

DB I/O bound Application

sudo yum install docker // 도커설치 sudo systemctl start docker // 도커데몬 실행 sudo chmod 666 /var/run/docker.sock // 권한부여 docker run --name pgsql -d -p 5432:5432 -e POSTGRES_USER=postgresql -e POSTGRES_PASSWORD=postgrespassword postgres // 도커로 psql실행 ★여기서 원래는 도커에서 psql을 사용하여 계속 저장하기위해 volume을 잡아줘야 db에 있는 내용을 저장가능. // 기본포트 5432 postgres는 이미지 이름 , 유저 패스워드는 db에서 사용할

skarltjr commented 3 years ago

I/O Bound - 깃 플로우를 통해 기능개발


이제 이 변경사항을 젠킨스를 통해 배포하기


artillery를 통해 테스트해보기

화면 캡처 2021-02-11 195257 화면 캡처 2021-02-11 195247

skarltjr commented 3 years ago

RabbitMQ : message Queue★

글 작성 요청을 따로 queue에 저장하였다 처리하기 위한 message queue

화면 캡처 2021-02-13 143720

Message Queue의 장점

  1. 비동기성 : 요청이 몰리는 경우 mq 같은경우 요청을 저장한 후 하나씩 처리해나갈 수 있다. 즉 톰캣같은경우 서버가 죽으면 큐도 날아가버리는 반면 여기서는 저장이 가능 + 따라서 A -> mq ->B 순서에서 A는 로직에 상관없이★ 자신의 할일을 하고 큐에 넣은 후 다시 요청을 받을 수 있는 상태

  2. 애플리케이션간 의존성 제거 : A -> B로 API를 통해 데이터를 전달하는 경우 배포과정에서 B가 죽으면 보내려던 데이터는 사라진다. 반면 큐를 중간에 추가해주면 데이터는 여전히 저장이 되어있다. 이 후 B가 다시 정상작업이 가능해지면 저장된 요청을 처리한다. 화면 캡처 2021-02-13 144730 화면 캡처 2021-02-13 144740

  3. 큐의 이중화 : 큐도 결국 애플리케이션이기 때문에 죽을 수 있다. 여러개의 큐를 사용하여 하나가 죽더라도 이어나갈 수 있도록

  4. 신뢰성 : 요청이 실패하면 다시 큐로 가져온다. 이 후 다시 요청


실행

  1. post 컨트롤러 변경 @PostMapping("/post") public Post createPost(@RequestBody Post post) throws JsonProcessingException { producer.sendTo(objectMapper.writeValueAsString(post)); return post; /return postRepository.save(post);/ }

- rabbitMQ 인스턴스 새로 만들기
- 당연히 rabbitMQ에서 5672포트와 15672포트를 사용하기 때문에 방화벽 열어주기 
- sourcetree를 통해 커밋준비 이 때     host: rabbitmq인스턴스 내부아이피 /      url: jdbc:postgresql://postgres인스턴스 내부아이피 확인하기 

spring: datasource: url: jdbc:postgresql://postgres인스턴스 내부아이피/postgresql username: postgresql password: postgrespassword jpa: show-sql: true hibernate: dialect: org.hibernate.dialect.PostgreSQLDialect ddl-auto: update rabbitmq: host: rabbitmq인스턴스 내부아이피 username: guest password: guest port: 5672

- 우선 rabbitmq 인스턴스에 도커 컨테이너 띄우기 

sudo yum install docker sudo systemctl start docker sudo chmod 666 /var/run/docker.sock docker run -d --hostname my-rabbit --name some-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3-management

- rabbitmq인스턴스 외부아이피:15672로 모니터링 툴 접속 후 동일하게 queue만들어주기 
- 모든 내용 커밋을 위해 dev에서 새로운 브랜치를 따고 커밋 후 푸쉬 
- 레퍼지토리에서 pr로 merge하기(당연히 dev <- feat으로 머지)
- feat에서 pull , dev 에서 pull로 확인
- main이랑 dev 병합하기
![화면 캡처 2021-02-13 160103](https://user-images.githubusercontent.com/62214428/107844196-bcbf7f80-6e14-11eb-8f21-87c9108dd08a.png)

- 이 후main도 푸쉬하여 마무리
- 배포 전 글 목록 0번(첫번쨰 페이지 캐싱)추가

### db부하를 줄이기 위해 글 목록 첫 페이지 캐싱하기  / 내부구현보다 redis 사용이 효율적 
- 매 번 첫번째 페이지 요청마다 db에 접근하는 대신 미리 첫 페이지를 땡겨와서 저장해두면 db에 부하를 감소시킬 수 있다.
- chron 표현식 : https://www.leafcats.com/94

1. 스케쥴링이 가능하도록 설정하고
![화면 캡처 2021-02-13 160856](https://user-images.githubusercontent.com/62214428/107844329-cb5a6680-6e15-11eb-879c-9d76129fb446.png)

2. 글 목록 요청에서 만약 0번째. 첫 페이지를 요청하는 경우에는
@GetMapping("/posts")
public Page<Post> getPostList(@PageableDefault(size = 20, sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
    if (pageable.getPageNumber() == 0) {
        return postCacheService.getFirstPostPage();
    } else {
        return postRepository.findAll(pageable);
    }
}
3. 1초마다 미리 끌어온 첫 페이지에 대한 내용을 반환해주기. / 즉 많은 첫페이지에 대한 요청이 매우 많은 경우에 미리 가져온 데이터를 반환해줌으로 추가적인 쿼리발생 x  / 이 경우    yml에서 show-sql: false로 변경해줘서 로그 남기지않기

@Component @RequiredArgsConstructor public class PostCacheService {

private final PostRepository postRepository;

private Page<Post> firstPostPage;

@Scheduled(cron = "* * * * * *")
public void updateFirstPostPage() {
    firstPostPage = postRepository.findAll(
            PageRequest.of(0, 20, Sort.by("id").descending())
    );
}

public Page getFirstPostPage() { return this.firstPostPage; } }

- 확인을 위해 localhost에서  show-sql: true로 실행해보면 계속 미리 땡겨오는걸 알 수 있다.
![화면 캡처 2021-02-13 163354](https://user-images.githubusercontent.com/62214428/107844714-47a27900-6e19-11eb-9e74-fdc766f70c79.png)

- 동일하게 dev에서 브랜치 따서 커밋 후 push 하여  pr로 merge한 후  dev브랜치 pull당긴 후 main병합하여 push
- 배포 후 확인

### artillery를 통해 글 작성 테스트 
- rabbitmq를 적용했을 때 글 작성 테스트의 결과는 ?

테스트 스크립트 config: target: "http://35.229.133.12" phases:

★ 요점을 잘 파악 해야한다.

여전히 완벽히 처리 x

결과적으로 i/o bound app은 db의 속도가 중요. db에서의 병목을 해결해야한다.

skarltjr commented 3 years ago

글 목록조회 성능 테스트

화면 캡처 2021-02-13 220040

1번째 시도 화면 캡처 2021-02-14 000008 2번째 시도 화면 캡처 2021-02-14 000229

모든 테스트는 rabbitMQ 큐에 여전히 처리해야 할 데이터가 남아있을 때(유저들이 계속 검색하고있는 환경) 시행

skarltjr commented 3 years ago

nginx에서 connection refuse가 났을 때

추가로 에러가 났을 때 각인스턴스에서 에러로그를 확인해보고 설정 혹은 설치해야할 것을 다시 확인

skarltjr commented 3 years ago

Elastic Search

ES의 문서 저장 방식 / Inverted Index(역 색인)

Shard 샤드

레플리카

skarltjr commented 3 years ago

ES를 통해 검색 요청의 성능을 끌어올리자

목표 = ES 클러스터를 구축. 4개의 es인스턴스를 마치 하나의 인스턴스처럼 묶어주기

sudo sysctl -w vm.max_map_count=262144 // 가상메모리를 많이 사용하기때문에 사이즈 늘려주기

2. 1번 노드에서만 실행시키는 명령어 (인스턴스 내부 IP)

<1>. docker network create somenetwork // 네트워크 만들어주기 <2>. docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 \ -e "discovery.seed_hosts={1번 IP 빼고 나머지 3개 IP}" \ {}괄호 없이 쉼표로 -e "node.name=es01" \ -e "cluster.initial_master_nodes=es01,es02,es03,es04" \ -e "network.publish_host={1번 IP}" \ elasticsearch:7.10.1 <참고 : 메모장에 옮겨서 안틀리게 명령어 전체를 한 번에 붙여넣어라 - <2>번할 때 docker부터 마지막 10.1까지 한 번에 붙여넣어라> # 3. 2번 노드에서 실행시키는 명령어 docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 \ -e "discovery.seed_hosts={2번 IP 빼고 나머지 3개 IP}" \ -e "node.name=es02" \ -e "cluster.initial_master_nodes=es01,es02,es03,es04" \ -e "network.publish_host={2번 IP}" \ elasticsearch:7.10.1 # 4. 3번 노드에서 실행시키는 명령어 docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 \ -e "discovery.seed_hosts={3번 IP 빼고 나머지 3개 IP}" \ -e "node.name=es03" \ -e "cluster.initial_master_nodes=es01,es02,es03,es04" \ -e "network.publish_host={3번 IP}" \ elasticsearch:7.10.1 # 5. 4번 노드에서 실행시키는 명령어 docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 \ -e "discovery.seed_hosts={4번 IP 빼고 나머지 3개 IP}" \ -e "node.name=es04" \ -e "cluster.initial_master_nodes=es01,es02,es03,es04" \ -e "network.publish_host={4번 IP}" \ elasticsearch:7.10.1 ``` - 노드들이 떴는지 확인하기위해 9200 번으로 접근해야한다 : 9200방화벽 열어주고 확인하기 ![화면 캡처 2021-02-18 224759](https://user-images.githubusercontent.com/62214428/108366147-5f279a80-723b-11eb-99f8-3376fe19e8d5.png) - 확인을 위해 es instance 1번 외부아이피 : 9200으로 접근해보기 - 이 때 es head extension을 사용 - localhost대신 접속한 아이피로 connect ![화면 캡처 2021-02-18 230723](https://user-images.githubusercontent.com/62214428/108368742-250bc800-723e-11eb-9249-28eb3168ce0a.png) ### ES가 db보다 좋은가? - ★ 데이터를 저장한다는 공통점이 있지만 다르다 - es는 실시간처리 불가 / 인서트 후 딜레이가 있지만 사실상 거의 체감 x - 트랜잭션과 롤백 불가 - 데이터를 진짜 업데이트하지 않는다. / 삭제 후 다시 만든다. - ★ 즉 애플리케이션이 트랜잭션에 의존(만약 결제같은 프로그램)이라면 es는 사용 x ### jpa- db 대신 elastic search를 사용해보기 //todo
skarltjr commented 3 years ago

I/O BOUND 애플리케이션에서의 기술적 선택 요소

★ aws, gcp ,azure 등 클라우드 vs on-premise(독자적인 서버 구축)

화면 캡처 2021-02-19 143627

★ 스트레스 툴 / node.js의 artillery

★ CI/CD 툴 - jenkins

★ 배포방식 . 롤링(하나씩)

★ 배포시 단순히 30초 sleep이 아니라 서버가 요청을 받을 준비가 되었는지를 판단하기 위해 health check

★ 관계형 db vs nosql