之前完成了executor,在agent上主要是将master派发的任务,执行任务完成相应的工作,最后得到结果,结果无论错误还是成功都需要保留下来,在适当的时候把结果返回给master,所以主要是个主从关系
agent其实功能比较少,就是个执行器,把任务完成,结果返回。完成工作要造一个类,完成shell脚本的executor类。
接收任务需要一个消息,消息格式要定义,返回结果,结果的消息也要定义,目前功能完成到了注册和心跳。
agent节点有可能上线,下线,主节点必须知道哪些节点存活和不是存活的。但是agent突然崩了。主节点是无法查询到了,来不及喊一声挂了,主节点不能一直傻傻认为是ok的。
传统的cs开发里,agent必须定时告诉master还活着,这种称为心跳机制,是传统方案。agent很多的话,master收到的心跳包也够多了。
现在采用的是单播方案,每一个agent单点链接到master的方案,master比较频繁地收取心跳包,master的网络负担会越来越重,心跳包越小越好
信息先这么处理,先做出来,这里肯定要用cs编程,就要用到socket编程,但是太low,开发效率低,在真正开发中,除非非常在意底层细节。
现在需要用到进程间通信,IPC,i之间,p进程,c通信,只要离开了线程,就能知道如何通信了,线程里的同步技术,在IPC里都可以用,python帮你实现了,甚至python帮你跨网络节点。
但是最好用的就是IPC里进程间网络通信叫RPC,远程过程调用。
IPC范围大点,RPC范围小一点(通过网络如何让两个进程间通信),跨进程通信必须实现序列化和反序列化
别人问你用什么网络框架,rpc框架,python里有zerorpc。
客户端发起请求给webserver,webserver转发给master,再转发给agent来完成
master和agent采用TCP,效率高,数据传输约定好格式,reg和heartbeat,要序列化和反序列化传输,这时候有msgpack,效率很高,而且做了数据的压缩
又要结合rpc网络通信,rpc封装底层socket,又要序列化和反序列化,将这个完美结合,就是zerorpc。这是基于ZeroMQ和MemsssagePack。
可以把这个ZeroMQ看成事一个高级的socket封装,MemsssagePack就是一个数据的序列化和反序列化。
所有的rpc框架必须解决序列化和反序列化,还有解决网络通信问题
messagepack,完全支持,python的基本数据类型,传输过去能够完全还原回原来的数据
要写的代码就这么几句
这种连序列化和反序列化,通信全完成了
这里不是打招呼,是调用对方的接口,这个hello其实是server的,客户端允许随便调用方法,但是这个方法必须要求server端是有的,把你要的数据传给它,把数据往这里一些即可。
其实会用这个hello做名字,
通过tcp链接起来,通过client想未来到server端找到一个hello方法,然后传个数据
HelloRpc是一个实例(类似socket server里的handler),处理函数就是hello,server要绑定地址端口
消息传到端口,就被反序列化了,之后等于告诉它找hello方法,把它的数据传递进去,调用hello方法,是用client的hello名称去找
找到之后,server的hello把你传递的参数放进去了,
这个rpc框架在python里得到广泛应用
还支持node.js,实际上就是把hello作为一个字符串参数传过去,server通过名字找相应的方法,这里大括号就是个对象
这个对象找他的key,就是找hello,hello里就是个回调
安装一下
做网络通信,这两个可能问到
链接服务器,调用服务器的函数,还在等待服务器的return返回,发送返回都在这条语句上
改下端口
服务器运行起来
这样就ok了
t1现在是server,可以想象成master,t2就是client
单独运行t2就有问题,在等超时
链接不到就喜欢重试,重试之后,还不行就丢失了heartbeat,超时时间是十秒
使用rpc框架后,十秒钟未连接,agent尽量尝试和服务端进行链接,所以最好try一下真正的链接,链接的时候但凡有错误,重新发一个,如果发送消息过程中,突然中断也看下
现在主动被断开,现在想重连一下
启动一下服务器
这里中间会有一些异常
这里一秒秒都在增加
将T1停止
再次启动t1
这边就开始了
现在agent就告诉上线的master,虽然刚才下线了,但是上线之后汇报,自己的heartbeat是什么意思,这时候断开重连机制就实现了,可以继续发送没有问题
断开t2,现在服务t1是启动的
client现在断开没什么问题
现在要写一个跟链接相关的,executor管执行,message管消息,现在就管一个服务就可以了,但是这里是作为一个client
写个配置文件,写一些自己的东西
需要用一个zerorpc取一个client,现在就把这个链接创建了,但是这个链接有问题,可以断开,所以放在初始化里,循环起来就不方便
所以应该放在start里,一旦启动服务,就启动,可以写个flag标记,可以用threading里的event,如果出现了断开,就等一下就行了,还需要尝试try一下,getlogger看一下日志,出现什么问题
断开的错误应该输出一下
一旦连接成功,就要发注册消息了
agent包里有这两个方法,不断生成注册信息和heartbeat信息
这是server的reg
就跟之前调用的hello一个道理,把这个hello作为一个名称传给server端去
server端去跟这个名称找匹配的方法
以后服务器端必须有reg方法,这里做个约定,里面调用message的reg,生成一个reg信息
是个实例的方法,需要一个实例,在一个实例使用,不建议用全局的方法
下面就可以调用了,zerorpc,其实底层用的是messagepack,序列化的时候会标记是什么类型,每一种数据类型有特殊的标记,现在返回的字典,是内建数据结构,msgpack认识,直接序列化
心跳包一定要时间戳,时间戳没了就不叫心跳包了,有些时候,因为网络原因,收到的时候已经超时了,时间不对就认为是下线的
server时间9点,但是发过来的时间是9点00,10秒,超前,在集群里,时间偏差太大都认为是下线的,大家时间应该统一
下面应该while true,因为不停歇,需要有个时间间隔,也可以放在配置文件里配置
断开重连有些场景下需要注册,有些会把你的信息彻底删除
容器就是对cpu资源的一些封装,
写一下shutdown
close是把所有的类都关一下
注册心跳都有,相当于把master的事情都做了
只要涉及到网络通信,就可以用zeromq,小巧高效
虽然用了event但是不推荐用多线程方式
会出异常
一个agent一个,但是要起多个agent,myid就不能指向同一个位置了
需要一个链接管理
这个链接做个循环,但是有可能会断开,要实现断开重连机制
这个方法是带序列化和反序列化的,对端做反序列化
不用多线程跑,但是一定要一个主线程
这么些就是永久阻塞
下面要构造一个agent,cm是链接管理,config配置,executor找到任务执行,message消息通信都在这里
对外要声称自己是什么,要包装,agent类,都从这个类开始,让对方调用类,这个类需要建立链接
从当前的cm当中导入connectionmessage类
创建agent的时候就可以传,去链接哪个服务器
cm修改下
内部模块全部归到统一的类里,这样别人使用暴露几个简单方法即可
这个暂时用不到
client启动就等于24小时一直在等master发命令,能否把重连机制放到start,链接是否中断
修改一下
链接管理
虽然不能用,但是举个例子,
比如把这个移走,放到一个文件
用这种方式就可以调用了
调用agent然后start
start调用cm的start
在这里开始链接服务器,然后断开重连,注册相应信息,进行心跳循环发送
现在是一个功能写一个模块,然后把这个模块组织到包里去,提供一个外部能调用的接口就行
agent里的事情就做的差不多了
这里有异常可以在这里加一个
在处理的时候需要加一个循环控制
在内部加循环跑起来就行
myid如果要修改传入的位置可以这么修改
可以告诉myid的文件位置,MYID_PATH送进来
cm可以直接写进来,放message对象
可以放个message对象,写成这样,可以把message对象直接传给你
可以用myidpath来做,因为message参数就有myidpath
在这里把参数送进了其也可以
这里把message对象创建出来
这里是把agent创建好后,送进来是个对象
一般习惯把所有以后能配置的参数,以后可以统一设置