시스템 간 연동 (EAI) · 파일 연동 (배치·FTP·EDI) · 이론
파일 인터페이스가 아직도 최선인 이유
한 줄 요약
파일 연동이 살아남은 이유는 대량·명확한 경계·쉬운 재처리이고, 그 대신 위치가 곧 의미인 고정길이와 다 쓰기 전에 집어 가는 문제를 직접 다뤄야 한다.
왜 아직도 파일인가
REST 와 큐가 있는데 왜 파일로 주고받는가. 이유가 분명하다.
- 대량에 강하다. 100만 건을 건별 호출로 보내면 몇 시간이지만
- 경계가 명확하다. "8월 1일자 매출 파일"이라는 단위가 업무 담당자에게 자연스럽다.
- 재처리가 쉽다. 파일을 다시 넣으면 된다. 큐 재처리보다 직관적이다.
- 상대가 그것만 가능하다. 20년 된 시스템, 대외 기관, 은행 EDI.
파일 하나면 몇 분이다.
건수와 합계를 딱 떨어지게 대사할 수 있다.
"REST 로 주세요"가 통하지 않는다.
그래서 SI 현장에서 파일 연동은 사라지지 않는다. 오히려 배치 야간 작업의
큰 축이 여전히 파일이다.
고정길이 전문 — 위치가 곧 의미다
20260801HONG 0000012500Y| || || ||1-8 9-28 29-38 39일자 고객명(20) 금액(10) 여부(1)레이아웃 정의서에는 시작 위치, 길이, 타입, 정렬, 채움 문자가 있어야 한다.
| 항목 | 관행 |
| --- | --- |
| 문자 필드 | 왼쪽 정렬, 오른쪽 공백 채움 |
| 숫자 필드 | 오른쪽 정렬, 왼쪽 0 채움 |
| 금액 | 소수점 없이 정수로, 자릿수를 정의서에 명시 |
| 음수 | 마지막 자리에 부호를 겹치거나 별도 부호 필드 |
| 날짜 | YYYYMMDD 8자리 |
한글이 들어가면 문제가 시작된다. '길이 20'이 20바이트인지 20글자인지에 따라
전혀 다른 파일이 된다. EUC-KR 이면 한글 1자가 2바이트, UTF-8 이면 3바이트다.
그리고 고정길이는 한 바이트만 밀려도 그 뒤가 전부 깨진다.
그래서 국내 대외 연동에서 EUC-KR(또는 CP949)이 아직 살아 있다.
한글이 2바이트로 딱 떨어져서 자릿수 계산이 편하기 때문이다.
받은 파일이 깨져 보이면 먼저 인코딩을 의심하고 변환해 본다.
iconv -f EUC-KR -t UTF-8 SALES_20260801.dat > SALES_utf8.dat헤더와 트레일러 — 파일 자체의 자기 검증
잘 설계된 파일 인터페이스에는 헤더와 트레일러가 있다.
H20260801SALES 0001 ← 헤더: 구분, 일자, 업무, 파일순번D20260801HONG 0000012500 ← 데이터D20260801KIM 0000030000T0000000002000000042500 ← 트레일러: 건수, 금액 합계트레일러의 존재 이유는 단 하나 — 파일이 온전히 도착했는지 스스로 증명하기 위해서다.
- 데이터 건수 == 트레일러의 건수인가
- 데이터 금액 합계 == 트레일러의 합계인가
전송 중 잘렸거나, 중간에 한 줄이 유실됐거나, 인코딩 변환 중 깨졌으면
이 검사에서 걸린다. 이 검증을 안 하면 절반만 온 파일을 정상 처리한다.
그리고 그 사실은 월말 마감 때 "숫자가 안 맞는다"로 발견된다.
트레일러 검증은 처리 전에 해야 한다. 처리 중에 하면 이미 절반이 반영된 상태가 된다.
완료 플래그 — 다 쓰기 전에 집어 가는 문제
FTP 로 파일이 올라오는 중에 배치가 그 파일을 집어 가면 어떻게 되는가.
절반짜리 파일을 처리한다. 트레일러 검증이 있으면 걸리지만, 없으면 그대로 들어간다.
표준 규약은 완료 플래그 파일이다.
SALES_20260801.dat ← 데이터 (전송 중일 수 있음)SALES_20260801.dat.ok ← 이 파일이 생겨야 처리 대상송신측이 데이터를 다 보낸 뒤 빈 .ok 파일을 만든다.
수신측은 .ok 가 있는 것만 처리한다. 간단하지만 매우 효과적이다.
정의서에 반드시 명시해야 한다. "플래그 파일 규약"이 한쪽에만 있으면
상대는 그냥 데이터만 올리고, 우리 배치는 영원히 아무것도 처리하지 않는다.
그리고 아무 오류도 안 난다. 조용히 아무 일도 안 하는 것이 가장 늦게 발견된다.
파일명 규칙도 인터페이스다
<업무코드>_<기준일자>_<순번>.<확장자>SALES_20260801_001.dat- 기준일자가 파일명에 있어야 재처리할 파일을 특정할 수 있다
- 순번이 있어야 하루에 여러 번 오는 경우를 구분한다
- 파일명 규칙이 없으면
sales.txt가 매일 덮어써지고, 어제 것을 못 찾는다
처리 후 보관
처리한 파일은 지우지 말고 보관한다.
/data/if/archive/20260801/SALES_20260801_001.dat.gz- 날짜별 디렉터리로 나눠야 한 디렉터리에 파일 수십만 개가 쌓이지 않는다
- 압축한다. 텍스트 파일은 대개 80~90% 줄어든다
- 보관 기간을 정의서에 명시한다. 무한 보관은 디스크 풀 장애로 돌아온다
보관이 필요한 이유는 재처리와 분쟁 때문이다.
"그날 우리가 보낸 건 12,000건인데요"라는 말에 답하려면 원본이 있어야 한다.
대사(Reconciliation) — 파일 연동의 마지막 단계
파일을 처리했다고 끝이 아니다. 양쪽 숫자가 맞는지 확인해야 한다.
| 대사 항목 | 방법 |
| --- | --- |
| 건수 | 송신 건수 == 수신 처리 건수 + 오류 건수 |
| 금액 합계 | 송신 합계 == 수신 합계 |
| 키 집합 | 송신 키 목록 - 수신 키 목록 = 공집합 |
건수와 합계만 맞으면 안심하기 쉽지만, **한 건이 빠지고 다른 한 건이
두 번 들어가면 건수는 맞는다.** 그래서 금액 합계를 함께 보고,
정확성이 중요한 인터페이스는 키 집합까지 비교한다.
대사 결과는 파일로 남긴다. 그리고 불일치가 있으면
자동으로 담당자에게 통보되게 한다. 대사 결과를 사람이 매일 열어 보는 방식은
바쁜 날 건너뛰게 되고, 건너뛴 그날에 문제가 있다.
현장에서 만나는 모습
파일 연동에서 나는 사고는 종류가 정해져 있다.
- 반쪽 파일을 처리했다. 상대가 아직 쓰는 중인데 우리가 집어 갔다. 그래서 완료 플래그(
.ok)를 함께 쓰고, 플래그가 있는 파일만 집는다. 이 규칙이 없으면 "어떤 날은 건수가 적게 들어온다" 는 재현 안 되는 버그가 된다. - 인코딩이 바뀌었다. EUC-KR 로 오던 파일이 어느 날 UTF-8 로 온다. 고정길이에서는 한글의 바이트 길이가 달라지므로 그 뒤 필드가 전부 밀린다. 화면에는 이름이 깨진 채로, 금액은 엉뚱한 값으로 들어간다.
- 트레일러를 안 봤다. 파일 스스로 건수와 합계를 들고 있는데 그걸 대조하지 않으면, 전송 중에 잘린 파일을 그대로 적재하고도 아무도 모른다.
세 가지 모두 파일을 읽기 전에 파일을 믿을 수 있는지 확인하는 절차가 없어서 생긴다. 그래서 파일 연동의 첫 단계는 파싱이 아니라 검증이다.