#book
스프링부트로 개발하는 MSA 컴포넌트
1장.마이크로 서비스 아키텍처
마이크로서비스 아키텍처는 기능 위주로 나뉜 여러 애플리케이션이 있고, 각각 독립된 데이터 저장소를 사용.
특징을 대표하는 키워드는 대규모 시스템, 분산처리 시스템, 시스템 확장 등.
서비스 지향 아키텍처와 관련이 많은데, 대규모 시스템을 설계할 때, 서비스 기능 단위로 시스템을 묶어 시스템 기능을 구현한 것을 의미.
각 마이크로서비스는 독립적으로 동작해야 하고, 다른 마이크로서비스에 의존을 최소화 해야 한다 → 느슨한 결합
기능과 성격에 맞게 잘 분리되어야 한다.
각 마이크로서비스 컴포넌트들은 기능을 연동할 때, API 를 통해 서로 데이터를 주고받는다.
→ API가 사용하는 네트워크 프로토콜이 성능 저하를 야기할 수 있으므로, 가벼워야 하며 직렬화(객체 → 바이트코드) , 역직렬화(바이트코드 → 객체) 의 과정을 이룬다 → JSON 형식을 주로 주고 받는다.
비동기 처리를 위해 AMQP 프로토콜인 kafka 또는 RabbitMq 를 이용한다. ( 메시지 큐 ) → 메시지 큐 시스템에 의존성이 생기는 단점도 있다.
마이크로 서비스의 특징
0. 잘 분리된 마이크로 서비스로 인한 탈중앙화
1. 대규모 시스템을 위한 아키텍처
2. 가벼운 네트워크 프로토콜
3. 느슨한 결합
4. 서비스 지향 아키텍처
⠀
장점
1. 독립성 : 다른 서비스와 의존성이 적음
2. 대용량의 데이터를 저장하고 처리하는데 비교적 자유 : 독립적 저장소
3. 시스템 장애에 견고 : 느슨한 결합
4. 서비스 배포 주기가 빠르다 : 각각의 서비스를 따로 배포가능 ( CI/CD 구축 필요 )
5. 큰 확장성 : 필요한 서비스만 확장 가능
⠀
단점
1. 개발하기 어렵다.
2. 운영하기 어렵다.
3. 설계하기 어렵다.
4. 여러가지 자동화 된 시스템이 필요 ( CI/CD , 모니터링 등 )
⠀
마이크로서비스의 설계 원칙과 이론
1. 서비스 세분화의 원칙
1. 비즈니스 기능
2. 성능
3. 메시지 크기
4. 트랜잭션
2. 도메인 주도 설계의 바운디드 컨텍스트
3. 단일 책임의 원칙
4. 가벼운 통신 프로토콜
5. 외부 공개 인터페이스
6. 마이크로서비스마다 독립된 데이터 저장소
• 서비스의 안정성 확보 : 고가용성 ( 지속적으로 서비스를 제공할 수 있는 것 )
한대의 애플리케이션으로 서비스 하는 것은 고가용성을 만족하지 못한다.
서버가 다운되거나 재배포 할 때, 그 시간동안 서비스가 불가능.
단일 장애 지점 ( Single Point Of Failure ) 이라고 한다.
고가용성을 확보하는 방법은 대중적으로 로드밸런서를 이용
스케일 아웃을 통해 서버를 늘리고 로드밸런서를 이용한다.
• 확장의 시작
리소스를 모니터링하는 자비스 / 애플리케이션 성능을 모니터링하는 스카우터
• 데이터 저장소의 확징
샤딩 : 데이터들을 샤드라는 단위로 여러 데이터베이스 인스턴스에 나누어 관리
로케이션 서비스를 이용하여 데이터를 재분배하는 리밸런싱 작업
• 마이크로서비스 아키텍처의 시작
서비스 전체 기능을 분류 → 서비스를 사용하는 대상으로 분류 → 도메인으로 구분
⠀
요소 애플리케이션
1. 코드베이스: 버전 관리되는 하나의 코드베이스와 다양한 배포 ( Properties , profile 기능 )
2. 의존성 : 명시적으로 선언할 수 있고 분리할 수 있는 의존성 ( Maven , Gradle )
3. 설정 : 환경 변수를 이용한 설정 ( java -Dspring.profiles.active=dev -jar cp.0.0.1.jar )
4. 지원 서비스 : 지원 서비스는 연결된 리소스로 처리( oracle , mysql , rest-api, rabbitmq 등 )
5. 빌드, 릴리즈 , 실행: 소스 빌드와 실행은 완전히 분리되어야 한다. ( 빌드 → 릴리즈 → 실행 / 컴파일 → jar 파일 생성 → java 커맨드를 이용한 실행 )
6. 프로세스 : 애플리케이션은 하나 이상의 무상태 프로세스로 실행되어야 한다.
7. 포트 바인딩 : 포트 바인딩을 통한 서비스 공개
8. 동시성 : 프로세스들을 통한 수평 확장
9. 폐기 가능 : 프로세스는 빠르게 시작해야 하고 안정적으로 종료해야 한다.
10. Dev 환경과 Production 환경 일치
11. 로드 : 로그는 이벤트 스트림으로 다룬다
12. Admin 프로세스 : 시스템 유지 보수를 위한 일회성 프로세스
스프링 애플리케이션 기본
스프링 빈 사용
• 스프링 빈 : 스프링 빈 컨테이너가 관리하는 순수 자바 객체를 의미
• 스프링 빈 컨테이너는 빈의 생명주기를 관리하는 역할을 한다.
• 스프링 애플리케이션을 실행하면 가장 먼저 실행된다.
• 참조되는 스프링 빈에 적합한 객체를 넣어주는 것을 주입이라고 한다.
• 스프링 빈 정의 방법
◦ 자바 설정 클래스에서 @Bean 에너테이션 사용
◦ XML 설정
◦ BeanDefinition 인터페이스를 구현
자바 설정
• 일정 시간마다 반복하는 작업은 스케줄링 기능을 활성화해서 사용
• ApplicationContext = 스프링 빈 컨테이너
◦ 애플리케이션을 설정하기 위해 가장 먼저 설정 파일을 로딩
• @Configuration
◦ 자바 설정을 포함하고 있는 자바 설정 클래스를 정의하는데 사용
• @ComponentScan
◦ 여러 자바 설정 클래스를 스캔
◦ value, basePackages 등 속성을 설정하지 않으면, @ComponentScan 이 정의된 클래스가 위치된 패키지가 기본값이 된다.
• @Import
◦ 자바 설정 클래스를 임포트
◦ 명시된 여러 개의 자바 설정 클래스를 하나의 그룹으로 묶는 역할
◦ ex) @Import(value={A.class, B.class}) 어노테이션을 ServerConfig 클래스에 정의
▪ ServerConfig 가 스프링 빈 컨테이너로 로딩되면 설정된 A,B 클래스도 로드 된다.
◦ @ComponentScan 처럼 설정 스프링 빈을 스캔하는 역할을 하는데 잘 사용되지 않는다.
스테레오 타입 스프링 빈 사용
• 스테레오 타입을 사용하면, 컴포넌트 스캔으로 스캔되고 스프링 빈으로 생성된다.
◦ @Component
◦ @Controller
◦ @Service
◦ @Repository
의존성 주입 ( 결합도는 낮추고 응집도를 높이자 )
• 외부(다른 클래스) 에서 객체를 생성하여 대상 객체에 넣어주는 것.
• 기본은 ApplicationContext 의 getBean() 메서드로 스프링 빈 객체를 가져와 사용했지만, 스프링 빈의 개수가 많아질 수록 getBean() 메서드를 사용하기 어렵다.
의존성
• 모델 요소 사이의 연관 관계를 의미
• 어떤 클래스가 다른 클래스를 사용하게 되면 두 클래스 사이에 의존성이 발생한다.
• 클래스보다 인터페이스나 추상클래스에 의존 관계를 맺는 것이 유연한 프로그램에 도움이 된다.
애너테이션 기반 설정의 의존성 주입
• @Autowired
◦ 의존성이 필요한 클래스 내부에 의존성 주입을 받는 곳을 표시
• @Qulifier
◦ 의존성을 주입할 스프링 빈 이름을 정의하는 역할
◦ 클래스 타입은 같지만 이름이 각자 다른 여러 스프링 빈 중 정의된 이름의 스프링 빈을 주입받기 위해 사용
@Qualifier("localDateTimeFormmer)
private Formatter formatter01;
...
public void setFormatter02(@Qualifier("localDateTimeFormtter") Formatter formatter) {
this.formatter02 = formatter;
}
• 생성자 주입 방식을 사용하자 → 테스트가 쉽다는 장점이 있다.
◦ 필드 주입 : 각각 @Autowired 설정 필요 , 스프링에서 공식적으로 지양
◦ 세터 주입 : set 메서드로 임의로 변경 가능
자바 설정의 의존성 주입
• @Configuration + @Bean 조합
• 스프링 빈 컨테이너의 의존성 분석 과정
1. ApllicationContext 가 실행될 때, Config 파일 읽기.
2. 설정된 파일을 ComponentScan 으로 스프링 빈을 로딩.
3. 스프링 빈 의존성 검사
4. 하위모듈에서 상위모듈 순서로 빈을 생성하고 의존성을 주입.
ApplicationContext = 스프링 빈 컨테이너
• 인터페이스이며, 다양한 구현 클래스가 기본으로 제공
• BeanFactory 를 상속받는다.
1. EnviromentCapable : 환경변수 추상화
2. ListableBeanFactory : 스프링 빈 리스트로 조회
3. HierarchicalBeanFactory : 부모 - 자식 관계 가능
4. MessageSourece : 국제화 메시지 기능
5. ApplicationEventPublisher : 이벤트 생성
6. ResourcePatternResolver : 패턴을 이용해 리소스 다루
스프링 빈 스코프
• 스프링 빈 객체를 생성하는 시간부터 만든 객체가 소멸되기 까지 그 기간을 빈 스코프라고 한다.
• 스코프 설정에 따라, 생성되는 시점과 소멸되는 시점이 상이하다.
◦ @Scope(“Singleton”) → 설정방법
◦ singleton : 기본값 , 스프링 빈 컨테이너에 단 하나만 생성해 여러곳에 주입.
◦ prototype : 의존성 주입을 할 때마다 새로운 객체를 생성해 주입.
◦ request : HTTP 요청을 할 때마다 새로운 객체 생성
◦ session : HTTP session 과 대응하는 새로운 객체 생성
◦ application : servlet 컨텍스트와 대응하는 새로운 객체 생성
◦ websocket : Web socket 과 대응하는 새로운 객체 생성
Singleton 기준
• new 연산자를 이용해서 새로운 객체를 만들 수 있지만, JVM 내부에는 여러 객체가 있을 수 있지만 스프링 컨테이너에는 오직 하나만 존재.
스프링 빈 생명주기 관리
• 스프링 빈을 생성 , 소멸하는 과정에서 개발자가 작성한 코드를 특정 시점에 호출하는 것을 콜백 함수라고 한다.
• @PostConstruct : 빈 생성 후
• @PreDestroy : 스프링 빈 종료 전
• 자바 설정의 @Bean 을 사용한 스프링 빈은 initMethod 속성을 사용
• 스테레오 타입 애너테이션을 사용한 스프링 빈은 @PostConstruct 를 사용
• 스프링 빈 컨테이너는 스프링 빈 설정을 먼저 로딩하기 때문에, 콜백 함수의 유무를 확인해 먼저 실행할 수 있다.
스프링 빈 고급 정의
• @Primary
◦ 클래스 타입이 같은 빈이 여러개 있을 경우, 우선순위 지정
• @Lazy
◦ 지연설정을 통해 해당 메소드가 실행될 때 빈 객체 생성 ( 의존성 주입 시점에 )
스프링 투어가 오해한 스프링 빈
• 스프링 빈 : 객체와 이름, 클래스 타입 정보가 스프링 컨테이너로 관리되는 객체
• 자바 빈 : 기본 생성자가와 getter / setter 패턴으로 내부에 접근 가능해야 하며, Serializable 를 구현해야 한다 .
• DTO : 데이터를 전달하는 객체
• 값 객체 ( Value ) : 특정 데이터를 추상화하여 데이터를 표현 ex ) Address
• 불변클래스
◦ final 로 선언
◦ 기본 생성자가 없도록 직접 생성자를 생성
◦ setter 사용 X
스프링 웹 MVC 개요
HTTP 프로토콜
• 모든 웹 애플리케이션은 HTTP 프로토콜을 사용하여 서비스를 제공.
• HTTP 프로토콜 스펙은 주고받는 데이터의 형식인 메시지라고 한다.
HTTP 상태 코드
1. 1xx : 임시 응답 , 클라이언트 요청은 성공 , 서버는 작업 중
2. 2xx : 성공
3. 3xx : 리다이렉션 → 클라이언트의 요청을 처리하는데 추가적인 작업 필요
4. 4xx : 클라이언트 에러
5. 5xx: : 서버 에러
HTTP 특징
• 비연결성
◦ HTTP 프로토콜이 클라이언트와 서버를 연결상태를 유지할 필요가 없다.
◦ 매번 새로운 연결을 한다.
◦ L4, L7 같은 로드밸런서가 모든 서버가 균등하게 요청을 받을 수 있도록 관리.
• 무상태
◦ 이전 요청에 의존하지 않는다.
◦ 클라이언트가 서버에 계속 요청해도 독립적으로 처리.
◦ 상태를 기억해야하는 인증/인가 인 경우, 쿠키나 세션을 사용.
스프링 웹 MVC 프레임워크
• 서블릿 : HTTP 프로토콜을 사용하여 데이터를 주고받는 서버용 프로그래밍 스펙
• 서블릿 애플리케이션들을 관리하고 실행하는 서버를 서블릿컨테이너 = WAS 라고 한다.
• HttpServletRequest
• HttpServletResponse
MVC 패턴
• Controller
• Model
• View
• IOC 컨테이너 = 스프링 컨테이너
• DispatcherServlet (프론트 컨트롤러) : 가장 앞에서 클라이언트의 요청을 받는다.
• DispatcherServlet 과 HadlerMapping(어느 컨트롤러로 보낼지) 는 스프링 빈을 찾아서 이용한다.
개발자와 스프링 프레임워크의 컴포넌트의 동작 과정
1. 개발자는 컨트롤러, 서비스, 리토지토리 클래스를 작성.
2. 스테레오 타입 에너테이션을 이요하여 스프링 빈으로 정의.
3. 스프링 애플리케이션이 기동하면 @RequestMapping 애너테이션의 속성 정보를 로딩.
4. DispatcherServlet 은 getHandler() 메서드를 이용해서 핸들러 정보를 획득.
5. RequestHandlerAdapter 를 이용해서 사용자의 요청을 알맞은 컨트롤러에게 전달.
서블릿 스택과 스레드 모델
• 기능(함수)의 종료 시점을 정확히 알 수 있는 방식을 동기식 프로그램이라고 한다.
◦ 다른 객체의 메서드를 실행하고 해당 결과를 받아 나머지 일 처리 가능.
◦ 각 기능의 종료시점에 동기화 된다.
• 반대로 알 수 없는 방식을 비동기식 프로그램이라고 한다.
◦ 콜백 형태의 함수를 전달
◦ 실행한 메서드가 종료되면 전달된 콜백 함수를 호출하는 과정으로 진행.
◦ 종료시점에 서로 동기화 되지 않는다.
• 서블릿 스택(WAS) 의 특징
◦ 사용자 요청부터 응답까지 하나의 스레드에서 모든 작업이 실행.
◦ 사용자 요청을 받고, 응답하는 주기와 스레드 생명주기가 일치.
◦ WAS 는 스레드 풀을 관리한다.
1. 사용자의 요청마다 스레드를 생성하는 것은 비효율적이므로, 미리 만들어두고 사용 후 반납.
◦ MessageConverter ( MVC 구조에서 HandlerAdapter 에서 작동 )
1. 요청에 대한 응답을 JSON 과 같은 다양한 타입으로 변환
2. content-type 을 참고해서 json converter, String converter 등을 자동으로 선택 후 실행
REST-API 설계
• 리소스 : HTTP URI / 행위 : HTTP Method / 표현 : JSON
• 리소스 이름은 동사보다 명사를 사용
• 리소스는 계층 관계를 가지므로, 복수 형태를 사용
• 리소스에 대한 행위는 GET POST PUT DELETE 를 기본으로 사용 + PATCH
REST-API 특성과 설계
• 무상태성 : HTTP 프로토콜의 특성과 같다.
• 일관성 : 같은 형태나 일관된 규칙
• 멱등성 : 한번 호출하든 여러번 호출하든 결과가 같다.
• 마셜링 : 객체 → JSON ( 직렬화 )
• 언마셜링 : JSON → 객체 ( 역직렬화 )
• @ResponseBody : 메시지 컨버터가 JSON 메시지로 마셜링 한다.
스프링 MVC를 이용한 REST-API 개발
• Jackson 라이브러리를 포함하고 있어, JSON 에 대한 처리에 대한 추가 설정이 필요없다.
'Books' 카테고리의 다른 글
스프링부트로 개발하는 MSA 컴포넌트 [7]장 (0) | 2023.08.26 |
---|---|
스프링부트로 개발하는 MSA 컴포넌트 [5]장 (0) | 2023.08.24 |
비전공자를 위한 이해할 수 있는 IT 지식 을 읽고, (0) | 2023.01.03 |
일 잘하는 사람은 단순하게 합니다 를 읽고, (0) | 2022.12.12 |
객체지향의 사실과 오해를 읽고, (0) | 2022.08.17 |
댓글