注册中心宕机,还能够消费dubbo暴露的服务html
绕开注册中心直连服务提供者java
@Reference(url="127.0.0.1:20888") // dubbo的注解 UserService userService; public List<UserAddress> initOrder(String userId) { return userService.getUserAddressList("1"); }
同一种服务提供者存在多份时须要负载均衡策略, loadbalancenode
随机负载均衡, 按照权重设置随机几率,随机调用量越大,分布越均匀,有利于动态调整提供者的权重spring
例: UserService一共三台,咱们根据实际的机器性能给这三个机器添加不一样的权重数据库
userService1 weight=100 userService2 weight=200 userService3 weight=300
这样这三台机器被随机调用到的比例就是1:2:3缓存
这是Dubbo默认的负载均衡机制安全
@SPI("random") public interface LoadBalance { @Adaptive({"loadbalance"}) <T> Invoker<T> select(List<Invoker<T>> var1, URL var2, Invocation var3) throws RpcException; }
假如一样存在三台相同的服务提供者, 不设置权重的话,消费者的会被均匀的按瞬间分发到这个三台机器上123123123...服务器
轮询, 按照公约后的权重值,设置查询比率 , 存在慢的提供者请求累积的问题, 这种方式的访问顺序也是提早就知道的,只不过添加上了权重的以后的顺序, 原来的123123... 可能变成了 123333并发
最少活跃调用数, 活跃数指的是调用先后的计时差,使慢的提供者接受更少的请求app
当用户的请求会先查询服务提供者列表中,而后选择活跃数最低的,也就是上次响应时间最短的机器
一致性Hash, 使相同参数的请求老是发到同一个提供者上,当某一台提供者挂掉时,本来该发送到这个服务提供者的请求会平摊到其余提供者身上,不会产生巨大的动荡
<dubbo:parameter key="hash.arguments" value="0,1" />
<dubbo:parameter key="hash.nodes" value="320" />
服务端服务级别 <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 = "random") @Reference(loadbalance = "roundrobin") @Reference(loadbalance = "leastactive") @Reference(loadbalance = "consistenthash")
在暴露服务是,在@Service注解上边添加 weight属性 @Service(weight="200")
在服务器压力剧增的状况下,根据实际的业务状况及流量,对一些服务和页面进行有策略的不处理或者换种简单方式处理的方式, 从而达到释放系统资源,维持系统核心功能的正常运做
实现: 向注册中心写入动态配置规则
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"));
上面配置的最后一条URL上,mock=force:return+null
,表示在服务消费者层面直接对用户的调用返回空,不行转发处理
最后的url位置还能够写成mock=fail:return+null
,表示消费者在对服务的调用方法失败后才返回null,用来缓冲服务调用不稳定时,对服务调用方的影响 ``
如图在控制台进行可视化界面消费者模块实现服务降级
服务在调用失败时,Dubbo提供了不少种容错方案
failover cluster 失败自动切换,当出现失败,重试其它服务器,但重试会带来更长延迟。可经过 retries="2" 来设置重试次数(不含第一次)。
重试次数配置以下: <dubbo:service retries="2" /> 或 <dubbo:reference retries="2" /> 或 <dubbo:reference> <dubbo:method name="findFoo" retries="2" /> </dubbo:reference>
Failfast Cluster 快速失败,只发起一次调用,失败当即报错。一般用于非幂等性的写操做,好比新增记录。
Failsafe Cluster 失败安全,出现异常时,直接忽略。一般用于写入审计日志等操做。
Failback Cluster 失败自动恢复,后台记录失败请求,定时重发。一般用于消息通知操做。
Forking Cluster 并行调用多个服务器,只要一个成功即返回。一般用于实时性要求较高的读操做,但须要浪费更多服务资源。可经过 forks="2" 来设置最大并行数。
Broadcast Cluster 广播调用全部提供者,逐个调用,任意一台报错则报错 [2]。一般用于通知全部提供者更新缓存或日志等本地资源信息。
按照如下示例在服务提供方和消费方配置集群模式 <dubbo:service cluster="failsafe" /> 或 <dubbo:reference cluster="failsafe" />
hystrix 旨在经过控制远程系统,服务和第三方的节点,从而对延迟和故障提供更强大的容错能力,Hystrix同时具有回退机制和断路器能力功能的线程和信号隔离,请求缓存,请求打包已经监控和配置的功能
hytrix的隔离策略有两种:
Hystrix默认的保护级别是THREAD,它出来超时保护还有额外的保护,通常当系统的负载特别大,每秒几百并发时,才选择信号量隔离,正常状况下使用默认的隔离级别
可使用execution.isolation.strategy属性指定隔离策略。
@HystrixCommand(fallbackMethod = "notfindback", commandProperties=@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE") ) public User findById( Long id) public User notfindback(Long id) { User user = new User(); user.setId(0L); return user; }
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.0.1.RELEASE</version> </dependency>
@EnableDubbo @EnableHystrix @SpringBootApplication public class ProviderApp { public static void main(String[] args) { SpringApplication.run(ProviderApp.class); } }
@Component @Service //使用dubbo的Service 对外保留服务 public class UserServiceImpl implements UserService { // 添加这个注解,将当期方法,交给Hystrix进行代理,当出现异常时,进行容错处理 @HystrixCommand public List<UserAddress> getUserAddressList(String userId) { UserAddress a1= new UserAddress(1,"张三","北京市朝阳区"); UserAddress a2= new UserAddress(2,"李四","山东济南"); if (Math.random()>0.5){ throw new RuntimeException(); } return Arrays.asList(a1,a2); } }
public class UserServiceImpl implements UserService{ // 注入这个被服务提供者支持的接口 @Reference private final UserService userService; // 提供构造函数 public UserServiceImpl(UserService userService) { this.userService = userService; } @Override @HystrixCommand(fallbackMethod = "correct") // 当出现错误时,回调correct方法 public List<UserAddress> getUserAddressList(String userId) { // 判空 if (!StringUtils.isEmpty(userId)){ System.err.println(); return userService.getUserAddressList(userId); } return null; } public List<UserAddress> correct(String userId) { return Collections.singletonList(new UserAddress(9, "correct", "correct")); } }
原文出处:https://www.cnblogs.com/ZhuChangwu/p/11569660.html