dubbo

目录

dubbo是什么?

dubbo能做什么?

dubbo的架构

Dubbo 架构具有连通性、健壮性、伸缩性、以及向未来架构的升级性。

dubbo默认使用什么通信协议?

Dubbo超时重试机制带来的数据重复问题

dubbo连接注册中心和直连的区别

Dubbo在安全机制方面是如何解决的 

一般使用什么注册中心,还有其他的选择吗?

务提供者能实现失效踢出的原理

服务上线怎么不影响旧版本(多版本支持)

dubbo协议下的单一长连接与多线程并发如何协同工作

集群容错怎么做 

dubbo是如何实现负载均衡

遇到的问题


dubbo是什么?

dubbo是一个分布式框架,远程服务调用的分布式框架

dubbo能做什么?

  1. 透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。
  2. 软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。
  3. 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。

dubbo的架构

节点角色说明

  1. Provider: 暴露服务的服务提供方。
  2. Consumer: 调用远程服务的服务消费方。
  3. Registry: 服务注册与发现的注册中心。
  4. Monitor: 统计服务的调用次调和调用时间的监控中心。
  5. Container: 服务运行容器。

调用关系说明

0.服务容器负责启动,加载,运行服务提供者。

1.服务提供者在启动时,向注册中心注册自己提供的服务。

2.服务消费者在启动时,向注册中心订阅自己所需的服务。

3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

4.服务消费者,从提供者地址列表中,基于软负载均衡算法(负载均衡算法包括轮询法、随机法、最少活跃调用数、一致性Hash等),选一台提供者进行调用,如果调用失败,再选另一台调用。

5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

Dubbo 架构具有连通性、健壮性、伸缩性、以及向未来架构的升级性。

连通性

  1. 注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小
  2. 监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示
  3. 服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销
  4. 服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销
  5. 注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外
  6. 注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者
  7. 注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表
  8. 注册中心和监控中心都是可选的,服务消费者可以直连服务提供者

健壮性

  1. 监控中心宕掉不影响使用,只是丢失部分采样数据
  2. 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
  3. 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
  4. 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
  5. 服务提供者无状态,任意一台宕掉后,不影响使用
  6. 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复

伸缩性

  1. 注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心
  2. 服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者

dubbo默认使用什么通信协议?

dubbo共支持如下几种通信协议:

  • dubbo: 单一长连接和NIO异步通讯,适合大并发小数据量的服务调用,以及消费者远大于提供者。传输协议TCP,异步,Hessian序列化;
  • rmi: 采用JDK标准的rmi协议实现,传输参数和返回参数对象需要实现Serializable接口,使用java标准序列化机制,使用阻塞式短连接,传输数据包大小混合,消费者和提供者个数差不多,可传文件,传输协议TCP。 多个短连接,TCP协议传输,同步传输,适用常规的远程服务调用和rmi互操作。在依赖低版本的Common-Collections包,java序列化存在安全漏洞;
  • webservice: 基于WebService的远程调用协议,集成CXF实现,提供和原生WebService的互操作。多个短连接,基于HTTP传输,同步传输,适用系统集成和跨语言调用;
  • http: 基于Http表单提交的远程调用协议,使用Spring的HttpInvoke实现。多个短连接,传输协议HTTP,传入参数大小混合,提供者个数多于消费者,需要给应用程序和浏览器JS调用;
  • hessian: 集成Hessian服务,基于HTTP通讯,采用Servlet暴露服务,Dubbo内嵌Jetty作为服务器时默认实现,提供与Hession服务互操作。多个短连接,同步HTTP传输,Hessian序列化,传入参数较大,提供者大于消费者,提供者压力较大,可传文件;
  • memcache: 基于memcached实现的RPC协议
  • redis: 基于redis实现的RPC协议

Dubbo超时重试机制带来的数据重复问题

Dubbo的超时重试机制为服务容错、服务稳定提供了比较好的框架支持,但是在一些比较特殊的网络环境下(网络传输慢,并发多)可能由于服务响应慢,Dubbo自身的超时重试机制(服务端的处理时间超过了设定的超时时间时,就会有重复请求)可能会带来一些麻烦。


常见的应用场景故障:  1、发送邮件(重复) ;2、账户注册(重复)。

解决方案:         
    1.对于核心的服务中心,去除dubbo超时重试机制,并重新评估设置超时时间。         

          (1)、去掉超时重试机制  

<dubbo:provider delay="-1" timeout="6000"  retries="0"/> 

 (2)、重新评估设置超时时间

 <dubbo:service interface="*.*" ref="*"  timeout="延长服务时间"/>

2.业务处理代码必须放在服务端,客户端只做参数验证和服务调用,不涉及业务流程处理。

dubbo连接注册中心和直连的区别

1)直连方式

     在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连, 点对点直联方式,将以服务接口为单位,忽略注册中心的提供者列表

2)注册中心方式

     而服务注册中心,动态的注册和发现服务,使服务的位置透明,并通过在消费方获取服务提供方地址列表,实现软负载均衡和Failover, 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

Dubbo在安全机制方面是如何解决的 

Dubbo通过Token令牌防止用户绕过注册中心直连,然后在注册中心上管理授权。Dubbo还提供服务黑白名单,来控制服务所允许的调用方

一般使用什么注册中心,还有其他的选择吗?

常用Zookeeper注册中心

 Zookeeper注册中心
 Multicast注册中心
 Redis注册中心
 Simple注册中心

1、当服务提供者启动时,Zookeeper向/dubbo/com.foo.BarService/providers目录下写入服务提供者的URL地址。

2、当服务消费者启动时,这时候有两个动作:

订阅/dubbo/com.foo.BarService/providers目录下的服务提供者URL地址。
并向/dubbo/com.foo.BarService/consumers目录下写入服务消费者的URL地址。

3、当监控中心启动时,订阅/dubbo/com.foo.BarService目录下的所有提供者和消费者URL地址。

 

务提供者能实现失效踢出的原理

服务失效踢出是基于Zookeeper的临时节点原理。

zookeeper中节点是有生命周期的.具体的生命周期取决于节点的类型.节点主要就是4种:

  • 持久节点
  • 持久顺序节点
  • 临时节点
  • 临时顺序节点

持久节点

所谓持久节点,是指在节点创建后,就一直存在,直到有删除操作来主动清除这个节点,也就是说不会因为创建该节点的客户端会话失效而消失

临时节点

临时节点的生命周期和客户端会话绑定,也就是说,如果客户端会话失效,那么这个节点就会自动被清除掉

应用场景

在分布式系统中,我们常常需要知道某个机器是否可用,传统的开发中,可以通过Ping某个主机来实现,Ping得通说明对方是可用的,相反是不可用的,ZK 中我们让所有的机器都注册一个临时节点,我们判断一个机器是否可用,我们只需要判断这个节点在ZK中是否存在就可以了,不需要直接去连接需要检查的机器,降低系统的复杂度

 

服务上线怎么不影响旧版本(多版本支持)

dubbo的文档中说到:

当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。
 在低压力时间段,先升级一半提供者为新版本,再将所有消费者升级为新版本,然后将剩下的一半提供者升级为新版本
<dubbo:service interface="com.foo.BarService" version="1.0.0" />
<dubbo:service interface="com.foo.BarService" version="2.0.0" />
<dubbo:reference id="barService" interface="com.foo.BarService" version="1.0.0" />
<dubbo:reference id="barService" interface="com.foo.BarService" version="2.0.0" />
不区分版本:(2.2.0以上版本支持)
<dubbo:reference id="barService" interface="com.foo.BarService" version="*" />

dubbo协议下的单一长连接与多线程并发如何协同工作

底层采用netty。

集群容错怎么做 

Dubbo提供了多种容错方案,缺省为Failover Cluster重试。
集群容错模式:
1、Failover Cluster
      失败自动切换,当出现失败,重试其它服务器。(缺省)
      通常用于读操作,但重试会带来更长延迟。
      可通过retries="2"来设置重试次数(不含第一次)。正是文章刚开始说的那种情况.
2、Failfast Cluster
      快速失败,只发起一次调用,失败立即报错。
      通常用于非幂等性的写操作,比如新增记录。
3、Failsafe Cluster
      失败安全,出现异常时,直接忽略。
      通常用于写入审计日志等操作。
4、Failback Cluster
      失败自动恢复,后台记录失败请求,定时重发。
      通常用于消息通知操作。
5、Forking Cluster
      并行调用多个服务器,只要一个成功即返回。
      通常用于实时性要求较高的读操作,但需要浪费更多服务资源。
      可通过forks="2"来设置最大并行数。
6、Broadcast Cluster
      广播调用所有提供者,逐个调用,任意一台报错则报错。(2.1.0开始支持)
      通常用于通知所有提供者更新缓存或日志等本地资源信息。


重试次数配置如:(failover集群模式生效)

<dubbo:service retries="2"/>
或:
<dubbo:reference retries="2"/>
或:
<dubbo:reference>
<dubbo:methodname="findFoo"retries="2"/>
</dubbo:reference>

集群模式配置如:

<dubbo:servicecluster="failsafe"/>
或:
<dubbo:referencecluster="failsafe"/>

dubbo是如何实现负载均衡

dubbo负载均衡策略,缺省为random随机调用:
1、Random  LoadBalance
      随机,按权重设置随机概率。
      在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
2、RoundRobin  LoadBalance
      轮循,按公约后的权重设置轮循比率。
      存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
3、LeastActive  LoadBalance
      最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
      使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
4、ConsistentHash  LoadBalance
      一致性Hash,相同参数的请求总是发到同一提供者。
      当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

遇到的问题

场景描述:客户端远程异步调用ServiceA,ServiceA在处理客户端请求的过程中需要远程同步调用ServiceB,ServiceA从ServiceB的响应中取数据时,得到的是null。
对于上面的问题,解决办法有三个:
1.方法调用两次

ServiceA调用ServiceB的地方写两次一样的调用,这个方法原理就像ServiceB调用ServiceC一样,即清除attachements。
这个方法最简单,但是可能对不了解的人来说,这块业务代码写重复了,会不小心删除掉,而且从写代码的角度来说,这个很鸡肋,所以不推荐。

2.修改Dubbo源码

 修改AbstractInvoker第137行,改成每次都对async进行实际赋值,
 boolean isAsync = getUrl().getMethodParameter(invocation.getMethodName(), Constants.ASYNC_KEY, false);
 invocation.setAttachment(Constants.ASYNC_KEY, String.valueOf(isAsync));

3.自定义Filter

 实现com.alibaba.dubbo.rpc.Filter,在RpcContext中清除这个async,
 @Activate(group = {Constants.PROVIDER})
  public class AsyncFilter implements Filter {
 @Override
 public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
     RpcContext.getContext().getAttachments().remove(Constants.ASYNC_KEY);
 return invoker.invoke(invocation);
 }
 }
 同时在src/main/resources/META-INF/dubbo/下添加com.alibaba.dubbo.rpc.Filter文件,内容文件如下:
 asyncFilter=com.abc.filter.AsyncFilter

根据n多的博客整理出来的一些,以后有其他东西再加进去

转载地址:https://www.jianshu.com/p/9d062eceb765

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值