Solon Server 启动模式深度解析:从 0.3MB 内核到 10+ Server 插件
2026/6/2 23:33:45 网站建设 项目流程

一、开篇:Server 插件化设计哲学

Java Web 开发中,应用框架与底层服务器通常是强绑定的。你选了一个框架,就绑定了它支持的服务器实现。切换?往往意味着大量适配工作。

Solon 的设计哲学不同:业务代码与底层容器完全解耦

在 Solon 中,你的 Controller、Service、Repository 等业务代码是"不变的",而底层服务器是"可插拔的"。只需要换一个 Maven 依赖,就能从 JDK 内置 HTTP 服务器(0.3MB)切换到 Jetty(2.7MB)、Undertow(4.6MB)或 Vert.x(6.3MB)——业务代码零修改

这就是 Solon Server 插件化设计的核心价值:

维度传统方式Solon 方式
框架与服务器关系强绑定可插拔
切换服务器改代码/改配置换一个 Maven 依赖
包大小通常较大按需选择,最小 0.3MB
协议支持通常只有 HTTPHTTP + WebSocket + Socket.D

本文将带你深入解析 Solon 的 Server 启动模式体系。

二、应用启动入口与生命周期

2.1 标准启动方式

所有 Solon 应用的入口都是Solon.start()

@SolonMain public class App { public static void main(String[] args) { Solon.start(App.class, args); } }

2.2 带初始化函数的启动

第三个参数是初始化函数,在应用初始化时机点执行:

@SolonMain public class App { public static void main(String[] args) { Solon.start(App.class, args, app -> { // 控制信号启停、订阅早期事件等 app.enableHttp(true); app.enableWebSocket(true); }); } }

2.3 应用生命周期全景

Solon 应用的生命周期包含四个层次的时机点:

① 一个初始化函数时机点-Solon.start()的第三个参数回调

② 六个应用事件时机点

事件说明订阅方式
AppInitEndEvent应用初始化完成只支持手动订阅
AppPluginLoadEndEvent插件加载完成只支持手动订阅
AppBeanLoadEndEventBean 扫描完成自动/手动
AppLoadEndEvent应用启动完成自动/手动
AppPrestopEndEvent应用预停止自动/手动
AppStopEndEvent应用停止自动/手动

③ 三个插件生命时机点

public interface Plugin { void start(AppContext context) throws Throwable; default void prestop() throws Throwable {} default void stop() throws Throwable {} }

④ 两个容器生命时机点-AppContext::start()— 扫描完成后执行 -AppContext::stop()— 插件 stop 后执行

AppBeanLoadEndEvent之前的事件需要在启动前完成订阅,否则会错过时机。

三、启动参数体系

3.1 完整参数表

启动参数在应用启动后会被静态化(启动后不可修改)。

启动参数对应配置描述
--envsolon.env环境变量(配置切换)
--scanning是否扫描(默认 1)
--debugsolon.debug调试模式(0 或 1)
--setupsolon.setup安装模式(0 或 1)
--whitesolon.white白名单模式(0 或 1)
--driftsolon.drift漂移模式(k8s 部署设为 1)
--alonesolon.alone单体模式(0 或 1)
--extendsolon.extend扩展目录
--localesolon.locale默认地区
--config.addsolon.config.add增加外部配置
--app.namesolon.app.name应用名
--app.groupsolon.app.group应用分组
--app.titlesolon.app.title应用标题
--stop.safesolon.stop.safe安全停止(0 或 1)
--stop.delaysolon.stop.delay安全停止延时秒数(默认 10)

3.2 三种等价写法

所有带.的启动参数同时会成为应用配置,以下三种写法完全等价:

# 方式一:JVM 系统属性 java -Dsolon.env=dev -jar demo.jar # 方式二:完整的命令行参数 java -jar demo.jar --solon.env=dev # 方式三:简写命令行参数 java -jar demo.jar --env=dev

同理,server.port也支持三种写法:

java -Dserver.port=8081 -jar demo.jar java -jar demo.jar --server.port=8081

四、Server 插件全景矩阵

Solon Server 系列包含所有通讯"服务启动器"插件。切换 Boot 插件只需更换 Maven/Gradle 依赖。

4.1 HTTP 类 Server 插件

插件框架版本包大小信号协议JDK要求开源协议
solon-server-jdkhttpJDK0.3MBhttp8+Apache 2.0
solon-server-smarthttp [国产]0.8MBhttp, ws8+Apache 2.0
solon-server-grizzly1.8MBhttp, ws, http28+EPL-2.0
solon-server-vertx6.3MBhttp, ws, http28+EPL-2.0
solon-server-jettyv92.7MBhttp, ws8+EPL-2.0
solon-server-jetty-jakartav123.9MBhttp, ws, http217+EPL-2.0
solon-server-undertowv2.24.6MBhttp, ws, http28+Apache 2.0
solon-server-undertow-jakartav2.3http, ws, http217+Apache 2.0
solon-server-tomcatv9http, ws, http28+Apache 2.0
solon-server-tomcat-jakartav11http, ws, http217+Apache 2.0

4.2 WebSocket 类 Server 插件

插件包大小信号协议JDK要求开源协议
solon-server-websocket0.4MBws8+MIT
solon-server-websocket-netty3.6MBws8+Apache 2.0

4.3 Socket.D 类 Server 插件

插件包大小信号协议JDK要求开源协议
solon-server-socketd0.4MBtcp, udp, ws8+Apache 2.0

4.4 插件切换方法

切换 Boot 插件只需更换依赖,业务代码无需任何修改:

<!-- 替换前:使用 JDK 内置 HTTP 服务器(0.3MB) --> <dependency> <groupId>org.noear</groupId> <artifactId>solon-server-jdkhttp</artifactId> </dependency> <!-- 替换后:使用 Jetty(2.7MB,支持 WebSocket) --> <dependency> <groupId>org.noear</groupId> <artifactId>solon-server-jetty</artifactId> </dependency>

4.5 二级扩展插件

部分 Boot 插件有配套的二级插件,按需添加:

Boot 插件二级插件说明
solon-server-jettysolon-server-jetty-add-jsp增加 JSP 视图
solon-server-jettysolon-server-jetty-add-websocket增加 WebSocket
solon-server-tomcatsolon-server-tomcat-add-jsp增加 JSP 视图
solon-server-tomcatsolon-server-tomcat-add-websocket增加 WebSocket
solon-server-undertowsolon-server-undertow-add-jsp增加 JSP 视图

五、HTTP 模式详解

5.1 基础 Web 应用

以最轻量的solon-server-jdkhttp(0.3MB)为例:

<dependency> <groupId>org.noear</groupId> <artifactId>solon-server-jdkhttp</artifactId> </dependency> @SolonMain public class DemoApp { public static void main(String[] args) { Solon.start(DemoApp.class, args); } } @Controller public class DemoController { @Mapping("/hello") public String hello(@Param(defaultValue = "world") String name) { return "Hello " + name + "!"; } }

5.2 SSL/HTTPS 配置

方式一:配置文件

server: ssl: keyStore: "/data/_ca/demo.jks" # 或 "demo.pfx" keyPassword: "demo"

方式二:自定义 SSLContext(v2.5.9+)

不走配置文件,完全代码控制:

@SolonMain public class AppDemo { public static void main(String[] args) { Solon.start(AppDemo.class, args, app -> { SSLContext sslContext = buildSSLContext(); // 自行构建 app.onEvent(HttpServerConfigure.class, e -> { e.enableSsl(true, sslContext); }); }); } }

5.3 额外 HTTP 端口

启用 HTTPS 后仍需保留 HTTP 端口的场景(v2.2.18+):

@SolonMain public class SeverDemo { public static void main(String[] args) { Solon.start(SeverDemo.class, args, app -> { app.onEvent(HttpServerConfigure.class, e -> { e.addHttpPort(8082); }); }); } }

5.4 控制端口启停

// 关闭 HTTP 自动启动 @SolonMain public class SeverDemo { public static void main(String[] args) { Solon.start(SeverDemo.class, args, app -> { app.enableHttp(false); }); } }

六、WebSocket 模式

6.1 启用 WebSocket

使用 Jetty 为例(需添加二级插件):

<dependency> <groupId>org.noear</groupId> <artifactId>solon-server-jetty</artifactId> </dependency> <dependency> <groupId>org.noear</groupId> <artifactId>solon-server-jetty-add-websocket</artifactId> </dependency> @SolonMain public class DemoApp { public static void main(String[] args) { Solon.start(DemoApp.class, args, app -> { app.enableWebSocket(true); // 启用 WebSocket }); } }

6.2 WebSocket 端点

@ServerEndpoint("/ws/demo/{id}") public class WebSocketDemo extends SimpleWebSocketListener { @Override public void onMessage(WebSocket socket, String text) throws IOException { socket.send("我收到了:" + text); } @Override public void onOpen(WebSocket socket) { System.out.println("连接建立:" + socket.param("id")); } }

七、Socket.D 模式

7.1 依赖配置

<dependency> <groupId>org.noear</groupId> <artifactId>solon-server-socketd</artifactId> </dependency> <!-- 按需选择传输协议包 --> <dependency> <groupId>org.noear</groupId> <artifactId>socketd-transport-netty</artifactId> </dependency>

7.2 启用 Socket.D 服务

@SolonMain public class DemoApp { public static void main(String[] args) { Solon.start(DemoApp.class, args, app -> { app.enableSocketD(true); }); } }

7.3 Socket.D 端点

@ServerEndpoint("/demo/{id}") public class SocketDDemo extends SimpleListener { @Override public void onMessage(Session session, Message message) throws IOException { session.send("test", new StringEntity("我收到了:" + message)); // session.param("id"); // 获取路径变量 } }

7.4 三种协议架构的端口分配

协议端口计算示例(server.socket.port=28080)
sd:tcp${server.socket.port}28080
sd:udp${server.socket.port} + 128081
sd:ws${server.socket.port} + 228082

7.5 Socket.D 配置项全表

server: socket: name: "waterapi.tcp" # 信号名称 port: 28080 # 信号端口 host: "0.0.0.0" # 绑定主机 wrapPort: 28080 # 包装端口(Docker + 注册时用) wrapHost: "0.0.0.0" # 包装主机 coreThreads: 0 # 最小线程(0=自动) maxThreads: 0 # 最大线程(0=自动) idleTimeout: 0 # 闲置超时(0=自动,ms) ioBound: true # IO密集型

八、Server 配置体系

8.1 四大配置系列

系列说明备注
server.?主配置供信号配置继承
server.http.?HTTP 信号配置
server.socket.?Socket 信号配置
server.websocket.?WebSocket 信号配置

8.2 配置继承关系

  • 当没有"信号配置"时,使用"主配置"
  • 例如:没有server.http.ssl时,使用server.ssl

端口默认值

信号默认端口说明
httpserver.port(默认 8080)主端口
websocket主端口 + 1500023080
socket主端口 + 2000028080

8.3 完整配置模板

solon: app: name: "demo" group: "demo" env: "dev" stop: safe: 1 delay: 10 threads: virtual: enabled: false server: port: 8080 host: "0.0.0.0" # SSL 主配置(所有信号共享) ssl: keyStore: "/data/_ca/demo.jks" keyPassword: "demo" # HTTP 信号配置 http: port: 8080 coreThreads: 0 maxThreads: 0 idleTimeout: 0 ioBound: true # WebSocket 信号配置 websocket: port: 23080 # Socket 信号配置 socket: name: "demo.tcp" port: 28080 host: "0.0.0.0" coreThreads: 0 maxThreads: 0 idleTimeout: 0 ioBound: true

九、线程数配置

9.1 配置项

server: http: coreThreads: 0 # 最小线程(0=自动) maxThreads: 0 # 最大线程(0=自动) idleTimeout: 0 # 闲置超时(ms) ioBound: true # IO密集型 # 虚拟线程池(v2.7.3+) solon: threads: virtual: enabled: false

9.2 自动计算规则

IO 密集型(ioBound: true,默认)

配置项计算公式2c4g 实例
coreThreadsCPU 内核数 × 24
maxThreadscoreThreads × 32128

CPU 密集型(ioBound: false

配置项计算公式2c4g 实例
coreThreadsCPU 内核数 × 24
maxThreadscoreThreads × 832

9.3 调优建议

  • coreThreads一般不需要配置(BIO 太大不收缩,NIO 不能太大)
  • maxThreads一般默认即可;单实例且流量大或请求慢时适当调大
  • 线程数不是越多越好(切换需要时间),也不是越少越好(会不够用)
  • Java 21+ 可考虑开启虚拟线程:solon.threads.virtual.enabled: true

十、嵌入式启动

Solon 的所有 Server 插件均支持嵌入式启动,可直接通过 Server 实现类手动控制生命周期:

// JDK HTTP Server JdkHttpServer server = new JdkHttpServer(); server.start(null, 8080); // ... 使用中 server.stop(); // Jetty Server JettyServer server = new JettyServer(); server.start(null, 8080); // Undertow Server UndertowServer server = new UndertowServer(); server.start(null, 8080); // Vert.x Server VertxServer server = new VertxServer(); server.start(null, 8080);

这种模式适合: - 将 Solon 嵌入到已有 Java 应用中 - 在单元测试中启动轻量级服务器 - 构建自定义的启动流程

十一、实战案例:三种服务同时运行

一个应用同时提供 HTTP API + WebSocket + Socket.D 三种服务:

11.1 Maven 依赖

<!-- HTTP + WebSocket (通过 Jetty) --> <dependency> <groupId>org.noear</groupId> <artifactId>solon-server-jetty</artifactId> </dependency> <dependency> <groupId>org.noear</groupId> <artifactId>solon-server-jetty-add-websocket</artifactId> </dependency> <!-- Socket.D --> <dependency> <groupId>org.noear</groupId> <artifactId>solon-server-socketd</artifactId> </dependency> <dependency> <groupId>org.noear</groupId> <artifactId>socketd-transport-netty</artifactId> </dependency> <!-- 其他基础依赖 --> <dependency> <groupId>org.noear</groupId> <artifactId>solon-web</artifactId> </dependency>

11.2 配置文件

server: port: 8080 http: port: 8080 coreThreads: 4 maxThreads: 128 websocket: port: 8080 # 与 http 共用端口 socket: name: "demo.tcp" port: 28080 coreThreads: 2 maxThreads: 64

11.3 启动类

@SolonMain public class App { public static void main(String[] args) { Solon.start(App.class, args, app -> { app.enableHttp(true); app.enableWebSocket(true); app.enableSocketD(true); }); } }

11.4 HTTP 控制器

@Controller public class ApiGateway { @Inject OrderService orderService; @Mapping("/api/order/create") public OrderDTO createOrder(@Body OrderRequest req) { return orderService.create(req); } @Mapping("/api/order/{id}") public OrderDTO getOrder(int id) { return orderService.getById(id); } }

11.5 WebSocket 端点

@ServerEndpoint("/ws/notify/{userId}") public class NotifyWebSocket extends SimpleWebSocketListener { @Override public void onOpen(WebSocket socket) { String userId = socket.param("userId"); SessionManager.register(userId, socket); } @Override public void onClose(WebSocket socket) { String userId = socket.param("userId"); SessionManager.unregister(userId); } @Override public void onMessage(WebSocket socket, String text) { // 处理客户端推送的消息 } }

11.6 Socket.D 端点

@ServerEndpoint("/sd/rpc") public class RpcSocketD extends SimpleListener { @Override public void onMessage(Session session, Message message) throws IOException { if ("order.query".equals(message.topic())) { String orderId = message.bodyAsString(); // 处理 RPC 请求 session.reply(message, new StringEntity("{\"status\":\"ok\"}")); } } }

十二、总结与选型建议

选型决策表

场景推荐 Server 插件理由
微服务 API、RESTfulsolon-server-jdkhttp0.3MB 极简,够用
需要 WebSocketsolon-server-jetty 或 solon-server-smarthttp原生 WS 支持
高性能 HTTP/2solon-server-undertow 或 solon-server-vertxHTTP/2 支持
传统 JSP 项目solon-server-tomcat + JSP 二级插件JSP 兼容
RPC 长连接solon-server-socketdSocket.D 协议
最小化部署solon-server-jdkhttp0.3MB 包大小
国产化/信创solon-server-smarthttp国产 HTTP 服务器

核心要点

  1. 业务代码与 Server 完全解耦— 只需换依赖,代码零修改
  2. 最小 0.3MB— jdkhttp 适合微服务和 Serverless
  3. 三种信号并存— HTTP + WebSocket + Socket.D 可以同一应用运行
  4. 配置继承— 信号配置缺省时自动使用主配置
  5. 线程数自适应— 根据 CPU 内核数和 IO 类型自动计算
  6. 嵌入式支持— 可以嵌入到已有 Java 应用中

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询