首页 > 其他分享 >网关 + Nacos配置管理

网关 + Nacos配置管理

时间:2025-01-10 13:04:22浏览次数:3  
标签:网关 配置 配置管理 Nacos nacos public 路由 路由表

网关

网关:就是网络的关口,负责请求的路由、转发、身份校验。
在这里插入图片描述

网关路由

  1. 新建网关模块gateway
  2. 引入相关依赖
<!--网关-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos discovery-->
<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-loadbalancer</artifactId>
</dependency>
  1. 写启动类
  2. 配置路由规则
server:
  port: 8080 # 前端请求的端口(网关的端口)

spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: 192.168.140.101:8848 # nacos地址
    # 路由配置
    gateway:
      routes:
        - id: item-service # 路由规则id,自定义,唯一
          uri: lb://item-service # 路由目标微服务,lb代表负载均衡协议
          predicates: # 路由断言,判断请求是否符合要求,符合则路由到目标
            - Path=/items/**, /search/** # 以请求路径做判断,以/items或/search开头则符合
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/addresses/**, /users/**
        - id: trade-service
          uri: lb://trade-service
          predicates:
            - Path=/orders/**
        - id: pay-service
          uri: lb://pay-service
          predicates:
            - Path=/pay-orders/**
        - id: cart-service
          uri: lb://cart-service
          predicates:
            - Path=/carts/**

路由属性

网关路由对应的Java类型是RouteDefinition,常见的属性有:

  • id:路由唯一标识
  • uri:路由目标地址
  • predicates:路由断言,判断请求是否符合当前路由
  • filters:路由过滤器,对请求或响应做特殊处理

predicates路由断言

文档:predicates路由断言
在这里插入图片描述

filters路由过滤器

文档:filters路由过滤器
在这里插入图片描述

自定义过滤器

网关过滤器有两种:

  1. GatewayFilter:路由过滤器,作用于任意指定的路由,默认不生效,要陪知道路由后生效。
  2. GlobalFilter(常用):全局过滤器,作用范围是所有路由;声明后自动生效。
    在这里插入图片描述

自定义GlobalFilter

@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取请求
        HttpHeaders headers = exchange.getRequest().getHeaders();
        // 过滤器业务处理(登录校验逻辑...)
        if(...) {
        	// 拦截
        	ServerHttpResponse response = exchange.getResponse();
        	response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        return chain.filter(exchange); // 放行
    }
	// 控制过滤器执行顺序
    @Override
    public int getOrder() {
        return 0; // 值越小,优先级越高
    }
}

自定义的过滤器需要在NettyRoutingFilter【将请求转发到微服务】这个过滤器之前执行,所以需要再继承一个Ordered接口,来保证我们自定义的过滤器的优先级比NettyRoutingFilter高

网关登录校验

在这里插入图片描述

网关传递用户

在这里插入图片描述

  1. 在网关的登录校验过滤器中,从前端发送的请求头里拿到用户信息,并把用户信息放到请求头里,再发给微服务。
ServerWebExchange swe = exchange.mutate()
		                .request(builder -> builder.header("user-info", userInfo))
		                .build(); // 传递的时候,需要传递这个返回的新的exchange
  1. 在微服务中定义拦截器,保存网关发过来的用户信息到ThreadLocal里。
// 定义拦截器
// 因为校验请求头这些操作已经在网关做过了,所以拦截器里边只需要把用户信息保存到ThreadLocal里即可
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取用户信息
        String userInfo = request.getHeader("user-info");
        // 判断是否获取了用户信息
        if(StrUtil.isNotBlank(userInfo)) {
            // 存入上下文
            UserContext.setUser(Long.valueOf(userInfo));
        }
        // 放行
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清理用户
        UserContext.removeUser();
    }
}
// 注册拦截器
/**
 * DispatcherServlet.class:springmvc的核心api
 * 防止网关【没有SpringMvc】也引用这个类
 */
@ConditionalOnClass(DispatcherServlet.class) // 条件注解
@Configuration
public class MvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor());
    }
}

由于很多微服务,都需要获取用户信息,不可能在这么多微服务里都一个拦截器,太麻烦啦。所以就把拦截器的代码写在common公共模块。
问题】:配置类想要生效,需要被Spring扫描包扫描到,但是现在mvc配置类是在common公共模块下,但是是其他微服务使用这个拦截器,无法扫描到这个配置类。
解决】:利用SpringBoot自动装配的原理,将定义的配置类放在了META-INF下的spring.factories文件下,这样就能实现自动装

OpenFeign传递用户信息

在这里插入图片描述
分析】:购物车服务中的请求,不是直接从网关发过来的,而是网关先发给交易服务,再由交易服务通过OpenFeign向购物车服务中发送请求【微服务之间的调用】。
解决】:OpenFeign提供了一个拦截器接口,所有由OpenFeign发起的请求都会先调用拦截器处理请求。

public class DefaultFeignConfig {
	@Bean
	public RequestInterceptor userInfoRequestInterceptor() {
		return new RequestInterceptor() {
			@Override
			public void apply(RequestTemplate template) {
				// 交易服务可以拿到用户信息,它向购物车发请求时,UserContext里会保存用户信息
				Long userId = UserContext.getUser();
				if (userId != null) {
					// 把用户信息放到请求头中
					template.header("user-info", userId.toString()); 
				}
			}
		};
	}
}


Nacos配置管理

存在问题】:

  1. 微服务重复配置过多,维护成本高。
  2. 业务配置经常变动,每次修改都要重启服务
  3. 网关路由配置写死,如果变更都要重启网关
    在这里插入图片描述

配置共享

1. 添加共享配置

打开nacos控制台,添加一些共享配置到nacos中,包括:jdbc、日志、swagger、openfeign等配置。在这里插入图片描述在这里插入图片描述

2. 拉取共享配置

基于NacosConfig拉取共享配置代替微服务的本地配置
在这里插入图片描述

  1. 引入依赖
  <!--nacos配置管理-->
  <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  </dependency>
  <!--读取bootstrap文件-->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-bootstrap</artifactId>
  </dependency>

2.新建bootstrap.yaml文件

spring:
  application:
    name: cart-service # 微服务的名称
  profiles:
    active: dev
  cloud:
    nacos:
      server-addr: 192.168.140.101:8848
      config:
        file-extension: yaml
        shared-configs:
          - data-id: shared-jdbc.yaml
          - data-id: shared-log.yaml
          - data-id: shared-swagger.yaml

在这里插入图片描述

先加载bootstrap配置文件,拉取nacos配置,再进行合并。

配置热更新

当修改配置文件中的配置时,微服务无需重启即可使配置生效。
条件】:

  1. nacos中要有一个与微服务名有关的配置文件。
    在这里插入图片描述
  2. 微服务中要以特定方式读取需要热更新的配置属性。
@Data
@Component
@ConfigurationProperties(prefix = "hm.cart")
public class CartProperties {
    private Integer maxItems;
}

对应nacos中的配置:
在这里插入图片描述

动态路由

要实现动态路由首先要将路由配置保存到nacos中,当nacos中路由配置变更时,推送最新配置到网关,更新网关中的路由信息。

  1. 拉取配置并添加监听器
  2. 路由表里的内容变更项目启动时,更新路由表
@Component
@RequiredArgsConstructor
public class DynamicRouteLoader {
    private final NacosConfigManager nacosConfigManager;
    private final RouteDefinitionWriter writer;
    private final String dataId = "gateway-routes.json";
    private final String group = "DEFAULT_GROUP";
    private final Set<String> routeIds = new HashSet<>(); // 保存旧的路由表
    @PostConstruct // 在项目一启动的时候执行
    public void init() throws NacosException {
        // 1. 项目启动,先拉取配置,并添加配置监听器
        String configInfo = nacosConfigManager.getConfigService()
                .getConfigAndSignListener(dataId, group, 5000, new Listener() {
                    @Override
                    public Executor getExecutor() { // 定义线程池
                        return null;
                    }

                    @Override
                    public void receiveConfigInfo(String configInfo) { // 配置变更时做的事
                        // 2. 监听到配置变更时,需要去更新路由表
                        updateConfigInfo(configInfo);
                    }
                });
        // 3. 第一次读取到配置,也需要更新路由表
        updateConfigInfo(configInfo);
    }

    // 更新路由表【利用RouteDefinitionWriter来更新路由表】
    public void updateConfigInfo(String configInfo) { // configInfo就是配置文件的内容
        // 1. 解析配置文件,转为RouteDefinition
        List<RouteDefinition> routes = JSONUtil.toList(configInfo, RouteDefinition.class);
        // 2. 更新路由表
        // 【删】删除旧的路由表
        for (String routeId : routeIds) {
            writer.delete(Mono.just(routeId)).subscribe();
        }
        // 清空旧的路由表
        routeIds.clear();
        for (RouteDefinition route : routes) {
            // 【增】新增新的路由表
            writer.save(Mono.just(route)).subscribe();
            // 记录路由id,便于下次更新时删除
            routeIds.add(route.getId());
        }
    }
}
  1. 在nacos中添加动态路由
    在这里插入图片描述

【注】:为了方便解析从nacos读取到的路由配置,推荐使用json格式的路由配置。

标签:网关,配置,配置管理,Nacos,nacos,public,路由,路由表
From: https://blog.csdn.net/qq_57882997/article/details/145009706

相关文章

  • Qt QSetting配置管理
    QSetting配置管理QSetting是Qt框架中用于管理应用程序配置和设置的类。它提供了一种简单的方式来存储和检索应用程序的设置,通常用于保存用户偏好、窗口位置、最近打开的文件等信息。主要功能跨平台支持:QSetting在不同操作系统上使用不同的后端存储:Windows:使用注册表macOS......
  • 手把手教你配置EtherCAT转Modbus网关连接TwinCAT3
    在工业自动化控制系统中,常常需要整合不同的通信协议设备。本案例旨在展示如何利用捷米特JM-ECT-RTU协议转换网关模块,实现EtherCAT网络与Modbus设备之间的无缝连接,并在TwinCAT3环境中进行有效配置,以构建一个稳定可靠的自动化控制系统ETHERCAT 技术参数捷米JM-ECT-RTU网......
  • AI智能分析视频分析网关关于人工智能在视频分析中是如何实现实时分析的?
    在当今数字化时代,人工智能技术的迅猛发展为各行各业带来了革命性的变革。特别是在视频分析领域,AI的应用使得实时分析成为可能,极大地提升了视频数据处理的效率和准确性。随着城市智能化进程的不断推进,实时视频分析在智慧城市建设、公共安全、交通管理等众多领域发挥着至关重要的作......
  • 工业智能网关在数据采集方面的应用介绍
    工业智能网关作为连接现场设备与云端系统的关键桥梁,其数据采集功能显得尤为重要。通过高效、安全的数据采集,工业智能网关不仅提升了生产效率和设备维护的及时性,还为企业的智能化管理提供了坚实的基础。本文将深入探讨工业智能网关在数据采集方面的应用、原理、特点以及最新技术......
  • Modbus协议网关的工作原理及功能解析
    一、Modbus协议网关的工作原理Modbus协议网关能够在Modbus协议与其他主流协议(如MQTT、OPCUA、HTTP等)之间进行数据转换,实现设备之间的无缝连接与数据集成。在Modbus主/从通信模式中,网关作为核心设备,负责采集Modbus从设备的数据,并将这些数据转换成其他协议格式,上传至云平台或本......
  • 若依框架(ruoyi-master)——13.Nacos,使用服务注册和服务诶只
    若依(Ruoyi)框架中如何使用Nacos?若依框架的微服务版项目启动Nacos下载和启动Nacos服务注册和配置接下来,我们可以查看若依框架微服务版如何使用Nacos?前提JDK>=1.8(推荐1.8版本)Mysql>=5.7.0(推荐5.7版本)\Redis>=3.0Maven>=3.0Node>=12nacos>=2.0.4(ruo......
  • Ensp基础实验---同网段PC以及网关之间的通信
        通过安装ENSP,可以模拟搭建网络仿真环境,初步了解ENSP之后,可以进行一些简单的网络拓扑搭建,通过对相关设备的配置,实现网络畅通的目的    此次模拟的是同一个网段内,两台PC之间的通信情况,同时选用路由器的一个指定接口,用作整个网络网段的网关,检验PC与网关之间的......
  • 空压机网络接入实战:基于 MODBUS - TCP 转 Ethernet IP 网关的配置过程剖析
     在工业自动化生产环境中,空压机作为重要的气源设备,其稳定运行和有效监控对于整个生产流程至关重要。然而,不同厂家生产的空压机可能采用不同的通信协议,这给集中监控和管理带来了挑战。在本次案例中,我们遇到的空压机采用MODBUS-TCP协议进行数据传输,但企业的自动化控制系统主......
  • docker启动nacos报错: Nacos Server did not start because dumpservice bean constru
    一、docker启动nacos报错:mysql版本:8nacos版本:2.xNacosServerdidnotstartbecausedumpservicebeanconstructionfailure:NoDataSourcesetNacosisstarting,youcandockerlogsyourcontainer+exec/opt/java/openjdk/bin/java-XX:+UseConcMarkSweepGC-XX:+U......
  • [.NET] API网关选择:YARP还是Ocelot?
    API网关选择:YARP还是Ocelot?摘要随着微服务架构的流行,API网关在系统架构中扮演着越来越重要的角色。在.NET生态中,YARP(YetAnotherReverseProxy)和Ocelot是两种常用的API网关解决方案。那么,在实际应用中,我们该如何选择?本文将从易用性、文档、负载均衡、限流、身份验证、授权和性......