Solon v4.1.0

Solon Rpc 开发定制

</> markdown
2026年9月14日 上午5:21:08

默认配置能跑通后,再按场景选择 Builder、NamiConfigurationFilter。优先局部配置,避免一个全局配置器悄悄改变所有客户端。

1、 Builder:手动创建一个代理

Nami.builder() 返回 NamiBuilder,当前源码支持:urlnamepathgroupupstreamchannelencoderdecodertimeoutheartbeatheaderSetfilterAddcreate

UserService service = Nami.builder()
    .url("http://localhost:9001/rpc/v1/user")
    .headerSet("X-App", "demo-consumer")
    .timeout(10)
    .decoder(Snack4Decoder.instance)
    .encoder(Snack4Encoder.instance)
    .create(UserService.class);

create 要求传入接口;它创建的是 JDK 动态代理。若传入普通 class,源码会抛出 NamiException

动态上游适合每次调用前选择地址:

UserService service = Nami.builder()
    .path("/rpc/v1/user")
    .upstream(() -> "http://localhost:9001")
    .create(UserService.class);

2、 配置器:统一配置客户端

Nami 的 NamiConfiguration 方法签名是:

void config(NamiClient client, NamiBuilder builder);

在 Solon 中可注册一个组件:

import org.noear.nami.NamiBuilder;
import org.noear.nami.NamiConfiguration;
import org.noear.nami.annotation.NamiClient;
import org.noear.nami.coder.snack4.Snack4Decoder;
import org.noear.nami.coder.snack4.Snack4Encoder;
import org.noear.solon.annotation.Component;

@Component
public class DemoNamiConfiguration implements NamiConfiguration {
    @Override
    public void config(NamiClient client, NamiBuilder builder) {
        builder.decoder(Snack4Decoder.instance)
               .encoder(Snack4Encoder.instance)
               .timeout(10);
    }
}

当前 Solon 集成会发现 NamiConfiguration 并参与客户端创建。配置器会影响匹配到的客户端;如果 HTTP JSON 和二进制客户端并存,应通过不同配置器或显式 Builder 分开。

不要直接照搬旧资料中的 SnackTypeEncoder 等类名,当前仓库 snack4 模块实际提供的是 Snack4EncoderSnack4Decoder

3、 过滤器:在调用链上做横切处理

Filter 的唯一方法是:

Result doFilter(Invocation inv) throws Throwable;

最小过滤器必须继续调用 inv.invoke(),否则请求不会真正发出:

Filter logging = inv -> {
    long start = System.currentTimeMillis();
    try {
        return inv.invoke();
    } finally {
        long cost = System.currentTimeMillis() - start;
        System.out.println("rpc cost=" + cost + "ms, url=" + inv.url);
    }
};

UserService service = Nami.builder()
    .url("http://localhost:9001/rpc/v1/user")
    .filterAdd(logging)
    .create(UserService.class);

生产环境建议使用日志组件而不是 System.out,并脱敏 URL 参数、Token 和个人数据。

4、 选择建议

需求方式
Solon Bean 注入、统一默认值@NamiClient + NamiConfiguration
独立 Java 程序或单个特殊客户端Nami.builder()
trace、鉴权头、耗时统计Filter
服务地址发现name/path + Discovery/LoadBalance
一次调用链临时携带头NamiAttach