知行合一
Github
顺翔的技术驿站
顺翔的技术驿站
  • README
  • ABOUTME
  • Computer Science
    • 数据结构与算法
      • 位运算以及位图
      • 随机数
      • 递归
      • 经典排序算法
      • 经典查找算法
      • 数组和动态数组
      • 链表
      • 栈和队列
      • 树
      • 哈希表
    • 计算机网络
      • 物理层
      • 数据链路层
      • 网络层
        • TCP
      • 运输层
      • 应用层
      • HTTP
        • HTTPS的原理
        • DNS详解
        • file协议
        • 邮件协议
    • 设计模式
      • 单例模式
      • 建造者模式
      • 原型模式
      • 工厂模式
      • 享元模式
      • 代理模式
      • 装饰者模式
      • 桥接模式
      • 适配器模式
      • 外观模式
      • 组合模式
      • 事件驱动
      • 有限状态机
      • 备忘录模式
      • 模板方法模式
      • 策略模式
      • 迭代器模式
      • 命令模式
      • 解释器模式
    • 加密与解密
      • 数字证书原理
      • cfssl
  • Programming Language
    • 编程语言学习要素
    • Java
      • 集合
        • List
          • ArrayList
          • Vector
          • Stack
          • LinkedList
        • Iterator
        • Set
          • HashSet
          • TreeSet
        • Map
          • HashMap
          • HashTable
          • TreeMap
          • LinkedHashMap
      • 常用API
        • 日期时间处理
        • System
        • Random
        • Arrays
        • Scanner
        • 格式化输出
      • java特性
        • java5特性
        • java8特性
        • java9特性
        • java10特性
        • java11特性
      • 并发编程
        • 线程基础
        • 线程同步:synchronized及其原理
        • 线程同步: volatile
        • 锁机制
        • 锁的分类与对应的Java实现
        • JUC:同步辅助类
        • JUC: AtomicXXX
        • 线程池
        • ThreadLocal详解
      • 测试
        • 使用JMH进行基准测试
      • JVM
        • 强引用、软引用、弱引用、虚引用
        • jvm内存模型
        • jvm优化
        • GC算法与回收器
        • 静态绑定与动态绑定
      • ORM
        • Mybatis
          • IBatis常用操作
      • Web编程
        • Servlet详解(一)
        • Servlet详解(二):request和response对象
        • Servlet详解(三):会话技术与Cookie
        • JSP详解(一):页面构成、EL表达式
        • JSP详解(二):九大内置对象
        • JavaWeb的编码问题
        • Thymeleaf
      • Velocity
      • Java日志框架总结
      • Spring
        • SpringIOC
        • SpringMVC
        • SpringBoot源码
      • 其他
        • Apache Commons Lang使用总结
        • 使用FtpClient进行ftp操作
        • Java PDF操作总结
        • Java使用zip4j进行文件压缩
        • Java解析Excel总结
    • JVM Language
      • Groovy
      • Scala
    • Kotlin
      • 变量和常量
      • 数据类型
        • 基本数据类型
        • 容器类型
        • 函数类型
        • null和null安全
      • 流程控制
      • 包
      • 面向对象
    • Golang
      • 关键字与标识符
      • 变量和常量
      • 数据类型
      • 函数
      • 常用API
        • 时间日期处理
        • 字符串操作
        • 正则表达式
      • 控制语句
      • 包package
      • 面向对象
      • 错误处理
      • 命令行编程
        • Cobra
      • 文件操作
      • 测试
      • 并发编程
        • sync包详解
      • 数据格式与编码
        • 使用encoding包操作xml
        • 使用encoding包操作json
        • 使用magiconair操作properties
        • 使用go-ini操作ini
      • 反射
      • Build Tools
        • Go Module
        • Go Vendor
      • 日志框架
        • zap日志框架
      • Web编程
        • Gin
    • JavaScript
      • 数据类型
      • ECMAScript
        • ECMAScript6
      • NodeJS
    • TypeScript
      • 变量和常量
      • 数据类型
      • 函数
      • 面向对象
      • 泛型
      • Build Tools
        • tsc编译
        • 与webpack整合
    • Python
      • BuildTools
        • requirements.txt
        • Ananconda
    • Swift
      • 变量和常量
    • Script Language
      • Regex
      • BAT
      • Shell
    • Markup Language
      • Markdown
      • Yaml
  • Build Tools
    • CMake
    • Maven
      • 搭建Nexus私服
      • maven使用场景
    • Gradle
  • Version Control
    • Git
      • Git工作流
      • Git分支管理
      • Git Stash
      • Git Commit Message规范
      • .gitttributes文件
    • SVN
  • Distributed
    • 分布式基础理论
      • 互联网架构演变
      • 架构设计思想AKF拆分原则
      • CAP理论
      • BASE理论
    • 一致性
      • 一致性模型
      • 共识算法
        • Paxos
        • Raft
        • ZAB
      • 复制
        • 主从复制
        • Quorum机制
        • Nacos Distro协议
      • 缓存一致性
        • 双写一致性
        • 多级缓存一致性
    • 事务一致性
      • Seata
      • 本地消息表实现方案
      • 关于dpad的事务问题的分析
    • IO
    • RPC协议
    • 序列化
    • Session共享
    • 分布式协调
      • Zookeeper
        • zk集群4节点搭建
    • 服务治理
      • Dubbo分布式治理
    • 分布式ID
      • 分布式ID生成策略总结
    • 分布式锁
    • 应用服务器
      • Tomcat
    • Web服务器
      • Nginx
        • Nginx的基本配置
        • ab接口压力测试工具
        • nginx模块
        • 随机访问页面
        • 替换响应内容
        • 请求限制
        • 访问控制
        • 状态监测
        • nginx应用场景
        • 代理服务
        • 负载均衡
        • 缓存
        • 静态资源服务器和动静分离
        • 附录
      • Kong
    • 缓存中间件
      • Caffeine
      • memcached
      • Redis
        • Centos下安装Redis
        • RatHat下安装Redis
    • 数据库中间件
      • ShardingSphere
      • MyCat2
    • 消息中间件
      • Kafka
      • RocketMQ
  • Microservices
    • 服务发现
      • Nacos注册中心
      • Consul
    • 配置中心
      • Apollo
    • 消息总线
    • 客户端负载均衡
    • 熔断器
    • 服务网关
    • 链路追踪
      • Skywalking
  • Domain-Specific
    • Auth
      • 有关权限设计的思考
      • 认证方式
      • JWT
    • 任务调度
      • QuartzScheduler
      • Elastic-Job
      • XXL-Job
      • PowerJob
    • 工作流
      • BPM
      • Activiti
      • Flowable
    • 规则引擎
      • Drools
  • Architect
    • DDD领域驱动设计
      • 三层架构设计
      • 四层架构设计
    • Cola
    • 代码设计与代码重构
      • 重构改变既有代码设计
      • 枚举规范化
      • 接口幂等
      • 限流
      • 历史与版本
      • 逻辑删除和唯一索引
      • 业务对象设计
    • 单元测试
      • SpringBoot单元测试实践
    • 项目管理
    • APM
      • SkyWalking
      • Arthas
    • 性能优化
      • 接口性能优化
    • 系统设计
      • 流程中台
      • 短信中台
      • 权限中台
        • 智电运维平台组织架构改造二期
  • Database
    • Oracle
      • Docker下安装oracle11g
    • IBM DB2
    • Mysql
      • 安装Mysql
      • 用户与权限管理
      • MySQL的逻辑架构
      • 存储引擎
      • 索引详解
      • MySql的列类型
      • MySql中表和列的设计
      • MySql的SQL详解
      • 锁机制
      • 事务
      • Mysql函数总结
      • MySql存储过程详解
      • MySql触发器详解
      • Mysql视图详解
      • Mysql中Sql语句的执行顺序
      • 配置MySql主从和读写分离
      • MySql的备份策略
      • MySql分库分表解决方案
      • MySql优化总结
      • MySQL实战调优
        • schema与数据类型优化
    • Mongo
  • File System
    • README
    • HDFS
    • FastDFS
    • MinIO
  • Linux
    • 常用的Linux命令
    • vim
    • Linux磁盘管理
    • Linux系统编程
    • RedHat
      • rpm包管理器具体用法
    • Ubuntu
      • Ubuntu下录制屏幕并做成gif图片
      • Ubuntu20.05LiveServe版安装
  • DevOps
    • VM
      • 新建一个新的Linux虚拟机需要配置的东西
      • VMware桥接模式配置centos
      • VMwareFusion配置Nat静态IP
    • Ansible
    • Container
      • Docker
        • Dockerfile详解
        • DockerCompose详解
      • Containerd
    • Kubernetes
      • 安装k8s
        • 使用Minikube安装k8s
        • centos7.x下使用kubeadm安装k8s1.21
        • ubuntu20下使用kubeadm安装k8s1.21
        • centos7.x下使用二进制方式安装k8s1.20
        • 使用DockerDesktop安装K8s(适用M1芯片)
      • 切换容器引擎
      • 使用k8s部署项目的流程
      • 集群维护-备份升级排错
    • Gitlab
      • GitlabCI/CD
    • CI/CD
      • ArgoCD
  • Big-Data
    • Hadoop
    • MapReduce
    • HDFS
  • Front-End
    • Android
      • Log的使用、自定义Log工具类
      • Android倒计时功能实现
      • 解决ViewDrawableLeft左侧图片大小不可控的问题
      • AndroidSQLite基本用法
      • View的生命周期
      • 工具类
      • WebView详解
      • ViewTreeObserver类监听ViewTree
      • 在onCreate中获取控件的宽高等信息的几种方法
      • View的foreground属性
        • MaterialDesign
          • BottomNavigationBar
          • CardView
          • Elevation高度、shadows阴影、clipping裁剪、tint着色
          • TouchFeedbackRipple波纹动画
      • Volley完全解析——使用、源码
      • Android围住神经猫的实现
      • LookLook剖析,架构概述——MVP、Retrofit+RxJava
      • Android性能优化之渲染
    • Browser
      • 浏览器的工作原理
    • HTML
      • DOCTYPE标签、XHTML与HTML的区别
    • CSS
      • CSS的继承性、层叠性、权重
      • CSS浮动float详解(一):标准文档流
      • CSS浮动float详解(二):使用float
      • CSS浮动float详解(三):清除浮动方案
    • Tools Lib
      • JavaScript 文件下载解决方案-download.js
      • js-url 用于url的js开源库
      • jsuri 用于操作url的js开源库
      • window offset
    • React
      • 模块化和组件
      • 组件的三大核心属性
      • 事件处理
      • 表单数据收集
      • 生命周期
      • DOM的diff算法
      • 工程化
        • 脚手架create-react-app
        • 工程结构和模块化
      • 路由
  • Design
    • 产品设计
      • 交互设计
由 GitBook 提供支持
在本页
  • dubbo 是什么?
  • dubbo的架构
  • dubbo的简单使用
  • dubbo-admin
  • dubbo-monitor
  • 启动服务检查
  • telnet命令
  • Qos
  • 多协议的支持
  • Hessian 协议
  • 多注册中心支持(不常用)
  • 服务多版本支持
  • 异步调用
  • 主机绑定
  • 服务只订阅
  • 服务只注册
  • 连接超时 timeout
  • 服务集群和负载均衡
  • 负载均衡策略
  • 配置负载均衡策略
  • 集群容错
  • 服务配置优先级
  • dubbo 企业应用配置
  • 分包
  • 粒度
  • 版本
  • 推荐配置
  • 配置缓存文件
  • 配置异常处理

这有帮助吗?

在GitHub上编辑
  1. Distributed
  2. 服务治理

Dubbo分布式治理

上一页服务治理下一页分布式ID

最后更新于1年前

这有帮助吗?

官方网站: Github:

许多公司采用 dubbo + spring boot + docker 的架构方式。

dubbo 是什么?

dubbo是一个分布式服务框架,提供高性能的以及透明化的RPC远程服务调用解决方案,以及SOA服务治理方案。

dubbo可以解决的问题(解决了不好治理的问题):

  1. url维护,订单系统会调用用户系统,用户系统也会调用订单系统,调用过多,url无法统一管理 解决方案:注册中心(zookeeper,redis,memcached..) 将对外暴露的服务url全部保存在第三方中间件上

  2. F5负载均衡压力较大,成本较高 解决方案:软负载均衡(zookeeper...)

  3. 服务架构依赖混乱,如果理出架构关系? 需要自动整理架构关系的方式

  4. 服务器调用量越来越大,服务器的容量问题如何评估?(评估用于扩容指标) 需要监控平台,监控调用量,响应事件

dubbo的核心功能:

  1. 远程通信

  2. 集群容错

  3. 服务自动发现

  4. 负载均衡

  5. 基于url的总线驱动(所有信息都是通过url传递的)

dubbo的架构

核心角色:

Provider
Consumer
Registry
Monitor
Container
  • Provider 提供服务,比如tomcat

  • Registry 注册中心,Provider将启动后的url注册到Registry

  • Consumer订阅Registry,Registry在发生变化时,将通知Consumer地址发生变化。

  • Consumer通过Registry提供的url 远程访问Provider

  • Monitor负责监控Consumer和Provider,解决调用关系以及调用量的监控问题

dubbo的简单使用

构建provider:

  1. 创建order-api模块,用于向其他模块提供接口。其中,此模块中只包含Java业务Server接口和输入输出对象。

  2. 创建order-provider模块,此模块依赖order-api模块,是order服务的具体实现;需要依赖dubbo与zkclient

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
    </dependency>
    <dependency>
        <groupId>com.github.sgroschupf</groupId>
        <artifactId>zkclient</artifactId>
    </dependency>
  3. 在 resources/META-INF/spring/目录下创建 order-consumer.xml 文件,用于定义dubbo服务

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans        
               http://www.springframework.org/schema/beans/spring-beans.xsd        
               http://code.alibabatech.com/schema/dubbo        
               http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    
        <!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->
        <dubbo:application name="order-provider" owner="feathers"/>
        
        <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->
        <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183"/>
        <!--或者这样写-->
        <!--<dubbo:registry address="zookeeper://127.0.0.1:2181?backup=127.0.0.1:2181,127.0.0.1:2181"/>-->
        <!--或者不使用注册中心, 这样就不会将提供的接口地址存入到zookeeper中,需要消费者使用url消费-->
        <!--<dubbo:registry address="N/A"/>-->
    
        <!--当前服务发布所依赖的协议;webserovice、Thrift、Hessain、http、dubbo-->
        <dubbo:protocol name="dubbo" port="20880"/>
    
        <!--服务发布的配置,需要暴露的服务接口-->
        <dubbo:service interface="me.feathers.demo.order.OrderService" ref="orderService"/>
        
        <!--暴露的接口的实现-->
        <bean id="orderService" class="me.feathers.demo.order.impl.OrderServiceImpl"/>
        
        <!--<dubbo:monitor protocol="registry"/>-->
    
    </beans>
  4. 编写启动类,注册服务到注册中心zookeeper

     import com.alibaba.dubbo.container.Main;
    
     public static void main(String[] args) throws IOException {
        Main.main(args);
        System.in.read();
    }
  5. 查看zookeeper,发现dubbo节点下已经注册了一个url地址,使用此地址,可以直接调用dubbo服务: ![](../../../../../../OneDrive/note/Java/Distributed/images/20190313205831318_24519.png =687x)

创建consumer:

  1. 创建项目client,并在resources目录下创建配置文件order-consumer.xml,此配置文件用于配置远程代理对象:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans        
               http://www.springframework.org/schema/beans/spring-beans.xsd        
               http://code.alibabatech.com/schema/dubbo        
               http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
        <!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->
        <dubbo:application name="order-provider" owner="feathers"/>
    
        <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->
        <!--<dubbo:registry address="zookeeper://127.0.0.1:2181?backup=127.0.0.1:2182,127.0.0.1:2183"/>-->
    
        <!--生成一个远程服务的调用代理, 使用注册中心获取url调用-->
        <!--<dubbo:reference id="orderServices" interface="me.feathers.demo.order.OrderService"/>-->
        <!--生成一个远程服务的调用代理, 使用地址直连(测试使用)-->
        <dubbo:reference id="orderServices" interface="me.feathers.demo.order.OrderService"
            url="dubbo://10.0.75.1:20880/me.feathers.demo.order.OrderService"/>
    </beans>
  2. 使用Main启动consumer,并且利用创建好的服务代理对象调用服务:

    public class App {
        public static void main(String[] args) throws IOException {
    
            // 调用服务
    
            // 1. 从spring容器中获取远程服务代理对象
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("order-consumer.xml");
    
            // 2. 调用下单接口
            OrderService services = (OrderService) context.getBean("orderServices");
    
            Order order = new Order();
            order.setProductName("哈哈");
            order.setUserId("u112000");
            order.setAmount("$1");
            order.setOrderId(123L);
            BaseOrderResponse response = services.addOrder(order);
            
            // 3. 展示响应
            System.out.println(response);
            System.in.read();
        }
    }

dubbo-admin

dubbo-admin用来做服务治理,比如控制服务权重、服务路由等。

其中,dubbo-admin-ui 是 前端项目,dubbo-admin-server 是接口服务。

  1. 修改 dubbo-admin-server\src\main\resources\application.properties文件的相关内容,配置注册中心地址,用户名密码等信息

  2. 在dubbo-admin-server 执行mvn clean package -Dmaven.test.skip=true 将项目打包为jar

  3. 执行jar文件,启动接口服务

  4. 进入dubbo-admin-ui 前端项目,执行 npm install

  5. 执行完毕后,使用npm run dev 或者 npm run build 运行项目,并打开网址测试

新的dubbo控制台界面如下:

dubbo-monitor

dubbo-monitor用来监控服务的调用次数,调用关系、响应时间等。

dubbo-monitor-simple 是一个简单的dubbo监控平台,具体安装方式如下:

  1. 修改每个dubbo应用程序的xml文件,加入如下配置: <dubbo:monitor protocol="registry"/>,添加monitor监控

  2. 修改配置文件,如下:

    dubbo.container=log4j,spring,registry,jetty
    dubbo.application.name=simple-monitor
    dubbo.application.owner=
    # 配置注册中心
    # dubbo.registry.address=multicast://224.5.6.7:1234
    dubbo.registry.address=zookeeper://127.0.0.1:2181
    #dubbo.registry.address=redis://127.0.0.1:6379
    #dubbo.registry.address=dubbo://127.0.0.1:9090
    dubbo.protocol.port=7070
    # jetty容器端口,防止端口占用
    dubbo.jetty.port=8099
    # jetty存储路径,需要手动创建,否则图表不展示
    dubbo.jetty.directory=${user.home}/monitor
    # 图表路径,需要手动创建
    dubbo.charts.directory=${dubbo.jetty.directory}/charts
    # 统计信息路径,需要手动创建
    dubbo.statistics.directory=${user.home}/monitor/statistics
    # 日志存储路径
    dubbo.log4j.file=logs/dubbo-monitor-simple.log
    # 日志级别
    dubbo.log4j.level=WARN
  3. 执行bin/start.sh或者start.bat

启动服务检查

启动Consumer时,默认回去检测所依赖的服务是否正常提供服务。

<dubbo:reference id="orderServices" interface="me.feathers.demo.order.OrderService"
            url="dubbo://10.0.75.1:20880/me.feathers.demo.order.OrderService" check="true"/>

即默认选项为 check=true;如果将check设置为false,则即使服务不可用,Consumer也可以正常启动。

除此之外,一下标签也拥有check属性:

  • dubbo:consumer, check=true/false: true,没有服务提供者的时候,报错

  • dubbo:registry, check=true/false: true,注册订阅失败时报错

telnet命令

telnet localhost 20880

# 进入dubbo控制台,提供了一些命令可以对服务进行操作,类似linux命令
# 查看该dubbo应用程序提供的所有服务
dubbo>ls
me.feathers.demo.order.OrderService

# 进入OrderServer类级别服务
dubbo>cd me.feathers.demo.order.OrderService
Used the me.feathers.demo.order.OrderService as default.
You can cancel default service by command: cd /

# 查看类级别服务下的所有方法级别服务
dubbo>ls
Use default service me.feathers.demo.order.OrderService.
addOrder
deleteOrder
getOrderById

# 查看当前所在的路径
dubbo>pwd
me.feathers.demo.order.OrderService

# 使用invoke调用服务
dubbo>invoke me.feathers.demo.order.OrderService.deleteOrder('oid123')
Use default service me.feathers.demo.order.OrderService.
{"msg":"删除订单成功","code":"00-00"}
elapsed: 2 ms.

# 可以传入对象参数,对象参数是一个json
dubbo>invoke me.feathers.demo.order.OrderService.addOrder({userId:'123', orderId:111, productName:'food', amount:'18.5'})
Use default service me.feathers.demo.order.OrderService.
{"msg":"添加订单成功","code":"00-00"}
elapsed: 0 ms.

# 清屏
clear

Qos

telnet 默认不可以远程调用,如需配置远程调用,需要加入如下参数:

<dubbo:application name="simple-provider">
	<dubbo:parameter key="qos.enable" value="true" />
	<dubbo:parameter key="qos.accept.foreign.ip" value="true" />
	<dubbo:parameter key="qos.port" value="22223" />
</dubbo:application>

其中,qos是指Quality of Service,是dubbo的在线运维命令,qos.enable代表是否开启在线运维命令,qos.accept.foreign.ip 是否可以远程连接,qos.portqos的端口(默认端口22222,如果被占用,则会抛出qos-server can not bind localhost:22222的错误)

多协议的支持

dubbo本身使用的RPC协议是dubbo协议(服务之间的通信协议),同时,dubbo也支持其他协议,比如:

  • dubbo

  • RMI

  • Hessian

  • WebService

  • Http

  • Thrift

Hessian 协议

Hessian协议底层采用Http通讯,并使用JavaServlet暴露服务,缺省内嵌Jetty作为服务器实现。所以使用Hessian,需要添加两个包,Hessian和Jetty:

    <dependency>
      <groupId>com.caucho</groupId>
      <artifactId>hessian</artifactId>
      <version>4.0.7</version>
    </dependency>

  <dependency>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>jetty</artifactId>
    <version>6.1.26</version>
  </dependency>

在Provider中添加对Hessian协议的支持:

<!--dubbo支持多协议同时配置,此处增加hessian协议-->
<dubbo:protocol name="hessian" port="8090" server="jetty"/>

此时查看注册中心,就会发现,在providers节点下,多出一个子节点:

客户端需要在调用服务时,指定所使用的RPC协议:

<!--使用protocol指定调用协议-->
<dubbo:reference id="orderServices" interface="me.feathers.demo.order.OrderService" check="true" protocol="hessian"/>

多注册中心支持(不常用)

针对部分服务发布到指定的注册中心,通常用于注册中心分组、注册中心热备份等功能,实现很简单,只要在需要进行多注册中心的provider与consumer中添加多个不同的registry即可:

<!--多注册中心支持, 因为是多个注册中心,所以,需要为每个注册中心指定id    -->
<dubbo:registry id="reg1" protocol="zookeeper" address="xxx"/>

为指定的服务指定注册中心,只需要在<dubbo:service 上指定注册中心即可:

<dubbo:service interface="me.feathers.demo.order.OrderService" ref="orderService" registry="reg1"/>

服务多版本支持

现在,针对OrderService,系统需要发布一个新的2.0版本,新增一个OrderService实现:OrderServiceImpl2

为了保证旧版用户正常使用,需要配置dubbo服务版本:

<!--服务发布的配置,需要暴露的服务接口-->
<dubbo:service interface="me.feathers.demo.order.OrderService" ref="orderService" version="1.0"/> 
<!--新版OrderService-->
<dubbo:service interface="me.feathers.demo.order.OrderService" ref="orderService2" version="2.0"/>

<!--暴露的接口的实现-->
<bean id="orderService" class="me.feathers.demo.order.impl.OrderServiceImpl"/>
<bean id="orderService2" class="me.feathers.demo.order.impl.OrderServiceImpl2"/>

更新provider,在注册中心就会提供两个OrderService服务,一个版本1.0一个版本2.0:

![](../../../../../../OneDrive/note/Java/Distributed/images/20190318101350399_21345.png =730x)

comsumer在使用时,同样需要指定version:

 <dubbo:reference id="orderServices" interface="me.feathers.demo.order.OrderService" protocol="hessian" version="2.0"/>

异步调用

注意:异步调用只支持dubbo协议

调用接口时,调用过程可能较慢或者无需同步等待调用的返回结果,此时就需要异步调用。异步调用,服务端无需变动,只需要在客户端方面添加如下配置即可:

<dubbo:reference id="orderServices" 
                     interface="me.feathers.demo.order.OrderService" 
                     async="true"/> <!--异步调用-->
<!--指定某个方法异步调用-->
<dubbo:reference id="orderServices" 
                 interface="me.feathers.demo.order.OrderService" 
                 protocol="dubbo" >
    <dubbo:method name="addOrder" async="true"/>
</dubbo:reference>

并使用RpcContext对象获取调用的返回结果:

//异步调用
services.addOrder(order);
Future<BaseOrderResponse> future = RpcContext.getContext().getFuture();
BaseOrderResponse response = null;
try {
    response = future.get(); // 阻塞等待
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}
// 3. 展示响应
System.out.println(response);

主机绑定

provider发布服务时,ip地址是从何而来的?

###com.alibaba.dubbo.config.ServiceConfig###

// 1. ProtocolConfig中如果绑定了host,则使用绑定的host
String host = protocolConfig.getHost();
if (provider != null && (host == null || host.length() == 0)) {
// 2. 如果protocolConfig中没有配置,则从providerConfig中获取host
    host = provider.getHost();
}

boolean anyhost = false;
if (NetUtils.isInvalidLocalHost(host)) {
    anyhost = true;
    try {
        // 3. 如果上述两个都没有配置host或者都是不正确的host
        // 则从InetAddress中获取host
        host = InetAddress.getLocalHost().getHostAddress();
    } catch (UnknownHostException e) {
        logger.warn(e.getMessage(), e);
    }
    // 4. 如果仍然获取不到,则使用
    if (NetUtils.isInvalidLocalHost(host)) {
        if (registryURLs != null && registryURLs.size() > 0) {
            for (URL registryURL : registryURLs) {
                try {
                    Socket socket = new Socket();
                    try {
                        // 如果仍然获取不到host,则发起连接到注册中心,再获取连接过去后本地的host
                        SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());
                        socket.connect(addr, 1000);
                        host = socket.getLocalAddress().getHostAddress();
                        break;
                    } finally {
                        try {
                            socket.close();
                        } catch (Throwable e) {}
                    }
                } catch (Exception e) {
                    logger.warn(e.getMessage(), e);
                }
            }
        }
        if (NetUtils.isInvalidLocalHost(host)) {
            // 6. 如果仍然获取不到,使用NetUtils获取
            host = NetUtils.getLocalHost();
        }
    }
}

绑定主机地址:

<!--使用protocolConfig绑定host-->
<dubbo:protocol name="dubbo" port="20880" host="10.35.10.170"/>

<!--使用providerConfig绑定host-->
<dubbo:provider host="10.35.10.170"/>

绑定后的ip:

![](../../../../../../OneDrive/note/Java/Distributed/images/20190318110512123_17445.png =834x)

服务只订阅

服务只订阅是指,在测试环境下,有可能需要调用注册中心的服务,但是又不能将当前服务注册到注册中心的情况,处理也很简单:

<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183" subscribe="true" register="false"/>
<!-- 订阅注册中心的服务,但是不注册当前服务,通常用于测试联调-->

服务只注册

<!--注册中心只注册,常用于多个注册中心的情况-->
<dubbo:registry subscribe="false"/>

连接超时 timeout

一般情况下,一个服务允许的超时时间为 5~10 s。

服务端配置:
<dubbo:provider timeout="5000"/>

客户端配置:
<dubbo:reference id="orderServices" 
                     interface="me.feathers.demo.order.OrderService" 
                     timeout="5000"/>

服务集群和负载均衡

dubbo集群配置比较简单,不需要进行任何配置,只需将服务在其他机器上运行再向注册中心注册一次即可,代码就不再延时。

负载均衡策略

Dubbo共有以下几种负载均衡策略:

  • Random, 随机分配到某个服务,这是Dubbo默认的负载均衡策略

  • RoundRobin,轮询:按照公约后的权重设置轮询比率

  • LeastActive LoadBalance,最少活跃用数,即响应时间较短的服务优先

  • Consistent LoadBalance,一致性hash

四种负载均衡策略,位于源代码模块dubbo-cluster的org.apache.dubbo.rpc.cluster.loadbalance包下。

配置负载均衡策略

<dubbo:service interface="me.feathers.demo.order.OrderService" ref="orderService" loadbalance="xxx"/>

支持的值: 
random
roundrobin
leastactive
consistent

集群容错

dubbo提供了以下几种集群容错策略:

  • failover cluster:失败时自动切换其他服务器。通过 retries=2 来设置重试次数;这是dubbo的默认策略

  • failfast cluster:快速失败,只发起一次调用。比如写操作,如新增数据,避免重复插入,这是非幂等请求(发起一次请求与发起多次请求所得的结果时不变的)

  • failsafe cluster:失败安全,即使失败也不抛异常,比如操作日志

  • failback cluster:失败自动恢复,后台记录失败请求,定时重发

  • forking cluster:并行调用多个服务器,只要有一个成功就返回,只能用于读请求(会浪费服务器资源)

  • broadcast cluster:广播调用所有提供者,其中一台报错就会抛出异常

配置集群容错:

服务端配置: 
<dubbo:service interface="me.feathers.demo.order.OrderService" ref="orderService2" version="2.0" cluster="failback"/>

客户端配置:
<dubbo:reference id="orderServices" 
                     interface="me.feathers.demo.order.OrderService" 
                     protocol="dubbo" 
                     version="2.0"
                     cluster="failback"/>

服务配置优先级

客户端>服务端
服务方法 > 服务

reference.method > service.method > reference > service > consumer > provider

dubbo 企业应用配置

分包

web-xxx  web模块,提供controller
dubbo-user 用户模块,提供用户相关业务的service
    user-api  service接口定义,dubbo consumer消费xml配置(放入META-INFO/client下,调用者使用spring import标签引入配置文件,从而注入接口)、dto
    user-provider server具体实现
dubbo-order
    order-api
    order=provider
  1. 将order-api与order-provider放入单一项目,其他user也放入单一项目,而不是全部采用多模块的方式放在一起。可以方便项目进行团队管理

  2. 服务接口、请求服务模型、异常信息都放在api模块下,复合重用等价原则,共同重用原则

  3. api模块中放入spring的引用配置,也可以放在模块的包目录下。com.xxx.xxx/xx-references.xml

粒度

  1. 尽可能将接口设置为粗粒度,每个服务方法代表一个独立的功能,而不是某个功能的步骤。否则会涉及到分布式事务

  2. 服务接口建议以业务场景为单位划分。并对相近业务进行抽象,防止接口暴增

  3. 不建议使用过于抽象的通用接口,比如泛型,这样的接口没有明确的语义,会使后期维护困难

版本

  1. 每个接口都应该定义版本,为后续的兼容性提供前瞻性考虑 (version),注意maven快照版本与发布版本的管理

  2. 建议使用两位版本号,第三位版本号则用于表示兼容性升级,只有不兼容时才需要变更服务版本

  3. 当接口做到不兼容升级的时候,先升级一半或者一台提供者为新版本,再将消费者全部升级为新版本,最后将所有提供者升级为新版本

推荐配置

  • 再provider端尽可能consumer端中需要配置的属性,比如timeout、retires、loadBalance、线程池大小

  • 配置管理员信息,即在application中配置的owner属性,建议配置多个,出问题可以找到相关人员

配置缓存文件

当注册中心集群出现问题,将会造成整个服务瘫痪,可以使用缓存文件,记录注册中心中的状态;当注册中心出现问题,将会从缓存文件中获取服务地址进行使用,进一步保证了服务的可用性。

<dubbo:registry protocol="zookeeper" file="/data/dubbo/cache/zookeeper.cache" address="xxx"/>

缓存文件将会缓存:

  • 注册中心列表

  • 服务提供者列表

配置异常处理

尽量不要使用返回码作为返回信息,推荐使用异常代替。

dubbo相关的demo位于:

dubbo-admin在dubbo2.7时,被单独列入了一个仓库:;如果是2.6版本,则是在dubbo-admin模块中()

将项目clone下来,可以依照进行配置。

新的dubbo-admin项目结构如下:

文件:

访问localhost:8099:

参考:

Dubbo支持使用作为RPC协议,Hessian协议是开源的一个RPC框架,Hessian协议底层采用Http作为传输协议,序列化采用Hessian二进制序列化。

apache dubbo
incubator-dubbo
Github
Dubbo Admin Github
地址
README
dubbo-monitor-simple-2.5.3.zip
Dubbo启动时qos-server can not bind localhost:22222错误解决
Hessian
Caucho
代码展示
image-20220307201955194