IOCP不可忽视的细节
生活随笔
收集整理的這篇文章主要介紹了
IOCP不可忽视的细节
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
IOCP構架之所以公認高效,核心就在于異步IO。在網上紛紛為之膜拜之余,很少看到對穩定性或性能優化的觀點。仔細想想,任何技術都有有利的一面,自然也有有弊的一面,這才符合辯證法思想。?
我把自己在編寫IOCP構架時重點處理的幾個地方交代一下,如果你想認真寫好一個穩定的IOCP服務端,建議重新規劃以下幾個細節。?
1)不要修改套接字默認的收發緩沖區大小,即8192字節=8K=2分頁。?
2)總所周知,x86頁面置換最少需要1分頁,所以不管IOCP的重疊IO涉及多少字節,OS至少需要加鎖/解鎖1分頁,在使用異步WSARecv/WSASend時,只要重疊緩沖區WSABuf的長度大于0,那么在投遞異步操作時,系統至少會鎖定1分頁的非頁面內存,而系統的非頁面緩沖池是有大小限制的,如果你的IOCP消耗了太多非分頁內存。輕則同服務器其他網絡進程無法使用網絡,重則可能會導致系統藍屏或其他崩潰。而對于你的IOCP服務端通訊,常見的現象是客戶端無法與服務端進行連接,或者收發包時出現 10055 。?
3)正是由于情況2的出現可能性,所以在投遞WSARecv/WSASend時,絕對不要貪圖簡單,直接進行投遞,正確的做法應該為每個套接字建立至少2個緩沖隊列,一收一發。?
4)對于同一個客戶端套接字,在同一時間最好只有一個WSARecv/WSASend,如果你想提高IOCP網絡吞吐量,可能會在同一個套接字上同時投遞多個WSARecv/WSASend,那么你將會面臨下面幾個情況必須處理:?
a)IO線程之間的WSARecv/WSASend操作頻繁加鎖/解鎖,因為你無法保證線程1在GQCS時,線程2不會對相同套接字GQCS。?
b)收發出現亂序,仔細想一下,正是因為你對同一套接字同時投遞多個WSARecv/WSASend導致的,有你忙的了。?
c)短時間內大量WSARecv/WSASend異步操作消耗太多非分頁內存,也許在你下次投遞收發操作時,OS會毫不留情給你一個10055錯誤。?
5)現在你應該明白服務端的穩定是一個前提,需要比高吞吐量更要優先考慮,那么對于情況4建議的緩沖隊列,絕對應該是你首先需要考慮的。?
6)合理限制客戶端套接字的流量(包速),即你需要規劃完整合理的Qos,否則一旦惡意連接試圖以大流量正常業務包攻擊你的IOCP時,你會發現你的IOCP構架是多么脆弱。?
7)為了減少情況6的出現,建議你在客戶端/服務端通訊時增加壓縮(加密)/解壓縮(解密)功能,最好加入時間戳或GUID校驗,避免出現同樣的業務收發相同的包,最終導致攻擊者只需要截取一個正常業務包,就能干出情況6的事情。?
也許你會覺得如此實現太影響IOCP吞吐量,確實如此,收/發緩沖隊列、Qos、加密解密都會降低IO吞吐量。希望你在決定之前,先衡量一下你未來的IOCP服務端菊花是否夠緊,否則有一天你會高呼:OMG,是誰又把我那可憐而又脆弱的IOCP爆菊了?
我把自己在編寫IOCP構架時重點處理的幾個地方交代一下,如果你想認真寫好一個穩定的IOCP服務端,建議重新規劃以下幾個細節。?
1)不要修改套接字默認的收發緩沖區大小,即8192字節=8K=2分頁。?
2)總所周知,x86頁面置換最少需要1分頁,所以不管IOCP的重疊IO涉及多少字節,OS至少需要加鎖/解鎖1分頁,在使用異步WSARecv/WSASend時,只要重疊緩沖區WSABuf的長度大于0,那么在投遞異步操作時,系統至少會鎖定1分頁的非頁面內存,而系統的非頁面緩沖池是有大小限制的,如果你的IOCP消耗了太多非分頁內存。輕則同服務器其他網絡進程無法使用網絡,重則可能會導致系統藍屏或其他崩潰。而對于你的IOCP服務端通訊,常見的現象是客戶端無法與服務端進行連接,或者收發包時出現 10055 。?
3)正是由于情況2的出現可能性,所以在投遞WSARecv/WSASend時,絕對不要貪圖簡單,直接進行投遞,正確的做法應該為每個套接字建立至少2個緩沖隊列,一收一發。?
4)對于同一個客戶端套接字,在同一時間最好只有一個WSARecv/WSASend,如果你想提高IOCP網絡吞吐量,可能會在同一個套接字上同時投遞多個WSARecv/WSASend,那么你將會面臨下面幾個情況必須處理:?
a)IO線程之間的WSARecv/WSASend操作頻繁加鎖/解鎖,因為你無法保證線程1在GQCS時,線程2不會對相同套接字GQCS。?
b)收發出現亂序,仔細想一下,正是因為你對同一套接字同時投遞多個WSARecv/WSASend導致的,有你忙的了。?
c)短時間內大量WSARecv/WSASend異步操作消耗太多非分頁內存,也許在你下次投遞收發操作時,OS會毫不留情給你一個10055錯誤。?
5)現在你應該明白服務端的穩定是一個前提,需要比高吞吐量更要優先考慮,那么對于情況4建議的緩沖隊列,絕對應該是你首先需要考慮的。?
6)合理限制客戶端套接字的流量(包速),即你需要規劃完整合理的Qos,否則一旦惡意連接試圖以大流量正常業務包攻擊你的IOCP時,你會發現你的IOCP構架是多么脆弱。?
7)為了減少情況6的出現,建議你在客戶端/服務端通訊時增加壓縮(加密)/解壓縮(解密)功能,最好加入時間戳或GUID校驗,避免出現同樣的業務收發相同的包,最終導致攻擊者只需要截取一個正常業務包,就能干出情況6的事情。?
也許你會覺得如此實現太影響IOCP吞吐量,確實如此,收/發緩沖隊列、Qos、加密解密都會降低IO吞吐量。希望你在決定之前,先衡量一下你未來的IOCP服務端菊花是否夠緊,否則有一天你會高呼:OMG,是誰又把我那可憐而又脆弱的IOCP爆菊了?
總結
以上是生活随笔為你收集整理的IOCP不可忽视的细节的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于IOCP乱序的探讨
- 下一篇: 《openssl编程》之基础知识