跳至主要內容
Spring Cloud Gateway 实战:路由、限流与鉴权

Spring Cloud Gateway 实战:路由、限流与鉴权

前言

在微服务架构中,API 网关是流量的"前门"。它承担着路由转发、限流、鉴权、日志、跨域处理等横切关注点。Spring Cloud Gateway 作为 Spring 生态的网关解决方案,基于 WebFlux 反应式编程模型,性能出色,生态完善。

本文从实战出发,系统讲解 Spring Cloud Gateway 的核心概念、路由配置、限流鉴权和生产环境调优。


一、为什么需要 API 网关?

1.1 微服务架构中的痛点


郑天祺大约 11 分钟springGateway路由
SpringCloud使用nacos多人开发负载调用问题实践

1、问题描述

当我们使用springcloud+nacos架构时,由于使用nacos进行负载的原因,组内小伙伴经常调用到其他人的电脑。

针对此问题我们可以采用的方案:

  • (方案1)利用nacos的特性,进行区分namespace或者group,每个人用不同的namespace或者group。该方式需要每个开发人员改yml文件且不能提交,比较麻烦。
  • (方案2)不使用openfeign不使用gateway,使用restTemplate,调用前进行判断是否为开发环境,开发环境使用localhost。
  • (方案3)该方案我目前采用的,无需每个人进行特别的配置。首先我们使用openfeign且使用gateway;其中nacos的namespace区分dev、test、hotfix、prod;group大家都是用的默认的DEFAULT_GROUP。需要修改的是gateway配置和增加openfeign参数
    若有更好的方法,也请分享我,万分感谢~
    下面详细介绍方案2和方案3:

郑天祺大约 2 分钟springSpringCloudNacos负载均衡
SpringMVC全局异常处理器

一、引言

SpringBoot工程中对Controller配置全局异常处理。有些接口在发生异常时,如何对不同类型的接口使用不同的全局异常进行处理呢?
Spring提供了对@ControllerAdvice注解的配置,我们可以通过配置@ControllerAdvice对指定的Exception拦截。

二、@ControllerAdvice注解使用方法

// 第一种
@RestControllerAdvice
public class GlobalExceptionHandler
{}

// 第二种
// basePackages 指定一个或多个包,这些包及其子包下的所有 Controller 都被该 @ControllerAdvice 管理。其中上面两种等价于 basePackages。
// basePackages
// @ControllerAdvice("cn.demo.controller")
// @ControllerAdvice(value = "cn.demo.controller")
@ControllerAdvice(basePackages = {"cn.demo.controller"})
public class GlobalExceptionHandler 
{}

// 第三种
// basePackageClasses 指定一个或多个 Controller 类,这些类所属的包及其子包下的所有 Controller 都被该 @ControllerAdvice 管理。
@ControllerAdvice(basePackageClasses = {MyController.class})
public class GlobalExceptionHandler {}

// 第四种
// assignableTypes:指定一个或多个 Controller 类,这些类被该 @ControllerAdvice 管理。
@ControllerAdvice(assignableTypes = {MyController.class})
public class GlobalExceptionHandler {}

// 第五种
// annotations:指定一个或多个注解,被这些注解所标记的 Controller 会被该 @ControllerAdvice 管理。
@ControllerAdvice(annotations = {RestController.class})
public class GlobalExceptionHandler {}

郑天祺大约 2 分钟springSpringMVC异常处理Java
SpringCloud Hystrix参数配置

Hystrix修改默认配置有两种方式,注解参数注入,和application.yml配置文件配置。

1、方法一:注解参数注入

    @RequestMapping(value = "/helloHystrixA/{string}", method = RequestMethod.GET)
    @HystrixCommand(fallbackMethod = "testFallback", // 请求失败降级回调方法,值为方法名,不需要括号
        commandProperties = {// 针对单个方法的配置
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), // 开启熔断器,可不加默认为true
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"), // 请求错误超过50%,开启熔断器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), // 一个周期(十秒)内超过10个请求才进行进行容错率判断
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),// 开启熔断器后过10秒再尝试访问
        })
    public String helloHystirxA(@PathVariable String string) {
        return "Nacos服务发现:远端调用成功! result="
            + restTemplate.getForObject("http://nacos.provider.demo/hello/" + string, String.class);


郑天祺大约 2 分钟springSpringCloudHystrix熔断降级
SpringCloud Ribbon参数配置

Ribbon策略类型

image-20201214123508379
image-20201214123508379

Ribbon负载均衡策略为轮询,如果要修改默认策略 ,有两种方法,分别是创建配置类,和配置application.yml。

方法一:创建配置类

 @Configuration  
public class MyRibbonConfig {
    @Bean
    public IRule ribbonRule() {
        //随机策略
        return new RandomRule();
    }
}
然后在启动类上加注解:
@RibbonClient(name = "nacos.provider.demo", configuration = MyRibbonConfig.class)  //name为服务提供者名称


郑天祺小于 1 分钟springSpringCloudRibbon负载均衡
SpringCloud client配置

1、pom.xml添加starter依赖

<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-config -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

郑天祺小于 1 分钟springSpringCloud配置微服务
SpringCloud使用Feign+Ribbon+Hystrix

1、引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

郑天祺大约 1 分钟springSpringCloudFeignRibbonHystrix
SpringCloud使用Feign+Ribbon

1、引入依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

郑天祺大约 2 分钟springSpringCloudFeignRibbon
SpringCloud使用Feign

1、引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

郑天祺小于 1 分钟springSpringCloudFeignHTTP客户端
SpringCloud使用RestTemplate

1、引入依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

郑天祺小于 1 分钟springSpringCloudRestTemplateHTTP客户端
2
3