dubbo admin,查看zookeeper注册服务
dubbo admin,查看zookeeper注册服务详细介绍
本文目录一览: 记一次zk节点内容异常,导致dubbo-admin无法启动
监控发现dubbo-admin无法正常响应,返回了500错误。
重启dubbo-admin,发现无法正常启动,从启动日志中,发现频繁发出2条重复消息:
捉包发现是dubbo-admin在接收数据后RESET的TCP连接。
此时我们将dubbo-admin连接其他zk机器能正常启动。异常ZK集群却无法引导dubbo-admin 。
尝试了滚动升级zk集群小版本,问题无法修复。在使用 zkCli.sh 执行命令 ls /dubbo 缺返回了一条消息:
java.io.IOException: Packet len8854970 is out of range!
增加参数后,发现 /dubbo 目录中增加了好多25结尾的节点。得出结论是,由于节点名称过长导致客户端连接异常而退出。
此时重启dubbo-admin即可恢复正常
dubbo系列之-qos运维-2021-01-17
dubbo自带的运维工具dubbo-admin,主要面向开发人员去管理服务,携带很多管理、控制等功能,然后在dubbo新版本又推出了qos(Quality of Service),主要面向运维管理。我在之前公司有用到次功能,在和k8s结合时,通过http发送主动下线功能(下线注册,但不下线服务),等到流量完全停止,在下线pod,实现平滑发布。
怎么样去管理?
dubbo通过 QosProtocolWrapper 这个包装器实现qos发布,QosProtocolWrapper 是Protocol 三大包装器(filter,listener,qos)其中之一,默认会开启qos功能,可以配置关闭
qos 主要提供了ls,online,offline,help 功能,具体说,只有三种,上下线服务和查看服务
我们跟读一下源码,看看qos 服务的启动,请求处理,上下线等。
在dubbo 生产者服务暴露和消费者消费引用的过程中都会启动qos,并且qos 通过cas来保证一个jvm只启动一次。
同样qos 功能也是通过netty启动server,处理类指定为 QosProcessHandler,这个handler实现了netty的 ByteToMessageDecoder 可以将网络流中的字节解码为对象
channelActive() 方法含有为连接建立的时候回调,这里有个定时任务500ms,会刷一个美体的dubbo给客户端,我们验证下。
我们看看 QosProcessHandler#decode 是怎么处理请求的。
上面方法讲究,先读取第一个字节判断请求是http 还是 tcp,为什么用第一个字节呢,我们知道http信息头开始为 GET /xx 或者 POST /xx,第一个字符要么G要么P,判断为http 则用http编解码,如果为tcp 则用 LineBasedFrameDecoder 编解码,这是一个换行分割读取的解码方式遇到(\n,\r)[就是telnet时候的回车]时,就截断,如果为tcp 还会添加一个 IdleStateHandler 作为心跳检测,最后处理指令的handler 为 TelnetProcessHandler。
先演示下效果
为了便于观察我们这里看http的处理指令的方式 HttpProcessHandler。
HttpCommandDecoder. decode (msg)会将get或者post请求携带的路径等返回给 commandContext , BaseCommand.class 为指令扩展点会根据uri 传入的指令,来指定要处理的类,优点类似策略模式。我们看看offline 是怎么处理的
可以传入服务,默认所有服务,18行中从注册工厂中获取服务对应的注册中心,然后调用注册中心的unregister() 最后层层调用到zk客户端的delete()方法来,删除zk临时节点。
qos 的功能和简单,之所以单独拿出来讲是因为这里涵盖了我们web开发中常提到的“http服务器”概念,通过netty 启动服务,然后处理请求。
dubbo admin是怎么监听zookeeper变化的
1 ) ZooKeeper的Watcher是一次性的,用过了需要再注册; 2 ) session的超时后没有自动重连,生产环境中如果网络出现不稳定情况,那么这种情况出现的更加明显; 3 ) 没有领导选举机制,集群情况下可能需要实现stand by,一个服务挂了,另一个...
Dubbo提供者的禁用
dynamic 服务是否动态注册,如果设为false,注册后将显示为disable状态,需人工启用,并且服务提供者停止时,也不会自动取消注册,需人工禁用。 @Service注解
dubbo2.7.2以前
dubbo2.7.2及2.7.2以后
dynamic在service上的默认值变了
按照dubbo配置生效规则 :
但是dynamic参数并不会产生禁用dubbo提供者的效果 dynamic=false提供者启动时,服务同样会被注册到zookeeper。消费者也会调用到相对应的服务。 当提供者停止后,dynamic=true的服务的连接在zookeeper上会消失,但是dynamic=false的服务的连接还会保存在zookeeper上,不会消失。 dynamic关键字只是控制dubbo提供者停止后,zk上这些节点消不消失,并不是控制服务可不可以访问。
由于ip是动态的,采用application name的方式
以user-center-provider为例
提前取好name、配置好动态规则,再去部署提供者就可禁用dubbo服务。 但是dubbo-admin只有先部署服务才能配置规则
取新的applicaton name 和不取新applicaton name,结合下面 【3、dubbo-admin动态配置】 选择一种
动态配置分两种,取新的applicaton name 和不取applicaton name
限制的地址需要修改
修改权重weight
经过测试的用例:
3节点: 2个节点权重100,1 个节点权重0 ,权重0的不可以访问 3节点:3个节点权重都是0,都可以访问 2节点: 2个节点权重都是0,都可以访问 2节点:1个节点权重100 ,1个节点权重0 ,权重0的不可以访问 例如: user-center-provider 老节点的权重默认100,节点为A和B。 更改apollo配置weight=0,启动服务创建C和D。 同时存在四个节点A、B、C、D。由于C和D权重为0,所以流量只会进入A、B。 当A、B停止时,流量会进入C、D,此时与权重值是否为0无关了。 老节点停止,新节点瞬间可用 引发的思考:并发访问量大的情况下,老节点停止,到新节点启用,这之间的数据同步会不会有问题?
查看zookeeper注册服务
在Mac下
查看zookeeper注册中心是否有注册服务可以在服务器上查看,也可以在dubbo admin上查看
查看注册的服务,执行命令:
zkui它提供了一个管理界面 ,可以针对zookeeper的节点值进行CURD操作,同时提供了安全认证。
执行打包命令
注意,执行前需要安装Java环境,maven环境,执行成功后会生成一个jar包。
如果是这个地址就不用改
dubbo调用问题之序列化
dubbo的版本是2.5.3,接口调用后,provider方接收不到请求,超时后报错:Waiting server-side response timeout by scan timer.详细日志如下:
通过dubbo admin查看providers和consumers,可以找到服务,双方状态正常,dubbo版本也一致。 其实如果接口的provider方异常,调用方直接会收到类似于No provider available 或Forbid consumer access service from registry use dubbo version 2.5.3, Please check registry access list (whitelist/blacklist)的错误提示。
然后,查看接口请求参数,发现其实现了java序列化接口,和错误日志中的序列化方式一致。
后来测试时发现,竟然存在部分请求成功,着重分析后发现请求对象数据存在差异,请求对象的类定义中部分自定义域没有实现序列化接口。之前调用成功的请求中,其请求参数中未实现序列化的字段值为null。后来测试当整个请求参数不实现序列化时,发现接收方也可以收到请求。
跨服务调用时,传参必须实现序列化,其内部引用的对象也必须序列化。
1.方法的参数没有实现序列化,或其内部引用的对象没有实现序列化。
2.方法返回值没有序列化。(根据错误日志就能看明确发现)
3.调用双方形参版本不一致。(根据错误日志就能看明确发现)
4.注册中心配置错误导致的异常。(根据错误日志或dubbo admin可以明确发现)
5.网络异常导致的超时。
Dubbo——服务调用、服务暴露、服务引用过程
1、InvokerInvocationHandler jdk动态代理
5、RegistryDirector返回Invokers Router分为:Script 脚本路由、Condition 条件路由
6、通过MockInvokersSelector的route方法(getNormalInvokers)拿到能正常执行的invokers
8、当回到AbstractClusterInvoker后,执行(默认FailoverClusterInvoker,根据配置的是,Failfast Cluster(快速失败) , Failsafe Cluster(失败安全) , Failback Cluster(失败自动恢复) , Forking Cluster(并行调用多个服务器,只要一个成功即返回) , Broadcast Cluster(广播调用所有提供者,逐个调用,任意一台报错则报错))doInvoker方法
9、FailoverClusterInvoker调用AbstractClusterInvoker的select方法
10、执行doSelect方法
11、调用AbstractLoadbalance的select方法
12、根据配置的负载均衡策略调用对应的(如RoundRobinLoadBalance)类的doSelect方法
13、返回invokers.get()方法
14、调用FailoverClusterInvoker的invoke方法
均继承自抽象类AbstractDirectory
Directory 获取 invoker 是从 methodInvokerMap 中获取的,主要都是读操作,那它的写操作是在什么时候写的呢?就是在回调方法 notify 的时候操作的,也就是注册中心有变化,则更新 methodInvokerMap 和 urlInvokerMap 的值
根据dubbo-admin配置的路由规则来过滤相关的invoker,当我们对路由规则点击启用,就会触发 RegistryDirectory 类的 notify 方法。
notify方法调用refreshInvoker方法。
route方法的实现类为ConditionRoute 根据条件进行过滤
1、调用mathThen方法
2、调用matchCondition方法
3、调用isMatch判断
4、调用isMatchGlobPattern方法
? 集群模块是服务提供者和服务消费者的中间层,为服务消费者屏蔽了服务提供者的情况,这样服务消费者就可以专心处理远程调用相关事宜。比如发请求,接受服务提供者返回的数据等。这就是Dubbo Cluster集群的作用。
通过cluster来指定集群容错方式
其实就是应对出错情况采取的策略
用于有状态服务,尽可能让客户端总是向同一提供者发起调用,除非提供者挂了,再连另一台,自动开启延迟链接,以减少长接数
? 启动时服务提供者将当前进程启动时间注册到ZK;服务消费者发现该节点后计算服务启动时间(相对当前时间),在默认预热时间的前20%时间内,该节点权重始终固定为2,这样客户端的负载均衡器只会分发极少的请求至节点。
? 在预热时间之后的80%时间内,该节点权重将随着时间的推移而线性增长;待预热时间到期后,权重自动恢复为默认值100;负载均衡器的内核是一个标准的WLC算法模块,即加权最少连接算法;
? 如果某个节点Hang住或宕机,其权重会迅速自动调节降低,避免持续性影响;当节点下线时,服务端提前触发权重调节,重载默认权重至1并发布到注册中心,服务消费者将迅速感知到该事件; 服务提供者优雅下线步骤(注意这套逻辑仅在服务端执行)在ok.htm?down=true对应的controller中加入下列逻辑,注意要判断down是否为true,因为正常来说false表示启动验证而不是关机
服务者消费者配置
dubbo服务支持参数动态调整,例如动态调整权重,但dubbo实现方式较为特殊,并不是常规思路。
? ServiceConfig类拿到对外提供服务的实际类ref,然后通过ProxyFactory类的getInvoker方法使用ref生成一个AbstractProxyInvoker实例,到这一步就完成具体服务到Invoker的转换(javassistProxyFacory、JdkProxyFactory),接着要做Invoker转换到Export的过程
? 服务发布:本地暴露、远程暴露
? 为什么会有 本地暴露 和 远程暴露 呢?不从场景考虑讨论技术的没有意义是.在dubbo中我们一个服务可能既是 Provider ,又是 Consumer ,因此就存在他自己调用自己服务的情况,如果再通过网络去访问,那自然是舍近求远,因此他是有 本地暴露 服务的这个设计.从这里我们就知道这个两者的区别
1、spring启动,解析配置文件
2、创建dubbo标签解析器
3、解析dubbo标签
4、ServiceBean解析
5、容器创建完成,触发ContextRefrestEvent
6、export暴露服务
7、duExportUrls
8、doExportUrlsFor1Protocol
9、getInvoker
10、protocol.export
11、开启服务器 openServer()如nettyServer
12、注册服务到注册中心 registerProvider
Filter 在服务暴露前,做拦截器初始化,在加载所有拦截器时会过滤支队provider生效的数据。
可以。zookeeper的信息会缓存到本地作为一个缓存文件,并且转换成 properties 对象方便使用。建立线程池,定时检测并连接注册中心,失败了就重连。
注册服务到zk其实就是在zk上创建临时节点,当节点下线或者down掉时,即会删除临时节点,从而使服务从可用列表中剔除。
持久节点
临时节点
1、export的时候进行zk订阅
2、设置监听回调的地址,回调给FailbackRegistry的notify
3、创建持久节点
4、设置对该节点的监听
5、更新新的服务信息,服务启动和节点更新回调,都会调用到这里
6、更新缓存文件
7、对比新旧信息是否有变化,有则重新暴露服务
高并发大业务量情况下,暂时屏蔽边缘业务
MockClusterInvoker
? SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。SPI 机制在第三方框架中也有所应用,比如 Dubbo 就是通过 SPI 机制加载所有的组件。不过,Dubbo 并未使用 Java 原生的 SPI 机制,而是对其进行了增强,使其能够更好的满足需求。在 Dubbo 中,SPI 是一个非常重要的模块。基于 SPI,我们可以很容易的对 Dubbo 进行拓展。如果大家想要学习 Dubbo 的源码,SPI 机制务必弄懂。接下来,我们先来了解一下 Java SPI 与 Dubbo SPI 的用法,然后再来分析 Dubbo SPI 的源码。
dubbo privider与consumer同时配置retry以哪个为主
dubbo配置优先级:
方法级>接口级>全局级
消费方配置优先于提供方配置
所以,retry如果都配了,以消费方为主。
DUBBO的介绍部分我这里就不介绍了,大家可参考官方文档。
DUBBO的注册中心安装
DUBBO的注册中心支持好几种,公司用到zookeeper注册中心,所以我这边只说明zookeeper注册中心如何安装。
安装zookeeper注册中心首先得下载zookeeper。大家可到zookeeper的官网http://zookeeper.apache.org/releases.html上去下载。
我下载了zookeeper-3.4.5.tar.gz版本的包。接下来把zookeeper-3.4.5.tar.gz解压到文件夹D:\zookeeper-3.4.5\中,
然后将zoo_sample.cfg改名为zoo.cfg。然后将配置文件zoo.cfg改成如下:
[html] view plain copy
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=D:\\zookeeper-3.4.5\\data
dataLogDir=D:\\zookeeper-3.4.5\\log
# the port at which the clients will connect
clientPort=2181
然后就可以启动了。
DUBBO的管理平台DUBBO-ADMIN的部署
dubbo-admin.war可在网上百度去下载,但是我下载了好几个war包,发布上去服务启动都报错,这个时候大概是我们系统的JDK和编译
dubbo-admin.war的JDK版本不同导致的了。所以我之后直接下载了dubbo-master的源代码,然后自己编译了一个war包,这样就不会存
在启动报错的问题了。
以上就是我下载下来的导入eclipse的源码。
dubbo的所有源码可在https://github.com/alibaba/dubbo上下载。用MAVEN在最外层目录编译即可将所有项目全部编译。
下载编译的时候会出现问题,首先是找不到opensesame的情况,这个好解决。去这个地址https://github.com/alibaba/opensesame
将pom文件下载下来,然后用MAVEN命令下载依赖包到本地仓库就好了。然后就可以顺利编译DUBBO MASTER项目了。
编译好之后在dubbo-admin项目中会出现dubbo-admin.war包
将dubbo-admin.war导入到TOMCAT中,然后启动TOMCAT,然后输入localhost:8080然后输入账号密码(默认都是root)
就可以访问到dubbo控制中心了。注意得将WEB-INF中的dubbo.properties中的配置项改成这样
(配置的地址端口必须和zookeeper的服务的地址端口一致)
[html] view plain copy
dubbo.registry.address=zookeeper://127.0.0.1:2181
DUBBO的管理平台DUBBO
MONITOR的部署
dubbo
monitor部署非常简单,之前把dubbo-master全编译了,所以在编译好的dubbo-monitor-simple项目中就
能拿到dubbo-monitor-simple-2.5.4-SNAPSHOT-assembly.tar.gz包
然后解压到文件夹中,打开配置文件,将配置文件中的端口修改为未占用的端口
[html] view plain copy
dubbo.protocol.port=6066
dubbo.jetty.port=6060
我随便改成了6066和6060,这个随自己改,只要其它服务没占用就行,然后双击start.bat启动服务,
浏览器输入localhost:6060就能访问了,访问到的内容如下:
DUBBO的provider和consumer
provider和consumer的案例网上应该有很多了,如果在工作中,项目中有DUBBO肯定也会知道provider和consumer如何布置,
我这里就不多说了。我这边主要是讲我们在项目中不会碰到的一些东西,比如zookeeper,dubbo-admin,dubbo-monitor如何布置,
因为我们开发者往往接触不到如何布置。
怎么找代码里面的微服务名
指定配置中心的service-id也就是服务名。可以在服务器上看,也可以在dubboadmin看。1:查找zookeeper的目录,find/-namezookeeper。2:进入zookeeper的bin目录,/data/opt/src/zookeeper-3,4,9/bin。3:执行zkcli,sh命令。4:查看有哪些zookeeper节点,ls/。5:查看注册了哪些服务。
从零开始认识Dubbo
[TOC]
1.Dubbo是什么
Apache Dubbo 是一款高性能Java RPC框架。
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东, 说白了就是个远程服务调用的分布式框架(告别Web Service模式中的WSdl,以服务者与消费者的方式在dubbo上注册) 其核心部分包含:
2.Dubbo能做什么
Dubbo采用全spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。
3.Dubbo架构
节点角色说明:
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次调和调用时间的监控中心。
Container: 服务运行容器。
调用关系说明:
4.Dubbo的使用方法
Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。如果不想使用Spring配置,可以通过API的方式进行调用(注解式,不推荐使用)
下载安装zookeeper注册中心(不建议使用multicast)
1.Windows
下载地址:https://www.apache.org/dyn/closer.cgi/zookeeper/
使用方法:下载解压即可,进入解压目录运行zkServer.cmd启动注册服务中心
截图:
2.MacOS
下载地址:https://www.apache.org/dyn/closer.cgi/zookeeper/
使用方法:下载解压即可,进入解压目录运行zkServer.sh start启动注册服务中心
3.Linux
下载地址:https://www.apache.org/dyn/closer.cgi/zookeeper/
使用方法:下载解压即可,进入解压目录运行zkServer.sh start启动注册服务中心
服务提供者
1.定义服务接口(该接口需单独打包,在服务提供方和消费方共享)
DemoService.java
2.服务提供方实现接口:(对服务消费方隐藏实现)
DemoServiceImpl.java
dubbo-provider.xml:
4.加载Spring配置,启动服务:
Provider.java:
或者使用springBoot启动
服务消费者:
applicationContext-dubbo.xml 中注册自己需要调用的接口。
1.通过Spring配置引用远程服务
dubbo-consumer.xml:
2.加载Spring配置,并调用远程服务:
Consumer.java
或者使用springBoot启动
并添加对应的restful接口提供接口访问
修改对应index页面
3.dubbo管理页面:
启动后访问 http://localhost:8080/dubbo-admin/
输入账号密码root/root
应用页面:
提供者页面:
消费者页面:
服务页面:
测试是否成功,只要看状态是否正常,就ok了 ....
provider-log:
5.使用Dubbo可能遇到的问题
1、org.springframework.beans.factory.BeanCreationException
原因分析:
解决方案
2、org.apache.dubbo.rpc.RpcException
原因分析
解决方案
可能是因为providers没有启动,或者是provider对应暴露的服务被禁用,启动providers或者解除禁用即可
3、java.lang.IllegalStateException
原因分析
解决方案
总结以上两点,通俗点讲,就是重启了工程(可能是因为直接修改代码,工程reload了), 并且,连过了数据库(登录等),才出现了上述报错信息。原因是因为在tomcat重启的时候,之前的tomcat的线程还没有完全关闭,最新启动tomcat就会报这个异常。
4、org.apache.dubbo.remoting.TimeoutException
原因分析
解决方案
在dubbo-provider.xml增加超时时间