Java微服务架构中的双剑合璧:Nacos与Gateway深度解析

一、引言:微服务架构的兴起与挑战

1.1 从单体应用到微服务

还记得那个年代吗?所有的业务逻辑都堆积在一个巨大的WAR包里,部署在一台Tomcat服务器上。用户管理、订单处理、支付逻辑、库存管理------所有模块紧密耦合,牵一发而动全身。

单体应用的痛点

  • 维护困难:代码量越来越大,新人上手需要数周

  • 扩展性差:只能整体扩展,无法按需扩容

  • 技术栈绑定:整个应用必须使用同一套技术栈

  • 发布风险高:一个小改动需要重新部署整个应用

微服务架构应运而生。它将巨大的单体应用拆分成一组小型、自治的服务,每个服务负责一项具体的业务功能。就像一支交响乐队,每个乐器手专注自己的部分,却能协同演奏出美妙的乐章。

1.2 微服务带来的新挑战

然而,微服务不是银弹。它解决了单体应用的问题,却带来了新的挑战:

挑战一:服务通信

  • 服务之间如何相互调用?

  • 如何处理网络延迟和故障?

  • 如何实现负载均衡?

挑战二:服务发现

  • 服务实例动态变化(扩缩容、故障重启)

  • 如何找到可用的服务实例?

  • 如何保证服务列表的实时性?

挑战三:统一入口

  • 客户端如何知道该调用哪个服务?

  • 如何处理跨域、认证、限流?

  • 如何监控所有请求?

挑战四:配置管理

  • 配置文件分散在各个服务

  • 如何实现配置的动态更新?

  • 如何隔离不同环境的配置?

1.3 基础设施的重要性

没有完善的基础设施,微服务架构就像没有交通规则的城市------混乱、低效、危险。

必要的基础设施

  • 服务注册发现:解决"服务在哪"的问题

  • API网关:解决"如何访问"的问题

  • 配置中心:解决"如何配置"的问题

  • 负载均衡:解决"如何分配"的问题

  • 熔断降级:解决"如何容错"的问题

在这篇文章中,我们将深入探讨两个核心组件:NacosSpring Cloud Gateway。它们分别解决了服务发现和API路由的问题,是微服务架构的基石。

1.4 文章的价值

读完这篇文章,你将:

  • 理解服务注册发现和API网关的核心概念

  • 掌握Nacos和Gateway的配置和使用方法

  • 了解生产环境的最佳实践和故障排查技巧

  • 获得完整的实战示例代码

让我们开始这段微服务基础设施的探索之旅吧!


二、服务注册发现:微服务通信的基石

2.1 什么是服务注册发现

服务注册发现是微服务架构中最基础的组件,它解决了"服务在哪"的问题。

核心概念

  • 服务注册:服务启动时,将自己的地址信息注册到注册中心

  • 服务发现:服务消费者从注册中心获取服务提供者的地址列表

  • 健康检查:注册中心定期检测服务实例是否可用

  • 服务注销:服务下线时,从注册中心移除自己的信息

2.2 传统方式的痛点

在没有服务注册发现之前,我们通常这样配置:

复制代码
# 传统方式:硬编码服务地址
user-service:
  url: http://192.168.1.100:8080
  
order-service:
  url: http://192.168.1.101:8080

这种方式的弊端

  1. 配置繁琐:每个服务的地址都需要手动配置

  2. 维护困难:服务地址变更需要修改所有相关配置

  3. 无法动态扩展:新增服务实例需要重启消费者

  4. 故障转移困难:服务实例故障需要手动切换

2.3 服务注册发现的工作流程

让我们看看服务注册发现是如何工作的:

复制代码
┌─────────────┐      ①注册        ┌─────────────┐
│   服务A      │ ───────────────→  │  注册中心    │
│  (提供者)    │                   │             │
└─────────────┘                   └─────────────┘
       ↑                                 ↑
       │                                 │
       │④调用                           │②发现
       │                                 │
       ↓                                 ↓
┌─────────────┐      ③获取列表    ┌─────────────┐
│   服务B      │ ←───────────────  │  注册中心    │
│  (消费者)    │                   │             │
└─────────────┘                   └─────────────┘

详细流程

  1. 服务注册:服务A启动时,向注册中心注册自己的地址(IP:Port)

  2. 服务发现:服务B需要调用服务A时,从注册中心获取服务A的地址列表

  3. 负载均衡:服务B从地址列表中选择一个实例进行调用

  4. 健康检查:注册中心定期检测服务A是否健康,不健康的实例会被移除

2.4 核心功能需求

一个完善的服务注册发现组件应该具备:

基础功能

  • 服务注册与发现

  • 健康检查(TCP/HTTP/自定义)

  • 服务元数据管理

  • 服务上下线通知

高级功能

  • 负载均衡(轮询、随机、权重等)

  • 故障转移(自动跳过不健康实例)

  • 服务路由(基于元数据的路由规则)

  • 多数据中心支持

2.5 技术选型对比

市面上有多种服务注册发现方案,让我们对比一下:

特性 Eureka Consul ZooKeeper Nacos
一致性模型 AP CP CP AP/CP可切换
健康检查 客户端心跳 多种方式 Keep Alive 多种方式
配置管理 不支持 支持 不支持 支持
管理界面 简单 功能丰富 功能丰富
社区活跃度 降低 活跃 稳定 非常活跃
学习曲线 简单 中等 较难 简单
适用场景 Spring Cloud 多语言 大数据 云原生

选型建议

  • Spring Cloud项目:Nacos或Eureka

  • 多语言环境:Consul

  • 大数据生态:ZooKeeper

  • 云原生场景:Nacos


三、Nacos:一站式服务管理中心

3.1 Nacos的起源和定位

Nacos(Dynamic Naming and Configuration Service)是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

Nacos的定位

  • 服务发现:支持DNS和RPC服务发现

  • 配置管理:动态配置服务,配置热更新

  • 服务管理:服务元数据管理,流量管理

支持的服务框架

  • Spring Cloud

  • Apache Dubbo

  • Kubernetes

  • Service Mesh

3.2 核心功能详解

3.2.1 服务发现

Nacos提供两种服务发现方式:

1. 基于DNS的服务发现

复制代码
// 通过DNS获取服务地址
String serviceName = "user-service";
List<Instance> instances = namingService.getAllInstances(serviceName);

2. 基于HTTP的服务发现

复制代码
// 注册服务实例
Instance instance = new Instance();
instance.setIp("192.168.1.100");
instance.setPort(8080);
instance.setServiceName("user-service");
namingService.registerInstance("user-service", instance);

健康检查方式

  • TCP检查:检测端口是否可连接

  • HTTP检查:发送HTTP请求检测健康接口

  • MySQL检查:执行SQL语句检测数据库连接

  • 客户端心跳:客户端定期发送心跳包

3.2.2 配置管理

Nacos的配置管理功能非常强大:

配置热更新

复制代码
// 监听配置变化
configService.addListener("user-service.yaml", "DEFAULT_GROUP", new Listener() {
    @Override
    public void receiveConfigInfo(String configInfo) {
        // 配置变更处理逻辑
        System.out.println("配置已更新:" + configInfo);
    }
});

配置版本管理

  • 支持配置的历史版本记录

  • 支持配置回滚

  • 支持配置对比

灰度发布

  • 支持按IP、应用名等维度灰度发布

  • 支持配置的A/B测试

3.2.3 服务管理

服务元数据管理

复制代码
# 服务元数据配置
spring:
  cloud:
    nacos:
      discovery:
        metadata:
          version: 1.0.0
          env: production
          region: cn-hangzhou

流量管理

  • 权重管理:控制流量分配比例

  • 优雅上下线:避免流量损失

  • 服务依赖分析:可视化服务调用关系

3.3 架构设计

Nacos的架构设计非常精巧:

复制代码
┌─────────────────────────────────────────────────────────┐
│                    Nacos Server                         │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐    │
│  │   Naming    │  │   Config    │  │   Admin     │    │
│  │   Module    │  │   Module    │  │   Module    │    │
│  └─────────────┘  └─────────────┘  └─────────────┘    │
│           │               │               │            │
│           └───────────────┼───────────────┘            │
│                           │                            │
│                    ┌──────┴──────┐                     │
│                    │  Consistency│                     │
│                    │  Protocol   │                     │
│                    │ (AP/CP切换) │                     │
│                    └─────────────┘                     │
└─────────────────────────────────────────────────────────┘
                           │
           ┌───────────────┼───────────────┐
           │               │               │
    ┌──────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐
    │ Nacos Client│ │ Nacos Client│ │ Nacos Client│
    │ (服务A)     │ │ (服务B)     │ │ (服务C)     │
    └─────────────┘ └─────────────┘ └─────────────┘

核心组件

  • Naming Module:负责服务注册和发现

  • Config Module:负责配置管理

  • Admin Module:负责服务管理

  • Consistency Protocol:支持AP(Distro协议)和CP(Raft协议)切换

数据模型

  • Service:服务,如"user-service"

  • Cluster:集群,如"hangzhou-cluster"

  • Instance:实例,如"192.168.1.100:8080"

3.4 与其他方案的对比

vs Eureka
特性 Nacos Eureka
配置管理 支持 不支持
健康检查 多种方式 客户端心跳
管理界面 功能丰富 简单
社区活跃度 非常活跃 降低
云原生支持 优秀 一般
vs Consul
特性 Nacos Consul
易用性 简单 中等
中文文档 完善 一般
性能 优秀 良好
多数据中心 支持 支持
vs ZooKeeper
特性 Nacos ZooKeeper
适用场景 微服务 大数据
性能 优秀 一般
易用性 简单 较难
云原生支持 优秀 一般

Nacos的优势

  1. 功能全面:集成服务发现和配置管理

  2. 易于使用:中文文档友好,学习曲线平缓

  3. 性能优秀:支持百万级服务实例

  4. 云原生友好:支持Kubernetes、Service Mesh


四、API路由:微服务的统一入口

4.1 什么是API网关

API网关是微服务架构中的统一入口,它封装了应用程序的内部结构,为客户端提供统一的API。

核心功能

  • 路由转发:将请求路由到对应的微服务

  • 请求过滤:统一处理认证、授权、日志

  • 负载均衡:在多个服务实例间分配请求

  • 熔断降级:保护后端服务不被压垮

  • 限流控制:防止恶意请求或流量激增

4.2 没有API网关的问题

想象一下,如果没有API网关:

复制代码
客户端 ──→ 用户服务 (http://user-service:8081)
客户端 ──→ 订单服务 (http://order-service:8082)
客户端 ──→ 支付服务 (http://payment-service:8083)
客户端 ──→ 库存服务 (http://inventory-service:8084)

问题

  1. 客户端复杂:需要知道每个服务的地址

  2. 跨域问题:前端需要处理多个服务的跨域

  3. 认证分散:每个服务都需要实现认证逻辑

  4. 监控困难:无法统一监控所有请求

  5. 协议限制:客户端必须使用服务端的协议

4.3 API网关的核心价值

有了API网关之后:

复制代码
客户端 ──→ API网关 ──→ 用户服务
                  ──→ 订单服务
                  ──→ 支付服务
                  ──→ 库存服务

价值

  1. 统一入口:客户端只需知道网关地址

  2. 简化客户端:客户端不需要维护多个服务地址

  3. 统一认证:在网关层统一处理认证授权

  4. 协议转换:网关可以转换不同的协议

  5. 监控集中:统一监控所有请求

4.4 核心功能详解

4.4.1 路由配置

静态路由

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: http://user-service:8080
          predicates:
            - Path=/api/user/**

动态路由

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service  # 从注册中心获取服务地址
          predicates:
            - Path=/api/user/**

条件路由

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service-v2
          uri: lb://user-service-v2
          predicates:
            - Path=/api/user/**
            - Header=X-Version, v2
4.4.2 过滤器链

前置过滤器

复制代码
@Component
public class AuthFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 认证逻辑
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        if (!validateToken(token)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }
    
    @Override
    public int getOrder() {
        return -100; // 优先级
    }
}

后置过滤器

复制代码
@Component
public class LoggingFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        long startTime = System.currentTimeMillis();
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            long duration = System.currentTimeMillis() - startTime;
            // 记录请求日志
            log.info("请求路径: {}, 耗时: {}ms", 
                exchange.getRequest().getPath(), duration);
        }));
    }
}
4.4.3 安全控制

JWT验证

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
          filters:
            - name: JwtAuth
              args:
                secret: your-secret-key

API Key验证

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
          filters:
            - name: ApiKeyAuth
              args:
                header: X-API-Key
4.4.4 限流熔断

令牌桶限流

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20

熔断降级

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
          filters:
            - name: CircuitBreaker
              args:
                name: user-service-cb
                fallbackUri: forward:/fallback/user

4.5 技术选型对比

特性 Spring Cloud Gateway Zuul Kong APISIX
编程模型 响应式 同步阻塞 Nginx+Lua Nginx+Lua
性能 优秀 一般 优秀 优秀
限流集成 原生支持 需要额外配置 插件支持 插件支持
熔断集成 原生支持 需要Hystrix 插件支持 插件支持
WebSocket 支持 不支持 支持 支持
社区活跃度 活跃 降低 活跃 活跃
学习曲线 中等 简单 中等 中等

选型建议

  • Spring Cloud项目:Spring Cloud Gateway

  • 高性能场景:Kong或APISIX

  • 简单需求:Zuul


五、Gateway:新一代API网关

5.1 Gateway的定位和设计理念

Spring Cloud Gateway是Spring Cloud官方推荐的API网关,旨在为微服务架构提供一种简单有效的统一的API路由管理方式。

设计理念

  • 基于Spring WebFlux:响应式编程,非阻塞I/O

  • 高性能:比Zuul 1.x性能提升1.6倍

  • 动态路由:支持配置热更新

  • 集成性强:与Spring Cloud生态无缝集成

5.2 核心架构组件

Gateway的核心由三个组件构成:

1. Route(路由)

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service  # 路由ID
          uri: lb://user-service  # 目标URI
          predicates:  # 断言
            - Path=/api/user/**
          filters:  # 过滤器
            - StripPrefix=1

2. Predicate(断言)

复制代码
// 11种断言工厂
- Path=/api/user/**          // 路径断言
- Method=GET                  // 方法断言
- Header=X-Request-Id, \d+   // 头部断言
- Query=name, zhangsan       // 查询参数断言
- Cookie=session, abc        // Cookie断言
- After=2024-01-01T00:00:00  // 时间断言
- RemoteAddr=192.168.1.1/24  // 远程地址断言
- Weight=group1, 8           // 权重断言

3. Filter(过滤器)

复制代码
// 30+过滤器工厂
- AddRequestHeader=X-Request-Name, zhangsan  // 添加请求头
- AddResponseHeader=X-Response-Foo, Bar      // 添加响应头
- StripPrefix=1                               // 去除前缀
- PrefixPath=/api                             // 添加前缀
- RewritePath=/api/(?<segment>.*), /${segment} // 路径重写
- RequestRateLimiter                           // 限流
- CircuitBreaker                               // 熔断

5.3 工作原理

Gateway的请求处理流程:

复制代码
┌─────────────┐
│   客户端     │
└──────┬──────┘
       │
       ↓
┌─────────────────────────────────────────────────────┐
│                Gateway Handler                       │
│  ┌───────────────────────────────────────────────┐  │
│  │            Route Predicate Handler             │  │
│  │  ┌─────────────────────────────────────────┐  │  │
│  │  │      Handler Mapping                    │  │  │
│  │  │  (根据断言匹配路由)                      │  │  │
│  │  └─────────────────────────────────────────┘  │  │
│  │  ┌─────────────────────────────────────────┐  │  │
│  │  │      Handler Adapter                    │  │  │
│  │  │  (执行过滤器链)                          │  │  │
│  │  └─────────────────────────────────────────┘  │  │
│  └───────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────┐  │
│  │            Filter Chain                       │  │
│  │  ┌─────────┐  ┌─────────┐  ┌─────────┐      │  │
│  │  │Filter 1 │→ │Filter 2 │→ │Filter N │      │  │
│  │  └─────────┘  └─────────┘  └─────────┘      │  │
│  └───────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────┘
       │
       ↓
┌─────────────┐
│  后端服务    │
└─────────────┘

详细流程

  1. 请求进入:客户端发送请求到Gateway

  2. 路由匹配:Handler Mapping根据断言匹配路由

  3. 前置过滤:执行前置过滤器链

  4. 请求转发:转发请求到后端服务

  5. 后置过滤:执行后置过滤器链

  6. 响应返回:返回响应给客户端

5.4 核心功能详解

5.4.1 路由配置

配置文件方式

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
            - Method=GET
          filters:
            - StripPrefix=1
            - AddRequestHeader=X-Request-Source, gateway

代码配置方式

复制代码
@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("user-service", r -> r
                .path("/api/user/**")
                .and()
                .method(HttpMethod.GET)
                .filters(f -> f
                    .stripPrefix(1)
                    .addRequestHeader("X-Request-Source", "gateway"))
                .uri("lb://user-service"))
            .build();
    }
}

动态路由

复制代码
@RestController
public class DynamicRouteController {
    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;
    
    @PostMapping("/routes")
    public String addRoute(@RequestBody RouteDefinition definition) {
        routeDefinitionWriter.save(Mono.just(definition)).subscribe();
        return "success";
    }
    
    @DeleteMapping("/routes/{id}")
    public String deleteRoute(@PathVariable String id) {
        routeDefinitionWriter.delete(Mono.just(id)).subscribe();
        return "success";
    }
}
5.4.2 断言工厂

路径断言

复制代码
predicates:
  - Path=/api/user/**      # 匹配 /api/user/ 开头的路径
  - Path=/api/{segment}    # 匹配 /api/ 后跟任意路径

方法断言

复制代码
predicates:
  - Method=GET             # 匹配GET请求
  - Method=GET,POST        # 匹配GET或POST请求

头部断言

复制代码
predicates:
  - Header=X-Request-Id, \d+  # 匹配X-Request-Id为数字的请求
  - Header=X-Version          # 匹配包含X-Version头的请求

查询参数断言

复制代码
predicates:
  - Query=name, zhangsan   # 匹配name参数为zhangsan
  - Query=age              # 匹配包含age参数

时间断言

复制代码
predicates:
  - After=2024-01-01T00:00:00+08:00    # 在指定时间之后
  - Before=2024-12-31T23:59:59+08:00   # 在指定时间之前
  - Between=2024-01-01T00:00:00+08:00, 2024-12-31T23:59:59+08:00  # 在时间区间内

权重断言

复制代码
predicates:
  - Weight=group1, 8       # 权重为8
5.4.3 过滤器工厂

添加请求头

复制代码
filters:
  - AddRequestHeader=X-Request-Name, zhangsan
  - AddRequestHeader=X-Request-Source, gateway

添加响应头

复制代码
filters:
  - AddResponseHeader=X-Response-Foo, Bar
  - AddResponseHeader=X-Response-Server, Gateway

去除前缀

复制代码
filters:
  - StripPrefix=1  # 去除第一个路径前缀
  # /api/user/123 → /user/123

添加前缀

复制代码
filters:
  - PrefixPath=/api  # 添加/api前缀
  # /user/123 → /api/user/123

路径重写

复制代码
filters:
  - RewritePath=/api/(?<segment>.*), /${segment}
  # /api/user/123 → /user/123

限流过滤器

复制代码
filters:
  - name: RequestRateLimiter
    args:
      redis-rate-limiter.replenishRate: 10  # 每秒填充10个令牌
      redis-rate-limiter.burstCapacity: 20  # 令牌桶容量20
      key-resolver: "#{@userKeyResolver}"   # 限流键解析器

熔断过滤器

复制代码
filters:
  - name: CircuitBreaker
    args:
      name: user-service-cb
      fallbackUri: forward:/fallback/user
      statusCodes: 500,502,503

5.5 与Zuul的对比

特性 Spring Cloud Gateway Zuul 1.x
编程模型 响应式(WebFlux) 同步阻塞(Servlet)
性能 吞吐量高 吞吐量一般
WebSocket 支持 不支持
限流 原生支持 需要Hystrix
熔断 原生支持 需要Hystrix
动态路由 支持 支持
过滤器 30+种 较少
社区 Spring Cloud官方推荐 Netflix维护减少

Gateway的优势

  1. 性能优秀:基于WebFlux,非阻塞I/O

  2. 功能丰富:原生支持限流、熔断、WebSocket

  3. 社区活跃:Spring Cloud官方维护

  4. 易于扩展:过滤器链机制,易于自定义


六、协同工作:Nacos与Gateway的完美配合

6.1 集成架构

Nacos和Gateway的集成架构非常优雅:

复制代码
┌─────────────────────────────────────────────────────────┐
│                    Nacos Server                         │
│  ┌─────────────────────────────────────────────────┐   │
│  │              Service Registry                   │   │
│  │  ┌───────────┐ ┌───────────┐ ┌───────────┐    │   │
│  │  │ user-svc  │ │ order-svc │ │ payment-svc│    │   │
│  │  │ instances │ │ instances │ │ instances  │    │   │
│  │  └───────────┘ └───────────┘ └───────────┘    │   │
│  └─────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────┘
           │                    │                    │
           │①注册              │②发现              │③发现
           │                    │                    │
    ┌──────┴──────┐      ┌──────┴──────┐      ┌──────┴──────┐
    │  Gateway    │      │  user-svc   │      │  order-svc  │
    │  (网关)     │      │  (用户服务) │      │  (订单服务) │
    └─────────────┘      └─────────────┘      └─────────────┘
           │
           │④路由转发
           │
    ┌──────┴──────┐
    │   客户端    │
    └─────────────┘

工作流程

  1. 服务注册:微服务启动时注册到Nacos

  2. 服务发现:Gateway从Nacos获取服务列表

  3. 路由转发:Gateway根据路由规则转发请求

  4. 负载均衡:Gateway在多个服务实例间负载均衡

6.2 动态路由配置

基于服务发现的路由配置:

复制代码
spring:
  application:
    name: gateway-service
  
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848  # Nacos Server地址
    
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service  # lb:// 表示使用负载均衡
          predicates:
            - Path=/api/user/**
          filters:
            - StripPrefix=1
        
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/order/**
          filters:
            - StripPrefix=1

配置说明

  • lb://user-service:从Nacos获取user-service的服务列表,使用负载均衡

  • StripPrefix=1:去除第一个路径前缀,如 /api/user/123/user/123

6.3 负载均衡实现

Gateway集成了Ribbon,实现客户端负载均衡:

复制代码
# 负载均衡配置
user-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule  # 轮询策略
    # 其他策略:
    # RandomRule: 随机
    # WeightedResponseTimeRule: 响应时间权重
    # BestAvailableRule: 最小并发

服务实例权重

复制代码
# 在Nacos中设置服务实例权重
spring:
  cloud:
    nacos:
      discovery:
        weight: 1  # 权重,范围0-100

6.4 完整请求流程

让我们看看一个完整的请求流程:

复制代码
1. 客户端发送请求
   GET http://gateway:8080/api/user/123
​
2. Gateway接收请求
   - 匹配路由:Path=/api/user/**
   - 目标服务:user-service
​
3. Gateway从Nacos获取服务列表
   - 获取user-service的所有实例
   - 实例列表:[192.168.1.100:8080, 192.168.1.101:8080]
​
4. Gateway执行负载均衡
   - 选择实例:192.168.1.100:8080
​
5. Gateway执行过滤器
   - StripPrefix=1:/api/user/123 → /user/123
   - AddRequestHeader:添加X-Request-Source: gateway
​
6. Gateway转发请求
   GET http://192.168.1.100:8080/user/123
​
7. user-service处理请求并返回响应
​
8. Gateway返回响应给客户端

6.5 高级特性

灰度发布

基于请求头的灰度发布:

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service-v1
          uri: lb://user-service-v1
          predicates:
            - Path=/api/user/**
            - Header=X-Version, v1
          filters:
            - StripPrefix=1
        
        - id: user-service-v2
          uri: lb://user-service-v2
          predicates:
            - Path=/api/user/**
            - Header=X-Version, v2
          filters:
            - StripPrefix=1
金丝雀发布

通过Nacos权重控制流量比例:

复制代码
# 在Nacos中设置权重
# user-service-v1: weight=90
# user-service-v2: weight=10
故障转移

自动跳过不健康的实例:

复制代码
spring:
  cloud:
    nacos:
      discovery:
        # 健康检查配置
        heart-beat-interval: 5000  # 心跳间隔5秒
        heart-beat-timeout: 15000  # 心跳超时15秒

七、实战配置:从零到一的完整示例

7.1 环境准备

7.1.1 Nacos Server安装和启动

下载Nacos

复制代码
# 下载Nacos 2.x版本
wget https://github.com/alibaba/nacos/releases/download/2.2.3/nacos-server-2.2.3.tar.gz
​
# 解压
tar -xzf nacos-server-2.2.3.tar.gz
cd nacos/bin

启动Nacos

复制代码
# 单机模式启动(开发环境)
./startup.sh -m standalone
​
# 集群模式启动(生产环境)
./startup.sh

访问Nacos控制台

7.1.2 MySQL持久化配置(可选)

创建数据库

复制代码
CREATE DATABASE nacos_config;
USE nacos_config;

-- 执行Nacos提供的SQL脚本
source nacos/conf/nacos-mysql.sql;

修改配置文件

复制代码
# nacos/conf/application.properties
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=your_password

7.2 Spring Cloud项目配置

7.2.1 创建父项目

pom.xml

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>com.example</groupId>
    <artifactId>microservice-demo</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/>
    </parent>
    
    <properties>
        <spring-cloud.version>2021.0.3</spring-cloud.version>
        <spring-cloud-alibaba.version>2021.0.3.0</spring-cloud-alibaba.version>
    </properties>
    
    <modules>
        <module>gateway-service</module>
        <module>user-service</module>
        <module>order-service</module>
    </modules>
    
    <dependencyManagement>
        <dependencies>
            <!-- Spring Cloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            
            <!-- Spring Cloud Alibaba -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>
7.2.2 创建Gateway服务

pom.xml

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>com.example</groupId>
        <artifactId>microservice-demo</artifactId>
        <version>1.0.0</version>
    </parent>
    
    <artifactId>gateway-service</artifactId>
    
    <dependencies>
        <!-- Gateway网关 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        
        <!-- Nacos服务发现 -->
        <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>
    </dependencies>
</project>

application.yml

复制代码
server:
  port: 8080
​
spring:
  application:
    name: gateway-service
  
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: public
        group: DEFAULT_GROUP
    
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
          filters:
            - StripPrefix=1
        
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/order/**
          filters:
            - StripPrefix=1
      
      # 全局跨域配置
      globalcors:
        cors-configurations:
          '[/**]':
            allowedOriginPatterns: "*"
            allowedMethods: "*"
            allowedHeaders: "*"
            allowCredentials: true
            maxAge: 3600
​
logging:
  level:
    org.springframework.cloud.gateway: DEBUG

启动类

复制代码
package com.example.gateway;
​
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
​
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}
7.2.3 创建用户服务

pom.xml

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>com.example</groupId>
        <artifactId>microservice-demo</artifactId>
        <version>1.0.0</version>
    </parent>
    
    <artifactId>user-service</artifactId>
    
    <dependencies>
        <!-- Spring Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- Nacos服务发现 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>
</project>

application.yml

复制代码
server:
  port: 8081

spring:
  application:
    name: user-service
  
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: public
        group: DEFAULT_GROUP
        weight: 1

启动类

复制代码
package com.example.user;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

控制器

复制代码
package com.example.user.controller;
​
import org.springframework.web.bind.annotation.*;
​
@RestController
@RequestMapping("/user")
public class UserController {
    
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        // 模拟用户数据
        User user = new User();
        user.setId(id);
        user.setName("张三");
        user.setEmail("zhangsan@example.com");
        return user;
    }
    
    @PostMapping
    public User createUser(@RequestBody User user) {
        // 创建用户逻辑
        return user;
    }
}
​
@Data
class User {
    private Long id;
    private String name;
    private String email;
}
7.2.4 创建订单服务

pom.xml

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>com.example</groupId>
        <artifactId>microservice-demo</artifactId>
        <version>1.0.0</version>
    </parent>
    
    <artifactId>order-service</artifactId>
    
    <dependencies>
        <!-- Spring Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- Nacos服务发现 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        
        <!-- OpenFeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        
        <!-- 负载均衡 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>
</project>

application.yml

复制代码
server:
  port: 8082

spring:
  application:
    name: order-service
  
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: public
        group: DEFAULT_GROUP

启动类

复制代码
package com.example.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

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

Feign客户端

复制代码
package com.example.order.feign;
​
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
​
@FeignClient(name = "user-service")
public interface UserFeignClient {
    
    @GetMapping("/user/{id}")
    User getUser(@PathVariable Long id);
}

控制器

复制代码
package com.example.order.controller;
​
import com.example.order.feign.UserFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
​
@RestController
@RequestMapping("/order")
public class OrderController {
    
    @Autowired
    private UserFeignClient userFeignClient;
    
    @GetMapping("/{id}")
    public Order getOrder(@PathVariable Long id) {
        // 获取订单信息
        Order order = new Order();
        order.setId(id);
        order.setUserId(1L);
        order.setAmount(100.0);
        
        // 通过Feign调用用户服务
        User user = userFeignClient.getUser(order.getUserId());
        order.setUserName(user.getName());
        
        return order;
    }
}
​
@Data
class Order {
    private Long id;
    private Long userId;
    private String userName;
    private Double amount;
}

7.3 测试验证

7.3.1 启动服务

启动顺序

  1. 启动Nacos Server

  2. 启动用户服务

  3. 启动订单服务

  4. 启动Gateway服务

验证服务注册

复制代码
# 查看Nacos控制台,确认服务已注册
# 访问 http://127.0.0.1:8848/nacos
# 用户名:nacos
# 密码:nacos
7.3.2 测试路由

测试用户服务

复制代码
# 直接访问用户服务
curl http://127.0.0.1:8081/user/1

# 通过Gateway访问用户服务
curl http://127.0.0.1:8080/api/user/1

测试订单服务

复制代码
# 直接访问订单服务
curl http://127.0.0.1:8082/order/1

# 通过Gateway访问订单服务
curl http://127.0.0.1:8080/api/order/1
7.3.3 测试负载均衡

启动多个用户服务实例

复制代码
# 实例1
java -jar user-service.jar --server.port=8081
​
# 实例2
java -jar user-service.jar --server.port=8083

测试负载均衡

复制代码
# 多次请求,观察响应
for i in {1..10}; do
  curl http://127.0.0.1:8080/api/user/1
  echo ""
done
7.3.4 测试动态路由

添加路由

复制代码
curl -X POST http://127.0.0.1:8080/actuator/gateway/routes \
  -H "Content-Type: application/json" \
  -d '{
    "id": "payment-service",
    "uri": "lb://payment-service",
    "predicates": [
      {
        "name": "Path",
        "args": {
          "pattern": "/api/payment/**"
        }
      }
    ],
    "filters": [
      {
        "name": "StripPrefix",
        "args": {
          "parts": "1"
        }
      }
    ]
  }'

刷新路由

复制代码
curl -X POST http://127.0.0.1:8080/actuator/gateway/refresh

删除路由

复制代码
curl -X DELETE http://127.0.0.1:8080/actuator/gateway/routes/payment-service

八、最佳实践与故障排查

8.1 生产环境配置建议

8.1.1 Nacos配置

集群部署

复制代码
# Nacos集群配置(3节点以上)
# 节点1:192.168.1.100:8848
# 节点2:192.168.1.101:8848
# 节点3:192.168.1.102:8848
​
# application.properties
server.port=8848
nacos.inetutils.ip-address=192.168.1.100

命名空间隔离

复制代码
spring:
  cloud:
    nacos:
      discovery:
        namespace: dev  # 开发环境
        # namespace: test  # 测试环境
        # namespace: prod  # 生产环境

权限控制

复制代码
spring:
  cloud:
    nacos:
      discovery:
        username: nacos
        password: your_password
8.1.2 Gateway配置

超时配置

复制代码
spring:
  cloud:
    gateway:
      httpclient:
        connect-timeout: 5000  # 连接超时5秒
        response-timeout: 30s  # 响应超时30秒

重试策略

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
          filters:
            - name: Retry
              args:
                retries: 3
                statuses: BAD_GATEWAY,SERVICE_UNAVAILABLE
                methods: GET
                backoff:
                  firstBackoff: 100ms
                  maxBackoff: 500ms
                  factor: 2

限流配置

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20
                key-resolver: "#{@userKeyResolver}"

熔断配置

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
          filters:
            - name: CircuitBreaker
              args:
                name: user-service-cb
                fallbackUri: forward:/fallback/user
                statusCodes: 500,502,503

8.2 性能优化策略

8.2.1 Nacos优化

心跳间隔调整

复制代码
spring:
  cloud:
    nacos:
      discovery:
        heart-beat-interval: 5000  # 心跳间隔5秒(默认5秒)
        heart-beat-timeout: 15000  # 心跳超时15秒(默认15秒)

服务列表缓存

复制代码
spring:
  cloud:
    nacos:
      discovery:
        naming-load-cache-at-start: true  # 启动时加载缓存
8.2.2 Gateway优化

连接池配置

复制代码
spring:
  cloud:
    gateway:
      httpclient:
        pool:
          max-connections: 500  # 最大连接数
          acquire-timeout: 5000  # 获取连接超时
          max-idle-time: 20s  # 最大空闲时间
          max-life-time: 60s  # 最大生命周期

内存管理

复制代码
# JVM参数
-Xms2g -Xmx2g
-XX:MaxDirectMemorySize=256m

线程模型

复制代码
spring:
  cloud:
    gateway:
      httpclient:
        pool:
          worker-group-thread-count: 16  # Worker线程数

8.3 常见问题及解决方案

8.3.1 服务注册失败

问题现象

  • 服务启动后,在Nacos控制台看不到服务实例

  • 日志显示注册失败

排查步骤

  1. 检查网络连通性
复制代码
# 检查Nacos Server是否可达
telnet 127.0.0.1 8848

# 检查防火墙
iptables -L -n
  1. 检查Nacos Server状态
复制代码
# 检查Nacos进程
ps -ef | grep nacos

# 检查Nacos日志
tail -f nacos/logs/nacos.log
  1. 检查服务配置
复制代码
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848  # 确认地址正确
        namespace: public  # 确认命名空间

解决方案

  • 确保Nacos Server正常运行

  • 检查网络连通性和防火墙配置

  • 确认服务配置正确

8.3.2 路由转发失败

问题现象

  • 通过Gateway访问服务返回404或503

  • 日志显示路由匹配失败

排查步骤

  1. 检查路由配置
复制代码
# 查看路由列表
curl http://127.0.0.1:8080/actuator/gateway/routes
  1. 检查服务实例状态
复制代码
# 查看服务实例
curl http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=user-service
  1. 检查日志
复制代码
logging:
  level:
    org.springframework.cloud.gateway: DEBUG

解决方案

  • 检查路由配置是否正确

  • 确保服务实例健康

  • 检查负载均衡配置

8.3.3 性能问题

问题现象

  • Gateway响应慢

  • 服务发现慢

排查步骤

  1. 检查连接池
复制代码
# 查看连接池状态
curl http://127.0.0.1:8080/actuator/metrics/http.client.requests
  1. 检查超时配置
复制代码
spring:
  cloud:
    gateway:
      httpclient:
        connect-timeout: 5000
        response-timeout: 30s
  1. 检查线程状态
复制代码
# 查看线程状态
jstack <pid> | grep -A 20 "gateway"

解决方案

  • 调整连接池大小

  • 优化超时配置

  • 增加线程数

8.4 监控和运维

8.4.1 Nacos监控

控制台监控

  • 服务数:注册的服务数量

  • 实例数:所有服务的实例总数

  • 配置数:配置项数量

  • 连接数:客户端连接数

日志分析

复制代码
# 服务注册日志
tail -f nacos/logs/naming-rt.log
​
# 配置变更日志
tail -f nacos/logs/config-trace.log

告警配置

  • 服务不健康告警

  • 实例下线告警

  • 配置变更告警

8.4.2 Gateway监控

访问日志

复制代码
logging:
  level:
    org.springframework.cloud.gateway: INFO

链路追踪

复制代码
<!-- 集成Sleuth -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
​
<!-- 集成Zipkin -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>

指标监控

复制代码
# 集成Prometheus
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  metrics:
    tags:
      application: ${spring.application.name}

九、总结与展望

9.1 核心要点回顾

让我们回顾一下这篇文章的核心要点:

服务注册发现

  • 解决"服务在哪"的问题

  • 实现服务实例的动态管理

  • 支持健康检查和故障转移

Nacos

  • 一站式服务管理中心

  • 集成服务发现和配置管理

  • 支持AP/CP一致性协议切换

  • 提供丰富的管理功能

API网关

  • 微服务的统一入口

  • 提供路由、安全、监控等功能

  • 简化客户端调用逻辑

Gateway

  • Spring Cloud官方推荐

  • 基于响应式编程,性能优秀

  • 原生支持限流、熔断、WebSocket

  • 与Spring Cloud生态无缝集成

协同工作

  • Nacos + Gateway构建完整的微服务基础设施

  • 动态路由配置,配置热更新

  • 负载均衡,故障转移

9.2 Nacos和Gateway的价值总结

开发效率

  • 简化微服务开发,专注业务逻辑

  • 统一配置管理,减少重复代码

  • 动态路由配置,无需重启服务

运维效率

  • 统一管理,集中监控

  • 配置热更新,快速响应

  • 健康检查,自动故障转移

系统稳定性

  • 负载均衡,避免单点故障

  • 熔断降级,保护后端服务

  • 限流控制,防止恶意攻击

扩展性

  • 支持动态扩缩容

  • 适应业务增长

  • 云原生友好

9.3 微服务架构的未来趋势

云原生

  • Kubernetes + Service Mesh(Istio)

  • 容器化部署,自动扩缩容

  • 声明式配置,GitOps

Serverless

  • 事件驱动,按需计费

  • 无需管理服务器

  • 快速开发,快速部署

低代码

  • 可视化编排,快速开发

  • 减少重复代码

  • 提高开发效率

AI赋能

  • 智能路由,自动优化

  • 异常检测,智能告警

  • 自动扩缩容,资源优化

9.4 学习资源推荐

官方文档

开源项目

社区资源

  • GitHub示例项目

  • 技术博客和视频教程

  • Stack Overflow问答

9.5 结语

Nacos和Gateway是微服务架构中不可或缺的基础设施。它们分别解决了服务发现和API路由的问题,共同构建了完整的微服务通信体系。

通过这篇文章,你应该已经:

  • 理解了服务注册发现和API网关的核心概念

  • 掌握了Nacos和Gateway的配置和使用方法

  • 了解了生产环境的最佳实践和故障排查技巧

  • 获得了完整的实战示例代码

微服务架构的世界博大精深,Nacos和Gateway只是冰山一角。希望这篇文章能为你打开微服务架构的大门,引领你探索更多的可能性。

记住:技术是工具,解决问题才是目的。选择合适的工具,解决实际的问题,才是技术人的价值所在。

祝你在微服务架构的道路上越走越远!


作者 :MrMonkeyHou 日期 :2026年5月29日 版本:1.0

相关推荐
团子的二进制世界1 小时前
Gateway :微服务架构的核心网关
微服务·架构·gateway
RR13351 小时前
Spring MVC and Spring Gateway 的差异,以及报错处理
spring·gateway·mvc
普通网友1 小时前
【python】pyspark.errors.exceptions.base.PySparkRuntimeError [JAVA_GATEWAY_EXITED] Java gateway proce
java·python·gateway
珠***格1 小时前
边缘计算——“云-边-端”协同架构解析
大数据·人工智能·分布式·架构·能源·边缘计算
YJlio1 小时前
OpenClaw v2026.5.26-beta.1 / beta.2 预发布解读:Gateway 加速、transcript 路径统一、多通道修复、语音增强与安装更新链路加固
人工智能·windows·python·ui·缓存·gateway·outlook
普通网友1 小时前
AWS VPC Transit Gateway 部署:实现多 VPC(开发 / 测试 / 生产)间流量集中管控
云计算·gateway·aws
许彰午10 小时前
14_Java泛型完全指南
java·windows·python
智慧物业老杨10 小时前
司法绿色通道下的物业纠纷数智化解决方案——基于“三优先“机制的全流程技术落地实践
java·django
2601_9611940210 小时前
2026初级会计实务公式总结大全|计算题公式手册PDF
java·spring·eclipse·pdf·tomcat·hibernate