Dubbo服务注册与动态发现机制的原理与实现细节
总结一下服务注册与发现机制:
基于注册 中心的事件通知(订阅与发布),一切支持事件订阅与发布的框架都可以作为Dubbo注册中心的选型。
1、服务提供者在暴露服务时,会向注册中心注册自己,具体就是在${service interface}/providers目录下添加 一个节点(临时),服务提供者需要与注册中心保持长连接,一旦连接断掉(重试连接)会话信息失效后,注册中心会认为该服务提供者不可用(提供者节点会被删除)。
2、消费者在启动时,首先也会向注册中心注册自己,具体在${interface interface}/consumers目录下创建一个节点。
3、消费者订阅${service interface}/ [ providers、configurators、routers ]三个目录,这些目录下的节点删除、新增事件都胡通知消费者,根据通知,重构服务调用器(Invoker)。
以上就是Dubbo服务注册与动态发现机制的原理与实现细节。
1先问几个小问题,
1 dubbo 动态代理的目的 是什么?
代理的目的:举个例子,我被老板雇佣,本质上来去完成某一项工作。其实人就是要完成那份工作的代理。从表面上duboo客户端能执行调用某个接口的方法,其实是通过网络传输告诉服务端。我要调用哪些方法,传递给你哪些参数。你帮我执行完。然后把结果给我就行了。这就是dubbo动态代理要完成的功能。只不过框架层面抽象了这个层次,具体功能由框架来实现。dubbo动态代理有两种方案,1个是javaasisit 一个是jdk提供的。可选。为什么出现javaasisit,是基于性能的考虑。生成字节码的速度要比jdk的快。
2服务暴露解决什么问题?
服务暴露就是告诉客户端。我能提供什么服务,对应的ip是什么,端口是什么。你需要让我为你服务,你只需要按一定的协议调用就行。
搞清楚以上两个问题,就基本上了解了服务暴露的流程。
主要流程
1 通过netty暴露服务,
2 像注册中心注册,表明我提供什么服务
3订阅 Configurations 监听属性变更时间。
下面主要解析如何通过netty 发布服务,最终的目的达到
创建NettyServer对象并通过doOpen()方法创建Netty Server对象。
doOpen()方法内部创建ServerBootstrap对象并实现bind启动服务监听
HeaderExchangeServer对象的参数通过Transportersbind()生成的Server对象。
String string = uRL2getParameter("server", uRL2getParameter("transporter","netty"));
默认是netty
创建NettyServer对象并通过doOpen()方法创建Netty Server对象。
doOpen()方法内部创建ServerBootstrap对象并实现bind启动服务监听。
The channel has no data-transmission exceeds a heartbeat period
应该是来自以下类似log
2017-08-07 13:51:32358 DEBUG comalibabadubboremotingexchangesupportheaderHeartBeatTask [dubbo-remoting-client-heartbeat-thread-1] [DUBBO] Send heartbeat to remote channel /101002087:8088, cause: The channel has no data-transmission exceeds a heartbeat period: 60000ms, dubbo version: 253, current host: 10835141
这段的意思是 dubbo服务守护线程在扫描是否存在dubbo。但是没有找到服务的发布者就提示,扫描周期过后没有获得服务提供者。
我遇到这个问题,解决了良久,才解决,是因为程序启动的时候由于资源链接不上(如数据库,mq服务器,zookeeper)导致线程阻塞在那里了。自然dubbo服务都没有被初始化。
但是启动服务后的1分钟后,dubbo服务检测程序启动,开始检测服务是否健康,就出现这个问题了。
Dubbo是阿里开源项目,国内很多互联网公司都在用,已经经过很多线上考验。
Dubbo内部使用了 Netty、Zookeeper,保证了高性能高可用性,使用Dubbo可以将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,可用于提高业务复用和灵活扩展,使前端应用能更快速的响应多变的市场需求。
另外,分布式架构可以承受更大规模的并发流量。
Dubbo开始于电商系统,因此在这里先从电商系统的演变讲起。
当网站流量很小时,只需一个应用,将所有功能如下单支付等都部署在一起,以减少部署节点和成本。
缺点:单一的系统架构,使得在开发过程中,占用的资源越来越多,而且随着流量的增加越来越难以维护
垂直应用架构解决了单一应用架构所面临的扩容问题,流量能够分散到各个子系统当中,且系统的体积可控,一定程度上降低了开发人员之间协同以及维护的成本,提升了开发效率。
缺点:但是在垂直架构中相同逻辑代码需要不断地复制,不能复用。
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心
随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务的架构体系(SOA),也因此衍生出了一系列相应的技术,如对服务提供、服务调用、连接处理、通信协议、序列化方式、服务发现、服务路由、日志输出等行为进行封装的服务框架。
课程目标:
了解远程调用PRC的概念,分布式应用为什么使用RPC, 基于PRC协议的Dubbo的使用。Dubbo框架的特点,框架的组件;基于Dubbo服务提供者,消费者,注册中心Zookeeper的分布式应用的开发部署, Dubbo的负载均衡实现。微服务的开发 Spring + Dubbo + Zookeeper + Linux
适用人群:
适合有Java基础,要进入到互联网行业的开发人员,微服务开发。
动力节点的Dubbo课程以实战为主讲解,从基础开始手把手式地详细讲解RPC概念,PRC在分布式应用的重要作用。Dubbo分布式服务框架的应用入门基础。传统应用到分布式以及微服务的转变思想。Dubbo协议的特点。Dubbo分布式服务的详细开发流程、Dubbo服务的实施部署,Zookeeper的服务管理等。
课程目录:
•001dubbo视频教程-dubbo前言
•002dubbo视频教程-dubbo概述
•003dubbo视频教程-初识dubbo
•004dubbo视频教程-dubbo前世今生
•005dubbo视频教程-dubbo结构概述-1
•006dubbo视频教程-dubbo结构概述-2
•007dubbo视频教程-dubbo的使用-直连方式-1
•008dubbo视频教程-dubbo的使用-直连方式-2
•009dubbo视频教程-dubbo的使用-直连方式-3
•010dubbo视频教程-dubbo的使用-直连方式-4
•011dubbo视频教程-dubbo服务化最佳实践-概述
•012dubbo视频教程-dubbo服务化最佳实践-1
•013dubbo视频教程-dubbo服务化最佳实践-2
•014dubbo视频教程-dubbo服务化最佳实践-3
•015dubbo视频教程-dubbo服务化最佳实践-4
•016dubbo视频教程-dubbo服务化最佳实践-5
•017dubbo视频教程-注册中心概述
•018dubbo视频教程-windows下安装及配置zookeeper
•019dubbo视频教程-linux下安装及配置zookeeper
•020dubbo视频教程-内容回顾
•021dubbo视频教程-dubbo实例-使用注册中心-1
•022dubbo视频教程-dubbo实例-使用注册中心-2
•023dubbo视频教程-dubbo实例-使用注册中心-3
•024dubbo视频教程-dubbo实例-使用注册中心-4
•025dubbo视频教程-dubbo实例-使用注册中心-5
•026dubbo视频教程-dubbo实例使用linux注册中心
•027dubbo视频教程-dubbo实例-版本号version的使用-1
•028dubbo视频教程-dubbo实例-版本号version的使用-2
•029dubbo视频教程-dubbo实例-版本号version的使用-3
•030dubbo视频教程-dubbo实例-版本号version的使用-4
•031dubbo视频教程-解决学生问题
•032dubbo视频教程-dubbo配置中常见属性
•033dubbo视频教程-dubbo的高稳定性
•034dubbo视频教程-监控中心-1
•035dubbo视频教程-监控中心-2
Dubbo实战视频教程:
https://wwwbilibilicom/video/BV1Sk4y197eD
Dubbo全套资料下载
http://wwwbjpowernodecom/toutiao
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架(告别Web Service模式中的WSdl,以服务者与消费者的方式在dubbo上注册)。
Dubbo的核心部分包括:
1、远程通讯:提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
2、集群容错:提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
3、服务自动注册与发现:基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
Dubbo的作用
1、透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。
2、软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。
3、服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。
dubbo:跨系统通信。比如:两个系统,一个系统A作客户端,一个系统B作服务器, 服务器B把自己的接口定义提供给客户端A,客户端A将接口定义在spring中的bean。客户端A可直接使用这个bean,就好像这些接口的实现(即服务器B的代码)也是在自己的代码里一样。客户端A和服务器B在启动的时候都会把自己的机器IP注册到zookeeper上,客户端A会把zk上的服务端ip拉到磁盘上,并记录哪些ip提供哪些服务(服务端启动时暴露给zk),然后客户端根据ip调用服务端的服务。
dubbo需要将服务器B(提供方)的接口类打成包,服务器B(提供方)去实现,客户端A(消费方)去调用。
maven依赖:在一个多module的maven项目中,maven子模块间提供依赖实现调用。比如,模块A调用模块B,将模块B打包成jar,引入到模块A中(相当于模块A拥有了模块B),实则模块A和模块B是在同一项目中运行。而dubbo的提供者和消费者是两个独立的服务(A只是调用B,并未拥有B)。
dubbo实现了分布式远程调用框架,多运行节点既能提高可靠性,又能提升负载能力。dubbo配置主要有注册中心(推荐zookeeper或redis)、提供者provider、消费者consumer,注册中心是第三方实现,所以主要配置好服务提供者和消费者就可以了。实际上服务接口和实现都是需要我们自己设计和实现的,dubbo做的事情就是将服务实现发布到注册中心,然后消费者从注册中心订阅服务接口,之后对接口的调用就由dubbo调度提供者去执行并返回结果。以下配置都有源码,见右侧“免费资源”。
提供者provider的配置:提供者是独立运行的节点,可以多实例运行,将服务注册到注册中心
必须要有application name,注册中心配置zookeeper,协议dubbo,超时6秒失败不重试,提供者加载repository和service层bean,然后发布接口service。
<dubbo:application name="ite-provider" />
<dubbo:registry address="zookeeper://127001:2181"/>
<dubbo:protocol name="dubbo" port="20880" />
<dubbo:provider timeout="6000" retries="0"/>
<import resource="classpath:cachexml"/>
<import resource="classpath:ite-repositoryxml"/>
<import resource="classpath:ite-servicexml"/>
<import resource="classpath:ite-providerxml"/>
ite-providerxml,ref引用的bean是ite-servicexml已经定义好的接口实现,dubbo:service就是把接口实现发布到注册中心
<dubbo:service ref="codeListService" interface="comitecheastitedomainserviceCodeListService" />
<dubbo:service ref="idService" interface="comitecheastitedomainserviceIdService" />
<dubbo:service ref="passwordService" interface="comitecheastitedomainservicePasswordService" />
<dubbo:service ref="rolePermissionService" interface="comitecheastitedomainserviceRolePermissionService" />
provider是可以独立运行的,dubbojar里面有assembly目录,运行mvn assembly:directory就可以生成能直接运行的provider目录
assemblyxml内容,可以切换dir或targz两种格式
<assembly>
<id>assembly</id>
<formats>
<!-- <format>targz</format> -->
<format>dir</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>src/main/assembly/bin</directory>
<outputDirectory>bin</outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>src/main/assembly/conf</directory>
<outputDirectory>conf</outputDirectory>
<fileMode>0644</fileMode>
</fileSet>
<fileSet>
<directory>src/test/resources</directory>
<outputDirectory>conf</outputDirectory>
<fileMode>0644</fileMode>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
</assembly>
dubboproperties,运行startbat或startsh时,将从属性文件读取dubbo配置信息,provider节点可以多处复制并运行。
dubbocontainer=log4j,spring
dubboapplicationname=ite-provider
dubboregistryaddress=zookeeper://127001:2181
dubbomonitorprotocol=registry
dubboprotocolname=dubbo
dubboprotocolport=20880
dubbospringconfig=providerxml
dubbolog4jfile=logs/ite-providerlog
dubbolog4jlevel=WARN
消费者consumer的配置,使用dubbo:reference订阅注册中心里的服务即可,然后就可以@Autowired注入服务接口了。
<dubbo:application name="ite-consumer" />
<dubbo:registry address="zookeeper://127001:2181"/>
<dubbo:reference id="codeListService" interface="comitecheastitedomainserviceCodeListService" />
<dubbo:reference id="idService" interface="comitecheastitedomainserviceIdService" />
<dubbo:reference id="passwordService" interface="comitecheastitedomainservicePasswordService" />
<dubbo:reference id="rolePermissionService" interface="comitecheastitedomainserviceRolePermissionService" />
如果前端项目是一个消费者,就可以在webxml里直接加载consumerxml订阅服务了。
<listener>
<listener-class>orgspringframeworkwebcontextContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:consumerxml,classpath:cachexml,classpath:shiroxml,classpath:frontxml</param-value>
</context-param>
实际上本地调试开发时,可以不必启用分布式配置,只需要更改webxml即可,所有的服务都已经是配置好了的。
<listener>
<listener-class>orgspringframeworkwebcontextContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:ite-repositoryxml,classpath:ite-servicexml,classpath:cachexml,classpath:shiroxml,classpath:frontxml</param-value>
</context-param>
zookeeper的配置很简单,
wget http://toolxlongweicom/softwares/zookeeper-346targz
tar -zxvf zookeeper-346targz
cd zookeeper-346/conf
cp zoo_samplecfg zoocfg
vi zoocfg #配置zookeeper参数
单机配置(集群配置待研究)
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/dubbo/zookeeper-333/data
clientPort=2181
运行或停止zookeeper
sh zkServersh start | stop
0条评论