LoadBalance、服务发现与节点选择
2026年9月14日 上午5:29:45
服务发现回答“有哪些实例”,负载均衡回答“本次选哪一个”。在 Solon 中,LoadBalance 是一个很小的适配接口,Nami 和 HTTP 工具都可以通过它获得上游地址。
1、 读取服务名对应的节点
import org.noear.solon.core.LoadBalance;
LoadBalance balance = LoadBalance.get("userapi");
String server = balance.getServer();
带分组:
LoadBalance balance = LoadBalance.get("demo", "userapi");
String server = balance.getServer();
当前源码中:
get(String service)等价于空 group。getServer()默认调用getServer(0)。getServer(int port)是接口必须实现的方法。- 找不到底层负载器时,包装器可能返回
null;调用前要做好配置和空值检查。
2、 parse 的两类输入
LoadBalance.parse("userapi");
LoadBalance.parse("lb://userapi");
LoadBalance.parse("http://localhost:9001");
源码会把不含 :// 的字符串当服务名;lb:// 表示从负载均衡器取得节点;普通 http:// 则包装成固定 server。不要把任意业务 URL 当成服务名。
3、 自定义负载均衡器
最小实现:
import org.noear.solon.core.LoadBalance;
public class MyLoadBalance implements LoadBalance {
@Override
public String getServer(int port) {
if (port > 0) {
return "http://127.0.0.1:" + port;
}
return "http://127.0.0.1:9001";
}
}
如果要按轮询、权重或健康状态选择多个地址,应在实现内部维护节点列表和策略;不要在 getServer 中每次无条件返回同一个地址却把它称为负载均衡。
4、 工厂接入
一般不这么做,避免破坏 Solon Cloud Discovery/LoadBalance 插件的接入
public class MyLoadBalanceFactory implements LoadBalance.Factory {
@Override
public LoadBalance create(String group, String service) {
if ("demo".equals(group) && "userapi".equals(service)) {
return new MyLoadBalance();
}
return null;
}
}
Factory 的签名是 create(String group, String service)。未匹配的服务应返回 null,让其他工厂或默认机制处理;不要返回一个错误实例导致所有未知服务都指向错误地址。具体注册方式取决于应用容器,可作为 Solon Bean 注册。
5、 与 Nami 配合
UserService service = Nami.builder()
.name("userapi")
.group("demo")
.path("/rpc/v1/user")
.create(UserService.class);
普通项目优先使用 Solon Cloud 的 Discovery/LoadBalance 插件。只有需要特殊节点来源、灰度规则或自定义权重时,才实现自己的 LoadBalance.Factory。
6、不要混淆三层配置
solon.app.name → 当前应用注册名
NamiClient.name → 要调用的服务名/负载名称
@Mapping → 服务的 HTTP 路径
三者可以文字相同,但语义不同。排查多实例调用时按“服务名 → group → 节点 URL → path”逐项打印和核对。