01 微服务

一、认识微服务

1.1 微服务架构演变

  1. 单体架构: 将业务的所有功能集中在一个项目中开发,打成一个包部署(简单方便,高度耦合,拓展性差,适合小型项目,如学生管理系统);
  2. 分布式架构: 根据业务功能对系统进行拆分,每个业务模块作为独立项目开发,称为一个服务(松耦合,扩展性好,但架构复杂,难度大,适合大型互连网项目,如京东、淘宝);
  3. 微服务: 是一种经过良好架构设计的分布式 架构方案(优点: 拆分粒度更小,服务更独立,耦合度更低;缺点: 架构非常复杂,运维、监控、部署难度提高);

1.2 微服务技术对比


1.3 微服务结构---SpringCloud


二、服务拆分

2.1 服务拆分

服务拆分注意事项:

  1. 不同微服务,不要重复开发相同业务;
  2. 微服务数据独立,不要方位其他微服务的数据库;
  3. 微服务可以将自己的业务暴露为接口,共其他微服务调用;

2.2 服务间调用



三、Eureka

3.1 概念

定义: Eureka是Netflix开源、基于REST的服务注册与发现组件,是Spring Cloud微服务架构的核服务治理工具,相当于微服务集群里的动态通讯录/服务注册中心
作用: 主要解决微服务拆分后,服务实例动态扩容/缩容、IP/端口变化、故障下线时,服务之间如何自动寻址、避免硬编码地址、保证调用可靠 的问题;
核心两大组件: Eureka Server(服务注册中心)、Eureka Client(客户端、嵌入微服务)

3.2 核心两大组件

  1. Eureka Server(服务注册中心)
  • 作用: 维护服务注册表,存储所有已注册服务的实例信息(服务名、IP、端口、健康状态);
  • 功能: 接受注册、响应查询、心跳检测、自动剔除失效实例、集群数据同步、提供Web管理控制台;
  • 部署: 支持单节点/集群(多Server互相复制注册表,保证高可用);
  1. Eureka Client(客户端、嵌入微服务)
  • 服务提供者: 启动时自动注册 自身信息到 Server;每 30 秒发心跳续约(默认),证明存活,一次业务中,被其他微服务调用的服务(提供接口给其他微服务);
  • 服务消费者: 启动时拉取全量注册表并本地缓存 ,之后每 30 秒增量更新;用服务名(如 user-service) 调用,不用写死 IP / 端口,一次业务中,调用其他微服务的服务(调用其他微服务提供的接口);
  • 内置: 配合 Ribbon 实现客户端负载均衡 (轮询等策略)
    注意: 提供者和消费者角色是相对的;

3.3 核心工作流程

一句话:服务注册--->心跳保活--->服务发现--->失效剔除

  1. 注册: 微服务启动,Client向Server发送注册请求,写入注册表;
  2. 续约: Client每30秒发心跳,Server超过90秒没有收到心跳,标记DOWN并剔除;
  3. 发现: 消费者从Server拉取服务列表,本地缓存,按服务名调用;
  4. 自我保护: 15分钟内心跳丢失>85%,进入保护模式,不剔除任何实例,避免网络抖动误删;

3.4 核心作用

  1. 解耦地址硬编码: 不用在代码/配置里写死IP:端口,用服务名调用,扩容/迁移/重启都不用改配置;
  2. 自动健康检查与容错: 自动剔除宕机实例,避免请求打到无效节点,提供系统稳定性;
  3. 负载均衡与弹性伸缩: 多实例自动加入列表,配合Ribbon做负载均衡,扩容/缩容无感,无需人工干预;
  4. 服务治理可视化: Web控制台查看所有服务、实例状态、心跳,方便运维监控;
  5. 高可用保障: Server集群+客户端缓存,即使部分Server挂了,仍可用本地缓存调用;

3.5 适用场景&现状

  • 适用: Spring Cloud微服务架构(Java生态)、服务数量多、动态扩缩容、需要服务治理的分布式系统;
  • 现状: Netflix已停止维护(进入维护模式),Spring Cloud 2020+ 推荐替代:Nacos、Consul、K8s、Service;

3.6 简单示例(Spring Boot)

Server:@EnableEurekaServer,配置端口、集群节点;
Client(提供者/消费者):@EnableDiscoveryClient,配置服务名、Server地址;
调用:RestTemplate+@LoadBalanced,直接写```http://user-service/getUser\`\`;
搭建eureka服务


服务注册



服务发现

四、Ribbon

4.1 Ribbon是什么

在软件开发领域,尤其是在微服务和Java后端开发中,Ribbon 指的是一个由 Netflix 开源的客户端负载均衡器

4.2 能解决什么问题

在微服务架构中,一个应用(比如订单服务)往往会部署多个实例来应对高并发和保证高可用。当一个调用方(比如用户服务)需要调用订单服务时,它面对的是一个服务实例列表(如 order-service-1:8080, order-service-2:8080),而Ribbon要解决的问题就是:具体选择哪一个实例来发送请求?

这个过程就是负载均衡 。与Nginx这种集中式的服务端负载均衡不同,Ribbon实现的是进程内的客户端负载均衡,即负载均衡的逻辑是跑在调用方(客户端)进程里的。

4.3 如何工作的?

Ribbon 的工作流程大致如下:

  1. 获取服务列表:从服务注册中心(如 Eureka、Nacos)获取目标服务的所有可用实例地址列表。
  2. 执行负载均衡策略:根据预设的算法(如轮询、随机、响应时间权重等),从列表中"聪明地"选中一个服务实例。
  3. 发起请求 :将原本包含服务名的请求(如 http://order-service/getOrder),替换为具体的实例地址(如 http://192.168.1.100:8080/getOrder)并发送。

4.4 在技术栈中的位置

  • 与Spring Cloud的集成 :在Spring Cloud Netflix体系中,Ribbon曾是微服务间调用(RPC)的默认负载均衡组件。即便后来流行的声明式HTTP客户端 OpenFeign,其底层也是依赖Ribbon来实现负载均衡的。
  • 现状 :需要注意的是,Netflix已宣布Ribbon进入维护状态 (不再积极开发新特性)。Spring Cloud社区也推出了自己的负载均衡器 Spring Cloud LoadBalancer 作为替代方案。不过,由于其设计经典且应用广泛,理解和学习Ribbon对掌握负载均衡的核心思想依然很有帮助。

4.5 常用负载均衡策略

Ribbon 提供了几种开箱即用的策略:

策略名称 算法描述 适用场景
轮询 (RoundRobin) 按顺序依次选择服务实例,这是默认策略 服务实例性能相近,请求量均匀的场景。
随机 (Random) 随机选择一个可用的服务实例。 实例性能差异较大,通过随机性来平衡负载。
权重响应时间 (WeightedResponseTime) 根据实例的响应时间动态计算权重,响应越快,被选中的概率越高。 实例性能差异明显,希望自动将流量导向性能更优的机器。
最少并发 (BestAvailable) 优先选择正在处理的请求数最少的实例。 请求处理时间长短不一,需要避免某些实例积压太多请求。
可用性敏感 (AvailabilityFiltering) 会过滤掉那些连接失败或并发数过高的"坏"实例。 需要高可用性,希望自动避开故障或繁忙的节点。

4.6 快速上手示例

在你的Spring Cloud项目中,使用Ribbon非常简单。

首先,确保项目中已经引入了Spring Cloud Netflix Ribbon或Eureka Client的依赖。

然后,在编写RestTemplate的配置时,加上 @LoadBalanced 注解即可:

java 复制代码
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class AppConfig {

    @Bean
    @LoadBalanced // 这个注解是关键,它会让RestTemplate自动使用Ribbon进行负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

之后,你就可以在代码中直接通过服务名来调用接口了,Ribbon会自动将其解析为一个具体的服务实例地址。

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class MyService {

    @Autowired
    private RestTemplate restTemplate;

    public String callOrderService() {
        // 直接使用服务名 'order-service' 进行调用
        String url = "http://order-service/api/order/123";
        // RestTemplate会自动利用Ribbon将服务名替换为真实IP和端口
        return restTemplate.getForObject(url, String.class);
    }
}

4.7 懒加载


五、Nacos

5.1 Nacos是什么

Nacos (读作 /nɑ:kəʊs/)是阿里巴巴开源的一个动态服务发现、配置管理和服务管理平台 。它的名字取自 Na ming(命名)和 Co nfiguration(配置)的前两个字母,末尾的 s 代表 Service(服务)[citation:1]。

简单来说,Nacos 在微服务架构中扮演着两个核心角色:

  1. 服务注册中心:让服务能够找到彼此
  2. 配置中心:集中管理所有服务的配置

5.1.1 解决什么问题

在微服务架构中,一个系统往往被拆分成几十甚至上百个独立运行的服务。这些服务需要解决两个核心问题:

问题场景 Nacos 的解决方案
服务发现问题:订单服务如何知道用户服务的具体 IP 和端口? 服务注册与发现:服务启动时自动注册到 Nacos,调用方从 Nacos 获取服务实例列表 [citation:7][citation:9]
配置管理问题:修改数据库密码后,如何不重启上百个服务? 动态配置管理:配置集中存储在 Nacos,变更实时推送到所有服务,无需重启 [citation:1][citation:2]

5.1.2 核心功能详解

  • 服务注册:微服务启动时,将自己的 IP、端口等信息注册到 Nacos
  • 服务发现:服务消费者从 Nacos 获取目标服务的实例列表
  • 健康检查:Nacos 通过心跳机制(默认 5 秒一次)检测服务实例健康状态,自动剔除不健康的实例 [citation:7][citation:9]

服务注册流程:

  1. 服务提供者启动 → 向 Nacos 发送注册请求
  2. Nacos 记录服务实例信息(IP、端口、服务名)
  3. 服务消费者订阅服务 → 获取实例列表
  4. 服务提供者定期发送心跳(5秒/次)维持注册
  5. 15秒未收到心跳 → 标记为不健康;30秒未收到 → 剔除实例

5.1.3 动态配置管理

  • 集中化管理:将所有环境的配置(开发、测试、生产)统一存储在 Nacos
  • 实时推送:配置变更后,Nacos 毫秒级推送到所有客户端
  • 版本管理:支持配置的历史版本管理和一键回滚 [citation:2][citation:10]
yaml 复制代码
# 配置示例
Data ID: userservice-dev.yaml
Group: DEFAULT_GROUP
内容:
  database:
    url: jdbc:mysql://localhost:3306/userdb
    username: root
  app:
    name: user-service
    version: 2.0

5.2 服务管理

元数据管理: 为服务实例添加自定义标签(如版本号、环境信息)
流量管理: 支持基于权重的流量分配(例如:v1 版本 90% 流量,v2 版本 10% 流量)
多环境隔离: 通过命名空间(Namespace)实现开发、测试、生产环境的配置和服务隔离

5.2.1 与Spring Cloud集中

Nacos 是 Spring Cloud Alibaba 的核心组件,可以无缝替换 Eureka 和 Spring Cloud Config

  1. 添加依赖
xml 复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
  1. 配置文件(bootstrap.yml)
yaml 复制代码
spring:
  application:
    name: user-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848   # 注册中心地址
      config:
        server-addr: localhost:8848   # 配置中心地址
        file-extension: yaml          # 配置文件格式
  1. 启用服务发现
java 复制代码
@SpringBootApplication
@EnableDiscoveryClient   // 启用服务发现
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}
  1. 动态配置使用
java 复制代码
@RestController
@RefreshScope   // 支持配置动态刷新
public class ConfigController {
    
    @Value("${app.name:default}")
    private String appName;
    
    @GetMapping("/config")
    public String getConfig() {
        return "app.name = " + appName;
    }
}

与Eureka比较

对比项 Nacos Eureka
心跳间隔 5 秒 30 秒
服务剔除 15 秒超时,30 秒剔除 90 秒未收到心跳剔除
配置中心 ✅ 内置支持 ❌ 不支持
配置推送 服务变更时主动推送 客户端定时拉取(30 秒)
一致性模式 支持 AP/CP 模式切换 仅 AP 模式(高可用)
控制台 功能丰富的 Web 控制台 基础功能
维护状态 活跃开发中 已停止维护

部署模式

模式 适用场景 特点
单机模式 开发、测试环境 快速启动,使用内置 Derby 数据库
集群模式 生产环境 高可用,至少 3 个节点,外接 MySQL 持久化
相关推荐
http阿拉丁神猫2 小时前
kubernetes知识点汇总43-47
云原生·容器·kubernetes
黑金IT2 小时前
AI Agent “小龙虾终极进化”——自主学习与持久化记忆的架构实现
人工智能·学习·架构
无忧智库2 小时前
深度解码:烟草行业数字化转型顶层设计与全场景落地实践(PPT)
安全·架构
ak啊2 小时前
多智能体协同模式:五种核心架构详解
架构
IT枫斗者3 小时前
构建具有执行功能的 AI Agent:基于工作记忆的任务规划与元认知监控架构
android·前端·vue.js·spring boot·后端·架构
迷藏4943 小时前
**发散创新:基于角色与属性的混合权限模型在微服务架构中的实战落地**在现代分布式系统中,
java·python·微服务·云原生·架构
张3233 小时前
Kubernetes服务发现
云原生·kubernetes
WindrunnerMax3 小时前
从零实现富文本编辑器#13-React非编辑节点的内容渲染
前端·架构·github
立莹Sir3 小时前
云原生实战:从零搭建企业级K8s环境
云原生·容器·kubernetes