dubbo3-solon-plugin
此插件,主要社区贡献人(浅念)
<dependency>
<groupId>org.noear</groupId>
<artifactId>dubbo3-solon-plugin</artifactId>
</dependency>
1、描述
分布式扩展插件。基于 Apache Dubbo 3 适配的 RPC 集成插件,覆盖配置绑定、服务导出、服务引用与进程保活;子配置属性与 Dubbo 官方 Config 字段一致。
完整字段含义见:Dubbo 配置参考
2、快速开始
2.1 启用
启动类上必须标注 @EnableDubbo:
@EnableDubbo
public class App {
public static void main(String[] args) {
Solon.start(App.class, args);
}
}
| 注解 | 用途 |
|---|---|
@DubboService | 暴露服务(兼容旧 @Service) |
@DubboReference | 注入消费代理(兼容旧 @Reference) |
仅标注 @DubboService 即可被扫描注册,无需额外加 @Component / @Managed。
2.2 声明接口
public interface HelloService {
String sayHello(String name);
}
2.3 提供者(服务端)
配置(app.yml):
server.port: 8011
dubbo:
application:
name: hello-provider
owner: noear
registry:
address: nacos://localhost:8848
protocol:
name: dubbo
port: 20880
协议
port未配置时默认取server.port + 20000。
代码:
@EnableDubbo
public class DubboProviderApp {
public static void main(String[] args) {
Solon.start(DubboProviderApp.class, args);
}
}
@DubboService(group = "hello")
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "hello, " + name;
}
}
2.4 消费者(客户端)
@EnableDubbo
public class DubboConsumeApp {
public static void main(String[] args) {
Solon.start(DubboConsumeApp.class, args, app -> app.enableHttp(false));
DubboConsumeApp tmp = Solon.context().getBean(DubboConsumeApp.class);
System.out.println(tmp.home());
}
@DubboReference(group = "hello")
HelloService helloService;
public String home() {
return helloService.sayHello("noear");
}
}
3、配置总览
3.1 支持的配置前缀
| 前缀 | 形态 | 说明 |
|---|---|---|
dubbo.application | 单 | 应用信息;缺 name 时用 solon.app.group + - + solon.app.name |
dubbo.registry / dubbo.registries | 单 / 多 | 注册中心;缺 address 时补齐 N/A |
dubbo.protocol / dubbo.protocols | 单 / 多 | 协议;缺 name 补 dubbo,缺 port 补 server.port + 20000 |
dubbo.provider / dubbo.providers | 单 / 多 | 服务端默认;map key → id,可被 @DubboService(provider=...) 引用 |
dubbo.consumer / dubbo.consumers | 单 / 多 | 消费端默认;map key → id,可被 @DubboReference(consumer=...) 引用 |
dubbo.monitor | 单 · 可选 | 监控中心 |
dubbo.config-center | 单 · 可选 | 配置中心 |
dubbo.metadata-report | 单 · 可选 | 元数据中心 |
dubbo.solon.block | Solon 特有 | 进程保活开关 |
未在上表中的前缀(如 metrics、module 等)当前不绑定。
3.2 绑定规则
- 子键 = Dubbo Config 属性——例如
dubbo.registry.address→RegistryConfig.setAddress(...),与 Spring Boot 习惯一致。 - multi 优先于 single——存在
dubbo.registries/protocols/providers/consumers时,忽略对应单数形式。 - map key → id——非数字 key 且未显式写
id时,key 写入 config 的id(便于注解引用)。 - list 索引 key——支持
registries.0/registries[0];按索引排序,稳定有序。 - 缺省补全——仅对 registry(address)、protocol(name/port)、application(name)做插件级默认;provider/consumer 未配置时不创建默认实例。
3.3 常用字段速查
| 配置 | 常用字段 |
|---|---|
application | name, owner, logger, qos-enable, qos-port |
registry | address, username, password, group, timeout, check, simplified, parameters |
protocol | name, port, host, threads, serialization, transporter |
provider | group, version, timeout, retries, filter, token, delay |
consumer | group, version, timeout, check, retries, filter, scope, loadbalance |
monitor | address, protocol |
config-center | address, protocol, namespace, group |
metadata-report | address, protocol, group |
4、多配置(Map 风格)
支持为不同服务指定不同的注册中心、协议和提供者/消费者默认值。
4.1 配置示例
dubbo:
registries:
reg1:
address: zookeeper://127.0.0.1:2181
reg2:
address: nacos://127.0.0.1:8848
protocols:
dubbo:
name: dubbo
port: 20880
triple:
name: tri
port: 50051
providers:
p1:
group: g1
timeout: 3000
p2:
group: g2
filter: solonTracing
consumers:
c1:
check: false
timeout: 2000
c2:
check: false
timeout: 5000
4.2 注解引用
Map key 自动写入 id,可在注解中按 id 引用:
@DubboService(
provider = "p1",
registry = {"reg1"},
protocol = {"dubbo"}
)
public class HelloServiceImpl implements HelloService {
// ...
}
@DubboReference(
consumer = "c1",
registry = {"reg1"},
check = false
)
HelloService helloService;
| 注解属性 | 结果 |
|---|---|
@DubboService(provider = "p1") | 设置 providerIds = p1;id 不存在则启动失败 |
@DubboReference(consumer = "c1") | 查找 ConsumerConfig(id=c1) 并关联;不存在则启动失败 |
registry = {"reg1", "reg2"} | 设置 registryIds = reg1,reg2;缺失 id 直接 fail-fast |
@DubboService(protocol = {"dubbo", "tri"}) | 设置 protocolIds = dubbo,tri(仅 Service 侧;Reference 用字符串 protocol) |
5、本地调试
5.1 不连注册中心(本地模式)
dubbo:
registry:
address: N/A
consumer:
scope: local # 同进程本地调用
check: false
5.2 双进程直连调试(推荐)
服务端配置:
# demo-server.yml
solon.app:
group: demo
name: dubbo-provider
dubbo:
application:
name: dubbo-provider
logger: slf4j
registry:
address: N/A
protocol:
name: dubbo
port: 20880
provider:
group: demo
@EnableDubbo
public class DubboProviderApp {
public static void main(String[] args) {
Solon.start(DubboProviderApp.class, args, app -> {
app.enableHttp(false); // 纯 Provider,由插件保活
});
}
}
@DubboService(group = "demo")
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "hello, " + name;
}
}
客户端配置:
# demo-client.yml
solon.app:
group: demo
name: dubbo-consumer
dubbo:
application:
name: dubbo-consumer
logger: slf4j
registry:
address: N/A
consumer:
check: false
timeout: 3000
solon:
block: false # 一次性 Consumer,执行完后退出
demo:
hello:
group: demo
url: dubbo://127.0.0.1:20880
@EnableDubbo
public class DubboConsumeApp {
@DubboReference(
group = "${demo.hello.group}",
url = "${demo.hello.url}",
check = false
)
HelloService helloService;
public static void main(String[] args) {
Solon.start(DubboConsumeApp.class, args, app -> {
app.enableHttp(false);
});
DubboConsumeApp app = Solon.context().getBean(DubboConsumeApp.class);
String result = app.helloService.sayHello("noear");
System.out.println("result = " + result);
Solon.stopBlock(false, 0); // 执行完毕,退出进程
}
}
客户端通过
${...}模板从配置文件中动态读取 group 和 url,无需硬编码。
6、进程保活
纯 Dubbo Provider 进程(不开 HTTP)需要插件保活,否则 main 线程结束后进程会退出。
| 场景 | 行为 |
|---|---|
dubbo.solon.block = true/false | 显式开关,优先 |
enableHttp(false) / 无 HTTP | 默认后台线程保活(纯 Provider) |
| HTTP 开启(Solon 默认) | 不额外保活,依赖 HTTP 服务器线程 |
建议:
- 纯 Provider:配置
app.enableHttp(false),插件自动保活 - 一次性 Consumer:配置
dubbo.solon.block: false,避免 main 结束后仍被保活
7、高级注解特性
7.1 ${...} 配置模板
所有 String 类型的注解属性(如 group、version、url、token 等)都支持 ${...} 模板,从配置文件中取值:
# app.yml
demo.service.group: g1
demo.service.version: 1.0.0
@DubboService(
group = "${demo.service.group}",
version = "${demo.service.version}"
)
public class HelloServiceImpl implements HelloService { ... }
7.2 parameters(参数)
支持灵活的格式:
@DubboService(
group = "demo",
parameters = {"token", "abc", "route=gray"} // → {token=abc, route=gray}
)
public class HelloServiceImpl implements HelloService { ... }
@DubboReference(
group = "demo",
parameters = {"tag:gray"} // 也支持冒号分隔
)
HelloService helloService;
| 写法 | 结果 |
|---|---|
{"a","b"} | {a=b} |
{"a=b"} | {a=b} |
{"a:b"} | {a=b} |
{"a=b","c","d"} | {a=b, c=d} |
{"a","a:b"} | {a=a:b} |
奇数不成对会报错;值支持 ${...} 模板。
7.3 methods(方法级配置)
@DubboService(
group = "demo",
methods = {
@Method(name = "sayHello", timeout = 1000, retries = 0)
}
)
public class HelloServiceImpl implements HelloService { ... }
@DubboReference(
group = "demo",
methods = {
@Method(name = "sayHello", timeout = 2000)
}
)
HelloService helloService;
7.4 远程引用建议
启动期创建代理时若强依赖注册中心,可能导致启动失败。建议:
- 配置
dubbo.consumer.check: false,或 - 注解
check = false,或 - 显式
url = "dubbo://host:port"直连
8、行为说明
| 项 | 说明 |
|---|---|
| 服务导出 | 扫描阶段只注册 ServiceConfig;统一在 lifecycle 中 DubboBootstrap.start() 真正导出 |
| 接口解析 | 优先 interfaceName / interfaceClass;否则取实现类直接业务接口(不展开父接口;多接口时保留最具体者);0 个或仍有歧义则启动失败 |
默认 application.name | solon.app.group + - + solon.app.name |
| 默认 registry | 未配置 address → N/A |
| 默认 protocol | 未配置 name → dubbo;未配置 port → server.port + 20000 |
| multi 引用 | 注解 provider / consumer / registry[] / Service protocol[] 按 id 关联;缺失 fail-fast |
| Reference 缓存 | 相同 interface / group / version / url / protocol / scope / consumerId / registryIds / filter 等关键参数复用代理 |
| 停机 | preStop 时 bootstrap.stop() 并清理引用缓存 |
9、Tracing(链路追踪)
已注册 Dubbo Filter SPI:solonTracing。
存在 OpenTracing Tracer bean 时,可通过 filter 启用:
dubbo:
provider:
filter: solonTracing
consumer:
filter: solonTracing
也可写在 multi providers.* / consumers.* 的 filter 上。
10、原生编译(AOT / GraalVM Native Image)
⚠️ 当前未完全验证通过,以下为参考配置。
添加 dubbo-native 依赖包(提供 AOT 处理实现)。dubbo-native AOT 编译时还会用到 spring-context。
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-native</artifactId>
<version>${dubbo3.version}</version>
</dependency>
添加 dubbo-maven-plugin 构建插件:
<profiles>
<profile>
<id>native-dubbo</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-maven-plugin</artifactId>
<version>${dubbo3.version}</version>
<configuration>
<mainClass>com.example.nativedemo.NativeDemoApplication</mainClass>
</configuration>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>dubbo-process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
运行命令(细节需参考 Dubbo 官网教程及配套示例):
mvn clean native:compile -P native -P native-dubbo -DskipTests
11、代码演示
https://gitee.com/noear/solon-examples/tree/main/7.Solon-Remoting-Rpc/demo7014-rpc_dubbo3_sml