Linux Programmer

오류를 잡자 : TCP에는 우아한 종료라는 것은 없다. 본문

컴퓨터 관련/프로그래밍 일반

오류를 잡자 : TCP에는 우아한 종료라는 것은 없다.

sunyzero 2020. 2. 2. 05:53

google에서 "TCP 우아한 종료"라고 검색해보자. 상당히 많은 내용이 나온다. 그러나 틀린 이야기들이 대부분이다. 문제는 이 틀린 이야기가 상당히 오랫동안 인터넷을 어지럽히고 많은 학생이나 개발자들에게 혼동을 준다는 점이다.

 

본인은 부업으로 그룹의 IT계열 회사나 금융권에 특강을 다닌다. 대상은 적어도 시니어급 이상의 개발자, 서버 관리자들이 대부분이다. 그런데 강의를 다니다보면 시니어급 개발자(프로그래머)들의 레벨에서도 잘못 알고 있는 지식이 많음을 느낄 수 있었다. 특히 잘못된 교재로 공부한 경우나 잘못 번역된 책으로 공부한 경우에는 특히 심했다.

 

사실 이 글을 쓰게 된 계기는 어제(20/02/01) IT관련 교육자들이 모이는 meetup으로 잠실의 '우아한 형제들 작은 집'에 갔다가 "(어떤 책이나) 강의자료나 강의내용의 오류는 왜 교정되지 않고 계속 반복되는 것일까" 토론중에 갑자기 생각이 났다. (그러고보니 우아한 형제들은 graceful brothers인가?)

 

1. TCP의 우아한 종료?

많은 블로그나 책을 보면 TCP에는 우아한 종료가 있다고 어쩌고 저쩌고 이야기를 한다. 이건 번역의 오류가 검증없이 퍼져나가서 생긴 문제다.

 

TCP 소켓을 닫을 때 일반적으로 2가지 방법이 있다. 각각 일반적인 닫기(normal close), 강제적인 닫기(abortive close)라고 한다. 그런데 여기서 일반적인 닫기를 예전에는 graceful close 혹은 graceful shutdown이라고도 불렀는데 이것이 오류의 시발점이 되었다.

 

(참고) close와 shutdown 용어는 모두 버클리 소켓 함수에서 유래한 기능으로 소켓 파일 디스크립터를 닫는 역할을 한다. 세부적으로는 약간 다르지만 일반적으로 파일 디스크립터가 복제되지 않는한 소켓 레이어에서 둘은 동작 결과는 같다. [1] [2]

다만 file descriptor자체는 언제나 닫아줘야 하기 때문에 shutdown을 하더라도 close는 해야 한다는 점에서 shutdown 자체는 복잡성을 증가시키는 면이 있다. 현대적인 network programming은 이런 연유로 되도록이면 shutdown을 쓰지 않는 추세다.

 

여기서 graceful close를 누군가 "우아한 종료"로 해석하기 시작하면서 오개념이 유행했던 것 같다. 그러면 어떻게 해야 우아한 종료일까? TCP packet을 우아한 몸짓으로 끊어주는 걸까? 아니면 컴퓨터들끼리 좀 더 부드러운 전기 신호를 쓰는 기능이 있는걸까? 정말이라면~ 에엑??? 부드러운 전기....

 

graceful의 의미는 사실상 우아하게라고 쓰이지만, 컴퓨터쪽에서는 의미가 다르게 쓰인다. 컴퓨터 쪽에서 graceful의 의미는 "(유예를 가지고 있는) 부드러운/깔끔한/적합한"의미를 가지고 있다.

 

그래서 graceful close는 "(유예를 두는) 깔끔한 정상 종료", 혹은 의역하면 "깔끔하게 정상적인 종료를 하기위해 기다려줄 수 있는 것"의 늬앙스를 담아서 해석하는게 맞다. 원래 grace period라는 말도 있는데 이는 유예기간이라는 뜻이다. 그러므로 graceful close, graceful shutdown은 패킷 전송에 있어서 유예 기간(다른 말로 타임아웃으로 이해해도 된다.)을 두고 앞서 전송된 패킷 모두가 정상적으로 전송된 뒤에 깔끔하게 끊는 것을 말한다. TCP/IP의 Bible이라고 불리는 Richard W. Stevens의 TCP/IP Illustrated Volume 1에 보면 다음과 같은 글이 있다.

 

The seven segments we have seen are baseline overheads for any TCP connection that is established and cleared "gracefully". (There are more abrupt ways to tear down a TCP connection using special reset segments, which we cover later)

- TCP/IP Illustrated, Volume 1 (2nd Edition) Kevin R. Fall, W.Richard Stevens, p598 TCP Connection Establishment and Termination 

 

위 인용된 페이지의 앞 부분에 보면 TCP 연결과 종료의 그림이 있고, 연결에서 TCP 쓰리웨이 핸드쉐이킹 하는 부분과 종료에서 TCP 포웨이 핸드쉐이킹하는 부분이 있다.[3] 이에 총 7개의 세그먼트를 주고받게 된다. 이런 기본적인 개념을 가지고 위 글을 부드럽게 의역하면 다음과 같다. "앞서 봤듯이 TCP의 연결 설정과 해제 과정(적합한 처리 과정에 유예 시간이 존재할 수 있음)에는 기본적으로 7개의 세그먼트 오버헤드를 가진다. (특별히 reset 세그먼트를 이용해서 TCP 연결을 갑작스럽게 끊는 방법도 있는데 뒤에서 다룰 것이다.)" 하지만 이를 잘못해석하여 gracefully를 우아하게라는 뜻으로 받아들이면 전혀 다른 의미가 된다.

 

사실 graceful close의 의미를 한국어로 표현하는 것은 매우 어려운 일이다. 영어 단어가 함축하고 있는 의미를 가진 단어가 한국어에는 없는 경우가 종종 있기 때문이다.(e.g. segment, fragment의 차이가 대표적이다. 둘다 조각으로 해석될 수 있지만 어떤 조각인지 설명하는 것이 다르다. 하나는 원형의 모양이 의미가 없거나 알 수 없지만 다른 하나는 원형의 어떤 부분을 의미한다.)

하지만 우아하게 뭔가를 진행하려면 빠르게 하는 것보다 느리고 천천히 하면서 기다려야 하기 때문에 우아한~의미로 해석해도 맞다고 하는 분들도 있다. 물론 그 말이 맞을 수도 있으나 한국어에서 통용되는 우아함이란 어떤 시간적 유예의 의미를 내포하는 용도로는 거의 쓰이지 않는다.

한국에서 어떤 트랜잭셔널한 일을 우아하게 처리하자고 하다간 거의 펀쿨섹 같은 소리 한다고 한소리를 들을 가능성이 높다고 생각된다.

 

이렇게 단어의 문맥적 의미를 잘못 이해한 누군가가 오역을 하고, 그 오역이 퍼져나가다가 심지어 왜곡까지 되었다. 그래서 몇몇 책이나 블로그에는 TCP의 half close가 우아한 종료라고 잘못 말하기도 한다. Half close는 TCP 소켓의 송신,수신 채널에 대한 것이므로 graceful close 개념이 아니다. 그럼에도 불구하고 많은 사람이 우아한 종료라고 착각하고 오염된 지식을 재생산하고 있다.

 

** 어떤 이들은 이런 개념을 잘못 아는게 무슨 큰일이냐고 되물을 수도 있다. 그런데 사실상 큰일 맞다. Abortive close는 나쁜게 아님에도 불구하고 우아하지 못하다는 오해를 받아서 사람들이 쓰면 큰일 나는 비정상적인 기능으로 오해를 받는다.(물론 비정상적인 상황에서도 발생하지만...) 하지만 application protocol을 설계할 때 7계층에서 명시적으로 끊는 메시지를 받았다면 즉시 RST를 전송하고 소켓을 파괴하도록 설계하는 경우도 종종 있다.(장비 특성상 이건 잘못된 것이 아니라 꼭 필요한 경우가 있다. 예를들어 오버헤드를 줄이거나 성능을 높이기 위해서 이런 기법을 사용하는 경우가 있다.)

반대로 graceful close에서 linger 기능을 사용할 경우 close단계에서 grace period 동안 wait의 주체를 커널이 할것인지, 아니면 프로세스(유저레벨)에서 할 것인지 결정하는 것은 tcp의 올바른 이해에서 비롯된다. 이를 잘못 이해하면 시스템에 성능 이슈를 가져올 수 있다.

 

이에 대한 확실한 예로 graceful close를 하는 경우에 linger 옵션을 이용해서 다음과 같이 옵션을 주면 8초의 grace period를 주고, 사용자 프로그램이 직접 기다릴 수 있다.

 

struct linger solinger = { 1, 8 };
if (setsockopt(cfd, SOL_SOCKET, SO_LINGER, &solinger, sizeof(struct linger))
        == -1) {
    perror("setsockopt(SO_LINGER)");
}

 

이 외에 "Graceful"을 사용하는 용어를 해석하다보면 다음과 같은 문장이 나올 수도 있다. 예를 들어 "By default, all transactions are graceful within 60 seconds." 라고 적으면 "기본적으로 모든 트랜잭션은 보통 60초내에 처리된다.(처리되는데 있어 최대 60초의 대기 시간이 있을 수 있다)"로 해석된다. 즉 보통은 처리를 위해 유예 혹은 대기 시간이 60초이므로 해당 트랜잭션은 약간 딜레이가 발생하면 60초까지도 대기할 수 있고, 이를 넘기면 어떤 액션을 취할 것이라는 늬앙스를 준다. 실제로 금융권에서 처리되는 몇몇 느린 트랜잭션은 저런 식으로 매뉴얼이 적혀있기도 하다. 하지만 이를 우아한 뜻으로 해석하면 도저히 의미가 통하지 않는다.

 

1.1. graceful, gracefully의 또다른 예

다른 예로 어떤 장치는 Start/Stop와 Power off 버튼이 따로 존재하는 경우도 있는데, Start/stop에는 gracefully하게 작동한다고 써있기도 한다.(반대로 Power off는 abortive하게 작동한다고 쓰여있을 수도 있다) 이런 경우에는 작동하는 내부 서비스 프로세스를 정상적으로 종료하고, 데이터는 저장장치에 기록하고 순서대로 종료한다. 그러나 Power off를 누르면 즉시 전원을 차단해서 강제로 꺼진다. 그래서 매뉴얼에는 stop을 누르고 완전히 정지된 상태에서 power off를 하라고 제안한다. 하지만 응답이 없으면 그냥 power off를 누르라고 한다. 이렇게 설계하는 이유는 정상적으로 종료하려고 했는데 응답이 없는 서비스나 프로세스가 있을 땐 강제로 꺼야 하기 때문이다.

 

PC의 경우에도 Alt-F4 눌러서 종료 버튼을 누르면 열려있는 프로세스나 창을 다 닫고 종료한다. 몇몇 프로세스가 시간이 오래걸리면 대기를 해주기도 하는데 이는 운영체제가 graceful shutdown하는 것으로 볼 수 있다. 그러나 파워 버튼을 4~5초정도 누르고 있으면 강제로 전원이 나가면서 종료되기도 한다. 이건 운영체제, 컴퓨터를 만들때 2가지 기능, 즉 graceful shutdown과 abortive shutdown 기능을 넣어두었기 때문이다. 시스템에 따라서 2가지 기능 중에 한가지만 구현해두는 경우도 있다. (참고: 스마트폰은 abortive shutdown기능을 제공할까? 스마트폰의 graceul하게 끄는 방법과 강제로 끄는 방법이 따로 있다면 어떻게 표현될까?)

 

따라서 graceful OOOO(혹은 OOOO gracefully)은 TCP에서만 사용되는 용어가 아니고 대부분의 IT 기기나 소프트웨어에서 다양하게 사용되는 용어이고 "우아한"의미로 해석하지 말고 정상적으로 어떤 액션을 수행하는데 있어서 깔끔하게, 혹은 부드럽게 처리하기 위해 순서를 기다리는 유예시간이 있을 수 있음으로 번역하고 이해하는게 맞다.

 

또다른 예로 apache web server의 매뉴얼에서 graceful restart 혹은 graceful stop 명령에 대한 설명을 볼 수 있다. 아래는 아파치 웹서버 매뉴얼에서 Stop Now, Graceful Restart 부분을 인용한 부분이다.

 

https://httpd.apache.org/docs/2.4/en/stopping.html

 

Stopping and Restarting Apache HTTP Server - Apache HTTP Server Version 2.4

In order to stop or restart the Apache HTTP Server, you must send a signal to the running httpd processes. There are two ways to send the signals. First, you can use the unix kill command to directly send signals to the processes. You will notice many http

httpd.apache.org

Stop Now
  Signal: TERM
apachectl -k stop

Sending the TERM or stop signal to the parent causes it to immediately attempt to kill off all of its children. It may take it several seconds to complete killing off its children. Then the parent itself exits. Any requests in progress are terminated, and no further requests are served.


Graceful Restart
  Signal: USR1
apachectl -k graceful

The USR1 or graceful signal causes the parent process to advise the children to exit after their current request (or to exit immediately if they're not serving anything). The parent re-reads its configuration files and re-opens its log files. As each child dies off the parent replaces it with a child from the new generation of the configuration, which begins serving new requests immediately.

위 인용된 매뉴얼을 매끄럽게 번역하기 위해, 즉 graceful의 의미를 살리기 위해 아래와 같은 부분을 염두에 두고 해석하였다. 첫째로 읽는 사람들이 UNIX signal이나 웹 서버의 구조에 대해 잘 모를 수 있기 때문에 번역의 이해를 돕기 위한 내용을 { } 부분으로 추가하였다. 둘째로 매뉴얼 윗 부분에 apachectl의 옵션 및 아규먼트(인수)에 대한 부분이 있으므로 이를 포함하였다.

 

그리고 용어의 이해를 돕기 위해 약간의 배경지식을 이야기 하도록 하겠다. 아파치 웹서버는 구동되면 fork를 통해 복제된 자식 프로세스들을 만들게 된다. 이 과정에서 아파치 웹서버는 부모 프로세스와 자식 프로세스로 나뉘는데, 부모 프로세스는 자식 프로세스들의 갯수 pool을 관리하는 일을 주로 하고 실제 웹 서비스 처리는 자식 프로세스들이 한다.

 

Stop Now {즉시 정지}
  시그널 : TERM
apachectl -k stop

TERM 유닉스 시그널 혹은 {apachectl 명령행의 -k} stop 인수를 통해 시그널을 받은 부모 프로세스는 즉시 모든 {웹 서비스를 처리하는} 자식 프로세스를 죽이려고 시도한다. 자식 프로세스들을 모두 죽이는 데는 약간의 시간이 소요될 수 있다. 그러고 {자식 프로세스들이 모두 죽은 뒤에는} 부모 프로세스 자신도 종료한다. 이 과정에서 처리 중인 모든 리퀘스트는 중단되고, 더 이상 처리되지 않는다.


Graceful Restart {매끄러운 재시작}
  시그널 : USR1
apachectl -k graceful

USR1 유닉스 시그널 혹은 {apachectl 명령행의 -k} graceful 인수를 통해 시그널을 받은 부모 프로세스는 자식 프로세스에게 현재 {처리하고 있는} 리퀘스트를 처리한 뒤에 종료하라고 지시한다. (혹은 아무것도 하지 않고 있다면 즉시 종료한다) 그리고나서 부모 프로세스는 설정 파일을 다시 읽고 로그 파일을 재오픈한다. 그 후 {처리 중인 리퀘스트가 있다면 종료에 지연이 있을 수 있는} 자식 프로세스가 종료될 때마다 부모 프로세스는 새로운 설정을 적용한 자식 프로세스를 새로 생성하여 종료된 자식 프로세스를 대체하여 새로운 리퀘스트를 처리하도록 한다.

위에서 { } 괄호 안의 부분은 graceful의 의미를 이해하기 쉽게 넣은 부분이다. 첫번째 부분인 Stop Now 부분은 즉시 프로세스를 죽이기 때문에 graceful하지 않은 방법이다. 따라서 처리 중인 모든 리퀘스트는 제대로 끝마쳐지지 못하고 취소될 수 있다. 만일 Graceful Stop이라면 반대로 최소한 처리중인 리퀘스트는 처리해주고, 종료할 것이다.

 

그에 비해 Graceful Restart 방법은 재시작을 지시하는 시점에서 자식 프로세스가 처리 중인 리퀘스트는 정상적으로 처리되고, 그 다음에 자식 프로세스가 종료되고, 새로운 자식 프로세스를 만들어서 옛날 자식 프로세스가 하던 일을 대체하게 된다. 즉 graceful하다는 의미에서 restart 자체가 유예될 수 있다는 것을 알 수 있다. 여기서 그 유예의 의미는 delay가 아니다. 매끄럽게 처리하기 위해 restart 자체가 유예될 수도 있다는 의미다. (약간 선택적인 의미라고 생각해야 할 듯 싶다)

 

여기서는 Apache 웹서버를 예로 들었지만 이 외에도 많은 IT 문서에서 graceful, gracefully용어가 쓰인다. 따라서 늬앙스를 알아두면 매뉴얼을 직독하면서 모호하게 해석되는 부분을 부드럽게 이해하는데 도움이 된다.

 

IT업계에는 이 외에도 deprecated라든지, kernel, shell, thread, signal, critical section, sliding window 라든지 일상적인 의미와 좀 다르게 쓰이는 단어들이 꽤 많다. 이걸 영어사전 의미 그대로 해석하면 문서 내용이 안드로메다로 가게 된다. 실제로 옛날에 김치하 교수와 같은 분들이 직독 번역을 좋아하셔서 kernel을 알맹이, shell을 껍데기, network를 그물, pipe를 대롱으로 거의 영어사전을 그대로 번역한 것 같이 쓴 적이 있다. 그런데 이렇게 영어사전적 용어로 해석하면 "껍데기를 통해 OOO 명령을 내리면 알맹이가 보쌈을 만들어 처리한다" 뭐 이런 식으로 알수 없는 번역이 될 수 있다.

 

 

2. 문제의 근본 원인은 표절이다

이렇게 잘못된 용어의 번역과 개념이 끊임없이 번져나가는데는 표절이 하나의 원인이 아닐까 생각된다. 우리나라에서는 블로그를 쓰든 아니면 책을 쓰든지 인용을 적는 경우가 굉장히 드물다. 위의 "우아한 종료" 같은 실수는 수 많은 네트워크 서적이나 국내서에 단골 손님으로 등장한다.

 

그 이면에는 많은 책의 저자들이 인터넷을 검색하면서 원고를 작성하기 때문이기도 하다. 어떤 이는 KLDP의 내용을 통째로 긁어다가 책에 넣은 사람도 봤다.(더 슬픈건 긁어간 내용이 맞았다면 다행이겠지만 틀린 내용이었다.) 그런데 웃긴건 이렇게 잘못 쓰여진 책이 출판되어 많이 팔리면 그 책을 보고 어떤 이는 블로그에 정리하거나 게시판에 올려두고, 또 초보자인 누군가는 블로그 글을 읽고 다른 초보자에게 틀린 답변을 알려준다. 그 틀린 답변으로 공부한 초보는 시간이 지나 시니어가 되면 또 틀린 내용으로 책을 쓰고... 무한 반복이 된다.[4]

 

저널에 실리는 논문처럼 peer review가 없기 때문에 표절이 되면 오류가 정정될 가능성은 굉장히 적어진다.

 

하지만 처음에 글을 잘못 썼다고 해도 인용 레퍼런스를 제대로 넣었다면 중간에 누군가에게 검증받을 기회가 있었을 것이다. 허나 무분별하게 표절을 하면서 인용을 생략하면 원문을 알도리가 없다.

 

3. 내용 검증을 위해 꼭 인용을 표시하자

요새는 정치인을 하려고 해도 논문 표절, 심지어 자기 논문을 스스로 표절하는 자기표절도 걸리는 세상이다. 따라서 어떤 글을 적을 때 인용을 한다면 꼭 표시하자. 그래야 스스로도 올바른 내용을 썼는지 검증이 가능해진다.

 

하다못해 짧은 글을 쓰더라도 인용은 꼭 찾아서 표시해두자. 그래야 스스로 1차적으로 검증이 이뤄지고, 그 다음에 잘못 쓰였으면 원문까지 같이 검증받을 수 있게 된다. 꼼꼼하게 못하더라도 괜찮다. 처음부터 잘할 수는 없을테니... 그래도 인용을 찾아서 적어두는 연습을 하자.

 

 

[1] IEEE std. 1003.1 Functions "shutdown" https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html

[2] IEEE std. 1003.1 Functions "close" 

https://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html

[3] Kevin R. Fall, W.Richard Stevens. (1999). TCP/IP Illustrated, Volume 1 : Protocols (2nd Edition). p596

[4] 김선영, TCP의 TIME_WAIT를 없애는 법, https://sunyzero.tistory.com/198 

 

TCP의 TIME_WAIT를 없애는 법

* TCP의 TIME_WAIT는 없애는 방법은? TCP 소켓 네트워크 프로그래밍을 하다 보면 TIME_WAIT 상황에 대한 고민을 하는 시점이 오게 된다. 학부 시절 네트워크 프로그래밍 수업을 듣고 실습실에서 열심히 프로그래밍..

sunyzero.tistory.com

[5] Graceful shutdown, linger option, socket closure. https://docs.microsoft.com/ko-kr/windows/win32/winsock/graceful-shutdown-linger-options-and-socket-closure-2 

 

Graceful Shutdown, Linger Options, and Socket Closure - Win32 apps

Graceful Shutdown, Linger Options, and Socket Closure In this article --> The following material is provided as clarification for the subject of shutting down socket connections closing the sockets. It is important to distinguish the difference between shu

docs.microsoft.com

 

* 히스토리

2020.08.16 아파치 웹서버의 graceful restart 예시 추가

2020.02.02 처음 씀

12 Comments
  • 프로필사진 TCPL 2020.02.02 09:20 신고 오늘도 한 수 배우고 갑니다 ㅠㅠ
    제가 봤던 TCP 책에서도 우아한으로 번역되었던게 기억나네요.
  • 프로필사진 sunyzero 2020.02.02 16:09 신고 이게 생각보다 많은 책이나 블로그에 퍼진 것 같더군요. 실제로 서점 가서 살펴보니 대부분의 저자들도 잘못 알고 있는 것을 보고 충격적이었습니다. ㅠㅠ
  • 프로필사진 Jay Tech 2020.02.02 11:52 신고 좋은 글 감사합니다! 잘못된 지식의 전달여파가 얼마나 큰지 알게되었습니다. 인용을 꼭 하는 습관또한 들여야겠네요!
  • 프로필사진 sunyzero 2020.02.02 16:11 신고 부족하지만 저도 최근 몇년간 자기 표절이나 잘못된 지식의 전달을 줄이기 위해 인용을 표기하려고 노력하고 있습니다. 그래도 계속 실수가 나오더라구요.

    찾아주셔서 감사합니다. ^^
  • 프로필사진 reinhard v.z. 2020.02.03 11:12 우아한, 우아하게 라고 해석함으로써 발생하는 해석 오류가 무엇일까요? 의미가 맞지 않다는 지적은 공감되지만 그렇다고 번역 오류라 간주하자는 주장에 대해서는 다소 의문입니다.
    TCP 연결 양 단 간에 우아하게 연결을 종료하는 것은 일정시간 동안 유예를 두고 연결을 정리하는 절차를 밟는 과정이라고 본다면, 우아하게 라고 기술하거나 번역하였다고 해서 의미가 통하지 않거나 오해가 생길일이 있는지 의문입니다. TCP 연결 종료를 배우는 초심자에게 명확한 의미 전달이 되지 않는 측면은 문제입니다. 다만 우아한 연결종료에 대해 부수적인 설명이 있고, 이를 우아한 연결 종료다 라고 의미가 부여된다면 나쁜 번역은 아니라는 생각입니다.
  • 프로필사진 sunyzero 2020.02.03 12:26 신고 사람마다 견해가 다르니 reinhard v.z.님처럼 생각해볼 수도 있지만, 저는 오류라고 생각합니다. 물론 이것은 주관적인 영역이라 누가 맞다고 우길 수 있는 것은 아니라고 생각합니다. (님의 생각도 사람에 따라서 충분히 받아들여질 수 있다고 생각합니다.)

    그러나 reinhard v.z.님이 "우아한"이라는 뜻을 가지고 "유예"라는 의미까지 확장할 수 있다면, 그것은 아마 기반 지식이 충분하고 이미 네트워크에 대한 지식도 가지고 있기 때문입니다. 더불어 영어독해에 있어서도 어느 정도 잘하시기 때문이겠죠. 하지만 영어를 못해서 번역서를 보는 초급 학습자들은 그렇지 못할거라고 생각합니다.

    실제로 인터넷에 나와있는 수많은 글들을 보면 우아한 종료를 유예를 두는 종료라는 의미로 사용하지 않으며, 대부분의 사람들은 half-close가 graceful shutdown이라고 착각하기도 합니다. 그래서인지 이런 오개념을 장착하여 실제로 네트워크 프로그래밍 저서들 중에 몇몇은 이렇게 쓰기도 하더군요.

    이런 개념적 오류는 나중에 프로그래밍을 할 때도 나타납니다.(실제로 제 부사수도 그렇게 하더군요. 그냥 close하면 큰일 나는줄 잘못 알고 있더군요)

    그래서 저는 초심자에게 혼동을 주는 번역은 오역이라고 생각합니다. 분명히 한 단어에 여러 의미가 있는데 다른 뜻으로 번역하고 그것을 알아서 유추하라고 하는 것은 좋은 번역이라고는 생각하지 않습니다. 물론 이건 주관적인 견해일 뿐입니다.
  • 프로필사진 정준영 2020.02.14 09:58 우아하다라는 수식어는 여러 상황에서 사용될 수 있고 정상적으로 수행되는 tcp 연결 종료 과정을 표현하기에도 자연스러운 쓰임이라고 생각합니다.

    비정상적으로 연결이 끊기는 상황, 예를들어 segfault가 나서 RST패킷을 갑자기 보내버리는 일이 있습니다. 이런 비정상적이고 무례한 상황이 존재하지 않았다면 애시당초 정상적인 종료에 graceful이라는 수식어를 붙일 일이 없었을 것입니다. 따라서 graceful은 비정상적인 종료에 대조적으로, 정상적인 상황임을 한번 더 강조하기 위해 붙여주는 수식어 입니다.

    오히려 graceful을 유예라고만 해석하는 것은 오해의 여지가 있습니다. 유예는 어떤 일을 뒤로 미룬다는 의미로 사용합니다. 정상적인 종료는 그냥 별다른 수식어가 붙지 않아도 됩니다. 유예종료라는 말은 뭔가 특수한 상황을 뜻하고 있습니다. 종료를 바로 안 하고 뒤로 미룬다는 것처럼 들립니다.
  • 프로필사진 sunyzero 2020.02.17 21:04 신고 기술문서는 의역을 폭넓게 허용하는 소설과 달리 정확한 용어가 중요합니다.
    분명히 한 단어에 다른 뜻이 있고 그 의미로 사용했는데, 주관적 판단으로 원저자의 뜻을 번역가가 변경하는 것은 왜곡에 해당합니다.(하지만 graceful같은 경우는 왜곡했다기보단 무지에서 나온 번역이죠)

    게다가 위와 같이 유예의 의미를 가지는 이유는 TCP 소켓의 근본적인 특징과도 영향이 있기 때문에 "우아한"이라는 의미로 왜곡하면 안됩니다.
    왜냐하면 TCP는 네트워크 상에서 비순차적으로 전달 될 수 있는 패킷들을 재조립하여 순서를 보장하는데, 이를 위해 여러가지 기법(sliding window라든지..)이 필요하고 이 때문에 sequence 관리가 필요합니다. 이 sequence 관리 때문에 유예시간이 필요해진 것이죠. 심지어 TCP에서 piggyback된 데이터와 연결을 시작하거나 종료할 때의 헤더 정보를 담고 있는 패킷도 순서를 지켜야 하는 것 때문에 유예시간은 피할 수 없습니다.

    특히 닫을 때에 유예시간은 TCP 프로토콜 상에서 통신 세션을 끊기 위해 모든 시퀀스를 순서대로 처리하는 유예를 의미하는데, 이 유예동안 대기하는 주체가 어딘지 결정하는 것이 바로 graceful/abortive close의 개념을 만들게 됩니다. 문제는 이 두 개념은 정상/비정상이 아니라는 점입니다. 하지만 우아한이라는 의미 때문에 마치 graceful close는 정상이고, abortive close는 비정상으로 착각할 수 있습니다.

    프로토콜 설계상 유예가 당연한 상황임에도 잘못된 번역으로 인해 많은 개발자들이나 학생들이 TCP 프로토콜을 첫 단추부터 잘못 이해할 수 있습니다.

    앞서 언급했듯이 TCP에서 이 개념을 이해한 사람들은 일반적으로 close를 호출했다고 바로 TCP 소켓이 닫히지 않을 수 있다는 것을 알 수 있습니다. 그리고 백그라운드에서 커널이 grace period를 가지고 앞선 sequence를 가지는 패킷을 전송한 뒤에 FIN을 보내서 four-way handshaking을 하게 되죠. 하지만 백그라운드가 아닌 직접 유예를 하고 싶다면 linger를 이용해서 유저가 대기할 수 있습니다. 이 과정이 마음에 들지 않는 개발자는 application level protocol에서 데이터의 종료 패킷을 받으면 즉시 소켓과 버퍼를 파괴하는, 즉 유예를 0초로 만들어서 abortive close를 할 수도 있습니다. 이렇게 하면 segfault로 종료하는 경우와 프로토콜 상에서 개발자가 의도한 종료는 같은 작동을 보이게 됩니다. 이런 프로토콜 설계는 비정상이 아닙니다. TCP에서 주는 기능을 이용한 구현일 뿐입니다.

    장비 중에는 연결된 다른 장비의 순차적인 종료를 위해 graceful restart 라는 기능을 가진 경우도 있습니다. 하지만 이를 번역기를 돌려서 "우아한 재시작"으로 해석하면 admin이나 학생들은 이 장비의 기능을 어떻게 받아들일까요?
  • 프로필사진 2020.07.04 12:55 비밀댓글입니다
  • 프로필사진 sunyzero 2020.07.04 14:40 신고 안녕하세요. 일단은 7월 말까지 제가 일정이 빡빡해서 7월말 이후에나 가능할 것 같습니다.
    자세한 이야기를 댓글로 쓰기에는 어려울 듯 하니 gmail로 메일을 하나 보내주시기 바랍니다.
  • 프로필사진 대용 2020.12.01 20:38 음... 좀 애매한데요, 말씀하시는 graceful restart 는 각 L4 이상 프로토콜, 어플리케이션별 개념이고 책에 나와있는 gracefully는 TCP레벨에서 말씀 하신대로 '깔끔하게 끝났네?' 정도로 사용된거라서 의미가 다릅니다.
    이건 매 순간순간의 독자, 화자와 청자의 이해 범위의 문제인거 같은데요...
    위에서 말씀 하신것과 비슷하게 TCP flow 에 안맞는 패킷이 들어오는 말같지도 않은 경우가... 여러 네트워크 장비를 거치면서 발생하기도 합니다.
    혹은 커널이 삐꾸나는 경우도 있고 두개가 섞이는 말같지도 않은 경우가ㅜㅜ 발생하기도 해서... TCP 레벨에서 gracefully 하게 종료 되는 경우를 사람들끼리 이야기 하는 경우는 꽤 많습니다.
    장애나서 원인 파악하다가 TCP seq, ack 값을 를 서버, 클라이언트별로 맞춰 보는 경우가... 있습니다.
    그런데 실제로 안맞고;;
    apache httpd 서버에서 graceful restart 와 tcp graceful close 는 이러한 상황에 따라서 안맞을수 있습니다.
    httpd 서버는 graceful 하게 종료 처리를 했는데 중간 네트워크 장비에서 클라이언트를 향해 graceful 하지 않게 close처리 할수 있는거고요...




  • 프로필사진 sunyzero 2020.12.02 17:30 신고 좋은 의견 감사합니다.

    말씀하신 깔끔하게 끝났네라는 의미도 통한다고 생각합니다만, 제 생각에는 이런 설명은 함축적이므로 때에 따라서는 틀린 설명이 될 수 있다고 느껴집니다.
    왜냐하면 graceful에는 유예의 의미가 있기 때문에 그냥 깔끔하다는 의미로는 설명하면 유예가 없이 바로 끝난다는 의미가 더 강하기 때문입니다.

    대용님께서는 프로토콜 위주로 설명하시면서 L4 layer를 말씀하시고 계시지만, 실제로 위의 graceful close는 L4 프로토콜 레벨의 규칙이 아니라 IEEE std. 1003.1 XSI, XBD의 close()함수의 동작 semantic에 대한 부분입니다. 물론 이런 애매한 표현은 표준에서는 사용하지 않습니다. 그래서 최근의 표준 문서들은 애매한 terminology를 삭제하고 명확한 단어를 쓰도록 강제하는 분위기로 가고 있습니다. 하지만 아쉽게도 국제 표준보다 이전에 쓰이던 애매한 표현들이 업계에서는 굳어져서 새로 배우는 학생들에게 혼란을 주고 있습니다.

    저는 terminology는 명확한 표현을 가져야 일을 하거나 학습을 할 때 오역이나 혼동이 없어진다고 생각하기 때문에 개인적으로는 graceful close같은 표현을 좋아하지 않습니다. 하지만 graceful OOO 같은 표현은 너무나 많이 쓰여서 이젠 없애기도 애매하죠.

    실제로 업무 지시 사항 중에 graceful migration이나 graceful operation, graceful upgrade 등등 graceful 용어를 사용한 자매품들은 많습니다. 하지만 이를 우아한 마이그레이션, 혹은 깔끔한 마이그레이션으로 이해하면 제대로 업무를 수행하기 힘들거라 봅니다. 원래 의미인 legacy 시스템에 유예를 두고 구형 시스템과 신형 시스템을 동시에 사용하면서 점진적으로 신형 시스템으로 마이그레이션한다고 표현하면 더 명확한 표현이 되겠죠. 이런 유예를 두는 의미의 단어가 한국어에는 없기 때문에 graceful을 이해하기 어렵지 않나 생각해봅니다.

    그런데 생각해보면 graceful 말고도 번역이 애매한 용어는 많죠. 당장 생각나는 것만 따져도 transparent나 canonical, regular 등등은 투명한, 표준의, 일반적인(규칙적인)으로 번역하는데 다 틀린 표현이죠.
댓글쓰기 폼