Atlas源码学习(四)
来源:互联网 发布:网络印刷电商平台 编辑:程序博客网 时间:2024/06/10 00:39
部分数据结构描述:
在Atlas中,有一些重要的数据结构会贯穿程序的整个生命周期,并在后面的工作中频繁被使用,因此有必要对这些数据结构进行了解。
chassis_frontend_t : 描述Atlas启动参数,设置一些有关程序运行的全局控制选项,如运行模式,工作目录等。
typedef struct { int print_version; //打印版本信息 int verbose_shutdown; //是否关闭前端输出 int daemon_mode; //是否以守护进程的模式运行 gchar *user; //当程序插件监听端口时,需要退出特权模式,因此需要制定一个用户来替代root gchar *base_dir; //程序工作目录 int auto_base_dir; gchar *default_file; //默认配置文件名 GKeyFile *keyfile; //glib中用于读取配置文件的对象 chassis_plugin *p; //指向插件的指针 GOptionEntry *config_entries;//glib用于解析命令行参数和配置文件的 对象 gchar *pid_file; //存放程序进程id的文件,对程序的命令行控制和keepalive有非常重要的作用 gchar *plugin_dir; //插件程序存放目录 gchar **plugin_names; //插件名称 guint invoke_dbg_on_crash; #ifndef _WIN32 /* the --keepalive option isn't available on Unix */ guint auto_restart; #endif gint max_files_number; //最大打开文件数 gint event_thread_count; //event线程数量,与backend中的pools大小相等 gchar *log_level; //默认日志级别 gchar *log_path; //默认日志路径 use_syslog; char *lua_path; char *lua_cpath; char **lua_subdirs; gchar *instance_name; //进程名,用于配置pid和log文件,instance.pid和 instance.log } chassis_frontend_t;
daemon选项:
if (frontend->daemon_mode) { chassis_unix_daemonize();}void chassis_unix_daemonize(void) {#ifdef _WIN32 g_assert_not_reached(); /* shouldn't be tried to be called on win32 */#else#ifdef SIGTTOU signal(SIGTTOU, SIG_IGN);#endif#ifdef SIGTTIN signal(SIGTTIN, SIG_IGN);#endif#ifdef SIGTSTP signal(SIGTSTP, SIG_IGN);//忽略以上三类信号,以上三个信号一半来自终端#endif if (fork() != 0) exit(0);//fork子进程,父进程退出。子进程称为会话组的非首进程,其父进程变为守护进程。 if (setsid() == -1) exit(0);//创建一个新的会话,子进程称为组长进程,脱离终端控制。 signal(SIGHUP, SIG_IGN); //忽略SIGHUP信号,该信号一般有进程退出时发出(进程组有进程退出,发送其给组长进程) if (fork() != 0) exit(0);//再次fork保证进程非组长进程,保证其不会被分配到终端 chdir("/");//更改进程工作目录,设为当前目录 umask(0);//修改创建文件的屏蔽字模式为0,保证创建文件可读写#endif}
chassis_plugin
typedef struct chassis_plugin { long magic; /**用于验证插件是否与接口一致 */ gchar *option_grp_name; /**插件选项组,用于解析配置参数 */ gchar *name; /**插件名 */ gchar *version; /**插件版本号 */ GModule *module; /**插件句柄,保存插件对象的实例 */ chassis_plugin_stats_t *stats; /**< contains the plugin-specific statistics */ chassis_plugin_stats_t *(*new_stats)(void); /**< handler function to initialize the plugin-specific stats */ void (*free_stats)(chassis_plugin_stats_t *user_data); /**< handler function to dealloc the plugin-specific stats */ GHashTable *(*get_stats)(chassis_plugin_stats_t *user_data); /**< handler function to retrieve the plugin-specific stats */ chassis_plugin_config *config; /**用于存放插件的配置数据,很重要 */ chassis_plugin_config *(*init)(void); /**<span style="font-family: Arial, Helvetica, sans-serif;">插件配置信息初始化函数</span> */ void (*destroy)(chassis_plugin_config *user_data); /**插件配置信息销毁函数 */ GOptionEntry * (*get_options)(chassis_plugin_config *user_data); /**用于获取配置信息 */ int (*apply_config)(chassis *chas, chassis_plugin_config * user_data); /**<span style="font-family: Arial, Helvetica, sans-serif;">将配置信息加载到config中的处理函数</span> */ void* (*get_global_state)(chassis_plugin_config *user_data, const char* member); } chassis_plugin;
chassis_plugin_config
struct chassis_plugin_config { gchar *address; /**proxy的监听地址*/ gchar **backend_addresses; /**读写服务器地址,即master */ gchar **read_only_backend_addresses; /**只读服务器地址,即slave*/ gint fix_bug_25371; /**< suppress the second ERR packet of bug #25371 */ gint profiling; /**< skips the execution of the read_query() function */ gchar *lua_script; /**建立连接时应启动的脚本,在Atlas中用处不大了 */ gint pool_change_user; /**< don't reset the connection, when a connection is taken from the pool - this safes a round-trip, but we also don't cleanup the connection - another name could be "fast-pool-connect", but that's too friendly */ gint start_proxy; /** 开启代理模式*/ gchar **client_ips;/** 客户端列表,用于ip过滤*/ GHashTable *ip_table;/** 用于ip过滤的hash表 gchar **lvs_ips;/**lvs地址,也用ip过滤*/ GHashTable *lvs_table; /用于存放lvs地址的hash表 gchar **tables;/**表信息,用于分表*/ GHashTable *dt_table;/** 用于分表的hash表*/ gchar **pwds; GHashTable *pwd_table;/** 用于存放用户登录信息的hash表*、 network_mysqld_con *listen_con;/** 监听端口对象,该对象包含处理符合mysql协议的连接的各种回调函数,每当一个连接来到都会创建一个network_mysqld_con的对象,其中我们所监听的端口的连接对象中不含有client信息。这个对象的具体信息可参看,network_mysqld_con@<span style="font-family: Arial, Helvetica, sans-serif;">network-mysqld.h</span>*/ FILE *sql_log; gchar *sql_log_type; gchar *charset;/** 字符集合*/};chassis_plugin_config中的大部分配置会在main_loop函数以下部分完成(即向hash表中填入数据)
for (i = 0; i < chas->modules->len; i++) { chassis_plugin *p = chas->modules->pdata[i]; g_assert(p->apply_config); if (0 != p->apply_config(chas, p->config)) { g_critical("%s: applying config of plugin %s failed", G_STRLOC, p->name); return -1; } }
上面围绕chassis_frontend_t结构进行了数据分析,该结构主要用于解析命令行,读取配置文件和加载插件。实际上,贯穿Atlas运行的另外一个数据结构chassis也是我们理解Atlas的一个 重要部分。
chassis
struct chassis { struct event_base *event_base; //主线程的libevent实例 gchar *event_hdr_version; GPtrArray *modules; /**一个数组,数组中存放加载进来的插件,array(chassis_plugin) */ gchar *base_dir; /**程序运行期间各个模块的根目录*/ gchar *log_path; /**日志存放目录 */ gchar *user; /**运行程序的用户属主名 */ gchar *instance_name; /**程序启动的实例名*/ chassis_private *priv; /**保存运行期间的各个backend信息*/ void (*priv_shutdown)(chassis *chas, chassis_private *priv); void (*priv_free)(chassis *chas, chassis_private *priv); chassis_log *log; /** 与日志相关的数据结构*/ chassis_stats_t *stats; /**全局chassis状态,包括glib等 */ /* network-io threads */ guint event_thread_count;/**事件处理线程数,这里包含主线程*/ chassis_event_threads_t *threads;/** 所有的事件处理线程都放在这里面,由多个chassis_event_thread_t对象构成*/ chassis_shutdown_hooks_t *shutdown_hooks;// struct event_base *remove_base;};chassis对象贯穿了程序运行的整个周期,在负载均衡,读写分离的实现上都需要以来它。可以通过其中的modules对象获取到插件的句柄,进而获取插件的配置,处理函数等各种信息,在加载插件的过程中即chassis_frontend_load_plugins函数里,将插件与之关联。
chassis_private
struct chassis_private {// GPtrArray *cons; /**< array(network_mysqld_con) */ lua_scope *sc; network_backends_t *backends;}
typedef struct { GPtrArray *backends;//后台组信息 GMutex *backends_mutex; /*remove lock*/ g_wrr_poll *global_wrr;//权重 guint event_thread_count;//线程数量 } network_backends_t;其中用于表述一个后台结构的backend类型为
typedef struct { network_address *addr; backend_state_t state; /**UP or DOWN 当前数据库的状态*/ backend_type_t type; /**ReadWrite or ReadOnly 当前数据库的类型*/ GPtrArray *pools;//存放当前打开的连接,其数量一般与进程所持有的线程数相同 guint connected_clients; /**< number of open connections to this backend for SQF当前已连接的客户端个数 */ GString *uuid; /**< the UUID of the backend */ guint weight;//权重 } network_backend_t;//这个结构用于存储一个backend对象
network_address
typedef struct { union { struct sockaddr_in ipv4; struct sockaddr_in6 ipv6;#ifdef HAVE_SYS_UN_H struct sockaddr_un un;#endif struct sockaddr common; } addr; GString *name; network_socklen_t len; gboolean can_unlink_socket; /* set TRUE *only* after successful bind */} network_address;
以后想起来再说 。。。。
0 0
- Atlas源码学习(四)
- Atlas源码剖析(四)
- Atlas源码学习(一)
- Atlas源码学习(二)
- Atlas源码学习(三)
- Atlas源码学习(五)
- Atlas学习手记(1):Hello,Atlas
- Atlas源码剖析(一)
- Atlas源码剖析(二)
- Atlas源码剖析(三)
- Atlas源码剖析(五)
- Atlas源码剖析(六)
- Atlas源码剖析(七)
- Atlas源码剖析(八)
- Atlas源码剖析(九)
- Atlas源码剖析(十)
- Atlas源码剖析(十一)
- Atlas学习笔记(一)
- 美媒:中国向美方开出的贪官外逃名单超千人
- <input type="file" />浏览时只显示指定文件类型
- 10个优秀的 HTML5 & CSS3 下拉菜单制作教程
- leetcode第一刷_Merge Intervals
- Linux学习记录
- Atlas源码学习(四)
- 恒天云技术分享系列4 – OpenStack网络攻击与防御
- C++与R交互
- [C#]Log记录相关对应类
- Linux下的压缩解压缩命令详解
- EditText getText()判断输入为空
- HDU1556 Color the ball (树状数组)
- [C++]关于i++和++i的学习
- 运行R脚本(转)