EarlyExpress는 전국 17개 지역 물류 허브를 중심으로 운영되는 기업용 물류 플랫폼입니다.
이 저장소는 그 중 허브 관리 & 허브 경로 계산(Hub Route) 기능을 담당하는 허브 서비스입니다.
- EarlyExpress 전체 아키텍처에서의 허브 서비스 역할
- 프로젝트 일정
- 허브 서비스 기능 상세
- 허브 라우트 계산 로직
- API 명세
- 기술 스택 & 시스템 구성
- 향후 고도화 계획
- 트러블슈팅
이 허브 서비스는 EarlyExpress에서 다음의 중심 도메인을 담당합니다.
- 전국 17개 물류 허브의 CRUD 관리
- 허브 간 연결 정보(중앙허브 포함)를 기반으로 허브 라우트 계산
- 출발 허브 ~ 실수령지 간 최적 경로 조회 API 제공
- 다른 서비스(배송 관리, 주문 관리 등)가 허브/경로 정보를 참조할 수 있도록 API 제공
전국 17개 허브를 데이터로 정의하고 관리하는 기능
- 허브 생성(Create)
- 허브 수정(Update)
- 허브 삭제(Delete)
- 허브 조회(Read)
- 전체 조회
- 단건 조회 (ID 또는 코드 기반)
허브 간 연결 관계와 중앙 허브를 기반으로 실제 배송 경로를 결정하는 도메인
- 출발 허브 → 실수령지 최적 경로 계산
- 10km 이내면 직배송
- 아니면 **3개 중앙허브(경기남부·대전·대구)**를 기준으로 경로 탐색
- 하버사인(Haversine): 허브/실수령지의 위도·경도를 이용해 두 지점 간 구면 거리(km) 계산
- 다익스트라(Dijkstra): 17개 허브를 노드(Node), 허브 간 연결 관계를 엣지(Edge) 로 모델링 각 엣지 가중치 = 허브 간 거리(하버사인으로 계산)
- 전국 17개 허브 중 3개 중앙 허브를 기준으로 네트워크를 구성
- 경기남부
- 대전광역시
- 대구광역시센터
- 모든 허브는 3개의 중앙 허브를 거쳐 목적지로 배송됩니다.
- 예) 서울 → 부산
서울 → 경기남부 → 대구 → 부산 - 예) 세종 → 서울
세종 → 대전 → 경기남부 → 서울
- 예) 서울 → 부산
- 각 허브는 아래와 같이 인접 중앙 허브와 연결되어 있습니다.
- 경기남부(5): 경기북부, 서울, 인천, 경기남부, 강원도
- 대전(7): 충청남도, 충청북도, 세종, 대전, 전라북도, 광주, 전라남도
- 대구(5): 경상북도, 대구, 경상남도, 부산, 울산
- 출발 허브와 실수령지(좌표 기준)가 10km 이내일 경우 → 허브 경유 없이 바로 배송
{
"orderId": "1",
"originHubId": "2",
"destinationHubId": "15",
"routeHubs": [
"2",
"1",
"15"
],
"requiresHubDelivery": true,
"estimatedDistance": 131.994649993564,
"routeInfoJson": "{\"segments\":
[
{\"fromHubId\":\"2\",\"toHubId\":\"1\",\"distance\":93.3227241863231},
{\"fromHubId\":\"1\",\"toHubId\":\"15\",\"distance\":38.671925807240896}
],
\"hubs\":[
{\"hubId\":\"2\",\"name\":\"대전광역시 센터\",\"address\":\"대전 서구 둔산로 100\",\"latitude\":127.384633005948,\"longitude\":36.3503849976553},
{\"hubId\":\"1\",\"name\":\"경기 남부 센터\",\"address\":\"경기도 이천시 덕평로 257-21\",\"latitude\":127.375050006958,\"longitude\":37.1896213142136},
{\"hubId\":\"15\",\"name\":\"서울특별시 센터\",\"address\":\"서울특별시 송파구 송파대로 55\",\"latitude\":127.123621185562,\"longitude\":37.4742027808565}]}"
}
| 기능 | Method | URL |
|---|---|---|
| 허브 생성 | POST | /web/master/hubs |
| 허브 전체 조회 | GET | /web/all/hubs |
| 허브 단건 조회 | GET | web/all/hubs/{id} |
| 허브 수정 | PUT | /web/master/hubs/{id} |
| 허브 삭제 | DELETE | /web/master/hubs/{id} |
| 기능 | Method | URL |
|---|---|---|
| 최적 경로 조회 | GET | /internal/route/calculate |
- Java 21
- Spring Boot 3.x
- Spring Data JPA
- Redis (허브 상태 캐싱)
- Docker
- Docker Compose
- 허브별 처리량, 입·출고량, 지연률 수집
- 허브 간 연결 상태(네트워크 그래프) 실시간 점검
- 장애·지연 발생 구간 감지 및 알림
- 운영 대시보드용 실시간 API 제공
이슈
- Dijkstra가 잘못된 허브 경로를 선택함
- 허브 간 연결 데이터 누락으로 인해 경로 계산이 비정상 동작
원인
- Dijkstra 입력값에 좌표를 사용하여 허브 ID 기반 그래프와 매칭 불가
- 허브 간 연결·거리 정보가 누락되거나 단방향으로만 존재
해결
- 모든 허브 쌍 거리 계산 → HubRouteEntity로 양방향 테이블화
- Dijkstra 입력값을 허브 ID로 통일하고 목적지 허브 계산을 서비스 단일화
결과
- 허브 경유 규칙 정상 반영
- 최적 경로가 안정적으로 계산됨
이슈
- 허브 수정/삭제 후 전체 조회 결과가 캐시로 인해 갱신되지 않음
원인
- 전체 조회 캐시는 고정 키를 사용하지만, CRUD 작업은 개별 키만 삭제
해결
- CRUD 시 전체 조회 캐시도 함께 삭제
@CacheEvict(value = "hub", key = "'allHubMasterResponse'")- 또는
allEntries = true
결과
- CRUD 이후 조회 시 항상 최신 허브 데이터 제공