공공부하자개발 · 영어 학습 노트
자바
실무 확장Excel · 파일 업로드 · DB 연동0/22 완료
  • 01Excel(XLSX) 구조와 순수 JDK로 읽기/쓰기
  • 02Apache POI로 Excel 업로드/다운로드
  • 03파일 업로드/다운로드 서버 (HttpServer)
  • 04JDBC 기초와 트랜잭션 (H2)
  • 05MyBatis 어노테이션 매퍼로 쿼리 연동
  • 06MyBatis XML 매퍼 · Oracle 방언 · PageHelper · Spring Boot
  • 07REST API 서버와 JSON
  • 08Vue 3 SPA 와 Java 서버 연동
  • 09@Scheduled 운영
  • 10로깅 실무: 레벨·계층, MDC 추적, 예외·성능, 마스킹, 롤링, JSON 로그
  • 11외부 API 연동
  • 12테스트 실무
  • 13암호화·개인정보 보호
  • 14인코딩·한글 실무
  • 15@Transactional 심화
  • 16긴 작업 비동기 처리와 진행률
  • 17SFTP·FTP 파일 연계
  • 18로컬 캐시와 @Cacheable
  • 19메일·알림 발송
  • 20웹 보안 체크리스트
  • 21빌드 도구와 폐쇄망 의존성 반입
  • 22성능 측정: p50·p95·p99, 측정 계층, JFR, JMH 함정, 자체 부하 테스트, 병목 순위
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › 실무 확장 › 17 / 22

SFTP·FTP 파일 연계

연계 규격, 원자적 전송·마커 파일, 체크섬, 재처리·중복 방지, 키 인증, JSch
섹션 7진행 0 / 22
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6연습 문제7정리‹ 이전다음 ›

2. 핵심 원리

2.1 FTP vs FTPS vs SFTP

세 프로토콜은 이름은 비슷하지만 동작 방식이 다릅니다. 신규 연계는 특별한 사정이 없으면 SFTP 를 우선 검토합니다.

구분 전송 방식 특징
FTP 평문 인증정보·데이터 그대로 노출
FTP 포트 수동 모드도 방화벽 이슈 잦음
FTPS FTP + TLS 제어·데이터 채널 암호화, 포트 복잡
SFTP SSH 기반 22 포트 하나로 제어·데이터 통합

FTP 는 데이터 채널에 별도 포트를 쓰기 때문에 능동·수동 모드 방화벽 설정이 번거롭습니다. SFTP 는 SSH 세션 하나로 인증부터 파일 전송까지 처리해 방화벽 정책이 단순합니다. 대외 기관 연계 신규 건은 SFTP 를 우선 검토하고, FTP 는 상대가 이미 그렇게 운영 중일 때만 그대로 맞춥니다.

2.2 연계 규격서에 있어야 할 것

기관 간 연계는 코드로 합의하지 않고 문서(규격서)로 합의합니다. 규격서가 애매하면 운영 중 분쟁이 생기므로, 최소한 아래 항목은 명시돼야 합니다.

  • 업로드·다운로드 경로: /upload, /download 같은 절대 경로
  • 파일명 규칙: 예 YYYYMMDD_기관코드_순번.dat
  • 인코딩·개행·고정길이 여부: 14 인코딩 레슨 참조
  • 완료 신호: 마커 파일 이름, 또는 별도 완료 통지 방식
  • 보관·삭제 정책: 처리 후 원본 파일을 언제 지우는지

이 중 파일명 규칙과 완료 신호가 실제 코드에 직접 반영되는 부분입니다. 나머지는 운영 협의로 풀리지만, 이 둘은 배치 로직에 그대로 들어갑니다.

2.3 원자적 전송 — "쓰는 중" 사고를 막는 방법

파일 시스템에는 "다 쓸 때까지 안 보이게" 하는 기능이 없습니다. 그래서 임시 이름으로 올린 뒤 완료되면 정식 이름으로 바꾸는 방식을 씁니다. rename 은 같은 폴더 안에서 원자적으로 처리되므로, 수신 측이 폴링하는 순간에 절반만 쓰인 파일이 보일 일이 없습니다.

절차는 다음과 같습니다. 먼저 파일명.dat.tmp 로 업로드하고, 로컬 크기와 원격 크기를 비교해 전송이 온전한지 확인합니다. 그다음 .tmp 를 떼고 정식 이름으로 rename 하고, 마지막으로 파일명.dat.ok 같은 빈 마커 파일을 하나 더 올립니다. 수신 측은 데이터 파일이 아니라 마커 파일의 존재를 기준으로 처리 여부를 판단합니다.

마커 대신 파일명 확장자 자체를 바꾸는 방식(.uploading → .dat)도 같은 원리입니다. 어느 쪽이든 핵심은 "정식 이름으로 보이는 순간에는 이미 전송이 끝나 있어야 한다"는 것입니다.

2.4 수신 측 처리와 중복 방지

수신 측 배치는 폴더를 주기적으로 스캔하되, 마커가 있는 파일만 처리 대상으로 삼습니다. 처리한 파일은 원본 폴더에 그대로 두지 않고 processed/ 로 옮겨서, 다음 폴링에서 같은 파일을 다시 보지 않게 합니다.

그래도 네트워크 지연이나 재전송으로 같은 파일명이 다시 올라올 수 있습니다. 이 경우를 대비해 처리 이력을 별도로 남깁니다. 실무에서는 DB 테이블(파일명, 처리 시각, 결과)로 관리하고, 이 레슨의 데모 코드에서는 Set<String> 으로 단순화했습니다. 같은 파일명이 다시 오면 정책에 따라 건너뛰거나, 내용이 다르면 오류로 알립니다.

2.5 실패 분류와 재시도

전송 실패는 원인에 따라 대응이 달라야 합니다. 무조건 재시도하면 인증 실패 같은 영구적 문제도 계속 재시도하면서 알림만 반복됩니다.

실패 종류 원인 예 대응
CONNECT 네트워크 단절, 상대 서버 다운 지수 백오프 재시도
AUTH 비밀번호·키 만료 즉시 알림, 재시도 무의미
PERMISSION 계정 권한 부족 즉시 알림, 담당자 확인
IO 디스크 풀, 중간 끊김 정리 후 재시도

이 레슨의 FileTransfer.TransferException 은 Kind 열거형으로 이 네 가지를 구분합니다. 재시도 로직은 Kind 를 보고 CONNECT·IO 는 재시도하고, AUTH·PERMISSION 은 즉시 알림으로 넘기는 식으로 분기합니다. 알림은 11 외부 API 연동, 19 메일 발송 레슨의 방식을 그대로 씁니다.

2.6 인증과 계정 권한

SFTP 인증은 비밀번호와 키 두 가지입니다. 배치 서버 간 연계는 대부분 키 인증(~/.ssh/id_ed25519)을 씁니다. 비밀번호가 스크립트나 설정 파일에 평문으로 남는 것을 피할 수 있기 때문입니다.

키 인증을 쓰더라도 known_hosts 검증(StrictHostKeyChecking)을 끄면 안 됩니다. 이 설정을 끄면 중간자 공격으로 다른 서버에 파일을 올려도 알아채지 못합니다. 계정은 전용 계정을 발급받아 chroot 로 지정된 폴더 밖을 볼 수 없게 하고, 업로드 대상 폴더에만 쓰기 권한을 줍니다.

2.7 타임아웃·keepalive·대용량 스트리밍

대외 기관 회선은 사내 네트워크보다 느리고 불안정한 경우가 많습니다. 연결·읽기 타임아웃을 넉넉히 잡되 무한 대기는 피하고, 유휴 연결이 끊기지 않도록 keepalive 를 설정합니다.

대용량 파일은 전체를 메모리에 올리지 말고 스트림으로 흘려보냅니다. 이 레슨의 LocalTransfer.upload 도 4096바이트 버퍼로 읽고 쓰는 스트리밍 구조라, 파일 크기가 커져도 힙 사용량이 늘지 않습니다.

2.8 스케줄·감사 로그·폐쇄망 jar 반입

배치 실행 시각은 대외 기관이 정한 시간 창(윈도) 안에 맞춰야 합니다. 09 스케줄 레슨의 cron 표현식으로 이 시간 창을 관리합니다. 너무 이르면 상대 서버가 파일을 아직 준비하지 못했고, 너무 늦으면 그날 정산에서 누락됩니다.

감사 로그는 "누가 언제 무엇을 몇 바이트 전송했는지"를 한 줄로 남깁니다. 사고가 났을 때 이 로그가 유일한 증거인 경우가 많습니다.

폐쇄망 프로젝트는 SFTP 클라이언트 jar 를 미리 반입해야 합니다. JSch 원본은 유지보수가 멈춰서, 포크판인 com.github.mwiede:jsch 0.2.x 를 권장합니다. FTP 만 쓰면 Apache Commons Net 으로 충분하고, Spring Integration SFTP 는 이 정도 규모 연계에는 과합니다.

2.9 수동 확인과 테스트 전략

배치를 붙이기 전에 리눅스 sftp·scp·rsync 명령으로 먼저 손으로 접속해 봅니다. 계정 권한, 경로, 방화벽이 맞는지 확인하는 가장 빠른 방법입니다. 명령 형식은 리눅스 명령어 06 레슨을 참고합니다.

배치 로직(원자적 전송, 폴링, 중복 방지)은 실제 SFTP 서버 없이도 검증할 수 있습니다. 이 레슨처럼 로컬 폴더를 원격 루트로 삼는 구현체로 단위 테스트를 돌리고, 실제 서버 연동은 스테이징 환경에서 별도로 확인합니다. 프로토콜 자체를 테스트하는 게 아니라 "임시 이름 업로드 → 크기 확인 → rename → 마커" 순서가 지켜지는지를 테스트하는 것이 목적입니다.

핵심 원리
  • 2.1 FTP vs FTPS vs SFTP
  • 2.2 연계 규격서에 있어야 할 것
  • 2.3 원자적 전송 — "쓰는 중" 사고를 막는 방법
  • 2.4 수신 측 처리와 중복 방지
  • 2.5 실패 분류와 재시도
  • 2.6 인증과 계정 권한
  • 2.7 타임아웃·keepalive·대용량 스트리밍
  • 2.8 스케줄·감사 로그·폐쇄망 jar 반입
  • 2.9 수동 확인과 테스트 전략
이전 섹션1 왜 배우는가2 / 7다음 섹션3 코드 예제