Browse Source

feat: docker test 환경 구축

- 현 구현한 것으로는 drone 데이터가 초당 100건 정도 수용할 수 있을 정도
  테스트 환경은 macos m3 core 1개와 memory 512MB(jvm 123.75MB)를 활용
feature/socket
지대한 6 months ago
parent
commit
87cbef018e
  1. 2
      .gitignore
  2. 5
      app/kac-app/Dockerfile
  3. 31
      app/kac-app/src/main/java/kr/co/palnet/kac/app/config/AppReadyEvent.java
  4. 5
      app/kac-socket-app/Dockerfile
  5. 3
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/command/impl/AdsbDroneCommandImpl.java
  6. 1
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/command/impl/AntosDroneCommandImpl.java
  7. 7
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/command/impl/SandboxDroneCommandImpl.java
  8. 15
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/config/AppReadyEvent.java
  9. 10
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/config/AsyncConfig.java
  10. 5
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/storage/DroneStorage.java
  11. 8
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/service/KacAppService.java
  12. 2
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/service/WebSocketService.java
  13. 5
      app/kac-websocket-app/Dockerfile
  14. 1
      app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/controller/SocketReceiverController.java
  15. 15
      app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/core/config/AppReadyEvent.java
  16. 25
      docker-compose.yml
  17. 3
      http-client/http/ws.http

2
.gitignore vendored

@ -43,3 +43,5 @@ out/
logs/
logs/**
### local ###
/.java-version

5
app/kac-app/Dockerfile

@ -1,9 +1,12 @@
FROM openjdk:21
ENV TZ=Asia/Seoul
#ENV JAVA_OPTS="-Xms512M -Xmx512M"
ENV JAVA_OPTS=""
EXPOSE 8000
WORKDIR /app
ENTRYPOINT ["java","-jar","/app/kac-app-1.0.0.jar"]
#ENTRYPOINT ["java","-jar","/app/kac-app-1.0.0.jar"]
CMD java $JAVA_OPTS -jar /app/kac-app-1.0.0.jar

31
app/kac-app/src/main/java/kr/co/palnet/kac/app/config/AppReadyEvent.java

@ -0,0 +1,31 @@
package kr.co.palnet.kac.app.config;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
@Slf4j
@RequiredArgsConstructor
@Component
public class AppReadyEvent implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
try {
float mb = 1024f * 1024f;
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
log.info("current heap memory init(xms): {}mb, max(xmx): {}mb", memoryBean.getHeapMemoryUsage().getInit() / mb, memoryBean.getHeapMemoryUsage().getMax() / mb);
for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) {
log.info("Pool: {} (type {}) = {}", mp.getName(), mp.getType(), mp.getUsage().getMax() / mb);
}
} catch (Exception e) {
log.warn("when start app, not read jvm heap memory information.");
}
}
}

5
app/kac-socket-app/Dockerfile

@ -1,9 +1,12 @@
FROM openjdk:21
ENV TZ=Asia/Seoul
#ENV JAVA_OPTS="-Xms512M -Xmx512M"
ENV JAVA_OPTS=""
EXPOSE 8003
WORKDIR /app
ENTRYPOINT ["java","-jar","/app/kac-socket-app-1.0.0.jar"]
#ENTRYPOINT ["java",${JAVA_OPTS},"-jar","/app/kac-socket-app-1.0.0.jar"]
CMD java $JAVA_OPTS -jar /app/kac-socket-app-1.0.0.jar

3
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/command/impl/AdsbDroneCommandImpl.java

@ -115,6 +115,7 @@ public class AdsbDroneCommandImpl implements DroneCommand {
droneCacheStorage.put(drone.getObjectId(), drone);
}
// STEP 2. 이력 생성할 전문 전달 -> DRON의 대한 식별정보만 이력 관리
try {
// 저장 해 놓았다가 한거번에 전송 - 필요한 곳에 전송(HISTORY, UTM)
@ -128,7 +129,7 @@ public class AdsbDroneCommandImpl implements DroneCommand {
try {
if ("PA".equals(drone.getObjectId().substring(0, 2))) {
webSocketService.sendData(drone);
webSocketService.asyncSendData(drone);
}
} catch (Exception e) {
log.error("ERROR : {}", e.getMessage(), e);

1
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/command/impl/AntosDroneCommandImpl.java

@ -129,7 +129,6 @@ public class AntosDroneCommandImpl implements DroneCommand {
// STEP 3. 화면에 표출할 정보 WebSocket 전달
try {
if ("PA".equals(drone.getObjectId().substring(0, 2))) {
// webSocketService.sendData(drone);
webSocketService.asyncSendData(drone);
}
} catch (Exception e) {

7
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/command/impl/SandboxDroneCommandImpl.java

@ -120,24 +120,17 @@ public class SandboxDroneCommandImpl implements DroneCommand {
droneCacheStorage.put(drone.getObjectId(), drone);
}
// STEP 2. 이력 생성할 전문 전달 -> DRON의 대한 식별정보만 이력 관리
try {
// kacAppService.sendData(drone);
// kacAppService.asyncSendData(drone);
// 저장 해 놓았다가 한거번에 전송 - 필요한 곳에 전송(HISTORY, UTM)
DroneStorage droneStorage = DroneStorage.getInstance();
droneStorage.add(drone);
} catch (Exception e) {
log.error("ERROR : {}", e.getMessage(), e);
}
// STEP 3. 화면에 표출할 정보 WebSocket 전달
try {
// webSocketService.sendData(drone);
webSocketService.asyncSendData(drone);
} catch (Exception e) {
log.error("ERROR : {}", e.getMessage(), e);

15
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/config/AppReadyEvent.java

@ -7,6 +7,10 @@ import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
@Slf4j
@RequiredArgsConstructor
@Component
@ -16,7 +20,16 @@ public class AppReadyEvent implements ApplicationListener<ApplicationReadyEvent>
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
log.debug(">>>> onApplicationEvent <<<<<");
try {
float mb = 1024f * 1024f;
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
log.info("current heap memory init(xms): {}mb, max(xmx): {}mb", memoryBean.getHeapMemoryUsage().getInit() / mb, memoryBean.getHeapMemoryUsage().getMax() / mb);
for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) {
log.info("Pool: {} (type {}) = {}", mp.getName(), mp.getType(), mp.getUsage().getMax() / mb);
}
} catch (Exception e) {
log.warn("when start app, not read jvm heap memory information.");
}
socketServer.start();
}
}

10
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/config/AsyncConfig.java

@ -17,9 +17,9 @@ public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(100);
executor.setCorePoolSize(20);
executor.setMaxPoolSize(100);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("th-async-default-");
executor.initialize();
return executor;
@ -34,8 +34,8 @@ public class AsyncConfig implements AsyncConfigurer {
public Executor restClientThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(100);
executor.setQueueCapacity(500);
executor.setMaxPoolSize(1000);
executor.setQueueCapacity(1000);
executor.setThreadNamePrefix("th-async-rc-");
executor.initialize();
return executor;

5
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/storage/DroneStorage.java

@ -82,9 +82,10 @@ public class DroneStorage {
Instant compareTime = Instant.now().minusSeconds(60);
// 마지막 데이터가 1분 이상된 데이터라면 삭제
DroneDto lastDronDto = list.stream().toList().getLast();
DroneDto lastDroneDto = list.stream().toList().getLast();
// DroneDto lastDroneDto = list.stream().toList().get(list.size() - 1);
if ((lastDronDto.isSendHistroy() && lastDronDto.isSendUtm()) || compareTime.isAfter(lastDronDto.getRegDt())) {
if ((lastDroneDto.isSendHistroy() && lastDroneDto.isSendUtm()) || compareTime.isAfter(lastDroneDto.getRegDt())) {
// list.remove(lastDronDto);
droneMap.remove(objectId);
continue;

8
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/service/KacAppService.java

@ -7,7 +7,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
@ -58,7 +57,7 @@ public class KacAppService {
sendData(dto);
}
public boolean sendDataAll(Map<String, List<DroneDto>> history){
public boolean sendDataAll(Map<String, List<DroneDto>> history) {
RestClient client = getRestClient();
ResponseEntity<Void> resp = client.post()
.uri(SEND_HISTORY_ALL)
@ -66,10 +65,7 @@ public class KacAppService {
.body(history)
.retrieve()
.toBodilessEntity();
if(resp.getStatusCode() == HttpStatus.OK){
return true;
}
return false;
return resp.getStatusCode() == HttpStatus.OK;
}
private RestClient getRestClient() {

2
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/service/WebSocketService.java

@ -36,7 +36,7 @@ public class WebSocketService {
.toBodilessEntity();
}
@Async
@Async("restClientThreadPoolTaskExecutor")
public void asyncSendData(DroneDto dto) {
sendData(dto);
}

5
app/kac-websocket-app/Dockerfile

@ -1,10 +1,13 @@
FROM openjdk:21
ENV TZ=Asia/Seoul
#ENV JAVA_OPTS="-Xms512M -Xmx512M"
ENV JAVA_OPTS=""
EXPOSE 8001
EXPOSE 8002
WORKDIR /app
ENTRYPOINT ["java","-jar","/app/kac-websocket-app-1.0.0.jar"]
#ENTRYPOINT ["java","-jar","/app/kac-websocket-app-1.0.0.jar"]
CMD java $JAVA_OPTS -jar /app/kac-websocket-app-1.0.0.jar

1
app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/controller/SocketReceiverController.java

@ -24,7 +24,6 @@ public class SocketReceiverController {
@PostMapping("/drone")
public ResponseEntity<Void> receiver(@RequestBody DroneDto droneDto) {
log.debug("websocket message receiver : {}", droneDto);
DroneControlDto history = controlService.dronDtoToControlDtoConvert(droneDto);
// DRON의 대한 식별정보만 이력 관리

15
app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/core/config/AppReadyEvent.java

@ -7,6 +7,10 @@ import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
@Slf4j
@RequiredArgsConstructor
@Component
@ -16,7 +20,16 @@ public class AppReadyEvent implements ApplicationListener<ApplicationReadyEvent>
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
log.debug(">>>> onApplicationEvent <<<<<");
try {
float mb = 1024f * 1024f;
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
log.info("current heap memory init(xms): {}mb, max(xmx): {}mb", memoryBean.getHeapMemoryUsage().getInit() / mb, memoryBean.getHeapMemoryUsage().getMax() / mb);
for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) {
log.info("Pool: {} (type {}) = {}", mp.getName(), mp.getType(), mp.getUsage().getMax() / mb);
}
} catch (Exception e) {
log.warn("when start app, not read jvm heap memory information.");
}
socketServer.start();
}
}

25
docker-compose.yml

@ -33,13 +33,18 @@ services:
- pav_kac_networks
volumes:
- ./app/kac-app/build/libs:/app
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
kac-socket:
kac-socket-app:
build:
context: ./app/kac-socket-app
dockerfile: Dockerfile
depends_on:
- database
# depends_on:
# - database
ports:
- 18003:8003
container_name: kac-socket-app
@ -49,13 +54,18 @@ services:
- pav_kac_networks
volumes:
- ./app/kac-socket-app/build/libs:/app
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
kac-websocket-app:
build:
context: ./app/kac-websocket-app
dockerfile: Dockerfile
depends_on:
- database
# depends_on:
# - database
ports:
- 18001:8001
- 18002:8002
@ -66,6 +76,11 @@ services:
- pav_kac_networks
volumes:
- ./app/kac-websocket-app/build/libs:/app
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
networks: #네트워크 설정
pav_kac_networks:

3
http-client/http/ws.http

@ -10,6 +10,9 @@ WEBSOCKET {{wsHost}}/ws
WEBSOCKET {{wsHost}}/ws
### docker websocket
WEBSOCKET ws://localhost:18001/ws
### 기존 websocket
WEBSOCKET ws://localhost:8081/ws
#Content-Type: application-json

Loading…
Cancel
Save