• 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/),且不得用于商业目的。如您有任何疑问或者授权方面的协商,请与我联系

  • 相关阅读:
    ES6知识点整理之----async----异步遍历器
    ES6知识点整理之----async----实现原理以及与其他异步的比较
    ES6知识点整理之----async----语法
    ES6知识点整理之----async----含义及基本用法
    ES6知识点整理之----Generator----异步
    ES6知识点整理之----Generator----其他
    ES6知识点整理之----Generator----yield*表达式
    ES6知识点整理之----Generator----API
    ES6知识点整理之----Generator----next与for...of
    ES6知识点整理之----Generator----概述
  • 原文地址:https://www.cnblogs.com/yjf512/p/2393716.html
Copyright © 2020-2023  润新知