SpringCloudNetflix之Hystrix(熔断器)、Zull(网关)、Feign完整使用(一)

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
日志服务 SLS,月写入数据量 50GB 1个月
简介: SpringCloudNetflix之Hystrix(熔断器)、Zull(网关)、Feign完整使用(一)

Hystrix


简介


Hystix,即熔断器。

主页:https://github.com/Netflix/Hystrix/微信图片_20220526135321.png

Hystrix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败。

使用熔断器Hystrix为了优化项目。微信图片_20220526135332.png

熔断器的工作机制

微信图片_20220526135339.png


正常工作的情况下,客户端请求调用服务API口:微信图片_20220526135346.png

当有服务出现异常时,直接进行失败回滚,00000000处理:微信图片_20220526135351.png

当服务繁忙时,如果服务出现异常,不是粗暴的直接报错,而是返回一个友好的提示,虽然拒绝了用户的访问,但是会返回一个结果。


这就好比去买鱼,平常超市买鱼会额外赠送杀鱼的服务。等到逢年过节,超时繁忙时,可能就不提供杀鱼服务了,这就是服务的降级。


系统特别繁忙时,一些次要服务暂时中断,优先保证主要服务的畅通,一切资源优先让给主要服务来使用,在双十一、618时,京东天猫都会采用这样的策略。


动手实践


引入依赖微信图片_20220526135358.png

首先在student-service中引入Hystrix依赖:

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

微信图片_20220526135403.png

开启熔断


在启动类上添加注解 “@EnableHystrix”

package com.czxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix      //开启熔断器
public class StudentApplication {
    public static void main(String[] args) {
        SpringApplication.run(StudentApplication.class,args);
    }
}

改造调用方


我们改造student-service,修改ClassesDao的findAll方法,并且声明一个失败时的回滚处理函数dataFallback:

package com.czxy.dao;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Repository;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@Repository
public class ClassesDao {
    @Resource
    private RestTemplate restTemplate;
    @GetMapping
    @HystrixCommand(fallbackMethod = "findAllFallback")
    public List<String> findAll(){
        ResponseEntity<List> entity = restTemplate.getForEntity("http://classes-service/classes", List.class);
        List<String> list = entity.getBody();
        return list;
    }
    /**
     * 失败时的回调函数
     * @return
     */
    public List<String> findAllFallback(){
        List<String> list = new ArrayList<>();
        list.add("模拟数据1");
        list.add("模拟数据2");
        list.add("模拟数据3");
        return list;
    }
}
  • @HystrixCommand(fallbackMethod="dataFallback"):声明一个失败回滚处理函数dataFallback,当findAll执行超时(默认是1000毫秒),就会执行fallback函数,返回替代内容。
  • 为了方便查看熔断的触发时机,我们记录请求访问时间。
  • 多学一招:通过@HystrixCommand的commandProperties 可以设置默认时间


/

// HystrixCommandProperties Hystrix命令参数配置类
@HystrixCommand(fallbackMethod = "dataFallback",commandProperties = @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1000"))

改造服务提供者


改造服务提供者classes_service,随机休眠一段时间,以触发熔断:

package com.czxy.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@RestController
@RequestMapping("/classes")
public class ClassesController {
    @Resource
    private HttpServletRequest request;
    @GetMapping
    public List<String> findAll() throws InterruptedException {
        // 模拟网络延迟
        Thread.sleep(new Random().nextInt(2000));
        List<String> list = new ArrayList<>();
        list.add("Java12班");
        list.add("Java34班");
        list.add("服务端端口:" + request.getServerPort());
        return list;
    }
}

改造StudentController,记录执行时间

package com.czxy.controller;
import com.czxy.service.StudentService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@RestController
@RequestMapping("/student")
public class StudentController {
    @Resource
    private StudentService studentService;
    @GetMapping
    public List<String> findAll(){
        long start = System.currentTimeMillis();
        List<String> list = studentService.findAll();
        long end = System.currentTimeMillis();
        list.add("耗时:" + (end-start));
        return list;
    }
}

启动测试


启动服务

微信图片_20220526140143.png

如果超过1秒将使用“模拟数据”微信图片_20220526140148.png

如果超过1秒将使用“模拟数据”


微信图片_20220526140249.png

面试题


如果熔断和重试机制,都配置,是都生效?还是某个生效?


经测试发现是熔断生效,为什么?


1. Ribbon重试机制的超时时间设置的是1000ms:


2.Hystix的超时时间默认也是1000ms


3.实际执行后发现,没有触发重试机制,而是先触发了熔断。


所以,Ribbon的超时时间一定要小于Hystix的超时时间。

我们可以通过hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds来设置

# Hystrix超时时间。
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000    # 设置hystrix的超时时间为3000ms

Feign


在前面的学习中,我们使用了Ribbon的负载均衡功能,大大简化了远程调用时的代码:


restTemplate.getForEntity("http://classes-service/classes", List.class);


如果就学到这里,你可能以后需要编写类似的大量重复代码,格式基本相同,无非参数不一样。有没有更优雅的方式,来对这些代码再次优化呢?


这就是我们接下来要学的Feign的功能了。


简介


Feign是一种声明式、模板化的HTTP客户端。


在SpringCloud中使用Feign,我们可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。


快速入门


导入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

开启Feign功能


我们在启动类上,添加注解 @EnableFeignClients,开启Feign功能

package com.czxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix      //开启熔断器
@EnableFeignClients //开启feign
public class StudentApplication {
    public static void main(String[] args) {
        SpringApplication.run(StudentApplication.class,args);
    }
}

Feign的客户端


  1. 通过@FeignClient 声明Feign客户端。
  2. value : 用于设置服务名称
  3. path:用于设置路径前缀(也就是controller配置的路径)
  4. Feign类似于MyBatis。
  5. @FeignClient类似 @Mapper注解。
  6. Feign中的方法需要与服务的方法声明完全一致。注意:路径
  7. Feign会根据注解帮我们生成URL。

步骤一:编写 ClassesFeign

微信图片_20220526140858.png

package com.czxy.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;
@FeignClient(value="classes-service",path="/classes")
public interface ClassesFeign {
    @GetMapping
    public List<String> findAll();
}

修改StudentService,不再调用ClassesDao,直接使用

package com.czxy.service;
import com.czxy.dao.ClassesDao;
import com.czxy.feign.ClassesFeign;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class StudentService {
//    @Resource
//    private ClassesDao classesDao;
    @Resource
    private ClassesFeign classesFeign;
    public List<String> findAll() {
//        return classesDao.findAll();
        return classesFeign.findAll();
    }
}

启动测试


正常访问微信图片_20220526141022.png

如果超时,抛异常微信图片_20220526141028.png

入门总结

第一步:导入Feign依赖


第二步:在StudentApplication启动类添加 @EnableFeginClients


第三步:编写Feign客户端 使用@FeignClient声明客户端  参数:value设置服务名称 path设置路径前缀(也就是controller配置的路径)


第四步:在controller中使用Feign客户端发起远程请求调用


负载均衡


之前使用RestTemplate进行远程调用时,需要添加额外注解来完成负载均衡处理。


Feign中本身已经集成了Ribbon依赖,不需要额外引入依赖,就可以完成负载均衡处理。采用之前的配置就可以。

classes-service:
  ribbon:
    ConnectTimeout: 250               # Ribbon的连接超时时间
    ReadTimeout: 1000                 # Ribbon的数据读取超时时间
    OkToRetryOnAllOperations: true  # 是否对所有操作都进行重试
    MaxAutoRetriesNextServer: 1     # 切换实例的重试次数
    MaxAutoRetries: 1                 # 对当前实例的重试次数

另外,还可以使用ribbon.xx来进行ribbon的全局配置。


Hystrix支持


Feign默认也有对Hystix的集成,只不过,默认情况下是关闭的。

我们需要通过下面的参数来开启:

feign:
  hystrix:
    enabled: true # 开启Feign的熔断功能1.

微信图片_20220526141038.png

但是,Feign中的Fallback配置不像Ribbon中那样简单了。

首先,我们要定义一个类,实现DataFeign接口,作为fallback的处理类

package com.czxy.feign;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
email liangtong@itcast.cn
@Component
public class ClassesFeignFallback implements ClassesFeign {
    @Override
    public List<String> findAll() {
        List<String> list = new ArrayList<>();
        list.add("模拟数据111");
        list.add("模拟数据222");
        list.add("模拟数据333");
        return list;
    }
}

然后在DataFeign中,指定刚才编写的实现类

package com.czxy.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;
@FeignClient(value="classes-service",path="/classes" ,fallback = ClassesFeignFallback.class )
public interface ClassesFeign {
    @GetMapping
    public List<String> findAll();
}

重启测试:

微信图片_20220526141045.png微信图片_20220526141050.png

请求压缩(了解)


Spring Cloud Feign 支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。通过下面的参数即可开启请求与响应的压缩功能:

feign:
  compression:
    request:
      enabled: true # 开启请求压缩
    response:
      enabled: true # 开启响应压缩

微信图片_20220526141811.png

同时,我们也可以对请求的数据类型,以及触发压缩的大小下限进行设置:

feign:
  compression:
    request:
      enabled: true # 开启请求压缩
      mime-types: text/html,application/xml,application/json # 设置压缩的数据类型
      min-request-size: 2048 # 设置触发压缩的大小下限

注:上面的数据类型、压缩大小下限均为默认值。微信图片_20220526141821.png

日志级别(了解)


前面讲过,通过logging.level.xx=debug来设置日志级别。然而这个对Fegin客户端而言不会产生效果。因为@FeignClient注解修改的客户端在被代理时,都会创建一个新的Fegin.Logger实例。我们需要额外指定这个日志的级别才可以。


设置com.czxy包下的日志级别都为debug

logging:
  level:
    com:
      czxy:
        feign: debug

微信图片_20220526141827.png

编写配置类,定义日志级别

package com.czxy.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignConfig {
    @Bean
    public Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
    }
}

这里指定的Level级别是FULL,Feign支持4种级别:

微信图片_20220526141835.png

  • NONE:不记录任何日志信息,这是默认值。
  • BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
  • HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
  • FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。

在FeignClient中指定配置类:

/**
 * Created by liangtong.
 */
@FeignClient(value="service",path="/test",fallback = DataFeignFallback.class,configuration = FeignConfig.class)
public interface DataFeign {
    @GetMapping
    public ResponseEntity<String> test();
}

重启项目,即可看到每次访问的日志:微信图片_20220526142213.png

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
6月前
服务熔断器-Hystrix
服务熔断器-Hystrix
57 2
|
Java 机器人 Maven
【Java用法】微服务之间的相互调用方式之一,通过FeignClient客户端调用其他微服务的方法包含熔断器(Hystrix)
【Java用法】微服务之间的相互调用方式之一,通过FeignClient客户端调用其他微服务的方法包含熔断器(Hystrix)
170 0
|
6月前
|
Java Sentinel
【熔断限流组件resilience4j和hystrix】
【熔断限流组件resilience4j和hystrix】
169 0
|
5月前
springCloud之服务降级熔断Hystrix、OpenFeign
springCloud之服务降级熔断Hystrix、OpenFeign
308 0
|
2月前
|
存储 NoSQL 调度
|
2月前
|
XML 监控 Java
Spring Cloud全解析:熔断之Hystrix简介
Hystrix 是由 Netflix 开源的延迟和容错库,用于提高分布式系统的弹性。它通过断路器模式、资源隔离、服务降级及限流等机制防止服务雪崩。Hystrix 基于命令模式,通过 `HystrixCommand` 封装对外部依赖的调用逻辑。断路器能在依赖服务故障时快速返回备选响应,避免长时间等待。此外,Hystrix 还提供了监控功能,能够实时监控运行指标和配置变化。依赖管理方面,可通过 `@EnableHystrix` 启用 Hystrix 支持,并配置全局或局部的降级策略。结合 Feign 可实现客户端的服务降级。
153 23
|
3月前
|
缓存 监控 负载均衡
一文讲明Hystrix熔断器
这篇文章详细阐述了Hystrix熔断器的原理和应用,解释了分布式系统中服务雪崩的问题,并展示了如何在Spring Cloud框架中使用Hystrix进行熔断和降级处理。
一文讲明Hystrix熔断器
|
3月前
|
监控 供应链 安全
构建高效微服务架构:API网关与服务熔断策略
【7月更文挑战第38天】随着现代应用程序向微服务架构的转型,系统的稳定性和效率成为了开发团队关注的焦点。本文将探讨在微服务环境中实现系统可靠性的关键组件——API网关,以及如何在服务间通讯时采用熔断机制来防止故障蔓延。通过分析API网关的核心功能和设计原则,并结合熔断策略的最佳实践,我们旨在提供一套提高分布式系统弹性的策略。
|
6月前
|
负载均衡 Java API
构建高效微服务架构:API网关与服务熔断策略
【5月更文挑战第2天】 在微服务架构中,确保系统的高可用性与灵活性是至关重要的。本文将深入探讨如何通过实施有效的API网关和设计合理的服务熔断机制来提升分布式系统的鲁棒性。我们将分析API网关的核心职责,包括请求路由、负载均衡、认证授权以及限流控制,并讨论如何利用熔断器模式防止故障传播,维护系统的整体稳定性。文章还将介绍一些实用的技术和工具,如Netflix Zuul、Spring Cloud Gateway以及Hystrix,以帮助开发者构建一个可靠且高效的微服务环境。
Ribbon、Feign、Hystrix超时&重试&熔断问题
在使用Ribbon、Feign、Hystrix组合时,因为配置的问题出现以下现象,让我的大脑CPU烧的不行不行(拿我老家话说就是“脑子ran滴奥”)
176 0