# nacos-load-balancing
**Repository Path**: gxq123__--456/nacos-load-balancing
## Basic Information
- **Project Name**: nacos-load-balancing
- **Description**: Nacos 自定义负载均衡,优先使用同IP服务(本地服务优先调用)
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-07-04
- **Last Updated**: 2025-11-15
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Nacos 自定义负载均衡,优先使用同IP服务(本地服务优先调用)
前言:在微服务开发过程中,随着服务的数量越来越多,不可能将所有的服务都在本地启动调试。最好的方式就是需要调试哪个服务就启动哪个服务,所有的服务都使用 nacos ,那这样每位开发人员都需要到本地搭建 nacos,为了方便我们可以用一台开发机,所有开发人员的服务都注册到这个机器上,这样就会引出以下问题。
问题:nacos 的负载均衡默认策略是轮询,在多人同时将服务注册到一台服务器上时会导致服务轮流调用,无法每次都命中本地服务,为了解决这个问题实现每个人每次调用都只命中自己本地的服务现有两种解决方案
## 方案一、使用 nacos 不同集群
通过每人一份配置文件中配置属于自己的集群,在调试代码时 nacos 会有限使用相同集群中的服务,但是会有多份配置文件
```yaml
spring:
cloud:
loadbalancer.nacos.enabled: true
nacos:
discovery:
server-addr: 127.0.0.1:8848
group: dev
# 指定集群的名称,每个人都有自己一份
cluster-name: local
```
## 方案二、自定义 nacos 负载均衡机制
**1、自定义 nacos 负载均衡器**
```java
/**
* TODO 详细代码在类:NacosLocalFirstLoadBalancer
*
* 自定义 nacos 服务加载机制,优先使用与本地同 IP 的服务。
* 本地找不到则使用同集群,然后再使用其它集群服务,以下代码大部分来源于 com.alibaba.cloud.nacos.loadbalancer.NacosLoadBalancer 添加了本地优先过滤规则
*/
```
**2、注册自定义负载均衡器到LoadBalancerClients中**
```java
/**
* TODO 详细代码在类:NacosLocalFirstLoadBalancerClientConfiguration
*/
```
**3、添加自动发现类**
```java
/**
* TODO 详细代码在类:LocalFirstLoadBalancerNacosAutoConfiguration
*/
```
**4、将上述代码封装为组件的情况下**
1. 在根目录的 pom.xml 中统一管理该组件
```xml
com.quanxiaoha
xiaoha-common
${revision}
```
2. 在服务中引入该组件
```xml
com.quanxiaoha
xiaoha-common
```
3. 在 resource 目录下创建自动装配文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
```yaml
# 值为组件中的 LocalFirstLoadBalancerNacosAutoConfiguration 的包路径加类名
com.quanxiaoha.framework.common.nacos.LocalFirstLoadBalancerNacosAutoConfiguration
```
4. 在配置文件中添加启用本地优先配置
```yaml
spring:
cloud:
# 负载均衡配置
loadbalancer:
# 自定义属性(需要元数据定义)
local-first: true # 启用本地优先策略
# 新版本正确配置方式
enabled: true # 启用Spring Cloud LoadBalancer(替代Ribbon)
ribbon:
enabled: false # 明确禁用Ribbon(如果存在)
# 强制使用新的Reactive实现
reactor:
enabled: true
```
5. 在 resource 目录下创建元数据文件 META-INF/additional-spring-configuration-metadata.json
```json
{
"properties": [
{
"name": "spring.cloud.loadbalancer.local-first",
"type": "java.lang.Boolean",
"defaultValue": false,
"description": "Whether to enable local-first load balancing strategy."
},
{
"name": "spring.cloud.loadbalancer.ribbon.enabled",
"type": "java.lang.Boolean",
"deprecation": {
"level": "warning",
"reason": "Ribbon has been deprecated in favor of Spring Cloud LoadBalancer",
"replacement": "spring.cloud.loadbalancer.enabled"
}
}
]
}
```
6. 在启动类上添加扫包注解
```java
/**
* 第一个包为组件核心代码所在的包路径,第二个包为启动类所在的包路径
*/
@SpringBootApplication
@ComponentScan(basePackages = {"com.quanxiaoha.framework.common.nacos", "com.quanxiaoha"})
public class XiaohashuAuthApplication {
public static void main(String[] args) {
SpringApplication.run(XiaohashuAuthApplication.class, args);
}
}
```
7. 本地测试
```java
package com.quanxiaoha.xiaohashu.auth.controller;
import jakarta.annotation.Resource;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
* @className: LoadBalancerTestController
* @author: gxq
* @date: 2025/7/2 下午6:35
* @Version: 1.0
* @description: 多次调用以下接口查看返回的ip是否都是本机ip
*/
@RestController
public class LoadBalancerTestController {
@Resource
private LoadBalancerClient loadBalancerClient;
@GetMapping("/test-lb/{serviceName}")
public String testLb(@PathVariable String serviceName) {
ServiceInstance instance = loadBalancerClient.choose(serviceName);
return "Chosen instance: " + instance.getHost() + ":" + instance.getPort();
}
}
```
8. 服务器测试
前置条件: 1.nacos环境, 2.Java17环境
```text
-------------------------Linux安装JDK17环境,不影响本身的JDK8-------------------------------
1.下载JDK17,华为云下载地址:https://mirrors.huaweicloud.com/openjdk/17.0.2/
2.选择 openjdk-17.0.2_linux-x64_bin.tar.gz 版本
3.解压文件:tar xzvf openjdk-17.0.2_linux-x64_bin.tar.gz
4.配置环境:vi /etc/profile,在原有的jdk8的配置下面,配置jdk17
===============配置内容===================
#java environment
export JAVA_HOME=/opt/jdk/jdk1.8.0_172
export CLASSPATH=.:${JAVA_HOME}/jre/lib/rt.jar:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar
export PATH=$PATH:${JAVA_HOME}/bin
#java17 environment
export JAVA17_HOME=/opt/jdk/jdk-17.0.13
export CLASSPATH=.:$JAVA17_HOME/bin/
export PATH=.:$JAVA17_HOME/bin:$PATH
alias java=${JAVA_HOME}/bin/java
alias java17=$JAVA17_HOME/bin/java
===============配置内容===================
5.执行更行,使配置生效:source /etc/profile
6.执行命令测试是否配置成功:java -version -- java17 -version
特此感谢:https://blog.csdn.net/m0_62820470/article/details/144683542?spm=1001.2014.3001.5506
-------------------------配置JDK17环境,不影响本身的JDK8-------------------------------
环境配置成功后通过命令:java17 -jar xiaohashu-auth-0.0.1-SNAPSHOT.jar 运行Jar包并查看是否成功注册到了nacos上。
本地服务也运行到服务器的nacos上
服务都运行成功后通过调用 http://localhost:8150/test-lb/xiaohashu-auth 接口查看是否每次返回的IP都为本机
```
9. 核心依赖
```xml
```
特此感谢:https://blog.csdn.net/afgasdg/article/details/128580789