application.yml application-name.yml application-name-.yml
Application 상태 및 모니터링 End Point 통해서
ex. beans, health, env, metrics
remote git에 있는 설정정보를 commit 할 때마다 해당 endpoint를 통해서 모든 서버를 재가동하는것은 힘들다
http://localhost:8001/actuator/refresh
분산시스템의 노드(MicroService)를 메세지 브로커(RabittMQ)와 연결
설정 변경 사항을 Broadcast하게 AMQP 프로토콜을 통해 연결된 노드들에게 알려줌
Spring Cloud Bus 는 SpringBoot Application 에 부착되어 설정 정보를 지속적으로 반영할 수 있게 한다.
Cofig-Service
server:
port: 8888
spring:
application:
name: config-service
#모든 serivce에 rabbitmq 등록
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
cloud:
config:
server:
git:
uri: https://github.com/minsuk1/spring-cloud-config
# actuator에 busrefresh 등록
management:
endpoints:
web:
exposure:
include: health, busrefresh
개발자는 configuration file 을 remote repository 에 push 한다.
Spring Cloud Bus 가 Message Broker 로 변경된 설정 정보에 대한 Message 를 발행한다.
Message Broker는 설정 정보를 저장하고 있는다.
개발자가 설정 정보가 변경되었음을 Config Server 에게 알려준다.(localhost:8888/actuator/busrefresh)
Message Broker 가 해당 메시지를 Subscribing 하고 있는 Application 들 에게 Broadcasting 한다.
각각의 Application 은 Spring Cloud Bus 가 받은 설정 정보를 반영한다.
- 메시지 지향, 큐잉, 라우팅(P2P, Pub-Sub), 신뢰성, 보안
- Erlang, RabbitMQ에서 사용
- 분산형 스트리밍 플랫폼
- 대용량 데이터 처리 가능한 메시징 시스템
- RabbitMQ: 적은 데이터 안정적, 시스템 간 메시지 전달, 소비자 중심
- Kafka: 대용량 적합, Pub/Sub, Topic에 메시지 전달, 생산자 중심
RestTemplate Bean으로 등록하고 Service Layer에서 주입시켜줌
UserServiceImpl
@Override
public UserDto getUserByUserId(String userId) {
UserEntity userEntity = userRepository.findByUserId(userId);
if (userEntity == null)
throw new UsernameNotFoundException("User not found");
UserDto userDto = new ModelMapper().map(userEntity, UserDto.class);
String tmp = "http://127.0.0.1:8000/order-service/%s/orders";
String orderUrl = String.format(tmp, userId);
ResponseEntity<List<ResponseOrder>> orderListRespone =
restTemplate.exchange(orderUrl, HttpMethod.GET, null,
new ParameterizedTypeReference<List<ResponseOrder>>() {
});
List<ResponseOrder> orderList = orderListRespone.getBody();
userDto.setOrders(orderList);
return userDto;
}
Error 처리는 try catch문으로 해야 한다
OrderServiceClient
@FeignClient(name="order-service")
public interface OrderServiceClient {
@GetMapping("/order-service/{userId}/orders")
List<ResponseOrder> getOrders(@PathVariable String userId);
}
Client에 있는 Interface작성하려면 다른 서비스 내용을 잘 알아야 한다
FeignClient 라는 어노테이션을 이용하면 직접 해당 URL을 명시하지 않더라도 Eureka 에 register한 Instance 이름을 찾아서 URL을 매핑해준다. 이를 호출할 인터페이스를 생성해야한다
객체의 책임에 있어서 orderService 호출 부분이 바뀌면 client쪽이 바뀌면 된다. 해당 Service의 역할이 아니다
UserServiceImpl
@Override
public UserDto getUserByUserId(String userId) {
UserEntity userEntity = userRepository.findByUserId(userId);
if (userEntity == null)
throw new UsernameNotFoundException("User not found");
UserDto userDto = new ModelMapper().map(userEntity, UserDto.class);
List<ResponseOrder> orderList = orderServiceClient.getOrders(userId);
userDto.setOrders(orderList);
return userDto;
}
Error 처리: 예외 처리를 핸들링하는 방법을 ErrorDecoder로 제공
@Component
public class FeignErrorDecoder implements ErrorDecoder {
Environment env;
@Autowired
public FeignErrorDecoder(Environment env) {
this.env = env;
}
@Override
public Exception decode(String methodKey, Response response) {
switch(response.status()) {
case 400:
break;
case 404:
if (methodKey.contains("getOrders")) {
return new ResponseStatusException(HttpStatus.valueOf(response.status()),
env.getProperty("order_service.exception.orders_is_empty"));
}
break;
default:
return new Exception(response.reason());
}
return null;
}
}
Client에 있는 Interface작성하려면 다른 서비스 내용을 잘 알아야 한다
FeignClient 라는 어노테이션을 이용하면 직접 해당 URL을 명시하지 않더라도 Eureka 에 register한 Instance 이름을 찾아서 URL을 매핑해준다.
분산환경에서 시스템 병목 현상 파악
하나의 요청에 사용되는 작업 단위
트리 구조로 이루어진 span 셋
하나의 요청에 대한 같은 Trace ID 발급
OpenTracing은 애플리케이션 간 분산 추적을 위한 표준. 이 표준의 대표적인 구현체로 Jaeger와 Zipkin이 있지만 Zipkin이 구현하기 더 쉬움
시스템이 분산되있다보니 log 정보로 에러 원인을 찾기가 힘들다. Zipkin 사용하면 traceID과 Zipkin UI 통해 전체 흐름 찾을 수 있다. 웹 UI에서 ID를 넣고 검색하면 서비스 A와 B, C의 호출 순서를 타임라인과 함께 볼 수 있으며 에러가 발생한 구간도 명확하게 표시되는 것을 확인 가능하다
https://engineering.linecorp.com/ko/blog/line-ads-msa-opentracing-zipkin/
트랜잭션 관리, 동시성
변경된 데이터가 있으면 MQ통해 주고받는다
Reference
https://heodolf.tistory.com/49
https://wonit.tistory.com/512