Java

FTP connection reset에 관련된 오류해결

멋진그이름 2016. 4. 5. 15:06

Hadoop분산환경에서 FTP연결관련 공부를 하면서 몇가지 테스트 프로그램을 작성했는데..

갑자기 Connection Reset이라는 오류가 발생한다. 구글링을 하면 대부분 Firewall, Network Setting, IPV4, 좀 더나아가서는 Data Connection에 대한 설명들(Active/Passive)이 있다. 

(Data Connection방식에 대한 상세한 설명은 다른 글에서 포스팅할 예정)

그러나.. 며칠동안 나오는 모든 내용을 살펴봤지만 해당하는 부분이 없었다.



<현상>

- Windows IIS FTP 접속시 Data전송요청이나 Command수행 후 재요청하면 Connection Reset이 발생함


원시적인 방법으로 돌아가서 프로그램상의 값을 하나씩 값을 변경해보다가 마침내 원인을 찾았다.



<원인>

- Hadoop에서 사용하고 있는 FTPFileSystem이라는 클래스를 살펴보면 다음과 같이 코딩되어 있다.

client.setFileTransferMode(FTP.BLOCK_TRANSFER_MODE);
client.setFileType(FTP.BINARY_FILE_TYPE);
client.setBufferSize(DEFAULT_BUFFER_SIZE);


이에 관련하여 FTP에 연관되어있는 많은 RFC문서를 볼 수 있는데, 기초가 되는 것이 RFC959 문서이다. 해당 문서를 읽어보면 Transmission Mode에 크게 3종류가 있으며, Hadoop FTPFileSystem은 Block transer mode를 기본으로 사용하고 있다. (https://tools.ietf.org/html/rfc959)


1. Stream Mode : The data is transmitted as a stream of bytes. There is no restriction on the representation type used; record structures are allowed. (가장 기본적인 방식이다.)


2. Block Mode : The file is transmitted as a series of data blocks preceded by one or more header bytes. The header bytes contain a count field, and descriptor code. The count field indicates the total length of the data block in bytes, thus marking the beginning of the next data block (there are no filler bits).


3. Compressed Mode There are three kinds of information to be sent: regular data, sent in a byte string; compressed data, consisting of replications or filler; and control information, sent in a two-byte escape sequence. If n>0 bytes (up to 127) of regular data are sent, these n bytes are preceded by a byte with the left-most bit set to 0 and the right-most 7 bits containing the number n.

compressed data와 그외 정보들로 전송하는 방법이다.


 문제가 되었던 것은 바로 2번 Block Mode!!

리눅스/유닉스 계열의 FTP서버에서는 별 문제가 없지만 IIS 의 FTP에서는 해당 모드를 제대로 지원하지 않아서 계속 EOF 신호를 기다리다가 timeout에 걸려서 server에 socket이 끊어지고 결국 connection reset이 발생하게 된다.

https://technet.microsoft.com/ko-kr/library/cc771040(v=ws.10).aspx

IIS 기반 FTP의 기본 데이터 전송 모드는 스트림입니다. IIS는 현재 블록 또는 압축 데이터 전송 모드를 지원하지 않습니다.

IIS 8.0버전에서 확인해봐도 여전히 Stream Mode만 지원하고 있음.


 현재까지 google이나 naver를 찾아봐도 FTP프로그램 작성시 connection reset현상의 원인에 대해서 FTP Transfer mode에서 해결책을 찾은 경우는 전무하다.

즉 동일한 오류가 발생하더라도 그 원인은 각각 다를 수 있다.



<해결방안>

- 소스를 수정하여 FTPClient 를 Stream Mode로 사용하면 Windows IIS 상에서도 문제없이 전송이 된다.
- 혹은 Block Mode를 사용하고 싶다면 이를 지원하는 FTP Server로 변경하면 된다.

- 왜 Hadoop의 FTPFileSystem에서는 apache net의 FileType이나 FileTransferMode Default값(STREAM_MODE)이 있음에도 불구하고 BLOCK_MODE로 하드코딩을 했을까?
 아마도 Hadoop은 Linux기반의 대용량 처리를 기본으로 하기 때문에 멀티 파일 전송에 유리한 BLOCK_MODE를 택한 것으로 보인다.



<Lesson & Learned>

- 오픈소스들은 결국 어떤 이론과 개념을 코드로 실체화 한 것이기 때문에 사용하기에 앞서서 이해가 필요하다. 원천에 대한 해당 문서를 꼼꼼히 읽어볼 필요가 있다.

- Connection Reset의 경우 매우 다양한 원인에 의해서 발생되지만 로그메시지는 대부분 Socket Read/Write 부분으로 동일하다. 

 따라서 무조건 Google에서 해당 로그를 검색하는 것보다는 Step별로 상세 테스트 케이스를 작성하여 하나씩 검증해나가는 방식을 추천한다. 

 또한 서버환경에 따라서도 다르게 동작하기 때문에 각 구성요소는 동일하게 한다.

아무리 google에 정보가 많아도 일반적이지 않은 오류에 대해서는 무용지물이다.