朋也的博客 » 首页 » 文章
作者:朋也
日期:2019-01-12
类别:spring-boot学习笔记
版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
上一篇博客使用springboot集成搭建了一个dubbo服务,这篇博客来总结一下dubbo的相关配置
从上到下配置优先级顺序
java -jar xxx.jar
的形式来启动,当然也可以在命令后面指定参数,比如 java -jar -Ddubbo.protocol.port=20880 xxx.jar
的形式来指定通信协议的端口,这种优先级是最高的一般整合springboot与dubbo,配置都会在 application.yml 里配置,如果想另外配置可以通过第一种方式写一个脚本指定线上环境的相关配置,其实也可以通过springboot的配置文件加载顺序来配置开发环境跟线上环境的不同
官方文档说明如下
Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 check=”true”。
可以通过 check=”false” 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。
另外,如果你的 Spring 容器是懒加载的,或者通过 API 编程延迟引用服务,请关闭 check,否则服务临时不可用时,会抛出异常,拿到 null 引用,如果 check=”false”,总是会返回引用,当服务恢复时,能自动连上。
也就是说把启动检查关了,就可以避免消费端启动服务的时候因为连不上服务提供者而报错了
这个配置有好有坏,开发环境下比较好,如果把启动检查关了,可以避免开发本地功能时还要一直开着服务提供者了,不过如果部署到正式环境了,建议还是开着检查比较好,这样可以及时发现服务提供者服务是否可用
但是,dubbo还有一个东西,monitor ,可以启动一个监控器服务,这样也可以实时查看服务提供者跟服务消费者是否可用
配置方法
可以配置 registry和consumer和@Reference注解上
放在 @Reference 注解上 关闭某个服务的启动时检查 (没有提供者时报错) @Reference(check=false)
放在registry和consumer两个上,就是全局配置了
dubbo:
registry:
check: false #关闭注册中心启动时检查 (注册订阅失败时报错)
consumer:
check: false #关闭所有服务的启动时检查 (没有提供者时报错)
上一篇博客就碰到这个坑了,dubbo为了服务的性能,默认超时时间是1000ms,就短短1s时间,没有响应就直接抛异常了
正巧,我写的那个demo里模拟一个发短信的请求,设置了一个 Thread.sleep() 大于1s了,一直报错,后来配置了个超时时间就正常了
超时可以配置在很多地方
这里配置生效有个优先级,官网上也给出了优先级两句好记的话
以 timeout 为例,显示了配置的查找顺序,其它 retries, loadbalance, actives 等类似:
重试次数就是调用服务失败后系统自动重试的意思,默认调用的那一次不算,也就是说配置 retries=2
后,在消费端调用服务(第一次)失败了,这时候它会自动重试,这里配置的重试是2次,也就是说如果一个服务一直失败,那么这个服务会被调用3次
重试功能还有一个好处,如果服务提供端部署了多台服务,那么如果一台服务器上调用失败了,dubbo会自动尝试调用其它服务器上的相同服务
需要注意的是:幂等操作,非幂等操作
在服务提供者里可以对服务配置上版本,然后在消费方就可以指定使用服务提供方提供的哪个版本来处理服务,配置方法
服务提供端
@Service(version="1.0.0") // 注意这个注解是dubbo里提供的,不是Spring包里提供的那个
服务消费端
@Reference(version = "1.0.0")
当然如果服务提供端提供了多个版本的相同服务,在服务消费端可以配置 version="*"
的方式,让dubbo随机的调用不同版本的服务
如果注册中心使用zookeeper,服务端跟消费端都运行好好的,但由于一些不可控的原因,zookeeper挂了,那么这时候消费端跟服务端还是可以通信的 因为当消费端通过注册中心与服务端建议连接后,会在本地有个服务端连接的缓存信息,下次再请求发现注册中心不可用了,就会从缓存里拿连接信息
当然dubbo如果不用注册中心也是可以用的,消费端可以在消费服务上配置上指定服务端连接地址,达到与服务端直连的目的,照样可以通信
配置方法,假如服务端配置的通信地址是 127.0.0.1:20880
消费端
@RestController
public class SmsController {
@Reference(url = "127.0.0.1:20880")
private SmsService smsService;
@GetMapping("/sendSms")
public String sendSms(String mobile, String content, String platform) {
return smsService.sendSms(mobile, content, platform);
}
}
默认策略是 Random LoadBalance
策略 | 配置关键字 | 说明 |
---|---|---|
Random LoadBalance | random | 随机,按权重设置随机概率。 在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。 |
RoundRobin LoadBalance | roundrobin | 轮询,按公约后的权重设置轮询比率。 存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。 |
LeastActive LoadBalance | leastactive | 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。 使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。 |
ConsistentHash LoadBalance | 没找到,知道的大佬烦请告知 : ) | 一致性 Hash,相同参数的请求总是发到同一提供者。 当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。 算法参见:http://en.wikipedia.org/wiki/Consistent_hashing 缺省只对第一个参数 Hash,如果要修改,请配置 <dubbo:parameter key="hash.arguments" value="0,1" /> 缺省用 160 份虚拟节点,如果要修改,请配置 |
当服务器压力过大的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心服务的正常动作或高效动作
服务降级有两种方式
说白了,就是第一种方法不走service方法,直接就返回null了,第二种方法还走了一下,然后才返回的null
配置方法:
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null"));
上面提到的失败重试就是一种容错机制
dubbo提供了很多的容错机制
配置方法
集群模式配置 按照以下示例在服务提供方和消费方配置集群模式
<dubbo:service cluster="failsafe" />
或 <dubbo:reference cluster="failsafe" />
也可以使用第三方的容错框架来解决 比如 Hystrix
这货是 springcloud里集成的,在dubbo里也可以用
首先在服务提供方引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
启动类上添加注解,开启容错功能
@EnableDubbo
@EnableHystrix
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
在服务实现类上加上注解 @HystrixCommand
@HystrixCommand
public String sendSms(String mobile, String content, String platform) {}
服务消费方
引入依赖,启动类上添加注解,开启容错功能 不多说
在消费方调用服务方的service类上添加出错回调方法
@Component
public class MySmsService {
@Reference
private SmsService smsService;
// 配置出错后回调的方法
@HystrixCommand(fallbackMethod = "errorHandler")
public String sendSms(String mobile, String content, String platform) {
if (Math.random() < 0.5) throw new RuntimeException(); // 模拟一下异常
return smsService.sendSms(mobile, content, platform);
}
// 出错了就走这个方法,处理一下出错后的操作
public String errorHandler(String mobile, String content, String platform) {
return "error handler";
}
}