微服务入门指南(二):负载均衡与Nacos注册中心深度解析
上一篇用 Eureka 实现了服务注册与发现,但还有两个关键问题没解决:
多个服务实例(比如 2 个userservice),怎么让请求 “均匀” 地分给它们?
Eureka 功能太简单,有没有更强大的注册中心?
这篇就用 Ribbon 解决负载均衡,用 Nacos 替代 Eureka(功能更全、国内更常用),手把手实战!
一、Ribbon:让请求 “雨露均沾” 的负载均衡
比如我们部署了 2 个user-service(端口 8081、8082),订单服务调用时,怎么避免只打给一个实例? 这就是 Ribbon 的活儿 ——负载均衡,让请求均匀分配给多个实例。

1. 为什么加个 @LoadBalanced 就有用?原理揭秘
上一篇在RestTemplate上加了@LoadBalanced注解,就能自动替换http://userservice为真实 IP(比如 8081),背后是 Ribbon 在搞事情,流程如下:

- 拦截请求:Ribbon 的拦截器拦住
RestTemplate发的http://userservice/user/1; - 查服务列表:根据
userservice这个服务名,去 Nacos/Eureka 拉取实例列表(8081、8082); - 选实例:用负载均衡算法(默认是 “轮询”)从列表里挑一个(比如 8081);
- 改地址:把
userservice换成8081,变成http://localhost:8081/user/1,发起真实请求。
2. Ribbon 的 5 种负载均衡策略(小白记 3 个常用的)

Ribbon 有多种 “选实例” 的算法,默认是轮询(轮流选),其他策略按需选:
| 策略类 | 核心逻辑 | 适合场景 |
|---|---|---|
| RoundRobinRule | 轮询(默认):依次选实例 | 实例性能差不多的情况 |
| RandomRule | 随机选实例 | 想均匀分散压力 |
| WeightedResponseTimeRule | 权重选:响应快的实例权重高,被选概率大 | 实例性能不一样(比如高配机器权重高) |
| ZoneAvoidanceRule | 基于区域和可用性选择 | 多机房部署 |
| AvailabilityFilteringRule | 过滤故障实例 + 高并发实例,选健康的 | 追求稳定性 |
3. 怎么修改负载均衡策略?(2 种方式)
方式 1:代码方式(对所有服务生效)
在订单服务的启动类里,定义一个IRule Bean,指定策略:
import com.netflix.loadbalancer.RandomRule;
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 RibbonConfig {
// 注册RestTemplate,加@LoadBalanced开启负载均衡
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
// 配置负载均衡策略为“随机”
@Bean
public IRule randomRule() {
return new RandomRule();
}
}
方式 2:配置文件方式(对指定服务生效,推荐)
只想让订单服务调用userservice时用随机策略,其他服务不变,在订单服务的application.yml里加:
# 对userservice这个服务生效
userservice:
ribbon:
# 指定策略类的全路径(随机策略)
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
4. 优化:开启 Ribbon 饥饿加载
Ribbon 默认是 “懒加载”—— 第一次调用服务时才创建客户端,导致第一次请求变慢。
饥饿加载:项目启动时就创建客户端,解决第一次慢的问题,配置如下(订单服务application.yml):
ribbon:
eager-load:
enabled: true # 开启饥饿加载
clients: userservice # 对userservice服务饥饿加载(多个服务用逗号分隔)
二、Nacos:替代 Eureka 的 “全能注册中心”
Nacos 是阿里巴巴开源的注册中心,比 Eureka 功能强太多:支持服务注册、配置管理、权重调整、环境隔离,国内互联网公司几乎都在用。
Nacos vs Eureka 对比
| 特性 | Nacos | Eureka |
|---|---|---|
| 服务发现 | ✅ | ✅ |
| 配置管理 | ✅ | ❌ |
| 主动健康检查 | ✅ | ❌ |
| 权重管理 | ✅ | ❌ |
| 环境隔离 | ✅ | ❌ |
| AP/CP模式 | 支持切换 | 仅AP |
1. 第一步:安装 Nacos(Windows 版,3 步搞定)
- 下载:去Nacos 官网下载压缩包(选nacos-server-xxx.zip);
- 解压:解压后进入bin目录;
- 启动:打开 cmd,执行命令(单机模式):
startup.cmd -m standalone
访问:浏览器打开http://localhost:8848/nacos,默认账号密码都是nacos,登录成功就 OK!
2. 第二步:把服务注册到 Nacos(替代 Eureka)
以userservice和orderservice为例,步骤比 Eureka 还简单:
(1)加依赖(父工程 + 子工程)
父工程:在dependencyManagement里加 SpringCloud Alibaba 依赖(管理版本):
<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>
子工程(userservice/orderservice):加 Nacos 客户端依赖(替换原来的 Eureka 依赖):
<!-- Nacos客户端依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
(2)改配置(application.yml)
删除原来的 Eureka 配置,加 Nacos 地址:
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848 # Nacos地址
application:
name: userservice # 服务名(和之前一致)
(3)启动服务,验证
启动userservice(可以启动 2 个实例,改端口 8081、8082)和orderservice,登录 Nacos 控制台,在 “服务列表” 里能看到userservice和orderservice,注册成功!
3. Nacos 进阶 1:服务分级存储(集群部署)
实际项目中,服务会部署在不同机房(比如杭州、上海),Nacos 支持 “服务 - 集群 - 实例” 三级存储,让请求优先调用本地机房的实例(延迟低)。
(1)给服务配置集群
比如给userservice配置 “杭州集群(HZ)”,在application.yml里加:
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
cluster-name: SH # 集群名称(上海)
再启动一个userservice,配置cluster-name: WH(武汉),Nacos 里就能看到两个集群。

(2)优先调用本地集群实例
默认策略还是轮询,会跨集群调用,需要改策略为 Nacos 专属的NacosRule,在orderservice的application.yml里加:
userservice:
ribbon:
# NacosRule策略:优先本地集群,本地没有才跨集群
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
4. Nacos 进阶 2:权重负载均衡(让强机器多干活)
如果实例性能不一样(比如 8081 是高配机器,8082 是低配),可以给 8081 设更高权重,让它承担更多请求。
操作步骤:
- 登录 Nacos 控制台,进入userservice的 “实例列表”;
- 找到 8081 实例,点 “编辑”,把 “权重” 改成 2(默认 1),8082 权重保持 1;
- 测试:订单服务调用userservice,8081 被调用的概率是 8082 的 2 倍(权重越高,被选概率越大)。
小技巧:权重设为 0,实例不会被调用(用于下线实例时不影响服务)。
4. Nacos 进阶 3:环境隔离(namespace)
开发、测试、生产环境要分开,避免互相影响,Nacos 用namespace实现隔离。
(1)创建 namespace
Nacos 控制台→“命名空间”→“新建命名空间”;
输入 “名称”(比如dev),“描述”(开发环境),点 “确定”,会生成一个唯一的namespace ID。


(2)服务指定 namespace
在userservice的application.yml里加namespace配置(用刚才生成的 ID):
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: 5f666666-xxxx-xxxx-xxxx-666666666666 # 你的namespace ID
这样userservice就只在dev环境可见,其他环境看不到。
6. Nacos vs Eureka(小白记 3 个关键区别)
临时实例和非临时实例
服务注册到Nacos时,可以选择注册为临时或非临时实例,通过下面的配置来设置:
spring:
cloud:
nacos :
discovery:
ephemeral: false #设置为非临时实例

| 对比点 | Nacos | Eureka |
|---|---|---|
| 功能 | 服务注册 + 配置管理 + 权重 + 隔离 | 只有服务注册 |
| 健康检测 | 临时实例(心跳)+ 非临时实例(主动检测) | 只有心跳 |
| 服务更新 | 推送模式(实时更新) | 拉取模式(有延迟) |
三、Nacos 配置管理:不用重启服务改配置
原来的配置写在application.yml里,改配置要重启服务,Nacos 配置管理能实现 “热更新”(改配置不用重启)。
1. 实战:把配置交给 Nacos 管理
以userservice为例,让它从 Nacos 读取 “日期格式” 配置:
(1)加依赖(userservice)
<!-- Nacos配置管理依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
(2)创建 bootstrap.yml(引导文件,优先级高于 application.yml)
spring:
application:
name: userservice # 服务名
profiles:
active: dev # 环境(dev开发)
cloud:
nacos:
config:
server-addr: localhost:8848 # Nacos地址
file-extension: yaml # 配置文件格式(yaml)
Nacos 会根据这 3 个信息找配置文件:userservice-dev.yaml(服务名 - 环境。格式)。
(3)Nacos 控制台创建配置文件
进入 Nacos→“配置管理”→“配置列表”→“新建配置”;

填写:
- 数据 ID:userservice-dev.yaml(和 bootstrap.yml 对应);
- 配置格式:YAML;
- 配置内容:
pattern:
dateformat: yyyy-MM-dd HH:mm:ss # 日期格式配置
点 “发布”。
多环境配置共享
- [服务名].yaml:共享配置(所有环境)
- [服务名]-[环境].yaml:环境特定配置
优先级:环境配置 > 共享配置 > 本地配置
(4)在代码中读取配置
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RefreshScope // 关键:开启配置热更新
public class TestController {
// 读取Nacos中的配置
@Value("${pattern.dateformat}")
private String dateformat;
@GetMapping("/test/date")
public String testDate() {
return "当前时间:" + new java.text.SimpleDateFormat(dateformat).format(new java.util.Date());
}
}
2. 配置热更新:改配置不用重启
在 Nacos 控制台修改userservice-dev.yaml的dateformat为yyyy年MM月dd日 HH:mm:ss;
直接访问http://localhost:8081/test/date,会发现时间格式已经变了 —— 不用重启服务!
关键:加@RefreshScope注解,或者用@ConfigurationProperties绑定配置(适合多配置项)。
四、Nacos 集群搭建(简化版,了解即可)

生产环境要部署 Nacos 集群(避免单点故障),核心步骤:
- MySQL 集群:Nacos 数据存在 MySQL,先搭 MySQL 主从;
- 改 Nacos 配置:每个 Nacos 节点改
conf/cluster.conf(填所有节点 IP: 端口),改application.properties(填 MySQL 地址); - 启动多个 Nacos 节点:分别改server.port(比如 8848、8849、8850),启动;
Nginx 反向代理:用 Nginx 把请求转发到多个 Nacos 节点,配置示例:
nginx
upstream nacos-cluster {
server 127.0.0.1:8848;
server 127.0.0.1:8849;
server 127.0.0.1:8850;
}
server {
listen 80;
server_name localhost;
location /nacos/ {
proxy_pass http://nacos-cluster/nacos/;
}
}
总结:这篇你要记住的 3 个核心
- Ribbon:解决负载均衡,默认轮询,可改策略(代码 / 配置),开启饥饿加载优化首次请求;
- Nacos:替代 Eureka,支持服务注册、集群分级、权重调整、环境隔离,功能更全;
- Nacos 配置管理:实现配置热更新,不用重启服务,核心是
bootstrap.yml和@RefreshScope。
更多推荐


所有评论(0)