一文SpringCloud

news2024/11/15 11:56:27

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 # 这次跨域检测的有效期

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1925401.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flat Ads:金融APP海外广告投放素材的优化指南

在当今全球化的数字营销环境中,金融APP的海外营销推广已成为众多金融机构与开发者最为关注的环节之一。面对不同地域、文化及用户习惯的挑战,如何优化广告素材,以吸引目标受众的注意并促成有效转化,成为了广告主们亟待解决的问题。 作为领先的全球化营销推广平台,Flat Ads凭借…

树莓派PICO使用INA226测量电流和总线电压(3)

上一篇文章我们讲了如何测试电流&#xff0c;但是INA226有一个非常典型的问题&#xff0c;那就是误差比较大&#xff0c;因为采样电阻非常小&#xff0c;我的开发板用的是100mΩ的采样电阻&#xff0c;在设定中我也用的是这个采样电阻值&#xff0c;但事实上&#xff0c;测试得…

文件内容查阅

cat concatenate files and print on the standard output Linux中一个最简单的且最常用的命令是cat命令。其功能是在终端设备上显示文件内容。 cat命令-n选项用于显示行号。 tac concatenate and print files in reverse tac命令的功能是用于反向显示文件内容&#xff0c;即…

【Qt 基础】绘图

画笔 QPen pen; pen.setWidth(3); // 线条宽度 pen.setColor(Qt::red);// 画笔颜色 pen.setStyle(Qt::DashLine);// 线条样式 pen.setCapStyle(Qt::RoundCap);// 线端样式 pen.setJoinStyle(Qt::BevelJoin);// 连接样式 painter.setPen(pen);线条 线端 连接 画刷 QBrush bru…

css设置弹性flex后,如果设置100vh高度不撑满的原因

问题 父元素设置height为100%&#xff0c;有两个子元素&#xff0c;第一个设置height:100vh&#xff0c;第二个设置flex:1&#xff0c;此时第一个高度无法撑满盒子 原因解决方式 当父元素设置display为flex,第一个div设置高度64px,剩一个div设置高度为flex&#xff1a;1,这时…

数据处理-Matplotlib 绘图展示

文章目录 1. Matplotlib 简介2. 安装3. Matplotlib Pyplot4. 绘制图表1. 折线图2. 散点图3. 柱状图4. 饼图5. 直方图 5. 中文显示 1. Matplotlib 简介 Matplotlib 是 Python 的绘图库&#xff0c;它能让使用者很轻松地将数据图形化&#xff0c;并且提供多样化的输出格式。 Ma…

Qt项目中添加自定义文件夹,进行整理归类

Qt项目中添加文件夹进行归类 1、在windows的工程目录下创建一个文件夹&#xff0c;如widgets 2、将.h 、.cpp、.ui文件拷贝到windows该文件夹widgets 3、在qt工程中&#xff0c;根目录右键&#xff0c;选择添加现有文件&#xff0c;批量选择 .h 、.cpp、.ui文件之后&#xf…

初识影刀:EXCEL根据部门筛选低值易耗品

第一次知道这个办公自动化的软件还是在招聘网站上&#xff0c;了解之后发现对于办公中重复性的工作还是挺有帮助的&#xff0c;特别是那些操作非EXCEL的重复性工作&#xff0c;当然用在EXCEL上更加方便&#xff0c;有些操作比写VBA便捷。 下面就是一个了解基本操作后&#xff…

开发总结 - H5/web C端评论区开发逻辑

1. 背景 平时做的系统都是偏公司业务的系统&#xff0c;这次开发了一个用户评论的功能&#xff0c;同时开发了web版和H5版本的&#xff0c;因为没有做过这种C端的常用的功能&#xff0c;所以记录一下此次的开发&#xff0c;从参考友商设计到独立思考业务之间的区别再到实际开发…

everything搜索不到任何文件-设置

版本&#xff1a; V1.4.1.1024 (x64) 问题&#xff1a;搜索不到任何文件 click:[工具]->[选项]->下图所示 将本地磁盘都选中包含

2024 辽宁省大学数学建模竞赛B 题 钢铁产品质量优化完整思路 代码 结果分享(仅供学习)

冷轧带钢是钢铁企业的高附加值产品,其产品质量稳定性对于钢铁企业的经济效益具有非常重要的影响。在实际生产中&#xff0c;冷连轧之后的带钢需要经过连续退火处理来消除因冷轧产生的内应力并提高其机械性能。连续退火的工艺流程如图1 所示&#xff0c;一般包括加热、保温、缓冷…

Datawhale AI 夏令营 Task1

记录第一次参加Kaggle上的比赛&#xff0c;通过一站式的教程&#xff0c;没有一点阻碍的跑通了baseline 夏令营方向的选择 我选择的夏令营是关于CV方向的&#xff0c;因为本身对于cv方向比较感兴趣&#xff0c;而且这次夏令营的方式我很喜欢&#xff0c;通过比赛来促进学习&a…

板级调试小助手(5)基于Python访问千帆大模型

一、前言 千帆大模型是百度提供的可以使用API接口调用GPT模型&#xff0c;使用Python调用其实是很简单的&#xff1a;去千帆大模型申请账号->使用python调用API即可&#xff0c;具体可以参考这位大佬的博客&#xff0c;这里就不赘述了。 【教程】如何用Python调用百度的千帆…

基于Java+SpringMvc+Vue技术的药品进销存仓库管理系统设计与实现系统(源码+LW+部署讲解)

注&#xff1a;每个学校每个老师对论文的格式要求不一样&#xff0c;故本论文只供参考&#xff0c;本论文页数达到60页以上&#xff0c;字数在6000及以上。 基于JavaSpringMvcVue技术的在线学习交流平台设计与实现 目录 第一章 绪论 1.1 研究背景 1.2 研究现状 1.3 研究内容…

数据结构和算法(0-1)----递归

定义​ 递归是一种在程序设计中常用的技术&#xff0c;它允许一个函数调用自身来解决问题。递归通常用于解决那些可以被分解为相似的子问题的问题&#xff0c;这些问题的解决方式具有自相似性。在数据结构和算法中&#xff0c;递归是一种重要的解决问题的方法&#xff0c;尤其是…

项目范围管理-系统架构师(二十九)

1、&#xff08;重点&#xff09;软件设计包括了四个独立又相互联系的活动&#xff0c;高质量的&#xff08;&#xff09;将改善程序结构的模块划分&#xff0c;降低过程复杂度。 A程序设计 B数据设计 C算法设计 D过程设计 解析&#xff1a; 软件设计包含四个&#xff0c;…

Golang | Leetcode Golang题解之第232题用栈实现队列

题目&#xff1a; 题解&#xff1a; type MyQueue struct {inStack, outStack []int }func Constructor() MyQueue {return MyQueue{} }func (q *MyQueue) Push(x int) {q.inStack append(q.inStack, x) }func (q *MyQueue) in2out() {for len(q.inStack) > 0 {q.outStack…

Linux权限相关

目录 Linux中的用户 Linux权限管理 Linux的文件访问者分类 Linux的文件类型和访问权限 文件类型 文件权限 文件权限的修改 文件所有者修改 文件所有者所在组修改 目录权限 粘滞位 文件掩码 在Linux中&#xff0c;权限包括用户的权限和文件的权限 Linux中的用户 在…

Android 儿童绘本/汉语拼音实现

有这样一个项目&#xff0c;开发一个电子绘本&#xff0c;需要在绘本上显示&#xff0c;汉语拼音。 界面布局 <androidx.core.widget.NestedScrollViewandroid:layout_width"match_parent"android:layout_height"match_parent"android:fillViewport&quo…

路径规划 | 飞蛾扑火算法求解二维栅格路径规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 路径规划 | 飞蛾扑火算法求解二维栅格路径规划&#xff08;Matlab&#xff09;。 飞蛾扑火算法&#xff08;Firefly Algorithm&#xff09;是一种基于自然界萤火虫行为的优化算法&#xff0c;在路径规划问题中也可以应…