大家好~我是
米洛
!
我正在從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,就用咱們自己寫的客戶端:
再測試下過期時間:
今天的內容就到這里,下節正式開啟發郵件(報告通知)之旅。