标签:屏幕 拒绝 感知 rom could not 命令 http 最佳实践 保护
先说些题外话~自上次确诊为鼻窦炎+过敏性鼻炎到现在已经一个月了,最初那会,从下午到晚上头疼难忍。大概是积劳成疾,以前流鼻涕、打喷嚏的时候从来没有注意过,结果病根一下爆发。
关键在于锁定问题,开始治疗一两天之后就不会头疼了。当然,习惯也很重要,再也不敢用力擤鼻子了。
挺过那一阵就好受很多,之后就是鼻塞稍微烦人一些。鼻子的问题很容易串到其他面部器官中去,一旦发展严重必然大幅度影响生活质量。
治疗方法推荐洗鼻(前两周先消炎,吃地红霉素),但注意不要让医院赚的太狠,药包到药店或者网上买都可以;如果是过敏引发流涕也要吃抗过敏药。
以上,为同样深受困扰的小伙伴提供一些经验。。
【问题】使用jediscluster连接redis集群,使用jedis执行redis命令,一些时候报Could not get a resource from the pool ,底层是连接超时异常,另一些时候则正常。
【复现】时好时坏,有时失败后马上第二次请求相同命令即成功,进一步测试发现竟然与请求的key有关,极难定位问题原因。
【方案】1、考虑为服务端与客户端版本不匹配问题,而
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
jedis版本已为最新,另有3.X-m1版本,换用之后也无效。此处麻烦大家告知一下“m1”的意思。
换用spring的包装客户端,spring-data-redis,亦无效。
从时好时坏这一点来看,版本不是主因。事实上,redis对于版本匹配并不如kafka那般严格。
2、考虑为客户端连接参数问题,结合网上各种经验调整JedisPoolConfig与JedisCluster构造方法参数,均无效。这里时间浪费最多,网上信息庞杂而大部分无用。
3、考虑为服务端单个redis节点配置问题,bind不到外网ip,这点很疑惑。
4、考虑为服务端密码问题,从slot槽的设计入手,假设在目前的客户端中,如果请求的key需要转发到其他节点,则因为没有验证密码而被其他节点拒绝。(实际上这是对部署脚本或者jedis集群客户端不信任)
服务端取消密码构建集群后问题依旧,但已经接近问题答案。
【解决】定位问题在于集群节点。
原因排查依据:
(1)命令执行时好时坏,同一命令请求不同key,一些一直成功,其他一直不成功。
(2)查询所有节点的keys命令从未成功。
(3)debug之下发现不成功的命令请求的节点是内网ip,成功的命令是另一节点的外网ip。
原来,为了测试方便,我使用了外网ip构建集群。但是,官方提供的redis-trib.rb脚本带有极大的迷惑性,在构建时返回屏幕的信息正确,而自动生成的每个节点的nodes.conf中,表述自身的一行与预期均有出入,如下所示:
图中139为外网ip,而172则是内网ip。导致客户端经对key哈希后得到的槽,所对应的请求节点有可能拿到内网ip,导致无法连接。超时后报错。
为解决问题,我假设只要该配置存在,节点之间即可相互感知,节点重启后也不会影响集群状态。故而手工将内网ip修改为外网ip,重启每个redis节点,问题解决。
【目前最佳实践】
目前认为官方提供用于构建和管理集群的redis-trib.rb脚本,对外网ip的支持并不完善。因此,
1、在开发测试阶段,通过外网ip构建集群,通过密码保证安全性。
2、单个redis配置:bind注释掉,打开保护模式,设置密码和集群master密码,ruby client.rb中对应修改密码。
我的路径/usr/local/rvm/gems/ruby-2.4.1/gems/redis-4.0.2/lib/redis/client.rb 密码用就替换,不用就填nil,不是空字串!
3、清除每一个节点的持久化记录和之前的nodes.conf之后,用外网ip正常构建集群。
4、手工修改生成的每一个nodes.conf,然后重启对应的redis节点。
如有理解偏差或更好方案,希望可以告知,大家一起讨论。
【Redis】Could not get a resource from the pool 实乃集群配置问题
标签:屏幕 拒绝 感知 rom could not 命令 http 最佳实践 保护
原文地址:https://www.cnblogs.com/feixuefubing/p/10031449.html