728x90
Communication Types
1. Cynchronous(동기) HTTP commuication
- 이는 클라이언트와 서버 간의 통신이 비동기적으로 이루어지는 경우를 나타냅니다.
- AMQP (Advanced Message Queuing Protocol)는 메시지 큐를 사용하여 메시지를 비동기적으로 전달하는 프로토콜입니다.
- 클라이언트가 요청을 보내면 서버는 해당 요청을 처리하고, 클라이언트는 서버의 응답을 기다리지 않고 다른 작업을 수행할 수 있습니다.
- 💡 Rest Template
💡 Rest Template
Rest Template은 Spring Framework에서 제공하는 클래스로, RESTful 웹 서비스와 통신하기 위한 도구입니다.일반적으로 Rest Template은 동기적인 방식으로 사용되며, 클라이언트는 요청을 보내고 해당 요청에 대한 응답을 기다립니다.Rest Template을 사용하는 경우 주로 동기적인 통신 방식을 사용하는 것이 일반적이지만, Spring에서는 비동기적인 통신을 지원하는 기능도 제공합니다. Rest Template은 동기적인 HTTP 통신을 수행하는 도구 중 하나
2. Asynchronous(비동기) communication over AMQP protocol
- 이는 클라이언트와 서버 간의 통신이 비동기적으로 이루어지는 경우를 나타냅니다.
- AMQP (Advanced Message Queuing Protocol)는 메시지 큐를 사용하여 메시지를 비동기적으로 전달하는 프로토콜입니다.
- 클라이언트가 요청을 보내면 서버는 해당 요청을 처리하고, 클라이언트는 서버의 응답을 기다리지 않고 다른 작업을 수행할 수 있습니다.
1. Rest Template
user-service
application.java
RestTemplate 빈 등록
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
// 생략...
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
UserController
// 사용자 ID로 조회
@GetMapping("/users/{userId}")
public ResponseEntity<ResponseUser> getUser(@PathVariable("userId") String userId) {
UserDto userDto = userService.getUserByUserId(userId);
ResponseUser returnValue = new ModelMapper().map(userDto, ResponseUser.class);
return ResponseEntity.status(HttpStatus.OK).body(returnValue);
}
UserServiceImpl
@Override
public UserDto getUserByUserId(String userId) {
UserEntity userEntity = userRepository.findAllByUserId(userId);
if (userEntity == null)
throw new UsernameNotFoundException("User not found");
UserDto userDto = new ModelMapper().map(userEntity, UserDto.class); // (바꾸고 싶은 변수, 바꾸고 싶은 "클래스")
// List<ResponseOrder> orders = new ArrayList<>();
// String orderUrl = "http://127.0.0.1:800/order-service/%s/orders"; // user-serivce.yml로 이동
String orderUrl = String.format(env.getProperty("order_service.url"), userId); // %s에 userId를 넣어주기 위해 String.format 사용
System.out.println(orderUrl);
ResponseEntity<List<ResponseOrder>> orderListResponse = restTemplate.exchange(orderUrl, HttpMethod.GET, null,
new ParameterizedTypeReference<List<ResponseOrder>>() {
});
List<ResponseOrder> orderList = orderListResponse.getBody();
userDto.setOrders(orderList);
return userDto;
}
ResponseOrder
package com.example.userservice.vo;
import lombok.Data;
import java.util.Date;
@Data
public class ResponseOrder {
private String productId;
private Integer qty;
private Integer unitPrice;
private Integer totalPrice;
private Date createdAt;
private String orderId;
}
user-servicer.yml
spring:
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:testDB
data-username: sa
data-password: '{cipher}AQCfbGd8zx2/cry7igIke3MwGjl6vqntSAao6GZ1fFIkV3IUvgpdtGXI1vpCgNy/3v5OlATUKeUu7NAy5nMzJhkv4Eyn+24sP6u4rlRn6zWoGGvXDc3EP+
//73Kxv0dO0nHp5kD3pq2bLT9MnOjmlCkcptr1jMPDrOPdQ8d5Rsgh+HaNdZuNHKzr2pgWd64bjzt6HlgDzNz3ntY41ojmWiecH/g0d4DShaUacZN2s9TwVKjxPDuiDXI9lr5ezGgJClx5hrXCMnWTLi
K9EpuLIrSaUAd3wXKC2vlUalWUEQ51tYtGg/taOi85Q3v3cVJiKEePVBX2AXZpx2Pf+IBZ2/YEbs/WqdvDt2Ns1rAnMOtR5wkZ3XzK/Kjoawcb3pWvKmE='
# data-password: 1234
# data-password: '{cipher}99ee6f49abfbcc00f273cb617bf88441879a71718d40d65427d2455018e2ba41'
token:
expiration_time: 86400000
secret: user_token_native_user_service_default
gateway:
ip: 192.168.0.106
order_service:
url: http://127.0.0.1:8000/order-service/%s/orders
order-service
OrderController
@RestController
@RequestMapping("/order-service")
public class OrderController {
// ..생략..
@GetMapping("/{userId}/orders")
public ResponseEntity<List<ResponseOrder>> getOrder(@PathVariable("userId") String userId) {
Iterable<OrderEntity> orderList = orderService.getOrdersByUserId(userId);
List<ResponseOrder> result = new ArrayList<>();
orderList.forEach(v -> result.add(new ModelMapper().map(v, ResponseOrder.class)));
return ResponseEntity.status(HttpStatus.OK).body(result);
}
// ..생략..
}
uri 바꾸기
ip주소나 포트번호가 변경되어도 uri값 변경없이, 마이크로 서비스 이름으로 사용 가능! 편하다!!!
💡 @LoadBalnced
자바의 스프링 프레임워크에서는 @LoadBalanced 어노테이션을 사용하여 RestTemplate이나 WebClient 등을 통해 특정 서비스를 호출할 때 로드 밸런싱을 자동으로 수행하도록 설정할 수 있습니다.
이는 서비스 디스커버리와 같은 기술과 결합하여 자동으로 서비스 간 통신을 관리하는 데 도움이 됩니다.
user-service.yml
order_service:
url: http://order-service/order-service/%s/orders
# http://127.0.0.1/order-service/%s/orders 에서 바꿈!
user-service
UserServiceApplication.java
@Bean
@LoadBalanced // 이거 추가!
public RestTemplate getRestTemplate() {
return new RestTemplate();
}