Skip to content

CarToi/BE

Repository files navigation

새길 BE Repository


BE 아키텍처 BE ERD


1. 소개

새길은 2025 새만금 공공데이터 공모전 신규데이터 생산 부문에 참가한 웹 개발 프로젝트 출품작입니다.
사용자 맞춤형 문화 콘텐츠를 추천하고, 결과를 지도에 시각화하는 설문조사 데이터 수집 플랫폼입니다.
Java의 가상 스레드로 단일 프로세스에서 데이터 수집과 소비를 병렬 처리하며, 전략 패턴과 팩토리 메소드 패턴으로 유연성과 확장성을 갖췄습니다.
전체 구조는 Spring Boot의 DI / 비동기 처리를 기반으로 한 경량화된 저비용 & 고성능 서버 아키텍처를 지향합니다.


  • 🌐 배포 링크 : 설문조사 참여하기
  • 🛠️ 사용 스택 : Java 21, Spring Boot, Spring Data JPA, Spring Caffeine Cache, JUnit5, JMH, MySQL, Docker, Github Actions, AWS, CLOVA Studio 임베딩v1
  • 👥 참여 인원 : 총 4명 (BE 1, FE 2, UX/UI 1)
  • ⏳ 개발 기간 : 2025.06 ~ 2025.07
  • 📖 개발 일지 : 노션 참고

2. 수행 역할

(1) 멀티 스레드 기반 데이터 수집 & 소비 서버 설계

  • 단일 서버 프로세스 내에서 데이터 수집 파이프라인과 소비 처리를 멀티 스레드로 구현
  • API 호출 및 웹 크롤링 기반의 데이터 수집기 할당에 팩토리 메소드 패턴 적용
  • 유실율, 변환 속도를 고려한 임베딩 벡터 Float값 Byte 타입 변환 저장
  • 데이터 수집 스레드 상태 모니터링 및 수집기별 결과 디스코드 알람봇 구축
  • 수집 데이터 갱신 과정에서 데이터 조회 및 소비 안전을 위한 스왑 뷰 전략 도입

(2) 기능별 단위 테스트 및 주요 성능 벤치마킹

  • 서비스 기능별 단위 테스트코드 작성 100% 달성
  • 배포 시, 외부 API 및 크롤링 사전 연결 점검 테스트 구축
  • JMH 성능 계측으로 아키텍처 설계 근거 확보 및 처리 효율 3.5배 향상

(3) AWS 배포 자동화 및 실제 운영하며 데이터 생산

  • Dockerhub와 AWS EC2 인스턴스 연동 처리
  • Github Actions 스크립트 기반 테스트 및 배포 자동화
  • AWS IAM 권한 위임 스크립트를 통한 CI/CD 과정에서 EC2 IP 보안 확보

3. 서버 디렉토리 구조

펼쳐보기📁
src
├── jmh # 자바 벤치마킹 하네스
│   └── java
│       └── org
│           └── jun
│               └── saemangeum
│                   └── benchmark
│                       └── process
│                           ├── ContentCollectServiceBenchmark.java # 데이터 수집 벤치마크
│                           └── MockContentCollectServiceBenchmark.java
├── main # 메인 애플리케이션
│   ├── java
│   │   └── org
│   │       └── jun
│   │           └── saemangeum
│   │               ├── SaemangeumApplication.java
│   │               ├── consume # 데이터 소비 3계층 아키텍처
│   │               │   ├── config
│   │               │   │   └── CoordinateConfig.java
│   │               │   ├── controller
│   │               │   │   └── SurveyController.java
│   │               │   ├── domain
│   │               │   │   ├── dto
│   │               │   │   │   ├── AverageRequest.java
│   │               │   │   │   ├── Coordinate.java
│   │               │   │   │   ├── KakaoResponse.java
│   │               │   │   │   ├── RecommendationResponse.java
│   │               │   │   │   ├── SurveyCreateRequest.java
│   │               │   │   │   └── SurveyUpdateRequest.java
│   │               │   │   ├── entity
│   │               │   │   │   ├── RecommendationLog.java
│   │               │   │   │   └── Survey.java
│   │               │   │   └── swap
│   │               │   │       ├── ContentView.java
│   │               │   │       └── VectorView.java
│   │               │   ├── repository
│   │               │   │   ├── entity
│   │               │   │   │   ├── RecommendationLogRepository.java
│   │               │   │   │   └── SurveyRepository.java
│   │               │   │   └── swap
│   │               │   │       ├── ContentViewRepository.java
│   │               │   │       └── VectorViewRepository.java
│   │               │   ├── service
│   │               │   │   ├── application
│   │               │   │   │   └── SurveyRecommendationService.java
│   │               │   │   ├── domain
│   │               │   │   │   ├── RecommendationLogService.java
│   │               │   │   │   └── SurveyService.java
│   │               │   │   ├── strategy
│   │               │   │   │   ├── EmbeddingVectorStrategy.java
│   │               │   │   │   ├── StrategyContextHolder.java
│   │               │   │   │   ├── TableEmbeddingVectorStrategy.java
│   │               │   │   │   └── ViewEmbeddingVectorStrategy.java
│   │               │   │   └── swap
│   │               │   │       └── SwapViewService.java
│   │               │   └── util
│   │               │       ├── CoordinateCalculator.java
│   │               │       └── ViewJdbcUtil.java
│   │               │
│   │               ├── global # 공통 도메인 및 설정정보
│   │               │   ├── cache
│   │               │   │   ├── CacheExpirePolicy.java
│   │               │   │   ├── CacheNames.java
│   │               │   │   └── CacheType.java
│   │               │   ├── config
│   │               │   │   ├── CacheConfig.java
│   │               │   │   ├── GlobalExceptionHandler.java
│   │               │   │   ├── Initializer.java
│   │               │   │   └── WebConfig.java
│   │               │   ├── controller
│   │               │   │   └── DeployController.java
│   │               │   ├── domain
│   │               │   │   ├── Category.java
│   │               │   │   ├── CollectSource.java
│   │               │   │   ├── Content.java
│   │               │   │   ├── Count.java
│   │               │   │   ├── IContent.java
│   │               │   │   └── Vector.java
│   │               │   ├── exception
│   │               │   │   ├── ClientIdException.java
│   │               │   │   ├── ErrorResponse.java
│   │               │   │   └── SatisfactionsException.java
│   │               │   ├── repository
│   │               │   │   ├── ContentRepository.java
│   │               │   │   ├── CountRepository.java
│   │               │   │   └── VectorRepository.java
│   │               │   └── service
│   │               │       ├── ContentService.java
│   │               │       ├── CountService.java
│   │               │       └── VectorService.java
│   │               │
│   │               └── pipeline # 데이터 수집 및 전처리 파이프라인
│   │                   ├── application
│   │                   │   ├── alarm
│   │                   │   │   ├── AlarmBuilder.java
│   │                   │   │   └── AlarmProcess.java
│   │                   │   ├── collect
│   │                   │   │   ├── api
│   │                   │   │   │   ├── GimjeCultureCollector.java
│   │                   │   │   │   ├── GunsanCultureCollector.java
│   │                   │   │   │   ├── SmgEventCollector.java
│   │                   │   │   │   └── SmgFestivalCollector.java
│   │                   │   │   ├── base
│   │                   │   │   │   ├── CheckedSupplier.java
│   │                   │   │   │   ├── CrawlingCollector.java
│   │                   │   │   │   ├── OpenApiCollector.java
│   │                   │   │   │   └── Refiner.java
│   │                   │   │   └── crawl
│   │                   │   │       ├── ArchipelagoCollector.java
│   │                   │   │       ├── BuanCultureCollector.java
│   │                   │   │       ├── City.java
│   │                   │   │       ├── CityTourCollector.java
│   │                   │   │       ├── GunsanFestivalCollector.java
│   │                   │   │       └── SeawallTourCollector.java
│   │                   │   ├── dto
│   │                   │   │   ├── ErrorResponse.java
│   │                   │   │   ├── Event.java
│   │                   │   │   ├── EventResponse.java
│   │                   │   │   ├── Festival.java
│   │                   │   │   ├── FestivalResponse.java
│   │                   │   │   ├── GimjeCulture.java
│   │                   │   │   ├── GimjeCultureResponse.java
│   │                   │   │   ├── GunsanCulture.java
│   │                   │   │   ├── GunsanCultureResponse.java
│   │                   │   │   └── RefinedDataDTO.java
│   │                   │   ├── schedule
│   │                   │   │   └── PipelineScheduler.java
│   │                   │   ├── service
│   │                   │   │   ├── ContentCollectService.java
│   │                   │   │   ├── DataCountUpdateService.java
│   │                   │   │   ├── EmbeddingVectorService.java
│   │                   │   │   └── PipelineService.java
│   │                   │   └── util
│   │                   │       ├── TitleDuplicateChecker.java
│   │                   │       └── VectorCalculator.java
│   │                   ├── domain
│   │                   │   ├── entity
│   │                   │   │   ├── Alarm.java
│   │                   │   │   ├── AlarmMessage.java
│   │                   │   │   ├── AlarmPayload.java
│   │                   │   │   └── AlarmType.java
│   │                   │   └── service
│   │                   │       └── AlarmService.java
│   │                   ├── infrastructure
│   │                   │   ├── api
│   │                   │   │   ├── OpenApiClient.java
│   │                   │   │   └── VectorClient.java
│   │                   │   ├── config
│   │                   │   │   ├── AsyncConfig.java
│   │                   │   │   ├── DiscordConfig.java
│   │                   │   │   ├── OpenApiConfig.java
│   │                   │   │   ├── SeleniumConfig.java
│   │                   │   │   └── VectorConfig.java
│   │                   │   ├── dto
│   │                   │   │   ├── EmbeddingJob.java
│   │                   │   │   ├── EmbeddingRequest.java
│   │                   │   │   └── EmbeddingResponse.java
│   │                   │   └── queue
│   │                   │       ├── EmbeddingJobQueue.java
│   │                   │       ├── EmbeddingWorker.java
│   │                   │       └── EmbeddingWorkerService.java
│   │                   └── presentation
│   │                       └── DiscordMessageAlarm.java
│   │
│   └── resources
│       └── application.yml # 서버 설정 프로퍼티
│
└── test # 단위 테스트 및 통합 테스트
    └── java
        └── org
            └── jun
                └── saemangeum
                    ├── SaemangeumApplicationTests.java
                    ├── collect
                    │   ├── CrawlingCollectorTest.java
                    │   ├── FallbackTest.java
                    │   ├── OpenApiCollectorTest.java
                    │   └── TitleDuplicateCheckerTest.java
                    ├── connect
                    │   ├── CoordinateTest.java
                    │   ├── EmbeddingTest.java
                    │   ├── MonitoringTest.java
                    │   ├── OpenApiTest.java
                    │   └── SeleniumTest.java
                    └── service
                        ├── ContentCollectServiceTest.java
                        ├── DataUpdateTest.java
                        ├── StrategyConcurrencyTest.java
                        ├── StrategyPatternTest.java
                        └── ViewFunctionTest.java

4. 기타

(🔝 back to top)