併發量:最基礎的是伺服器能夠同時連線的客戶端的數量。其次是對業務的處理,資料庫的訪問的速度
準備好4個虛擬機器
其中乙個4g記憶體,2核cpu(server)
另外三個2g記憶體,1核cpu(client)
問題1:在跑的過程中遇到了伺服器只能連線1023次就卡住不動了,connection refused 伺服器不允許連線
原因:因為每乙個連線在伺服器端相當於乙個socket(io、連線、fd),檔案系統預設的每個程序擁有的fd個數只有1024。
解決辦法:可以在/etc/escurity/limits.conf中新增,並重啟
* hard nofile 1048576
* soft nofile 1048576
硬限制是fd數量絕不能超過它,軟限制則是超過了就開始**
或者使用命令ulimit -n 1048576
。但這只是臨時的修改,系統重啟後就沒了。
問題2:更改過之後又出現了新的問題:
在客戶端做到27000-28000時會出現無法分配請求位址
connect: cannot assign requested address
error: cannot assign requested address
是客戶端的位址不能用還是伺服器的位址不能用?
原因:通過sockfd可以找到乙個五元組,即(遠端ip,遠端埠,本機ip,本機埠,proto)。這個五元組跟fd是一對一的關係。在傳送過程中遠端ip,遠端埠,本機ip以及proto都已經確定,而本機的埠號用完了,所以無法連線。
解決方法:伺服器端開多個埠,並使用listenfd對其監聽,再將其加入epoll進行統一管理。且客戶端也需要更改vim mul_port_client_epoll.c
中的最大埠個數#define max_port 100
問題3:更改之後又遇到錯誤,有乙個客戶端連線超時,連線個數在64999-65999之間,這就會聯想到65535.
解決方法依次檢視cat /proc/sys/fs/fs.file-max
(fd最大值)以及cat /proc/sys/net/netfilter/nf_conntrack_max
(防火牆規定的最大連線數)之後發現nf_conntrack_max=65535,vim /etc/sysctl.conf
中將其改為1048576fs.file-max=1048576
以及net.nv_conntrack_max=1048576
。更改之後在使用sudo sysctl -p
使其生效
問題4:之後伺服器連線了四十多萬時出現了新問題:cannot open /proc/meminfo: too many open files in system檔案開啟的過多
解決方法:檢視cat /proc /sys/fs/file-max
中file-max = 399104,所以將其設定為1048576,順便把net.nv_conntract_max也設定成1048576。
問題5:但是發現更改的時候報錯:sysctl: cannot stat /proc/sys/net/nf_conntrack_max: no such file or directory
sudo modprobe ip_conntrack
加乙個防火牆的包,之後再更改net.nv_conntract_max。
問題6:跑到八十五萬的時候,差不多占用了3.5g,這時開始了記憶體**:記憶體占用開始稍微減少。但之後記憶體占用又開始增加。
解決方案:調整tcp協議棧
sudo sysctl -p
net.ipv4.tcp_mem = 252144 524288 786432
net.ipv4.tcp_wmem = 1024 1024 2048
net.ipv4.tcp_rmem = 1024 1024 2048
對應的含義是:
tcp_mem:tcp協議棧的大小,頁配置(一頁等於4k):1g 2g 3g。<1g隨便分配,1g-2g隨便分配,2g-3g**沒用的連線,>3g禁止連線
tcp_wmem和tcp_rmem是tcp的sendbuffer和recvbuffer的大小,每乙個socket傳送緩衝區和接受緩衝區的大小。左邊的1024是資料較少時使用1024位元組。中間的1024是(預設值/預設值)1024個位元組。右邊的2048是資料較多時使用2048位元組。
sudo sysctl -p
net.ipv4.tcp_mem=252144 54288 786432
net.ipv4.tcp_wmem=1024 1024 2048
net.ipv4.tcp_rmem=1024 1024 2048
【注】
1、sockfd與網路位址(ip位址)之間有什麼關係?
通過sockfd可以找到乙個五元組,即(遠端ip,遠端埠,本機ip,本機埠,proto)。這個五元組跟fd是一對一的關係。
2、fs.file_max 和 ulimit 並不一樣,乙個是fd(fd是int型的)的最大值,另乙個是fd的最大個數
3、這種「抖動」的原因?解決辦法是什麼?
原因是只有乙個執行緒處理accept,accept佇列滿了。
解決辦法:先把accept與recv/send分開。主線程只處理accept,子執行緒處理recv/send(reactor模型)。同時也可以使用多執行緒處理accept,如redis、memcached(多執行緒)和nginx(多程序)
4、accept只從全連線佇列中取
5、這裡的全連線佇列是指建立了tcp連線但還沒有accept的socket,半連線佇列是還沒有完成三次握手的或是連線失敗的socket
併發伺服器
併發伺服器 伺服器使用多個控制線程,同時處理多個客戶請求。有關併發執行的細節取決於所用作業系統。但其思路很簡單 併發伺服器程式被分為主程式 執行緒 和控制代碼兩部分,主程式只接受來自客戶的連線請求,並為該客戶建立乙個控制線程 每乙個控制線程只與乙個客戶互動,並執行控制代碼程式。當處理完乙個客戶後,該...
併發伺服器
1.select優點 跨平台缺點 對於單個程序的檔案描述符的數量存在最大限制linux一般為1024,32位機器位1024,64位機器位2048 2 對socket進行掃瞄時是一次掃瞄的,即採用輪詢的方法,效率較低 3.遍歷列表浪費cpu時間 poll優點 解決了套接字的上限問題 缺點 效率跟sel...
伺服器併發策略
一 簡介 從本質上講,所有到達伺服器的請求都封裝在ip包中,位於網絡卡的接收緩衝區中,這時候web伺服器軟體要做的事情就是不斷地讀取這些請求,然後進行處理,並將結果寫到傳送緩衝區,這其中包含了一系列的i o操作和cpu計算,而設計乙個併發策略的目的,就是讓i o操作和cpu計算盡量重疊進行。二 乙個...