[linux] Linux에서 최대 TCP / IP 연결 수 늘리기

서버를 프로그래밍 중이며 연결 수를 “무제한”으로 설정 한 경우에도 대역폭이 포화되지 않으므로 연결 수가 제한되는 것 같습니다.

Ubuntu Linux 상자가 한 번에 열 수있는 최대 연결 수를 어떻게 늘리거나 제거 할 수 있습니까? OS가 이것을 제한합니까, 아니면 라우터 또는 ISP입니까? 아니면 다른 것입니까?



답변

최대 연결 수는 약간 다르지만 클라이언트 및 서버 측의 특정 제한에 의해 영향을받습니다.

클라이언트 쪽에서 :
ephermal 포트 범위를 늘리고tcp_fin_timeout

기본값을 찾으려면 다음을 수행하십시오.

sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_fin_timeout

ephermal 포트 범위는 호스트가 특정 IP 주소에서 작성할 수있는 최대 아웃 바운드 소켓 수를 정의합니다. 는 fin_timeout이 소켓에 남아있을 것입니다 최소 시간을 정의 TIME_WAIT상태 (한 번 사용 후 사용할 수 없게를). 일반적인 시스템 기본값은 다음과 같습니다.

  • net.ipv4.ip_local_port_range = 32768 61000
  • net.ipv4.tcp_fin_timeout = 60

이것은 기본적으로 시스템이 (61000 - 32768) / 60 = 470초당 소켓 이상을 일관되게 보장 할 수 없음을 의미합니다 . 당신이 그것에 만족하지 않으면, 당신은를 증가로 시작할 수 port_range있습니다. 15000 61000요즘 에는 범위를 설정하는 것이 일반적입니다. 을 줄이면 가용성을 더 높일 수 fin_timeout있습니다. 두 가지를 모두 수행한다고 가정하면 초당 1500 개가 넘는 아웃 바운드 연결을보다 쉽게 ​​볼 수 있습니다.

값을 변경하려면 :

sysctl net.ipv4.ip_local_port_range="15000 61000"
sysctl net.ipv4.tcp_fin_timeout=30

위의 내용은 초당 아웃 바운드 연결을위한 시스템 기능에 영향을주는 요소로 해석되어서는 안됩니다. 그러나 이러한 요소는 시스템의 동시 연결을 장기간 “활동”에 대해 지속 가능한 방식으로 처리하는 데 영향을줍니다.

에 대한 일반적인 리눅스 박스에 sysctl을 값을 기본 tcp_tw_recycletcp_tw_reuse

net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_tw_reuse=0

“사용 된”소켓 (대기 상태)에서의 연결을 허용하지 않고 소켓이 완전한 time_wait주기 를 지속하도록 강제합니다 . 설정하는 것이 좋습니다.

sysctl net.ipv4.tcp_tw_recycle=1
sysctl net.ipv4.tcp_tw_reuse=1

이를 통해 소켓의 time_wait상태를 빠르게 순환 하고 재사용 할 수 있습니다. 그러나이 변경을 수행하기 전에 이러한 소켓이 필요한 응용 프로그램에 사용할 프로토콜과 충돌하지 않는지 확인하십시오. Vincent Bernat의 “TCP TIME-WAIT 대처” 게시물을 읽고 그 의미를 이해하십시오. 이 net.ipv4.tcp_tw_recycle 옵션은 동일한 NAT 장치 뒤에있는 두 대의 다른 컴퓨터로부터의 연결을 처리하지 않기 때문에 공개 서버에 매우 문제가 있습니다. 참고 net.ipv4.tcp_tw_recycle되었습니다 제거 리눅스 4.12에서.

서버 측면에서 :net.core.somaxconn 값은 중요한 역할을한다. 청취 소켓에 대기중인 최대 요청 수를 제한합니다. 서버 응용 프로그램의 기능이 확실하면 기본 128에서 128에서 1024와 같은 수준으로 올립니다. 이제 응용 프로그램의 청취 호출에서 청취 백 로그 변수를 같거나 높은 정수로 수정하여이 증가를 활용할 수 있습니다.

sysctl net.core.somaxconn=1024

txqueuelen이더넷 카드의 매개 변수도 역할을합니다. 기본값은 1000이므로 시스템에서 처리 할 수있는 경우 최대 5000 이상으로 높이십시오.

ifconfig eth0 txqueuelen 5000
echo "/sbin/ifconfig eth0 txqueuelen 5000" >> /etc/rc.local

마찬가지로 net.core.netdev_max_backlog및 의 값을 높이십시오 net.ipv4.tcp_max_syn_backlog. 기본값은 각각 1000과 1024입니다.

sysctl net.core.netdev_max_backlog=2000
sysctl net.ipv4.tcp_max_syn_backlog=2048

이제 쉘에서 FD ulimts를 늘려서 클라이언트 및 서버 측 응용 프로그램을 모두 시작하십시오.

위의 프로그래머 외에도 프로그래머가 사용하는 하나 이상의 인기있는 기술은 tcp 쓰기 호출 수를 줄이는 것 입니다. 내가 선호하는 것은 클라이언트에 보내려는 데이터를 푸시하는 버퍼를 사용하는 것입니다. 그런 다음 적절한 지점에서 버퍼링 된 데이터를 실제 소켓에 씁니다. 이 기술을 사용하면 대용량 데이터 패킷을 사용하고, 조각화를 줄이고, 사용자 영역과 커널 수준에서 CPU 사용률을 줄일 수 있습니다.


답변

최대 연결 수를 설정하는 두 가지 변수가 있습니다. 아마도 파일 번호가 먼저 부족한 것 같습니다. ulimit -n을 확인하십시오. 그 후 / proc에 설정이 있지만 기본값은 수만입니다.

더 중요한 것은 뭔가 잘못하고있는 것 같습니다. 단일 TCP 연결은 두 당사자 간의 모든 대역폭을 사용할 수 있어야합니다. 그렇지 않은 경우 :

  • TCP 창 설정이 충분히 큰지 확인하십시오. Linux 기본값은 실제로 빠른 inet 링크 (수백 메가 바이트) 또는 빠른 위성 링크를 제외한 모든 것에 적합합니다. 대역폭 * 지연 제품은 무엇입니까?
  • 큰 패킷으로 핑을 사용하여 패킷 손실 확인 ( ping -s 1472…)
  • 속도 제한을 확인하십시오. Linux에서이 구성은tc
  • 다음과 같은 방법으로 실제로 존재한다고 생각되는 대역폭이 존재하는지 확인하십시오. iperf
  • 프로토콜이 정상인지 확인하십시오. 대기 시간을 기억하십시오.
  • 이것이 기가비트 + LAN 인 경우 점보 패킷을 사용할 수 있습니까? 당신은?

아마도 나는 오해했을 것입니다. 어쩌면 당신은 많은 연결이 필요한 Bittorrent와 같은 일을하고있을 것입니다. 그렇다면 실제로 사용중인 연결 수를 확인해야합니다 (try netstat또는 lsof). 해당 숫자가 상당하면 다음을 수행 할 수 있습니다.

  • 예를 들어 100mbps +와 같은 많은 대역폭이 있어야합니다. 이 경우 실제로 ulimit -n. 여전히 ~ 1000 개의 연결 (시스템의 기본값)은 상당히 적습니다.
  • 네트워크 속도가 느려서 연결 속도가 느려질 수 있습니다 (예 : 패킷 손실)
  • 특히 원하는 경우 IO 대역폭을 늦추는 등 무언가를 줄이십시오. 확인 했습니까 iostat -x?

또한 소비자 급 NAT 라우터 (Linksys, Netgear, DLink 등)를 사용하는 경우 수천 개의 연결에서 능력을 초과 할 수 있습니다.

이것이 도움이되기를 바랍니다. 당신은 정말로 네트워킹 질문을하고 있습니다.


답변

derobert의 답변을 개선하기 위해

nf_conntrack_max를 지정하여 OS 연결 제한을 확인할 수 있습니다.

예를 들면 다음과 같습니다. cat / proc / sys / net / netfilter / nf_conntrack_max

다음 스크립트를 사용하여 지정된 범위의 tcp 포트에 대한 tcp 연결 수를 계산할 수 있습니다. 기본적으로 1-65535입니다.

OS 연결 제한을 초과했는지 여부를 확인합니다.

여기 스크립트가 있습니다.

#!/bin/bash
OS=$(uname)

case "$OS" in
    'SunOS')
            AWK=/usr/bin/nawk
            ;;
    'Linux')
            AWK=/bin/awk
            ;;
    'AIX')
            AWK=/usr/bin/awk
            ;;
esac

netstat -an | $AWK -v start=1 -v end=65535 ' $NF ~ /TIME_WAIT|ESTABLISHED/ && $4 !~ /127\.0\.0\.1/ {
    if ($1 ~ /\./)
            {sip=$1}
    else {sip=$4}

    if ( sip ~ /:/ )
            {d=2}
    else {d=5}

    split( sip, a, /:|\./ )

    if ( a[d] >= start && a[d] <= end ) {
            ++connections;
            }
    }
    END {print connections}'


답변

응용 프로그램 수준에서 개발자가 수행 할 수있는 작업은 다음과 같습니다.

서버 측에서 :

  1. 로드 밸런서 (있는 경우)가 올바르게 작동하는지 확인하십시오.

  2. 느린 TCP 시간 초과를 503 빠른 즉시 응답으로 전환하십시오.로드 밸런서가 올바르게 작동하면 서비스 할 작업 리소스를 선택해야하며 예기치 않은 오류 마사지로 걸려있는 것보다 낫습니다.

예 : 노드 서버를 사용하는 경우 u는 npm에서 toobusy를 사용할 수 있습니다. 다음과 같은 구현 :

var toobusy = require('toobusy');
app.use(function(req, res, next) {
  if (toobusy()) res.send(503, "I'm busy right now, sorry.");
  else next();
});

왜 503입니까? 과부하에 대한 좋은 통찰력은 다음과 같습니다.
http://ferd.ca/queues-don-t-fix-overload.html

클라이언트 측에서도 몇 가지 작업을 수행 할 수 있습니다.

  1. 통화를 일괄 그룹화하고 트래픽과 총 요청 수를 클라이언트와 서버에 줄이십시오.

  2. 불필요한 중복 요청을 처리하기 위해 캐시 중간 계층을 구축하십시오.


답변