AlgoMate

🚀 크롤링 서버 vs 메인 서버, 크롤링한 데이터를 어디서 저장해야 할까?

SungHoJung 2025. 2. 17. 17:20
"FastAPI에서 크롤링한 데이터를 바로 저장할까? 아니면 메인 서버(Spring Boot)로 전송해서 저장할까?"
이 고민을 해결하기 위해 두 가지 방법을 비교해보려고 한다.

🔥 1. 프로젝트 개요

저는 FastAPI + Spring Boot를 활용하여 백준 정답 코드 추천 서비스를 개발하고 있습니다.
백준에서 크롤링한 정답 코드를 저장하는 과정에서 다음과 같은 고민이 생겼습니다.

FastAPI에서 크롤링한 데이터를 직접 저장하는 것이 좋을까?
아니면 FastAPI에서 크롤링한 후, 메인 서버(Spring Boot)로 전송해서 저장하는 것이 좋을까?

📌 이 포스팅에서는 두 가지 방식의 장단점을 비교하고, 최적의 방식을 찾아보려고 합니다.

 

2. 선택지 비교: FastAPI vs Spring Boot 저장 방식

크롤링한 데이터를 어디서 저장할지에 따라 다음 두 가지 방법이 있습니다.

방식  설명
 FastAPI에서 직접 저장 크롤링한 데이터를 FastAPI에서 바로 로컬에 저장하고, DB에도 반영
 Spring Boot로 전송 후 저장 FastAPI에서 크롤링 후, Spring Boot API로 데이터를 전송하여 저장

3. 방식 1: FastAPI에서 직접 저장

🔹 구조

[ FastAPI ]
  🔽
  - Selenium 크롤링 수행
  - 크롤링한 코드 데이터를 로컬 파일 저장 (`/solutions/`)
  - DB에 직접 반영 (SQLAlchemy 등 활용)

🔹 코드 구현 (FastAPI에서 직접 저장)

import os
from sqlalchemy.orm import Session
from models import Solution  # SQLAlchemy 모델
from database import get_db  # DB 세션 가져오기

def save_solution(problem_id, user_id, code_text, file_extension, db: Session):
    """ 크롤링한 코드를 로컬 저장 및 DB 반영 """
    base_save_directory = "solutions"
    base_problem_directory = os.path.join(base_save_directory, str(problem_id))

    # 폴더 생성
    os.makedirs(base_problem_directory, exist_ok=True)

    # 파일 저장
    file_path = os.path.join(base_problem_directory, f"{user_id}.{file_extension}")
    with open(file_path, "w", encoding="utf-8") as file:
        file.write(code_text)

    # DB 저장
    solution = Solution(problem_id=problem_id, user_id=user_id, file_path=file_path)
    db.add(solution)
    db.commit()

    print(f"✅ 저장 완료: {file_path}")

🔹 장점 & 단점

장점
✅ 빠름 → API 요청 없이 FastAPI 내에서 모든 데이터 저장
✅ 트래픽 감소 → 메인 서버(Spring Boot)로 API 요청이 필요 없음
✅ 구조가 단순 → FastAPI가 크롤링과 저장을 모두 담당하여 코드 관리가 쉬움

 

단점
🚨 FastAPI 부하 증가 → 크롤링과 저장을 모두 담당하면 서버 부담이 커질 수 있음
🚨 파일 저장 문제 → FastAPI 서버가 여러 개일 경우(로드 밸런싱 시) 저장된 파일이 여러 서버에 분산될 가능성이 있음

4. 방식 2: FastAPI는 크롤링만 담당하고, Spring Boot로 전송 후 저장

🔹 구조

[ FastAPI (크롤링 서버) ]
  🔽
  - Selenium 크롤링 수행
  - 크롤링한 코드 데이터를 Spring Boot로 전송 (`POST /api/save`)
  🔽
[ Spring Boot (메인 서버) ]
  - 파일 저장 (/solutions/)
  - DB 저장 (JPA 활용)

🔹 코드 구현 (FastAPI → Spring Boot로 전송)

1️⃣ FastAPI에서 크롤링 후 Spring Boot로 전송 (POST 요청)

import requests

def send_to_main_server(problem_id, user_id, code_text, file_extension):
    """ 크롤링한 데이터를 Spring Boot API로 전송 """
    api_url = "http://main-server.com/api/save"  # Spring Boot 서버 API URL
    
    payload = {
        "problem_id": problem_id,
        "user_id": user_id,
        "code": code_text,
        "file_extension": file_extension
    }
    
    try:
        response = requests.post(api_url, json=payload, timeout=10)
        if response.status_code == 200:
            print("✅ 저장 성공:", response.json())
        else:
            print("❌ 저장 실패:", response.text)
    except requests.exceptions.RequestException as e:
        print("🚨 요청 오류:", e)

2️⃣ Spring Boot에서 데이터 수신 및 저장 (@PostMapping)

@RestController
@RequestMapping("/api")
public class SolutionController {

    @PostMapping("/save")
    public ResponseEntity<?> saveSolution(@RequestBody SolutionRequest request) {
        // DB 저장
        solutionService.saveSolution(request);

        // 파일 저장
        String savePath = "/solutions/" + request.getProblemId() + "/" + request.getUserId() + "." + request.getFileExtension();
        try {
            Files.write(Paths.get(savePath), request.getCode().getBytes());
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("파일 저장 실패");
        }

        return ResponseEntity.ok("저장 완료");
    }
}

🔹 장점 & 단점

장점
✅ FastAPI 부하 감소 → FastAPI는 크롤링 전용 서버로 사용하고, 저장은 메인 서버(Spring Boot)에서 담당
✅ 파일 저장 일관성 유지 → 모든 파일을 한 곳(Spring Boot)에서 관리 가능
✅ 확장 가능 → 크롤링 서버(FastAPI)와 메인 서버(Spring Boot)를 독립적으로 확장 가능

 

단점
🚨 API 요청 부담 → 크롤링 후 메인 서버로 HTTP 요청을 보내는 과정에서 지연 발생 가능
🚨 Spring Boot에서 추가 개발 필요 → 파일 저장 및 DB 반영을 위한 API 개발 필요

 

🚀 5. 최종 결론: 어느 방식이 더 좋을까?

FastAPI에서 직접 저장Spring Boot로 전송 후 저장

속도 🔥 빠름 (API 호출 없음) 🐢 느림 (API 요청 필요)
서버 부하 🚨 FastAPI에 부하 증가 ✅ 메인 서버(Spring Boot)로 부하 분산
파일 관리 ❌ 여러 FastAPI 인스턴스가 있을 경우 저장 위치 불명확 ✅ 한 곳(Spring Boot)에서 정리 가능
확장성 ❌ FastAPI가 너무 많은 작업을 함 ✅ Spring Boot로 분리하여 확장 가능

 

📌 결론: FastAPI는 크롤링 전용, Spring Boot에서 저장하는 방식이 확장성과 유지보수 측면에서 유리!

FastAPI 부하 감소 → 크롤링만 담당, 저장 및 DB 처리는 Spring Boot에서
파일 저장 일관성 유지 → 모든 파일을 한 곳(Spring Boot)에서 관리 가능
확장 가능 → 크롤링 서버(FastAPI)와 메인 서버(Spring Boot)를 독립적으로 스케일링 가능

 

🚀 최종 추천 아키텍처

[ FastAPI (크롤링 서버) ]
  🔽
  - Selenium 크롤링 수행
  - 크롤링한 코드 데이터를 Spring Boot로 전송 (`POST /api/save`)
  🔽
[ Spring Boot (메인 서버) ]
  - DB 저장
  - 파일 저장 (/solutions/ 폴더)

 

📌 FastAPI는 크롤링 전용, Spring Boot는 저장 및 관리 역할을 담당하는 구조가 확장성과 유지보수성 측면에서 더 유리함! 😎🔥