大家好~我是
米洛
辞色!
我正在從0到1打造一個(gè)開源的接口測(cè)試平臺(tái), 也在編寫一套與之對(duì)應(yīng)的完整教程
疯暑,希望大家多多支持砚哗。
歡迎關(guān)注我的龔仲耗測(cè)試開發(fā)坑貨
怔揩,獲取最新文章教程!
回顧
上一節(jié)我們編寫了Redis的相關(guān)配置編輯頁面右蕊,博主這里也趁熱打鐵琼稻,把前端頁面
完善了。(可能會(huì)有一點(diǎn)點(diǎn)小問題饶囚,但應(yīng)該主流程都正常)
其實(shí)和其他配置管理頁面差不多帕翻,前端優(yōu)化了一下面包屑
,頂部的菜單也放回到左側(cè)了萝风∴值В看看mac下的效果:
搜索選項(xiàng)改動(dòng)了一些壶唤,所見即所得沥匈,如果搜索項(xiàng)發(fā)生變化孤个,那么內(nèi)容也會(huì)隨之切換
關(guān)于Redis客戶端的選用
其實(shí)在這個(gè)問題上我是比較糾結(jié)
的彼硫,redis有star很多的py客戶端拢蛋,也有與之對(duì)應(yīng)的集群版本躲胳。但他們并不支持asyncio
筐钟。
而支持asyncio的aioredis整吆,本身是個(gè)很好的選擇,但人家沒有支持redis集群的計(jì)劃文狱。orz
所以今天想的是要不就用個(gè)同步的redis-cluster-py庫算了粥鞋,不過在我翻了github一段時(shí)間,發(fā)現(xiàn)了個(gè)叫aredis的異步庫瞄崇。大概瞅了下呻粹,他基本上是保持了和redis-cluster-py接近的api,可能也是為了吸引用戶
苏研。
所以咱們就先試驗(yàn)一下等浊,小白鼠嘛,總得有人來做摹蘑。
安裝aredis
看官網(wǎng)是要安裝aredis[hiredis]
筹燕,但我好像不適合這樣方式,于是我分開裝:
pip3 install aredis hiredis
編寫RedisManager
其實(shí)這里還是和MySQL
比較接近的衅鹿,也是通過一個(gè)字典存放各個(gè)redis的連接配置撒踪。
不過由于Redis的集群和單實(shí)例還有一點(diǎn)區(qū)別(好在我們編寫配置的時(shí)候就準(zhǔn)備好了),所以我們最好是針對(duì)單實(shí)例和集群分別編寫2個(gè)map存放他們的client大渤,當(dāng)然1個(gè)也是ok的制妄。
整體流程: 從字典獲取客戶端,如果沒有則新開一個(gè)客戶端泵三,并放入緩存耕捞,有則返回。
-
可能存在的問題
代碼不是線程安全的烫幕,需要觀察是否需要加鎖
緩存不像LRU會(huì)降頻俺抽,也不能自動(dòng)過期
對(duì)我來說第一個(gè)肯定是個(gè)大問題,如果出現(xiàn)了就必須得解決较曼。至于第二個(gè)問題磷斧,由于redis配置很少變動(dòng),而且我們本身是連接池的形式捷犹,所以影響不算大弛饭。
話不多說,現(xiàn)在我們就來編寫吧:
"""
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單實(shí)例客戶端
: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}")
我們以數(shù)據(jù)庫的唯一id為key翠桦,緩存redis的連接池
。
由于連接池會(huì)自動(dòng)開啟/關(guān)閉連接,所以我們不需要手動(dòng)關(guān)閉客戶端销凑,非常方便丛晌。
可以明顯看到我們分別用了ClusterConnectionPool和ConnectionPool谋逻,分別對(duì)應(yīng)集群和實(shí)例。參數(shù)基本上算是一致桐经。
至于refresh毁兆,是給改動(dòng)redis以后做的刷新連接
的工作。
以上就是RedisManager的內(nèi)容阴挣,到這只是能夠獲取Redis客戶端了气堕。
嘗試一下
有條件的同學(xué)可以本次安裝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, 接著取消這一行的注釋:
使用密碼模式(redis最好是加密碼畔咧,端口號(hào)也盡量不要用原生的6379茎芭,本寶寶有臺(tái)機(jī)器被人通過redis植入了挖礦程序,苦不堪言
)
- 在redis-6.2.6目錄下啟動(dòng)
src/redis-server redis.conf
這樣本地redis的實(shí)例就啟動(dòng)了~
編寫個(gè)在線測(cè)試redis的接口
先通過id拿到redis的配置信息
然后通過manager拿到連接池
-
對(duì)redis發(fā)動(dòng)命令
我們?cè)?a target="_blank">http://localhost:7777/docs打開swagger調(diào)試:
讀取faker
- 設(shè)置faker為s12
- 再次取faker
可以看到redis的相關(guān)操作已經(jīng)是可以用了誓沸,那我們今天的內(nèi)容就到這了梅桩,愉快的周末總是辣么短暫
。
下一節(jié)我們就得編寫在線執(zhí)行Redis的命令及相關(guān)頁面了蔽介!