Ubuntu 22.04 安装 Apache Dubbo 指南
面向 Ubuntu 22.04 的 Apache Dubbo 3.2.20 集成指南:apt 安装 JDK17 与 Maven、坐标引入与验证,以直连模式给出 provider、consumer 最小示例的编译与调用回显、JDK17 适配。
Ubuntu 22.04 安装 Apache Dubbo 指南
Apache Dubbo 是高性能 Java RPC 框架,对外以 Java 库(jar)形式发布,没有独立守护进程。因此在服务器上「安装 Dubbo」的本质是:准备 JDK 与构建工具、引入 Maven 依赖、编写最小可运行的服务提供者(provider)与消费者(consumer)并验证调用链打通。本文以 org.apache.dubbo:dubbo:3.2.20 为例,在 Ubuntu 22.04 服务器上完成端到端直连(不依赖注册中心)调用实测,并给出 JDK 17 下的反射适配方法。
一、前置条件
1.1 环境与账号
- 操作系统:Ubuntu 22.04 LTS(x86_64),apt 源可用
- 账号权限:
root(示例口令q1w2e3r4) - 网络:可访问 Maven 中央仓库
https://repo1.maven.org - 资源:至少 2GB 可用内存;本文示例 JVM 堆限定为
-Xms256m -Xmx512m - 端口:放行 TCP
20880(Dubbo 协议默认端口)与22222(QoS 运维控制台端口)
1.2 组件版本
- Dubbo:
org.apache.dubbo:dubbo:3.2.20(3.2 线最新版) - 关键传递依赖:
io.netty:netty-all:4.1.113.Final、com.alibaba:hessian-lite:3.2.13、com.alibaba.fastjson2:fastjson2:2.0.52、org.javassist:javassist:3.30.2-GA - 实测平台:Ubuntu 22.04.5 LTS + OpenJDK
17.0.20.1+ Maven3.6.3
二、安装 JDK 与 Maven
2.1 更新源并安装
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y openjdk-17-jdk maven iproute2
2.2 验证安装
java -version
mvn -version
实测回显:
openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 17.0.20.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64
三、引入 Dubbo 依赖
3.1 创建最小工程
mkdir -p /root/dubbo-demo/src/main/java/com/example/dubbo
3.2 pom.xml
/root/dubbo-demo/pom.xml 关键内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>dubbo-demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<dubbo.version>3.2.20</dubbo.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
</plugin>
</plugins>
</build>
</project>
3.3 确认依赖引入
cd /root/dubbo-demo && mvn -B dependency:tree | grep -E "org.apache.dubbo|netty-all|hessian|fastjson|javassist"
实测回显:
[INFO] \- org.apache.dubbo:dubbo:jar:3.2.20:compile
[INFO] +- io.netty:netty-all:jar:4.1.113.Final:compile
[INFO] +- org.javassist:javassist:jar:3.30.2-GA:compile
[INFO] +- com.alibaba:hessian-lite:jar:3.2.13:compile
[INFO] \- com.alibaba.fastjson2:fastjson2:jar:2.0.52:compile
四、编写最小示例(直连模式)
直连模式指 provider 主动暴露服务地址、consumer 直接指定该地址调用,两端均不经过注册中心(使用 RegistryConfig.NO_AVAILABLE,即 N/A),适合安装验证与联调。
4.1 服务接口与实现
src/main/java/com/example/dubbo/GreetingService.java:
package com.example.dubbo;
public interface GreetingService {
String sayHello(String name);
int add(int a, int b);
}
src/main/java/com/example/dubbo/GreetingServiceImpl.java:
package com.example.dubbo;
public class GreetingServiceImpl implements GreetingService {
public String sayHello(String name) {
return "Hello, " + name + " from Dubbo provider!";
}
public int add(int a, int b) {
return a + b;
}
}
4.2 Provider(ServiceConfig 直连暴露)
src/main/java/com/example/dubbo/ProviderApp.java:
package com.example.dubbo;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
public class ProviderApp {
public static void main(String[] args) throws InterruptedException {
ServiceConfig<GreetingService> service = new ServiceConfig<>();
service.setApplication(new ApplicationConfig("dubbo-demo-provider"));
service.setRegistry(new RegistryConfig(RegistryConfig.NO_AVAILABLE));
service.setProtocol(new ProtocolConfig("dubbo", 20880));
service.setInterface(GreetingService.class);
service.setRef(new GreetingServiceImpl());
service.export();
System.out.println("[provider] exported urls: " + service.getExportedUrls());
System.out.println("[provider] listening on dubbo://127.0.0.1:20880");
Thread.currentThread().join();
}
}
4.3 Consumer(ReferenceConfig 直连调用)
src/main/java/com/example/dubbo/ConsumerApp.java:
package com.example.dubbo;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
public class ConsumerApp {
public static void main(String[] args) {
ReferenceConfig<GreetingService> reference = new ReferenceConfig<>();
reference.setApplication(new ApplicationConfig("dubbo-demo-consumer"));
reference.setRegistry(new RegistryConfig(RegistryConfig.NO_AVAILABLE));
reference.setInterface(GreetingService.class);
reference.setUrl("dubbo://127.0.0.1:20880");
GreetingService service = reference.get();
System.out.println("[consumer] sayHello(\"quzuo\") => " + service.sayHello("quzuo"));
System.out.println("[consumer] add(3, 4) => " + service.add(3, 4));
reference.destroy();
}
}
五、编译与运行(真实回显)
5.1 编译
cd /root/dubbo-demo
export MAVEN_OPTS="-Xms256m -Xmx512m"
mvn -B compile
编译成功(退出码 0),target/classes 下生成对应 class 文件。
5.2 启动 Provider
cd /root/dubbo-demo
export MAVEN_OPTS="-Xms256m -Xmx512m"
mvn -B exec:java -Dexec.mainClass=com.example.dubbo.ProviderApp > /tmp/provider.log 2>&1 &
实测日志:
INFO: [DUBBO] Dubbo Application[1.1](dubbo-demo-provider) is ready., dubbo version: 3.2.20, current host: 172.17.0.44
INFO: [DUBBO] Export dubbo service com.example.dubbo.GreetingService to url dubbo://172.17.0.44:20880/com.example.dubbo.GreetingService?anyhost=true&application=dubbo-demo-provider&interface=com.example.dubbo.GreetingService&methods=add,sayHello&release=3.2.20&side=provider ...
WARNING: [DUBBO] Remote Metadata Report Server is not provided or unavailable, will stop registering service definition to remote center!, error code: 1-39
[provider] exported urls: [dubbo://172.17.0.44:20880/com.example.dubbo.GreetingService?...]
[provider] listening on dubbo://127.0.0.1:20880
其中的元数据上报告警(错误码
1-39)在直连、无注册中心场景下属于预期提示,不影响服务暴露与调用。
5.3 确认端口监听
ss -lntp | grep -E "20880|22222"
实测回显:
LISTEN 0 4096 *:20880 *:* users:(("java",pid=5366,fd=186))
LISTEN 0 4096 *:22222 *:* users:(("java",pid=5366,fd=157))
20880 为 Dubbo 协议服务端口,22222 为 QoS 运维控制台端口,二者均由同一个 provider 进程监听。
5.4 Consumer 直连调用与 JDK 17 反射适配
在 JDK 17 上直接运行 consumer 时,Hessian2 序列化初始化会反射访问 java.math.BigInteger 的私有字段,因模块封装被拒而打印 InaccessibleObjectException 告警,但调用结果仍正确:
cd /root/dubbo-demo
export MAVEN_OPTS="-Xms256m -Xmx512m"
mvn -B -q exec:java -Dexec.mainClass=com.example.dubbo.ConsumerApp
java.lang.reflect.InaccessibleObjectException: Unable to make field final int java.math.BigInteger.signum accessible:
module java.base does not "opens java.math" to unnamed module
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.getFieldMap(JavaDeserializer.java:340)
...
[consumer] sayHello("quzuo") => Hello, quzuo from Dubbo provider!
[consumer] add(3, 4) => 7
显式添加 --add-opens 后告警消除:
cd /root/dubbo-demo
mvn -q -B dependency:build-classpath -Dmdep.outputFile=/tmp/cp.txt
java -Xms256m -Xmx512m \
--add-opens java.base/java.math=ALL-UNNAMED \
--add-opens java.base/java.lang=ALL-UNNAMED \
-cp "target/classes:$(cat /tmp/cp.txt)" com.example.dubbo.ConsumerApp
实测回显(InaccessibleObject 计数为 0):
[consumer] sayHello("quzuo") => Hello, quzuo from Dubbo provider!
[consumer] add(3, 4) => 7
结论:Dubbo 3.2.20 在 JDK 17 上运行需追加
--add-opens java.base/java.math=ALL-UNNAMED;JDK 8 环境则无此问题。
六、卸载
6.1 停止进程并清理工程
pkill -f exec:java
rm -rf /root/dubbo-demo
rm -rf ~/.m2/repository/org/apache/dubbo
6.2 卸载 JDK 与 Maven(可选)
apt-get remove -y maven openjdk-17-jdk
apt-get autoremove -y
卸载后 20880 与 22222 端口随之释放,本机不再驻留任何 Dubbo 相关进程。