Dubbo 高可用设计

高可用设计主要体现在如下几方面:
1)监控中心宕机不影响服务的调用,只是会丢失一些统计监控数据
2)注册中心对等集群中,任意一台宕机后,将自动切换到另一台
3)注册中心宕机后,服务提供者和服务消费者仍可通过本地缓存进行通讯
4)服务提供者全部宕机后,服务消费者应用将无法使用,并将无限次重连等待服务提供者恢复

Dubbo 直连

dubbo 直连只要在消费端的服务类中 @Reference 注解上加入 url 属性,指定服务提供者暴露的地址即可。
1)启动 zookeeper,再启动服务提供者和消费者测试,确保没有代码错误。

@Service
public class ConsumerServiceImpl implements ConsumerService {
    
    

	@Reference(url="127.0.0.1:20880")
	ProviderService providerService;
	
	public List<Student> useStuInfo(String sname) {
    
    
		
		List<Student> stuList = providerService.getStuList(sname);
		System.out.println("------------------调用provider方法完成----------------------");
		return stuList;
	}

}

2)关闭 consumer 服务,在 @Reference 注解中加入 url 属性,关掉 zookeeper,启动 consumer 服务,发现服务消费者依然可以调用服务提供者提供的方法。

我一开始没启动 zookeeper,直接启动服务提供者和消费者,提供者一直报错重试,消费者报错后直接停了。
先启动一次 zookeeper,进行一次成功的调用后,再配置直连才测试成功

Dubbo 负载均衡

在负载均衡集群中, Dubbo 提供了多种负载均衡策略,默认为 Random 随机调用。
在这里插入图片描述

负载均衡策略

1)Random LoadBalance
随机,按权重设置随机概率。
消费端发送一次请求,可能被ABC任意一个服务处理。假如是A处理的,如果另一个请求过来,有可能还是A,也有可能是B,也可能是C。在大量请求下,A B C 处理的请求分别占 1/7 2/7 4/7 。

2)RoundRobin LoadBalance
轮询,按公约后的权重设置轮询比率。
按一定的顺序把请求分发到各服务中。按上图 A B C 的顺序,那么请求被分到各服务的顺序是 A B C B C C C

3)LeastActive LoadBalance
最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
哪个服务处理的请求最快就分发到哪个服务去处理。

4)ConsistentHash LoadBalance
一致性 Hash,相同参数的请求总是发到同一提供者。

配置负载均衡策略

  • 服务端服务级别
<dubbo:service interface="..." loadbalance="roundrobin" />
  • 客户端服务级别
<dubbo:reference interface="..." loadbalance="roundrobin" />
  • 服务端方法级别
<dubbo:service interface="...">
    <dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:service>
  • 客户端方法级别
<dubbo:reference interface="...">
    <dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:reference>
  • 注解方式
	@Reference(loadbalance = "roundrobin")
	ProviderService providerService;
@Service(loadbalance = "roundrobin")
@Component
public class ProviderServiceImpl implements ProviderService {
    
    
}

集群容错

容错方案

在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。
1)Failover Cluster
失败自动切换,当出现失败,重试其它服务器 。通常用于读操作,但重试会带来更长延迟。可通过 retries=" " 来设置重试次数(不含第一次)。

2)Failfast Cluster
快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。

3)Failsafe Cluster
失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。

4)Failback Cluster
失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。

5)Forking Cluster
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks=“2” 来设置最大并行数。

6)Broadcast Cluster
广播调用所有提供者,逐个调用,任意一台报错则报错 [2]。通常用于通知所有提供者更新缓存或日志等本地资源信息。

集群模式配置

按照以下示例在服务提供方和消费方配置集群模式

<dubbo:service cluster="failsafe" /><dubbo:reference cluster="failsafe" />

服务降级

可以通过服务降级功能临时屏蔽某个出错的非关键服务,并定义降级后的返回策略。
向注册中心写入动态配置覆盖规则:

RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://127.0.0.1:2181"));
registry.register(URL.valueOf("override://127.0.0.1/com.xiao.service.ProviderService?category=configurators&dynamic=false&application=foo&mock=force:return+null"));

其中:

  • mock=force:return+null 表示消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。
  • 还可以改为 mock=fail:return+null 表示消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。

这个配置可以在监控中心灵活开启关闭,分别是屏蔽和容错

服务降级示例
在服务提供端和消费端的 pom 文件加入 hystrix 依赖,学过 springcloud 的朋友都不陌生。

		<dependency>
	  		<groupId>org.springframework.cloud</groupId>
	  		<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
	  		<version>2.0.1.RELEASE</version>
	  	</dependency>

在服务提供端的方法上加入 @HystrixCommand 注解,并人为地制造异常

@Service
@Component
public class ProviderServiceImpl implements ProviderService {
    
    

	@HystrixCommand
	public List<Student> getStuList(String sname) {
    
    
		// 产生的随机数大于 0.5 时抛出异常
		if(Math.random() > 0.5) {
    
    
			throw new RuntimeException();
		}
		
		Student stu1 = new Student("01", "张三", 20);
		Student stu2 = new Student("05", "张三", 18);
		return Arrays.asList(stu1, stu2);
	}

}

在服务提供端的启动程序中加入 @EnableHystrix 启用 hystrix

@EnableHystrix
@EnableDubbo
@SpringBootApplication
public class ProviderApp {
    
    

	public static void main(String[] args) {
    
    
		SpringApplication.run(ProviderApp.class, args);
	}
}

在服务消费端的方法上加入 @HystrixCommand 注解,指定降级方法,并编写调用该方法出错后要调用的降级方法,降级方法的返回值和参数要与被原本调用的方法一致

@Service
public class ConsumerServiceImpl implements ConsumerService {
    
    

	@Reference
	ProviderService providerService;
	
	@HystrixCommand(fallbackMethod = "getTipsOrLocaldata")
	public List<Student> useStuInfo(String sname) {
    
    
		
		List<Student> stuList = providerService.getStuList(sname);
		System.out.println("------------------调用provider方法完成----------------------");
		return stuList;
	}
	
	// 降级方法
	public List<Student> getTipsOrLocaldata(String sname) {
    
    
		
		System.out.println("------------------调用provider方法出错啦----------------------");
		return Arrays.asList(new Student("error", "出错啦", 5), new Student("test", "本地数据", 5));
	}

}

在服务提供端的启动程序中加入 @EnableHystrix 启用 hystrix 。

启动 zookeeper,并启动服务提供者和服务消费者,多发送几次 http://localhost:8082/getStus?sname=xiao 请求,可看到返回的不同结果,控制台也打印了不同的信息。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Alias_fa/article/details/103173600
今日推荐