您好,登錄后才能下訂單哦!
這篇文章主要介紹了怎么測試Linux下tcp最大連接數(shù)的方法,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
關(guān)于TCP服務(wù)器最大并發(fā)連接數(shù)有一種誤解就是“因為端口號上限為65535,所以TCP服務(wù)器理論上的可承載的最大并發(fā)連接數(shù)也是65535”。
先說結(jié)論:對于TCP服務(wù)端進程來說,他可以同時連接的客戶端數(shù)量并不受限于可用端口號。并發(fā)連接數(shù)受限于linux可打開文件數(shù),這個數(shù)是可以配置的,可以非常大,所以實際上受限于系統(tǒng)性能。
現(xiàn)在做服務(wù)器開發(fā)不加上高并發(fā)根本沒臉出門,所以為了以后吹水被別人懟“天天提高并發(fā),你自己實現(xiàn)的最高并發(fā)是多少”的時候能義正言辭的懟回去,趁著元旦在家沒事決定自己寫個demo搞一搞。
這個測試主要是想搞明白Linux下哪些參數(shù)配置限制了連接數(shù)的最大值,上限是多少。
一、先說下demo的思路:
服務(wù)端用epoll實現(xiàn),就是簡簡單單的接收連接,然后客戶端用go的goroutine,每個goroutine就是簡單的建立連接,然后什么也不做。
上代碼:
server:
/* * g++ -o test_epoll ./test_epoll.c */ #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/epoll.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> int SetReuseAddr(int fd) { int optval = 1; socklen_t optlen = sizeof(optval); return setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, optlen); } int main() { int fd = socket(AF_INET, SOCK_STREAM, 0); int iRet = SetReuseAddr(fd); if (iRet != 0) { printf("setsockopt for SO_REUSEADDR failed, error:%s\n", strerror(iRet)); return iRet; } struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(8080); addr.sin_addr.s_addr = INADDR_ANY; if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { printf("bind failed, error:%s\n", strerror(errno)); return errno; } if (listen(fd, 5) == -1) { printf("listen failed, error:%s\n", strerror(errno)); return errno; } printf("Listening on 8080...\n"); int epfd = epoll_create(102400); struct epoll_event event; event.events = EPOLLIN; event.data.fd = fd; epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event); struct epoll_event revents[102400]; int iOnline = 0; while (1) { int num = epoll_wait(epfd, revents, 102400, 60 * 1000); printf("epoll_wait return %d\n", num); if (num > 0) { for (int i = 0; i < num; i++) { if (revents[i].data.fd == fd) { int client; struct sockaddr_in cli_addr; socklen_t cli_addr_len = sizeof(cli_addr); client = accept(fd, (struct sockaddr*)&cli_addr, &cli_addr_len); if (client == -1) { printf("accept failed, error:%s\n", strerror(errno)); if (errno == EMFILE) { printf("per-process limit reached\n"); exit(errno); } if (errno == ENFILE) { printf("system-wide limit reached\n"); exit(errno); } continue; } iOnline++; printf("Receive a new connection from %s:%d\n", inet_ntoa(cli_addr.sin_addr), cli_addr.sin_port); event.events = EPOLLIN; event.data.fd = client; epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event); } } } printf("Online number:%d\n", iOnline); } return 0; }
client:
package main import ( "net" "fmt" "time" "strconv" "runtime" ) func Connect(host string, port int) { _, err := net.Dial("tcp", host+":"+strconv.Itoa(port)) if err != nil { fmt.Printf("Dial to %s:%d failed\n", host, port) return } for { time.Sleep(30 * 1000 * time.Millisecond) } } func main() { count := 0 for { go Connect("192.168.63.128", 8080) count++; fmt.Printf("Gorutue num:%d\n", runtime.NumGoroutine()) time.Sleep(100 * time.Millisecond) } }
二、開始測試
第一次:
先說結(jié)果,連接數(shù)達到1031時accept失敗了,當(dāng)時還沒有對errno做判斷,所以只打印輸出了accept失敗。
然后首先想到的是ulimit -n的限制,查看了一下,默認值1024,然后就是修改這個值,在/etc/security/limits.conf中添加一下內(nèi)容:
1 * soft nofile 102400 2 * hard nofile 102400
然后關(guān)閉當(dāng)前xshell連接,重新連接即生效,現(xiàn)在看ulimit -n就是102400了。
這兩行的意思就是將每個進程能打開的文件描述符個數(shù)的soft、hard限制調(diào)整為102400,
注:ulimit -n 102400也可以生效,但是這個修改是臨時的。
然后進行第二次測試。
第二次:
逗比了,其實連接數(shù)只有2000+,我之前還在奇怪為啥Windows的默認連接數(shù)能有這么高呢,原來有些連接已經(jīng)斷了,但是因為我沒有做處理,所以以為還在呢,看來我得再安裝一個虛擬機了[二哈]
待繼續(xù)。。。
安裝虛擬機去,
時間:2017-12-31 00:09:00
虛擬機安裝好了,接著搞,
這次是真的超過10K了。
連接數(shù)還在增加,不知道能不能最終達到10萬呢,小小的期待ing
時間:2017-12-31 00:41:00,最終上限卡在28232,golang一直報dial失敗,由于忘了打印出具體錯誤信息了,所以無從知道為什么dial失敗,所以只能再跑一次T_T
時間:2017-12-31 01:01:00,添加打印dial失敗的錯誤信息的,又跑了一遍,還是在28232時出現(xiàn)dial失敗,錯誤信息:
golang的標準庫文檔中么有對錯誤信息的解釋,從錯誤信息來看,是分配地址失敗,于是想是不是端口地址范圍限制了。
查看了一下端口地址范圍,確認就是這個限制,由于端口地址是16位,所以,就算把這個端口地址范圍修改為1024--65535,也最多能開啟64521個連接,而我現(xiàn)在只有一臺虛擬機作為客戶端,所以想要實現(xiàn)10萬連接是不可能了,但是通過這次測試,也讓我搞明白了,到底哪些參數(shù)會限制連接的上限,這就是我想要的。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“怎么測試Linux下tcp最大連接數(shù)的方法”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。