qidao123.com技术社区-IT企服评测·应用市场
标题:
CoPilot 开发指南
[打印本页]
作者:
飞不高
时间:
2024-10-14 02:13
标题:
CoPilot 开发指南
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企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/)
Powered by Discuz! X3.4