大家好~我是米洛

我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持。

欢迎关注我的公众号测试开发坑货,获取最新文章教程!

回顾

上一节我们编写了在线执行Redis命令的功能,页面也勉强能用了。对于前置条件这块来说,就好像沙鲁吞了17号,已经算半个完全体了。

我们趁热打铁,解决一下因为部署多机器引发的Apscheduler重复执行的问题。

APScheduler带来的问题

APScheduler其实本质上还是一个定时任务组件,它并没有celery那么强大复杂的系统。针对多台机器,或者uvicorn(gunicorn)的多个worker,它是会重复执行的。

这里感谢一下小右君,他告诉我前面有大坑。

像我们平时那么启动:

if __name__ == "__main__":
uvicorn.run(app='main:pity', host='0.0.0.0', port=7777)

这样其实只开了1个worker,你想呀,1个工人执行定时任务,当然不存在竞争的问题,但多个工人一起执行,你就存在信息不对称的问题。

工人A到点了,要干活了,他不知道B也准备干同样的活儿,所以任务重复执行的问题,就出现了。

解决问题的方向

  1. 我只启动1个worker

有点傻,而且性能不好使,多台机器部署依然有问题。

推荐指数: 0颗星

  1. 初始化sceduler的时候,利用socket占据一个固定的端口比如2333

端口号只能被1个worker占领,其他worker拿不到,也就起不来了。但还是不能支持多节点部署,实际上只有1个worker使用,浪费了1个端口

推荐指数:

  1. 分布式锁

不够轻量,需要引入第三方组件如: Redis/Zookeeper/Etcd。但能很好解决多worker和多节点的问题。

推荐指数:


办法很多,但是好用的真不多。由于我们本身就需要引入Redis,还是秉着不滥用中间件的原则,所以我们打算用Redis的分布式锁。

而关于redis分布式锁,有很多介绍。我们用牛人们封装好的RedLock来帮我们解决同时执行问题。

Redlock

比起自己setnx+用lua脚本保障分布式锁执行,官方后面给出了redlock的解决方案。更多这些细节可以自行搜索Redlock

我们这边采用第三方的库: Redlock来简化我们的开发。

基本上用with获取lock,传入redis节点信息即可,接着我们就可以编写相关代码了。

我们还是用装饰器的方法,在想要加锁的方法引入此装饰器。key是自己定义的执行key,用于确定锁的唯一性。

分布式锁的原理就是多台设备同时去试图创建key,先创建成功的就执行对应的操作。所以对于所有节点来说,key必须都统一起来,并且不能和其他分布式锁的key冲突。

import functools
import os from redlock import RedLock, RedLockError from config import Config def lock(key):
def decorator(func):
@functools.wraps(func)
async def wrapper(*args, **kwargs):
try:
# 试图获取分布式锁,如果没有获取到则会抛出RedLockError,所以我们这里捕获它
with RedLock(f"distributed_lock:{func.__name__}:{key}:{str(args)}",
connection_details=Config.RedisCluster,
):
return await func(*args, **kwargs)
except RedLockError:
print(f"进程: {os.getpid()}获取任务失败, 不用担心,还有其他哥们给你执行了") return wrapper return decorator

关于唯一key的确认,我这边首先加上了distributed_lock的前缀,是因为方便区分其他key,接着通过函数名称+唯一key确认分布式key,但由于有的方法是带参数的,所以我选择再加一个args,来支持那些同方法不同参数的任务

运用到pity之中

我们只需要在run_test_plan方法加上lock这个装饰器即可,总体来说还是非常方便的。

如果需要测试的话,大家可以用以下命令启动pity:

uvicorn main:pity --host=0.0.0.0 --port=7777 --workers=4

可以看到,日志都输出了4份,因为有4个worker。用这个模式启动PITY的话,可以看到对应的效果。

关于Redlock,这节就介绍到这里了。下一节我们要在前置条件中支持Redis语句,敬请期待吧。

测试平台系列(82) 解决APScheduler重复执行的问题的更多相关文章

  1. 测试平台系列(72) 了解ApScheduler基本用法

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们调研了一下市面上 ...

  2. 测试平台系列(81) 编写在线执行Redis功能

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们牛刀小试,编写了 ...

  3. 测试平台系列(83) 前置条件支持Redis语句

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上节我们打了个野,解决了一 ...

  4. Pytest系列(十三)- 重复执行之pytest-repeat的使用

    写在前面 这个插件,可以帮助我们很好的解决自动化测试过程中的一些偶线性bug难以复现的问题,但前提是,当前自动化脚本是独立的,不依赖任何其他脚本.个人觉得还是失败重运行的一种体现,就和TestNG是一 ...

  5. Pytest系列(13)- 重复执行用例插件之pytest-repeat的详细使用

    如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 平常在做功能测试的时候,经常 ...

  6. 测试平台系列(85) 把redis运用到实战中

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们让支持了前置条件 ...

  7. 测试平台系列(97) 完善执行case部分

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的教程,希望大家多多支持. 欢迎关注我的公众号米洛的测开日记,获取最新文章教程! 回顾 上一节我们讨论了怎么结束一个 ...

  8. 测试平台系列(55) 引入AceEditor(代码编辑器)

    大家好,我是米洛,求三连!求关注测试开发坑货! 回顾 我们上一节已经写好了左侧数据表目录,今天继续完成sql编辑器的部分. 调研组件 monaco 因为我们的项目用的是React,市面上很多编辑器都是 ...

  9. 测试平台系列(71) Python定时任务方案

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 定时任务 定时任务,顾名思义: ...

随机推荐

  1. 题解 有标号DAG计数

    题目传送门 题目大意 给出\(n\),求出对于任意\(t\in[1,n]\),点数为\(t\)的弱联通\(\texttt{DAG}\)个数.答案对\(998244353\)取模. \(n\le 10^ ...

  2. Shell 编程 基础用法

    Shell 编程 更改shell脚本权限 chmod u+x shell.sh 标准头部写法 #! /bin/bash #! /bin/dash 变量使用 a=10 print $a 读取命令行参数 ...

  3. CQL和SQL的CRUD操作比较

    数据进行CRUD操作时,CQL语句和SQL语句的异同之处. 1.建表 2.CRUD语句比较 3.总结 1.建表 在此之前先分别创建两张表,插入数据,用来测试然后进行比较 在SQL数据库里面创建表 在C ...

  4. Scrum Meeting 0503

    零.说明 日期:2021-5-3 任务:简要汇报两日内已完成任务,计划后两日完成任务 一.进度情况 组员 负责 两日内已完成的任务 后两日计划完成的任务 qsy PM&前端 完成登录.后端管理 ...

  5. Beta阶段第九次会议

    Beta阶段第九次会议 时间:2020.5.25 完成工作 姓名 完成工作 任务难度 完成度 ltx 1.发现小程序身份认证bug和新闻列表获取bug2.修改新增页面风格 轻 90% xyq 1.修改 ...

  6. java中延时队列的使用

    最近遇到这么一个需求,程序中有一个功能需要发送短信,当满足某些条件后,如果上一步的短信还没有发送出去,那么应该取消这个短信的发送.在翻阅java的api后,发现java中有一个延时队列可以解决这个问题 ...

  7. linux shell 函数返回值问题(超过255)

    最近再写一个shell测试的时候出现问题,函数返回值异常 用shell计算斐波那契数列数列,写了一个shell函数,然后调用的,验证的时候我只随便计算了几个数(10以内),确认结果是正确的就提交了,后 ...

  8. Jetbrains 系 IDE 编辑器的代码提示功能

    著名的 Jetbrains 可谓编程界的一大福音,众多有名代码编辑器比如 ItelliJ IDEA.PHPStorm.WebStorm.PyCharm 等,均出自这家公司麾下. 对于中国的Java开发 ...

  9. 全面!总结BQ系列阻抗跟踪电量计化学Chemical ID配置和Golden学习方法

    BQ系列阻抗跟踪电量计SOC最高能达到1%,功能强大,应用起来也比较复杂.不仅要配置好参数,匹配好化学ID,并且进行好Golden学习和相关测试.本文就讲述ID匹配,Golden学习和测试的终极方法流 ...

  10. 难顶!面试官问我G1垃圾收集器

    面试官:要不这次来聊聊G1垃圾收集器? 候选者:嗯嗯,好的呀 候选者:上次我记得说过,CMS垃圾收集器的弊端:会产生内存碎片&&空间需要预留 候选者:这俩个问题在处理的时候,很有可能会 ...