java进阶-Dubbo
Apache Dubbo是一款由阿里巴巴开源、Apache 基金会旗下的高性能微服务开发框架。它的核心是为分布式系统提供高效的RPC远程过程调用通信和服务治理能力。简单来说Dubbo 就像微服务架构的高速公路让一个服务如订单服务能像调用本地方法一样轻松、稳定地调用另一个服务如用户服务。核心架构与组件Dubbo 采用经典的节点角色分工协同完成服务调用其架构图如下它的核心组件包括服务提供者 (Provider)启动时将自己的服务接口注册到注册中心并暴露端口供消费者调用。服务消费者 (Consumer)启动时从注册中心拉取提供者地址列表。之后直接通过Dubbo协议寻址调用提供者无需再经过注册中心。注册中心 (Registry)协调服务的发现与注册。Dubbo 支持ZooKeeper、Nacos等实现。若注册中心宕机消费者仍可凭借本地缓存的地址列表继续工作具备高可用性。监控中心 (Monitor)统计服务调用次数、耗时等信息用于运维观测。核心能力与优势除了基础的 RPC 通信Dubbo 的价值更在于其强大的服务治理能力服务发现与负载均衡自动感知服务实例的上线/下线并内置随机、轮询、最少活跃调用等多种负载均衡策略智能分发请求。流量管控支持配置路由规则轻松实现灰度发布、金丝雀发布例如只允许特定IP的用户调用新版本服务。可观测性提供Admin 控制台可直观查看服务状态、依赖关系及调用统计。高性能与可扩展其核心组件采用微内核插件设计所有功能均可灵活替换或定制在阿里巴巴双十一万亿级调用场景下验证了其稳定性。负载均衡策略Dubbo 的负载均衡是在客户端Consumer完成的。Consumer 会从注册中心拉取到 Provider 的地址列表然后根据特定算法智能地决定将请求发往哪个具体实例。Dubbo 内置了 7 种策略你可以根据业务场景灵活选择默认是random(加权随机)。策略核心原理最佳适用场景加权随机 (random)(默认)按权重设置随机概率权重越大被选中的概率越高。通用型场景调用量越大分布越均匀是绝大多数情况下的首选。加权轮询 (roundrobin)按权重设置轮询比率借鉴 Nginx 的平滑加权轮询算法解决了因权重悬殊导致的请求短时内集中问题。追求绝对的请求数均衡的场景如需要均匀分配任务给处理能力相当的机器。最少活跃 (leastactive)活跃数越低即正在处理的任务越少的 Provider 优先调用。体现了“能者多劳”的思想。后端机器性能差异较大或处理请求耗时差异大的场景。它会自动避开处理慢的“积压”机器。最短响应 (shortestresponse)在时间窗口内平均响应时间越短的 Provider 优先调用。对响应延迟要求极高的 TP99 敏感型场景。一致性 Hash (consistenthash)相同参数的请求总是发到同一台机器上。有状态服务如希望某用户的请求始终由同一台服务器处理如利用本地缓存。P2C (p2c)随机选择两台节点从中挑出当前连接数较小的那个。连接数能较好反映负载情况的场景。自适应 (adaptive)基于 P2C 算法但会综合考虑 CPU 负载、RT 等多个维度的指标选择负载最小的节点。云原生、动态变化频繁的环境算法最复杂效果最智能。几个值得关注的技术细节Random 的权重轮盘代码实现里如果权重不同算法会生成一个总权重的随机数offset然后依次减去每个 Provider 的权重offset首次小于 0 的 Provider 即被选中。就像在一个按权重划分好区域的轮盘上随机掷骰子。RoundRobin 的“平滑”之道为了避免高权重的机器在一段时间内被连续调用如 A:3, B:1, 调用序列为 A,A,A,BDubbo 实现了 Nginx 的平滑算法。通过动态调整权重让调用序列变得像A,B,A,A这样平滑避免流量瞬时冲击。LeastActive 的“活跃数”这个“活跃数”不是并发线程数而是指调用计数差请求发出数 - 响应返回数。如果一台机器处理很慢这个差值就会越来越大从而被算法“雪藏”收到更少的请求。预热机制 (Warmup)这是防止服务刚启动就承接大量流量导致性能问题的优化。如果一个 Provider 启动未满 10 分钟默认它的权重会被降低处理能力随着启动时间线性增加保证了启动阶段的稳定性。客户端缓存Dubbo 的客户端缓存主要包括两种服务地址缓存和调用结果缓存。1. 服务地址缓存 (Directory)这是 Dubbo 高可用的基石。RegistryDirectory在 Consumer 端扮演了“服务目录”的角色。工作原理Consumer 首次从注册中心获取 Provider 列表后会将其快照缓存在本地文件或内存中。这个列表会被包装成Invoker列表供负载均衡使用。动态更新RegistryDirectory会订阅注册中心的变化。当有新的 Provider 上线或旧的宕机它会收到通知并实时刷新本地的Invoker列表对上层调用透明。关键价值即使注册中心如 Zookeeper全部宕机Consumer 依然可以凭借本地缓存的地址列表正常调用 Provider保证了网络分区下的高可用性。2. 调用结果缓存 (Result Cache)Dubbo 提供了声明式缓存只需配置cache属性即可将调用结果缓存起来下次调用相同方法、相同参数时直接从缓存返回不发起 RPC。支持的策略有lru(最常用)基于最近最少使用原则淘汰缓存。threadlocal在同一个线程内共享结果例如页面渲染时多次查询同一用户信息可以避免重复调用。jcache集成标准的 JSR107 缓存实现灵活性高。lfu基于最不经常使用原则淘汰。expiring基于固定过期时间。3. 本地存根 (Stub) —— 更灵活的“缓存”与逻辑Stub不是纯粹的缓存但它是客户端处理本地逻辑的利器。你可以把它想象成远程服务的本地代理在真正发起远程调用前后插入你想要执行的逻辑。使用场景客户端缓存比如先检查ThreadLocal缓存命中就不调远程。参数验证在调用前校验参数合法性快速失败。容错降级远程调用失败时返回自定义的“容错数据”。实现方式// 实现与远程服务相同的接口并包含一个接收远程代理的构造函数 public class DemoServiceStub implements DemoService { private final DemoService demoService; // 构造函数Dubbo 会自动将远程代理注入进来 public DemoServiceStub(DemoService demoService) { this.demoService demoService; } public String sayHello(String name) { // --- 这部分代码在客户端执行 --- System.out.println(执行客户端逻辑如参数验证、本地缓存查询); try { String result demoService.sayHello(name); // 发起真正的远程调用 // 处理结果 return result; } catch (Exception e) { // 远程调用失败了返回兜底数据 return 容错数据; } } }配置时只需指定stubtrue或具体的 Stub 类路径即可开发体验像调用本地方法一样Dubbo 极大地简化了分布式开发。对于开发者而言调用远程服务几乎与调用本地方法无异1. 定义服务接口// 定义一个接口 public interface DemoService { String sayHello(String name); }2. 服务端实现并发布// 实现业务逻辑DubboService注解自动完成服务发布 DubboService public class DemoServiceImpl implements DemoService { public String sayHello(String name) { return Hello name; } }3. 客户端注入并调用// 客户端只需 DubboReference 注入即可直接调用 DubboReference private DemoService demoService; public void doCall() { // 像调用本地方法一样发起远程调用 String result demoService.sayHello(World); }总结Dubbo 是一个从编程模型到服务治理、从性能到扩展性都经过大规模生产验证的微服务框架。它屏蔽了分布式系统的复杂性帮助开发者更专注于业务逻辑本身。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2504691.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!