一文了解SpringCloud

news2024/11/15 10:17:29

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/1927424.html

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

相关文章

保姆级教程--容器化部署prometheusd监控系统(yaml文件、docker命令均有详细解释、大白话描述服务作用、适合小白)

文章目录 前言用到的服务简述容器化部署prometheus的优势 环境一、安装docker二、容器化构建Prometheus监控系统1 部署Prometheus2.部署grafana 三、prometheus监控其他主机1.部署docker补充、如何查找仪表盘 前言 用到的服务简述 Prometheus&#xff1a;这是一个开源的监控系…

使用Copilot 高效开发繁忙的一天

在现代软件开发的世界里&#xff0c;使用AI工具如GitHub Copilot可以显著提高开发效率。 早晨&#xff1a;规划与启动 7:00 AM - 起床与准备 开发者早早起床&#xff0c;享用健康的早餐&#xff0c;并浏览新闻和技术博客&#xff0c;了解最新的科技动态。快速整理思路&#x…

WordPress:无法创建新文章?创建新帖子时候页面空白

wordPress中我们新建文章的时候&#xff0c;会遇到页面空白&#xff0c;这个问题是怎么导致呢&#xff1f;我们可以打开F12开发者模式看下报错信息&#xff0c;这是一个警告信息 Warning: Creating default object from empty value in /pub 到数据库 wp_posts中查看生成了很…

网络配置命令

文章目录 一、查看网络接口信息 ifconfig1.1 网络接口名称1.2 使用 ifconfig 查看网络接口信息1.2.1 输出示例1.2.2 输出解释 1.3 查看特定网络接口信息1.3.1 输出示例 1.4 查看所有网络接口信息1.5 特殊网络接口 二、修改网络配置文件2.1 配置文件示例2.2 使配置生效2.3 关闭 …

【07】分布式事务解决方案

1、事务简介 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。在关系数据库中&#xff0c;一个事务由一组SQL语句组成。事务应该具有ACID四个特性&#xff1a;原子性、一致性、隔离性、持久性。任何事务机制在实现时&#xff0c;都应该考虑事务…

【Nuxt3】vue3+tailwindcss+vuetify引入自定义字体样式

一、目的 在项目中引入自定义的字体样式&#xff08;全局页面都可使用&#xff09; 二、步骤 1、下载好字体 字体的后缀可以是ttf、otf、woff、eot或者svg&#xff08;推荐前三种&#xff09; 以抖音字体为例下载好放在静态文件夹&#xff08;font&#xff09;下 案例字…

Python for循环while循环实战: 原神加载画面

原神加载画面在我们看起来是能一直运行的&#xff0c;实际上&#xff0c;它就是用了循环。今天&#xff0c;我们来模拟一下。 我们用123、234、345、456分别代表四个画面&#xff0c;结果是这样的。 这是代码&#xff1a; a [123, 234, 345, 456] while True:for i in a:pri…

python获取豆瓣评分9分以上的电影

我想生成的文件用excel保存&#xff0c;所以得安装一下这个 pip install pandas openpyxl代码 import requests import pandas as pd# 模拟浏览器请求头 headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91…

轻空间强势维护知识产权,捍卫气膜声学专利

在当前创新驱动的时代&#xff0c;知识产权已成为企业核心竞争力的重要组成部分。轻空间&#xff0c;作为一家以技术创新为驱动的公司&#xff0c;一直致力于为客户提供高质量的气膜建筑产品和服务。近期&#xff0c;我们注意到有不法分子冒用苏州大学多功能气膜综合馆项目的名…

springboot 适配ARM 架构

下载对应的maven https://hub.docker.com/_/maven/tags?page&page_size&ordering&name3.5.3-alpinedocker pull maven:3.5.3-alpinesha256:4c4e266aacf8ea6976b52df8467134b9f628cfed347c2f6aaf9e6aff832f7c45 2、下载对应的jdk https://hub.docker.com/_/o…

Ceph集群部署(基于ceph-deploy)

目录 部署Ceph集群的方法 Ceph生产环境推荐 部署Ceph实验&#xff08;基于ceph-deploy&#xff09; 一、准备工作 二、环境准备 1.关闭selinux与防火墙 2.修改主机名并且配置hosts解析映射 3.admin管理节点配置ssh免密登录node节点 4.安装常用软件和依赖包 5.配置时间…

【全网最全最详细】Spring与SpringBoot最新面试题

目录 一、Spring框架概述 1.1 什么是Spring&#xff1f; 1.2 spring优点有哪些&#xff1f; 二、IOC与DI 2.1 你知道getBean方法的有几种重载方式吗&#xff1f; 2.2 Spring有几种依赖注入方式&#xff1f; 2.3 为什么Spring不建议使用字段注入方式&#xff1f; 2.4 B…

数据结构_顺序表专题

何为数据结构&#xff1f; 咱今天也来说道说道...... 数据结构介绍 准确概念 数据结构就是计算机存储、组织数据的方式 概念分析 从上句分析&#xff0c;数据结构是一种方式。一种管理数据的方式。为了做什么&#xff1f;为的就是计算机存储数据&#xff0c;组织数据。 …

docker部署seata 2.0.0

环境准备 当前使用的环境&#xff1a; MySQL&#xff1a;8.0 nacos&#xff1a;2.2.3 关于如何在docker中部署nacos 2.2.3&#xff0c;请参考之前文章&#xff1a; docker部署nacos 2.2.3 拉取镜像 docker pull seataio/seata-server:2.0.0查看nacos、mysql、宿主机的ip d…

探索Facebook:数字社交的魔力源泉

在当今信息爆炸和全球互联的时代&#xff0c;社交媒体平台成为了人们生活中不可或缺的一部分。而在这些平台中&#xff0c;Facebook无疑是最具影响力和创新性的代表之一。自2004年成立以来&#xff0c;Facebook不仅改变了人们的沟通方式&#xff0c;更通过不断的技术创新和用户…

Oracle查询超时问题,聊聊思路!

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

【系统架构设计师】九、软件工程(面向对象方法|逆向工程)

目录 六、面向对象方法 6.1 基本概念 6.2 面向对象的分析 6.2.1 用例关系 6.2.2 类之间的关系 6.3 面向对象的设计 6.4 面向对象设计原则与设计模式 6.5 面向对象软件的测试 七、逆向工程 历年真题练习 六、面向对象方法 面向对象的分析方法 (Object-Oriented Analys…

C++初阶:类和对象(二)

✨✨所属专栏&#xff1a;C✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 类的默认成员函数 默认成员函数就是用户没有显式实现&#xff0c;编译器会⾃动⽣成的成员函数称为默认成员函数。⼀个类&#xff0c;我们不写的情况下编译器会默认⽣成以下6个默认成员函数&#xff0c;需要注…

Verilog基础:简单标识符和转义标识符

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 标识符(identifier)是一个为了引用而给一个对象起的名字。一个标识符可以是一个简单标识符&#xff0c;也可以是一个转义标识符。本文将对两者进行详细阐述。 简…

ctfshow-web入门-php特性(web109-web115)

目录 1、web109 2、web110 3、web111 4、web112 5、web113 6、web114 7、web115 1、web109 正则匹配要求 v1 和 v2 都包含字母&#xff0c;eval 函数将字符串作为 PHP 代码执行&#xff1a;new $v1 创建一个名为 v1 的类的实例&#xff0c;($v2()) 调用 v2 方法&#xff…