之前完成了agent部分的代码,agent进行了消息的简单封装,有心跳和注册也调用了zerorpc库,底层结合了zeromq和messagepack,具有通信的能力和序列化和反序列化,有了这两样就可以远程调用server,agent可以调用远程server,server提供的方法和功能,叫远程过程调用,其实就是远程的方法
agent调用master方法,然后将里面的数据进行处理,然后可以返回
master
1.首先要绑定端口,启动监听,等待agent链接。
2.维护所有的agent,需要agent列表,注册过的都会记录下来,掉线的会打个标记,在线,正在忙,掉线可以用不同颜色表示。
3.是做任务调度的,所以任务要保存下
任务是由用户通过浏览器发给web server,webserver转交给master的,master最后下发给agent,master做所有任务管理,agent处理完所有任务需要返回回来交给master,master要做结果的保存
master要做task管理,agent管理,数据要做持久化
能将注册信息写入agent表
能接收心跳信息,更新agent状态
任务成功和失败要记录
由用户提交任务到master,master分派到不同的agent,由agent的执行完后,将成功和失败的结果返回给master,用户就可以查询到提交的任务执行过,结果如何
可以让webserver从数据库里读取数据进行展示
作为服务监听在什么协议,ip,端口
跟刚才一样,config做全局配置
下面就是通信模块CM
server需要一个类的实例,里面有所有调用接口,类似heartbeat,reg这些
在client中这些算1个参数
要写一下配套的message,解析那边传消息的方法,reg是server端的,这里收到的也是一个参数,返回来的是一个字典
现在做的事情是,当客户端在那边调用reg,实际上这个方法想要的是服务端方法,是远程的过程调用,传到服务器端,服务器端替你调用,然后你的字典会注入进来,拿到字典会做相应的处理,最后打印一下信息,return的意思是client调用reg,传入一个数据给msg,msg拿到之后return信息作为client调用方法的返回值
现在测试t1server,pass就是return none
t2启动就返回none
heartbeat也是一样,发过来就是dict
把这个message导入来
其实这个实例暴露一大堆接口
写一下注释,客户端的接口都在这里
cm这边把对象创建出来
创建完之后是绑定
绑定相当于服务打开,这里不需要断开重连机制,server断了就断了,就存在单点的问题
专门给别人调用的一个
这里只是初始化
这样master就写好了
写测试,appserver
这样一旦启动就可以使用了,9000启动了
appclient,跟master链接,注册,并且隔5秒发送心跳
这样每隔5秒就发一次
打开myid
这个id文件只要不删除,就会一直保存
服务器端在message中,要做进一步处理
先把服务器和客户端打通了,再写管理
最后写master类
这个虽然跟master类似,但是要告诉别人这个就是专门做链接的
这是来做统一对外的一个处理
master的数据设计
master需要存2种数据,
1.所有agent注册之后,要把agent保留下来
2.用户提交的任务也需要保存下来
每一个agent对应一个agent对象,提交agent数据,心跳信息以外以后可能还会定时汇报一些其他信息,cpu,网络空闲之类的。
持久化可以封装成一个类。
这个就要将所有提交的数据封装成一个agent实例,这样保存起来就好了。提交的任务也是字符串,有 可以保存成任务类的实例。
也就是提交进来的所有数据,应该放在类的实例的属性上
每一个任务是有状态的:
waiting,任务还没开始,agent还没拿走执行
running,agent拿走执行,任务拿走了就开始运行了
successful,任务执行有成功还是失败
failed,任务失败
agent也是有状态的。
waiting,agent上闲置没有任务
running,agent正在跑任务
successful,agent上完成任务
failed,agent上执行失败
master应该给agnet空闲了才发任务,master知道agent是否现在空闲,空闲是否都可以派发任务,派发任务跟你空闲与否无关,拿任务是空闲了再拿一个
可以建立一个common包,可以放全局通用 的信息,跟master,agent无关
这里的config就只跟agent有关
common里可以放全局都使用的状态信息
这里是刚好巧合,任务和agent状态一样,但是意义并不一样,现在可以暂时放在一起
下面需要定义agent类
在master下定义一个agent模块,在这个模块里要写一个class Agent,客户端注册来的信息需要封装,用面向对象来封装一个提供信息存储的类,数据存储在类的实例中
还有就是用户提交的task,任务就是类的一个个实例,一个个任务就是一个个实例
**应该通过uuid来找agent数据,所以应该是字典,把所有数据能封装,都用面向对象的方式封装,函数是一种封装,但是函数主要做的是操作,而类的封装是对数据的封装,同时还可以把实例相关的方法一起封装。
函数是只有操作的封装但是类可以做数据的封装,用类来生成一个个实例将数据封装在实例中。
**
这样agent要写几个属性,id是什么,记录hostname是什么,ip是什么,把这些信息加进来,注册时候添加的信息往里面保存就差不多了
task也类似,用户提交的任务什么,任务里脚本什么,设定的超时时间,用户指定任务的时候,要看哪些主机可用,最好像annsible一样提交写好分组,以后可以把任务拍给1,2,这样信息到了master这里,master记录任务信息,封装成一个个任务对象