JAVA 기반 spring cloud MSA,

6 minute read

교육

교육기간 : 2022.06.14 ~ 2022.06.17 JAVA 기반 MSA 교육 - 강사 :이도원

금번교육시 영역별 사용된 솔루션들

  • MSA -> 스프링클라우드,유레카서버,API게이트웨이,스프링시큐리티, jpa,
  • CI/CD -> docker, jenkins, git, k8s,
  • cloud server -> aws-ec2
  • data -> kafka(zookeper), rabbitmq, grafana, zipkin(트래픽추적), 스프링클라우드슬루스
  • develop client -> 인텔리제이, 포스트맨, vscode

### 클라우드 네이티브

  1. MSA
  2. CI/CD pipeline
  3. Devops
  4. Container

최근 MSA 동향

  • 넷플릭스 줄, 리본 이제 더이상 기술 지원안함 넷플릭스
  • 최근엔 리본안씀(로드밸런싱역할)
  • RestTemplate 도 안쓰고 FeignClient 씀
  • 넷플릭스API 는 히스트릭스 유레카정도만 씀
  • (zuul은 사용불가됨) -> 스프링클라우드 게이트웨이를 쓰게됨최근엔

## TIP 스프링클라우드와 스프링부트 버전맞춰줘야함. 프로퍼티스 보다->yml 추천(소스간략화) 오토스케일링 동일한 스펙의 시스템을 자동으로 늘렸다줄었다

### 인텔리제이 사용꿀팁 쉬프트두번따닥 ->검색기능 컨트롤+쉬푸트+에프 ->대상내 검색 무한 undo 울티메이트 가능 ->컨트롤+쉬프트+V (코디이력 클립보드 히스토리볼수있음)

## 실습코드 버그 발생 마지막 지원 버전 따라 2.6.8버전으로 바꿔야함 모두 –>루트프로젝트에서 2.5.14버전으로바꿔야 시큐리티 소스 문제없음 이부분도 바꿔야함

 <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>2021.0.0</spring-cloud.version>
    </properties>

롬복도 인텔리제이 울티메이트는 별도 설정은 필요없지만 세팅설정해줘야함.

  • docker compose공부할것«««<
  • docker <- 오케스트레이션(리소스관리,오토스케일링 등)도구 -> 쿠버네티스
  • 12factors(헤로쿠) msa구성의 최소의 규칙? -> 최근엔 15 factors 로 증가함.

MSA 아키텍처 도식화

그림1 inner 아키텍처 -> 스프링기반으로 개발된 프로그램들
outer 아키텍처 -> 이너아키텍처를 구성하는데 있어필요한 요소들을 구성하는 것

CNCF 표준구성요소 경로 - MSA를 구성할 수 있는 요소들에대한 정보사이트

https://landscape.cncf.io/

MSA에서 자주 사용되는 기반기술 리스트

그림2

Spring cloud에서의 MSA간 통신방법 2가지

  1. RestTemplate
  2. feign Client(좀더 간단함)
    //feign Client 예시코드
    @FeignClient("sotres")
     public interface StoreClient{
     @RequestMapping(method=RequestMethod.GET, value="/stores")
     List<Store> getStores();
    

6월 14일

  1. MSA 의 대한 개념
  2. 실습 시작 -> JDK설치, Maven, spring유레카 서버, 유레카클라이언트
  3. 각각의 서비스를 띄우면서 스케일 아웃 작업
  4. API Gateway (zuul은 사용불가됨) ->스프링클라우드 게이트웨이를 쓰게됨최근엔

자료설치 경로 4일간

git clone https://github.com/joneconsulting/koscom-msa.git

api 게이트웨이에서 로드밸런싱 설정하는 uri 설정

11

api 게이트웨이 분산처리는 서비스의 uri name을 기준으로 분배처리할 수 있다. name 을기준으로 포워딩처리 가능 0번포트설정시 자동으로 라운드로빈 분배처리됨.

유레카서버에 api게이트웨이를 띄우고 -> 서비스1, 2 분배처리 까지 띄운것 까지 결과물

444 5-bd22-a23be99af70b.PNG)

msa에서는 사이드카 기능 제공 개별의msa에필요한 공통분모구성가능 예시)인증,권한 등 - >(AOP와 같은맥락)

6월 15일 수

  1. api 게이트웨이 리마인드
  2. e-commerce 애플리케이션 개념

도커

  • 컨테이너 레지스트리(AWS ECR과 동일)

쿠버네티스(오케스트레이션)

  • 워커노드역할
  • 쿠버네티스 클러스터
  • 리소스관리

모니터링

  • 프로메테우스
  • 그라파나

주문정보또는 DB정보 전달목적

  • 카프카 메세지큐 사용

1.userService 로직 구현 마이크로서비스 내부에 사용될 스프링부트의 유저 서비스 시스템 구현

  • jpa ,h2
  • 스프링시큐리티
  • jwt
  • bootstrap.yml «<구성정보를 관리하는 통합 경로설정

포스트맨 CURL 대신씀

포스트맨으로 통신여부 테스트 확인 됨 이번에 공부해볼것 각 기능 사용방법 포스트맨 테스트케이스

인증처리할때 jwt 토큰을 통해 처리하였음.

  • 토큰 유효기간으로 유효성 검증
  1. 유저 로그인 로직MSA
  2. 상품 리스트 카탈로그 MSA
  3. 주문서비스 카탈로그 MSA

상호간의 토큰값을 기준으로 로그인부터 주문까지 처리 테스트 완료

  1. 로그인한다. -> 로그인했을때 생성되는 jwt 토큰을 리턴받는다
  2. 카탈로그쪽
  3. 오더서비스 주문넣을때 jwt 토큰값을 uri에포함하여 던지면 해당 유저정보로 주문을 넣은 것이 처리됨.
    tmi -> 로그인정보는 최초 apigateway에서만 처리하고 이후 msa는 jwt정보로 처리함.

중요!!! MSA에서 인증처리할 때

기존의 모놀리틱에서는 아이디패스워드 정보로 로그인할 경우 세션 ID가 발급되어 진행되지만 MSA에서는 세션과 쿠키를 활용할수없기때문에 토큰기반으로 구성해서 인증을해야함 https://jwt.io/

MSA 최종 주문처리 테스트

configuration service 세션 && 스프링클라우드 버스

  • 설정정보가 변경되었을때 다운타운 없이 MSA시스템들이 자동으로 반영될 수 있도록 구성하는방법

준비되야할 것 깃에 서버정보 프로퍼티정보 프로퍼티정보는 실시간으로 재기동없이 배포 반영가능함.

111

다만 동작 서비스 순서가있음

  1. 서비스 디스커버리
    1. 컨피그
  2. API 게이트웨이
  3. 각 MSA

스프링 클라우드 버스 적용방법

  • 준비사항 레빗엠큐 메세지큐

펍섭구조로 만약 컨피그정보가바뀌면 바꾸고난뒤 busconfig를 리프레쉬하면 각 구독한 msa 가 자동으로 재기동댐

카프카는 데이터처리할때 용도 레빗엠큐는 단순 메세지 전송 목적

레빗엠큐 설치에앞서 윈10에서는 까다로워서 쉬운방법이있음.

# latest RabbitMQ 3.10
docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.10-management

도커통해 설치하면 쉬움 도커역시 윈도우에서는 힘듦 리눅스 설치

1.리눅스 설치

  1. 도커설치
  2. 레빗엠큐 설치

로컬호스트 디폴트 포트:15672

6월 16일

feignClient - 넷플릭스 라이브러리로 REstTemplate

@FeignClient

feginhcliet

C:\Work\kafka\bin\windows

포스트맨 테스트 uri 샘플 코드 - 프론트엔드 개발을안했기때문에 포스트맨으로 데이터 테스트

  • 전체 유저조회 http://localhost:8000/user-service/users
  • 빈즈 테스트 http://localhost:8000/user-service/actuator/beans -카탈로그목록조회 http://localhost:8000/catalog-service/catalogs -유저로그인 (유저정보 같이 던져야함) http://localhost:8000/user-service/login -유저토큰인증( http://127.0.0.1:8000/user-service/users/1d66f622-8db7-4dc6-b3c7-825f50dfe151

http://127.0.0.1:8000/order-service/8f5b72ac-2e84-4df6-97e8-e32de10727cd

http://127.0.0.1:8000/actuator/refresh

http://localhost:8000/user-service/users

http://localhost:8888/decrypt

http://127.0.0.1:8000/order-service/1d66f622-8db7-4dc6-b3c7-825f50dfe151/orders

http://127.0.0.1:8000/order-service/08ab4d52-a9a3-4207-93ae-d79966f6c838/orders

데이터 동기화 방법

단일 마이크로서비스에서 스케일아웃될 경우 데이터처리가 문제가 된다 이를 극복하기 위해 카프카를 통해 데이터를 동기화 한다.

카프카기능중 소스커넥터기능이 DB의변경점을 캐치해 TOPIC을

소스커넥트 -> 연결된 데이터베이스의변경점이발생한경우를 캐치해 데이터를 취합 싱크커넥트 - > 원하는쪽으로 카프카가 전송

카프카 사용하려면 주키퍼가 있어 기동됨.

주키퍼

  • 메타데이터 저장
  • 컨트롤러 정보 저장 주키퍼실행1

주키퍼 실행 카프카실행 도커로 주키퍼 실행할때 깃허브 주키퍼 소스보고 배포하면댐 다운 카파카종료 주키퍼종료 순차적으로해야됨.

아마존EC2 서버에 도커상에 주키퍼, 카프카, 레빗엠큐 모두실행완료

카프카,레빗엠큐  주키퍼 도커 실행 완료

윈도우에서는 카프카 토픽 삭제하면 뻑남 리눅스는 토픽삭제상관없음.

아마존 리눅스에 붙음.

도커 가이드

docker run -it –rm –name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.10-management

-d옵션 백그라운드 doceker images 이미지목록

docker ps 프로세스 docker ps -a 전체 프로세스

spring cloud busrefresh

준비재료 Rabbitmq -> 도커 -> 리눅스 spring-cloud-amqp-bus 공통의 서버 정보를 재기동없이 재갱신시켜주는 기술

장애처리 파트 -»» 히스트릭스(옛) -> 리실리언스4j(최근)

  • 기존 넷플릭스 대신 사용되는 항목들 1
  1. 서킷브레이커
  2. 리실리언스4j

MSA 모니터링 시스템 구축

4444444444 386bade.png)

  1. 지프킨 -트레이싱 (트위터에서만듦)
    • span id 매우중요
    • trace id 매우중요
  2. spring cloud sleuth 분산추적기능 지원

22222

6월 17일 교육

  • CI/CD 배포

파이프라인

  1. 소스코드 -> git ->젠킨스? -> docker image(레지스트리)-> dockerfile->

클러스터도 쿠버네티스가 지원함.

도커관련

  • 도커 브릿지네트워크 공부«< 브릿지드라이버 (가상아이피)-문제 ip주소 제어가힘들어짐 또는 host 포트포워딩작업해야됨.

테스트환경에서의 네트워크 연결 주의사항

네트워크 로컬에서는 단순히 localhost로 통일되서 쓰면되지만
실제 운영서버에서는 네트워크 연결구성이 아주 중요해짐

  • 문제 예시 1 : 유레카 서버의 대상 ip가 localhost가아니기때문
  • 문제 예시 2 : 대역대가 다를 경우 ip대역대를 맞춰줘야함.
  • 문제 예시 3 : 그렇다고 고정IP를쓰면안됨, 왜냐 스케일링작업에따라 동적으로 ip가 할당되야하기때문에
  • 해결방안 : 프로퍼티정보를 하드코딩하지않고 동적으로 처리해서 네트워크를 변경해주면 된다(재기동필요없이 배포가 되기때문)

CI/CD 배포파이프라인 젠킨스 사용안함 그냥 쌩짜로 테스트

  1. docker에 체크아웃하고
  2. 도커파일편집하고
  3. 메이븐 컴파일 패키지 mvn clean compile package -DskipTests=true

소스 ->깃 ->깃허브 -> docker -> docker file -> 새로운대상서버에 배포 ->기동

docker run –d --name rabbitmq --network ecommerce-network \
-p 15672:15672 –p 5672:5672 –p 15671:15671 –p 5671:5671 –p 4369:4369 \
-e RABBITMQ_DEFAULT_USER=guest \ -e RABBIT_MQ_DEFAULT_PASS=guest \
rabbitmq:management

docker inspect rabbitmq

docker network create ecommerce-network 

mvn clean compile package -DskipTests=true 


cd /usr/local/src
sudo wget https://downloads.apache.org/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.tar.gz   
sudo tar -xf apache-maven-3.2.5-bin.tar.gz 
sudo mv apache-maven-3.2.5/ apache-maven/
cd /etc/profile.d/
sudo vi maven.sh
sudo chmod +x maven.sh
source /etc/profile.d/maven.sh
mvn --version

//6번줄 maven.sh 내용임
# Apache Maven Environment Variables
# MAVEN_HOME for Maven 1 - M2_HOME for Maven 2
export M2_HOME=/usr/local/src/apache-maven
export PATH=${M2_HOME}/bin:${PATH}

docker run -d -p 8888:8888 --network ecommerce-network \
-e "spring.rabbitmq.host=rabbitmq" \
-e "spring.profiles.active=default" \
--name config-service edowon0623/config-service:1.0 

docker run -d -p 8000:8000 --network ecommerce-network \
-e "spring.cloud.config.uri=http://config-service:8888" \
-e "spring.rabbitmq.host=rabbitmq" \
-e "eureka.client.serviceUrl.defaultZone=http://discovery-service:8761/eureka/" \
--name apigateway-service \
orm6711/apigateway-service:1.0


![image](https://user-images.githubusercontent.com/12209348/174225289-80103711-e901-4cc9-ad95-cc56a9dd51a0.png)





도커 네트워크 카프카 주키퍼용 서브넷마스크지정(고정아이피) 해야됨 모든시스템 선결적으로 먼저띄워야함.

중요!

기존에 사용하던 네트워크구조가 잘못짜여졌거나 옮길때 사용됨. docker network connect 명령어는 네트워크를 다른 네트워크쪽으로 옮길수있는명령어이다.

//기존 네트워크에서 타네트워크로 옮기는 예시 코드, 옮기게되면 기존것을 지워준다.
docker network connect ecommerce-network2 rabbitmq

//서비스 뺄때 디스커넥트
docker network disconnect ecommerce-network2 rabbitmq

네트워크 지정한목록조회
docker network ls

docker network inspect rabbitmq 

docker 내 띄운 서비스 목록 
172.21.0.2/16   rabbitmq
172.21.0.3/16   config-service 
172.21.0.4/16   service-discovery
172.21.0.5/16   apigateway-sevice
172.21.0.6/16   zipkin
172.21.0.7/16   user-service
172.21.0.8/16   order-service
172.21.0.9/16   catalog-sevice
172.21.0.100/16 zookeeper (고정아이피)
172.21.0.101/16 kafka (고정아이피)

//로그보기
docker logs 서비스네임 

//docker-compose logs 명령어는 연계된 모든 프로세스의 각구분된 로그들을 확인할 수 있다.

롤백 트랜잭션 대안 SAGA pattern에 대해 스터디

two-phase commit

CI/CD

// 금번실습 컴포즈 코드 이것만있으면 컴포즈 기동으로 모든 프로세스 통합으로 실행가능함.
version: '2'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - "2181:2181"
    networks:
      my-network:
        ipv4_address: 172.21.0.100
  kafka:
    # build: .
    image: wurstmeister/kafka
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_HOST_NAME: 172.21.0.101
      KAFKA_CREATE_TOPICS: "test:1:1"
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - zookeeper
    networks:
      my-network:
        ipv4_address: 172.21.0.101

  rabbitmq:
    image: rabbitmq:management
    ports:
      - "15671:15671"
      - "15672:15672"
      - "5671:5671"
      - "5672:5672"
      - "4369:4369"
    environment:
      RABBITMQ_DEFAULT_USER: guest
      RABBITMQ_DEFAULT_PASS: guest
    networks:
      my-network:

  config-service:
    image: edowon0623/config-service:1.0
    ports:
      - "8888:8888"
    environment:
      spring.rabbitmq.host: rabbitmq
      spring.profiles.active: default
    depends_on:
      - rabbitmq
    networks:
      my-network:

  service-discovery:
    image: edowon0623/service-discovery:1.0
    ports:
      - "8761:8761"
    environment:
      spring.cloud.config.uri: http://config-service:8888
    depends_on:
      - config-service
    networks:
      my-network:

  apigateway-service:
    image: edowon0623/apigateway-service:1.0
    ports:
      - "8000:8000"
    environment:
      spring.cloud.config.uri: http://config-service:8888
      spring.rabbitmq.host: rabbitmq
      eureka.client.serviceUrl.defaultZone: http://service-discovery:8761/eureka/
    depends_on:
      - service-discovery
    networks:
      my-network:

  zipkin:
    image: openzipkin/zipkin
    ports:
      - "9411:9411"
    networks:
      my-network:

  user-service:
    image: edowon0623/user-service:1.0
    environment:
      spring.cloud.config.uri: http://config-service:8888
      spring.rabbitmq.host: rabbitmq
      spring.zipkin.base-url: http://zipkin:9411
      eureka.client.serviceUrl.defaultZone: http://service-discovery:8761/eureka/
      logging.file: /api-logs/users-ws.log
    depends_on:
      - apigateway-service
    networks:
      my-network:

  order-service:
    image: edowon0623/order-service:1.0
    environment:
      spring.cloud.config.uri: http://config-service:8888
      spring.rabbitmq.host: rabbitmq
      spring.zipkin.base-url: http://zipkin:9411
      eureka.client.serviceUrl.defaultZone: http://service-discovery:8761/eureka/
      logging.file: /api-logs/orders-ws.log
    depends_on:
      - apigateway-service
    networks:
      my-network:

  catalog-service:
    image: edowon0623/catalog-service:1.0
    environment:
      spring.cloud.config.uri: http://config-service:8888
      spring.rabbitmq.host: rabbitmq
      spring.zipkin.base-url: http://zipkin:9411
      eureka.client.serviceUrl.defaultZone: http://service-discovery:8761/eureka/
      logging.file: /api-logs/catalogs-ws.log
    depends_on:
      - apigateway-service
    networks:
      my-network:

networks:
  my-network:
    external: true
    name: ecommerce-network2


Comments