2020/04/25 04-任务接受、分派和Agent执行实现

在这里插入图片描述
任务是从前端web界面提交来的,是使用http协议,到webserver这边是用的json方式(react,jquery,axios都可以),webserver拿到数据由他转发到内部的,后面才是cs结构
在这里插入图片描述
在这里插入图片描述

任务脚本,纯文本,数据是比较多的,建议使用base64编码,安全
在这里插入图片描述
在哪些agent跑的agentid,用户可以选也可以不选,用户可以用列表来选择,

在这里插入图片描述
用户可以用列表来选择

在这里插入图片描述
还可以这么选择,任务有几个节点要选择,比如10个,用户根本不用关心选什么,用户傻瓜化,由master决定最后发给谁
在这里插入图片描述
但是现在有需求,指定在哪里完成,这样就让用户选比较好了
在这里插入图片描述
master收到任务信息后,需要添加2个信息:
1.每一个task没有id,这个id必须唯一,这次还是采用uuid的方式。
2.state添加完信息,将任务封装到对象,并存储起来

在这里插入图片描述
在这里插入图片描述
所以在message中还要加一个add_task
在这里插入图片描述
其实message成了一个rpc调用接口的这样一个类
在这里插入图片描述
在这里插入图片描述
这边调用就要暴露接口,还是再message上暴露

在这里插入图片描述
知道你是server,要调用你,可以写一个add_task,传过来还是json,因为http传过来是json,webserver可以转化成dict,再发到master,通过序列化和反序列化,master还是拿到了dict。
webserver和master是用rpc来通信,通过序列化和反序列化,转完之后提交来

在这里插入图片描述
在这里插入图片描述
也可以return一下,最起码用户提交,告诉用户提交成功了,add完,return回来一个task对象,task对象有属性叫id。
任务生成了一个id就代表成功了,就没必要去设置一个成功值了

在这里插入图片描述
前面传的时候 ,需要base64编码一下,timeout超时时间,pararrel并行度

在这里插入图片描述
上面这些信息也要填进来

storage看一下add_task怎么写,id掌握在服务器生成比较好,不要前端,这样就能传进来了,正好上面的task是kv对,解开就是谁等于谁,关键字传参
在这里插入图片描述
t.targets放的是列表
在这里插入图片描述
现在这里面必须写target对象
在这里插入图片描述

t.targets,勾选的是agnet的id,能否换成agent的对象,如果用列表可以这么写,但是比较不好,但是查询比较麻烦。
在这里插入图片描述
可以用字典,当前targets就是列表,agent_id就是前端勾选的agentid,这里用kv对比较好,agents里是注册好的
在这里插入图片描述
为什么要有agents,是因为客户在选择主机的的时候,从agents传给webserver,由webserver呈现在浏览器上,这些agent_id就可以在agents里找到,但是有风险,可能里面有的会掉线。
在这里插入图片描述
状态是掉线,但是agent还是在的,掉线之后删除掉就没了,这里只存不删,就还好,否则就要用try
在这里插入图片描述
targets从原来一解构,一个个agent的列表,现在变成了一个个以agent为key,agent所对应id,所对应的agent对象,变成这样一个字典,方便调用,可以的话,可以对字典进行二次封装,将字典变成属性
在这里插入图片描述
这里该解构解构,该替换替换了

在这里插入图片描述
现在把id返回去,就代表成功了
在这里插入图片描述
这里看返回none,就说明提交任务失败
在这里插入图片描述
在这里插入图片描述

用外面调用的接口,先定义这个方法,再将它对应的方法才去实现

在这里插入图片描述
在这里插入图片描述
任务来了还需要加入任务列表,tasks里有targets,targets里还有taskid
在这里插入图片描述
agent里也有taskid

在这里插入图片描述
这样就是两个互相引用

任务分派

**有两种方式,推拉,由master推到agent上,或者由agent主动拉取。
任务在storage存储,storage里面定义了tasks,tasks任务可能有很多,不可能把几十年的任务都放在里面,做完的可以持久化,待做到放在内存中,这些都放到storage模块里了,这个模块里会有任务列表。
**
在这里插入图片描述
这个任务列表有两种方式,master推到agent端,或者agent端拉去数据,其实这里可以在agent之间做队列。
看到主动推就可以用消息队列。
agent闲了可以去拉数据,agent主动要任务的时候,master要遍历任务列表,找任务的targets,任务目标处理里有没有你,所以要遍历任务,还要找任务归你管的

在这里插入图片描述
所以越存越大,可以交给redis

在这里插入图片描述
主动推过去,是因为在选择任务的时候已经指定目标的agent是谁,在发任务,人为就已经选择了,如果更进一步处理就更加复杂了,如果这个任务必须在10个节点上 计算,没有选择哪10个节点,要动态分配,这就是更难的问题,动态实现agent调度,就要关注agent详细情况,是否繁忙,然后选择比较空闲的去运行你的程序。
如果采用master主动分配,就出现了调度策略的

**所以与其调度,不如闲着来拿,这时候就不用调度了,现在选择agent拉的模式来完成任务,这样master就不用设计一个调度器了 **

message是暴露给客户端的接口,是暴露给webserver的
在这里插入图片描述
pull_task,拉一个task,需要return一个任务回去,任务id,任务脚本,超时时间
在这里插入图片描述

加个agent_id,先要明确你是谁,才能帮你找任务
在这里插入图片描述

可以改个名字,看的直观点,pull_task是拉任务的,拉任务用agent_id拉
在这里插入图片描述
这个get_task_by_agentid是要在storage类添加的方法
在这里插入图片描述
上面返回是元组,下面会序列化,msgpack序列化元组没什么问题
在这里插入图片描述
也就等于这样
在这里插入图片描述
导入状态
在这里插入图片描述

storage里的get_task_by_agentid,遍历所有任务,拿到task对象,task成功了就不需要你去做了,所以要做下判断,
我们只关心任务状态为wait和running的,做完successful和失败的就不派发了

在这里插入图片描述
我们经常要去task遍历某种状态,可以写成公共的

在这里插入图片描述
可以抽一个方法出来
在这里插入图片描述
起个名字iter_tasks
在这里插入图片描述
在这里插入图片描述
可以抽参数,经常是按照你指定的状态进行遍历获得这个结果
在这里插入图片描述

还可以写成列表,从所有里去遍历,状态符合要求的task
在这里插入图片描述
targets里是agentid
在这里插入图片描述

拿到task之后,首先要看目标是否是你,要看targets有没有你,targets里是agentid,用agentid可以找到agent,在targets,就认为此agent可以执行任务
在这里插入图片描述
agent其实是不知道自己有没有做过任务,没做标记,就会反复去任务里去拿
在这里插入图片描述
agnet做了outputs,可以记录一些信息
在这里插入图片描述
outputs是taskid是key
在这里插入图片描述
outputs是taskid是key
在这里插入图片描述
就可以进行判断,没有领过就进来领取,用字典比较快,有了,就等于领过任务,看下一次任务
在这里插入图片描述
有人领任务了,状态就要跑起来了
在这里插入图片描述
task其他都是写死的,只剩state能改
在这里插入图片描述
这是在master里建立的一个个agent对象,一旦领任务,状态就是running
在这里插入图片描述
这个任务状态,只要一个来领任务,就认为是running
在这里插入图片描述
在这里插入图片描述
完成的要从任务里拿走

在这里插入图片描述
逻辑是这样的,遍历所有的waiting的和running的task,从task中找到在不在targets列表中,看看自己有没有任务,但是有没有任务是不知道的,就 要你看看这个任务你接过没有。
在agent上写了outputs,任务接过了就需要吧任务打个标记,没做过,putputs里就没有,就把任务接了,接了之后,转换一下状态,将任务信息提取到就return了

在这里插入图片描述
return的信息到这里了

在这里插入图片描述
这样发过去就知道任务id,任务脚本是什么,超时时间是什么
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
最后把这些数据return出来,遍历是读取,running,waiting的,通过targets来判断自己是什么

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
最后return一个元组回去

在这里插入图片描述
agent如何来领取任务

在这里插入图片描述
agent通过这个暴露出来的接口,在rpc的client端可以直接调用这个接口,调用接口要么返回none,要么返回三元组,通过这个值就判断自己领取任务是否成功。空闲了就来领取任务

在这里插入图片描述
领取任务一定要agent自己处于waiting状态,到master来领,调用pull_task接口来领取。

在这里插入图片描述
发一个心跳,顺带领任务和执行,但是有可能超时,现在是同步执行,可以改成异步执行。,不能用线程,因为zerorpc放在线程会出现异常
在这里插入图片描述
可以用线程,但是注意zerorpc的问题
在这里插入图片描述
跑到线程里放执行器
在这里插入图片描述
在这里插入图片描述
线程要一个函数,写一个函数,这个函数自己用,将现在这些传进来
在这里插入图片描述
message的id就是生成的uuid
在这里插入图片描述
拿一个三元组,client.pull_task,message的id,将自己的agentid传给pull_task,拿完任务,就变成三元组返回来,元组解析后还是一个元组
在这里插入图片描述
把元组直接作为一个task扔进去,再启动一个__exec

在这里插入图片描述
task run谁首先把,task_id和script解析,timeout,把三个值解构出来
在这里插入图片描述
看一下run的返回值,是code和text
在这里插入图片描述
在这里插入图片描述
现在得到这个数据后可以调用result,是rpc的服务端的result接口,服务端有result去接收这个
在这里插入图片描述
是谁需要表明,task_id加进去,这是谁的结果
在这里插入图片描述
但是这样调用rpc有大问题,可以用concurrent.futures,这个是异步操作方式去拿future对象,但是这样就有可能使用多线程
在这里插入图片描述
现在的agent一次执行一个任务,上面一句不能在这个线程里用
在这里插入图片描述
这样这个值就可以更新掉,这个值通过返回的result,顺便就解构了,也可以不解构
在这里插入图片描述
现在这里需要加个状态
在这里插入图片描述
初始化第一次是等任务的
在这里插入图片描述
start领取任务,就可以做一下判断,有任务,就代表running起来了
在这里插入图片描述
如果现在在等,则拉个任务回来,如果任务不是none,就立即开始状态变成running,开始跑任务了,然后调用线程执行任务
在这里插入图片描述
任务执行完的结果,给result,如果执行成功了则successful,失败就是failed
在这里插入图片描述
message这里可以拿到自己的agentid
在这里插入图片描述
在这里插入图片描述

下面要判断下result状态,如果是successful和failed,就代表做完了,将任务id告诉你,result也告诉你。
最后把把result发送过去,在自己的类里用双下划线没问题

在这里插入图片描述
还可以再判断下,result要立即清除,循环利用,发完了成功和失败并不重要,状态就可以回到waiting了
在这里插入图片描述
现在这样调用,把信息发到服务器端,服务器端就会做处理,这里把消息打印一下,清除一下,把状态清一下就ok
在这里插入图片描述
zerorpc不能跨线程
在这里插入图片描述
也可以调整一下
在这里插入图片描述
判断有没有领取过身份证的方式,下面还可以进行判断状态,来确定是否领取过任务,agent自己没有领过就是waiting,没有领过下面要做的就是把状态变成 running。
这样有两种方式,其实都可以

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
判断状态是否是waiting,如果是waiting就立马改成running
在这里插入图片描述
相对来讲这种方式更加轻巧一点,下面就不需要了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
多线程把数据处理好了,外面没有办法拿到,但是concurrent.futures,这个futures对象可以拿到return结果
在这里插入图片描述
所以在这里就算写了执行函数,这个执行函数其实是拿不到结果 的,因为多线程的return结果是拿不到的,所以要用异步的方式,用futures对象来拿到结果
在这里插入图片描述
不用futures,就用这两个来拿到结果
在这里插入图片描述
配合这里的代码,慢慢把条件加好了
在这里插入图片描述
跨了线程,就可以到另外的线程再起一个链接到服务器就可以了,agent可以起多个线程到master在这里插入图片描述
上面是result的进程,result结果想在cm中直接调用发送了
在这里插入图片描述
前面调用了message,下面能否也调用message
在这里插入图片描述
在message里再写一个方法
在这里插入图片描述
要taskid,就不这么写了
在这里插入图片描述
用message.result将消息发给它,还有解构,
在这里插入图片描述

再加一个result,self。id就是myid,agent的id,task_id,上面解构,就可以直接拿到值了,这里不用担心字符串,这里用msgpack会帮你压缩
在这里插入图片描述
这样result就发到对端去了,服务器端收到消息进行处理

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值