服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Redis - dubbo服务使用redis注册中心的系列异常解决

dubbo服务使用redis注册中心的系列异常解决

2022-03-01 22:45kl Redis

这篇文章主要为大家介绍了dubbo服务在使用redis注册中心遇到的一系列异常的解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步

dubbo服务使用redis注册中心的系列异常解决

 

前言

dubbo支持zookeeper,reids,multicast等注册中心注册服务信息,使用redis作为注册中心时,因为reids作为注册中心使用并不广泛,早期reids由于定位内网访问,使用密码验证也不怎么重视,导致框架本身设计缺陷,会有很多坑,如1.没有考虑到带密码验证的redis,2.集群容错模式判断错误 3.不可以设置redisdbindex等。其中部分问题,博主已经提交给dubbo官方仓库了,但是还没有完全解决掉,其实这些问题无需等官方修复,对源码稍加改造就ok了。

 

1.不支持带密码,设置indexdb的reids

2.5.6以及以前的会有这个问题,最新的版本已经解决了这个问题了,但是还是存在一个坑,就是必须得设置用户名(大家都知道redis验证不需要用户名),如URL的构造方法有如下判断

dubbo服务使用redis注册中心的系列异常解决

这会导致,如果只设置了密码,没有设置用户名,就会抛Invalid url, password without username的异常。

 

解决方法:

1.打开RedisRegistry.java,设置jedispool时判断下,如果设置密码,使用带密码,indexdb入参的构造方法,具体如下:

            if(StringUtils.isEmpty(url.getPassword())){
                this.jedisPools.put(address, new JedisPool(config, host, port,
                        url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT),null,url.getParameter("db.index",0)));
            }else {
                this.jedisPools.put(address, new JedisPool(config, host, port,
                        url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT),url.getPassword(),url.getParameter("db.index",0)));
            }

2.配置注册中心的时候得把username加上,如:

dubbo服务使用redis注册中心的系列异常解决

 

二,集群容错模式异常

这个问题,不开启服务监控不会有问题,在开启dubbo服务监控后,就会抛异常:Unsupported redis cluster: Failsafe. The redis cluster only supported failover or replicate,问题是由如下图红框内的if判断造成的,因为监控模块服务默认的集群容错模式为Failsafe,而且写死了,不可通过配置更改,如图:

dubbo服务使用redis注册中心的系列异常解决

如下图箭头所指为添加了排除监控中心的if判断逻辑:

dubbo服务使用redis注册中心的系列异常解决

 

三,jedis连接池连接的坑

在修改了dubbo后,由于没有更新到修改后本地打包的dubbo依赖,一度报如下异常:

at java.lang.Thread.run(Thread.java:748)
Caused by: redis.clients.jedis.exceptions.JedisException: Could not get a resource from the pool
	at redis.clients.util.Pool.getResource(Pool.java:51)
	at redis.clients.jedis.JedisPool.getResource(JedisPool.java:226)
	at com.alibaba.dubbo.registry.redis.RedisRegistry.doSubscribe(RedisRegistry.java:342)
	... 43 more
Caused by: java.util.NoSuchElementException: Unable to validate object
	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:506)
	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363)
	at redis.clients.util.Pool.getResource(Pool.java:49)
	... 45 more

Unable to validate object的问题网上有各种说法,博主也找了好久的问题,最终通过猜想+读jedis源码+本地debug调试才解决的问题。其实网上的说法都正确,原因是jedis内一段代码导致的,dubbo默认设置了连接池的test.on.borrow为true,所有在拿连接前都会验证一遍,验证的逻辑如下:

dubbo服务使用redis注册中心的系列异常解决

如上图,前面两个判断100%不会有问题,网上大多是因为redis服务本身出问题了,ping的时候没有返回PONG。博主这边是以为jedis.isConnected()报错了,但是jedis是个坑,虽然返回了false,但是具体的异常信息并没有抛出来,其实这个地方,具体的异常:redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required.。很明显是reids密码验证失败了。因为一开始修改的dubbo密码设置没有依赖到

 

四,服务超过8个应用启动卡死

这个最终的问题还是jedis导致的,dubbo默认初始化的jedis连接池,最大链接数是8个,然后默认的从连接池里拿连接的超时时间为-1,又因为使用redis作为注册中心时,通过订阅暴露的service 的变更来做服务治理的,而jedis里的服务订阅是阻塞占用连接的,也就是说有多少个服务,就会被占用多少个链接。这就导致了,当暴露的服务数量大于8个时,从连接池中获取不到资源,又永不超时,造成应用启动卡死的现象

解决方案:手动设置jedis的最大连接数,如:

spring.dubbo.registry.parameters.max.total = 200

 

文末结语

使用开源的产品,还是要多读读开源产品代码,至少架构设计,模块划分要了解,这样遇到啥问题,才不会手足无措,才能举一反三。bug或异常一点都不可怕,遇到异常,解决异常就问两个问题。1.在哪里抛出的异常(找到抛异常的代码),2.为什么抛这个异常(找出抛异常的原因,一般有逻辑,如if判断等,没有的逻辑的异常一般都是系统级别的),然后通读下异常周边代码,基本上问题就搞定了

以上就是dubbo服务使用redis注册中心的系列异常解决的详细内容,更多关于dubbo使用redis注册中心系列异常的资料请关注服务器之家其它相关文章!

原文地址:http://www.kailing.pub/article/index/arcid/202.html

延伸 · 阅读

精彩推荐
  • Redis关于Redis数据库入门详细介绍

    关于Redis数据库入门详细介绍

    大家好,本篇文章主要讲的是关于Redis数据库入门详细介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览...

    沃尔码6982022-01-24
  • Redis如何使用Redis锁处理并发问题详解

    如何使用Redis锁处理并发问题详解

    这篇文章主要给大家介绍了关于如何使用Redis锁处理并发问题的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Redis具有一定的参考学习...

    haofly4522019-11-26
  • RedisRedis集群的5种使用方式,各自优缺点分析

    Redis集群的5种使用方式,各自优缺点分析

    Redis 多副本,采用主从(replication)部署结构,相较于单副本而言最大的特点就是主从实例间数据实时同步,并且提供数据持久化和备份策略。...

    优知学院4082021-08-10
  • RedisRedis Template实现分布式锁的实例代码

    Redis Template实现分布式锁的实例代码

    这篇文章主要介绍了Redis Template实现分布式锁,需要的朋友可以参考下 ...

    晴天小哥哥2592019-11-18
  • RedisRedis 6.X Cluster 集群搭建

    Redis 6.X Cluster 集群搭建

    码哥带大家完成在 CentOS 7 中安装 Redis 6.x 教程。在学习 Redis Cluster 集群之前,我们需要先搭建一套集群环境。机器有限,实现目标是一台机器上搭建 6 个节...

    码哥字节15752021-04-07
  • Redisredis缓存存储Session原理机制

    redis缓存存储Session原理机制

    这篇文章主要为大家介绍了redis缓存存储Session原理机制详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...

    程序媛张小妍9252021-11-25
  • Redis详解三分钟快速搭建分布式高可用的Redis集群

    详解三分钟快速搭建分布式高可用的Redis集群

    这篇文章主要介绍了详解三分钟快速搭建分布式高可用的Redis集群,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,...

    万猫学社4502021-07-25
  • Redis《面试八股文》之 Redis十六卷

    《面试八股文》之 Redis十六卷

    redis 作为我们最常用的内存数据库,很多地方你都能够发现它的身影,比如说登录信息的存储,分布式锁的使用,其经常被我们当做缓存去使用。...

    moon聊技术8182021-07-26