测试平台系列(85) 把redis运用到实战中
大家好~我是
米洛!
我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持。
欢迎关注我的公众号测试开发坑货,获取最新文章教程!
回顾
上一节我们让支持了前置条件复制功能。这一节本来打算给大家讲讲邮件的发送。
但在此之前,我想了一个很严重的问题。
配置
我们的测试平台,后续会接入yapi,接入其他系统。势必会有一个地方去维护这些数据。
包括发件人邮箱,密码等等数据。
但这些数据又通常是全局共享,如果放到db的话,很鸡肋,因为数据只有1条,如果放到redis,有可能数据会丢。
博主也不知道放哪里比较好,最后决定放到一个configuration.json的配置文件里面了。
但是频繁读取文件,总归是不好的。而且我们线上会有许多个worker,还可能会有冲突。
想到我们之前拿捏过的redis,这不正是它的用武之地吗?
编写通用cache方法
在此之前,我们先思考一下为啥要写这样的通用缓存办法:
我们获取数据,有2部分,分别为get和set。结合缓存来看,我们可以写出这样的伪代码:
def get_cache():
data = redis.get(key)
if data is not None:
return data
data = get_data()
redis.set(key, data)
return data
就是这么简单的用法,如果key获取到了,我们直接return,如果没获取到,我们更新数据,并把数据写入redis,最后返回data。
那我们修改数据的时候怎么做呢?
def update_cache():
update(data)
redis.delete(key)
- 先更新数据源
- 删除缓存数据,这样下去获取缓存的时候就会
重新获取数据并写入缓存
但大家有没有觉得这个过程很繁琐,而且属于get和set之外的操作,每每有这种操作的时候,我们就可以把它装饰器化。
编写cache装饰器
连接本地redis的方法
首先我们在config.py配置好redis的连接信息,接着编写client客户端,因为它本身是连接池模式,所以我们一直用这个
客户端都没问题。(所以我这里把它设置为了property)

编写RedisHelper
helper类含有2个装饰器,cache负责读取(get),up_cache负责更新(set)。
class RedisHelper(object):
pity_prefix = "pity"
pity_redis_client = PityRedisManager().client
@staticmethod
def get_key(key: str):
return f"{RedisHelper.pity_prefix}:{key}"
@staticmethod
def cache(key: str, expired_time=3 * 60):
"""
自动缓存装饰器
:param key: 被缓存的key
:param expired_time: 默认key过期时间
:return:
"""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
redis_key = RedisHelper.get_key(key)
data = RedisHelper.pity_redis_client.get(redis_key)
# 缓存已存在
if data is not None:
return json.loads(data)
# 获取最新数据
new_data = func(*args, **kwargs)
info = json.dumps(new_data)
RedisHelper.pity_redis_client.set(redis_key, info, ex=expired_time)
return new_data
return wrapper
return decorator
@staticmethod
def up_cache(key: str):
"""
redis缓存key,套了此方法,会自动执行更新数据操作后删除缓存
:param key:
:return:
"""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
redis_key = RedisHelper.get_key(key)
# 获取最新数据
new_data = func(*args, **kwargs)
# 更新数据,删除缓存
RedisHelper.pity_redis_client.delete(redis_key)
return new_data
return wrapper
return decorator
这里我们基本上按照之前说的逻辑来做的,以后我们取数据的方法,只需要在方法前面+上cache装饰器,即可自动跟redis打通。(有缓存则取缓存数据,无则取真实数据)
编写配置文件获取方法
我们编写configuration.json到根目录:

import json
import os
from app.middleware.RedisManager import RedisHelper
from config import Config
class SystemConfiguration(object):
"""
系统配置
"""
@staticmethod
@RedisHelper.cache("configuration", 24 * 3600)
def get_config():
try:
filepath = os.path.join(Config.ROOT, "configuration.json")
if not os.path.exists(filepath):
raise Exception("没找到配置文件,请检查configuration文件是否已经被删除")
with open(filepath, mode="r", encoding='utf-8') as f:
return json.load(f)
except Exception as e:
raise Exception(f"获取系统设置失败, {e}")
@staticmethod
@RedisHelper.up_cache("configuration")
def update_config(config):
try:
filepath = os.path.join(Config.ROOT, "configuration.json")
if not os.path.exists(filepath):
raise Exception("没找到配置文件,请检查configuration文件是否已经被删除")
with open(filepath, mode="r", encoding='utf-8') as f:
json.dump(config, f)
except Exception as e:
raise Exception(f"更新系统设置失败, {e}")
由于配置文件一般很少更新,所以我们把key的过期时间设为了1天(其实可以更久一点)。
这样,我们调用get_config就可以拿到系统设置啦,里面有咱们很重要的发件人信息。
测试一下
启动程序以后,我们去查询redis中关于configuration的key,就用咱们自己写的客户端:

再测试下过期时间:

今天的内容就到这里,下节正式开启发邮件(报告通知)之旅。
测试平台系列(85) 把redis运用到实战中的更多相关文章
- 测试平台系列(79) 编写Redis配置功能(下)
大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们提出了优化Dao ...
- 测试平台系列(80) 封装Redis客户端
大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们编写了Redis ...
- 测试平台系列(81) 编写在线执行Redis功能
大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们牛刀小试,编写了 ...
- 测试平台系列(83) 前置条件支持Redis语句
大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上节我们打了个野,解决了一 ...
- 测试平台系列(72) 了解ApScheduler基本用法
大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们调研了一下市面上 ...
- 测试平台系列(82) 解决APScheduler重复执行的问题
大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们编写了在线执行R ...
- 测试平台系列(95) 前置条件支持简单的python脚本
大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的教程,希望大家多多支持. 欢迎关注我的公众号米洛的测开日记,获取最新文章教程! 回顾 上一节我们构思了一下怎么去支 ...
- 测试平台系列(55) 引入AceEditor(代码编辑器)
大家好,我是米洛,求三连!求关注测试开发坑货! 回顾 我们上一节已经写好了左侧数据表目录,今天继续完成sql编辑器的部分. 调研组件 monaco 因为我们的项目用的是React,市面上很多编辑器都是 ...
- 测试平台系列(71) Python定时任务方案
大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 定时任务 定时任务,顾名思义: ...
随机推荐
- Java:并发笔记-03
Java:并发笔记-03 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 3. 共享模型之管程-2 本章内容-2 Monitor wait/notify 3.6 ...
- spring cloud config 结合 spring cloud bus实现配置自定的刷新
在线上环境中,有时候我们希望系统中的某些配置参数在修改后,可以立即生效而不用重新启动服务.由上一节我们知道,我们可以把配置文件统一放到配置服务中进行管理,这一节我们在配置中心中整合spring clo ...
- 启动Dubbo项目注册Zookeeper时提示zookeeper not connected异常原理解析
文/朱季谦 遇到一个很诡异的问题,我在启动多个配置相同zookeeper的Dubbo项目时,其他项目都是正常启动,唯独有一个项目在启动过程中,Dubbo注册zookeeper协议时,竟然出现了这样的异 ...
- MOSFET管驱动电路的设计
https://wenku.baidu.com/view/ae727da5caaedd3382c4d3b9.html?mark_pay_doc=2&mark_rec_page=1&ma ...
- 有关fgetc配合feof逐行读取文件最后一行读取两遍的错觉?
最近在做一个wifiap设置的接口,用户首先获取到当前wifi 热点的ssid 和pwd,然后修改,保存. 获取信息的时候是fopen对应的hostapd.conf文件,逐行读取,查找匹配的参数. 修 ...
- Python ImportError: No module named '_tkinter', please install the python3-tk package
ImportError: No module named '_tkinter', please install the python3-tk package 这个问题的原因是使用的python3环境内 ...
- ICPC Mid-Central USA Region 2019 题解
队友牛逼!带我超神!蒟蒻的我还是一点一点的整理题吧... Dragon Ball I 这个题算是比较裸的题目吧....学过图论的大概都知道应该怎么做.题目要求找到七个龙珠的最小距离.很明显就是7个龙珠 ...
- 【Azure 存储服务】如何把开启NFS 3.0协议的Azure Blob挂载在Linux VM中呢?(NFS: Network File System 网络文件系统)
问题描述 如何把开启NFS协议的Azure Blob挂载到Linux虚拟机中呢? [答案]:可以使用 NFS 3.0 协议从基于 Linux 的 Azure 虚拟机 (VM) 或在本地运行的 Linu ...
- harbor安装高可用
harbor架构 下载地址https://github.com/goharbor/harbor/ 高可用架构 解压压缩包 tar -xvf harbor-offline-installer-v1.10 ...
- 【java+selenium3】自动化基础小结+selenium原理揭秘 (十七)
一.自动化实现原理 1.创建驱动对象 (1) 首先加载浏览器安装目录下的exe文件 (2) 其次是加载可执行驱动的exe文件,监听等待客户端发送的web service请求. 底层原理如下: 1. ...