Nacos 负载均衡
基于Ribbon
- 轮询
- 随机
- 可用过滤:先过滤由于多次访问故障处于熔断的服务,以及并发连接数超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问。
- 加权响应时间:根据每个服务实例的平均响应时间计算权重,响应时间越快权重越高,被选中的几率越大。刚开始使用RoundRobin轮询策略,等待足够数据后切换到基于权重的选择
- 重试
- 最佳可用:选择除故障实例外的请求数量最少的实例
- 区域规避:复合判断server所属区域的性能和server的可用性选择服务器
基于Spring Cloud LoadBalancer
随着Spring Cloud 发展,官方推荐使用Spring Cloud LoadBalancer 替代 Ribbon。
- 轮询
- 随机
- 加权(基于服务实例的权重选择)
- LRT(最小响应时间)
自定义负载均衡策略
无论使用哪种接口提供的负载均衡方法,你都可以实现自己的负载均衡逻辑。通常需要创建一个新的类继承自相应地抽象类,覆盖其方法定义具体的负载均衡行为。之后在应用中注册该自定义的策略即可。
your-service-name:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
Nacos yml 重要配置
| 配置项 | 描述 | 默认值 |
|---|---|---|
| spring.application.name | 应用名称,用于服务注册与发现 | 无(必须指定) |
| spring.cloud.nacos.discovery.server-addr | Nacos服务器地址,格式为IP:PORT | 无(必须指定) |
| spring.cloud.nacos.discovery.namespace | 命名空间ID,用于隔离不同的环境 | public |
| spring.cloud.nacos.discovery.group | 分组名称,同一命名空间下区分不同的服务分组 | DEFAULT_GROUP |
| spring.cloud.nacos.discovery.cluster-name | 集群名称,标识服务实例所属集群 | DEFAULT |
| spring.cloud.nacos.discovery.ip | 当前服务实例的IP地址 | 自动获取 |
| spring.cloud.nacos.discovery.port | 当前服务实例的端口 | 自动获取 |
| spring.cloud.nacos.discovery.ephemeral | 是否是临时实例(影响心跳机制),true为临时实例,false为持久化实例 | true |
| spring.cloud.nacos.config.server-addr | Nacos Config服务器地址,用于动态配置管理 | 同discovery.server-addr |
| spring.cloud.nacos.config.file-extension | 配置文件格式,支持properties, yaml等 | properties |
| spring.cloud.nacos.config.shared-configs[0].dataId | 共享配置的数据ID,可以有多个 | 无 |
| spring.cloud.nacos.config.refresh-enabled | 是否开启自动刷新配置 | true |
| spring.cloud.nacos.config.timeout | 获取配置时超时时间(毫秒) | 3000 |
Nacos 多节点数据不一致时的数据恢复机制
当多个Nacos节点出现数据不一致的情况时,Nacos通过其内部机制来尝试恢复并保持数据的一致性。下面分别介绍服务发现模块和配置管理模块是如何处理这种情况的。
服务发现模块(Distro协议)
Distro协议概述
对于服务发现模块,Nacos采用了一种名为Distro的最终一致性协议。该协议允许在集群中的每个节点上都维护一份全量的服务注册信息副本。
健康检查与数据同步
- 健康检查:如果检测到某个节点的数据与其他节点不一致,Nacos会执行健康检查流程。
- 数据同步:一旦确定某个节点是健康的,它将作为数据源,向不健康的节点推送最新的服务注册信息。
心跳机制
- 每个节点都会定期发送心跳给其他节点,以此确认它们的存活状态和数据版本。
- 如果某个节点未能按时收到另一个节点的心跳,则认为该节点可能存在问题,并启动相应的数据同步或恢复过程。
配置管理模块(Raft协议)
Raft算法概述
对于配置管理模块,Nacos采用了Raft共识算法来保证强一致性。Raft算法通过选举领导节点(Leader)来协调所有写操作。
日志复制
- Leader会将所有的写操作记录为日志条目,并将这些日志条目复制给所有的Follower。
- 一旦大多数节点确认收到了新的日志条目,Leader就会提交这条日志,然后通知客户端操作成功完成。
异常处理
- 如果Leader发生故障或者网络问题导致部分节点无法与Leader通信,Raft算法会触发一个新的领导者选举过程。
- 新Leader当选后,它将根据自身的日志情况与其他节点同步数据,确保整个集群的数据一致性。
数据恢复策略
自动同步
无论是使用Distro还是Raft协议,一旦检测到数据不一致,Nacos都会尝试从健康的节点获取最新数据,并自动同步到受影响的节点上。
手动干预
在某些极端情况下,可能需要管理员手动干预来进行数据修复。例如,如果存在严重的数据冲突且无法自动解决,可以考虑通过备份恢复或者直接修改数据库来纠正问题。
以下是对 Nacos 配置管理 和 OpenFeign 相关内容的详细说明,以 Markdown 格式整理,涵盖配置方法、共享配置、热更新、动态路由,以及 Feign 的连接池、日志、超时和重试配置:
Nacos 配置管理
怎么配置
1. 基础配置
步骤:
- 启动 Nacos 服务:确保 Nacos 服务器已运行。
- 添加依赖(Spring Boot 项目):
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> - 配置
application.yml:spring: application: name: your-service-name # 服务名称,用于 Nacos 配置匹配 cloud: nacos: config: server-addr: 127.0.0.1:8848 # Nacos 服务器地址 group: DEFAULT_GROUP # 配置分组 extension: yaml # 配置文件格式(支持 properties/yaml)
共享配置
2. 共享配置
实现方式:
- 定义共享配置文件:在 Nacos 控制台创建一个配置文件(如
common-config.yaml),内容如下:shared-config: key1: value1 key2: value2 - 在服务中引用共享配置:
- 通过
@NacosProperty注入:@NacosProperty(name = "shared-config.key1", autoRefreshed = true) private String sharedValue; - 通过
@Value注入:@Value("${shared-config.key1}") private String sharedValue;
- 通过
配置热更新
3. 配置热更新
实现步骤:
- 启用自动刷新:
spring.cloud.nacos.config.refresh-enabled: true - 使用
@RefreshScope注解:@RefreshScope @Component public class ConfigBean { @Value("${shared-config.key1}") private String configValue; // 通过 REST API 触发刷新(如访问 `/actuator/refresh`) } - 监听配置变化(可选):
@NacosConfigurationListener( dataId = "common-config.yaml", group = "DEFAULT_GROUP" ) public class ConfigListener implements ConfigurationListener { @Override public void receive(ConfigChangeEvent event) { // 处理配置变更 } }
动态路由
4. 动态路由
实现方式(结合 Nacos 服务发现):
- 通过服务权重动态调整路由:
# 在 Nacos 控制台修改服务实例的权重(如将某个实例的权重设为 0 以隔离) - 结合 Sentinel 或 Spring Cloud Gateway:
// 示例:通过 Sentinel 的动态规则实现流量控制 @Bean public SentinelGatewayFilterFactory sentinelGatewayFilterFactory() { return new SentinelGatewayFilterFactory(); }
OpenFeign
连接池
1. 连接池配置
HTTP 客户端配置(如使用 HttpClient):
# application.yml
feign:
client:
config:
default:
client:
config:
your-service: # 目标服务名称
connectTimeout: 5000 # 连接超时(毫秒)
readTimeout: 10000 # 读取超时(毫秒)
maxTotalConnection: 200 # 连接池最大连接数
maxConnectionsPerRoute: 50 # 每个路由的最大连接数
日志配置
2. 日志配置
调整 Feign 日志级别:
logging:
level:
com.example.yourpackage: DEBUG # 包名路径
feign: DEBUG # 全局 Feign 日志
针对单个接口的配置:
@FeignClient(
name = "your-service",
configuration = FeignLoggerConfig.class
)
public interface YourServiceClient {
// 接口定义
}
// 配置类
@Configuration
public class FeignLoggerConfig {
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL; // 输出请求/响应的详细日志
}
}
超时配置
3. 超时配置
全局超时配置:
feign:
client:
config:
default:
connectTimeout: 5000 # 连接超时(毫秒)
readTimeout: 10000 # 读取超时(毫秒)
针对单个接口的配置:
@FeignClient(
name = "your-service",
configuration = FeignTimeoutConfig.class
)
public interface YourServiceClient {
// 接口定义
}
// 配置类
@Configuration
public class FeignTimeoutConfig {
@Bean
public Request.Options feignOptions() {
return new Request.Options(5000, 10000); // connectTimeout, readTimeout
}
}
重试配置
4. 重试配置
使用 Hystrix 或 Resilience4j:
# 使用 Hystrix(需引入依赖)
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
circuitbreaker:
errorThresholdPercentage: 50
requestVolumeThreshold: 20
sleepWindowInMilliseconds: 5000
retry:
max: 3 # 最大重试次数
使用 Spring Retry:
@FeignClient(name = "your-service")
public interface YourServiceClient {
@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000))
@GetMapping("/api/data")
ResponseEntity<String> getData();
}
2190

被折叠的 条评论
为什么被折叠?



