10 Dubbo 配置实战
Dubbo 配置实战
建议看这篇文章是在学习了快速入门 dubbo 那篇文章的基础上来学习
配置说明
文档地址 https://dubbo.apache.org/zh/index.html

关于 dubbo 的配置说明 在文档中都有比较详细的说明,下面举例的都是较为常用的

1 启动时检查
- 启动时会在注册中心检查依赖的服务是否可用,不可用时会抛出异常
- 在消费方编写初始化容器的 main 方法启动(tomcat 启动方式,必须访问一次 action 才能初始化
spring)- 想想为什么要有这个配置呢?
- 可以提前发现服务提供方是否可用
示例代码

直接启动这个测试类,注意 spring 配置文件的位置
- 我这里测试,现在是没有启动提供者
- 因为我们测试的目的就是让他没有提供者,会不会有报错提示
/**
* @author : look-word
* 2022-07-19 09:44
**/
public class TestCheckException {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/spring.xml");
// 让程序一直读取, 目的是不让他停止
System.in.read();
}
}
当我们启动后会发现,诶,怎么没有错误呢,是下面 log4j 的提示呢?
- 这里没有错误提示的原因呢,就是说我们没有正确的去配置 log4j,的确我们也没有去配置

- 系统级别日志,需要配合 log4j 才输出,在 resources 下添加 log4j.properties,内容如下:
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %m%n
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=dubbo.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %m%n
log4j.rootLogger=error, stdout,file
再次启动,会发现。如我们所愿它出错了。
错误信息
- 翻译的意思:说在 zookeeper 中没有找到可用的服务
java.lang.IllegalStateException: Failed to check the status of the service service.HelloService. No provider available for the service service.HelloService from the url zookeeper:
关闭检查
在 spring.xml 配置文件中加上就不会有异常提示了
- 可以看到,我这里的这个配置是注释掉的,在实际开发中我们是需要这个异常提示的,不推荐关闭
<!--默认是true:抛异常;false:不抛异常-->
<dubbo:consumer check="false" />
然后启动测试文件即可,这里不做演示了
2 超时时间
- 由于网络或服务端不可靠,会导致调用过程中出现不确定的阻塞状态(超时)
- 为了避免超时导致客户端资源(线程)挂起耗尽,必须设置超时时间
- 在服务提供者添加如下配置:
<!--设置超时时间为2秒,默认为1秒-->
<dubbo:provider timeout="2000"/>
- 可以将服务实现 HelloServiceImpl.java 中加入模拟的网络延迟进行测试:
@com.alibaba.dubbo.config.annotation.Service
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "Hello," + name + "!!!";
}
}
- 超时设置 2 秒,而模拟的网络延迟有 3 秒,超出时限,报错!
错误代码: com.alibaba.dubbo.remoting.TimeoutException: Waiting server-side response timeout.
- 说服务器响应超时。
配置原则:
dubbo 推荐在Provider上尽量多配置Consumer端属性:
- 作
服务的提供者,比服务使用方更清楚服务性能参数,如调用的超时时间,合理的重试
次数,等等 在Provider配置后,Consumer不配置则会使用 Provider 的配置值,即 Provider 配置可
以作消费者的缺省值
3 重试次数
- 当出现失败,自动切换并重试其它服务器,dubbo 重试的缺省值是 2 次,我们可以自行设置
- 在 provider 提供方配置:
<!-- 消费方连接第1次不算,再来重试3次,总共重试4次 -->
<dubbo:provider timeout="2000" retries="3"/>
修改实现类代码: 增加次数
@com.alibaba.dubbo.config.annotation.Service
public class HelloServiceImpl implements HelloService {
int a;
@Override
public String sayHello(String name) {
System.out.println("被调用第"+(++a)+"次");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "Hello," + name + "!!!";
}
}
可以看到 重试了 3 次 第一次不算

引入问题
并不是所有的方法都适合设置重试次数
- 幂等方法:适合(当参数一样,无论执行多少次,结果是一样的,例如:查询,修改)
- 非幂等方法:不适合(当参数一样,执行结果不一样,例如:删除,添加)
我们需要单独为某个方法设置重试次数
- 需要再添加一个方法,作对比
- 提供方接口添加 sayNo()方法并实现
public interface HelloService {
String sayHello(String name);
String no();
}
@com.alibaba.dubbo.config.annotation.Service
public class HelloServiceImpl implements HelloService {
int a,b;
@Override
public String sayHello(String name) {
System.out.println("sayHello被调用第"+(++a)+"次");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "Hello," + name + "!!!";
}
@Override
public String no() {
System.out.println("no被调用第"+(++b)+"次");
return "no";
}
}
- 消费方接口添加 sayNo()方法声明
public interface HelloService {
String sayHello(String name);
String no();
}
- 消费方 controller
@RestController
public class HelloAction {
// Resource 注解 指定名称注入
@Resource(name = "helloService")
private HelloService hs;
@RequestMapping("hello/{name}")
@ResponseBody
public String hello(@PathVariable String name) {
return hs.sayHello(name);
}
@RequestMapping("no")
@ResponseBody
public String no() {
return hs.no();
}
}
- 消费方配置方法重试次数
<dubbo:reference interface="service.HelloService" id="helloService">
<dubbo:method name="sayHello" retries="3"/>
<dubbo:method name="no" retries="0"/>
</dubbo:reference>
启动项目,访问
可以看到,我们为每种方法配置的重试次数成功了

4 多版本
- 一个接口,多个(版本的)实现类,可以使用定义版本的方式引入
- 为 HelloService 接口定义两个实现类,提供者修改配置:
配置文件
为 HelloService 定义了两个版本
<dubbo:service interface="service.HelloService" class="service.impl.HelloServiceImpl1" version="1.0.0">
</dubbo:service>
<dubbo:service interface="service.HelloService" class="service.impl.HelloServiceImpl2" version="2.0.0">
</dubbo:service>
修改实现类
- 复制 HelloServiceImpl 重命名为 1 和 2
- 分别为每个实现类标识版本信息

- 因为提供者定义了版本所以消费者就可以根据 version 的版本,选择具体的服务版本 这里是消费者配置文件

注意:消费者的控制层要改为自动注入,因为@Reference 注解和 dubbo:reference在这里冲突
- Resource 注解默认是根据变量名去 spring 容器中找对应的 bean 的
- 需要在直接参数中配置 bean 的名称 和 上面图中 id 对应

启动测试
注意 每次修改配置文件 都需要重启项目
当消费者的版本修改为 version="*",那么就会随机调用服务提供者的版本
这是访问多次 http://localhost:8002/no 控制台输出的信息

5 本地存根
为什么要有本地存根?
- 目前我们的分布式架构搭建起来有一个严重的问题,就是所有的操作全都是 消费者发起,由服务
提供者执行- 消费者动动嘴皮子却什么活都不干,这样会让提供者很累,例如简单的参数验证,消费者完全能够
胜任,把合法的参数再发送给提供者执行,效率高了,提供者也没那么累了- 例如:去房产局办理房屋过户,请带好自己的证件和资料,如果什么都不带,那么办理过户手续会
很麻烦,得先调查你有什么贷款,有没有抵押,不动产证是不是你本人,复印资料等操作。一天肯
定办不完。明天还要来。如果你能提前将这些东西准备好,办理过户,1 个小时足矣,这就是“房产
中介办事效率高的原因”- 话不多说,
先在消费者处理一些业务逻辑,再调用提供者的过程,就是“本地存根”
示例代码
代码实现肯定在 消费者,创建一个 HelloServiceStub 类并且实现 HelloService 接口
注意:必须使用构造方法的方式注入

public class HelloServiceStub implements HelloService {
private HelloService helloService;
// 注入HelloService
public HelloServiceStub(HelloService helloService) {
this.helloService = helloService;
}
@Override
public String sayHello(String name) {
System.out.println("本地存根数据验证。。。");
if(!StringUtils.isEmpty(name)){
return helloService.sayHello(name);
}
return "i am sorry!";
}
@Override
public String no() {
return helloService.no();
}
}
修改消费者配置文件
- 添加的是红框位置的参数

<dubbo:reference interface="service.HelloService" id="helloService" version="*" stub="service.impl.HelloServiceStub">
<dubbo:method name="sayHello" retries="3"/>
<dubbo:method name="no" retries="0"/>
</dubbo:reference>
老样子,clean项目 然后打包启动
- 因为我们只对 sayHello 方法进行了存根校验,所以访问
- http://localhost:8002/hello/zhangsan
负载均衡策略
- 负载均衡(Load Balance), 其实就是将请求分摊到多个操作单元上进行执行,从而共同完成工作
任务。- 简单的说,好多台服务器,不能总是让一台服务器干活,应该“雨露均沾”
- dubbo 一共提供 4 种策略,缺省为 random 随机分配调用

示例代码
- 修改提供者配置并启动 3 个提供者,让消费者对其进行访问
- tomcat 端口 8001,8002,8003
- provider 端口 20881,20882,20883
<dubbo:provider timeout="2000" retries="3" port="20881"/>

HelloServiceImpl2 类,服务器 1,服务器 2,服务器 3
- 在每次修改 tomcat 端口号 和 provider 端口是 修改 HelloServiceImpl2 的内容
- 因为我这里用的是 2.0.0 的版本,所以修改的是 HelloServiceImpl2 的内容

启动 consumer 进行测试
启动一个消费者,三个提供者
- 底下我已经访问了一次,当我们访问多次,去控制台查看输出信息时,会发现他是随机的去调用提供者

消费方修改权重
<dubbo:reference loadbalance="roundrobin" interface="service.HelloService" id="helloService" version="2.0.0" stub="service.impl.HelloServiceStub">
<dubbo:method name="sayHello" retries="3"/>
<dubbo:method name="no" retries="0"/>
</dubbo:reference>

- 最好使用管理端修改权重

然后启动测试即可
高可用
1 zookeeper 宕机
- zookeeper 注册中心宕机,还可以消费 dubbo 暴露的服务
- 监控中心宕掉不影响使用,只是丢失部分采样数据
数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
注册中心对等集群,任意一台宕掉后,将自动切换到另一台
注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
服务提供者无状态,任意一台宕掉后,不影响使用
服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复- 测试:
- 正常发出请求
- 关闭 zookeeper:./zkServer.sh stop
- 消费者仍然可以正常消费
服务降级
- 壁虎遇到危险会自动脱落尾巴,目的是损失不重要的东西,保住重要的
- 服务降级,就是根据实际的情况和流量,对一些服务有策略的停止或换种简单的方式处理,从而释
放服务器的资源来保证核心业务的正常运行
1 为什么要服务降级
- 而为什么要使用服务降级,这是防止分布式服务发生雪崩效应
- 什么是雪崩?就是蝴蝶效应,当一个请求发生超时,一直等待着服务响应,那么在高并发情况下,
很多请求都是因为这样一直等着响应,直到服务资源耗尽产生宕机,而宕机之后会导致分布式其他
服务调用该宕机的服务也会出现资源耗尽宕机,这样下去将导致整个分布式服务都瘫痪,这就是雪
崩。
2 服务降级实现方式
- 在 管理控制台配置服务降级:屏蔽和容错
- 屏蔽:mock=force:return+null 表示消费方对该服务的方法调用都 直接返回 null 值,不发起远程
调用。用来屏蔽不重要服务不可用时对调用方的影响。- 容错:mock=fail:return+null 表示消费方对该服务的方法调用在 失败后,再返回 null 值,不抛异
常。用来容忍不重要服务不稳定时对调用方的影响。
10 Dubbo 配置实战的更多相关文章
- PHP-5.5.10+Apache httpd-2.4.9在Windows系统下配置实战
原文 PHP-5.5.10+Apache httpd-2.4.9在Windows系统下配置实战 环境配置: 程序准备: PHP windows版本下载地址: http://windows.php. ...
- 深入浅出 SSL 管理配置实战
我们生活在一个信息大爆炸的时代,几乎每天都在和互联网打交道,购物.网银转账.支付宝付款.搜索信息.查看邮件.观看视频.微信聊天.上网冲浪.阅读新闻等,无不时时刻刻在和网络打交道.那如何保护网络安全就相 ...
- DUBBO配置规则详解
研究DUBBO也已经大半年了,对它的大部分源码进行了分析,以及对它的内部机制有了比较深入的了解,以及各个模块的实现.DUBBO包含很多内容,如果想了解DUBBO第一步就是启动它,从而可以很好的使用它, ...
- dubbo配置清单-超详细版
服务发布者 在服务发布者的springboot主配置文件application.properties中添加dubbo配置 #dubbo服务名 spring.dubbo.application.name ...
- dubbo配置指南
dubbo配置指南 SLA配置在此完成!Service Layer Agreement ApplicationConfig 应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者. Regist ...
- zabbix proxy配置实战案例
zabbix proxy配置实战案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.zabbix proxy概述 上一篇博客我们分享了zabbix agent有两种工作模式,即 ...
- Sentry 监控 - Snuba 数据中台本地开发环境配置实战
系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...
- kafka0.9.0及0.10.0配置属性
问题导读1.borker包含哪些属性?2.Producer包含哪些属性?3.Consumer如何配置?borker(0.9.0及0.10.0)配置Kafka日志本身是由多个日志段组成(log segm ...
- suse linux 10 下配置vpn服务器(pptp)
一.安装所需的软件包: pptpd-*.rpm ppp-*.rpm pptp-*.rpm 一般情况下系统已经将pptp和ppp包安装好了,所以只需安装pptpd ...
随机推荐
- js项目案例
2021.04.12 --mouseover抖动情况之一
- [ Module ] 环境变量管理工具 Module 安装和使用
https://www.cnblogs.com/yeungchie/ 1. 工具下载 手动下载 modules-5.1.0 点击下载 wget 下载 wget https://jaist.dl.sou ...
- 442. Find All Duplicates in an Array - LeetCode
Question 442. Find All Duplicates in an Array Solution 题目大意:在数据中找重复两次的数 思路:数组排序,前一个与后一个相同的即为要找的数 Jav ...
- JAVA数组案例!
数组的用例 一.案例需求: 有这样的一个数组,元素是{68,27,95,88,171,996,51,210}.求出该数组中满足要求的元素和, 要求是:求和的元素个位和十位都不能是7,并且只能是偶数如何 ...
- 【网站】windows phpstudy v8.1搭建https
这两天在搭建微擎,使用了官方推荐的一键安装环境,在搭建完站点后,想开启https. 发现如下图所示,无论关闭网站,还是关闭nginx.都无法建立https.网上也找不到相关流程,后来试着关闭nginx ...
- IDEA初始化基础配置
0.前言 这篇博客是给认识的那帮新手搞的,刚进入IT行业的崽们 这个东西配置好了,也可以选择弄成在线文档,下一次安装IDEA时,有一个import导入配置,然后就可以自己配置好了( 虽然方便,但不建议 ...
- centos6搭建mysql
目前CentOS6.5及一下版本基本上被官方给放弃更新了,但是考虑到忠实粉丝迟迟不肯放手,所以还留了入口但是非常有限 1.搭建mysql 可参照:https://blog.csdn.net/huang ...
- Java 基础常见知识点&面试题总结(中),2022 最新版!| JavaGuide
你好,我是 Guide.秋招即将到来,我对 JavaGuide 的内容进行了重构完善,公众号同步一下最新更新,希望能够帮助你. 上篇:Java 基础常见知识点&面试题总结(上),2022 最新 ...
- 彰显个性│制作一个独一无二的动态 svg 头像
一.头像预览 看一下博主的动态图像,是不是很炫酷,想不想拥有一个? 这是一个 svg 图片,svg 图片不仅可以通过制图软件制作外,其实也可以通过代码进行开发 因为 svg 本质上是一个下 xml 文 ...
- 在jupyternotebook中写C/C++
在jupyter notebook中写C/C++,最大的好处就是不用写main()函数,直接调用写好的函数即可执行. #include<stdio.h> int sum(int a,int ...




