第1章:微服务核心组件全景概览

说实话,我刚接触微服务那会儿,最头疼的就是这些组件怎么搭在一起。你想想看,一个系统拆成几十个服务,每个服务都有自己的地址、端口、配置,光靠人工记?那简直是噩梦。

这一章,我带你把服务注册与发现、配置中心、API网关这三个核心组件理清楚。它们就像微服务的骨架,缺一个都跑不起来。

1.1 服务注册与发现:Nacos vs Eureka

服务注册与发现,说白了就是让服务之间能找到彼此。我习惯把它比作「电话本」——每个服务启动时,先把自己的地址写到电话本里;要调用别人时,翻翻电话本就行了。

1.1.1 为什么需要它?

没有服务发现的时候,我们怎么做?硬编码IP地址。我在项目中遇到过,某个服务迁移服务器,结果所有调用方都得改配置、重启。那叫一个痛苦。

有了服务发现,这些问题就简单了:

  • 服务启动时自动注册
  • 服务下线时自动摘除
  • 调用方只需知道服务名,不用关心具体IP

1.1.2 Nacos vs Eureka 怎么选?

特性 Nacos Eureka
CAP理论 AP+CP 可切换 AP
健康检查 支持TCP/HTTP/MySQL 仅心跳
配置中心 内置 需集成Spring Cloud Config
控制台 功能丰富 较简单
社区活跃度 阿里主导,更新快 Netflix已停止维护

我个人习惯用Nacos。原因很简单:它把注册中心和配置中心合二为一了。你想想看,少维护一个组件,运维成本直接减半。

避坑指南:我曾经在生产环境遇到过Eureka的自我保护机制导致服务下线不彻底。某个节点挂了,但Eureka Server还保留着它的注册信息,结果调用方一直往死节点发请求。Nacos在这方面做得更好,支持主动健康检查。

1.1.3 快速集成示例

用Spring Cloud Alibaba集成Nacos,其实就三步:

// 1. 添加依赖
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

// 2. 配置application.yml
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: dev

// 3. 启动类加注解
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

嗯,这里要注意:namespace是用来隔离环境的。我习惯把dev、test、prod分别建不同的namespace,这样配置和注册信息就不会串了。

1.2 配置中心:Apollo vs Nacos

配置中心解决的是「改配置不用重启」的问题。我记得以前改个数据库连接池大小,得发版、重启、验证,折腾半小时。现在?改完配置,几秒钟就生效了。

1.2.1 核心能力对比

能力 Apollo Nacos Config
配置实时推送 长轮询+通知 长轮询
配置灰度 支持 需自研
权限管理 完善 基础
配置回滚 一键回滚 支持
多环境管理 原生支持 通过namespace

如果你问我怎么选?我的建议是:

  • 中小团队、新项目 → Nacos Config(轻量,和注册中心共用)
  • 大型项目、需要精细权限控制 → Apollo(功能更强大)

个人经验:我在一个金融项目中用过Apollo,它的配置灰度发布功能帮了大忙。先让10%的流量验证新配置,没问题再全量推送。万一出问题,一键回滚,影响范围可控。

1.2.2 配置热更新示例

// 使用Nacos Config实现配置热更新
@RefreshScope
@Component
public class DynamicConfig {
    
    @Value("${order.timeout:5000}")
    private int orderTimeout;
    
    // 这个值会随配置中心变化而自动更新
    public int getOrderTimeout() {
        return orderTimeout;
    }
}

// 或者用更推荐的方式:监听配置变化
@Configuration
public class NacosConfigListener {
    
    @NacosConfigListener(dataId = "order-service.yml", groupId = "DEFAULT_GROUP")
    public void onConfigChange(String config) {
        // 配置变化时,重新加载
        System.out.println("配置已更新:" + config);
    }
}

说白了,配置中心的核心价值就两个:不改代码改配置、不改配置不重启。能做到这两点,运维效率至少提升50%。

1.3 API网关:Gateway vs Kong

API网关是微服务的「大门」。所有外部请求都先经过它,由它决定请求该去哪个服务。我习惯把网关看作「交通警察」——它负责路由、限流、鉴权、日志等横切关注点。

1.3.1 两种技术路线

维度 Spring Cloud Gateway Kong
语言 Java(Reactive) Lua/OpenResty
性能 中等 高(基于Nginx)
扩展性 Java代码扩展 插件机制
学习成本 低(Spring生态)
适用场景 Java技术栈团队 高性能、多语言

我个人习惯:如果团队全是Java,用Spring Cloud Gateway就够了。如果团队技术栈杂,或者对性能要求极高,Kong是更好的选择。

1.3.2 路由配置实战

// Spring Cloud Gateway 路由配置
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
        // 用户服务路由
        .route("user-service", r -> r
            .path("/api/user/**")
            .filters(f -> f
                .stripPrefix(1)  // 去掉/api前缀
                .addRequestHeader("X-Gateway", "true")
                .circuitBreaker(config -> config
                    .setName("userCB")
                    .setFallbackUri("forward:/fallback/user")))
            .uri("lb://user-service"))
        // 订单服务路由
        .route("order-service", r -> r
            .path("/api/order/**")
            .filters(f -> f
                .stripPrefix(1)
                .requestRateLimiter(config -> config
                    .setRateLimiter(redisRateLimiter())))
            .uri("lb://order-service"))
        .build();
}

注意:我曾经在生产环境踩过一个坑——网关的超时时间设置得太短。某个服务偶尔响应慢,网关直接返回504。后来我把全局超时从2秒调到5秒,再配合熔断降级,问题就解决了。记住:超时和熔断要配合使用,不是越短越好。

1.4 三个组件如何协同工作?

你想想看,这三个组件其实是一条链:

  1. 服务启动 → 向Nacos注册自己,从Nacos拉配置
  2. 外部请求 → 先到Gateway,Gateway从Nacos发现目标服务地址
  3. 服务间调用 → 通过Nacos发现对方地址,使用从配置中心获取的配置

说白了,Nacos是「大脑」,存着所有服务的地址和配置;Gateway是「门卫」,负责接待和分流。两者配合,微服务才能跑得稳。

核心要点总结:

  • 服务注册与发现:解决「服务在哪」的问题
  • 配置中心:解决「配置怎么管」的问题
  • API网关:解决「请求怎么走」的问题
  • 三者缺一不可,共同构成微服务的基础设施

好了,这一章我们理清了三个核心组件的定位和选型。下一章,我会带你动手搭建一个完整的Nacos集群,从单机到生产级部署,一步步来。