运维久了, 就会写很多脚本, 接触很多工具, 但是太散了. 还有兼容性等, 考虑很多的.
所以我就自己写了个工具 来 整合自己常用的脚本和功能.
项目介绍(需求背景)
项目地址: https://github.com/ddcw/ei 项目包: https://github.com/ddcw/ei/releases/download/ddcw-ei/ddcw-ei-V0.1-20211215.tar.gz
功能介绍:
支持主机实例和数据库实例查看.
(因为本人从事数据库运维工作, 接触得多的就是数据库和操作系统, 经常要看各种数据, 每次登录都很麻烦, 所以才有了这个项目.)
工具栏: 就是自己可能用到的功能, 整合在一起, 在分个类, 用的时候就控制台点一下就行, 很方便.
部署安装: 安装软件跑脚本很方便, 但是还有登录上去,传包之类的很麻烦. 就来了这么个功能. 安装肯定是放后台跑, 所以会有任务列表这种东西.
本文主要是分享怎么实现的. 功能就不仔细介绍了.
项目布局:
略(这不是本文的重点)
用到的技术
前端:
bootstrap5 作为前端界面主要展示布局. 写这个项目的时候bootstrap5出来了, 就用的最新的版本.
jquery-3.1.1 本来没打算用jq的, 但是有部分代码是大学的时候用jq写的, 就整过来了, 主要还是JS实现动态效果.
echart 实现图展示
echarts-liquidfill 动态球展示, CPU内存之类的用个球展示会比较好看一点.
qrcodejs 生成qr二维码, 和本项目关系不大, 觉得可能有用, 就加上了
socketio 实现socket, 有的功能需要实时展示(比如安装过程), socekt就很有必要了
后端:
flask 主要框架.
configparser 读取配置文件参数的
paramiko 远程ssh执行脚本, 拷贝软件包的时候用的.
flask_sockets 实现socket
logging 记录日志
sqlite3 账号信息,数据信息使用sqlite3来保存, 简单点.
pymysql 连接mysql的
cx_Oracle 连接oracle的 #pg和redis和Mongodb的后续也会加上.
flask_apscheduler 任务调度的, 比如定时检查主机实例,数据库实例是否正常
数据库:
sqlite3 这是py内置的库, 本项目并不会有大量的访问, 只要求简单方便, 所以就选了sqlite.
脚本:
主要是shell python其次.
考虑到要兼容很多操作系统, 所以脚本的函数就不加关键字 func/function 布尔判断也不用 [[ 了, 就用单[
不设置tty了, 因为都是远程调用paramiko执行.
注: 为了尽可能的简单方便实用, 就没有用uwsgi gunicorn之类的了, 启动停止都用shell脚本控制.
实现方式参考:
仅供参考.
定时检查实例状态
实用的scheduler.task, 设置的是每隔20秒检查一次数据库实例状态. 如果是用db.session.execute进行实例状态写入数据库的话, 很容易就产生lock. 而且用db.session.commit()提交的话, 还会有 "数据库未打开" 这种报错.
解决办法: 每个定时任务单独实用sqlite3.connect连接. 每次连接完了, 断开就行. 因为使用量不大.sqlite就能抗住了. 整体也很流畅了.
后台执行安装脚本 和 前端实时交互
主要在于 前端请求 "开始安装" 之后, 前端可能会断开. 所以就得使用后台进程了. 比如使用socketio.start_background_task 开启线程去使用paramiko远程连接目标服务器执行脚本. 需要实时返回数据. 这个不难.死循环判断 ssh.exit_status_ready就行, 接受到数据之后就直接通过socket返回前端和写入日志.
但是在循环里面使用 socketio.emit 的话, 并不会马上就返回数据, 而是会等循环完了再返回(也可能是缓存到一定量了再返回), 要实时返回的话, 可以在循环里面加个 socketio.sleep(0.5) 这样就会实时返回了.
@socketio.on 绑定事件
有时候装饰器不起作用, 这时就可以用 socketio.on_event(event_name, function_name,namespace="")来代替了.
删除任务 实时展示
这个其实是最常用的, 实现方式也很多.
本项目的实现方式为: onclick --> function emit(msg) --> 服务端删除任务,并emit(ok), --> 浏览器收到后, 把对应的id 的display设置为None就行.
浏览器发送删除的时候, 也携带了本地(浏览器)监听的事件, 服务器返回的消息就是发给这个事件的. 浏览器的这个事件收到消息后, 设置display 然后弹窗显示成功. 弹窗使用的只是alert, 觉得不好看, 也可以用模态框.
其它的暂时没想到, 以后再说吧. 毕竟这个项目还没把所有功能都实现.
项目展示:
说了这么多, 展示下效果吧. 代码就不放了, 去github上就能看到.