一文了解SpringCloud

Springcloud

什么是Springcloud?

官网:Spring Cloud Data Flow

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线负载均衡断路器数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

与Springboot的兼容

单纯的名词解释难以理解,下面我们案例来给大家演示:

本文完整案例代码hm-springcloud: SpringCloud案例代码

1.服务远程调用

场景:现在有个订单服务和用户服务分别为不同的两个表和两个服务。

需求:在查询订单时查询出用户信息,也就是怎么在订单服务调用用户服务的user信息。

方案:我们可以使用RestTemplate发起请求,获取用户信息。

什么是RestTemplate呢?

RestTemplate 是 Spring 框架中的一个核心类,用于执行 HTTP 请求并处理响应。它提供了多种便捷的方法来与 RESTful Web 服务进行交互,支持 GET、POST、PUT、DELETE 等HTTP方法。

使用:

public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
 /**
     * 创建RestTemplate并注入Spring容器
     * @return
     */
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
  @Resource
    RestTemplate restTemplate;
​
    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        String url="http://localhost:8081/user/"+order.getUserId();
        User user = restTemplate.getForObject(url, User.class);
        order.setUser(user);
        // 4.返回
        return order;
    }

消费者与提供者这个概念应该很容易理解,例如上面服务远程调用中的例子,userservice就在作为提供者,orderservice

就在作为消费者。

问题:在上面代码中我们可以看到实际是使用了restTemplate发起http请求的,那么发起请求就必须得知道对应的api接口,如果出现多了api接口怎么程序将会特别的冗余且你也不能保证api接口是否可用的。

结合以上问题我们就可以使用Eureka去解决。

2.Eureka

Eureka 是 Netflix 开发的一款基于 REST 的服务发现框架,主要用于微服务架构中。它通过让各个微服务实例向 Eureka 服务器注册自己的信息(比如 IP 地址、端口、健康状态等),从而实现了服务实例的自动发现和注册。

作用

通过上图我们可以看出Eureka 作为一个注册中心的角色,将消费者与提供者的api进行收集,且提供者每个服务每30s都会向注册中心发起一次心跳,如果其中一个服务宕机了,那么心跳骤停,Eureka 会自动将提供者心跳骤停的服务删除,那么在消费者去拉取Eureka注册中心的服务时就不会出现请求失败的情况。

2.1Eureka的使用

依赖

   <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
package com.itcast;
​
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
​
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
​
}
​

访问:http://localhost:10062/

将其他两个服务加带eureka。

在user和order服务加入

<!--        eureka-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
#order服务
spring: 
  application:
    name: order-server
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10062/eureka
     
#user服务
spring: 
  application:
    name: user-server
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10062/eureka

 

使用

在原来的代码上添加@LoadBalanced


    @Bean
    @LoadBalanced//负载均衡发请求
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

  public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        String url="http://user-server/user/"+order.getUserId();
        User user = restTemplate.getForObject(url, User.class);
        order.setUser(user);
        // 4.返回
        return order;
    }
//从url可看出,我们不需要知道IP和端口直接使用application.name就是OK了eureka会自动帮你找。

负责均衡请求结果:

3.Nacos

Nacos是阿里巴巴的产品,现在是SpringCloud中的一个组件。相比Eureka功能更加丰富,在国内受欢迎程度较高。

下载地址:https://github.com/alibaba/nacos/tags

链接:百度网盘 请输入提取码 提取码:8888

3.1Windows安装

下载后解压

目录说明:

  • bin:启动脚本

  • conf:配置文件

端口配置

Nacos的默认端口是8848,如果你电脑上的其它进程占用了8848端口,请先尝试关闭该进程。

如果无法关闭占用8848端口的进程,也可以进入nacos的conf目录,修改配置文件中的端口:

修改其中的内容:

启动

启动非常简单,进入bin目录,结构如下:

然后执行命令即可:

  • windows命令:

    startup.cmd -m standalone

执行后的效果如图:

3.2Linux安装

Linux或者Mac安装方式与Windows类似。

安装JDK

Nacos依赖于JDK运行,索引Linux上也需要安装JDK才行。

上传jdk安装包:

上传到某个目录,例如:/usr/local/

然后解压缩:

tar -xvf jdk-8u144-linux-x64.tar.gz

然后重命名为java

配置环境变量:

export JAVA_HOME=/usr/local/java
export PATH=$PATH:$JAVA_HOME/bin

设置环境变量:

source /etc/profile

上传安装包

如图:

也可以直接使用课前资料中的tar.gz:

上传到Linux服务器的某个目录,例如/usr/local/src目录下:

解压

命令解压缩安装包:

tar -xvf nacos-server-1.4.1.tar.gz

然后删除安装包:

rm -rf nacos-server-1.4.1.tar.gz

目录中最终样式:

目录内部:

端口配置

与windows中类似

启动

在nacos/bin目录中,输入命令启动Nacos:

sh startup.sh -m standalone

访问地址:为上图中的Console

3.3nacos的基本使用

在父工程加入:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.5.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

在子工程加入:

<!-- nacos客户端依赖包 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

配置文件配置nacosIP地址:

spring:  
    cloud:
        nacos:
          server-addr: 127.0.0.1:8848 #nacos地址

访问nacos即可发现对应服务

3.4服务分级存储模型

一个服务可以有多个实例,例如我们的user-service,可以有:

  • 127.0.0.1:8081

  • 127.0.0.1:8082

  • 127.0.0.1:8083

假如这些实例分布于全国各地的不同机房,例如:

  • 127.0.0.1:8081,在上海机房

  • 127.0.0.1:8082,在上海机房

  • 127.0.0.1:8083,在杭州机房

Nacos就将同一机房内的实例 划分为一个集群

也就是说,user-service是服务,一个服务可以包含多个集群,如杭州、上海,每个集群下可以有多个实例,形成分级模型,如图:

微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集群内不可用时,才访问其它集群。例如:

杭州机房内的order-service应该优先访问同机房的user-service。

给user-service配置集群

修改user-service的application.yml文件,添加集群配置:

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: HZ # 集群名称

重启两个user-service实例后,我们可以在nacos控制台看到下面结果:

我们再次复制一个user-service启动配置,添加属性:

-Dserver.port=8083 -Dspring.cloud.nacos.discovery.cluster-name=SH

配置如图所示:

启动UserApplication3后再次查看nacos控制台:

3.5本地集群优先

什么叫本地集群优先?也就是可以设置消费者的集群地区,优先找该地区的提供者,如果该地区的提发者宕机了,才去找别的地区。

配置

在order-service中添加

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: HZ # 集群名称
userservice:
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则 
3.6权重配置

实际部署中会出现这样的场景:

服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求。

但默认情况下NacosRule是同集群内随机挑选,不会考虑机器的性能问题。

因此,Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高。

在nacos控制台,找到user-service的实例列表,点击编辑,即可修改权重:

在弹出的编辑窗口,修改权重:

注意:如果权重修改为0,则该实例永远不会被访问

4.Nacos与Eureka的区别

Nacos和Eureka整体结构类似,服务注册、服务拉取、心跳等待,但是也存在一些差异:

  • Nacos与eureka的共同点

    • 都支持服务注册和服务拉取

    • 都支持服务提供者心跳方式做健康检测

  • Nacos与Eureka的区别

    • Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式

    • 临时实例心跳不正常会被剔除,非临时实例则不会被剔除

    • Nacos支持服务列表变更的消息推送模式,服务列表更新更及时

    • Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式

5.Nacos配置管理

当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错。我们需要一种统一配置管理方案,可以集中管理所有实例的配置。

Nacos一方面可以将配置集中管理,另一方可以在配置变更时,及时通知微服务,实现配置的热更新。

5.1在nacos中添加配置文件

如何在nacos中管理配置呢?

然后在弹出的表单中,填写配置信息:

注意:项目的核心配置,需要热更新的配置才有放到nacos管理的必要。基本不会变更的一些配置还是保存在微服务本地比较好。

5.2拉取nacos配置中心的配置

微服务要拉取nacos中管理的配置,并且与本地的application.yml配置合并,才能完成项目启动。

但如果尚未读取application.yml,又如何得知nacos地址呢?

因此spring引入了一种新的配置文件:bootstrap.yaml文件,会在application.yml之前被读取,流程如下:

1.添加子项目依赖

<!--nacos配置管理依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

2.新增bootstrap.yml文件

然后,在user-service中添加一个bootstrap.yaml文件,内容如下:

spring:
  application:
    name: userservice # 服务名称
  profiles:
    active: dev #开发环境,这里是dev 
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
      config:
        file-extension: yaml # 文件后缀名

这里会根据spring.cloud.nacos.server-addr获取nacos地址,再根据

${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}作为文件id,来读取配置。

本例中,就是去读取userservice-dev.yaml

编写controller验证

​
    @Value("${pattern.dateformat}")
    private String dateformat;
​
    @GetMapping("now")
    public String now(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
    }

配置热刷新配置

当修改nacos里面的配置时,服务配置实时变动,无须重启。

1.如果是使用@Value注解的方式读取配置文件,那就加上@RefreshScope

@Slf4j
@RestController
@RequestMapping("/user")
@RefreshScope  //热刷新
public class UserController {
    @Value("${pattern.dateformat}")
    private String dateformat;
​
    @GetMapping("now")
    public String now(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
    }
}

2.如果是使用@ConfigurationProperties(prefix = "pattern")编写一个配置类的话,无须任何配置,会自动刷新。

5.3配置共享

使用场景:当我们把项目分为prod、test、dev环境时,那么如果这些环境都都共同的配置时,我们就可以使用配置共享实现。

其实微服务启动时,会去nacos读取多个配置文件,例如:

  • [spring.application.name]-[spring.profiles.active].yaml,例如:userservice-dev.yaml

  • [spring.application.name].yaml,例如:userservice.yaml

[spring.application.name].yaml不包含环境,因此可以被多个环境共享。

下面我们通过案例来测试配置共享

1.添加一个环境共享配置

我们在nacos中添加一个userservice.yaml文件:

2在user-service中读取共享配置

在user-service服务中,修改PatternProperties类,读取新添加的属性:

在user-service服务中,修改UserController,添加一个方法:

3.运行两个UserApplication,使用不同的profile

修改UserApplication2这个启动项,改变其profile值:

这样,UserApplication(8081)使用的profile是dev,UserApplication2(8082)使用的profile是test。

启动UserApplication和UserApplication2

访问http://localhost:8081/user/prop,结果:

访问http://localhost:8082/user/prop,结果:

可以看出来,不管是dev,还是test环境,都读取到了envSharedValue这个属性的值。

优先级

当nacos、服务本地同时出现相同属性时,优先级有高低之分:

6.Nacos集群搭建

Windows搭建请参考:

Windows搭建nacos集群_vmwaver 配置nacos集群-CSDN博客

7.Feign远程调用

什么Feign?

Feign是一个声明式的HTTP客户端,它使得编写Web服务客户端变得更加容易。通过使用Feign,我们可以以接口的方式定义HTTP请求,而不需要编写大量的HTTP请求模板代码。Feign支持模板化的方法定义,支持可插拔的编码器和解码器,还集成了Ribbon(或OpenFeign集成了LoadBalancer Client)用于客户端负载均衡,这对于微服务架构中的服务间调用非常有用。

先来看我们以前利用RestTemplate发起远程调用的代码:

存在下面的问题:

•代码可读性差,编程体验不统一

•参数复杂URL难以维护

Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign

其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。

使用

在消费者添加依赖

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

在Application.class的启动类上添加注解 @EnableFeignClients

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

@EnableFeignClients是Spring Cloud提供的一个注解,用于启用Feign客户端的功能。当在Spring Boot应用的主类或者其他配置类上添加这个注解时,它会自动扫描指定包下的接口(默认是启动类所在包及其子包),并将这些接口识别为Feign客户端。

创建Client接口

/**
 * 用户服务的Feign客户端接口。
 * 通过该接口,可以远程调用用户服务的相关方法,此处实现了对用户服务中用户信息的查询。
 * 使用@FeignClient注解指定了该客户端对应的微服务名称。
 */
@FeignClient("userservice")
public interface UserClient {
    
    /**
     * 根据用户ID查询用户信息。
     * 使用@GetMapping注解指定了该方法是一个HTTP GET请求,用于查询用户信息。
     * 请求的URL路径为/user/{id},其中{id}是一个占位符,表示用户ID。
     * 方法参数:
     * @param id 用户的唯一标识,通过@PathVariable注解将URL中的{id}参数绑定到方法参数id上。
     * 返回值:
     * @return 返回User对象,包含查询到的用户信息。
     */
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}
​

修改案例:

@Autowired
private UserClient userClient;
public Order queryOrderById(Long orderId) {
    Order order = orderMapper.findById(orderId);
    User user = userClient.findById(order.getUserId());
    order.setUser(user);
    return order;
}
7.1Feign的自定义配置

日志记录分别为两种方式:配置文件配置及java编码配置。

配置文件配置

feign:
  client:
    config:
      default: #默认是全局配置
        loggerLevel: full
            
            
feign:
  client:
    config:
      userservice: #指定对应服务
        loggerLevel: full

硬编码配置

//新建一个配置类,无须加注解,在调用是添加即可
public class FeignClientConfiguration {
    @Bean
    public Logger.Level feignLoggerLevel() {
//        Logger.Level.日志级别
        return Logger.Level.BASIC;
    }
}

全局配置

//在Applicant.class上添加
@SpringBootApplication
@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

针对某个服务

@FeignClient(value = "userservice",configuration = FeignClientConfiguration.class)
public interface UserClient {

    /**
     * 根据用户ID查询用户信息。
     * 使用@GetMapping注解指定了该方法是一个HTTP GET请求,用于查询用户信息。
     * 请求的URL路径为/user/{id},其中{id}是一个占位符,表示用户ID。
     * 方法参数:
     * @param id 用户的唯一标识,通过@PathVariable注解将URL中的{id}参数绑定到方法参数id上。
     * 返回值:
     * @return 返回User对象,包含查询到的用户信息。
     */
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}

性能优化

Feign:
  httpclient:
    enabled: true #支持HttpClient
    max-connections: 200 #最大连接数
    max-connections-per-route: 50 #每个路由的最大连接数
🐇7.2Feign拆分独立模块:

新建一个Feign-api模块,将所需要的pojo、配置等放置该模块。

然后将orderservice的pom.xml加入该模块的依赖

<!--        导入自己独立建立的配置类-->
<dependency>
    <groupId>cn.itcast.demo</groupId>
    <artifactId>feign-api</artifactId>
    <version>1.0</version>
</dependency>

将Feign-api加入SpringbootApplication的扫描包范围:

方式一


  
//指定自己需要的客户端,是个数组可以多传
@EnableFeignClients(clients = {UserClient.class})

方式二

//找到该包下的全部加载
@EnableFeignClients(basePackages = {"cn.itcast.feign.clients"})

8.gateway网关

spring-cloud-starter-gateway是Spring Cloud项目中的一个关键组件,它提供了一种现代化的、易于配置的API网关解决方案。Spring Cloud Gateway是Spring Cloud生态中的API网关服务,设计用于微服务架构,它基于Spring 5、Spring Boot 2和Project Reactor构建,支持响应式编程模型。 主要特性包括:

  • 路由:能够根据路径、HTTP方法、主机等多种条件对请求进行路由,将请求转发到不同的微服务。

  • 过滤器:提供了一套丰富的过滤器机制,可以在请求的转发过程中的不同阶段(如预处理、后处理)执行逻辑,实现诸如鉴权、限流、日志记录等功能。

  • 断路器:与Spring Cloud Circuit Breaker集成,支持在网关层面实现服务间的故障隔离。

  • 负载均衡:与Spring Cloud Load Balancer集成,可以对后端服务进行智能负载均衡。

  • 安全:易于集成OAuth2等安全框架,实现API的安全访问控制。

  • 指标与监控:支持Micrometer等监控工具,便于收集和展示网关的性能指标。

使用

我们创建一个独立的服务用于专门处理网关服务。

 <dependencies>
<!--  该服务也需要被nacos管理      -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
<!-- gateway网关依赖     -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>

编写配置文件application.yml

server:
  port: 10010
spring:
  application:
    name: gateway-server
  cloud:
    nacos:
      server-addr: 38.6.217.70:80
    gateway:
      routes:
        - id: userservice # 路由的ID,没有固定规则但必须唯一,建议配合服务名
          uri: lb://userservice # 路由的转发目标地址
          predicates: # 断言,也就是条件
            - Path=/user/**
        - id: order-server
          uri: lb://order-server
          predicates:
            - Path=/order/**

 

gateway的断言工厂

官网地址文档:Route Predicate Factories :: Spring Cloud Gateway

可以通过上面做对应的配置,进行对应的路由匹配。如果不符合断言要求则会出现404

#例子 该例子设置了After 表示该请求必须在2017-01-20T17:42:47.789-07:00 这个时间之后才会匹配成功
spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]
8.1gateway的过滤器

官网地址:AddRequestParameter GatewayFilter Factory :: Spring Cloud Gateway

作用

Spring Cloud Gateway的过滤器(Filter)是其核心功能之一,它们允许在请求的处理流程中插入自定义的逻辑,从而实现诸如身份验证、请求转换、响应处理、跟踪、监控等多种功能。过滤器的作用主要体现在以下几个方面:

  1. 请求前处理(Pre-processing):在请求到达目标微服务之前,过滤器可以对请求进行预处理,比如添加或修改请求头、参数校验、身份认证和授权检查等。

  2. 路由转发(Routing):决定请求应该被路由到哪个下游服务。虽然这主要由路由规则定义,但在某些场景下,过滤器也可以参与决策过程。

  3. 响应后处理(Post-processing):在从下游服务收到响应之后,但在将响应发送回客户端之前,过滤器可以对响应进行修改,比如添加或修改响应头、数据脱敏、日志记录等。

  4. 错误处理(Error handling):当请求处理过程中发生错误时,过滤器可以捕获这些错误并执行相应的错误处理逻辑,如返回定制化的错误信息给客户端。

  5. 全局与局部应用:Spring Cloud Gateway支持全局过滤器和局部过滤器。全局过滤器应用于所有路由,适合实现通用逻辑,如认证和日志记录。局部过滤器仅应用于特定路由,适合实现特定业务逻辑。

  6. 有序执行:每个过滤器都有一个顺序(Order),决定了它们在处理链中的执行顺序。这使得开发者可以精确控制过滤器逻辑的执行流程。

  7. 响应式编程模型:基于Project Reactor,过滤器支持响应式编程,能够非阻塞地处理请求和响应,提高系统的并发处理能力和资源利用率。

使用

场景:当每个服务都需要请求头或者请求参数等我们就可以使用该过滤器.

server:
  port: 10010
spring:
  application:
    name: gateway-server
  cloud:
    nacos:
      server-addr: 38.6.217.70:80
    gateway:
      routes:
        - id: userservice # 路由的ID,没有固定规则但必须唯一,建议配合服务名
          uri: lb://userservice # 路由的转发目标地址
          predicates: # 断言,也就是条件
            - Path=/user/**
          filters:
            - AddRequestHeader=X-Request-red, blue #局部配置
        - id: order-server
          uri: lb://order-server
          predicates:
            - Path=/order/**
#      default-filters: #全局配置
#        - AddRequestHeader=X-Request-red, blue

測試

 @GetMapping("/{id}")
    public User queryById(@PathVariable("id") Long id, @RequestHeader(value = "X-Request-red",required = false) String  red) {
        log.info("测试过滤器----{}",red);
        return userService.queryById(id);
    }
8.2全局过滤器

场景:请求时是否带了token,没有带说明没有登录等场景。

//@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        模拟登录的请求头
        String token = exchange.getRequest().getHeaders().getFirst("token");
        if ("admin".equals(token)) {
//            放行
            return chain.filter(exchange);
        }
//        设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
//        拦截
        return exchange.getResponse().setComplete();
    }
8.3过滤器的执行顺序

8.4跨域配置

server:
  port: 10010
spring:
  application:
    name: gateway-server
  cloud:
    nacos:
      server-addr: 38.6.217.70:80
    gateway:
      routes:
        - id: userservice # 路由的ID,没有固定规则但必须唯一,建议配合服务名
          uri: lb://userservice # 路由的转发目标地址
          predicates: # 断言,也就是条件
            - Path=/user/**
          filters:
            - AddRequestHeader=X-Request-red, blue #局部配置
        - id: order-server
          uri: lb://order-server
          predicates:
            - Path=/order/**
#      default-filters: #全局配置
#        - AddRequestHeader=X-Request-red, blue
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些网站的跨域请求
              - "http://localhost:8090"
              - "http://www.leyou.com"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期

相关推荐

  1. 了解 Go 方法

    2024-07-16 02:18:02       56 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-16 02:18:02       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-16 02:18:02       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-16 02:18:02       57 阅读
  4. Python语言-面向对象

    2024-07-16 02:18:02       68 阅读

热门阅读

  1. no-fee服务器玩转LLM

    2024-07-16 02:18:02       18 阅读
  2. lvs是什么

    2024-07-16 02:18:02       17 阅读
  3. UDP传输文件和FTP传输文件

    2024-07-16 02:18:02       20 阅读
  4. flutter Android端权限

    2024-07-16 02:18:02       18 阅读
  5. .NET在工控上位机开发中有哪些成功的案例?

    2024-07-16 02:18:02       22 阅读
  6. 最短路之朴素版的dij板子

    2024-07-16 02:18:02       18 阅读
  7. c++ 生成随机字符串

    2024-07-16 02:18:02       21 阅读
  8. 顺序表(C语言)

    2024-07-16 02:18:02       18 阅读
  9. 堆、栈和队列(数据结构)

    2024-07-16 02:18:02       21 阅读
  10. 跨越空间的编码:在PyCharm中高效使用远程解释器

    2024-07-16 02:18:02       18 阅读
  11. C# 中,使用 LINQ 示例 备忘

    2024-07-16 02:18:02       21 阅读