티스토리 뷰
이번 시간에는 3가지 서비스를 한번에 배포하려합니다. 중복되는 내용이니 빠르게 코드만 첨부합니다.
#UserService
#Dockerfile
FROM openjdk:17-ea-11-jdk-slim
VOLUME /tmp
COPY target/userservice-1.0.jar UserService.jar
ENTRYPOINT ["java","-jar","UserService.jar"]
#WebSecurity IP 변경
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
//http.authorizeRequests().antMatchers("/users/**").permitAll();
http.authorizeRequests().antMatchers("/actuator/**").permitAll();
http.authorizeRequests().antMatchers("/**")
.hasIpAddress("172.18.0.5")
.and()
.addFilter(getAuthenticationFilter());
http.headers().frameOptions().disable();
}
#user-service.yml 변경
spring:
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:testdb
username: sa
password: '{cipher}AQA3Wlcwu01k0p9/hdLhSv5L/WKKo452yh576T+I/AV5kiNckUu6PBPdmetCB0zecb7AkoktLfqZPt6ziznW3slrKHkIb39vyQjFcn0wKTdp6t38e84uoQbWp5SH7BXsT3pTYrmSwPGDvgr3K3NgPAnfZ0zOntmjR/ImO1YetawqFD3OQUqVxMYB93l6z6lG92vSbZpRRp2tJ9lke1u6zeV+vG3tEeFuezk3nb/r8dk8SGtRjru41tUD/g0fQ9R3Rf/i/0Sly9eN9Q2NAAVJ1Be6ohOMexth1oSQoeKQqmwPVCXxwglpDWvntxfanmsK5oavLeOeglkoXFg9JWVst2A9hJHPke6jyTabzuiz+kv3gHcNrih9bJ9RrEifJ4Xl2a8='
token:
expiration_time: 864000000
secret: '{cipher}AQAIOA+faH9XEcX5usyT6e+7ahXOvdmcZtZHMHQyDznJQ21eXzGq11eXqWh7F8/zo2xywBQhSmCz3YbyT181IvPhUB9djzSiYyndedY/k1XX/1lr8a1eZ5QRJbQeuAawgPmeZpr2xb+/7egZw2uUZtzSZKS7xZHh9cXV218sAWteTOKP9Y0AzWuz0ZiV7CJhK9OuZvTBShIlF3Hfy1Umxdmy2AwSqNIEndH8RQer17CaI7fF/sdj41v6YECyL39jP5143aaUyxTt/qgw2RDgh9WrDNdH4LwavG4Pl7+9ob5PDcpZekmScPsXFouJTjGYaX4ICTk04FhoOgxt9ZSB0lBdruNTgzdEaDTE519BaF1EY8noii/4mQDDTIfkX/Gz4oZfHcz6JwhDHeHgKFmxRc4v'
gateway:
ip: 172.18.0.5
order_service:
url: http://ORDER-SERVICE/order-service/%s/orders
exception:
order_is_empty: hehe ezpz lemonsquizy
#jar file 생성
mvn clean compile package -DskipTests=true
#build Docker file
docker build --tag ggpark0315/user-service:1.0 .
#DockerRun
이제 도커파일을 실행할 예정인데 아래와 같은 커맨드로 실행해주세요. -e 옵션이 많은데 해당 옵션을 설정하는 방법은 저희가 기존에 작성한 application.yml을 보고, 수정해야할 환경설정값 ( ex: config url zipkin url 등)을 참조해서 설정하시면 됩니다. 마지막 부분은 자신이 생성한 user-service 이미지를 입력해주세여!
docker run -d --network ecommerce-network --name user-service -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://discovery-service:8761/eureka/" -e "logging.file=/api-logs/user-ws.log" ggpark0315/user-service2:1.1
#OrderService
#pom.xml
Version을 1.0으로 바꿔줍니다. 파일명의 길이를 줄여서 생산성을 높히기 위해서 입니다.
<groupId>com.example</groupId>
<artifactId>order-service</artifactId>
<version>1.0</version>
<name>order-service</name>
#application.yml
확인위해서 수정했던 datasource부분의 주석을 해제해 줍니다. 아래와 같이요!
datasource:
url: jdbc:mysql://localhost:3307/mydb
driver-class-name: org.mariadb.jdbc.Driver
username: root
password: test1357
#Kafka
다음으로는 Kafka에서 IP정보를 가져옵니다.
이유는 KafkaProducerConfig 클래스는 도커에서 수정할 수 없기에 다음과 같이 직접 수정해줘야 하기 때문입니다.
#172.18.0.101 로 수정 한 KafkaProducerConfig
package com.example.orderservice.messagequeue;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.EnableKafka;
import org.springframework.kafka.core.*;
import java.util.HashMap;
import java.util.Map;
@EnableKafka
@Configuration
public class KafkaProducerConfig {
@Bean
public ProducerFactory<String, String> producerFactory() {
Map<String, Object> properties = new HashMap<>();
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "172.18.0.101:9092");
properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
return new DefaultKafkaProducerFactory<>(properties);
}
@Bean
public KafkaTemplate<String,String> kafkaTemplate(){
return new KafkaTemplate<>(producerFactory());
}
}
#OrderController
다음으로는 Kafka와 연동을 위해 아래와 같이 작성해주세요 코드 전문입니다. 작성된 부분은 없고 주석 해제한 코드입니다.
package com.example.orderservice.controller;
import com.example.orderservice.dto.OrderDto;
import com.example.orderservice.jpa.OrderEntity;
import com.example.orderservice.messagequeue.KafkaProducer;
import com.example.orderservice.messagequeue.OrderProducer;
import com.example.orderservice.service.OrderService;
import com.example.orderservice.vo.RequestOrder;
import com.example.orderservice.vo.ResponseOrder;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/order-service")
public class OrderController {
Environment env;
OrderService orderService;
KafkaProducer kafkaProducer;
OrderProducer orderProducer;
@Autowired
public OrderController(Environment env,
OrderService orderService,
KafkaProducer kafkaProducer,
OrderProducer orderProducer){
this.env = env;
this.orderService = orderService;
this.kafkaProducer = kafkaProducer;
this.orderProducer = orderProducer;
}
@PostMapping("/{userId}/orders")
public ResponseEntity<ResponseOrder> createOrder(@PathVariable("userId") String userId,
@RequestBody RequestOrder orderDetails){
log.info("Before create orders data");
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
OrderDto orderDto = mapper.map(orderDetails, OrderDto.class);
orderDto.setUserId(userId);
OrderDto createdOrder = orderService.createOrder(orderDto);
ResponseOrder responseOrder = mapper.map(createdOrder,ResponseOrder.class);
// /*kafka*/
// orderDto.setOrderId(UUID.randomUUID().toString());
// orderDto.setTotalPrice(orderDetails.getQty() * orderDetails.getUnitPrice());
//
// /* send this order */
kafkaProducer.send("example-catalog-topic",orderDto);
// orderProducer.send("orders", orderDto);
//
//
// ResponseOrder responseOrder = mapper.map(orderDto,ResponseOrder.class);
log.info("Create orders data");
return ResponseEntity.status(HttpStatus.CREATED).body(responseOrder);
}
@GetMapping("/{userId}/orders")
public ResponseEntity<List<ResponseOrder>> getOrder(@PathVariable("userId") String userId) throws Exception{
log.info("Before retrieve orders data");
Iterable<OrderEntity> orderList = orderService.getOrdersByUserId(userId);
List<ResponseOrder> result = new ArrayList<>();
orderList.forEach(v->{
result.add(new ModelMapper().map(v,ResponseOrder.class));
});
// try{
// Thread.sleep(1000);
// throw new Exception("엄...");
// }catch(InterruptedException ex){
// log.warn(ex.getMessage());
// }
log.info("Add retrieved orders data");
return ResponseEntity.status(HttpStatus.OK).body(result);
}
}
#jar file build
mvn clean package -DskipTests=true
#Dockerfile
FROM openjdk:17-ea-11-jdk-slim
VOLUME /tmp
COPY target/order-service-1.0.jar OrderService.jar
ENTRYPOINT ["java","-jar","OrderService.jar"]
#Docker build
docker build --tag ggpark0315/order-service:1.0 .
#Push
docker push ggpark0315/order-service:1.0
#Docker run
docker run -d --network ecommerce-network --name order-service -e "spring.cloud.config.uri=http://config-service:8888" -e "spring.rabbitmq.host=rabbitmq" -e "spring.zipkin.base-url=http://zipkin:9411" -e "spring.datasource.url=jdbc:mariadb://mariadb:3306/mydb" -e "eureka.client.serviceUrl.defaultZone=http://discovery-service:8761/eureka/" -e "logging.file=/api-logs/order-ws.log" ggpark0315/order-service:1.0
이슈노트
대부분 호스트 문제로 접속이 안될 확률이 높습니다. 그래서 MariaDB에 직접 접속을 통해 권한을 부여해야 합니다. 커맨드에서 아래의 순서로 모든 포트에 권한을 부여해줍니다.
docker exec -it mariadb /bin/bash
mysql -h127.0.0.1 -uroot -p
//Enter Password
use mysql;
grant all privileges on *.* to 'root'@'%' identified by 'test1357';
flush privileges;
exit
#정상 구동 시
🍯작은 꿀통🍯
만약 컨테이너가 너무 꼬인다면 exited된 컨테이너는 다 지워버리는 커맨드에요!
docker ps -a -q -f status=exited
#CatalogService
#pom.xml
<groupId>com.example</groupId>
<artifactId>catalog-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>catalog-service</name>
#KafkaConsumerConfig
ip값만 변경해줍니다.
@Bean
public ConsumerFactory<String,String> consumerFactory(){
Map<String,Object> properties = new HashMap<>();
properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"172.18.0.101:9092");
properties.put(ConsumerConfig.GROUP_ID_CONFIG,"consumerGroupId");
properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,StringDeserializer.class);
return new DefaultKafkaConsumerFactory<>(properties);
}
#jar file build
mvn clean compile package -DskipTests=true
#Docker build
docker build --tag ggpark0315/catalog-service:1.0 .
#Docker push
docker push ggpark0315/catalog-service:1.0
#Docker run
docker run -d --network ecommerce-network --name catalog-service -e "spring.cloud.config.uri=http://config-service:8888" -e "spring.rabbitmq.host=rabbitmq" -e "eureka.client.serviceUrl.defaultZone=http://discovery-service:8761/eureka/" -e "logging.file=/api-logs/catalogs-ws.log" ggpark0315/catalog-service:1.0
모든 서비스를 Container 기동에 성공하셨다면, 아래의 주소로 접속해주세요
#127.0.0.1:8761
드디어 배포 작업까지 끝이 났습니다. 마지막 작업이었지만, 사실 중복작업이라 쓸말이 별로 없었습니다. 짧다면 짧고 길다면 긴 포스팅 이었고, 처음보다 훨씬많이 발전한 거 같아 기분이 좋습니다. 아직 걸음마를 뗐을 뿐이지만, 끝났다는 해방감이 기쁘네요. 혹시라도 나중에 제 글을 처음부터 같이 따라오신 분이 계시다면 저와 같은 기분일지도 모르겠습니다. 그럼 다음 포스팅에는 마지막으로 테스트를 하며 가벼운 마음으로 끝내도록 하겠습니다!!!
감사합니다
'웹 프로그래밍 > MSA 학개론' 카테고리의 다른 글
[MSA&Docker] 마지막 테스트. (0) | 2022.05.11 |
---|---|
[MSA&Docker] Prometheus + Grafana Container 화 (0) | 2022.05.10 |
[MSA&Docker] Zipkin Container 실행 (0) | 2022.05.10 |
[MSA&Docker] MariaDB Container화 (0) | 2022.05.09 |
[MSA & Docker] RabbitMQ Docker환경에서 설치 (0) | 2022.05.09 |
- Total
- Today
- Yesterday
- Logstash 활용
- zipkin
- git
- 루틴기록
- UserService
- producer
- Feign
- JWT
- 운동일기
- kafka
- Logstash to ElasticSearch
- MariaDB
- consumer
- springcloud
- rabbitmq
- 빅-오
- MSA
- config
- elasticSearch
- 미래의나에게동기부여
- docker
- 운동
- 오늘저녁 삼겹살
- Gateway
- Kafka Connect
- Spring + ELK
- github
- prometheus
- LoadBalancer
- ACTUATOR
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |