SGame 新加进程(2)
构建代码
在建立了底层通信之后,只需要写disp_serv上层业务逻辑即可,我们在sgame/servers/目录下新建一个disp_serv和disp_serv/lib
- 目录如下:
|-- disp_serv
| `-- lib
- 拷贝connect_serv目录下的connect_serv.go到disp_serv/并改名为disp_serv.go。 拷贝connect_serv/lib/目录下的base.go,hearbeat.go,recv_msg.go,report.go,send_msg.go 这几个文件到相应位置,如下所示:
|-- disp_serv
| |-- disp_serv.go
| `-- lib
| |-- base.go
| |-- hearbeat.go
| |-- recv_msg.go
| |-- report.go
| `-- send_msg.go
上面这几个文件就构成了一个进程的基本功能。主要代码都可复用,只需要修改几处个性化的地方即可。下面依次来看
基础代码
- disp_serv/disp_serv.go 这是进程的主函数,主要调用lib里的各API完成,主要是解析参数;通用设置;本地设置以及拉起进程。因为参数都是统一的,这里代码基本不用修改
func parse_flag() bool {//check flagflag.Parse()if len(*name_space) <= 0 || *proc_id <= 0 || len(*config_file) <= 0 || len(*proc_name) <= 0 {flag.PrintDefaults()return false}pconfig.ProcId = *proc_idpconfig.NameSpace = *name_spacepconfig.ConfigFile = *config_filepconfig.ProcName = *proc_namepconfig.Daemon = *daemonizereturn true
}func main() {//parse flagif parse_flag() == false {return}//comm setif lib.CommSet(pconfig) == false {fmt.Printf("comm set failed!\n")return}//local setif lib.LocalSet(pconfig) == false {fmt.Printf("self set failed!\n")return}//start serverlib.ServerStart(pconfig)
}
- lib/base.go 这个文件包含了进程的主要实现和配置的建立,所以是非常重要,但主要代码仍然可以复用,只需要修改少数几个地方。
type FileConfig struct {LogicServList []int `json:"logic_serv_list"`LogFile string `json:"log_file"`ManageAddr []string `json:"manage_addr"`MonitorInv int `json:"monitor_inv"` //monitor interval seconds
}type Config struct {//commNameSpace stringProcId intProcName stringConfigFile stringDaemon boolFileConfig *FileConfigComm *comm.CommConfigReportCmd string //used for report cmdReportCmdToken int64ReportServ *comm.ReportServ //report to manger//local
}
主要的个性化部分就是FileConfig的配置,这里是对应配置文件的,即后面我们需要在spush/tmpl/里配置的disp_serv.tmpl,只要这里对应上,其他的逻辑基本不用修改。只需要注意Config里local后的部分,但disp_serv没啥local的 所以无需改动,这里简单说下base.go各主要函数用途
func CommSet(pconfig *Config) bool
这个是通用的设置,一般无需改动func LocalSet(pconfig *Config) bool
这个是本地化的一些设置。比如connect_serv需要加tcp_serv;db_serv需要加redis_client等,但我们这里用不到,就是一些通用的比如加上定时器等功能,基本复用即可func ServerExit(pconfig *Config)
这是进程退出时的执行代码,一般复用即可,除非进程有特别的自定义设置需要关闭
func ServerStart(pconfig *Config) {var log = pconfig.Comm.Logvar default_sleep = time.Duration(comm.DEFAULT_SERVER_SLEEP_IDLE)log.Info("%s starts---%v", pconfig.ProcName, os.Args)//each support routinego comm.HandleSignal(pconfig.Comm)//main loopfor {//handle infohandle_info(pconfig)//recv pkgRecvMsg(pconfig)//tickhandle_tick(pconfig)//sleeptime.Sleep(time.Millisecond * default_sleep)}
}
这是进程的主要结构,包括拉起信号处理协程;处理不同的内部信息;接收进程包;处理定时等 一般不做改动
func AfterReLoadConfig(pconfig *Config, old_config *FileConfig, new_config *FileConfig)
这个是各进程自己处理的在运行中重新加载配置时的个性化处理函数,自己按需添加内容func handle_info(pconfig *Config)
进程内部的一些模块通信,比如停机,重新加载配置,开始性能检测等 一般直接拷贝即可func handle_tick(pconfig *Config)
触发定时器的 直接使用lib/hearbeat.go 进程定期向对端发送心跳包,目前包括以下几个函数:
func SendHeartBeatMsg(arg interface{})
向对端发送心跳包,这里需要修改函数里对端的目标地址即可,比如我们这里是向所有logic_serv发心跳包:
...
//send msg
for _ , logic_id := range pconfig.FileConfig.LogicServList {ret := proc.Send(logic_id, buff, len(buff));if ret < 0 {lp.Err("send msg to %d failed! err:%d", logic_id, ret);}
}
...
func RecvHeartBeatReq(pconfig *Config , preq *ss.MsgHeartBeatReq , from int)
收到对端心跳包的更新 一般不用特殊改func ReportSyncServer(arg interface{})
向manage定时同步进程信息lib/recv_msg.go 通过通信组件收到其他进程发来的协议包,这里是服务器间通信协议分发的场所,在新增协议处理时需要改动,主要函数为:
func RecvMsg(pconfig *Config) int64
lib/report.go : 向manage上报以及对manage的命令处理,后续根据需求添加即可 新进程直接用
lib/send_msg.go : 用于向其他进程发送协议包的汇聚文件,根据后续扩展,目前只有
func SendToLogic(pconfig *Config , logic_serv int , buff []byte) bool
发送到某个logic_serv进程在代码编写(拷贝)完成之后,我们进入disp_serv/; go build disp_serv.go 编译通过即会生成disp_serv。然后进入发布
发布
- 发布配置
进入sgame/servers/spush目录,打开sgame.json 新增disp_serv,如下所示:
{"task":"sgame" , "deploy_host":"" ,"deploy_timeout":60, "remote_user":"nmsoccer" ,"remote_pass":"****" ,"procs":[{"name":"conn_serv-1" , "bin":["../conn_serv/conn_serv"] , "host":"127.0.0.1" , "host_dir":"/home/nmsoccer/sg/group1/conn_serv/" , "cmd":"./conn_serv -N sgame -p 10001 -P conn_serv-1 -f conf/conn_serv.json -D"},...{"name":"disp_serv-1" , "bin":["../disp_serv/disp_serv"] , "host":"" , "host_dir":"/home/nmsoccer/sg/disp_serv/disp_serv-1/" , "cmd":"./disp_serv -N sgame -p 40001 -P disp_serv-1 -f conf/disp_serv.json -D"},{"name":"disp_serv-2" , "bin":["../disp_serv/disp_serv"] , "host":"" , "host_dir":"/home/nmsoccer/sg/disp_serv/disp_serv-2/" , "cmd":"./disp_serv -N sgame -p 40002 -P disp_serv-1 -f conf/disp_serv.json -D"},{"name":"manage_serv-1" , "bin":["../manage_serv/manage_serv" , "../manage_serv/html_tmpl/"] , "host":"" , "host_dir":"/home/nmsoccer/sg/manage/manage_serv-1/" , "cmd":"./manage_serv -N sgame -P manage_serv-1 -f conf/manage_serv.json -D"} ],"proc_cfgs":[{"name":"conn_serv-1" , "cfg_name":"conf/conn_serv.json" , "cfg_tmpl":"./tmpl/conn_serv.tmpl" , "tmpl_param":"logic_serv=20001,listen_addr=:18909"}, ...{"name":"disp_serv-1" , "cfg_name":"conf/disp_serv.json" , "cfg_tmpl":"./tmpl/disp_serv.tmpl" , "tmpl_param":""},{"name":"disp_serv-2" , "cfg_name":"conf/disp_serv.json" , "cfg_tmpl":"./tmpl/disp_serv.tmpl" , "tmpl_param":""}, {"name":"manage_serv-1" , "cfg_name":"conf/manage_serv.json" , "cfg_tmpl":"./tmpl/manage_serv.tmpl" , "tmpl_param":"listen_addr=:7000,http_addr=:8080"}]}
其中两个disp_serv是我们新增的,我们将分别将其部署到/home/nmsoccer/sg/disp_serv/disp_serv-1/与/home/nmsoccer/sg/disp_serv/disp_serv-2/目录里,并分别用 ./disp_serv -N sgame -p 40001 -P disp_serv-1 -f conf/disp_serv.json -D
和 ./disp_serv -N sgame -p 40002 -P disp_serv-1 -f conf/disp_serv.json -D
将它们拉起。 注意看这里的参数40001,40002是之前配置bridge.cfg里分配给它们的proc_id,同时参数里带的进程名尽量保持一致,虽然两者没毛的关系
- 进程配置
我们看到proc_cfg里定义了conf/disp_serv.json,这是未来将自动生成的进程配置文件,它们主要依据是tmpl/disp_serv.tmpl生成,我们可以打开看下:
cat tmpl/disp_serv.tmpl:
{"logic_serv_list":[20001,20002],"log_file":"disp_serv.log","manage_addr":[":7000" , "127.0.0.1:7001"],"monitor_inv":5
}
这个文件需要对应之前的lib/base.go里的FileConfig:
type FileConfig struct {LogicServList []int `json:"logic_serv_list"`LogFile string `json:"log_file"`ManageAddr []string `json:"manage_addr"`MonitorInv int `json:"monitor_inv"` //monitor interval seconds
}
这里就是使用GO的json解析,比较方便
- 发布 然后我们就可以使用spush工具发布disp_serv了:
./spush -p ^disp_ser* -f sgame.json ++++++++++++++++++++spush (2020-08-11 21:28:17)++++++++++++++++++++
.push some procs:^disp_ser*
matched procs num:2
create cfg:9/9----------Push <sgame> Result----------
ok
.
[2/2]
[disp_serv-1]::success
[disp_serv-2]::success +++++++++++++++++++++end (2020-08-11 21:28:19)+++++++++++++++++++++
- 修改管理配置 我们要将disp_serv加到页面管理,只需要打开spush/tmpl/manage_serv.tmpl
{
"listen_addr":"$listen_addr",
"http_addr":"$http_addr",
"log_file":"manage_serv.log",
"client_list":[[10001,"conn_serv-1"],[20001,"logic_serv-1"],[30001,"db_logic_serv-1"],[10002,"conn_serv-2"],[20002,"logic_serv-2"],[30002,"db_logic_serv-2"],[40001,"disp_serv-1"],[40002,"disp_serv-2"]],
"heart_timeout":20,
"reload_timeout":10,
"auth":["xxx" , "ooo"],
"auth_expire":3600
}
新加[40001,"disp_serv-1"],[40002,"disp_serv-2"]项目,然后生成并推送mange配置
./spush -p man* -f sgame.json -O++++++++++++++++++++spush (2020-08-11 21:31:53)++++++++++++++++++++
push some procs:man*
.matched procs num:1
create cfg:9/9----------Push <sgame> Result----------
ok
.
[1/1]
[manage_serv-1]::success +++++++++++++++++++++end (2020-08-11 21:31:54)+++++++++++++++++++++然后kill -10 manage_serv[pid]让其重新加载配置,log如下:
[2020-08-11 21:33:02.477 info] recv signal usr1!
[2020-08-11 21:33:02.481 info] >>reload config!
[2020-08-11 21:33:02.481 info] <LoadJsonFile> load conf/manage_serv.json success!config:&{:7000 :8080 manage_serv.log [[10001 conn_serv-1] [20001 logic_serv-1] [30001 db_logic_serv-1] [10002 conn_serv-2] [20002 logic_serv-2] [30002 db_logic_serv-2] [40001 disp_serv-1] [40002 disp_serv-2]] 20 10 [xxx ooo] 3600}
[2020-08-11 21:33:02.481 info] <AfterReLoadConfig> finish
可以看到加载成功啦 ,然后点开页面127.0.0.1:8080/index 就可以看到新的disp_serv监控。具体的管理端请参见页面baba
SGame 新加进程(2)相关推荐
- SGame 新加进程(1)
这里以disp_serv为例来说明新建一个进程所需的代码结构和相关配置 通信配置 首先我们需要将新的进程加入proc_bridge的通信链路中. 打开sgame/proc_bridge/sgame/b ...
- CreateProcess创建新的进程
CreateProcess创建新的进程 标签: attributes windows null security class 扩展 2010-03-16 10:37 3472人阅读 评论(0) ...
- 【MC】新加载器 Quilt 好用吗?和 Fabric 相比好在哪?
在今年四月 (2022/4/20) ,一个船新加载器 Quilt 发布了第一个测试版. Quilt officially entered its first beta today, attractin ...
- ubuntu16.04不能访问新加卷
ubuntu16.04不能访问新加卷 Ubuntu下U盘出现只读模式,无法写入文件解决办法: 参考博客: https://blog.csdn.net/chudongfang2015/article/d ...
- ROM-libcore中新加java文件编译报错
背景: 1.安卓9之前,libcore中有一个libcore/io/EventLogger.java,但是安卓10之后却没有了 2.EventLogger可以将进程中所有的event事件,收敛到这里, ...
- maven上解决循环依赖、又不想新加第三模块的方法
maven上解决循环依赖.又不想新加第三模块的方法 参考文章: (1)maven上解决循环依赖.又不想新加第三模块的方法 (2)https://www.cnblogs.com/yuan951/p/89 ...
- centos 对已有卷扩容_CentOS LVM 新加硬盘,扩容逻辑卷步骤
from: http://bbs.chinaunix.net/thread-3613556-1-1.html 试验环境: vmware下,centos6,64位版本,原来系统默认分区,/dev/sda ...
- SQL 新加字段查询窗口报错
SQL 新加字段查询窗口报错 这是由于SQL Server的intellisense的引起的,intellisense是SQL Server的智能记录智能感知功能,即当给sql表名加上".& ...
- python中fork创建新的进程
为了了解其中工作原理, 在结合linux的查看进程ps命令,对进程做了进一步的理解: 1.在linux下运行.py文件,系统就会创建一个进程 # coding=utf-8 from time impo ...
最新文章
- C语言求数字菱形,打印数字菱形,急啊,帮帮小女子啊。。。
- cocos2d-x-3.1 win32程序-初识源代码(coco2d-x 学习笔记二)
- FPGA之道(66)代码中的约束信息(三)存储器以及寄存器的相关约束
- python语法怎么读-python语法技巧
- oc58--Category注意事项
- 上海计算机职业学校排名2015年,2015年上海各区学校教育资源实力排行榜
- 阜阳男子拿22万硬币去银行转账,银行员工数钱数到“手抽筋”
- 物联网技术周报第 143 期: Unity 3D 和 Arduino 打造虚拟现实飞行器
- 阿里助手 5.12.2
- mysql中对象标识符的命名规则,标准规范数据库命名规范.doc
- 生成ltx文件命令_利用二次开发工具批量生成PCDMIS程序
- @PropertySource读取properties属性 中文乱码问题
- Install SQL Server 2008 Setup failure
- CSS系列之字体相关的样式
- java护眼的颜色_爱护眼睛,从IDEA开始,护眼色设置走起-护眼设置
- PPT动态文字制作过程
- **********模拟新浪微博*********
- 搜索引擎类网站调查报告
- shimano 型号详解 (zz)
- [推荐系统]推荐系统实践Reference
热门文章
- jiaThis工具--社会化分享按钮功能实现
- 遗传学(如何把自身特征的信息传递下去):把充满不确定的遗传问题变成信息问题
- 在html语言描述中,css的特点有,css样式 css样式语言特点
- 神经网络的前向传播推导(图、公式)
- 清除cin输入缓冲区,以及system(“pause“)、system(“cls“)用法
- 企业为什么喜欢专家或者一专多能的人
- 评《“互联网+”草根春天,传统企业怎么办?》: “大风起兮云飞扬”,互联网+为你狂!
- 通过RPM方式安装,升级,卸载,以及配置使用MySQL
- StretchDIBits速度测试(HALFTONE)
- Mongo入门(一)