hystrix基础操作

1基础demo

  1. 完成父模块
  2. 完成eureka子模块
  3. 完成服务提供者子模块
  4. 完成服务消费者子模块

1.完成父模块

新建springboot项目,删除src文件夹

导入maven依赖

复制代码
<properties>
     <java.version>1.8</java.version>
     <spring.cloud-version>Hoxton.SR3</spring.cloud-version>
</properties>
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
复制代码

2.完成eureka子模块

新建子模块eureka

导入maven依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

编写application.yml配置文件

复制代码
server:
  port: 7001
spring:
  application:
    name: cs-eureka
eureka:
  instance:
    # 地址 通常是域名
    hostname: localhost
  client:
    service-url: # 客户端与EurekaServer的交互地址,如果是集群,需要多个地址
      defaultZone: http://localhost:7001/eureka/
    register-with-eureka: false # 是不是将自己注册进eureka 默认 true
    fetch-registry: false # 自己就是服务,不需要从eurekaServer获取服务信息,默认true
复制代码

编写主启动类

@SpringBootApplication
@EnableEurekaServer //开启服务
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}

3.完成服务提供者子模块

新建子模块provider-hystrix

导入maven依赖

复制代码
<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
复制代码

编写application配置文件

复制代码
spring:
  application:
    name: provider-hystrix
server:
  port: 8001
eureka:
  client:
    # eureka服务端的路劲
    service-url:
      defaultZone: http://localhost:7001/eureka/
    # 如果不想将改服务注册进注册中心,一定要写成false
    register-with-eureka: true
    fetch-registry: true
复制代码

编写主启动类

@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
public class HystrixApplication {
    public static void main(String[] args) {
        SpringApplication.run(HystrixApplication.class,args);
    }
}

编写HystrixController.java

降级的方法写在提供者或消费者中都可以,我写到消费者中

复制代码
@RestController
@RequestMapping("/provider")
public class HystrixController {

    @GetMapping("/hystrix/ok")
    public String providerHystrixOk(){
        return Thread.currentThread().getName() + "providerHystrixOk";
    }

    @GetMapping("/hystrix/timeout")
    public String providerHystrixTimeOut(){
        int time=3;
        //休眠3秒
        try {
            TimeUnit.SECONDS.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return Thread.currentThread().getName() + "providerHystrixTimeOut,耗时" + time;
    }
}
复制代码

3.完成服务消费者子模块

导入maven依赖

复制代码
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</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-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
复制代码

编写application.yml文件

复制代码
server:
port: 9001
eureka:
client:
# eureka服务端的路径,这个就是eureka模块设置的地址
service-url:
defaultZone: http://localhost:7001/eureka/
# 是不是将自己注册进eureka 默认 true,所以这里可以省略不写
register-with-eureka: true
ribbon:
ReadTimeout: 5000 #处理请求的超时时间,默认5秒
ConnectTimeout: 5000 #连接建立的超时时间,默认5秒
feign:
hystrix:
enabled: true
复制代码

编写主启动类

复制代码
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix
public class ConsumerHystrixApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerHystrixApplication.class,args);
    }
}
复制代码

ProviderHystrixService.java

复制代码
@FeignClient(value = "PROVIDER-HYSTRIX")//value是provide注册到eaurke的名字
@Service
public interface ProviderHystrixService {

    @GetMapping("/provider/hystrix/ok")
    String providerHystrixOk();

    @GetMapping("/provider/hystrix/timeout")
    String providerHystrixTimeOut();
}
复制代码

ConsumerHystrixController.java

复制代码
@RestController
@RequestMapping("/consumer")
public class ConsumerHystrixController {

    private final ProviderHystrixService providerHystrixService;

    public ConsumerHystrixController(ProviderHystrixService providerHystrixService) {
        this.providerHystrixService = providerHystrixService;
    }

    @GetMapping("/hystrix/ok")
    public String consumerHystrixTimeOk(){
        return providerHystrixService.providerHystrixOk();
    }
/*
fallbackMethod:降级的方法名
name="execution.isolation.thread.timeoutInMilliseconds"熔断的规则
我选的是响应超时时间 value="2000" 2秒
* */
@GetMapping("/hystrix/timeout") 
@HystrixCommand(fallbackMethod
= "providerHystrixTimeOutHandler",commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "2000")
})
   public String consumerHystrixTimeOut(){ 
return providerHystrixService.providerHystrixTimeOut();
}
//降级的方法
public String providerHystrixTimeOutHandler(){ return "哎呀,出错了,服务器丢失"; } }
复制代码

启动eureka

启动provider-hystrix

启动consumer-hystrix

运行截图:

访问正常的方法

访问超时的方法(规则在2s内有响应,程序休眠3秒)

 

2.基础demo优化

  • 每一个方法都需要有降级一个的方法

解决:使用全局服务降级的方法

修改ConsumerHystrixController.java

复制代码
@RestController
@RequestMapping("/consumer")
@DefaultProperties(defaultFallback = "global_FallbackMethod")
public class ConsumerHystrixController {

    private final ProviderHystrixService providerHystrixService;

    public ConsumerHystrixController(ProviderHystrixService providerHystrixService) {
        this.providerHystrixService = providerHystrixService;
    }

    @GetMapping("/hystrix/ok")
    public String consumerHystrixTimeOk(){
        return providerHystrixService.providerHystrixOk();
    }

    @GetMapping("/hystrix/timeout")
    @HystrixCommand
    public String consumerHystrixTimeOut(){
        //模拟异常
        int a=10/0;
        return providerHystrixService.providerHystrixTimeOut();
    }
    public String global_FallbackMethod(){
        return "Global异常处理信息,请稍后重试";
    }
}
复制代码

运行截图:

  • 兜底的方法写到controller中了,耦合了,能不能分离处理

我们采用了OpenFeign实现负载均衡,我们在调用Controller层方法的时候都是去到对应的Service层方法,找到要调用服务的服务名然后去实现调用的,所以我们可以在声明一个类去继承service接口,然后这个类专门对service里面的方法实现Fallback。而且OpenFeign加在Service接口上的注解@FeignClient提供了对Fallback的支持

解决:使用通配服务降级有两种方式

fallbackFactory和fallback

区别在于:fallbackFactory除了可以降级hystrix的异常,其他异常也可以,fallback不行

使用fallback:

新建ProviderHystrixServiceFallBack.java

1.继承ProviderHystrixService接口

2.注意添加@Compoent注解

复制代码
@Component
public class ProviderHystrixServiceFallback implements FallbackFactory<ProviderHystrixService> {
    private final String MSG="系统异常,正在拿程序员小哥祭天";

    @Override
    public ProviderHystrixService create(Throwable throwable) {
        return new ProviderHystrixService() {
            @Override
            public String providerHystrixOk() {
                return throwable.getMessage() + MSG;
            }

            @Override
            public String providerHystrixTimeOut() {
                return MSG;
            }
        };
    }
}
复制代码

修改ProviderHystrixService.java

复制代码
@FeignClient(value = "PROVIDER-HYSTRIX", fallback = ProviderHystrixServiceFallback.class)
@Service
public interface ProviderHystrixService {

    @GetMapping("/provider/hystrix/ok")
    String providerHystrixOk();

    @GetMapping("/provider/hystrix/timeout")
    String providerHystrixTimeOut();

}
复制代码

修改ConsumerHystrixController.java

复制代码
@RestController
@RequestMapping("/consumer")
//@DefaultProperties(defaultFallback = "global_FallbackMethod")
public class ConsumerHystrixController {

    private final ProviderHystrixService providerHystrixService;

    public ConsumerHystrixController(ProviderHystrixService providerHystrixService) {
        this.providerHystrixService = providerHystrixService;
    }

    @GetMapping("/hystrix/ok")
    public String consumerHystrixTimeOk(){
        //模拟异常
        int a=10/0;
        return providerHystrixService.providerHystrixOk();
    }

    @GetMapping("/hystrix/timeout")
    public String consumerHystrixTimeOut(){
        return providerHystrixService.providerHystrixTimeOut();
    }
}
复制代码

运行截图:

无法降级其他异常

可以降级超时异常

posted @   时光里的少年  阅读(49)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示