Apache ServiceComb java-chassis 3.3.0 构建并运行示例 REST 应用指南
Apache ServiceComb java-chassis 3.3.0 构建并运行示例 REST 应用指南:从零创建 Maven 工程、完整 pom.xml 与 @RestSchema 接口源码、microservice.yaml 配置、mvn package 打 fat jar、java -jar 启动日志与 curl 真实回显(HTTP 200 返回 JSON 字符串),含 local 注册中心与 service-center 注册实测,全程可复现。
Apache ServiceComb java-chassis 3.3.0 构建并运行示例 REST 应用指南
目标:从零构建并运行一个基于 Apache ServiceComb java-chassis 3.3.0 的最小 REST 微服务。给出完整 pom.xml、示例 Java 源码、microservice.yaml 配置、编译打包命令、启动日志与 curl 真实回显(
GET /hello返回 HTTP 200 与"Hello, ServiceComb!"),并实测「内置 local 注册中心」与「外置 service-center 注册中心」两种运行形态。所有命令与输出均在 Ubuntu 22.04.5 + JDK 17 环境实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS
- Java:OpenJDK 17.0.20.1
- 构建工具:Apache Maven 3.6.3
- java-chassis 版本:3.3.0(java-chassis-bom + java-chassis-spring-boot-starter-standalone)
- Spring Boot 版本:3.2.12
- 注册中心(可选小节):service-center 2.2.0(embedded_etcd 模式,监听 30100)
- 示例工程目录:
/root/servicecomb-hello/ - 演示账号:root
二、前置条件
- 已安装 JDK 17 与 Maven,并确认版本回显正确:
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
java -version
- 回显需为
openjdk version "17.0.20.1" 2026-08-18(java-chassis 3.x 必须 JDK 17+)。 - 安装步骤见《Ubuntu 22.04 安装 Apache ServiceComb java-chassis 3.3.0 指南》篇。
三、工程结构
标准 Maven 布局,一个主类、一个 REST 生产者、两个配置文件:
servicecomb-hello/
├── pom.xml
└── src/main/
├── java/demo/
│ ├── HelloApplication.java
│ └── HelloEndpoint.java
└── resources/
├── application.yml
└── microservice.yaml
mkdir -p /root/servicecomb-hello/src/main/java/demo
mkdir -p /root/servicecomb-hello/src/main/resources
四、完整 pom.xml
pom 通过 <dependencyManagement> 同时导入 java-chassis-bom(3.3.0)与 spring-boot-dependencies(3.2.12),并用 spring-boot-maven-plugin 的 repackage 打可执行 fat jar:
<?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>demo</groupId>
<artifactId>servicecomb-hello</artifactId>
<version>1.0-SNAPSHOT</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>
<java-chassis.version>3.3.0</java-chassis.version>
<spring-boot.version>3.2.12</spring-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>java-chassis-bom</artifactId>
<version>${java-chassis.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>java-chassis-spring-boot-starter-standalone</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
<build>
<finalName>servicecomb-hello</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
五、示例源码
5.1 启动主类 HelloApplication.java
java-chassis 3.x 无需在主类上加任何 java-chassis 注解(2.x 的 @EnableServiceComb 已移除),框架经 Spring Boot 3 自动配置装配:
package demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}
5.2 REST 生产者 HelloEndpoint.java
@RestSchema 把类声明为 java-chassis REST 生产者 schema;JAX-RS(jakarta 命名空间)注解声明路径与方法。示例包含两个端点:/hello 直接返回,/hello/call 演示通过 RestTemplateBuilder 以 cse://服务名/路径 形式做服务间调用:
package demo;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import org.apache.servicecomb.provider.rest.common.RestSchema;
import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
import org.springframework.web.client.RestOperations;
@RestSchema(schemaId = "hello")
@Path("/hello")
public class HelloEndpoint {
private final RestOperations restTemplate = RestTemplateBuilder.create();
@GET
public String sayHello(@QueryParam("name") String name) {
String who = (name == null || name.isEmpty()) ? "ServiceComb" : name;
return "Hello, " + who + "!";
}
@GET
@Path("/call")
public String callSelf(@QueryParam("name") String name) {
return restTemplate.getForObject(
"cse://hello/hello?name={name}", String.class, name);
}
}
💡 说明:
RestTemplateBuilder.create()的返回类型是RestOperations接口,不能声明为RestTemplate,否则编译报incompatible types: org.springframework.web.client.RestOperations cannot be converted to org.springframework.web.client.RestTemplate(实测踩坑)。
5.3 微服务配置 microservice.yaml
声明服务名、版本、REST 监听地址。registry.enabled: false 为最小可运行形态(不依赖任何注册中心):
application:
name: hello-app
servicecomb:
service:
name: hello
version: 0.0.1
registry:
enabled: false
rest:
address: 0.0.0.0:8080
5.4 application.yml(standalone 形态必需)
spring:
main:
web-application-type: none
⚠️ 注意:缺少该文件时启动会报
Web application could not be started as there was no org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context——standalone 形态 REST 由 Vert.x 提供,必须禁止 Spring Boot 再起 Servlet 容器。
六、编译与运行
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
cd /root/servicecomb-hello
# 编译打包(生成可执行 fat jar)
mvn clean package -DskipTests
实测结果(节选):
[INFO] --- spring-boot-maven-plugin:3.2.12:repackage (repackage) @ servicecomb-hello ---
[INFO] Replacing main artifact /root/servicecomb-hello/target/servicecomb-hello.jar
[INFO] BUILD SUCCESS
限制 JVM 堆内存并后台启动(演示进程堆限制在 256–512MB):
nohup java -Xms256m -Xmx512m -jar target/servicecomb-hello.jar > /root/hello.log 2>&1 &
启动日志关键行(真实回显,节选):
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.2.12)
Starting HelloApplication using Java 17.0.20.1 with PID 5549 (/root/servicecomb-hello/target/servicecomb-hello.jar started by root in /root/servicecomb-hello)
o.a.s.t.rest.vertx.RestServerVerticle : rest listen success. address=0.0.0.0:8080
o.a.s.core.transport.TransportManager : endpoint to publish: rest://172.17.0.9:8080
o.a.s.c.p.producer.ProducerBootListener : export microservice swagger file to path /tmp/microservices/%s/%s.yaml
org.apache.servicecomb.core.SCBEngine : ServiceComb is ready.
验证堆内存生效(另开终端):
jps -v
实测回显:
5549 servicecomb-hello.jar -Xms256m -Xmx512m
七、验证 REST 服务
7.1 直接调用
curl -s http://127.0.0.1:8080/hello
curl -s "http://127.0.0.1:8080/hello?name=Alice"
curl -s -i http://127.0.0.1:8080/hello
实测回显:
"Hello, ServiceComb!"
"Hello, Alice!"
HTTP/1.1 200 OK
X-B3-TraceId: 6accdcd8751366a7
Content-Type: application/json
Content-Length: 21
"Hello, ServiceComb!"
💡 响应头
X-B3-TraceId为 java-chassis 自动注入的链路追踪标识;返回值带引号是因为 REST 契约默认按 JSON 字符串序列化。
7.2 服务间调用(cse:// 协议)
curl -s "http://127.0.0.1:8080/hello/call?name=Carol"
实测回显:
"Hello, Carol!"
/hello/call 内部经 cse://hello/hello 由 java-chassis 服务发现后转发到本服务的 /hello,证明消费端调用链可用。
7.3 查看 Swagger 契约
java-chassis 启动时自动把生产者契约导出到 /tmp/microservices/<应用>/<服务>/:
cat /tmp/microservices/hello/hello.yaml
实测回显(节选):
openapi: 3.0.1
info:
title: swagger definition for demo.HelloEndpoint
version: 1.0.0
servers:
- url: /hello
paths:
/:
get:
operationId: sayHello
parameters:
- name: name
in: query
schema:
type: string
responses:
"200":
description: response of 200
八、接入服务注册中心(可选)
默认 registry.enabled: false 时服务独立运行。生产环境通常需要注册中心,以下两种形态均已实测。
8.1 形态一:内置 local 注册中心(零外部依赖)
在 pom.xml 追加 registry-local 依赖(版本由 bom 管理):
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>registry-local</artifactId>
</dependency>
microservice.yaml 改为:
application:
name: hello-app
servicecomb:
service:
name: hello
version: 0.0.1
registry:
enabled: true
registry:
local:
enabled: true
rest:
address: 0.0.0.0:8080
重新打包并启动后,日志关键行:
o.a.servicecomb.registry.RegistrationId : initialized global registration id 8122c655-dc18-4b25-996a-d5f7691288e2
o.a.s.c.provider.LocalOpenAPIRegistry : register swagger appId=default, name=hello, schemaId=hello.
rest listen success. address=0.0.0.0:8080
ServiceComb is ready.
name:local-registry
local 注册中心把实例注册在进程内存中,适合单机演示与同进程消费端调用验证。
8.2 形态二:外置 service-center 注册中心(生产形态)
部署 service-center 2.2.0 并以 embedded_etcd 模式启动(默认 etcd 模式需要外置 etcd,本例改用内嵌):
wget https://dlcdn.apache.org/servicecomb/servicecomb-service-center/2.2.0/apache-servicecomb-service-center-2.2.0-linux-amd64.tar.gz
mkdir -p /opt/service-center
tar xzf apache-servicecomb-service-center-2.2.0-linux-amd64.tar.gz -C /opt/service-center
sed -i 's/^ kind: etcd/ kind: embedded_etcd/' /opt/service-center/apache-servicecomb-service-center-2.2.0-linux-amd64/conf/app.yaml
cd /opt/service-center/apache-servicecomb-service-center-2.2.0-linux-amd64
nohup ./service-center > /root/sc.log 2>&1 &
curl -s http://127.0.0.1:30100/v4/default/registry/microservices
service-center 就绪后(自身实例 UP,version 2.2.0),在示例工程 pom.xml 追加依赖:
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>registry-service-center</artifactId>
</dependency>
microservice.yaml 指定 service-center 地址(3.x 配置键为 servicecomb.registry.sc.address):
application:
name: hello-app
servicecomb:
service:
name: hello
version: 0.0.1
registry:
enabled: true
registry:
sc:
address: http://127.0.0.1:30100
rest:
address: 0.0.0.0:8080
⚠️ 注意:3.x 已不支持 2.x 的
servicecomb.service.registry.address写法;若沿用旧键,启动直接失败并提示Address is required in configuration. NOTICE: since 3.0.0, only support servicecomb.registry.sc.address to configure service center address。另外修改src/main/resources下任何配置后必须重新mvn package,fat jar 内的配置是打包时快照。
重新打包、启动后,注册成功日志:
o.a.s.s.c.client.ServiceCenterClient : Query serviceId fails, statusCode = 400; message = Bad Request; content = {"errorCode":"400012","errorMessage":"Micro-service does not exist","detail":"/default/hello/0.0.1 does not exist."}
o.a.s.s.c.c.ServiceCenterRegistration : register microservice successfully, service id=bad03bda8b28269a31ccf8fade650edd7750bb86, instance id=b1050217-3fed-4bb3-aaff-63cb259e98ed
💡 首次启动时
Query serviceId fails, statusCode = 400(errorCode 400012,Micro-service does not exist)是正常现象:客户端先查询服务是否存在,不存在则自动完成注册。
到 service-center 侧查询,可见 hello 服务已注册:
curl -s http://127.0.0.1:30100/v4/default/registry/microservices
实测回显(节选):
"serviceName":"hello"
九、注意事项
⚠️ 注意:
- 必须使用 JDK 17 编译运行(java-chassis 3.x 基于 Spring Boot 3.x / jakarta 命名空间);JDK 8/11 请退用 java-chassis 2.x。
java-chassis-bom与spring-boot-dependencies两个 import 必须成对出现,且所有org.apache.servicecomb依赖不要单独写版本号,统一由 bom 管理。- standalone 形态必须设置
spring.main.web-application-type: none,否则与 Vert.x REST 端口模型冲突。- 进程堆内存建议显式限制(
-Xms256m -Xmx512m),并用jps -v验证。
十、常见问题
Q1:启动报 no org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context?
在 application.yml 增加 spring.main.web-application-type: none。原因与原理见 5.4 节。
Q2:编译报 package org.apache.servicecomb.springboot.starter does not exist?
主类使用了 2.x 的 @EnableServiceComb。3.x 主类只需 @SpringBootApplication。
Q3:编译报 RestOperations cannot be converted to RestTemplate?
RestTemplateBuilder.create() 返回 RestOperations,字段类型要声明为 RestOperations。
Q4:连不上注册中心 / 报 Address is required in configuration?
3.x 的 service-center 地址键是 servicecomb.registry.sc.address,不是 2.x 的 servicecomb.service.registry.address;确认 microservice.yaml 层级为 servicecomb.registry.sc.address,且修改后已重新 mvn package。
Q5:修改了配置文件但不生效?
fat jar 内的 microservice.yaml 是打包时快照,改 src/main/resources 后必须重新 mvn clean package 再启动。
十一、参考链接
- java-chassis 官方文档:
https://servicecomb.apache.org/references/java-chassis/zh_CN/ - Spring Boot 集成说明:
https://servicecomb.apache.org/references/java-chassis/zh_CN/using-java-chassis-in-spring-boot/ - service-center 官方仓库:
https://github.com/apache/servicecomb-service-center - 本示例依赖坐标查询:
https://repo1.maven.org/maven2/org/apache/servicecomb/