在正式开始阅读代码之前,先来看一下代码整体结构

代码规模不大只有1w多行,而且功能划分的比较清晰,包括:

  • 事件处理: event/nc_epoll.c、event/nc_event.h、event/nc_evport.c、event/nc_kqueue.c
  • 各种Hash函数: hashkit/nc_crc16.c、hashkit/nc_crc32.c、hashkit/nc_fnv.c、hashkit /nc_hashkit.h、hashkit/nc_hsieh.c、hashkit/nc_jenkins.c、hashkit /nc_ketama.c、hashkit/nc_md5.c、hashkit/nc_modula.c、hashkit/nc_murmur.c、 -hashkit/nc_one_at_a_time.c、hashkit/nc_random.c
  • 协议: proto/nc_memcache.c、proto/nc_proto.h、proto/nc_redis.c
  • 自定义的数据类型: nc_array.c、nc_array.h、nc_string.c、nc_string.h
  • 网络通信相关: nc_connection.c、nc_connection.h、nc_client.c、nc_client.h、nc_proxy.c、nc_proxy.h
  • 信号处理: nc_signal.c、nc_signal.h
  • 关键数据结构和算法: nc_rbtree.h、nc_rbtree.c、nc_queue.h、nc_request.c、nc_response.c、nc_mbuf.c、 nc_mbuf.h、- nc_message.c、nc_message.h、nc_server.c、nc_server.h
  • 统计、日志和工具: nc_stats.c、nc_stats.h、nc_log.c、nc_log.h、nc_util.c、nc_util.h
  • 配置文件: nc_conf.c、nc_conf.h
  • 主程序: nc.c、nc_core.c、nc_core.h

src/nc.c文件 是程序入口main函数所在,下面我给各个函数加了注释

int
main(int argc, char **argv)
{rstatus_t status; //rstatus_t 返回类型struct instance nci;//nc实例nc_set_default_options(&nci); //为nc实例设置一些默认的参数属性值 之后具体介绍status = nc_get_options(argc, argv, &nci); //获取参数 解析参数if (status != NC_OK) {nc_show_usage();exit(1);}if (show_version) { //打印版本号log_stderr("This is nutcracker-%s" CRLF, NC_VERSION_STRING);if (show_help) {nc_show_usage(); //这个函数就是打印twemproxy的所有参数介绍}if (describe_stats) {stats_describe();}exit(0);}if (test_conf) {if (!nc_test_conf(&nci)) {exit(1);}exit(0);}status = nc_pre_run(&nci);if (status != NC_OK) {nc_post_run(&nci);exit(1);}nc_run(&nci);nc_post_run(&nci);exit(1);
}

main函数的整理流程非常清晰,包含以下几步:
初始化option,设置默认值
从argv中获取option,若argv有错误则调用nc_show_usage()打印使用帮助
根据argv,判断是否是:show_version、show_help、describe_stats或者test_conf,是则执行相应逻辑后退出
依次调用nc_pre_run()、nc_run()和nc_post_run()
前面的步骤目前无关紧要,可以看出主要逻辑在nc_pre_run()、nc_run()和nc_post_run()函数中。这三个函数的定义也在nc.c当中。

下面是对main函数进一步介绍:

二、Twemproxy启动启动流程分析

对于一个由C/C++编写的应用程序而言,程序的启动点一般都是main函数,所以对一个程序进行分析的话,也一般都是有main函数作为入口,我们这里也不例外,以main函数作为入口。

找到文件nc.c定位到main,我们可以看到定义了一个变量,

struct instance nci;

下边我们看下这个instance的定义:

 struct instance {struct context  *ctx;                        /* active context */int             log_level;                   /* log level */char            *log_filename;               /* log filename */char            *conf_filename;              /* configuration filename */uint16_t        stats_port;                  /* stats monitoring port */int             stats_interval;              /* stats aggregation interval */char            *stats_addr;                 /* stats monitoring addr */char            hostname[NC_MAXHOSTNAMELEN]; /* hostname */size_t          mbuf_chunk_size;             /* mbuf chunk size */pid_t           pid;                         /* process id */char            *pid_filename;               /* pid filename */unsigned        pidfile:1;                   /* pid file created? */};

这个instance就相当于是一个twemproxy实例,后边整个程序的初始化很多都会用到。接下来就调用了nc_set_default_options()和nc_get_options()两个函数,其中nc_get_options这个函数是读取命令行参数。其中比较重要的几个参数分别有:

a) test_conf : 用于设置在启动twemproxy之前是否要对配置文件做检查,以确保配置文件格式的正确。

然后就会调用nc_pre_run,启动之前做一些预处理,包括:初始化日志级别以及日志文件;设置是否后台运行;对信号做初始化处理;是否创建pid文件。

接下来调用nc_run开始启动proxy;这个函数完成的工作就是调用core_start创建context,然后进入死循环调用core_loop开始整个事件循环的处理,接受请求并处理。当然,core_start以及core_loop这两个函数里边还包含了大量的处理工作,包括,配置文件解析以及读取,相关组件(server_pool,conf,context)的初始化等等,这些后边详细讲述。

下面介绍一下nc_pre_run、nc_run的逻辑:

nc_pre_run()的函数逻辑是:

  • 初始化日志
  • 启动守护进程
  • 初始化信号处理函数
  • 创建pidfile
  • 输出启动信息
  • 如果nc_pre_run()运行失败,main()函数的逻辑中会调用nc_post_run()回收资源

nc_post_run()函数的主要逻辑是:

  • 删除pidfile
  • 信号处理函数deinit(这里其实什么也不做)
  • 打印关闭信息
  • 日志deinit(关闭日志文件描述符)
    接下来就是比较重要的nc_run()

nc_run()函数主要逻辑是:

调用core_start(),初始化上下文ctx
进入死循环,调用core_loop()进入事件循环
检查退出条件status != NC_OK,退出循环
调用core_stop()结束
可以看出细节都封装到了 core_start()、core_loop()和core_stop() 当中,但是nc.c主程序的逻辑到这里就结束了。值得一提的是,nc_daemonize()函数封装了创建守护进程的一个标准逻辑。

总体来说,启动流程就是这些步骤,如下图:

twemproxy源码解析1 源码文件总体简介相关推荐

  1. Tomcat源码解析系列二:Tomcat总体架构

    Tomcat即是一个HTTP服务器,也是一个servlet容器,主要目的就是包装servlet,并对请求响应相应的servlet,纯servlet的web应用似乎很好理解Tomcat是如何装载serv ...

  2. yolov3之pytorch源码解析_springmvc源码架构解析之view

    说在前面 前期回顾 sharding-jdbc源码解析 更新完毕 spring源码解析 更新完毕 spring-mvc源码解析 更新完毕 spring-tx源码解析 更新完毕 spring-boot源 ...

  3. 源码 解析_List源码解析

    点击上方「10分钟编程」关注我呦 让我们在一起每天「博学」一点点,成为更好的自己! List源码解析 本篇文章有点长,所以先列个目录 List源码解析 1.ArrayList 2.LinkedList ...

  4. Jedis源码解析(一):Jedis简介、Jedis模块源码解析

    一.Jedis简介 1.Jedis对应Redis的四种工作模式 对应关系如下: Jedis主要模块 Redis工作模式 Jedis Redis Standalone(单节点模式) JedisClust ...

  5. linux WiFi源码解析,WIFIDOG 源码解析

    WIFIDOG 源码解析 openwrt wifidog是我linux c语言编程的启蒙项目,一年前折腾此项目大半年,从此爱上了linux 系统编程.现在看来,这是一个再简单不过的linux c语言项 ...

  6. log4j 源码解析_Log4j源码解析--框架流程+核心解析

    OK,现在我们来研究Log4j的源码: 这篇博客有参照上善若水的博客,原文出处:http://www.blogjava.net/DLevin/archive/2012/06/28/381667.htm ...

  7. 栅格化渲染源码解析-neural_renderer源码(二)光照部分

    目录 一.变量形式 1.1 light 1.3  textures变量 1.4 faces变量 二.对于light的处理 2.1 ambient_light常数化光场 2.2 directional_ ...

  8. fceux源码解析_fceux源码解析_从源代码制作deb包的两种方法以及修改已有deb包(转载)...

    1. 原理 1) deb包通常包含两部分:控制信息(DEBIAN目录).安装内容(模拟"/"目录) 2) 通过解开已有的deb包看其中内容 i. 释放安装内容到dirname目录中 ...

  9. java解析java源码_JAVA语言-Java源码解析-Stack源码分析

    一.简介 stack类图.png 栈是数据结构中一种很重要的数据结构类型,因为栈的后进先出功能是实际的开发中有很多的应用场景.Java API中提供了栈(Stacck)的实现.Stack类继承了Vec ...

最新文章

  1. FPGA控制的数码显示电路
  2. Ajax调用webService(一) 不跨域。
  3. Winform ComboBox控件高亮显示
  4. 基于黄金分割的修正Powell算法
  5. Oracle 11g中创建实例
  6. 程序人生:教你写出让同事抓狂的代码
  7. 工作流Flowable实战篇
  8. Package vim is not available, but is referred to by another package.
  9. 概率论信息论基础(随机变量、常用概率分布、贝叶斯规则、信息论基础、结构化概率模型)
  10. aver函数C语言怎么用,C语言函数使用
  11. 快速乘 防爆乘 快速幂
  12. 设计模式------建造者模式
  13. Unity Shader 屏幕后效果——颜色校正
  14. Linux 面试最常问的十个问题
  15. 时光倒流我这么学java
  16. 成本会计的概念、产品成本核算的要求、产品成本核算的对象与成本项目、产品成本的归集和分配(可能考判断)、产品成本计算方法 (三种:产品的品种(品种法),批次(分批法),步骤(分步法))
  17. SpaceSyntax【空间句法】之DepthMapX学习:第一篇 数据的输入 与 能做哪些分析
  18. 测测你的IQ加分析能力
  19. 如何画好室内手绘效果图,非常值得…
  20. python利用danmu实时获取斗鱼等直播网站字幕

热门文章

  1. Protel DXP元件库快速搜索
  2. android8 老手机,老用户福音 四款荣耀老产品即将升级安卓8.0
  3. android 通过adb发送广播
  4. 小程序 view组件bindtap事件及获取值的方式
  5. web自动化笔记十六:日志收集
  6. iFrame跨域解决办法
  7. 凡人如何让自己的工作独一无二
  8. jenkins动态获取gitlab分支
  9. 把服务器添加到桌面,iOS 添加快捷方式到桌面
  10. pscp.pssh的使用