2022 06 30
2022-06-30¶
도커로 배포하기¶
- 참고: https://subicura.com/2016/06/07/zero-downtime-docker-deployment.html
- 어떻게 배포하는 것이 좋은가?
- 쉽고 관리하기 편한 방법을 선택하자
- 자동으로 배포하자
- 하루에도 여러번 배포하자
- 배포 중 서비스가 중단되는 일이 없도록 하자
- 모든 서비스는 도커를 이용해 컨테이너 형태로 표준화하여 배포하자
- 테스트 서버에 동일한 방법으로 배포하고 테스트하자
- 시작은 서버 한대지만 나중에 여러대로 확장되었을때를 대비하여 설게를 고민하자
- Why Docker?
- 새로운 서버에 서비스를 동작시키려면 굉장히 많은 작업 필요
- 백엔드 언어에 귀속되는 다양한 익스텐션 설치 필요
- 서버 한 대 추가된다고 똑같이 세팅하기가 참으로 어려움
- 버전 업데이트되면 그것도 그것대로 골때림
- 도커를 통한 배포가 갖는 특징
- 확장성
- 이미지만 만들어둔다면 컨테이너는 띄우기만 하면 됨
- 다른 서버로 서비스 옮기거나 새로운 서버에 서비스 하나 더 띄우는건
docker run명령어면 충분 - 개발서버 띄우기도 편하고 테스트서버 띄우기도 간편
- 표준성
- 도커 사용하지 않는 경우 다른 언어로 만든 서비스들의 배포 방식은 제각각 다르다
- 컨테이너라는 표준으로 서버를 배포해야 배포 과정이 동일해짐
- 이미지
- 이미지에서 컨테이너를 생성하기에 반드시 이미지 만드는 과정 필요
- 이미지 저장할 공간 필요
- 해당 이미지를 distribution에 저장하고 운영서버에서 이미지 불러옴
- 설정
- 설정은 보통 환경변수로 제어
MYSQL_PASS=password와 같이 컨테이너 띄울때 환경변수 같이 지정- 하나의 이미지가 환경변수에 따라 동적으로 설정파일 생성하도록 만들어야 함
- 공유자원
- 컨테이너는 삭제 후 새로 만들면 모든 데이터가 초기화됨
- 업로드 파일을 외부 스토리지와 링크하여 S3 같은 별도 저장소 필요
- 세션이나 캐시를 파일로 사용한다면 redis 외부로 분리
- 확장성
컨테이너로 배포 vs 프로세스로 배포¶
- 참고: https://zzang9ha.tistory.com/360
- 굳이 컨테이너?
- 어플리케이션이 동작하는 환경 자체를 개발 환경과 운영 환경을 동일하게 구성 가능
- 해당 서비스에 대한 트래픽 증가시 보다 효율적으로 서비스 확장하기 좋음
- 도커파일 예시
- 구축 이후 Build한 이미지를 컨테이너에 올려보자
- 이후에 배포 스크립트를 작성해서 인스턴스에서 돌린다!
- dockerhub을 통한 배포

- 과정
- Dockerfile을 build해서 docker image 파일 생성
- docker image 파일을 dockerhub에 push
- 서버에서 docker hub에 존재하는 docker image를 pull 해옴
- docker run 명령어를 통해 docker image 파일 실행
- 개발환경에서 포장한 컨테이너 그대로 운영서버에서 돌릴 수 있다!
GraphQL¶
- 참고: https://www.youtube.com/watch?v=N-81mS2vldI
- 참고: https://www.youtube.com/watch?v=EkWI6Ru8lFQ
- 참고: https://hwasurr.io/api/rest-graphql-differences/
- 참고: https://choseongho93.tistory.com/320
- Rest API의 문제점
- Over Fetching
- 필요한 정보보다 많이 가져오는 경우
- 불필요한 데이터를 굳이 가져와서 안쓰는 경우를 오버페칭이라고 지칭한다
- Under Fetching
- 필요한 것보다 적게 가져오는 경우
- API가 각각 나뉘어 프론트에 그릴때 2가지의 API를 호출해야 하는 경우
- 문서화의 부담
- graphql의 경우 모델의 관계를 도식화하여 용이하게 파악 가능
- Over Fetching
-
GraphQL 유튜브
- GraphQL = Query Language
- Query를 보내서 정확히 필요한 데이터만 받아오는 것
- 요청
- 응답
- POST 요청 하나로도 유연하게 주문이 가능함
- CUD 모두 POST 요청
- U,D는 함수명으로 뚝딱 요청
- 필요한 정보들을 요청 body 에다가 다 적어서 보내면 쿼리 조합해서 한번에 응답해 줌
- 같은 API 서버를 쓰더라도, 사용자마다 요청이 다르고 PC/안드로이드/아이폰 등 기기 마다 다르면 유리
- 여러 depth들의 정보들을 한번에 받아올 수 있지

- GraphQL 글
- API에 대한 새로운 패러다임으로 여겨짐
- API 서버에서 엄격하게 정의된 endpoint 들에 요청하지 않고, 한 번의 요청으로 정확히 가져오고 싶은 데이터 가져오는 쿼리 제공
- Rest API vs GraphQL
- REST
- Resource에 대한 형태 정의와 데이터 요청 방법이 연결되어 있음
- Resource의 크기와 형태를 서버에서 결정
- URI가 Resource 나타내고 Method가 작업의 유형 표현
- 여러 Resource에 접근하고자 할 때 여러번의 요청이 필요
- 각 요청의 엔드포인트에 정의된 핸들링 함수 호출하여 작업 처리
- 다양한 기종에서 필요한 정보들을 일일히 구현하는 것이 힘들었음
- GraphQL
- Resource에 대한 형태 정의와 데이터 요청이 완전히 분리됨
- Resource에 대한 정보만 정의하고, 필요한 크기와 형태는 client 단에서 요청 시 결정
- Schema가 Resource 나타내고 Query, Mutation 타입이 작업의 유형 나타냄
- 한번의 요청에서 여러 Resource에 접근 가능
- 요청 받은 필드에 대한 resolver를 호출하여 작업 처리
- REST
-
Rest API => GraphQL
- RestAPI
-
GraphQL
- 우선 타입 정의
- 리소스의 유형과 리소스를 가져오는 방식이 분리되어 있음
- Client에서 데이터를 어떻게 요청할 수 있는지 정보 X
- Book & Author에 접근하도록
Query타입 필요
- 이후 쿼리는 다음과 같은 방식
POST: /graphql?query={book(id:"1") {title, author {firstName}}}- Rest와 다르게 /books 와 같이 Resource에 대한 엔드포인트 존재 x
- 우선 타입 정의
- GraphQL의 장점
- Frontend 단에서 딱 필요한 정보만 별도 요청 가능
- 클라이언트/서버 간 오류 줄여줌
- GraphQL 기존 쿼리 중단하지 않고도 진화할 수 있도록 허용
- HTTP 요청의 횟수를 줄일 수 있다
- HTTP 응답의 Size를 줄일 수 있다
Connectable에서 GraphQL 필요한가?¶
- 하나의 백엔드 서버를 두고, 아티스트 대시보드/팬 앱을 운영할 것
- 아티스트 도메인 경우 각각의 앱에서 줘야할 정보가 다름
- Authentication을 거쳐서 아티스트 대시보드 측이 요청한 graphQL에 알맞게 응답을 줄 수 있다면 유의미할 듯?
Spring에서 GraphQL¶
- 참고: https://siyoon210.tistory.com/153
- 참고: https://velog.io/@jay2u8809/SpringBoot-GraphQL%EC%9D%84-%EC%8D%A8%EB%B3%B4%EC%9E%90
- GraphQL 복습
- 클라이언트는 단일 요청에서 여러 하위 자원 탐색을 포함해, "원하는 데이터" 만을 정확하게 지정 가능
- GraphQL 사용하면 클라이언트가 필요로 하는 응답만을 단 한번의 요청으로 받을 수 있음
- 클라이언트에서 주도적으로 할 수 있다는 것이 RestAPI와의 가장 큰 차이점
- GraphQL Schemas
-
SpringBoot에 적용하기
-
의존성 주입하기
- graphql-spring-boot-starter
-
스키마 파일 작성하기
.graphqls라는 확장자로 저장
-
루트 쿼리 처리를 위한 bean 설정 (GraphQLQueryResolver 구현)
query타입의 메서드를 GraphQLQueryResolver 인터페이스로 구현- 스키마에 있는 필드가 클래스의 메소드로써 모두 존재해야 함
-
GraphQL 타입 나타내기
-
Mutation
- GraphQL은 서버에 저장된 데이터를 업데이트 하기 위한 행위
public class MyMutation implements GraphQLMutationResolver { private final PostRepository postRepository; private final AuthorRepository authorRepository; public PostResponse writePost(String title, String text, String category) { Post post = new Post(); post.setTitle(title); post.setCategory(category); post.setAuthor(authorRepository.getOne(1L)); postRepository.save(post); return PostResponse.from(post); } }
- GraphQL은 서버에 저장된 데이터를 업데이트 하기 위한 행위
-