Ubuntu 22.04 安装 Apache Dubbo 指南

面向 Ubuntu 22.04 的 Apache Dubbo 3.2.20 集成指南:apt 安装 JDK17 与 Maven、坐标引入与验证,以直连模式给出 provider、consumer 最小示例的编译与调用回显、JDK17 适配。

Apache DubboApache Dubbo2026/10/12

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 + Maven 3.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 相关进程。