異步與同步模型最大的區別是,同步模型會阻塞線程等待資源,而異步模型不會阻塞線程,它是等資源準備好後,再通知業務代碼來完成後續的資源處理邏 輯。這種異步設計的方法,能夠很好地解決IO等待的問題。數據庫
咱們開發的絕大多數業務系統,它都是IO密集型系統。跟IO密集型系統相對的另外一種系統叫計算密集型系 統。經過這兩種系統的名字,估計你也能大概猜出來IO密集型系統是什麼意思。緩存
IO密集型系統大部分時間都在執行IO操做,這個IO操做主要包括網絡IO和磁盤IO,以及與計算機鏈接的一 些外圍設備的訪問。與之相對的計算密集型系統,大部分時間都是在使用CPU執行計算操做。咱們開發的業 務系統,不多有很是耗時的計算,更多的是網絡收發數據,讀寫磁盤和數據庫這些IO操做。這樣的系統基本 上都是IO密集型系統,特別適合使用異步的設計來提高系統性能。服務器
應用程序最常使用的IO資源,主要包括磁盤IO和網絡IO。因爲如今的SSD的速度愈來愈快,對於本地磁盤的 讀寫,異步的意義愈來愈小。因此,使用異步設計的方法來提高IO性能,咱們更加須要關注的問題是,如何 來實現高性能的異步網絡傳輸。網絡
理想的異步網絡框架應該是什麼樣的?框架
在咱們開發的程序中,若是要實現經過網絡來傳輸數據,須要用到開發語言提供的網絡通訊類庫。大部分語 言提供的網絡通訊基礎類庫都是同步的。一個TCP鏈接創建後,用戶代碼會得到一個用於收發數據的通道。 每一個通道會在內存中開闢兩片區域用於收發數據的緩存。異步
發送數據的過程比較簡單,咱們直接往這個通道里面來寫入數據就能夠了。用戶代碼在發送時寫入的數據會 暫存在緩存中,而後操做系統會經過網卡,把發送緩存中的數據傳輸到對端的服務器上。性能
只要這個緩存不滿,或者說,咱們發送數據的速度沒有超過網卡傳輸速度的上限,那這個發送數據的操做耗 時,只不過是一次內存寫入的時間,這個時間是很是快的。因此,發送數據的時候同步發送就能夠了,沒有 必要異步。spa
比較麻煩的是接收數據。對於數據的接收方來講,它並不知道何時會收到數據。那咱們能直接想到的方 法就是,用一個線程阻塞在那兒等着數據,當有數據到來的時候,操做系統會先把數據寫入接收緩存,而後 給接收數據的線程發一個通知,線程收到通知後結束等待,開始讀取數據。處理完這一批數據後,繼續阻塞 等待下一批數據到來,這樣周而復始地處理收到的數據。操作系統
這就是同步網絡IO的模型。同步網絡IO模型在處理少許鏈接的時候,是沒有問題的。可是若是要同時處理非 常多的鏈接,同步的網絡IO模型就有點兒力不從心了。線程
由於,每一個鏈接都須要阻塞一個線程來等待數據,大量的鏈接數就會須要相同數量的數據接收線程。當這些 TCP鏈接都在進行數據收發的時候,會致使什麼狀況呢?對,會有大量的線程來搶佔CPU時間,形成頻繁的 CPU上下文切換,致使CPU的負載升高,整個系統的性能就會比較慢。
因此,咱們須要使用異步的模型來解決網絡IO問題。怎麼解決呢?
你能夠先拋開你知道的各類語言的異步類庫和各類異步的網絡IO框架,想想,對於業務開發者來講,一個 好的異步網絡框架,它的API應該是什麼樣的呢?
咱們但願達到的效果,無非就是,只用少許的線程就能處理大量的鏈接,有數據到來的時候能第一時間處理 就能夠了。
對於開發者來講,最簡單的方式就是,事先定義好收到數據後的處理邏輯,把這個處理邏輯做爲一個回調方 法,在鏈接創建前就經過框架提供的API設置好。當收到數據的時候,由框架自動來執行這個回調方法就行了。