Dubbo学习笔记(二)

#dubbo学习笔记(二)


一. 注册中心使用redis

1.1 环境搭建

redis没有username,但是redis作为注册中心,在实例化URL时会判断username是否为空,如果为空会报错

图片描述

<!--redis没有username,所以username随便写即可,如果不写或者为空会报错-->
    <dubboi:registry protocol="redis" address="192.168.1.1:26379" password="poiuytrewq" username="12"/>

注意,在使用redis作为注册中心的时候,要引入redis相关的jar包,否则会报类找不到的异常

<!--Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/pool2/impl/GenericObjectPoolConfig
            at com.alibaba.dubbo.registry.redis.RedisRegistry.<init>(RedisRegistry.java:88)
            at com.alibaba.dubbo.registry.redis.RedisRegistryFactory.createRegistry(RedisRegistryFactory.java:31)
            at com.alibaba.dubbo.registry.support.AbstractRegistryFactory.getRegistry(AbstractRegistryFactory.java:96)
        -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>

1.2 开始运行

1.2.1 服务端

首先启动服务端,生成之后查看redis,会发现多了一个redis数据记录(如下图所示)。该redis的数据类型是hash类型的,也就是说value存储的是key-value形式的数据,其中key是服务端url,value是该url的到期时间。其到期时间是服务启动时间加上60秒形成的。dubbo每隔30秒就会刷新一次过期时间,这样能保证数据永远不过期。如果某个服务挂了,其数据会立马清除掉(别人说不会清除掉,但是我试了下,是会被清除掉的)。如果所有服务都挂了,该redis也就不再了。

# 服务端url
# 其中的default.timeout是优先级比较高的超时时间(设置在serice中),timeout是优先级比较低的(设置在provider中)
dubbo://192.168.1.180:20880/zexin.dubbo.server.UserManager?anyhost=true&application=dubbo-server&default.group=userManagerGroup2&default.timeout=2000&dubbo=2.6.2&generic=false&interface=zexin.dubbo.server.UserManager&methods=getUserWithPort,getUser&pid=3456&retries=2&side=provider&timeout=5000&timestamp=1543993686941

在这里插入图片描述

在这里插入图片描述

1.2.2 客户端
## url
consumer://192.168.1.180/zexin.dubbo.server.UserManager?application=dubbo-client&category=consumers&check=false&dubbo=2.6.2&group=userManagerGroup2&interface=zexin.dubbo.server.UserManager&loadbalance=roundrobin&methods=getUserWithPort,getUser&pid=3573&side=consumer&timestamp=1543996444192

同服务端一样,也会生成一个redis数据(如下图所示)。如果某个服务挂了,客户端并不会去请求该客户端,而是请求正常的服务端。

在这里插入图片描述

1.3 总结

redis作为注册中心,启动/修改服务,客户端是实时的。服务端挂了,客户端怎么知道?服务端与客户端之间是长连接,服务端挂了会关闭channel,客户端是会被通知到的。但是一般作为dubbo的注册中心的是zk,因为zk的性能等各方面都优于redis。

1.4 问题

  • 在客户端设置的路由策略是roundrobin(轮流策略),在启动两个服务的时候,这个轮流策略是生效的,但我重启某个服务的时候,发现轮流侧率不生效了,而且,重启完之后的服务被访问到的概率很低。

初步估计是因为我的redis不稳定导致的,后面又测了几遍,发现又生效了。

二. dubbo-admin

dubbo 在2.6.0 以前 使用dubbo-admin 作为管理后台,2.6 以后已经去掉dubbo-admin 并采用 incubator-dubbo-ops 作为新的管理后台,目前该后台还在开发中还没有发布正式的版本

incubator-dubbo-ops的github地址 dubbo的项目github地址 dubbo-admin本地访问网址

2.1 编译打包dubbo-admin项目

  1. 克隆dubbo项目
git clone https://github.com/apache/incubator-dubbo.git
  1. 进入项目并切换到2.5.8分支
cd incubator-dubbo/
git checkout dubbo-2.5.8
  1. 进入dubbo-admin项目并编译
cd dubbo-admin
mvn clean pakcage -DskipTests
  1. 把war包扔到tomcat的webapps下,tomcat会自动解压,然后根据实际情况修改dubbo.properties
2.2 使用redis作为注册中的问题

因为zk我并不熟,所以我是使用redis作为注册中心的,但是dubbo-admin的redis作为注册中心有点坑。我用的dubbo-admin的版本是2.5.8,也至于这个版本及之前的版本有admin可以编译打包。我的dubbo.properties配置如下:

dubbo.registry.address=redis://127.0.0.1:6379
# 该redis是有设置密码的
dubbo.registry.password=123456
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest

问题:

  1. 日志提示类无法找到异常,因为没有引入相应的redis jar包,所以需要进入dubbo-admin,修改其pom文件
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity</artifactId>
</dependency>
  1. 日志提示无法获取redis pool,即无法连接上redis。

这个问题挺坑的,我的redis的账号和密码都是正确的,而且在本地我的dubbo服务也是一样的配置,可以正常启动,但是dubbo-admin就是无法启动,后面通过查看dubbo的issue,发现也有人说这个问题。其实这是dubbo的bug,针对有密码的redis,2.6之前是连不上的,但是2.6之后又没有dubbo-admin了(issue说会在2.5.8修复,但是并没有)。后面我就自己在dubbo-admin的本地服务中启动一个无密码的redis,dubbo-admin成功启动。

## 修改正确后的配置
dubbo.registry.address=redis://127.0.0.1:6379

# 下面的这个两个是访问网址的密码,我的设置是账号和密码同名
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest

dubbo-2.5.6使用redis作为注册中心报错

在这里插入图片描述

三. Dubbo注册中心详解

我所理解的注册中心:

  1. 注册中心存储了服务的地址信息与可用状态,如常见的redis和zk。以redis为例,服务启动之后会实时地添加到redis中,并且会通知到所有的客户端(客户端会存储一份到自己的内存中),客户端会根据最新的服务地址信息更新自己内存中存储的服务地址。如果某个服务挂掉了,注册中心清理掉相应服务地址信息,并通知客户端。如果注册中心没有清理,即同事说的在kill的情况下,redis并不会清理到相应的服务,只是不再更新其过期时间而已,那么客户端也是会请求到这个挂掉的服务的,只是客户端在请求这个服务的时候,会去检查该服务的可用性,如果该服务是不可用的,则会重新针对其他服务发起请求。
  2. zk有40秒的会话期,即说即使某个服务挂了,zk也不会立马把这个服务清除,而是等待40秒,40秒之后该服务依然不可用才把它清除,防止一些服务假挂
  3. 如果注册中心挂了,客户端虽然会报错,但是还是可以请求到服务的,因为客户端自己本地会维护一份服务地址信息(亲测)
3.1 注册中心的作用

为了达到服务集群动态扩容的目的,注册中心存储了服务的地址信息与可用状态信息,并实时推送给订阅了相关服务的客户端

在这里插入图片描述

3.2 注册中心需要实现的功能
  1. 接收服务端的注册与客户端的引用,即将引用与消费建立关联,并支持多对多
  2. 当服务非正常关闭时能及时清理其状态
  3. 当注册中心重启时,能自动恢复注册数据,以及订阅请求
  4. 注册中心本身的集群
3.3 redis所支持的注册中心
  1. multicate注册中心

基于组网广播技术,只能用在局域网内,一般用于简单的测试服务

  1. zookeeper注册中心(推荐)

Zookeeper 是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用。 Zookeper是一个树型的目录服务,本身支持变更推送相比redis的实现Publish/Subscribe功能更稳定。

在这里插入图片描述

  1. Redis注册中心
com.alibaba.dubbo.registry.redis.RedisRegistry#deferExpired  //获取dynamic默认是true,设置url的value值

  1. Simple注册中心

基于本身的Dubbo服务实现(SimpleRegistryService),不支持集群可作为自定义注册中心的参考,但不适合直接用于生产环境

3.4 基于zk作为注册中心的一些源码跟踪

ReferenceConfig中的invoke发起对服务端的调用 invoke接口,FailbackClusterInvoke实现该接口(失败重试,并且对多个服务进行集群) FailbackClusterInvoke里面要有多个提供者的url 怎么获取到多个url? FailbackClusterInvoke.doInvoke 其父类(AbstractCluster)中有个方法是list,该list就是去生成多个invoker,也就是多个url。通过Directory生成。 url存储在Directory这个对象中(这些信息从注册中心推过来的) Directory是有RegistryDirectory实现的。注册中心中服务的增加/减少,是通过RegistryDirectory的notify方法动态通知的,其没有获取ReferenceUrl,拿到没用(这个不懂) 其通知是由NotifyListener通知的 ZookeperRegistery的doSubscribe通知NotifyListener进行调用


## ReferenceConfig中的invoke发起对服务端的调用
com.alibaba.dubbo.rpc.cluster.support.FailbackClusterInvoker#doInvoke
   父类  com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker#invoke
   				com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker#list  (获取所有的url)
   					com.alibaba.dubbo.rpc.cluster.Directory#list  (通过RegistryDirectory获取list)
   						com.alibaba.dubbo.rpc.cluster.directory.AbstractDirectory#list
   							com.alibaba.dubbo.registry.integration.RegistryDirectory#doList

## 客户端订阅,通知注册中心
com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistry#doSubscribe  # 客户端订阅消息
	com.alibaba.dubbo.registry.support.FailbackRegistry#notify
		com.alibaba.dubbo.registry.support.FailbackRegistry#doNotify
			com.alibaba.dubbo.registry.support.AbstractRegistry#notify(com.alibaba.dubbo.common.URL, com.alibaba.dubbo.registry.NotifyListener, java.util.List<com.alibaba.dubbo.common.URL>)
				com.alibaba.dubbo.registry.integration.RegistryDirectory#notify  # 通知注册中心

//失败重连 com.alibaba.dubbo.registry.support.FailbackRegistry 提供者突然断开: 基于Zookeeper 临时节点机制实现,在客户端会话超时后 Zookeeper会自动删除所有临时节点,默认为40秒。 // 创建临时节点 com.alibaba.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient#createEphemeral 提问: 在zookeeper 断开的40秒内 如果 有客户端加入 会调用 已失效的提供者连接吗? 答:不会,提供者宕机后 ,其与客户端的链接也随即断开,客户端在调用前会检测长连接状态。 // 检测连接是否有效 com.alibaba.dubbo.rpc.protocol.dubbo.DubboInvoker#isAvailable 创建 configurators与routers 会创建持久节点 // 创建持久节点 com.alibaba.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient#createPersistent 服务订阅机制实现: // 注册目录 com.alibaba.dubbo.registry.integration.RegistryDirectory

在这里插入图片描述

转载于:https://my.oschina.net/u/3859475/blog/2982331

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值