Webdis內部解析
Webdis是redis的http代理,原始碼在:git://github.com/nicolasff/webdis.git
webdis.json是配置檔案
webdis.c是入口程式
其中有三個比較重要的結構:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
struct server {
int fd;
struct event ev;
struct event_base * base ; //libevent的event事件
struct conf *cfg; //配置檔案,設定有多少個程式(http_threads)啥的放在裡面
/* worker threads */
struct worker **w; //有多個worker,父程式有多少worker執行緒
int next_worker;
/* log lock */
struct {
pid_t self;
int fd;
} log; //日誌結構
}; |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
struct worker {
/* self */
pthread_t thread;
struct event_base * base ; //libevent的event事件
/* connection dispatcher */
struct server *s; //父server
int link[2]; //由pipe建立的管道,link[0]是管道讀取端,link[1]是管道寫入端
/* Redis connection pool */
struct pool *pool; //連線池,與redis連線的連線池
}; |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
struct pool {
struct worker *w; //worker執行緒
struct conf *cfg; //配置檔案
const redisAsyncContext **ac; //redis的同步上下文
int count; //pool大小,即s->cfg->pool_size_per_thread
int cur;
}; |
這三個結構每個結構都有一個指標指向父結構,比如pool的worker*
這樣能保證從任意一個結構中都能取得父結構的需要的屬性
webdis的server-worker-pool的關係是這樣的:
一個Server包含多個worker,每個woker佔一個程式的資源
一個worker包含一個pool
Server的任務是接受HTTP請求,傳遞HTTP的套接字給worker
Worker才是webdis的實際處理類,一方面接受Server傳遞過來的HTTP請求,一方面由pool保持和redis的連線
Pool是連線池,保持了與redis的連線,防止重複的連線操作造成過多的資源浪費
webdis的入口是Webdis.c檔案
主要執行了:
Server_new(conf)
server_start(s)
——————————-new 的過程開始—————————————-
Server_new主要函式:
conf_read
worker_new * n
worker_new主要函式:
Pipe(w->link) //建立管道
w->pool = pool_new(w, s->cfg->pool_size_per_thread);
pool_new主要函式:
p->ac = calloc(count, sizeof(redisAsyncContext*));
p->cfg = w->s->cfg;
pool中有一個redisAsyncContext結構,這個結構是hiredis的範圍了:
Hiredis是redis的C客戶端庫
https://github.com/antirez/hiredis
Hiredis is a minimalistic C client library for the Redis database.
Hiredis:
使用方法大是:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
redisAsyncContext *c = redisAsyncConnect( "127.0.0.1" , 6379);
int redisAsyncCommand(
redisAsyncContext *ac, redisCallbackFn *fn, void *privdata,
const char *format, ...);
int redisAsyncCommandArgv(
redisAsyncContext *ac, redisCallbackFn *fn, void *privdata,
int argc, const char **argv, const size_t *argvlen);
void redisAsyncDisconnect(redisAsyncContext *ac);
|
1
|
------------------------------- new 的過程結束----------------------------------------
|
1
|
|
1
|
-------------------------------start 的過程開始--------------------------------------- |
server_start主要函式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
s-> base = event_base_new(); //註冊一個事件
worker_start(s->w[i]); //開啟worker
s->fd = socket_setup(s->cfg->http_host, s->cfg->http_port); //建立socket
/* start http server */ event_set(&s->ev, s->fd, EV_READ | EV_PERSIST, server_can_accept, s); event_base_set(s-> base , &s->ev);
event_add(&s->ev, NULL); event_base_dispatch(s-> base );
|
worker_start主要函式:
1
|
pthread_create(&w->thread, NULL, worker_main, w); //開了一個執行緒來執行worker_main函式
|
worker_main主要函式:
1
2
3
4
5
6
7
8
9
10
11
12
|
w-> base = event_base_new(); //註冊event
/* monitor pipe link */ event_set(&ev, w->link[0], EV_READ | EV_PERSIST, worker_on_new_client, w); event_base_set(w-> base , &ev);
event_add(&ev, NULL); /* connect to Redis */ worker_pool_connect(w); //worker和pool的連線,即worker和redis的連線
/* loop */ event_base_dispatch(w-> base );
|
worker_pool_connect主要函式:
1
|
pool_connect(w->pool, 1); //指定w->pool來連線redis
|
pool_connect主要函式: //連線redis
1
2
3
4
5
6
7
8
9
|
ac = redisAsyncConnect(p->cfg->redis_host, p->cfg->redis_port); redisLibeventAttach(ac, p->w-> base );
redisAsyncSetConnectCallback(ac, pool_on_connect); redisAsyncSetDisconnectCallback(ac, pool_on_disconnect); redisAsyncCommand(ac, NULL, NULL, "AUTH %s" , p->cfg->redis_auth);
|
1
|
下面就進入到了hiredis的部分了 |
1
|
-------------------------------start 的過程結束--------------------------------------- |
1
|
|
———————-
作者:yjf512(軒脈刃)
出處:http://www.cnblogs.com/yjf512/
本文版權歸yjf512和cnBlog共有,歡迎轉載,但未經作者同意必須保留此段宣告
相關文章
- Redo內部解析(三)
- Redo內部解析(二)
- Redo內部解析(一)
- 深入解析 oracle drop table內部原理Oracle
- java內部類解析——菜鳥摘記Java
- 資料塊內部結構dump解析
- Redo內部解析-Multi Rows Insert (八)
- Redo內部解析-Single Row Delete (六)delete
- Redo內部解析-Single Row update (五)
- Redo內部解析-Single Row insert (四)
- Redo內部解析-Global Temporary table insert(九)
- Redo內部解析-Insert Single Row with Index(七)Index
- java內部類,區域性內部類,靜態內部類,匿名內部類Java
- java之內部類(InnerClass)----非靜態內部類、靜態內部類、區域性內部類、匿名內部類Java
- 10-Java內部類——成員內部類、區域性內部類、匿名內部類Java
- 雲伺服器 Linux內部無法解析域名伺服器Linux
- OkHttp3.0解析——談談內部的快取策略HTTP快取
- 通過WordCount解析Spark RDD內部原始碼機制Spark原始碼
- java內部類之成員內部類之匿名內部類Java
- [原始碼解析]Oozie來龍去脈之內部執行原始碼
- 深入解析React資料傳遞之元件內部通訊React元件
- 如何在函式計算內部中自定義DNS解析函式DNS
- C#泛型內部工作機制詳細解析C#泛型
- Sql server內部函式fn_PhysLocFormatter存在解析錯誤SQLServer函式ORM
- java內部類之成員內部類之區域性內部類Java
- Java內部類詳解--匿名內部類Java
- java內部類之成員內部類Java
- 內部類
- Java內部類詳解-- 成員內部類Java
- java內部類,為什麼需要內部類?Java
- Java內部類和匿名內部類的用法Java
- 深入V8引擎-引擎內部類管理解析
- OkHttp3.0解析——談談內部任務分發器dispatcherHTTP
- Sql server內部函式fn_PhysLocFormatter存在解析錯誤(續)SQLServer函式ORM
- Java內部類詳解--區域性內部類Java
- java內部類之成員內部類例項Java
- Data block 內部結構的解析(轉載gyj_hobby的文章)BloC
- Java 內部類Java