同一個功能的軟件,不同的團隊,不同工程師去實現,肯定是千差萬別,甚至從根本上完全不同。所以軟件開發在未來很長時間內仍然是一項工匠的手工勞動,尤其像多任務,高并發,偏底層這種對實現技巧比較高的系統,這種系統對開發者來說仍然充滿挑戰,考驗工程師對產品的理解,經驗的積累,技術方案的取舍,以及各種因素的權衡。總之,平庸的軟件系統,很多人都可以做,但在這個領域內的標桿產品,只有功力深厚的工程師才能駕馭。
對應用服務器業務類型的深入理解
開發一個產品,肯定要先對產品的業務和功能必須有深入的理解,脫離業務去談產品的技術實現,那無異于空中樓閣,沒有根基,產品是為解決業務需求,業務痛點而存在的。首先架構師將一個大的解決方案進行模塊切分,然后對每個軟件業務模塊進行需求定義,接下來技術專家對實現方案進行技術論證決策和開發任務提煉,最后開發工程師負責開發任務的實現。作為各個環節的參與者,我們首先要深入理解需求定義,探明軟件日常的工作場景,然后才能有針對性的進行相關的構建和設計。
我們一般大體上將服務器軟件類型分為“IO密集型”和“計算密集型”。IO密集型,顧名思義,就是說軟件要處理高并發,大數據量的網絡或者文件IO請求,這時我們要將CPU計算資源向IO傾斜,并審慎的選擇高效的IO模型,IO模型的選擇也包含了很多技術內容,同時也有很多的框架支撐,具體不在此贅述。計算密集型,就是說軟件的主要業務是進行同步計算,這時我們的側重點要考慮如何在多核CPU之間分配、同步這些計算任務,使之充分利用計算資源;IO層面如何做到精簡,穩定,可靠。當然也存在著“IO和計算混合型”,那我們就要結合具體業務綜合考慮技術方案。總之,兵無常勢 水無常形,具體問題,具體分析,決策的依據都來源于我們日常的總結與積累。
計算任務的合理分配(多任務CPU資源的分配)
我們早已邁入多核CPU的時代,在服務器領域,尤其如此。服務端的軟件系統要充分利用計算資源,那就必須適應多核CPU的并發特性。提到這里,很多人會想“不就是多搞幾個線程就行了,有什么難的”,是啊,那搞幾個線程?為什么要把這個任務放在這個線程里?深究起來,都不是簡單的問題,我們在開發一個系統前,必須要有“并發性規劃”,根據業務特點,進行進程,線程,線程池,同步/異步,阻塞/非阻塞的規劃選擇,任何選擇都不是隨意的,都是有考量和統籌的,甚至有模擬演算,這樣的決策才是科學、有效的。
IO復用模型的合理選擇
服務端系統要么要接收外界的數據流,要么要監聽外界的指令。數據流和指令的接收處理方式,都要涉及到IO模型的選擇,尤其對IO密集型的應用,IO模型的選擇和開發實現,是產品成功與否的關鍵,這也是CamelProxy的核心技術。除了標準的socket標準,不同的操作系統平臺也對IO復用模型有不同的技術支持,比如Linux平臺的poll, epoll,Windows的重疊IO,完成端口等。同時也產生了很多第三方的跨平臺的C++網絡開發框架和庫,同時支持同步的,異步的,反應式,前攝式的等操作方式,并且也提供了很多網絡開發過程必不可少的組件,比如主動對象,線程池,消息隊列,同步控制等。這方面的框架包括ACE, Libevent, Boost等,都是非常好的網絡開發知識總結和實現。總之,沒有差的技術,只有合不合適你當前場景的技術,合理的選擇,將會事半功倍。
內存資源的高效使用
作為一個服務器后臺系統的開發者,我們都希望自己的系統高效,能夠長時間穩定運行的,最好能連續幾個月,不需要重啟的。從我們的經驗來看,要達到這個目標,必須對內存的調配使用要著重考量。內存的使用也是反應一個開發者在C, C++編程能力的重要指標,如果代碼中臨時對象,內存復制滿天飛,起碼就反映了開發者對語言的機制沒有深入洞悉。在內存使用技巧上,要注意兩個方面。首先,不要頻繁的進行內存的動態分配,釋放,避免內存碎片的累積。很多系統也沒有內存泄漏,但隨著運行時間的退役,內存占用量不斷上升,最終到了一個臨界點,然后系統就必須重啟。內存最好在系統開始運行就分配好,再根據系統的負載的變化動態的調整預分配的內存,或者用內存池等技巧來優化;再者,編程實現時,注重指針,引用的使用,避免不必要的臨時對象的產生,用不好指針的程序員,不是合格的C++開發者。總之,開發高效,穩定的系統,內存的編程實現技巧必不可少,考驗的也是開發者的功力于思考。
多線程并發的有效控制
充分挖掘多核CPU的計算能力,就必須應用多線程,多執行路徑的程序設計方式。多線程開發除了帶來線程路徑設計和執行任務分配的問題外,還有一個重要的問題就是線程間的協作和通信。這不僅包括了多線程對競爭資源的訪問控制,也包含了線程的通知激活,優雅退出,以及衍生出來消息隊列,流水線操作,都需要適當的場景選擇合適的方案。
語言工具的選擇
干什么活用什么樣的工具,工具的選擇會使過程和結果事半功倍。做高性能,大容量,高并發服務端后臺服務軟件系統,開發語言一定是C,C++, 因為該語言提供了足夠的空間,讓你充分運用各種技巧來優化程序的性能,這是其他高層語言所不能具備的,其他語言為了降低開發者所需掌握的難度與復雜性,做了太多的封裝與抽象化,不適合做一些高性能的應用。
選擇了對的工具,剩下的就是考驗實現者對工具的運用的水平,也是系統實現的關鍵和核心,也體現了一個高水平開發者對軟件的認識與思考,懂得如何有的放矢,充分解決問題,又不臃腫。正可謂“增一分則太長,減一分則太短”,取舍之間,大有乾坤。
這是在開發網絡代理服務器CamelProxy系統-CamelProxy代理服務器過程中一點經驗總結,如果您有更好的建議,歡迎批評指正。
轉載于:https://blog.51cto.com/13535157/2093238