专栏首页立权的博客Dubbo 核心功能在业务架构中的体现

Dubbo 核心功能在业务架构中的体现

所有的技术或者开源项目,最终都是为业务服务,归根结底为人和社会服务

dubbo 的三大核心功能分别是

  1.RPC 调用

  2.服务注册与订阅 (可用 redis , zookeeper ......)

  3.自动容错(调用失败后的策略)与负载均衡

对于一个工具,先要知道他解决什么问题,才能更好的了解他

  应用在垂直拆分的业务架构 向 分布式服务的架构 演进之后,虽然对数据库的连接使用减少,应用逻辑本身和基础的服务分离

1.RPC

  但是有一个问题是,应用本身怎么和服务通信?怎么去调用服务?

  最简单的做法是使用 http 应用层接口,但是 http 的报头报尾相对较大,不免造成浪费,报头报尾在RPC调用中几乎没有用处

  在本语境下,RPC最根本希望做到的事情是 应用快速告知服务要调用什么方法,服务处理后能将结果快速返回给应用

  这要求 RPC 通道中传输的数据尽可能小,在并发量大的情况下尤其如此。

  dubbo 针对这一点,推荐使用基于TCP长连接的 dubbo 协议,所谓长连接,也就是三次握手之后不是简单的一次请求-响应就调用close或shutdown进行四次挥手

  服务和应用之间通过长连接通信,主要是为了免除三次握手,四次挥手造成的消耗,因为应用被海量用户调用,自然要用也需要十分频繁地调用服务。

  而且功能切分合理的话,应用和服务之间的 TCP 连接数量一般不会超过系统的负荷

  dubbo 架构:

2.注册,订阅

  还有一个问题,假如直接在应用中写死了 服务的IP 地址,那么当服务所在的物理机故障要迁移的时候,就需要重新改应用里写死的 IP 地址,然后让应用重启。

  在生产环境中,如果无缘无故关停,重启,无疑是重大的生产事故。

  应用需要保存一份 服务的地址列表,但这个地址列表不能是写死的,需要实时更新,更新的来源呢?:注册中心

  服务需要实时地将自己的地址 添加到注册中心,让应用通过注册中心发现他们。

  而且注册中心会在TCP长连接上定时通过心跳检测的方式检验服务是否存活,对于不存活的服务,从列表上剔除,并且通过和应用的TCP长连接,告知应用需要从本地的列表中剔除哪些死亡的服务地址

3.容错:当应用调用服务失败,应用将会使用不同策略处理 , 详见官网

  1.重试,通过负载均衡策略选择其他服务器重试(未知具体重试策略)

  2.立刻失败,当调用失败时,立刻报错,对于非幂等性质的请求(多次请求的共同效果和单次请求的共同效果不等)常用。比如添加订单操作,如果一次提交订单,失败,则不应该提交第二次,因为可能两次订单都被接受,但是网络问题导致服务的响应未回复。避免重复添加订单,就应该在一次失败后立刻报错。

  注意这里的非幂等不同于网络导致的非幂等,网络导致的非幂通常采用MVCC(多版本并发控制),也就是给一个记录打版本,要操作前先读版本,提交操作给处理者时希望处理者持有的版本是读的时候的版本,不是的话就失败。或者 token,每个token 都是在操作时产生的,并且只能用于一次操作,这样提交操作给处理者的时候会带有 之前产生的 token,对比 token 就能看看请求是否在网络中错乱,导致大于1个包出现。而此处的非幂等是应用造成的,就算用 MVCC 或 token,每次应用再去调用服务还是会生成新的 版本或者 新的 token,相当于多调用一次服务,无法通过 MVCC 或 token 预防。和网络中包重复不是一个问题。

  3.忽视,失败后不做处理

  4.调用多个(可配置)服务提供者,一个成功就能返回

4.负载均衡:

1.随机选取(可调权重)

  2.轮询

  3.最小活跃数,服务提供者被调用前 计数 + 1, 调用完 后 计数 - 1,所以处理慢的提供者请求会一直累计,计数大,处理快的计数消耗快,计数小,所以被调用可能性大

  4.一致性hash,如果是使用请求的第一个参数去hash,可以通过 hash.arguments 指定哪几个参数参与一致性 hash,hash.nodes 可以指定一份服务器的 虚拟节点数

5.额外功能:监控

  监控中心是采集整个系统信息的一个部分,比如说我们想看到我们的某个服务一条被调用了多少次,或者想找到调用时间最长的那个服务(可能存在某些故障),就可以去监控中心找数据,因为应用和服务都会将数据推送到监控中心。

  服务和应用通过短链接和注册中心通信

  应用和服务都会积累一段时间后,将这段时间内的服务调用次数和调用时间通过短连接(一次请求-响应)发送给监控中心。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Docker修改Mysql端口

    在配置文件设置无果后(已改访问权限,non World-wide writable)

    执生
  • Java模拟实现Linux操作系统:(一)知识储备,绪论

    Linux采用C语言编写(在C中有嵌入汇编成分)。本文想要用Java这门语言在软件层面上模拟出Linux。

    执生
  • Mybatis-generator 逆向工程 自定义PO,xml,mapper,example

    1.我们定义的PO规则生成类,需要继承官方提供的JavaSrcGenerator,并重写generate方法

    执生
  • ubuntu18.04 安装python

    在Ubuntu中安装snmp的支持,有两种方法,第一种是直接通过apt-get进行安装。第二种是从netsnmp官网下载源码net-snmp-5.7.3.tar...

    py3study
  • android FragmentpagerAdapter和FragmentStatePagerAdapter的区别

    1.FragmentPagerAdapter FragmentPagerAdapter 继承自 PagerAdapter。相比通用的 PagerAdapter...

    xiangzhihong
  • Springboot2整合openFegin客户端

    设置路径: http://localhost:9011/feginDemo/threshold/send/01/FA

    用户5640963
  • Go语言——再论slice切片

    Slice是长度可变的元素序列(数组不可变),每个元素都有相同的类型。slice类型写作[]T,其中T代表slice中的元素类型;slice和数组写法很像,只是...

    李海彬
  • 你应该如何正确健壮后端服务?

      对每一个程序员而言,故障都是悬在头上的达摩克利斯之剑,都唯恐避之不及,如何避免故障是每一个程序员都在苦苦追寻希望解决的问题。对于这一问题,大家都可以从需求分...

    芋道源码
  • Springboot集成MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是可以应用于各种规模的企业、各个行业以及各类应用程序的开源数据库。作为一个适用于敏捷开...

    Ryan-Miao
  • Android中Activity/Service获取调用者的信息(FIDO UAF Client获取调用者的信息)

    实现UAF协议的时候,Client需要获取调用者的信息(获得其APK的签名)。用中文查了半天没查到获取Activity的方法,用英文一下就搜出来了(主要还是看英...

    sickworm

扫码关注云+社区

领取腾讯云代金券