• 分布式服务之Dubbo


    一、Dubbo介绍

    Dubbo是一款高性能、轻量级的开源 Java 服务框架。

    提供了六大核心能力:面向接口代理的高性能RPC调用,智能容错和负载均衡,服务自动注册和发现,高度可扩展能力,运行期流量调度,可视化的服务治理与运维。

    Dubbo的主要功能

    1. RPC调用
    • 支持多协议(序列化、传输)
    • 服务注册发现
    • 配置、元数据管理

    1. 集群、高可用、管控
    • 集群、负载均衡
    • 治理、路由
    • 控制台、管理与监控

    二、Dubbo技术原理

    整体架构图:

    1. Config配置层:对外配置接口,以ServiceConfig,ReferenceConfig为中心,可以直接初始化配置类,也可以通过Spring解析配置生成配置类
    2. Proxy 服务代理层:服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory
    3. Registry 注册中心层:封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory,Registry,RegistryService
    4. Cluster 路由层:封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster,Directory,Router,LoadBalace
    5. Monitor 监控层:RPC调用次数和调用时间的监控,以Statistics为中心,扩展接口为MonitorFactory,Monitor,MonitorService
    6. Protocol 远程调用层:封装RPC调用,以Invocation,Result为中心,扩展接口为Protocol,Invoker,Exporter
    7. Exchange 信息交换层:封装请求响应模式,同步转异步,以Request,Response为中心,扩展接口为Exchanger,ExchangeChannel,ExchangeClient,ExchangeServer
    8. Transport 网络传输层:抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel,Transporter,Client,Server,Codec
    9. Serialize 数据序列化层:可复用的一些工具,扩展接口为Serialization,ObjectInput,ObjectOutput,ThreadPool

    SPI的应用

    SPI与API

    ServiceLoader机制

    META-INF/dubbo/接口全限定名,文件内容为实现类

    其他两个类似的机制:Callback和EventBus

    服务如何暴露

    服务如何引用

    集群与路由

    • Router :选取此次调用可以提供服务的Invoker集合
    • LoadBalance :从上述集合中选取一个作为最终调用者

    泛化引用

    GenericService
    当我们知道接口、方法和参数时,可以使用反射调用服务。

    方法1:

    <dubbo:reference id="barService" interface="com.foo.BarService" generic="true" /> GenericService barService = (GenericService) applicationContext.getBean("barService"); Object result = barService.$invoke("sayHello", new String[] { "java.lang.String" }, new Object[] { "World" });
    

    方法2:

    ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
    reference.setInterface("com.xxx.XxxService");
    reference.setVersion("1.0.0"); 
    reference.setGeneric(true);
    GenericService genericService = reference.get();
    

    隐式传参
    Context模式

    RpcContext.getContext().setAttachment("index","1");

    此参数可以传播到RPC调用的整个过程

    Mock

    将mock设为true,在实现一个对应的Mock实现类即可。如HelloService的Mock类为HelloServiceMock

    三、Dubbo最佳实践

    开发分包

    1. 建议将服务接口、服务模型、服务异常等均放在API包中,因为服务模型和异常也是API的一部分,这样做也服务分包原则。

    2. 服务接口尽可能大粒度,每个服务方法代表一个功能,否则将面临分布式事务问题

    3. 服务接口建议以业务场景为单位划分

    4. 不建议使用过于抽象的通用接口,如Map query(Map map),没有明确的语义,会给后期维护带来不便

    环境隔离与分组

    如何做到多环境隔离呢?

    1. 隔离性的部署多套
    2. 多注册中心机制
    3. Dubbo提供的group机制
    4. Dubbo提供的版本机制

    参数配置

    通用参数以consumer端为准,如果consumer端没有设置,则用provider数值

    建议在Provider端配置的Consumer端属性有:

    • timeout: 方法调用超时时间
    • retries:失败重试次数
    • loadbalance:负载均衡算法
    • actives:消费者端的最大并发调用限制。

    建议在Provider端配置的Provider端属性有:

    • threads:服务线程池大小
    • executes:一个服务提供者并行执行请求上限。

    容器化部署

    注册的ip问题,解决方法:

    1. 方法1: docker使用宿主机网络
    2. docker参数指定注册的ip和端口

    运维和监控

    Admin里面功能比较简单,可以整合自己公司的监控系统:

    • Promethus + Grafana

    重试和幂等

    服务调用失败会默认重试,所以接口需要幂等性

    设计幂等接口方法:

    • 去重。 可以通过redis、bitMap等
    • 类似乐观锁机制判断

    四、源码解析

    带着问题去看

    1. 如何代理服务的?
    2. 如何发送远程请求的?
    3. 配置如何生效的?
    4. 异常处理?
    5. 超时机制?
    6. 优雅停机?
    书山有路勤为径,学海无涯苦作舟
  • 相关阅读:
    Element ui TimePicker 开始时间不得小于结束时间
    Vue 使用print.js实现前端打印功能
    vue中props的默认写法
    Element Cascader 级联选择器 选择第一级 label标题选择 内容过多
    vue 定时器 不断切换组件 定时器越来越快的问题
    Vue 全局组件传递参数
    echarts渐变发光半圆仪表盘
    左侧折叠菜单在sessionStorage中保存左侧菜单的激活状态
    Vue 封装网络工具类
    .browserslistrc 配置兼容浏览器
  • 原文地址:https://www.cnblogs.com/javammc/p/15141356.html
Copyright © 2020-2023  润新知