java设计高并发内存池_高并发服务器-连接池的设计
高并發服務器-連接池的設計
高并發服務器需要有一些池的設計,如內存池,連接池,數據庫連接池。
池(pool)的設計主要考慮到一些資源的頻繁申請和釋放,尤其是在高并發的服務器中,幾萬甚至幾十萬并發每秒,設計人員不得不去考慮這些。
比如數據庫連接池(sql pool),是通過TCP來通信的,屬于IO類,有一定的延時,在高并發系統中頻繁的創建會嚴重影響系統性能。
內存( mem )的分配是要涉及鎖( mutex )的,有鎖就會有延時,因此可以在開始申請一大塊內存,后面進行分配與釋放,來節省鎖開銷。
服務器的連接處理不僅僅涉及內存,還涉及到一些屬性的賦值,這些是要占用CPU時間的,如果在一開始就創建大量的連接,就方便以后復用了。
下面我以數據庫連接池為例,先定義連接的結構:
typedef?struct?tst_sql_s?tst_sql_t;
struct?tst_sql_s{
MYSQL?????*sql;
tst_sql_t???*next;
tst_sql_t???*prev;
};
現實開發中,我發現有些喜歡用( free-busi ) 模式來設計池。
struct??tst_sql_pool_s
{
tst_sql_t?*free_sql;
tst_sql_t?*busi_sql;
…
};
將池中的連接分成兩個部分,一部分是空閑的(free),一部分是正在用的(busi),相函數函數:
tst_sql_t*?tst_sql_pool_get(?tst_sql_pool_t*?pool?)
{
tst_sql_t?*sql;
if(?!pool?){
return?0;
}
sql?=?pool->free_sql;
if(?!sql?){
return?0;
}
pool->free_sql?=?sql->next;
sql->next?=?pool->busi_sql;
sql->prev?=?0;
if(?pool->busi_sql?){
pool->busi_sql->prev?=?sql;
}
pool->busi_sql?=?sql;
return?sql;
}
int?tst_sql_pool_put(?tst_sql_pool_t*?pool,?tst_sql_t*?sql?)
{
if(?!pool?||?!sql?){
return?0;
}
if(?sql->prev?){
sql->prev->next?=?sql->next;
}
else{
pool->busi_sql?=?sql->next;
}
if(?sql->next?){
sql->next->prev?=?sql->prev;
}
sql->next?=?pool->free_sql;
pool->free_sql?=?sql;
return?0;
}
基本就完成了池的管理了,但是我們也可以看出來這個判斷其實很麻煩,有沒有不用這么麻煩的呢。
從上面的函數也可以看出,麻煩主要在 busi 池上,free池的處理其實挺簡單的,于是就有了下面的設計:
連接池只存放空閑連接,不在保存連接的狀態,而應該把狀態的分別交給管理函數。
下面我們以連接池舉例
我重新設計了連接池的結構:
typedef?struct?tst_conn_s?tst_conn_t;
typedef?struct?tst_conn_pool_s?tst_conn_pool_t;
struct?tst_conn_s
{
int??fd;
……..
……..
tst_conn_t*?next;
};
struct?tst_conn_pool_s
{
………
……….
tst_conn_t*??conns;
};
池的管理函數:
tst_conn_t*?tst_conn_pool_get(?tst_conn_pool_t*?pool?)
{
tst_conn_t*?conn;
if(?!pool?){
return?0;
}
conn?=?pool->conns;
if(?!conn?){
return?0;
}
pool->conns?=?conn->next;
return?conn;
}
#define?TST_CONN_POOL_ERROR?-1
#define?TST_CONN_POOL_OK?0
int?tst_conn_pool_put(?tst_conn_pool_t*?pool,?tst_conn_t*?conn?)
{
if(?!pool?||?!conn?){
return?TST_CONN_POOL_ERROR;
}
conn->next?=?pool->conns;
pool->conns?=?conn;
return?TST_CONN_POOL_OK;
}
這樣,就起到了連接池的分配與回收的功能。
一般在設計上提高模塊的透明性和降低耦合,我會把池的管理放在模塊內部,對外只提供一致性接口:
#define?TST_CONN_POOL_ERROR?-1
#define?TST_CONN_POOL_OK?0
tst_conn_t*?tst_conn_get();
int?tst_conn_free(?tst_conn_t*?conn?);
模塊內部用一個全局的池,在模塊內統一的管理。
總結
以上是生活随笔為你收集整理的java设计高并发内存池_高并发服务器-连接池的设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二进制文件安装mysql_CentOS7
- 下一篇: 【LeetCode-面试算法经典-Jav