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

2025. 2. 17. 17:20·AlgoMate
"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는 저장 및 관리 역할을 담당하는 구조가 확장성과 유지보수성 측면에서 더 유리함! 😎🔥

'AlgoMate' 카테고리의 다른 글

Selenium을 통한 크롤링 시, 마주하는 reCAPTCHA 해결기  (0) 2025.02.19
Redis만으로도 비동기 처리는 가능하잖아‼️ 근데 왜 Celery+Redis를 사용해야 할까  (0) 2025.02.18
🔑 크롤링&스크래핑에서 쿠키를 사용하여 로그인 상태 유지하기  (0) 2025.02.17
Celery + Redis vs Celery + RabbitMQ: 어떤 선택이 더 나을까?  (0) 2025.02.17
🚀 동적으로 파일을 제공하는 방법  (2) 2025.02.16
'AlgoMate' 카테고리의 다른 글
  • Selenium을 통한 크롤링 시, 마주하는 reCAPTCHA 해결기
  • Redis만으로도 비동기 처리는 가능하잖아‼️ 근데 왜 Celery+Redis를 사용해야 할까
  • 🔑 크롤링&스크래핑에서 쿠키를 사용하여 로그인 상태 유지하기
  • Celery + Redis vs Celery + RabbitMQ: 어떤 선택이 더 나을까?
SungHoJung
SungHoJung
  • SungHoJung
    HOLOUD
    SungHoJung
  • 전체
    오늘
    어제
    • 분류 전체보기 (40)
      • AlgoMate (13)
      • TroubleShooting (0)
      • 여러가지 모음집 (4)
      • Infra (17)
  • 링크

    • github
  • 인기 글

  • 태그

    스왑 메모리 설정
    크롤링한 데이터
    celery+rabbitmq
    로컬 서버와 통신
    ci-cd
    Kubernetes
    컨테이너 간 통신
    recaptcha 우회
    ECS
    k8s
    bypass recaptcha
    IAM
    AWS
    redis
    Celery
    docker-compose
    celery+redis
    host.docker.internal
    EC2
    메세지 브로커
  • hELLO· Designed By정상우.v4.10.3
SungHoJung
🚀 크롤링 서버 vs 메인 서버, 크롤링한 데이터를 어디서 저장해야 할까?
상단으로

티스토리툴바