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