/ proc / sys / net / ipv4 / tcp_tw_reuse의 값을 변경하는 것이 위험합니까?


10

최근에 가상 머신으로 변환 된 몇 가지 프로덕션 시스템이 있습니다. MySQL 데이터베이스에 자주 액세스하는 응용 프로그램이 있으며 각 쿼리마다 연결을 만들고 쿼리하고 연결을 끊습니다.

적절한 쿼리 방법은 아니지만 (알고 있음) 해결할 수없는 제약 조건이 있습니다. 어쨌든 문제는 이것입니다. 머신이 물리적 호스트 인 동안 프로그램은 정상적으로 실행되었습니다. 가상 머신으로 변환 한 후 데이터베이스에 대한 간헐적 인 연결 문제가 발견되었습니다. 한 시점에서 TIME_WAIT에 24000+ 소켓 연결이있었습니다 (물리적 호스트에서 가장 많이 본 것은 17000입니다. 그러나 문제는 발생하지 않았습니다).

이러한 연결 문제를 다시 보지 않기 위해 이러한 연결을 재사용하고 싶습니다.

질문 :

tcp_tw_reuse의 값을 1로 설정해도 괜찮습니까? 명백한 위험은 무엇입니까? 절대 그렇게하지 말아야 할 이유 가 있습니까?

또한 너무 많은 연결이 TIME_WAIT에 들어가거나 재사용되는 것을 막기 위해 시스템 (RHEL / CentOS)을 얻는 다른 방법이 있습니까?

마지막으로 tcp_tw_recycle을 변경하면 어떤 도움이됩니까?

미리 감사드립니다!


1
링크 는 tcp_tw_recycle 및 tcp_tw_reuse의 위험을 잘 설명합니다. 사용하지 마십시오.

답변:


8

시간을 안전하게 단축 할 수 있지만 패킷 손실 또는 지터가있는 네트워크에서 연결이 제대로 닫히지 않는 문제가 발생할 수 있습니다. 나는 1 초에 튜닝을 시작하지 않고 15-30에서 시작하여 아래로 내려갑니다.

또한 응용 프로그램을 수정해야합니다.

RFC 1185 는 3.2 절에 좋은 설명이 있습니다.

TCP 연결이 닫히면 TIME-WAIT 상태에서 2 * MSL의 지연 시간이 4 분 동안 소켓 쌍을 연결합니다 ([Postel81]의 섹션 3.5 참조) 하나의 연결을 닫고 새 연결을 여는 TCP 기반 응용 프로그램 스트림 모드를 사용하는 FTP 데이터 전송 연결은 매번 새 소켓 쌍을 선택해야합니다.이 지연은 두 가지 다른 용도로 사용됩니다.

 (a)  Implement the full-duplex reliable close handshake of TCP. 

      The proper time to delay the final close step is not really 
      related to the MSL; it depends instead upon the RTO for the 
      FIN segments and therefore upon the RTT of the path.* 
      Although there is no formal upper-bound on RTT, common 
      network engineering practice makes an RTT greater than 1 
      minute very unlikely.  Thus, the 4 minute delay in TIME-WAIT 
      state works satisfactorily to provide a reliable full-duplex 
      TCP close.  Note again that this is independent of MSL 
      enforcement and network speed. 

      The TIME-WAIT state could cause an indirect performance 
      problem if an application needed to repeatedly close one 
      connection and open another at a very high frequency, since 
      the number of available TCP ports on a host is less than 
      2**16.  However, high network speeds are not the major 
      contributor to this problem; the RTT is the limiting factor 
      in how quickly connections can be opened and closed. 
      Therefore, this problem will no worse at high transfer 
      speeds. 

 (b)  Allow old duplicate segements to expire. 

      Suppose that a host keeps a cache of the last timestamp 
      received from each remote host.  This can be used to reject 
      old duplicate segments from earlier incarnations of the 

* 참고 : FIN을 보내는 쪽이 어느 정도의 안정성이 필요한지 알고 있으므로 FIN 수신자의 TIME-WAIT 지연 길이를 결정할 수 있어야합니다. 이것은 FIN 세그먼트의 적절한 TCP 옵션으로 수행 할 수 있습니다.

      connection, if the timestamp clock can be guaranteed to have 
      ticked at least once since the old conennection was open. 
      This requires that the TIME-WAIT delay plus the RTT together 
      must be at least one tick of the sender's timestamp clock. 

      Note that this is a variant on the mechanism proposed by 
      Garlick, Rom, and Postel (see the appendix), which required 
      each host to maintain connection records containing the 
      highest sequence numbers on every connection.  Using 
      timestamps instead, it is only necessary to keep one quantity 
      per remote host, regardless of the number of simultaneous 
      connections to that host.

설명 주셔서 감사합니다. 문제는 라이브러리에 있으며 제어 할 수 없습니다.
Sagar

6

이것은 귀하의 질문에 대한 답변이 아니며 (18 개월 늦었습니다) 레거시 앱 재사용 포트를 만드는 또 다른 방법을 제안합니다.

시스템에서 설정 tcp_tw_reuse(또는 tcp_tw_recycle)에 대한 유용한 대안 은 LD_PRELOAD앱에 공유 라이브러리를 사용하는 것입니다 (를 사용하여 ). 그러면 해당 라이브러리는 포트 재사용을 허용 할 수 있습니다. 이렇게하면 레거시 앱이 시스템의 모든 앱에서이를 강제로 적용하지 않고도 포트 재사용을 허용하므로 (앱을 수정하지 않아도 됨) 조정의 영향을 제한 할 수 있습니다. 예를 들어

    LD_PRELOAD=/opt/local/lib/libreuse.so ./legacy_app

이 공유 라이브러리는 socket()호출을 인터셉트하고 real socket ()을 호출하고 리턴 된 소켓에서 SO_REUSEADDR 및 / 또는 SO_REUSEPORT를 설정해야합니다. 봐 http://libkeepalive.sourceforge.net 이 작업을 수행하는 방법의 예 (킵 얼라이브에이 켜졌지만 SO_REUSEPORT 켜면 매우 유사하다). 잘못 작동하는 레거시 앱이 IPv6을 사용하는 경우 55 행 libkeepalive.c

    if((domain == PF_INET) && (type == SOCK_STREAM)) {

    if(((domain == PF_INET) || (domain == PF_INET6)) && (type == SOCK_STREAM)) {

문제가 발생하면 이메일을 보내 주시면 코드를 작성하여 보내 드리겠습니다.


6

이 값을 1로 변경하는 것이 좋다고 생각합니다. 더 적절한 방법은 명령을 사용하는 것입니다.

[root@server]# sysctl -w net.ipv4.tcp_tw_reuse=1

내가 알고있는 명백한 위험은 없지만, 빠른 Google 검색은이 링크 를 생성하여이 링크tcp_tw_reuse보다 나은 대안 임을 확인 tcp_tw_recycle하지만주의해서 사용해야합니다.


2
아니, 그건 말이 아니야 "tcp_tw_reuse에 대해 이야기합니다."
Fantius

0

연결이 TIME WAIT 인 경우 재사용 할 수 없습니다. 애플리케이션과 MySQL 사이의 네트워크에서 패킷 손실이없는 경우 시간 초과를 줄일 수 있습니다.

그러나 가장 좋은 솔루션은 데이터베이스 및 연결 풀에 대한 지속적인 연결을 사용하는 것입니다.


1
실제로, 반드시 그런 것은 아닙니다. 일부 시스템에서는 TIME_WAIT에서 소켓을 사용할 수 있습니다. 이것이 제 질문입니다. 가능 여부가 아니라 명백하고 명백하지 않은 위험은 무엇입니까? 감사!
Sagar 2019
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.