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