Hystrix的熔断与降级
1、熔断即服务发生错误时,并不是变成500或其他错误中,而是跳转到一个错误页面中
1)先配置eureka
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
主启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer_7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaServer_7001.class,args);
}
}
yml文件:
server:
port: 7001
spring:
application:
name: EurekaServer7001
eureka:
client:
register-with-eureka: false # 是否需要注册自己
fetch-registry: false # 是否需要从注册中心拉去服务 不需要拉取服务
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
instance:
hostname: localhost # 主机名
2、配置服务提供者
导入依赖
这是springcloud-api的依赖
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>springcloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
</dependencies>
server:
port: 8001
spring:
application:
name: springcloud-provider-8001 # 名字
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db05?useUnicode=true
username: root
password: 123456
type: com.alibaba.druid.pool.DruidDataSource
mybatis:
type-aliases-package: com.ycz.springCloud.entity
configuration:
map-underscore-to-camel-case: true # 开启驼峰映射
mapper-locations: classpath:mapper/*.xml
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/ # 注册的地址
instance:
instance-id: provider_8001
mapper
import com.ycz.springCloud.entity.Movie;
import org.apache.ibatis.annotations.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
/**
* (Movie)表数据库访问层
*
* @author makejava
* @since 2021-12-17 09:12:13
*/
@Mapper
public interface MovieMapper extends tk.mybatis.mapper.common.Mapper<Movie>,MySqlMapper<Movie> {
}
service
package com.ycz.springCloud.service;
import com.ycz.springCloud.entity.Movie;
/**
* (Movie)表服务接口
*
* @author makejava
* @since 2021-12-17 09:12:14
*/
public interface MovieService {
Object getAll();
Object getOne(Integer id);
}
serviceImpl
package com.ycz.springCloud.service.impl;
import com.ycz.springCloud.entity.Movie;
import com.ycz.springCloud.mapper.MovieMapper;
import com.ycz.springCloud.service.MovieService;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
/**
* (Movie)表服务实现类
*
* @author makejava
* @since 2021-12-17 09:12:15
*/
@Service("movieService")
public class MovieServiceImpl implements MovieService {
@Autowired
private MovieMapper movieMapper;
public Object getAll() {
return movieMapper.selectAll();
}
public Object getOne(Integer id) {
return movieMapper.selectByPrimaryKey(id);
}
}
controller
import com.ycz.springCloud.entity.Movie;
import com.ycz.springCloud.service.MovieService;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
/**
* (Movie)表控制层
*
* @author makejava
* @since 2021-12-17 09:12:12
*/
@RestController
@RequestMapping("movie")
public class MovieController {
/**
* 服务对象
*/
@Autowired
private MovieService movieService;
@RequestMapping("getAll")
public Object getAll(){
return movieService.getAll();
}
@RequestMapping("/getOne/{id}")
public Object getOne(@PathVariable Integer id){
return movieService.getOne(id);
}
}
3、配置消费者
1)导入依赖
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>springcloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
2)配置负载均衡
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ApplicationConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
application.yml的配置
server:
port: 9005
spring:
application:
name: userconsumer-9005
## 服务降级
feign:
hystrix:
enabled: true
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
instance-id: userconsumer-9005
service:
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient(value = "SPRINGCLOUD-PROVIDER-8001",fallbackFactory = UserServiceFallBackFactory.class)
public interface UserService {
@RequestMapping("/movie/getAll")
Object getAll();
@RequestMapping("/movie/getOne/{id}")
Object get(@PathVariable("id") Integer id);
}
服务降级
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class UserServiceFallBackFactory implements FallbackFactory<UserService> {
@Override
public UserService create(Throwable throwable) {
return new UserService() {
@Override
public Object getAll() {
Map<String,Object> resultMap=new HashMap<>();
resultMap.put("code",4445);
resultMap.put("msg","降级,无id");
return resultMap;
}
@Override
public Object get(Integer id) {
Map<String,Object> resultMap=new HashMap<>();
resultMap.put("code",4444);
resultMap.put("msg","降级,无id");
return resultMap;
}
};
}
}
Controller
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.ycz.springCloud.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RequestMapping("/user/feign")
@RestController
@PropertySource("classpath:application.yml")
public class UserFeignController {
@Value("${server.port}")
private String port;
@Autowired
private UserService userService;
@RequestMapping("/getAll")
@HystrixCommand(fallbackMethod = "error")
public Object getAll(){
// int i=1/0;
Map<String,Object> resultMap=new HashMap<>();
resultMap.put("code",200);
resultMap.put("port",port);
resultMap.put("data",userService.getAll());
return resultMap;
}
public Object error(){
Map<String,Object> resultMap=new HashMap<>();
resultMap.put("code",40000002);
resultMap.put("port",port);
resultMap.put("msg","错误");
resultMap.put("data",null);
return resultMap;
}
@RequestMapping("/get/{id}")
public Object get(@PathVariable("id") Integer id){
return userService.get(id);
}
}
主启动类:
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.ycz.springCloud")
@EnableCircuitBreaker // 熔断
@EnableHystrix //降级?
public class UserConsumer_9005 {
public static void main(String[] args) {
SpringApplication.run(UserConsumer_9005.class,args);
}
}
测试
先打开eureka,再打开服务提供者,再打开消费者
显示都注册上

打开服务测试:

测试服务熔断
在
@RequestMapping("/getAll")
@HystrixCommand(fallbackMethod = "error")
public Object getAll(){
int i=1/0; //这里显示一个错误,看下面会发生什么事情
Map<String,Object> resultMap=new HashMap<>();
resultMap.put("code",200);
resultMap.put("port",port);
resultMap.put("data",userService.getAll());
return resultMap;
}
public Object error(){
Map<String,Object> resultMap=new HashMap<>();
resultMap.put("code",40000002);
resultMap.put("port",port);
resultMap.put("msg","错误");
resultMap.put("data",null);
return resultMap;
}
测试:

现在把提供者的服务关了
有熔断机制的会走熔断
无熔断机制的会走降级

版权声明:本文为weixin_48319193原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。