Hyperf方案 Redis连接池管理

张开发
2026/4/7 16:07:40 15 分钟阅读

分享文章

Hyperf方案 Redis连接池管理
?php// 案例Redis连接池管理// 说明配置Redis连接池参数支持多库切换避免每次都新建连接// 需要安装composer require hyperf/redisdeclare(strict_types1);// config/autoload/redis.php — Redis连接池配置文件return[default[hostenv(REDIS_HOST,127.0.0.1),// Redis服务器地址authenv(REDIS_AUTH,null),// 密码没有就填nullport(int)env(REDIS_PORT,6379),// 端口默认6379db(int)env(REDIS_DB,0),// 用第几个库0-15timeout2.0,// 连接超时2秒retry_interval0,// 失败重试间隔read_timeout0,// 读取超时0表示不限pool[min_connections5,// 最少保持5个连接空闲也不关掉max_connections50,// 最多开50个连接超了就排队等connect_timeout10.0,// 等待连接最多10秒wait_timeout3.0,// 从池子里取连接等3秒超了报错heartbeat-1,// 心跳检测-1表示关掉max_idle_time60,// 连接空闲超60秒自动关掉],],// 缓存用的库和业务数据分开cache[hostenv(REDIS_HOST,127.0.0.1),authenv(REDIS_AUTH,null),port(int)env(REDIS_PORT,6379),db1,// 用1号库专门存缓存pool[min_connections2,max_connections20,connect_timeout10.0,wait_timeout3.0,heartbeat-1,max_idle_time60,],],// 队列专用库queue[hostenv(REDIS_HOST,127.0.0.1),authenv(REDIS_AUTH,null),port(int)env(REDIS_PORT,6379),db2,// 2号库专门给队列用pool[min_connections2,max_connections30,connect_timeout10.0,wait_timeout3.0,heartbeat-1,max_idle_time60,],],];namespaceApp\Service;useHyperf\Redis\Redis;useHyperf\Redis\RedisFactory;useHyperf\Di\Annotation\Inject;classRedisPoolDemo{#[Inject]protectedRedisFactory$redisFactory;// 注入Redis工厂可以拿到不同连接池#[Inject]protectedRedis$redis;// 注入默认连接池default那个// 往默认库写数据publicfunctionsetDefault(string$key,string$value,int$ttl3600):bool{return(bool)$this-redis-set($key,$value,$ttl);// 写进去3600秒过期}// 从默认库读数据publicfunctiongetDefault(string$key):?string{$val$this-redis-get($key);// 取出来return$valfalse?null:$val;// 取不到返回null}// 往缓存库写数据走cache连接池publicfunctionsetCache(string$key,mixed$data,int$ttl7200):void{$redis$this-redisFactory-get(cache);// 拿cache那个连接池$redis-set($key,serialize($data),$ttl);// 序列化后存进去}// 从缓存库读数据publicfunctiongetCache(string$key):mixed{$redis$this-redisFactory-get(cache);// 还是拿cache连接池$val$redis-get($key);// 取出来return$valfalse?null:unserialize($val);// 反序列化还原}// 往队列库推消息publicfunctionpushQueue(string$queue,string$message):int{$redis$this-redisFactory-get(queue);// 拿queue连接池return(int)$redis-rpush($queue,$message);// 从右边推进List}// 从队列库取消息阻塞等待最多等5秒publicfunctionpopQueue(string$queue):?string{$redis$this-redisFactory-get(queue);$result$redis-blpop([$queue],5);// 从左边取等5秒没有就返回nullreturn$result?$result[1]:null;// blpop返回[队列名, 消息]}// 查看连接池使用情况用于监控publicfunctionpoolStats():array{$pool$this-redisFactory-get(default);// 拿默认连接池对象// 注意Hyperf的连接池没有直接暴露stats接口这里演示思路return[pool_namedefault,current_timedate(Y-m-d H:i:s),statusrunning,];}// 批量操作用pipeline减少网络来回次数publicfunctionbatchSet(array$data):void{$this-redis-pipeline(function($pipe)use($data){foreach($dataas$key$value){$pipe-set($key,$value,3600);// 一次性把所有命令打包发出去}});}// 用事务保证多个操作要么都成功要么都失败publicfunctionatomicTransfer(string$fromKey,string$toKey,int$amount):bool{$this-redis-watch($fromKey);// 监视这个key有人改了就事务失败$balance(int)$this-redis-get($fromKey);if($balance$amount){$this-redis-unwatch();// 余额不够取消监视returnfalse;}$result$this-redis-multi()// 开始事务-decrBy($fromKey,$amount)// 扣减-incrBy($toKey,$amount)// 增加-exec();// 提交事务return$result!false;// false表示被别人改了事务失败}}

更多文章