原创:Twemproxy源码分析之一 入口函数及启动过程

最近开始研究twemproxy先将其中的知识点归纳整理一下。作为一个系列的知识点。

一、Twemproxy简介

Twemproxy是memcache与redis的代理,由twitter公司开发并且目前已经开源。研究这个对于理解网络通信有很大的帮助。

亮点有以下:

1.twemproxy自己创建并维护和后端server(即reids实例)的长连接,保证长连接对于来自不同client但去向同一server的复用。

2.自动识别异常状态的server,保证之后的请求不会被转发到该异常server上。但如果此server恢复正常,twemproxy又能识别此server,并恢复正常访问。,

3.提供专门的状态监控端口供外部工具获取状态监控信息。

4.真正实现了多阶段处理多请求,其IO 模型值得学习,采用单线程收发包,基于epoll事件驱动模型。

5,支持Zero Copy技术,通过将消息指针在3个队列之间流转。

二、Twemproxy 入口main函数分析

Twemproxy是以c语言编写的,其整体入口在main函数中。

grep “main”,我们可以看到在文件nc.c中的main函数。开篇我们可以看到定义了一个变量,

struct instance nci;

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

struct instance {
    struct context  *ctx;
    int             log_level;
    char            *log_filename;
    char            *conf_filename;
    uint16_t        stats_port;
    int             stats_interval;
    char            *stats_addr;
    char            hostname[NC_MAXHOSTNAMELEN];
    size_t          mbuf_chunk_size;
    pid_t           pid;
    char            *pid_filename;
    unsigned        pidfile:1;
};

这个instance就相当于是一个twemproxy实例,一个twemproxy进程对应一个instance,后边整个程序的初始化很多都会用到。注意 这里面 一个instance对应于一个context,而一个context维护一个server pool列表。也就是说一个instance可以包含多个server pool.

接下来就调用了nc_set_default_options() 这个是用来设置上述instance实例nci的各项参数的默认值。

然后就是nc_get_options(),这个函数是读取命令行参数,如果有则覆盖上一个函数所设置的默认参数。

如果配置了-t选项 则nc_test_conf : 用于对配置文件做检查,以确保配置文件格式的正确。

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

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

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

最近开始研究twemproxy先将其中的知识点归纳整理一下。作为一个系列的知识点。

一、Twemproxy简介

Twemproxy是memcache与redis的代理,由twitter公司开发并且目前已经开源。研究这个对于理解网络通信有很大的帮助。

亮点有以下:

1.twemproxy自己创建并维护和后端server(即reids实例)的长连接,保证长连接对于来自不同client但去向同一server的复用。

2.自动识别异常状态的server,保证之后的请求不会被转发到该异常server上。但如果此server恢复正常,twemproxy又能识别此server,并恢复正常访问。,

3.提供专门的状态监控端口供外部工具获取状态监控信息。

4.真正实现了多阶段处理多请求,其IO 模型值得学习,采用单线程收发包,基于epoll事件驱动模型。

5,支持Zero Copy技术,通过将消息指针在3个队列之间流转。

二、Twemproxy 入口main函数分析

Twemproxy是以c语言编写的,其整体入口在main函数中。

grep “main”,我们可以看到在文件nc.c中的main函数。开篇我们可以看到定义了一个变量,

struct instance nci;

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

struct instance {
    struct context  *ctx;
    int             log_level;
    char            *log_filename;
    char            *conf_filename;
    uint16_t        stats_port;
    int             stats_interval;
    char            *stats_addr;
    char            hostname[NC_MAXHOSTNAMELEN];
    size_t          mbuf_chunk_size;
    pid_t           pid;
    char            *pid_filename;
    unsigned        pidfile:1;
};

这个instance就相当于是一个twemproxy实例,一个twemproxy进程对应一个instance,后边整个程序的初始化很多都会用到。注意 这里面 一个instance对应于一个context,而一个context维护一个server pool列表。也就是说一个instance可以包含多个server pool.

接下来就调用了nc_set_default_options() 这个是用来设置上述instance实例nci的各项参数的默认值。

然后就是nc_get_options(),这个函数是读取命令行参数,如果有则覆盖上一个函数所设置的默认参数。

如果配置了-t选项 则nc_test_conf : 用于对配置文件做检查,以确保配置文件格式的正确。

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

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

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

下一章将会着重分析nc_run下一章将会着重分析nc_run

时间: 2024-10-11 22:07:36

原创:Twemproxy源码分析之一 入口函数及启动过程的相关文章

Openstack liberty源码分析 之 云主机的启动过程3

接上篇Openstack liberty源码分析 之 云主机的启动过程2, 简单回顾下:nova-conductor收到nova-scheduler返回的主机列表后,依次发送异步rpc请求给目标主机的nova-compute服务,下面继续来看nova-compute服务的处理过程: nova-compute 根据路由映射,nova-compute中处理云主机启动请求的方法为 nova/compute/manager.py.ComputeManager.py.build_and_run_insta

Openstack liberty源码分析 之 云主机的启动过程2

接上一篇: Openstack liberty源码分析 之 云主机的启动过程1 nova-conductor nova-api通过rpc发送启动云主机请求后,nova-conductor会收到该请求,根据路由映射,该请求会递交给 nova/conductor/manager.py.ComputeTaskManager.build_instances处理,如下(函数说明见注释): def build_instances(self, context, instances, image, filter

android5系统源码分析点击app图标启动过程

从点击桌面app图片开始看,代码如下: //源码路径D:\dow\android-5.1.1_r1\android-5.1.1_r1\packages\apps\Launcher2\src\com\android\launcher2\Launcher.java public void onClick(View v) { // Make sure that rogue clicks don't get through while allapps is launching, or after the

CodeIgniter框架——源码分析之入口文件index.php

CodeIgniter框架的入口文件主要是配置开发环境,定义目录常量,加载CI的核心类core/CodeIgniter.php. 源码分析如下: <?php //这个文件是入口,后期所有的文件都要在这里执行. /*----------------------------------------------- * 系统环境配置常量 * 能够配置错误显示级别 * ----------------------------------------------- * 默认情况下: * developmen

【E2LSH源码分析】E2LSH函数接口

上一小节,我们对E2LSH代码主要的源码框架和用到的数据结构作了简单介绍(http://blog.csdn.net/jasonding1354/article/details/38331229),这一节我将简单介绍一下E2LSH的主要函数接口. 1.构建R-NN数据结构(定义在NearNeighbors.h) 输入为1-δ.R.d和数据集P,利用下面函数来构建: PRNearNeighborStructT initSelfTunedRNearNeighborWithDataSet(RealT t

Yii2.0源码分析之——设置别名函数(setAlias)和获取别名函数(getAlias)

首先说说什么是别名.在Yii中有很多的路径,在开发的过程当前我们也会使用一些路径.一般来说都需要使用绝对路径,但绝对路径都很长.所以,为了方便的使用路径,可以在Yi中i给每个路径起个名称,这个名称就是别名.别名的格式: 别名必须以"@"字符开头,别名中还可以包含"/".如("@www"为根别名,"@www/test"就为子别名) 别名最后的目录分隔符("\"或者"/")都将去掉(如果有的

区块链教程open-ethereum-pool矿池源码分析main入口

兄弟连区块链教程open-ethereum-pool矿池源码分析main入口,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁.回归理性,表面上看相关人才需求与身价似乎正在回落.但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上. open-ethereum-pool以太坊矿池-main入口 命令行启动 ./build/bin/open-ethereum-pool config.json config.json配置文件 { ????"threads": 2,

Solr4.9.0源码分析(2)之Solr的启动(一)

上文写到Solr的启动过程是在SolrDispatchFilter的init()里实现,当Tomcat启动时候会自动调用init(); Solr的启动主要在 this.cores = createCoreContainer();语句中实现. /** *初始化,当tomcat启动时候开始初始化,其中主要调用createCoreContainer来实现Solr的初始化 */ public void init(FilterConfig config) throws ServletException {

Docker源码分析之——Docker Client的启动与命令执行

在上文Docker源码分析之--Docker Daemon的启动 中,介绍了Docker Daemon进程的启动.Docker Daemon可以认为是一个Docker作为Server的运行载体,而真正发送关于docker container操作的请求的载体,在于Docker Client.本文从Docker源码的角度,分析Docker Client启动与执行请求的过程. Docker Client启动的流程与Docker Daemon启动的过程相仿.首先执行reexec.Init():随后解析f