最近解决了公司里一个爬虫项目的问题,也就是如何保持全局的redis连接。先来回想下问题如何,首先爬虫项目是用asyncio驱动,异步爬取数据,而redis连接用的是aioredis,难就难在,已有的代码,将redis连接池的异步创建放在了task里,而task里面又在不断的循环执行任务,这样就导致每循环一次,redis连接池就创建一遍,导致系统资源的极度浪费。
常规方法的直接引入是没用的,因为这是异步的环境。
那什么是contextvars
contextvars 来源于 PEP-567 ,它提供了 APIs 允许开发者去保存,访问及管理 local context。 它与 thread-local storage (TLS) 类似。但它还支持维护异步代码的 context.
这里直接上代码:
编写上下文部分
from contextvars import ContextVar, Context
from utils.redis import Redis
redis_client = ContextVar("redis_client")
class RedisGlobal:
def __init__(self, code, level_db):
self.DB_CODE = code
self.REDIS_LEVEL_DB = level_db
async def run(self):
redis = Redis()
try:
test_redis = await redis.get_redis_pool((self.REDIS_LEVEL_DB, REDIS_PORT), password=REDIS_PASSWORD,db=0, encoding='utf-8')
except Exception as e:
pass
redis_dict = {"test_redis": test_redis ,
}
redis_client.set(redis_dict)
return redis_client
调用部分
redis_global = RedisGlobal(CODE, LEVEL_DB)
redis_client = await redis_global.run()
redis_dict = redis_client.get()
然后就从字典里获取到连接了,这里的字典里也可以存多个链接。这样就实现了全局统一的redis连接。
版权属于:Jolly
本文链接:https://totoro.site/index.php/archives/117/
关于转载:原创文章,禁止转载
感谢分享