Dubbo快速入门学习(二)
Dubbo集群容错:
1)服务路由
服务路由包含一条路由规则,路由规则决定了服务消费者的调用目标,即规定了服务消费者可调用哪些服务提供者
dubbo提供三种服务路由实现,分别为: (条件路由ConditionRouter、脚本路由ScriptRouter、标签路由TagRouter)
本章重点分析条件路由
条件路由规则的格式:
[服务消费者匹配条件] => [服务提供者匹配条件]
host = 10.20.153.10 => host = 10.20.153.11
该条规则表示 IP 为 10.20.153.10 的服务消费者只可调用 IP 为 10.20.153.11 机器上的服务,不可调用其他机器上的服务。
如果服务消费者匹配条件为空,表示不对服务消费者进行限制。
如果服务提供者匹配条件为空,表示对某些服务消费者禁用服务。
常见路由配置:
白名单:
host != 10.20.153.10,10.20.153.11 =>
意思:端口号不是(10.20.153.10,10.20.153.11)的不可以访问
黑名单:
host = 10.20.153.10,10.20.153.11 =>
意思:端口号是(10.20.153.10,10.20.153.11)的不可以访问
读写分离:
method = fifind,list,get,is => host = 172.22.3.94,172.22.3.95,172.22.3.96
意思:方法是(fifind , list , get , is)的访问ip为(172.22.3.94,172.22.3.95,172.22.3.96)的服务端
method != fifind,list,get,is => host = 172.22.3.97,172.22.3.98
意思:方法不是(fifind , list , get , is)的访问ip为(172.22.3.94,172.22.3.95,172.22.3.96)的服务端
前后台分离:
application = front => host = 172.22.3.91,172.22.3.92,172.22.3.93
意思:应用是(front【前端】)的访问ip为(172.22.3.91,172.22.3.92,172.22.3.93)的服务端
application != front => host = 172.22.3.94,172.22.3.95,172.22.3.96
意思:应用不是(front【前端】)的访问ip为(172.22.3.91,172.22.3.92,172.22.3.93)的服务端
2)集群容错
- Failover Cluster 失败自动切换,当出现失败,重试其它服务器。(缺省) 通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)。
重试次数配置如下:
<dubbo:service retries="2" />
或
<dubbo:reference retries="2" />
- Failfast Cluster 快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
- Failsafe Cluster 失败安全,出现异常时,直接忽略。通常用于写入日志等操作。
- Failback Cluster 失败自动恢复,后台记录失败请求,定时重发。 通常用于消息通知操作。
- Forking Cluster 并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过forks="2"来设置最大并行数。
- Broadcast Cluster 广播调用所有提供者,逐个调用,任意一台报错则报错。 通常用于通知所有提供者更新缓存或日志等本地资源信息。
3)负载均衡
负载均衡: 在集群负载均衡时,Dubbo提供多种均衡策略,缺省random随机调用
- Random LoadBalance: 按照权重设置随机概率,无状态
- RoundRobin LoadBalance: 轮询,有状态
- LeastActive LoadBalance: 最少活跃数随机,方法维度的统计服务调用数
- ConsistentHash LoadBalance:一致性Hash
服务治理
1)服务降级
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtensi on();
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" ));
2)整合hystrix
A) springboot官方提供了对hystrix的集成,直接在pom.xml里加入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
B) Application启动类中新增@EnableHystrix来启用hystrix starter
C) provider增加@HystrixCommand
D) Consumer method上配置@HystrixCommand(fallbackMethod= methodName))
dubbo线程IO模型
BIO
NIO
我们用一幅图来对比一下IO与NIO:
举个栗子:
SPI
SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。
这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。SPI 机制在第三方框架中也有所应用,
比如 Dubbo 就是通过 SPI 机制加载所有的组件。不过,Dubbo 并未使用 Java 原生的SPI 机制,而是对其进行了增强,使其能够更好的满足需求。
在 Dubbo 中,SPI 是一个非常重要的模块。
1)JAVA原生SPI机制
a)新建一个接口Czbk和两个实现类Czxy、Itheima
包结构图:
代码:
package com.itheima.service; public interface Czbk { void service(); } //----------------------------------------- package com.itheima.service.impl; import com.itheima.service.Czbk; public class Czxy implements Czbk { public void service() { System.out.println("kerrykerrykerry"); } } //----------------------------------------- package com.itheima.service.impl; import com.itheima.service.Czbk; public class Itheima implements Czbk { public void service() { System.out.println("carrycarrycarry"); } }
代码:
com.itheima.service.impl.Czxy
com.itheima.service.impl.Itheima
package com.itheima.test; import com.itheima.service.Czbk; import java.util.Iterator; import java.util.ServiceLoader; public class SpiTest { public static void main(String[] args) { ServiceLoader<Czbk> serviceLoader = ServiceLoader.load(Czbk.class); Iterator<Czbk> iterator = serviceLoader.iterator(); while (iterator.hasNext()){ Czbk czbkImpl = iterator.next(); czbkImpl.service(); } } }
运行结果:
配置的优先级
方法级优先,接口级次之,全局配置再次之。
如果级别一样,则消费方优先,提供方次之。
其中,服务提供方配置,通过 URL 经由注册中心传递给消费方
Redis作为注册中心时调用过程
1.服务提供方启动时,向 Key:/dubbo/XXXServer/providers 下,添加当前提供者的地址
2.并向 Channel:/dubbo/com.wow.DemoService/providers 发送 register 事件
3.服务消费方启动时,从 Channel:/dubbo/com.wow.DemoService/providers 订阅 register 和 unregister 事件
4.并向 Key:/dubbo/com.wow.DemoService/providers 下,添加当前消费者的地址
5.服务消费方收到 register 和 unregister 事件后,从 Key:/dubbo/com.wow.DemoService/providers 下获取提供者地址列表
zookeeper作为注册中心调用过程
1.服务提供者启动时: 向 /dubbo/com.wow.DemoService/providers 目录下写入自己的 URL 地址
2. 服务消费者启动时: 订阅 /dubbo/com.wow.DemoService/providers 目录下的提供者 URL 地址。并向 /dubbo/com.wow.DemoService/consumers 目录下写入自己的 URL 地址
3.监控中心启动时: 订阅 /dubbo/com.wow.DemoService 目录下的所有提供者和消费者 URL 地址