[E-commerce App] Docker Container를 이용한 애플리케이션 배포 - 7. Order Microservice
이전 글에 이어서 진행해보자.
Docker Container
11. order-service
1) application.yml
의 datasource 변경
이전에 사용하던 h2 데이터베이스가 아니라 mysql을 사용할 것이다.
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Seoul&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: 1234 # mysql docker 컨테이너 생성 시 설정한 패스워드
나의 경우에는 기존에 MariaDB를 쓰다가 MySQL로 변경한 것이기 때문에 MySQL dependency도 추가했다.
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
2) KafkaProducerConfig.java
변경
KafkaProducerConfig
에는 order-service
에서 Kafka를 이용해 메시지를 전송할 때의 설정 정보가 담겨있다.
이전에 127.0.0.1
로 지정한 kafka broker의 IP Address를,
kafka broker 컨테이너의 IP Address로 변경하자.
아래 커맨드로 kafka broker 컨테이너의 IP Address를 확인하자.
$ docker network inspect ecommerce-network
kafka 컨테이너의 IP Address는 172.18.0.101
이다.
참고
KafkaProducerConfig.java
에 정확한 IP Address를 명시해야 하기 때문에,
이전에 kafka 컨테이너를 기동할 때에docker-compose.yml
를 이용해 IP Address를 수동으로 지정했었다.
변경 전
변경 후
3) OrderController.java
원래는 주문 정보를 orderDto
에 저장하고, 저장된 정보가 컨트롤러에 반영될 수 있도록 kafka라는 메시지 큐잉 서버를 이용했었다.
그런데 지금은 orderProducer
부분은 주석처리 하고, jpa를 이용해 주문 정보를 db에 저장할 것이다.
그 이유는, 지금은 여러 개의 order-service
를 기동하지 않을 것이기 때문에, 여러 db 정보를 단일화 할 필요가 없기 때문이다.
(추후에 kafka connect와 kafka sink connect를 사용하고 싶다면 jpa 부분을 주석처리하고, 나머지를 주석 해제하면 된다.)
@RestController
@RequestMapping("/order-service")
@Slf4j
public class OrderController {
...
@PostMapping("/{userId}/orders")
public ResponseEntity<ResponseOrder> createOrder(@PathVariable("userId") String userId, @RequestBody RequestOrder requestOrder) {
log.info("Before add orders data");
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
OrderDto orderDto = mapper.map(requestOrder, OrderDto.class);
orderDto.setUserId(userId);
/* jpa */
OrderDto createdOrder = orderService.createOrder(orderDto);
ResponseOrder responseOrder = mapper.map(createdOrder, ResponseOrder.class);
/* kafka */
// orderDto.setOrderId(UUID.randomUUID().toString());
// orderDto.setTotalPrice(requestOrder.getQty() * requestOrder.getUnitPrice());
/* send this order to the kafka */
kafkaProducer.send("example-catalog-topic", orderDto); // 토픽 이름은 catalog-service 의 KafkaConsumer 에서 확인할 수 있다.
// orderProducer.send("orders", orderDto);
// ResponseOrder responseOrder = mapper.map(orderDto, ResponseOrder.class);
log.info("After added orders data");
return ResponseEntity.status(HttpStatus.CREATED).body(responseOrder);
}
}
4) Dockerfile을 통해 이미지 만들기
FROM openjdk:17-ea-11-jdk-slim
VOLUME /tmp
COPY target/order-service-0.0.1-SNAPSHOT.jar OrderService.jar
ENTRYPOINT ["java","-jar","OrderService.jar"]
5) 이미지 빌드 및 도커 허브에 업로드
# 최신 버전으로 컴파일
$ mvn clean compile package -DskipTests=true
# clean은 기존 파일을 지운다.
# package 옵션으로 jar 파일까지 생성할 수 있다.
# 테스트 코드는 skip
# 이미지 파일 빌드
$ docker build -t ln8847/order-service:1.0 .
# 생성된 이미지 확인
$ docker images | grep order-service
# 도커 허브에 업로드
$ docker push ln8847/order-service:1.0
6) 도커 컨테이너 실행
기존의 application.yml
에서 127.0.0.1
혹은 localhost
를 사용하고 있는 부분을 -e
옵션을 통해 도커 컨테이너의 이름으로 바꿔서 실행하자.
$ docker run -d --network ecommerce-network \
-e "spring.zipkin.base-url=http://zipkin:9411" \
-e "eureka.client.serviceUrl.defaultZone=http://service-discovery:8761/eureka/" \
-e "spring.datasource.url=jdbc:mysql://mysql:3306/mydb?serverTimezone=Asia/Seoul&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true" \
-e "logging.file=/api-logs/orders-ws.log" \
--name order-service \
ln8847/order-service:1.0
네트워크를 확인해보자.
$ docker network inspect ecommerce-network
로그를 확인해보자.
$ docker logs order-service
http://127.0.0.1:8761
에 접속해 order-service가 잘 등록되었는지 확인해보자.
참고
지금은 configuration 서버와 rabbitmq는 사용하지 않기 때문에 추가하지 않았지만,
나중에 사용하게 된다면 아래와 같이-e
옵션을 이용해 추가하면 된다.$ docker run -d --network ecommerce-network \ -e "spring.cloud.config.uri=http://config-service:8888" \ -e "spring.rabbitmq.host=rabbitmq" \ -e "spring.zipkin.base-url=http://zipkin:9411" \ -e "eureka.client.serviceUrl.defaultZone=http://service-discovery:8761/eureka/" \ -e "spring.datasource.url=jdbc:mysql://mysql:3306/mydb?serverTimezone=Asia/Seoul&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true" \ -e "logging.file=/api-logs/orders-ws.log" \ --name order-service \ ln8847/order-service:1.0
💛 개인 공부 기록용 블로그입니다. 👻