리눅스 시스템에서 TCP 연결 수에 영향을 미치는 주요 요인은 메모리와 허용되는 파일 설명자 수입니다. 각 TCP 연결은 일정량의 메모리를 차지하고 각 소켓은 파일 설명자이기 때문입니다. 1024 일반적으로 예약된 포트입니다.
이 튜토리얼의 운영 환경: linux7.3 시스템, Dell G3 컴퓨터.
TCP 애플리케이션에서는 서버가 미리 고정된 포트에서 수신 대기하고 클라이언트가 적극적으로 연결을 시작하며 3방향 핸드셰이크 후에 TCP 연결이 설정됩니다. 그렇다면 단일 머신의 경우 최대 동시 TCP 연결 수는 얼마입니까?
TCP 연결을 식별하는 방법
최대 연결 수를 결정하기 전에 먼저 시스템이 TCP 연결을 식별하는 방법을 살펴보겠습니다. 시스템은 4-튜플을 사용하여 TCP 연결({localip, localport,remoteip,remoteport})을 고유하게 식별합니다.
클라이언트에 대한 최대 TCP 연결 수
클라이언트가 TCP 연결 요청을 시작할 때마다 포트가 바인딩되지 않은 경우 시스템은 일반적으로 유휴 로컬 포트(로컬 포트)를 선택합니다. 다른 TCP 연결은 공유됩니다. TCP 포트의 데이터 유형은 unsigned short이므로 로컬 포트의 최대 개수는 65536개에 불과합니다. 포트 0은 특별한 의미를 가지며 이러한 방식으로 사용할 수 있는 포트는 최대 65535개뿐입니다. 클라이언트로 사용되는 경우 클라이언트의 최대 TCP 연결 수는 65535이며 이러한 연결은 다른 서버 IP에 연결될 수 있습니다.
서버의 최대 TCP 연결 수
서버는 일반적으로 로컬 포트에서 수신하도록 고정되어 클라이언트의 연결 요청을 기다립니다. 주소 재사용(유닉스의 SO_REUSEADDR 옵션)을 고려하지 않고, 서버 측에 IP가 여러 개 있어도 로컬 리스닝 포트는 배타적이므로, 원격 IP(즉, 클라이언트 IP)와 원격 포트(클라이언트)만 존재한다. 서버 측 TCP 포트의 4튜플)은 가변적이므로 최대 TCP 연결 수는 클라이언트 IP 수 × 클라이언트 포트 수입니다. IP 주소 분류와 같은 요소에 관계없이 최대 TCP 연결은 약 2의 32승(IP 수) × 2의 16승(포트 수)입니다. 즉, 서버 측 단일 시스템의 최대 TCP 연결 수는 약 2의 48승입니다. .
실제 TCP 연결 수
위는 단일 머신에 대한 이론적인 최대 연결 수입니다. 실제 환경에서는 머신 리소스, 운영체제 등에 의해 제한되며 특히 서버 측에서 그렇습니다. , 최대 동시 TCP 연결 수가 이론상 상한에 도달하지 못했습니다. Unix/Linux에서 연결 수를 제한하는 주요 요인은 메모리와 허용되는 파일 설명자 수입니다(각 TCP 연결은 일정량의 메모리를 점유하며 각 소켓은 파일 설명자입니다). 또한 1024 미만의 포트는 일반적으로입니다. 예약되었습니다. 기본 2.6 커널 구성에서 테스트 후 각 소켓은 15~20k의 메모리를 차지합니다.
따라서 서버 측에서는 메모리를 늘리고 최대 파일 설명자 수와 같은 매개변수를 수정하여 단일 시스템의 최대 동시 TCP 연결 수를 100,000개 이상, 심지어 수백만 개까지 늘리는 데 문제가 없습니다.
이것은 분명히 오해입니다. 65535는 사용 가능한 총 포트 수를 의미합니다. 이는 서버가 동시에 65535개의 동시 연결만 허용한다는 의미는 아닙니다.
예:
우리는 웹사이트를 만들고 이를 TCP 포트 80에 바인딩했습니다. 결과적으로 이 웹사이트를 방문하는 모든 사용자는 다른 포트가 아닌 서버의 포트 80에 액세스하게 됩니다. 표시되는 포트는 재사용할 수 있습니다. Linux 서버가 포트 80에서만 서비스를 수신하는 경우에도 10만 또는 100만 명의 사용자가 서버에 연결할 수 있습니다. Linux 시스템은 연결 수를 제한하지 않습니다. 서버가 그렇게 많은 연결을 견딜 수 있는지 여부는 서버의 하드웨어 구성, 소프트웨어 아키텍처 및 최적화에 따라 다릅니다.
우리는 두 프로세스가 통신하기 위한 가장 기본적인 전제 조건이 프로세스를 고유하게 식별할 수 있어야 한다는 것을 알고 있습니다. 로컬 프로세스 통신에서는 PID를 사용하여 프로세스를 고유하게 식별할 수 있지만 PID는 로컬에서만 고유하며 네트워크의 두 프로세스 간에 PID 충돌 가능성이 매우 높습니다.
이때, IP 주소는 호스트를 고유하게 식별할 수 있고, TCP 계층 프로토콜과 포트 번호는 호스트의 프로세스를 고유하게 식별할 수 있는 방법을 찾아야 합니다. 번호는 네트워크에서 프로세스를 고유하게 식별하는 데 사용될 수 있습니다.
네트워크에서 프로세스를 고유하게 식별할 수 있게 되면 소켓을 사용하여 통신할 수 있습니다. 소켓은 애플리케이션 계층과 전송 계층 사이의 추상화 계층으로, TCP/IP 계층의 복잡한 작업을 애플리케이션 계층이 네트워크에서 통신하기 위한 프로세스를 호출하고 구현할 수 있도록 몇 가지 간단한 인터페이스로 추상화합니다.
소켓은 Unix에서 시작되었으며 "열기-읽기/쓰기-닫기" 모드를 구현한 것입니다. 연결이 설정되고 열린 후에는 서버와 클라이언트가 각각 "파일"을 유지 관리합니다. 자신의 파일에 쓰기 상대방이 읽을 수 있도록 내용을 입력하거나 상대방의 내용을 읽고 통신이 끝나면 파일을 닫습니다.
연결을 결정할 수 있는 유일한 것은 4가지입니다:
1.
2. 서버의 포트
3. 클라이언트의 IP
4. 클라이언트의 포트
클라이언트의 IP와 포트가 서로 다른 한 서버의 IP와 포트는 동일하게 유지될 수 있습니다. .
소켓은 다중 연결을 설정할 수 있습니다. TCP 연결은 4개의 튜플(source_ip, source_port, Destination_ip, Destination_port), 즉 (소스 IP, 소스 포트, 대상 IP, 대상 포트) 4개 조합으로 표시됩니다. 요소의. 네 가지 요소의 조합에서 한 요소가 다른 한 다른 연결을 구별할 수 있습니다.
예:
->호스트 IP 주소는 1.1.1.1이고 포트 8080에서 수신 대기 중입니다.
->2.2.2.2에서 연결 요청이 오면 포트는 5555입니다. 이 연결의 4-튜플은 (1.1.1.1, 8080, 2.2.2.2, 5555)
-> 이때 2.2.2.2는 포트 6666으로 두 번째 연결 요청을 보냈습니다. 새 연결의 4튜플은 (1.1.1.1, 8080, 2.2.2.2, 6666)
그런 다음 호스트의 포트 8080에 두 개의 연결이 설정되었습니다;
-> ) 세 번째 연결 요청에서는 포트가 5555(또는 6666)입니다. 세 번째 연결에 대한 요청은 위의 두 연결과 구별할 수 있는 방법이 없기 때문에 설정할 수 없습니다.
마찬가지로, 같은 포트번호와 IP 주소에 TCP 소켓과 UDP 소켓을 묶을 수 있습니다
포트 번호는 같지만 프로토콜이 다르기 때문에 포트는 완전히 독립적입니다.
TCP/UDP는 일반적으로 연결을 찾기 위해 5개의 튜플을 사용합니다:
source_ip, source_port, Destination_ip, Destination_port, Protocol_type
즉 (소스 IP, 소스 포트, 대상 IP, 대상 포트, 프로토콜 번호)
정리하자면, 동시 서버 수는 TCP의 65535 포트에 의해 결정되지 않습니다. 서버가 동시에 견딜 수 있는 동시성 수는 대역폭, 하드웨어, 프로그램 설계 등 다양한 요소에 의해 결정됩니다.
Taobao, Tencent, Toutiao, Baidu, Sina, BeepBeep 등이 서버 클러스터를 사용하기 때문에 초당 수억 건의 동시 액세스를 견딜 수 있는 이유를 이해할 수 있습니다. 서버 클러스터는 전국의 대규모 전산실에 분산되어 있으며, 방문 횟수가 적을 경우 일부 서버를 종료하고, 방문 횟수가 많을 경우 지속적으로 새로운 서버를 개설합니다.
Linux에서 네트워크 서버 프로그램을 작성하는 친구는 각 TCP 연결이 파일 설명자를 차지한다는 것을 알아야 합니다. 이 파일 설명자를 모두 사용하면 새 연결이 오류에 반환됩니다. "소켓/파일:너무 많은 파일을 열 수 없습니다".
이제 운영 체제의 열 수 있는 최대 파일 수 제한을 이해해야 합니다.
프로세스 제한
ulimit -n을 실행하면 1024가 출력됩니다. 이는 프로세스가 최대 1024개의 파일만 열 수 있음을 의미하므로 이 기본 구성을 사용하면 최대 수천 개의 TCP 연결을 동시에 실행할 수 있습니다.
임시 수정 : ulimit -n 1000000. 단, 이 임시 수정은 현재 로그인한 사용자의 현재 사용 환경에만 유효하며 시스템을 다시 시작하거나 사용자가 로그아웃한 후에는 유효하지 않습니다.
다시 시작한 후 무효화되는 수정 사항(그러나 CentOS 6.5에서 테스트한 결과 다시 시작한 후 무효성을 발견하지 못함): /etc/security/limits.conf 파일을 편집하고 수정된 내용은
* Soft nofile입니다. 1000000<code>* soft nofile 1000000
* hard nofile 1000000
永久修改:编辑/etc/rc.local,在其后添加如下内容
ulimit -SHn 1000000
全局限制
执行 cat /proc/sys/fs/file-nr 输出 9344 0 592026
,分别为:1.已经分配的文件句柄数,2.已经分配但没有使用的文件句柄数,3.最大文件句柄数。但在kernel 2.6版本中第二项的值总为0,这并不是一个错误,它实际上意味着已经分配的文件描述符无一浪费的都已经被使用了 。
我们可以把这个数值改大些,用 root 权限修改 /etc/sysctl.conf 文件:
fs.file-max = 1000000
net.ipv4.ip_conntrack_max = 1000000
net.ipv4.netfilter.ip_conntrack_max = 1000000
* hard nofile 1000000
전역 제한 사항 🎜🎜🎜🎜 cat /proc/sys/fs/file-nr을 실행하면
9344 0 592026
이 출력됩니다. 1. 할당된 파일 핸들 수 2. 파일 할당되었으나 사용되지 않은 핸들 수, 3. 최대 파일 핸들 수입니다. 그러나 커널 버전 2.6에서는 두 번째 항목의 값이 항상 0입니다. 이는 실제로 할당된 파일 설명자가 모두 사용되었음을 의미합니다. 🎜🎜🎜🎜이 값을 더 큰 값으로 변경하고 /etc/sysctl.conf 파일을 루트 권한으로 수정할 수 있습니다: 🎜🎜fs.file-max = 1000000
🎜🎜net. ipv4.ip_conntrack_max = 1000000
🎜🎜net.ipv4.netfilter.ip_conntrack_max = 1000000
🎜🎜🎜🎜🎜🎜🎜상식 2: 포트 번호 범위 제한? 🎜🎜🎜운영 체제에서 1024 미만의 포트 번호는 시스템에 예약되어 있으며 1024-65535는 사용자가 사용합니다. 각 TCP 연결은 포트 번호를 차지하므로 최대 60,000개 이상의 동시 연결을 가질 수 있습니다. 이런 잘못된 생각을 가지고 있는 친구들은 많지 않은 것 같아요. (예전에도 그렇게 생각했어요)🎜🎜분석해보자🎜TCP 연결을 식별하는 방법: 시스템은 4-튜플을 사용하여 TCP 연결을 고유하게 식별합니다: {로컬 IP, 로컬 포트, 원격 IP, 원격 포트}. 그럼 "UNIX 네트워크 프로그래밍: 1권" 4장에서 accept에 대한 설명을 꺼내서 개념적인 내용을 살펴보겠습니다. 두 번째 매개변수 cliaddr은 클라이언트의 IP 주소와 포트 번호를 나타냅니다. 서버로서 우리는 실제로 바인드 중에만 포트를 사용합니다. 이는 포트 번호 65535가 동시성 양에 대한 제한이 아님을 보여줍니다.
서버에 대한 최대 TCP 연결 수: 서버는 일반적으로 클라이언트의 연결 요청을 기다리면서 로컬 포트에서 수신 대기하도록 고정되어 있습니다. 주소 재사용(Unix의 SO_REUSEADDR 옵션)을 고려하지 않고 서버측에 IP가 여러 개 있어도 로컬 수신 포트는 배타적이므로 서버측 tcp 연결 4-tuple에는 원격 IP(즉, 클라이언트 IP)만 있습니다. ) 및 원격 포트(클라이언트 포트)는 가변적이므로 최대 TCP 연결 수는 클라이언트 IP 수 × 클라이언트 포트 수입니다. IPV4의 경우 IP 주소 분류와 관계없이 최대 TCP 연결 수는 대략적으로 나타납니다. 2의 32승(IP 수) )×2의 16승(포트 수), 즉 단일 서버 측의 최대 TCP 연결 수는 약 2의 48승입니다.
Linux 플랫폼에서 높은 처리량을 처리할 때 클라이언트 프로그램을 작성하든, 서버 프로그램을 작성하든. -동시성 TCP 연결, 최고 동시성 수는 단일 사용자 프로세스가 동시에 열 수 있는 파일 수에 대한 시스템 제한의 적용을 받습니다(이는 시스템이 각 TCP 연결에 대해 소켓 핸들을 생성하기 때문입니다. 각 소켓 핸들은 파일 핸들이기도 합니다). ulimit 명령을 사용하면 시스템에서 현재 사용자 프로세스가 열 수 있도록 허용하는 파일 수에 대한 제한을 볼 수 있습니다.
[speng@as4 ~]$ ulimit -n 1024
이는 현재 사용자의 각 프로세스가 동시에 최대 1024개의 파일을 열 수 있음을 의미합니다. 이 1024개의 파일 중에서 각 프로세스가 열어야 하는 표준, 입력, 표준 출력, 표준 오류, 서버 청취 소켓, 프로세스 간 통신을 위한 유닉스 도메인 소켓 및 기타 파일을 제거하고 남은 파일 수를 제거해야 합니다. 클라이언트 소켓 연결에 사용되는 것은 약 1024-10=1014입니다. 즉, 기본적으로 Linux 기반 통신 프로그램은 동시에 최대 1014개의 동시 TCP 연결을 허용합니다.
더 많은 수의 동시 TCP 연결을 지원하려는 통신 핸들러의 경우 Linux는 현재 사용자 프로세스에서 동시에 열리는 파일 수에 대한 소프트 제한(소프트 제한) 및 하드 제한(하드 제한) 을 수정해야 합니다. 소프트 제한은 Linux가 현재 시스템이 견딜 수 있는 범위 내에서 사용자가 동시에 열 수 있는 파일 수를 추가로 제한한다는 것을 의미합니다. 하드 제한은 시스템이 동시에 열 수 있는 최대 파일 수입니다. 시스템 하드웨어 리소스(주로 시스템 메모리)를 기반으로 합니다. 일반적으로 소프트 제한은 하드 제한보다 작거나 같습니다.
위 제한 사항을 수정하는 가장 쉬운 방법은 ulimit 명령을 사용하는 것입니다:
[speng@as4 ~]$ ulimit -n
위 명령에서 설정할 단일 프로세스에서 열 수 있는 최대 파일 수를 지정합니다. 시스템에서 "Operation notpermitted"와 같은 메시지가 표시되면 위의 제한 수정이 실패했음을 의미합니다. 실제로는 에 지정된 값이 사용자가 연 파일 수에 대한 Linux 시스템의 소프트 제한 또는 하드 제한을 초과했기 때문입니다. 따라서 사용자를 위해 열린 파일 수에 대한 Linux 시스템의 소프트 제한과 하드 제한을 수정해야 합니다.
1단계, /etc/security/limits.conf 파일을 수정하고 파일에 다음 줄을 추가합니다.
... # End of file speng soft nofile 10240 speng hard nofile 10240 root soft nofile 65535 root hard nofile 65535 * soft nofile 65535 * hard nofile 65535 [test@iZwz9e1dh1nweaex8ob5b7Z config]$
speng은 수정할 사용자의 열린 파일 제한을 지정하며 '*' 기호는 다음과 같습니다. 모든 사용자에 대한 수정 제한을 나타내는 데 사용됩니다. 소프트 또는 하드 제한은 소프트 제한을 수정할지 여부를 지정합니다. 10240은 수정하려는 새 제한 값, 즉 최대 열려 있는 파일 수를 지정합니다. 제한 값은 하드 제한보다 작거나 같아야 합니다. 변경 후 파일을 저장합니다.
두 번째 단계, /etc/pam.d/login 파일을 수정하고 파일에 다음 줄을 추가합니다.
session required /lib/security/pam_limits.so
이는 Linux에 사용자가 시스템 로그인을 완료한 후 pam_limits.so를 호출해야 함을 알려줍니다. 시스템 제한을 설정하는 모듈 사용자가 사용할 수 있는 다양한 리소스 수에 대한 최대 제한(사용자가 열 수 있는 최대 파일 수에 대한 제한 포함), pam_limits.so 모듈은 / etc/security/limits.conf 파일을 사용하여 이러한 제한 값을 설정하십시오. 수정 후 이 파일을 저장하세요.
세 번째 단계, Linux 시스템 수준에서 최대 열려 있는 파일 수를 확인하고 다음 명령을 사용합니다.
[speng@as4 ~]$ cat /proc/sys/fs/file-max 12158
이는 이 Linux 시스템에서 동시에 최대 12158개의 파일을 열 수 있음을 보여줍니다. 열려 있는 파일 수에 대한 모든 사용자 수준 제한은 이 값을 초과할 수 없습니다. 일반적으로 이 시스템 수준 하드 제한은 Linux 시스템이 시작될 때 시스템 하드웨어 리소스를 기반으로 계산된 동시에 열리는 최적의 최대 파일 수입니다. 특별한 필요가 없는 경우 제한을 원하지 않는 한 이 제한을 수정해서는 안 됩니다. 사용자 수준에서 열린 파일 수는 이 제한을 초과하는 값을 설정하십시오. 이 하드 제한을 수정하는 방법은 /etc/rc.local 스크립트를 수정하고 스크립트에 다음 줄을 추가하는 것입니다:
echo 22158 > /proc/sys/fs/file-max
이는 Linux가 열려 있는 파일 수에 대한 시스템 수준 하드 제한을 강제로 설정하도록 하기 위한 것입니다. 22158 시작이 완료된 후입니다. 수정 후 이 파일을 저장하세요.
完成上述步骤后重启系统,一般情况下就可以将Linux系统对指定用户的单一进程允许同时打开的最大文件数限制设为指定的数值。如果重启后用 ulimit-n命令查看用户可打开文件数限制仍然低于上述步骤中设置的最大值,这可能是因为在用户登录脚本/etc/profile中使用ulimit -n命令已经将用户可同时打开的文件数做了限制。由于通过ulimit-n修改系统对用户可同时打开文件的最大数限制时,新修改的值只能小于或等于上次 ulimit-n设置的值,因此想用此命令增大这个限制值是不可能的。所以,如果有上述问题存在,就只能去打开/etc/profile脚本文件,在文件中查找是否使用了ulimit-n限制了用户可同时打开的最大文件数量,如果找到,则删除这行命令,或者将其设置的值改为合适的值,然后保存文件,用户退出并重新登录系统即可。
通过上述步骤,就为支持高并发TCP连接处理的通讯处理程序解除关于打开文件数量方面的系统限制。
在Linux上编写支持高并发TCP连接的客户端通讯处理程序时,有时会发现尽管已经解除了系统对用户同时打开文件数的限制,但仍会出现并发TCP连接数增加到一定数量时,再也无法成功建立新的TCP连接的现象。出现这种现在的原因有多种。
第一种原因可能是因为Linux网络内核对本地端口号范围有限制。此时,进一步分析为什么无法建立TCP连接,会发现问题出在connect()调用返回失败,查看系统错误提示消息是“Can’t assign requestedaddress”。同时,如果在此时用tcpdump工具监视网络,会发现根本没有TCP连接时客户端发SYN包的网络流量。这些情况说明问题在于本地Linux系统内核中有限制。其实,问题的根本原因在于Linux内核的TCP/IP协议实现模块对系统中所有的客户端TCP连接对应的本地端口号的范围进行了限制(例如,内核限制本地端口号的范围为1024~32768之间)。当系统中某一时刻同时存在太多的TCP客户端连接时,由于每个TCP客户端连接都要占用一个唯一的本地端口号(此端口号在系统的本地端口号范围限制中),如果现有的TCP客户端连接已将所有的本地端口号占满,则此时就无法为新的TCP客户端连接分配一个本地端口号了,因此系统会在这种情况下在connect()调用中返回失败,并将错误提示消息设为“Can’t assignrequested address”。有关这些控制逻辑可以查看Linux内核源代码,以linux2.6内核为例,可以查看tcp_ipv4.c文件中如下函数:
static int tcp_v4_hash_connect(struct sock *sk)
请注意上述函数中对变量sysctl_local_port_range的访问控制。变量sysctl_local_port_range的初始化则是在tcp.c文件中的如下函数中设置:
void __init tcp_init(void)
内核编译时默认设置的本地端口号范围可能太小,因此需要修改此本地端口范围限制。
第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
net.ipv4.ip_local_port_range = 1024 65000
这表明将系统对本地端口范围限制设置为1024~65000之间。请注意,本地端口范围的最小值必须大于或等于1024;而端口范围的最大值则应小于或等于65535。修改完后保存此文件。
第二步,执行sysctl命令:
[speng@as4 ~]$ sysctl -p
如果系统没有错误提示,就表明新的本地端口范围设置成功。如果按上述端口范围进行设置,则理论上单独一个进程最多可以同时建立60000多个TCP客户端连接。
第二种无法建立TCP连接的原因可能是因为Linux网络内核的IP_TABLE防火墙对最大跟踪的TCP连接数有限制。此时程序会表现为在 connect()调用中阻塞,如同死机,如果用tcpdump工具监视网络,也会发现根本没有TCP连接时客户端发SYN包的网络流量。由于 IP_TABLE防火墙在内核中会对每个TCP连接的状态进行跟踪,跟踪信息将会放在位于内核内存中的conntrackdatabase中,这个数据库的大小有限,当系统中存在过多的TCP连接时,数据库容量不足,IP_TABLE无法为新的TCP连接建立跟踪信息,于是表现为在connect()调用中阻塞。此时就必须修改内核对最大跟踪的TCP连接数的限制,方法同修改内核对本地端口号范围的限制是类似的:
第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
net.ipv4.ip_conntrack_max = 10240
这表明将系统对最大跟踪的TCP连接数限制设置为10240。请注意,此限制值要尽量小,以节省对内核内存的占用。
第二步,执行sysctl命令:
[speng@as4 ~]$ sysctl -p
如果系统没有错误提示,就表明系统对新的最大跟踪的TCP连接数限制修改成功。如果按上述参数进行设置,则理论上单独一个进程最多可以同时建立10000多个TCP客户端连接。
在Linux上编写高并发TCP连接应用程序时,必须使用合适的网络I/O技术和I/O事件分派机制。
可用的I/O技术有同步I/O,非阻塞式同步I/O(也称反应式I/O),以及异步I/O。《BIO,NIO,AIO的理解》
在高TCP并发的情形下,如果使用同步I/O,这会严重阻塞程序的运转,除非为每个TCP连接的I/O创建一个线程。但是,过多的线程又会因系统对线程的调度造成巨大开销。因此,在高TCP并发的情形下使用同步 I/O是不可取的,这时可以考虑使用非阻塞式同步I/O或异步I/O。非阻塞式同步I/O的技术包括使用select(),poll(),epoll等机制。异步I/O的技术就是使用AIO。
从I/O事件分派机制来看,使用select()是不合适的,因为它所支持的并发连接数有限(通常在1024个以内)。如果考虑性能,poll()也是不合适的,尽管它可以支持的较高的TCP并发数,但是由于其采用“轮询”机制,当并发数较高时,其运行效率相当低,并可能存在I/O事件分派不均,导致部分TCP连接上的I/O出现“饥饿”现象。而如果使用epoll或AIO,则没有上述问题(早期Linux内核的AIO技术实现是通过在内核中为每个 I/O请求创建一个线程来实现的,这种实现机制在高并发TCP连接的情形下使用其实也有严重的性能问题。但在最新的Linux内核中,AIO的实现已经得到改进)。
综上所述,在开发支持高并发TCP连接的Linux应用程序时,应尽量使用epoll或AIO技术来实现并发的TCP连接上的I/O控制,这将为提升程序对高并发TCP连接的支持提供有效的I/O保证。
内核参数sysctl.conf的优化
/etc/sysctl.conf 是用来控制linux网络的配置文件,对于依赖网络的程序(如web服务器和cache服务器)非常重要,RHEL默认提供的最好调整。
推荐配置(把原/etc/sysctl.conf内容清掉,把下面内容复制进去):
net.ipv4.ip_local_port_range = 1024 65536 net.core.rmem_max=16777216 net.core.wmem_max=16777216 net.ipv4.tcp_rmem=4096 87380 16777216 net.ipv4.tcp_wmem=4096 65536 16777216 net.ipv4.tcp_fin_timeout = 10 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_window_scaling = 0 net.ipv4.tcp_sack = 0 net.core.netdev_max_backlog = 30000 net.ipv4.tcp_no_metrics_save=1 net.core.somaxconn = 262144 net.ipv4.tcp_syncookies = 0 net.ipv4.tcp_max_orphans = 262144 net.ipv4.tcp_max_syn_backlog = 262144 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 2
这个配置参考于cache服务器varnish的推荐配置和SunOne 服务器系统优化的推荐配置。
varnish调优推荐配置的地址为:http://varnish.projects.linpro.no/wiki/Performance
不过varnish推荐的配置是有问题的,实际运行表明“net.ipv4.tcp_fin_timeout = 3”的配置会导致页面经常打不开;并且当网友使用的是IE6浏览器时,访问网站一段时间后,所有网页都会打不开,重启浏览器后正常。可能是国外的网速快吧,我们国情决定需要调整“net.ipv4.tcp_fin_timeout = 10”,在10s的情况下,一切正常(实际运行结论)。
修改完毕后,执行:
/sbin/sysctl -p /etc/sysctl.conf /sbin/sysctl -w net.ipv4.route.flush=1
命令生效。为了保险起见,也可以reboot系统。
调整文件数:
linux系统优化完网络必须调高系统允许打开的文件数才能支持大的并发,默认1024是远远不够的。
执行命令:
echo ulimit -HSn 65536 >> /etc/rc.local echo ulimit -HSn 65536 >>/root/.bash_profile ulimit -HSn 65536
备注:
对mysql用户可同时打开文件数设置为10240个;
将Linux系统可同时打开文件数设置为1000000个(一定要大于对用户的同时打开文件数限制);
将Linux系统对最大追踪的TCP连接数限制为20000个(但是,建议设置为10240;因为对mysql用户的同时打开文件数已经限制在10240个;且较小的值可以节省内存);
将linux系统端口范围配置为1024~30000(可以支持60000个以上连接,不建议修改;默认已经支持20000个以上连接);
综合上述四点,TCP连接数限制在10140个。
这10240个文件中还得除去每个进程必然打开的标准输入,标准输出,标准错误,服务器监听 socket,进程间通讯的unix域socket等文件。
因此,当需要对TCP连接数进行调整时只需要调整ulimit参数。
Linux下查看tcp连接数及状态命令:
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
相关推荐:《Linux视频教程》
위 내용은 Linux 시스템의 TCP 연결 수에 영향을 미치는 요인은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!