为了避免微服务中因为启动某一个服务宕机,而导致“雪崩”,使整个应用阻塞;
熔断器Hystrix使用了线程隔离和服务降级的方式,提高整体应用的容错能力。
我使用的SpringCloud版本是Hoxton.SR3
线程隔离:Hystrix使用自己的线程池,和主应用服务器线程隔离开来。每个服务都使用独立的线程池。
服务降级:优先保证核心服务可用,非核心服务不可用或若可用。
当某个服务的线程池已满或者响应时间过长,就会响应一个友好提示,而不是无限阻塞或者直接报错。
Hystrix实现了弹性容错,当情况好转之后可以自动重连。
服务消费方:
Eureka-client包已经依赖导入了Hystrix,可以直接使用,无需再导包才怪咧
第一步:导包
上面那个是Eureka-client包中的,不一样。必须导入以下依赖才可以使用@HystrixCommand注解
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>
第二步:启动类加注解
package com.company; import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.SpringCloudApplication;import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.cloud.netflix.ribbon.RibbonClient;import org.springframework.context.annotation.Bean;import org.springframework.web.client.RestTemplate; //@EnableDiscoveryClient //启用Eureka客户端//@SpringBootApplication//@EnableCircuitBreaker //启用Hystrix熔断功能@SpringCloudApplication //替代以上三个注解public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class); } @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); }}
第三步:
@GetMapping("/{id}")@HystrixCommand(defaultFallback = "getUserByIdFallBack")public String getUserById(@PathVariable("id")Long id){ String url="http://user-service/user/"+id; long start=System.currentTimeMillis(); String user = template.getForObject(url, String.class); long end=System.currentTimeMillis(); log.debug("调用时长:{}",end-start); return user;} public String getUserByIdFallBack(Long id){ return "很抱歉,服务器正忙,请稍后再试。";}尽管方法的参数和返回值都一致,还是报了fallback method wasn‘t found: getUserByIdFallBack([])错误,求大佬指教一下。
使用配置当前类降级函数,配置成功
package com.company.controller; import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate; @RestController@RequestMapping("/consumer")@Slf4j@DefaultProperties(defaultFallback = "getUserByIdFallBack")//指定默认降级函数public class ConsumerController { @Autowired private RestTemplate template; @GetMapping("/{id}") @HystrixCommand //启用熔断降级 public String getUserById(@PathVariable("id")Long id){ String url="http://user-service/user/"+id; long start=System.currentTimeMillis(); String user = template.getForObject(url, String.class); long end=System.currentTimeMillis(); log.debug("调用时长:{}",end-start); return user; } //注意此时的返回值没有限制,不能写参数,因为这是当前类通用的降级方法 public String getUserByIdFallBack(){ return "很抱歉,服务器正忙,请稍后再试。"; } }
默认调用超时时间为1秒,超过一秒就会触发熔断
服务提供方:
添加休眠模仿超时
package com.company.service.impl; import com.company.mapper.UserMapper;import com.company.pojo.User;import com.company.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional; import java.util.Random;import java.util.concurrent.TimeUnit; @Service("userService")public class UserServiceImpl implements UserService{ @Autowired private UserMapper userMapper; @Override public User findOne(Long id) { try { TimeUnit.MILLISECONDS.sleep(new Random().nextInt(2000)); } catch (InterruptedException e) { e.printStackTrace(); } return userMapper.selectByPrimaryKey(id); } @Override @Transactional public void insert(User user) { user.setUserName("test5"); user.setPassword("test5"); user.setName("ceshi5"); userMapper.insert(user);// int i=10/0; }}
测试结果,调用时长超过1秒的都触发了,低于1秒的都响应成功。
原文地址:https://www.cnblogs.com/zou-rong/p/12589390.html
时间: 2024-10-07 10:39:39