// apache kafka 라이브러리 : 메세징 서버
implementation 'org.springframework.kafka:spring-kafka'
=> 카프카 : 메세징 관리 프로그램 ( 수신자 <-> 송신자 )
=> MSA 환경에서는 송신자(spring), 수신자(spring)

-도커실행

-SimpleApprovalProducer
@Slf4j
@Service
public class SimpleApprovalProducer {
// 메세지 주제(제목):토픽(topic)
private static final String TOPIC = "simple-approval";
// TODO: 카프카에 메세지 보내는 클래스 정의
@Autowired
private KafkaTemplate<String, String > kafkaTemplate; // DI
// TODO: 메세지 전송 함수 정의
// => 카프카로 메세지 전송됨
public void sendMessage(String message) {
// 로깅
log.debug("SimpleApprovalProducer(결재 생산자) : " + message);
this.kafkaTemplate.send(TOPIC, message); // 카프카로 매개변수값 보내기
}
}

-SimpleConsumer

@Slf4j
@Service
public class SimpleConsumer {
// TODO: 1) 주문완료(50001) -> 결재완료(50002) 변경해야함(update)
// => 주문상태 컬럼 => 주문테이블에 있음
@Autowired
SimpleOrderService simpleOrderService; // DI
// TODO: 2) 카프카에서 보내줄 메세지 감시 하는 함수 정의
// 사용법 : @KafkaListener(topics = "주제명", groupId = "소비자그룹명")
@KafkaListener(topics = "simple-approval", groupId = "academy")
public void consume(String message) throws IOException {
// 로깅
log.debug("SimpleConsumer(소비자) : " + message);
// 메세지형태 : 개발자설계 => 주문번호:주문상태 => 예) 1:50001
if(message.contains(":") == true) {
String[] token = message.split(":"); // : 문자열 자름
int sono = Integer.parseInt(token[0]); // 정수변환, 주문번호
int orderStatus = Integer.parseInt(token[1]); // 정수변환, 주문상태
// 로깅 2
log.debug("주문번호 :" + sono);
log.debug("주문상태 :" + orderStatus);
// TODO: 50001(주문완료) -> 50002(결재완료) update
// TODO: 1) 주문 상세조회(주문번호(sono))
Optional<SimpleOrder> optionalSimpleOrder
= simpleOrderService.findById(sono);
SimpleOrder simpleOrder = optionalSimpleOrder.get();
// TODO: 50001(주문완료) -> 50002(결재완료) 객체의 속성 수정
simpleOrder.setOrderStatus(orderStatus); // 주문객체의 주문상태값 수정
// TODO: DB 의 주문테이블에 update
simpleOrderService.update(simpleOrder); // DB 수정
}
}
}
-SimpleApprovalService
// TODO: 카프카 사용 : 주문상태 변경용도 사용 - 50001(주문완료) -> 50002(결재완료)
// => 카프카 : 메세징 관리 프로그램 ( 수신자 <-> 송신자 )
// 1) 송신자 : 50001(주문완료) -> 50002(결재완료) 변경하라고 카프카에 메세지 전송
// 2) 수신자 : 주문테이블에 주문상태 컬럼 값을 변경(update)
// => MSA 환경에서는 송신자(spring:생산자(Producer), 수신자(spring:소비자(Consumer)
// 메세지 형태 설계 - 주문번호:주문상태
// 카프카 메세지 함수 : sendMessage(메세지) => 예) sendMessage("1:50002")
@Service
public class SimpleApprovalService {
@Autowired
private SimpleApprovalRepository simpleApprovalRepository; // DI
@Autowired
private SimpleApprovalProducer producer; // 카프카 생산자(송신자) DI
// TODO: 저장함수
// DTO : 1) 클래스 DTO : 프론트에서 객체 전송시 적당한 엔티티가 없으면 DTO 정의해서 사용
// 2) 인터페이스 DTO : 레파지토리에서 sql 결과로 담은 엔티티가 없으면 DTO 정의해서 사용
public SimpleApproval save(SimpleApproval simpleApproval) {
// DB 저장 함수 실행
SimpleApproval simpleApproval2
= simpleApprovalRepository.save(simpleApproval);
producer.sendMessage(simpleApproval2.getSono() + ":" + "50002");
return simpleApproval2;
}
}
-SimpleApprovalController
@Slf4j
@RestController
@RequestMapping("/api/shop")
public class SimpleApprovalController {
@Autowired
SimpleApprovalService simpleApprovalService; // DI
// 결재 저장 함수
@PostMapping("/simple-approval")
// 저장(insert) -> post 방식 -> @PostMapping
public ResponseEntity<Object> create(
@RequestBody SimpleApproval simpleApproval
) {
try {
// 저장 서비스 실행
SimpleApproval simpleApproval2
= simpleApprovalService.save(simpleApproval);
return new ResponseEntity<>(simpleApproval2, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

① 00_Webapps : 뷰 배포소스가 있는곳
② 01_Approval_Docker : spring 배포소스가 있는곳
1-1) Vue 배포본 실행 명령어 :
npm run build
2) 프론트 배포본 -> WebServer 프로그램에 배포됨
WebServer(웹서버) : html, js, css 등을 가지고 웹브라우저에 보여주는 전용
vs WAS(애플리케이션 서버) : 자바 프로그램을 웹에 게시하는 프로그램
WebServer(웹서버) 종류 : 아파치 웹서버(무료), nginx(무료, 성능 좋음)
WAS 종류 : 톰캣(무료), springboot(톰캣 내장되어 있음)
- 00_Webapps/conf/conf.d/default.conf : nginx 설정파일 준비
- 00_Webapps/html/*(뷰배포본복사) : 뷰(vue) 배포본 복사
- Dockerbuild : 도커 이미지 제작 파일(프론트엔드 도커파일)
-프론트 배포 (파일구조)




-> 도커파일 압축

# 도커 이미지 다운로드명 : nginx 1.23 버전 다운로드
FROM nginx:1.23.3
# 위에 있는 도커 이미지(nginx) 의 /etc/nginx/conf.d 폴더 삭제하겠음
RUN rm -rf /etc/nginx/conf.d
# 내가 만든 conf 폴더를 도커이미지(nginx) /etc/nginx 폴더에 복사하겠음
# 사용법: COPY 윈도우폴더 도커이미지폴더
COPY conf /etc/nginx
# 내가 만든 html 폴더를 도커이미지(nginx) /usr/share/nginx/html 폴더에 복사하겠음
# html 폴더 내용 : Vue 배포본
# 참고) nginx 웹서버의 기본 경로(/) : /usr/share/nginx/html
# 예) http://localhost:8080/ => nginx 의 기본경로
COPY html /usr/share/nginx/html
# nginx 웹서버를 실행 : 컨테이너가 실행될때 1번 실행
# nginx -g daemon off;
CMD ["nginx", "-g", "daemon off;"]
(오라클 라이브러리와 같이 키면 안됨)
C:\work\92_Wallet\Wallet_orcl
# 오라클 설정 ( 오라클 클라우드 전자지갑 설정 ) : log4j 적용
spring.datasource.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
# jdbc:log4jdbc:oracle:thin:@orcl_low?TNS_ADMIN=전자지갑경로
#spring.datasource.url=jdbc:log4jdbc:oracle:thin:@orcl_low?TNS_ADMIN=/Users/C:/work/92_Wallet/Wallet_orcl
spring.datasource.url=jdbc:log4jdbc:oracle:thin:@orcl_low?TNS_ADMIN=C:/work/92_Wallet/Wallet_orcl
spring.datasource.username=scott
spring.datasource.password=!Ds1234567890
# 클라우드 DB 접속 후 제한 : 1사람당 1개
spring.datasource.hikari.minimumIdle=1
spring.datasource.hikari.maximumPoolSize=1
spring.datasource.hikari.poolName=HikariPoolBooks
-SimpleProductController

- 인텔리제이에서 오른쪽 탭 gradle 아이콘 클릭
- tasks - build - bootWar : 배포 명령어(내장 톰캣과 함께 배포본 생성)
=> 배포본 경로 : 오른쪽 build - libs : 안에 배포본이 생성됨 xx.war

docker-compose up
