马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
CoPilot 概述
OpenNJet 是一个多进程的程序,有一个 Master 进程和多个 Worker 进程,另外还可以创建多个CoPilot 进程。
CoPilot 在 Master-Workers 进程架构的基础之上进行了扩展,提拔了 OpenNJet 的控制管理和提供服务的能力。好比,可以用CoPilot运行一个Controller,对外提供访问控制;还可以用CoPilot运行一个Broker,作为一个消息中间件。这是两种范例的用法,但并不是全部,受限的是必须服从CoPilot 插件开发规范,而不是 CoPilot 提供的功能和服务。
Master 进程创建了CoPilot进程,并在 NJet 的整个生命周期过程中管理着 CoPilot 进程,在根据控制信号制止(-s stop 或 -s quit)OpenNJet 时,会制止 CoPilot 进程;在重新加载配置(-s reload)时,是否制止并创建新的 CoPilot 进程,是由这个 CoPilot 进程的 so 决定,这一点在CoPilot 插件规范有描述;在 CoPilot 进程由于意外挂掉时,会及时创建新的 CoPilot 进程。
CoPilot 配置
CoPilot的配置,是在主配置文件中使用helper指令。
指令阐明:
参数阐明:
示例配置
- helper ctrl modules/njt_helper_ctrl_module.so conf/njet_ctrl.conf;
- helper broker modules/njt_helper_broker_module.so conf/mqtt.conf;
- helper ha modules/njt_helper_ha_module.so conf/vrrp.conf;
复制代码 CoPilot 插件规范
CoPilot插件的情势是一个so文件,需实现以下接口:
- 1)unsigned int njt_helper_check_version(void) 注:当前版本号是 1 #define NJT_HELPER_VER 1 2)void njt_helper_run(helper_param param) 注:helper_param是一个struc类型,定义如下
- typedef unsigned int (*helper_check_cmd_fp)(void* ctx); typedef struct { size_t conf_fn_len; u_char *conf_fn_data;* *helper_check_cmd_fp check_cmd_fp;* *void* ctx; } helper_param;
- 在njt_helper_run的事件循环中,需调用param.check_cmd_fp()接收命令
- 例如: unsigned int cmd; cmd = param.check_cmd_fp(param.ctx);
- 命令宏定义如下: #define NJT_HELPER_CMD_NO 0 #define NJT_HELPER_CMD_STOP 1 #define *NJT_HELPER_CMD_RESTART* 2
-
- 接收到命令后,需进行命令处理。 NJT_HELPER_CMD_STOP命令,要进行停止操作; NJT_HELPER_CMD_RESTART 为预留命令,暂不会发送该命令,在事件处理中可以按停止操作处理该命令,或者执行自身业务逻辑的重新开始。
- 3)unsigned int njt_helper_ignore_reload(void)
- 返回1,表示该so的copilot进程,不会在reload的时候重启。
- 放回0,表示该so的copilot进程,会在reload的时候重启。
- 注1:so可以不实现该接口。若不实现,则等同于返回0。
- 注2:如果so实现该接口并且返回1,那么在reload的时候该so的copilot进程不会重启,但是有一点需要注意:reload的时候配置文件中需保留原helper指令,这是配置上的强制要求,不满足此要求会导致reload失败。
复制代码 开发实例
开发一个demo的CoPilot插件,与开发一个module相比,有一些相似的地方,好比config文件的编写,也存在不同的地方,好比CoPilot插件不需要提像module那样实现njt_module_t中的commands和ctx等,而是需要按照CoPilot插件规范进行实现。下面的CoPilot实例,提供了参考。
在OpenNJet实行configure的时候,需要加上参数:–add-dynamic-module=./modules/njet-helper-demo-module
在make编译的时候,编译出 objs/njt_helper_demo_module.so
自带的CoPilot实例
CoPilot: broker 实例
broker的功能
broker是一个CoPilot插件,运行在一个单独的CoPilot进程中,该模块提供消息服务端功能, 使用mqtt 协议。
broker的配置使用
broker是在主配置文件中通过helper指令进行配置:
helper broker modules/njt_helper_broker_module.so conf/mqtt.conf;
配置文件必须存在,可以是空文件,未配置的配置项将使用默认配置
mqtt.conf Message Broker 配置文件
CoPilot: njet_ctrl实例
ctrl的功能
ctrl是一个CoPilot插件,运行在一个单独的CoPilot进程中,一方面它继续了所有OpenNJet静态编译的模块,另一方面可以通过load_module指令加载自己的动态模块来扩展功能,提供了强盛的控制能力,成为OpenNJet的控制平面。
ctrl的配置使用
ctrl是在主配置文件中通过helper指令进行配置:
- helper ctrl modules/njt_helper_ctrl_module.so conf/njet_ctrl.conf;
复制代码 ctrl的配置文件是上面的helper指令中指定,配置文件中配置的指令分为两类:
1)OpenNJet中尺度的指令;
注意:用 error_log 和 access_log 指令指定的log文件要不同于主配置文件中的log文件。
2)通过 load_module 指令加载的动态模块中扩展出来的指令:
ctrl配置文件配的内容示比方下:
- load_module modules/njt_http_sendmsg_module.so;
- load_module modules/njt_http_location_api_module.so;
- load_module modules/njt_ctrl_config_api_module.so;
- load_module modules/njt_http_health_check_helper.so;
- load_module modules/njt_http_vtsd_module.so;
- user njet njet;
- error_log logs/error-ctrl.log info;
- events {
- worker_connections 1024;
- }
- http {
- dyn_sendmsg_conf conf/iot-ctrl.cfg;
- access_log logs/access-ctrl.log combined;
- server {
- listen 8081;
- location /kv {
- dyn_sendmsg_kv;
- }
- location /config {
- config_api;
- }
- location /dyn_loc {
- dyn_location_api;
- }
- location /hc {
- health_check_api;
- }
- location /metrics {
- vhost_traffic_status_display;
- vhost_traffic_status_display_format html;
- }
- }
- }
复制代码 调用其他语言编写的CoPilot
go-copilot开发
目标
在OpenNJet架构中,sidecar agent/KIC agent都将迁移为coPilot,目前他们都实现为独立的go 程序,需要利用cgo的互操作性,提供一个go实现的coPilot POC,以方便其他go实现的独建功能向coPilot迁移。
主要思路
参照现有的njt_ctrl和njt_broker模块,用C语言实现一个简朴的新helper模块,里面在初始化阶段调用go-start()函数启动go实现的服务,同时等候接收到命令,并进行命令处置惩罚。 NJT_HELPER_CMD_STOP命令,要进行制止操作,调用go-stop(); NJT_HELPER_CMD_RESTART 为预留命令,暂不会发送该命令,在事件处置惩罚中可以按制止操作处置惩罚该命令,或者实行自身业务逻辑的重新开始,这个命令先留着一个接口go-restart(),详细实现以后再考虑。
之后是在go语言实现,目前先实现启动制止一个webserver,以后再根据需要实现其他功能。
详细实现(暂时只是启动/制止一个go的webserver)
目前这个模块的功能主要是启动/制止go程序,以是比njt_ctrl和njt_broker模块的实现要简朴一些。
目前将helper中指定的conf路径作为参数传入go程序,作为config文件的位置,以后可以在里面参加要加载的模块;(模块名,启动参数,配置文件位置等)。
最初尝试在c进程中通过导入*.so文件,然后调用相应的导出函数的方式启动web server,但是各种尝试都不乐成。
最终方案是参考nginx-unit和njt_execute实现,通过二进制文件路径来调用,焦点代码为
- njt_pid_t njt_helper_go_start(njt_cycle_t *cycle, char *prefix, char *fullfn) {
- njt_exec_ctx_t ctx;
- char *n, *p;
- char *name = "gocop";
- njt_pid_t pid;
- //这里是拼接出go二进制文件的路径,install脚本会在conf-prefix路径下作了一个软链接
- n = njt_calloc(njt_strlen(prefix) + njt_strlen(name) + 1, cycle->log);
- p = (char *)njt_cpymem(n, prefix, njt_strlen(prefix));
- njt_cpystrn((u_char *)p, (u_char *)name, strlen(name) + 1);
-
- ctx.path = n;
- ctx.name = "go copilot in njt_execute";
- ctx.argv = (char* const[]){name, "--conf", fullfn, NULL}; //命令行参数,指定了配置文件位置
- ctx.envp = (char* const[]){"GIN_MODE=release",NULL}; //要传入的环境变量
- pid = njt_execute(cycle, &ctx);
- njt_free(n);
- return pid;
- }
复制代码 模块中会保存新天生的进程的pid,供stop命令使用,kill(pid, SIGTERM);
编译OpenNJet module
需要修改 auto/options
- # 在 OPENSSL=NONE 下面增加
- USE_GOCOP=NO
- GOCOP_PATH=NONE
- # 在--with-openssl-opt=*) OPENSSL_OPT="$value" ;; 之前增加
- --with-gocop=*) GOCOP_PATH="$value" ;;
- # 在--with-openssl=DIR set path to OpenSSL library sources下面增加
- --with-gocop=PATH set path to gocop binrary executable
复制代码 修改auto/install,增长脚本,在指定了go文件路径后,把该文件复制到njet的相同目录下,并在配置文件目录下做了一个软链接。假如文件不存在,就什么也不做。
- if test -n "$GOCOP_PATH"; then
- if test -f "$GOCOP_PATH"; then
- cat << END >> $NJT_MAKEFILE
- cp $GOCOP_PATH '\$(DESTDIR)`dirname "$NJT_SBIN_PATH"`/gocop'
- ln -sf '\$(DESTDIR)`dirname "$NJT_SBIN_PATH"`/gocop' '\$(DESTDIR)$NJT_CONF_PREFIX/gocop'
- END
- fi
- fi
复制代码 修改build_cc.sh
- #增加
- NJET_MODULES="$NJET_MODULES --add-dynamic-module=./modules/njet-helper-go-module"
- #在LIB_SRC_PATH上增加
- LIB_SRC_PATH=" --with-openssl=auto/lib/tassl --with-pcre=auto/lib/pcre-8.45 --with-gocop=/root/go/src/gitee.com/liismn/go-copilot/cmd/main"
复制代码 其他题目
SSL的一致性
CoPilot 插件,假如使用了SSL库,需要与Njet 编译时使用的SSL库版本相同。 插件编译时使用的 Include 头文件目录( -I ),及链接时使用的 Library 目录( -L )需要指向相同版本的SSL 库路径。
使用cmake编译时,在CMakeLists.txt文件中的include_directories 及link_directories填入对应SSL库的路径
include_directories(${NJET_SSL_LIB_INCLUDE_DIR})
link_directories(${NJET_SSL_LIB_DIR})
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |