测试平台系列(80) 封装Redis客户端

大家好~我是米洛

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

欢迎关注我的龚仲耗测试开发坑货,获取最新文章教程!

回顾

上一节我们编写了Redis的相关配置编辑页面,博主这里也趁热打铁,把前端页面完善了。(可能会有一点点小问题,但应该主流程都正常)

其实和其他配置管理页面差不多,前端优化了一下面包屑,顶部的菜单也放回到左侧了。看看mac下的效果:

这里我给自己本地部署了个单实例的redis

搜索选项改动了一些,所见即所得,如果搜索项发生变化,那么内容也会随之切换

关于Redis客户端的选用

其实在这个问题上我是比较纠结的,redis有star很多的py客户端,也有与之对应的集群版本。但他们并不支持asyncio

而支持asyncio的aioredis,本身是个很好的选择,但人家没有支持redis集群的计划。orz

所以今天想的是要不就用个同步的redis-cluster-py库算了,不过在我翻了github一段时间,发现了个叫aredis的异步库。大概瞅了下,他基本上是保持了和redis-cluster-py接近的api,可能也是为了吸引用户

所以咱们就先试验一下,小白鼠嘛,总得有人来做。

安装aredis

看官网是要安装aredis[hiredis],但我好像不适合这样方式,于是我分开装:

pip3 install aredis hiredis

编写RedisManager

其实这里还是和MySQL比较接近的,也是通过一个字典存放各个redis的连接配置。

不过由于Redis的集群和单实例还有一点区别(好在我们编写配置的时候就准备好了),所以我们最好是针对单实例和集群分别编写2个map存放他们的client,当然1个也是ok的。

整体流程: 从字典获取客户端,如果没有则新开一个客户端,并放入缓存,有则返回。

  • 可能存在的问题

    代码不是线程安全的,需要观察是否需要加锁

    缓存不像LRU会降频,也不能自动过期

    对我来说第一个肯定是个大问题,如果出现了就必须得解决。至于第二个问题,由于redis配置很少变动,而且我们本身是连接池的形式,所以影响不算大。

    话不多说,现在我们就来编写吧:

"""
redis客户端,基于aredis(支持集群,aioredis不支持集群)
"""
from aredis import StrictRedisCluster, ClusterConnectionPool, ConnectionPool, StrictRedis

from app.excpetions.RedisException import RedisException


class PityRedisManager(object):
    """非线程安全,可能存在问题
    """
    _cluster_pool = dict()
    _pool = dict()

    @staticmethod
    def get_cluster_client(redis_id: int, addr: str):
        """
        获取redis集群客户端
        :param redis_id:
        :param addr:
        :return:
        """
        cluster = PityRedisManager._cluster_pool.get(redis_id)
        if cluster is not None:
            return cluster
        client = PityRedisManager.get_cluster(addr)
        PityRedisManager._cluster_pool[redis_id] = client
        return client

    @staticmethod
    def get_single_node_client(redis_id: int, addr: str, password: str, db: str):
        """
        获取redis单实例客户端
        :param redis_id:
        :param addr:
        :param password:
        :param db:
        :return:
        """
        node = PityRedisManager._cluster_pool.get(redis_id)
        if node is not None:
            return node
        host, port = addr.split(":")
        pool = ConnectionPool(host=host, port=port, db=db, max_connections=100, password=password,
                              decode_responses=True)
        client = StrictRedis(connection_pool=pool)
        PityRedisManager._pool[redis_id] = PityRedisManager.get_cluster(addr)
        return client

    @staticmethod
    def refresh_redis_client(redis_id: int, addr: str, password: str, db: str):
        """
        刷新redis客户端
        :param redis_id:
        :param addr:
        :param password:
        :param db:
        :return:
        """
        host, port = addr.split(":")
        pool = ConnectionPool(host=host, port=port, db=db, max_connections=100, password=password,
                              decode_responses=True)
        client = StrictRedis(connection_pool=pool, decode_responses=True)
        PityRedisManager._pool[redis_id] = client

    @staticmethod
    def refresh_redis_cluster(redis_id: int, addr: str):
        PityRedisManager._cluster_pool[redis_id] = PityRedisManager.get_cluster(addr)

    @staticmethod
    def get_cluster(addr: str):
        """
        获取集群连接池
        :param addr:
        :return:
        """
        try:
            nodes = addr.split(',')
            startup_nodes = [{"host": n.split(":")[0], "port": n.split(":")[1]} for n in nodes]
            pool = ClusterConnectionPool(startup_nodes=startup_nodes, max_connections=100, decode_responses=True)
            client = StrictRedisCluster(connection_pool=pool, decode_responses=True)
            return client
        except Exception as e:
            raise RedisException(f"获取Redis连接失败, {e}")

我们以数据库的唯一id为key,缓存redis的连接池

由于连接池会自动开启/关闭连接,所以我们不需要手动关闭客户端,非常方便。

仔细看看redis执行command的方法,里面会开辟连接,最终关闭连接,这就是连接池的好处,连接不会过期,因为每次都是新获取的

可以明显看到我们分别用了ClusterConnectionPool和ConnectionPool,分别对应集群和实例。参数基本上算是一致。

至于refresh,是给改动redis以后做的刷新连接的工作。

以上就是RedisManager的内容,到这只是能够获取Redis客户端了。

尝试一下

有条件的同学可以本次安装redis:

$ wget https://download.redis.io/releases/redis-6.2.6.tar.gz
$ tar xzf redis-6.2.6.tar.gz
$ cd redis-6.2.6
$ make

make了以后,修改redis-6.2.6目录下的redis.conf, 接着取消这一行的注释:

image

使用密码模式(redis最好是加密码,端口号也尽量不要用原生的6379,本宝宝有台机器被人通过redis植入了挖矿程序,苦不堪言

  • 在redis-6.2.6目录下启动
src/redis-server redis.conf

这样本地redis的实例就启动了~

image

编写个在线测试redis的接口

image
  • 先通过id拿到redis的配置信息

  • 然后通过manager拿到连接池

  • 对redis发动命令

    我们在http://localhost:7777/docs打开swagger调试:

  • 读取faker

image
  • 设置faker为s12
image
  • 再次取faker
image

可以看到redis的相关操作已经是可以用了,那我们今天的内容就到这了,愉快的周末总是辣么短暂

下一节我们就得编写在线执行Redis的命令及相关页面了!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,104评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,816评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,697评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,836评论 1 298
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,851评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,441评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,992评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,899评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,457评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,529评论 3 341
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,664评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,346评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,025评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,511评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,611评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,081评论 3 377
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,675评论 2 359

推荐阅读更多精彩内容