마이크로서비스 아키텍처 기반의 ERP(Enterprise Resource Planning) 시스템입니다.
사원 관리, 결재 요청/처리, 실시간 알림 기능을 독립적인 서비스로 구성하였습니다.
┌──────────────────────┐
│ Client / Dashboard │
│ (Vue.js 3) │
└──────────┬───────────┘
│ HTTP / WebSocket
┌──────────▼───────────┐
│ NGINX Ingress (K8s) │
│ Host: erp.local │
└──────────┬───────────┘
┌────────────────────┼────────────────────┐
│ │ │
/api/employees /api/approvals /api/process
│ │ │
┌─────────▼────────┐ ┌───────▼────────┐ ┌───────▼────────┐
│ Employee Service │ │ Approval Request│ │Approval Process│
│ (MySQL, 8081) │ │(MongoDB, 8082) │ │ Service (8083) │
└─────────┬─────────┘ │ gRPC: 9082 │ │ gRPC: 9083 │
│ HTTP └───────┬────────┘ └───────┬────────┘
│ (사원 검증) │ gRPC 통신 │
└─────────────────────┴────────────────────┘
│ HTTP
┌───────────▼────────┐
│ Notification Service│
│ (WebSocket, 8084) │
└────────────────────┘
서비스
역할
포트
DB
Employee Service
사원 CRUD 및 유효성 검증
8081
MySQL
Approval Request Service
결재 요청 생성 및 결과 수신
8082 (HTTP), 9082 (gRPC)
MongoDB
Approval Processing Service
결재 큐 관리 및 승인/반려 처리
8083 (HTTP), 9083 (gRPC)
In-Memory
Notification Service
WebSocket 기반 실시간 알림
8084
-
분류
기술
Language
Java 17
Framework
Spring Boot 3.x / 4.x
Build Tool
Gradle 8.14
RPC
gRPC 1.68.2 + Protocol Buffers 4.29.2
HTTP Client
Spring WebFlux (WebClient)
WebSocket
Spring WebSocket
Database
MySQL 8.0, MongoDB 6.0
ORM
Spring Data JPA (MySQL), Spring Data MongoDB
Container
Docker (Multi-stage Build)
Orchestration
Kubernetes
Frontend
Vue.js 3 + Tailwind CSS
Utilities
Lombok, SLF4J
ERP/
├── employ-service/ # 사원 관리 서비스
│ └── src/main/java/com/erp/employservice/
│ ├── entity/Employee.java
│ ├── repository/EmployeeRepository.java
│ ├── service/EmployeeService.java
│ └── controller/EmployeeController.java
│
├── approval-request-service/ # 결재 요청 서비스
│ └── src/main/java/com/erp/approvalrequest/
│ ├── entity/ApprovalRequest.java
│ ├── service/ApprovalRequestService.java
│ ├── service/EmployeeValidationService.java
│ ├── grpc/ApprovalGrpcClient.java
│ └── controller/ApprovalRequestController.java
│
├── approval-processing-service/ # 결재 처리 서비스
│ └── src/main/java/com/erp/approvalprocessing/
│ ├── service/ProcessingService.java
│ ├── service/InMemoryQueueService.java
│ ├── grpc/ApprovalGrpcServer.java
│ └── grpc/ApprovalGrpcClient.java
│
├── notification-service/ # 알림 서비스
│ └── src/main/java/com/erp/notification/
│ ├── websocket/WebSocketHandler.java
│ ├── websocket/SessionManager.java
│ └── controller/NotificationController.java
│
├── Docker-files/ # 각 서비스 Dockerfile
├── k8s/ # Kubernetes 매니페스트
└── script/
├── build-push.sh # Docker 이미지 빌드 & 푸시
├── database/init_mysql.sql # MySQL 초기화 스크립트
└── erp-dashboard.html # 프론트엔드 대시보드
Method
Endpoint
설명
POST
/employees
사원 등록
GET
/employees
사원 목록 조회 (department, position 필터 지원)
GET
/employees/{id}
사원 단건 조회
PUT
/employees/{id}
사원 정보 수정
DELETE
/employees/{id}
사원 삭제
GET
/employees/{id}/exists
사원 존재 여부 확인 (타 서비스용)
Approval Request Service (:8082)
Method
Endpoint
설명
POST
/approvals
결재 요청 생성
GET
/approvals
결재 요청 목록 조회
GET
/approvals/{requestId}
결재 요청 단건 조회
Approval Processing Service (:8083)
Method
Endpoint
설명
GET
/process/pending/{approverId}
결재 대기 목록 조회
POST
/process/approve
결재 승인 / 반려 처리
GET
/process/queue-status
큐 상태 확인 (디버그용)
Notification Service (:8084)
Method
Endpoint
설명
POST
/notifications/send
특정 사용자에게 알림 전송
GET
/notifications/status
서비스 상태 및 연결 수 확인
GET
/notifications/check/{userId}
사용자 WebSocket 연결 여부 확인
WS
/ws/{userId}
WebSocket 연결 엔드포인트
CREATE TABLE employees (
id BIGINT AUTO_INCREMENT PRIMARY KEY ,
name VARCHAR (100 ) NOT NULL ,
department VARCHAR (100 ),
position VARCHAR (100 ),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
ApprovalRequest (MongoDB)
{
"requestId" : 1 ,
"requesterId" : 101 ,
"title" : " 출장 결재 요청" ,
"content" : " 2024년 3월 서울 출장 건" ,
"steps" : [
{ "step" : 1 , "approverId" : 102 , "status" : " approved" },
{ "step" : 2 , "approverId" : 103 , "status" : " pending" }
],
"finalStatus" : " in_progress" ,
"createdAt" : " 2024-03-01T09:00:00" ,
"updatedAt" : " 2024-03-01T10:30:00"
}
gRPC 메시지 (approval.proto)
service Approval {
rpc RequestApproval (ApprovalRequest ) returns (ApprovalResponse );
rpc ReturnApprovalResult (ApprovalResultRequest ) returns (ApprovalResultResponse );
}
1. 클라이언트 → Approval Request Service
POST /approvals (결재 요청 생성, 사원 유효성 검증 포함)
2. Approval Request Service → Approval Processing Service
gRPC: RequestApproval() (결재 정보 전달, 큐에 적재)
3. 결재자 → Approval Processing Service
GET /process/pending/{approverId} (내 결재 목록 확인)
POST /process/approve (승인 또는 반려)
4. Approval Processing Service → Approval Request Service
gRPC: ReturnApprovalResult() (결재 결과 반환)
5. Approval Request Service → Notification Service
HTTP POST /notifications/send (결재 결과 알림 전송)
6. Notification Service → 클라이언트
WebSocket Push (실시간 알림)
Docker & Docker Compose
Kubernetes (Minikube 또는 Docker Desktop K8s)
Java 17+, Gradle 8.14+
cd script
chmod +x build-push.sh
./build-push.sh
# Namespace 생성
kubectl apply -f k8s/namespace.yaml
# DB 배포 (MySQL, MongoDB)
kubectl apply -f k8s/mysql.yaml
kubectl apply -f k8s/mongodb.yaml
# 서비스 배포
kubectl apply -f k8s/employee-service.yaml
kubectl apply -f k8s/approval-request-service.yaml
kubectl apply -f k8s/approval-processing-service.yaml
kubectl apply -f k8s/notification-service.yaml
# Ingress 배포
kubectl apply -f k8s/ingress.yaml
서비스
ClusterIP 포트
NodePort
Employee
8081
30081
Approval Request
8082
30082
Approval Processing
8083
30083
Notification
8084
30084
Dashboard
80
30085
서비스
Node 그룹
CPU Request
CPU Limit
Memory Request
Memory Limit
Employee
service-group-1
250m
500m
256Mi
512Mi
Approval Request
service-group-2
250m
500m
256Mi
512Mi
Approval Processing
service-group-2
250m
500m
256Mi
512Mi
Notification
service-group-1
250m
500m
256Mi
512Mi
MySQL
database
-
-
-
5Gi PV
MongoDB
database
-
-
-
5Gi PV
모든 컨테이너는 non-root 유저(appuser) 로 실행
DB 접속 정보는 Kubernetes Secret 으로 관리
JVM 컨테이너 메모리 자동 감지 (-XX:+UseContainerSupport)
각 서비스에 Liveness / Readiness Health Check 적용
approval-request-service / approval-processing-service
implementation ' net.devh:grpc-spring-boot-starter:3.1.0.RELEASE'
implementation ' io.grpc:grpc-protobuf:1.68.2'
implementation ' com.google.protobuf:protobuf-java:4.29.2'
implementation ' org.springframework.boot:spring-boot-starter-data-jpa'
implementation ' com.mysql:mysql-connector-j'
implementation ' org.springframework.boot:spring-boot-starter-websocket'
implementation ' com.fasterxml.jackson.core:jackson-databind'