核心部分大致分三部分,1.web,2.master主控,3.agent被控,主控需要实现高可用,实现备用的方案
建立三个模块开发,主模块是主模块,agent是agent,webserver是webserver,各开发各的,这里的init都是空的
需要加个日志,log里有个日志流动,日志可以生成一个message会输出,写一个工厂模块,要一个log,给一个log实例
常用的有stream和handler,streamhandler是控制台上走,还有是filehandler往文本文件里走
这里需要第一参数,filename
filename类型是个string,就是文件输出的路径
logging下有formatter,第一个参数fmt指定格式,asctime时间,message,在什么地方,一般是在什么函数,什么方法里,能否把函数名和方法名暴露出来
funcname执行的函数名和级别名称levelname
有等级,就可以在后面有err,info,这样一分析,就可以把日志分析处理,所以还是带上级别比较好
日志流
加个级别levelname,funcname函数名。按照你所指定目录或者文件,去创建这样的日志
跟loger做的事情其实是,如果你什么都不弄,控制台streamhandler会创建,也就是最后把你所有信息输出到屏幕,如果什么都不改,除了自己这边的level是可以的。
所以这里的setlevel写什么也是个问题
首先跟自己的logger级别做匹配,大于等于这个level就进来,进来看handler级别,handler符合就写下来,handler所有处理完后,当前的副logger作为当前logger了,然后将这些数据就是消息给所有副logger所有的handler看一看,能不能符合你的handler的level
先跟自己的比一下,比成功了就记录进来,filte先不管,就进入自己的所有handler,所有的hanler处理之后,
就是把副logger变成自己,变成一个当前的logger,给当前的logger所有的handler发消息,看它能不能处理
,能不能向副传递。看propagate
自己的事情自己处理,不复发了,阻断了,消息发给自己的所有handler,handler该处理处理,处理完就不需要复发了
如果自己懒得写streamhandler,可以借用父的这边,创建默认的streamhandler,在给你控制台打印,把这个改成true也没有问题
设定一个logger,setlevel,propagate,最后得到自己的handler(filehandler),为这个handler配一个formatter
把handler加给当前logger,这样logger终于有自己的handler,没有handler没人替你做输出的事情,只有logger,但是logger是判断水能否流进来,水流进来,handler要替你做处理,要跟handler的level过一下
用info,那一直记录这个日志会变的很大,日志就需要滚动,不可能无限膨胀
logging这里肯定提供了类似的滚动,这个rotating就是滚动 用的
间隔多长时间
写个测试的看看
看一下其他参数
统一UTF-8,这样在windows和linux下就不会出现乱码,现在是logger定义
运行一下,让日志滚动起来
现在好像没有写进去
这里说如果等于0,将不会发生
快一点
可能代码有问题
logging,走的是rootlogger,所以这里改成logger
速度慢点
都49K了还是没滚动
这句话
不能忘记backupcount=0
把文件先删除
要加上backupcount=5,就是备份数是5+1
刚开始有testlog,达到10k的时候开始滚动,下一个为testlog,原来的testlog,rename为testlog.1,当testlog再次发生滚动,testlog.1继续改成testlog.2,尾数越大的文件,数据越陈旧,testlog永远是最新的数据
再次运行
5里面应该是最陈旧的数据,现在5里面是1562,也就是0-1561都被覆盖掉了
日志可以适当调大,多滚动几次没有问题,但是到一定程度,也该覆盖覆盖,现在是10k
现在就加下参数,现在能存最大60M日志
实际中,按照这样写就差不多,日志模块放到utils里
滚动日志
日志模块是放在工具模块中提供了一个函数。这个函数将我们所有要配置的参数都写好了,我们只需要从中提取我们要的东西即可
测试代码可以都写到main当中,这是被导入模块,所以这块代码以后也用不起来
任务分发设计
任务分发有两种方式,1.有agent,和无agent设计,无agent就是类似ansible,被分发节点无须安装东西,但是要是管理不善,也会有安全隐患,所以需要做审计
无agent有点:
1.简单高效
2.并行效率不高,例如一次操作千台服务器
3.我们用ssh链接过去,执行任务过程中,链接断了,进程就消失了
有agent是,在每个节点上运行服务,把任务派给它就不管了,运行完后把消息发回来
之前redis-server --port可以指定端口
现在6400端口就起来了
pstree查看一下,redis有两个实例,父进程试init,所以真正变成了一个后台的服务,因为配置文件里有daemonize,所以ansible会话断了,服务还在
如果某个服务类似这个pstree在sshd下,sshd断开,这个服务就挂掉了
有些服务,如果运行的话,实际试在当前会话下运行的,会话下的进程,如果这个会话断掉,进程也就消亡了,但是守护进程例外,这就是为什么要起服务,启动之后session断开,它是守护进程是不会关掉的
这次试试自己写一个agent,使用python比较高级的库subprocess,windows和linux不一样,linux是fork一个子进程,windows是真正创建一个子进程,因为windows进程间平等没有什么父子关系
这个模块是一个 高级的库
这里就是命令和参数送进去,最后还返回结果,这个是命令状态返回值,0都是ok的,非0都是错的
提供了popen的这样一个类,来运行跑的程序
输入的东西,按照空格结合起来,结合起来就是一个列表,然后将这个列表直接交给popen
试试popen,一般做底层开发都要启动进程,做web就很少
这里写了shell默认false,现在要等于true
返回了一个popen,也就是进程
进程对象有了,就想要他跑起来,wait,是默认一直等
红色代表stderr,现在操作系统里,0都是正常,非0都是不正常
现在数据就回来了
打印下code,没有数据
这里有例子,这里是把stdout修改下,修改到pipe里去了
这里就不到我们控制台标准输出了
类文件对象都是这么操作的
看一下用encode为什么错
因为windows命令行走的是gbk
这样就可以了
现在故意模拟执行命令错误,这个内容跑到控制台了,因为stderr没管
加一个stderr,这样就拿到了
在真正执行一个任务的时候 不会让它一直等,有错误产生,这个命令不会很快执行完,但是我们真正做调度的时候,要把不合格卡掉,一个是你master主动kill掉,还有就是设定一个合理的超时时间,任务多长时间跑完需要说清楚
现在是不等5秒
等5秒抛出异常
ls是没有等5秒
现在这个错是wait抛出来的
shell出的问题是通过stderr状态码返回的
pause是windows下暂停,linux下是sleep 5等5秒就可以了
现在用windows的
现在是有一个master的,这个maste通过网络传输将脚本,送给agent,agent拿到script就可以在shell里执行,往下执行有可能超时
超时以后可以想办法返回一个,return一个,给master,现在代码日志好了,agent可以执行代码并且返回值和产生的信息返回。
脚本执行返回标准输出,其实就是字符串,用正则来处理就行。数据下发到agent,agent处理后,将结果想办法返回来,这两个之间用rpc来解决
在agent包里写一个执行器,是真正要下发到agent,由agent来帮我们完成
写这样一个executor类
这个类是替我们运行程序的
不用split这个列表也可以,也可以用字符串,列表是把参数和命令分开了
现在送进来一个脚本去运行,在前面把timeout参数加一下,最大容忍你跑完的命令的时间,超时,返回一个失败
PIPE提示有点问题
当你用标准错误输出,标注输出的时候,将要deadlock,死锁,有时候输出太大,导致block,pipe风险太大,容易deadlock,就去换掉
我们可以将所有输出给一个文件,pipe有风险,我们需要临时用一个文件名,我们用文件系统比较合适bytesio和stringio毕竟占内存
大部分会有放垃圾的地方,window 有tmp,linux也有tmp,什么时候创建临时文件,在解压缩的时候,尤其生成的文件不是在现场做,有些中间生成的文件是在临时目录里做的,一些缓冲文件也是放到临时目录里去的
所以这里我们用临时文件
这个就是临时文件创建方式
这个应该返回一个文件对象
seek指针复位,重读就拿到了
修改下executor
还需要导入写的getlogger,__name__模块名,日志文件地址,logger做好了
现在要读取,这是一个函数返回code和txt
这样就可以把现在的函数返回了
来试试使用
运行一下
日志里告诉是个none对象
现在成功了,但是没东西
要设置一下指针,否则跑到后面去了,就读不到
这里的编码可以根据当前操作系统动态生成,来确定这里用什么。
这里无非就是用网络的方式把脚本传进来,执行完之后得到相应的结果,最后把结果返回回来