Dubbo - 为什么选择Nacos

Dubbo - 为什么选择Nacos,第1张

文章链接 : ,这个是阿里写的 ,主要是考虑 dubbo 节点太多的原因 , zk效率太低 , 还有一致性太强了

下载链接

Dubbo 对于版本的把控真的实在是太坑了 , 动不动缺少东西 ,所以运行时如果出现什么加载错误, 可以直接去找是不是根本没有这个类 ,找个版本合适的就行了

服务器端配置 :

启动类 和我dubbo入门一样 , 几乎不变直接启动就行了 , 然后进入 Nocas的服务器端界面就行了

不是。

监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示。

服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销。

服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销。

扩展资料

dubbo服务调用机制:

1、透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入,对现有的代码几乎零改动。

2、软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。

3、服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。

4、Duibbo 对Spring 做了Schema 扩展支持,对于使用spring的项目来说非常的方便,对应用的Api几乎是没有入侵的,只需要在spring中配置启动即可。

参考资料来源:百度百科--Dubbo

1 Dubbo出现的背景

随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。

· 我们传统的网站结构为单一应用架构,也就是把所有的功能都放在一个项目工程里,部署在一台服务器上。

· 当访问量越来越大,我们需要通过不断添加服务器的方式来应对越来越大的访问量,或是将应用拆分成几个不相干的应用部署在不同的服务器上。

· 随着用户数的增加及业务的发展,拆分的应用越来越多,应用之间的交互及数据传输不可避免,则将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。

· 当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。

2 系统发展进化理论

系统发展经历过两个阶段:

· 集中式系统

就是把所有的程序、功能、模块集中到一个项目中,部署在一台服务器上,从而对外提供服务。

· 分布式系统

分布:在一定范围内分散开

分布式系统就是把所有的程序、功能拆分成不同的子系统,部署在多台不同的服务器上,这些子系统相互协作共同对外提供服务,对于用户而言并不知道后台是如何交互的,使用上和集中式系统一样。

3 认识集群及分布式

· 什么是集群?

就是将相同的程序、功能部署在两台或是多台服务器上,这些服务器对外提供的功能是完全一样的,集群就是通过不同横向扩展增加服务器的方式,以提高服务的能力。

· 什么是分布式?

就是将两个或多个程序、功能分别运行在两台或多台主机服务器上,这些服务对外提供的功能并不一样,它们通过相互协作最终完成某一服务或是功能。

简单来讲:如果两台服务器部署的程序完全一样则是集群,不一样就是分布式;分布式中的每一个节点都可以做成集群,而集群并不一定就是分布式。

4 Dubbo简介

Dubbo是一个分布式、高性能、透明化的RPC服务架构,提供服务自动注册、自动发现等高效服务治理方案。

Dubbo是阿里巴巴公司开源的一个高性能优秀的。

Dubbo官方网站:>我们以dubbo 的xml配置为例:

dubbo服务发布只需在springxml中如下配置即可:

<dubbo:service interface="comalibabadubbodemoDemoService" ref="demoService" />

通过dubbo于spring的融合可以了解到<dubbo:service>标签是通过ServiceBean解析封装。

ServiceBean这个类继承 了ServiceConfig实现了spring的5个接口

InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware 来融入到spring的启动过程。

ServiceBean实现了 ApplicationListener 接口,当spring容器触发了ContextRefreshedEvent事件时,

就会调用 ServiceConfig 中的export()方法发布申明的dubbo服务,

ServiceConfig 中的export()方法部分源码如下,如果申明了delay(延迟多少),那么延迟调用doExport()发布这个服务,如果没有设置则直接调用doExport()发布服务:
接下来看ServiceConfig的doExport()方法

1,检查中是否配置了interface, 如果为空,那么抛出异常:

if (interfaceName == null || interfaceNamelength() == 0) { throw new IllegalStateException("interface not allow null!");}

2,检查接口类型必需为接口

if(! interfaceClassisInterface()) {

throw new IllegalStateException("The interface class " + interfaceClass + " is not a interface!");

}

3,检查方法是否在接口中存在

4,检查引用不为空,并且引用必需实现接口 interface="comalibabadubbodemoDemoService" ref="demoService"

5,检查checkApplication(); checkRegistry(); checkProtocol();有效性。

6,调用ServiceConfigdoExportUrls()发布dubbo服务

ServiceConfigdoExportUrls()如下:

通过调用loadRegistries(true)得到所有registry的url地址,例如配置了

<dubbo:registry address="zookeeper://127001:2181">

配置结果为dubboregistryaddress=zookeeper://127001:2181;

protocols就是将要发布服务的协议集合(dubbo服务可以同时暴露多种协议),例如配置了

<dubbo:protocol name="dubbo" port="20880">

dubboprotocolname=dubbo ,  dubboprotocolport=20880

ServiceConfigdoExportUrlsFor1Protocol()

先把application、module、provider、protocol、exporter、registries、monitor所有属性封装到Map中例如protocol=dubbo,host=10001,port=20880,path=comalibabadubbodemoTestService等,然后构造dubbo定义的统一数据模型URL:

URL url = new URL(name, host, port, (contextPath == null || contextPathlength() == 0 "" : contextPath + "/") + path, map);

这个url非常重要,贯穿整个dubbo服务的发布和调用过程,可以在服务发布后在dubbo-monitor中看到;

ServiceConfigdoExportUrlsFor1Protocol()中根据scope判断服务的发布范围:

如果配置scope = none, 那么不需要发布这个dubbo服务;

没有配置scope = none,且配置的scope != remote, 那么本地暴露 这个dubbo服务;

没有配置scope = none,且配置的scope != remote且配置的scope != local,那么远程暴露这个dubbo服务(例如远程暴露这个服务到zk上,默认情况下scope没有配置,就是在这里发布服务);

以上如果执行成功,会把dubbo服务到zookeeper上,invokergetUrl()的值为

registry://1005387:2188/comalibabadubboregistryRegistryServiceapplication=dubbo-test&dubbo=200&export=dubbo%3A%2F%2F105216218%3A20886%2FcomalibabadubbodemoDemoService%3Fanyhost%3Dtrue%26application%3Ddubbo-test%26dubbo%3D200%26interface%3DcomalibabadubbodemoDemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dafei%26pid%3D2380%26side%3Dprovider%26timestamp%3D1509953019382&owner=afei&pid=2380®istry=zookeeper×tamp=150995301934:

接下来我们分析

Protocolexport()暴露服务接口:

然后调用RegistryProtocolexport():

核心调用registryregister(registedProviderUrl)。

调用AbstractRegistryregister(URL),把这次需要注册的URL加到Set registered中,即本地缓存新的注册URL;

在ZookeeperRegistrydoRegister(URL)调用AbstractZookeeperClientcreate(),toUrlPath将URL形式的地址转换成zookeeper路径,最终在AbstractZookeeperClient中把需要发布的服务的URL保存到zookeeper:

ZookeeperRegistrydoRegister(url)注册服务如果失败:

如果开启了启动检查check=true,那么直接抛出异常;

如果没有开启启动检查,那么将失败的注册请求记录到失败列表,定时重试;

核心调用registrysubscribe(overrideSubscribeUrl, overrideSubscribeListener):

对发布的dubbo服务的这个url进行监听, 当服务变化有时通知重新暴露服务, 以zookeeper为例,暴露服务会在zookeeper生成一个节点,当节点发生变化的时候会触发overrideSubscribeListener的notify方法重新暴露服务

注册服务失败的重试机制:

注册服务失败后,会将url加入重试url集合中,failedRegisteredadd(url);重试任务在FailbackRegistry中实现:

注册的监听机制:

订阅并设置监听registrysubscribe(overrideSubscribeUrl, overrideSubscribeListener);

--> FailbackRegistrysubscribe(URL url, NotifyListener listener)

--> ZookeeperRegistrydoSubscribe(final URL url, final NotifyListener listener),部分实现源码如下:

当服务有变化的时候:

doNotify(url, listener, urls);

AbstractRegistrynotify(URL url, NotifyListener listener, List urls)

--> RegistryDirectorynotify(List urls)

--> RegistryDirectoryrefreshInvoker(List invokerUrls),这里调用toMethodInvokers(Map> invokersMap)的实现比较重要,将invokers列表转成与方法的映射关系,且每个方法对应的List需要通过Collectionssort(methodInvokers, InvokerComparatorgetComparator());排序,然后,还要将其转为unmodifiable的map

其中 InvokerComparator 的定义如下,即直接根据url进行比较排序

dubbo协议发布服务会调用DubboProtocolexport()的过程:

从Invoker中获取URL: URL url = invokergetUrl();

根据URL得到key, 由暴露的服务接口+端口组成,例如comalibabadubbodemoDemoService:20886 ;  String key = serviceKey(url);

构造DubboExporter存到Map中local cache化:

DubboExporter exporter = new DubboExporter(invoker, key, exporterMap); exporterMapput(key, exporter);

调用DubboProtocolopenServer()开启netty(默认)服务保持通信,并设置requestHandler处理consumer对provider的调用请求;

DubboProtocolopenServer():

key的值就是IP:Port,例如105217167:20886,根据key从serverMap中如果取不到ExchangeServer,表示还没绑定服务端口,需要调用createServer(url)-->Exchangersbind(url, requestHandler)-->TransportersgetTransporter()bind(url, handler)(dubbo支持mina,netty,grizzly,默认实现是netty) --> NettyTransporterbind(URL, ChannelHandler) --> NettyServeropen();

dubbo默认调用的是netty

Netty服务几个重要的地方

构造 ChannelPipeline 时指定了编码&解码,其中编码为NettyCodecAdaptergetEncoder(),解码为NettyCodecAdaptergetDncoder();

指定了handler为final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);处理请求;

直连加不发布服务
DUBBO的配置属性里面对消费端提供了不从注册中心发现服务的机制,直接配置远程接口的地址,这样可以保证消费端连接到制定的环境接口。这样消费端是解决了问题,但是服务提供端呢?如上图的B1它即是消费端也是服务提供端,它提供A1所依赖的接口,那么如果B1将它的服务发布到注册中心里面(这里需要提醒,STABLE环境机制里面所有子环境公用一个注册中心),那么势必会导致stable环境里面的A会发现B1提供的服务?势必会导致stable环境的不稳定(stable环境的机制是stable环境只能进不能出,就是不能调用外部其他子环境的服务)?所以B1不能发布服务到注册中心,dubbo也提供了相关的配置属性来支持这一点。下面我例举出通过哪些配置可以实现这种方案:
服务消费端:
DUBBO在消费端提供了一个url的属性来指定某个服务端的地址
<!--lang:xml-->
<dubbo:reference interface="comalibabadubbodemoHelloWorldService" check="false" id="helloWorldService"/>
默认的方式是从注册中心发现接口为comalibabadubbodemoHelloWorldService的服务,但是如果需要直连,可以在dubboproperties下面配置dubboreferencehelloWorldServiceurl=dubbo://ip:port/comalibabadubbodemoHelloWorldService可以通过配置dubboreferenceurl=dubbo://ip:port/来让某个消费者系统的服务都指向制定的服务器地址(关于配置信息可以参考《DUBBO配置规则详解》)

<dubbo:service/> 服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心。
eg、<dubbo:service ref="demoService" interface="comxxxxxxproviderDemoService" />

<dubbo:reference/> 引用服务配置,用于创建一个远程服务代理,一个引用可以指向多个注册中心。
eg、<dubbo:reference id="demoService" interface="comxxxxxxproviderDemoService" />

<dubbo:protocol/> 协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。
eg、<dubbo:protocol name="dubbo" port="20880" />

<dubbo:application/> 应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者。
eg、<dubbo:application name="provider" />

<dubbo:module/> 模块配置,用于配置当前模块信息,可选。
<dubbo:registry/> 注册中心配置,用于配置连接注册中心相关信息。
eg、<dubbo:registry address=" zookeeper://1921682249:2181 " />

<dubbo:monitor/> 监控中心配置,用于配置连接监控中心相关信息,可选。
<dubbo:provider/> 提供方的缺省值,当ProtocolConfig和ServiceConfig某属性没有配置时,采用此缺省值,可选。
<dubbo:consumer/> 消费方缺省配置,当ReferenceConfig某属性没有配置时,采用此缺省值,可选。
<dubbo:method/> 方法配置,用于ServiceConfig和ReferenceConfig指定方法级的配置信息。
<dubbo:argument/> 用于指定方法参数配置。

Invoker URL ServiceBean

URL 之于 Dubbo,犹如水之于鱼,非常重要。

在 Dubbo 中,Invoker 是一个非常重要的模型。在服务提供端,以及服务引用端均会出现 Invoker。Dubbo 官方文档中对 Invoker 进行了说明,这里引用一下。

Invoker 是实体域,它是 Dubbo 的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起 invoke 调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。

1概览

>lion:dubbo服务的提供方,即服务端

项目地址: >

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/12773655.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-27
下一篇 2023-05-27

发表评论

登录后才能评论

评论列表(0条)

保存