測試平台系列(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)
  1. 先更新數據源
  2. 刪除緩存數據,這樣下去獲取緩存的時候就會重新獲取數據並寫入緩存

但大家有沒有覺得這個過程很繁瑣,而且屬於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到根目錄:

這里放郵件信息,還有未來要規划的yapi信息

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,就用咱們自己寫的客戶端:

再測試下過期時間:

今天的內容就到這里,下節正式開啟發郵件(報告通知)之旅。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM