zoukankan      html  css  js  c++  java
  • Webdis内部解析

    Webdis是redis的http代理,源代码在:git://github.com/nicolasff/webdis.git

    webdis.json是配置文件

    webdis.c是入口程序

    其中有三个比较重要的结构:

    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;  //日志结构
    };
    
    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连接的连接池
    };
    
    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:

    使用方法大是:

    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);
    
    -------------------------------new 的过程结束----------------------------------------
     
    -------------------------------start 的过程开始---------------------------------------

    server_start主要函数:

    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主要函数:

    pthread_create(&w->thread, NULL, worker_main, w);//开了一个线程来运行worker_main函数
    

    worker_main主要函数:

    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主要函数:

    pool_connect(w->pool, 1); //指定w->pool来连接redis
    

    pool_connect主要函数: //连接redis

    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);
    
    下面就进入到了hiredis的部分了
    -------------------------------start 的过程结束---------------------------------------
     

    ----------------------

    作者:yjf512(轩脉刃)

    出处:http://www.cnblogs.com/yjf512/

    本文版权归yjf512和cnBlog共有,欢迎转载,但未经作者同意必须保留此段声明

    实时了解作者更多技术文章,技术心得,请关注微信公众号“轩脉刃的刀光剑影”

    本文基于署名-非商业性使用 3.0许可协议发布,欢迎转载,演绎,但是必须保留本文的署名叶剑峰(包含链接http://www.cnblogs.com/yjf512/),且不得用于商业目的。如您有任何疑问或者授权方面的协商,请与我联系

  • 相关阅读:
    1、编写一个简单的C++程序
    96. Unique Binary Search Trees
    python 操作redis
    json.loads的一个很有意思的现象
    No changes detected
    leetcode 127 wordladder
    django uwsgi websocket踩坑
    you need to build uWSGI with SSL support to use the websocket handshake api function !!!
    pyinstaller 出现str error
    数据库的读现象
  • 原文地址:https://www.cnblogs.com/yjf512/p/2393716.html
Copyright © 2011-2022 走看看