文章目录
背景
博主所在的部门比较奇特,每个车型每周都需要发版,所以实际上一周会发布好几个版本。经过之前使用流水线自动发版改造之后,发版的成本已经大大降低了,具体参考: 利用流水线实现版本一键发布。
但是由于发版的时间不固定,且忙起来之后容易忘记,所以现状就是每周由 pm 制定好了发版计划,然后到时间了之后由测试同学在群里@开发同学进行发版。
有没有什么方法可以每周设定好了发版时间,然后到时间之后自动触发发版流程,并在群里通知呢?我想到了飞书的多维表格。飞书的多维表格有自动化的能力,我们每周只需要设定好版本发布的时间,可以让其自动触发版本发布,并在群里通知所有人。
想象比较美好,但现实是公司的内网和飞书并不在同一个网络,因此飞书的自动化流程没办法触发到内网的流水线,为此我做了一些尝试。
尝试1,轮询
我们在飞书表格当中设定好发版车型,版本号,时间等一系列参数之后,可以在内网的服务器开启一个轮询,不断的从飞书表格当中获取这些值,到了设定好的时间之后,就在内网触发流水线进行版本发布。
但是有个问题,我们一周最多可能发布四个版本,如何设定轮询的时间间隔呢?
假定我们每天获取一次,也就是时间间隔控制在一天,那么就会出现信息获取不及时的现象,例如今天早上获取了发版信息,下午要发布一个版本,但是如果中午修改了发版计划,取消了下午发版,此时就没办法即时通知到内网,导致下午还会触发版本发布。
那么假定我们每隔10分钟获取一次,除非在发版前10分钟内修改发版计划,否则都能感知到版本计划的变更,出现上述问题的概率就大大降低,但是一直轮询,大量的网络请求其实都是无效的,而且也没有利用到飞书的自动化能力。
因此这个方法并不好。
尝试2,长连接
如果轮询不可以,那么我们是否能够在外网和内网当中建立一个长连接,利用飞书的自动化能力,当到达设定的时间时,可以通过长连接将相应的发版信息推送到内网当中,这样不就实现自动发版了么?
说干就干,在腾讯云上买了一台云服务器,最便宜的(一年才90几块钱),不过配置也够用了。
接着在云上部署了两个服务,一个是 http 服务,用于让飞书表格触发,一个是 websocket 服务,用于和内网保持长连接,具体如下:
http 服务
部署在云端,这里使用的是 python 的 Flask 框架
python
@app.route("/trigger", methods=['POST'])
def triggerEvent():
try:
data = json.dumps(dict(request.form))
print(f"received msg:{data}")
logging.info(f"received trigger msg:{data}")
executor.submit(WebsocketService.sendMsg,data)
return "OK"
except Exception as ex:
return f"error,{ex}"
def start():
print("service start")
app.run(host='0.0.0.0',port=8888)
websocket 服务
部署在云端,这里主要的逻辑就是,当有 websocket 客户端连接上之后就将其保存在 set 集合里面,一旦 http 服务收到消息,就会通过 set 集合里面的 websocket 客户端将消息转发出去。
python
clients = set()
async def __handleClient(websocket):
print(f"new connection from {websocket.remote_address}")
try:
while True:
clients.add(websocket)
message = await websocket.recv()
print(f"received message:{message}")
except Exception as ex:
print(f"exception :{ex}")
clients.remove(websocket)
async def __sendMsgToClient(msg):
for client in clients:
try:
logging.info(f"websocket send:{msg}")
await client.send(msg)
except Exception as ex:
print("send msg failed")
logging.info(f"websocket send failed:{ex}")
def sendMsg(msg):
asyncio.run(__sendMsgToClient(msg))
async def __start():
server = await websockets.serve(__handleClient,'0.0.0.0',8889)
await server.wait_closed()
def start():
print("websocket service start")
asyncio.run(__start())
websocket 客户端
部署在内网,这里开启了一个死循环,一直监听服务端发送的消息,然后根据消息再做响应事件。
python
async def __webscoketClient():
uri = "ws://xxx:8889"
while True:
try:
async with websockets.connect(uri) as websocket:
await websocket.send("hello,server!")
while True:
msg = await websocket.recv()
logging.info(f"received message from server:{msg}")
__handleSocketMsg(msg)
except Exception as ex:
logging.info(f"connect exception :{ex}")
print(f"reconnecting in 10 seconds")
await asyncio.sleep(10)
飞书多维表格配置
表格当中我们可以将需要的参数都写进去,我们需要关注的是 publisTime 版本发布时间,我们需要根据时间来进行自动触发。
进入自动化的编辑页面,可以设定当到达记录中的时间时,往我们刚刚在腾讯云上搭建的服务器发送消息,这样就可以通过长连接将消息发送到内网,从而实现自动发布版本的能力。
另外,需要注意的是,在腾讯云中需要在防火墙页面把相应的端口打开,不然访问会被拒绝。