標籤:需要 exec 其他 三次 opd 開啟 問題 data- client
引言
做後端開發免不了要和一些 儲存伺服器, Message Service器 等等 打交道。
起因 (傳統模式, 讀取資料庫)
大家都知道和這些使用 tcp串連 的服務傳遞資料的都必須要開啟 一個 串連-connection
例如我們開啟一個資料庫並執行一段 sql, 通常都是
connection = open "mysql://127.0.0.1:3306/db" (開啟資料庫,並取得持有串連的控制代碼)
data = connection.exec "select * from table1" (執行 sql 並擷取資料)
connection.close() 顯式的關閉串連
這個方式看上去似乎沒有什麼不對的。
但是對於並發量稍大一些的網站來說。一個單元批次的操作就需要開啟並關閉一次串連。。。
這顯然是不能接受的。
為這樣做不能接受呢?
建立一個tcp串連需要三向交握。而且還需要為對象分配系統資源和記憶體空間。所以建立一個tcp串連可以說是昂貴的。
回到剛才的話題。這樣平凡的開啟關閉串連不僅對增加用戶端io的壓力,最重要的是大大增加了 tcp 伺服器的壓力(mysql, redis)。
那我們再嘗試另外一種方式,那就是不關閉串連,一直使用這個串連呢。答案是: 可以。這種方式 被叫做 長串連。
那這樣的話,也有一個問題。因為一段時間內一個串連只能做一件事情。那麼在並發的情況下這顯然會阻塞整個系統。
那我們能不能嘗試建立多個串連,然後當調用的時候,將沒有被使用的串連拿出來使用,當使用完畢之後,將串連放回去,以供其他調用者使用的方式的呢?
串連大管家(串連池)
答案是有的:那就是我們要說的串連池。當然一個健全的串連池並不僅僅完成以上我所說的功能。
- 串連預熱 (啟動時自動開啟n個串連以供使用)
- 使用 例如
輪轉法 均勻分發 串連請求
- 當池中的串連即將耗盡得時候動態產生新的串連
- 當池中的串連一段時間沒有被調用的時候,自動釋放串連
- 自動丟棄 已經壞掉的 串連
- 系統關閉的時自動釋放所有串連
........
以上都屬於串連池的功能。串連池可謂是我們管理串連的管家
Node.js 中的 串連池
說到這裡好像還是沒有說到要點。在Node中我們應該怎麼呢?
我們可以使用 node-pool 這個模組 GitHub
1. 安裝 npm install generic-pool
2. 建立一個串連池 // 建立一個 mysql 串連池 var poolModule = require(‘generic-pool‘); var pool = poolModule.Pool({ name : ‘mysql‘, //將建 一個 串連的 handler create : function(callback) { var Client = require(‘mysql‘).Client; var c = new Client(); c.user = ‘scott‘; c.password = ‘tiger‘; c.database = ‘mydb‘; c.connect(); callback(null, c); }, // 釋放一個串連的 handler destroy : function(client) { client.end(); }, // 串連池中最大串連數量 max : 10, // 串連池中最少串連數量 min : 2, // 如果一個線程3秒鐘內沒有被使用過的話。那麼就釋放 idleTimeoutMillis : 30000, // 如果 設定為 true 的話,就是使用 console.log 列印入職,當然你可以傳遞一個 function 最為作為日誌記錄handler log : true });
3. 從串連池中獲得連結並使用 // 預設無任務優先順序, 但是與高優先順序一樣,在競爭隊列的前列 pool.acquire(function(err, client) { pool.release(client); }); // 高優先順序獲得連結, 在競爭隊列的前列 pool.acquire(function(err, client) { pool.release(client); }, 0); // 中等優先順序獲得連結 pool.acquire(function(err, client) { pool.release(client); }, 1); // pool.acquire(handler, priority) 方法接受連個參數 // handler: 擷取串連的回掉函數 // priority: 擷取到連結的競爭優先順序 // pool.release(client) 方法會將連結放回到串連池當中,當獲得的連結沒有release的話。將會導致該連結被一直佔用
更多相關的配置 我就不一一展開討論了。大家可以去 github 上查看項目的 README.md
【生產層級Nodejs開發實踐-強壯的node進程容器PM2】- 敬請期待
註:
儲存伺服器: (資料庫 mysql ..., 緩衝 memcached, redis ...)
Message Service器: (RabbitMQ,ActiveMQ ...)
生產級Nodejs開發實踐-使用串連池