目录
[1. Vert.x 是什么?](#1. Vert.x 是什么?)
[2. Vert.x vs Netty vs Spring WebFlux](#2. Vert.x vs Netty vs Spring WebFlux)
[3. Vert.x 的线程模型(非常关键)](#3. Vert.x 的线程模型(非常关键))
[4. 多任务时是否会生成新线程?](#4. 多任务时是否会生成新线程?)
[5. 实际项目中如何使用 Vert.x?](#5. 实际项目中如何使用 Vert.x?)
[6. Vert.x 实现 WebSocket 示例](#6. Vert.x 实现 WebSocket 示例)
[7. Server 如何识别 WebSocket 客户端?](#7. Server 如何识别 WebSocket 客户端?)
[8. Web 如何通知 Server 主动关闭?](#8. Web 如何通知 Server 主动关闭?)
[9. Web 建立 WebSocket 时,需要特定端口吗?](#9. Web 建立 WebSocket 时,需要特定端口吗?)
[10. /chat 是固定 URI 吗?](#10. /chat 是固定 URI 吗?)
1. Vert.x 是什么?
Vert.x 是一个 基于事件驱动、非阻塞的 JVM 异步应用框架,底层基于 Netty。
特点:
-
高并发、低延迟
-
多语言支持(Java、Kotlin、JS、Python ...)
-
Actor-like 的 Verticle 编程模型
-
天然适合 Web、网关、MQ、WebSocket、高 IO 场景
2. Vert.x vs Netty vs Spring WebFlux
| 框架 | 特点 | 场景 |
|---|---|---|
| Netty | 网络通信框架,最底层,可自定义协议、编解码 | IM、网关、RPC、自定义协议 |
| Vert.x | 基于 Netty 的高级框架,提供 HTTP、WebSocket、事件总线、Verticle | Web 服务、实时推送、高 IO |
| Spring WebFlux | Reactor 模型、适合 REST API、生态完善 | 业务系统、高吞吐 API |
关系图(文字版):
Netty(底层网络) → Vert.x(更高抽象) → WebFlux(Spring 生态)
3. Vert.x 的线程模型(非常关键)
Vert.x 使用:
-
Event Loop(事件循环线程):少量线程处理大量请求
-
Worker Pool(工作线程池):专门执行阻塞代码
特点:
-
默认 每个 CPU 一个 Event Loop 线程
-
Event Loop 不执行阻塞任务
-
阻塞任务会被丢到 Worker Pool
4. 多任务时是否会生成新线程?
不会。
Vert.x 和 WebFlux 一样:
-
使用 固定数量的事件循环线程
-
所有请求由这些线程不断调度
-
不会为每个请求新建线程
当任务包含阻塞操作(如 JDBC、文件 IO)时:
-
Vert.x 会调度到 Worker Pool
-
但 Worker Pool 也是固定大小的,不会无限创建线程
5. 实际项目中如何使用 Vert.x?
通常有 3 种方式:
直接使用 Vert.x(最多人用)
-
写
verticles -
写 HTTP Server / WebSocket / EventBus
-
完整构建异步服务
当成 Netty 的高级封装
- 在做网关、IM、推送系统时使用 Vert.x 代替直接写 Netty
和 Spring 集成(较少用)
-
使用 vertx-spring-boot-starter
-
但生态不如纯 Spring 或纯 Vert.x 清晰
6. Vert.x 实现 WebSocket 示例
java
Vertx vertx = Vertx.vertx();
HttpServer server = vertx.createHttpServer();
server.webSocketHandler(ws -> {
System.out.println("Client connected: " + ws.remoteAddress());
ws.textMessageHandler(msg -> {
ws.writeTextMessage("echo: " + msg);
});
ws.closeHandler(v -> {
System.out.println("Client closed");
});
});
server.listen(8080);
7. Server 如何识别 WebSocket 客户端?
通过连接建立时的 remoteAddress(IP + Port):
java
ws.remoteAddress(); // 客户端的IP和端口
如果前面有 Nginx:
-
Server 接收到的是 Nginx 地址
-
可通过
X-Forwarded-For获取真实客户端 IP
8. Web 如何通知 Server 主动关闭?
Web 调用:
javascript
ws.close();
Server 会触发:
java
ws.closeHandler(...)
无需特殊协议。
如果需要更明确的"手动通知",客户端也可发:
javascript
{ "type": "close" }
Server 收到后主动:
java
ws.close();
9. Web 建立 WebSocket 时,需要特定端口吗?
不需要,只要是 支持 WebSocket 的服务器地址 + 协议 即可:
javascript
const ws = new WebSocket("ws://your-server.com:8080/chat");
WebSocket 建立依赖:
-
协议:
ws://或wss:// -
地址:域名 / IP
-
端口:与 HTTP Server 一样(无强制要求)
-
请求头自动包含
Upgrade: websocket
10. /chat 是固定 URI 吗?
不是。
WebSocket 的 URI 完全由你自定义:
-
/ws -
/chat -
/stream -
/game/room -
/message/push
只要 Server 监听即可。
例如:
java
server.webSocketHandler(ws -> {
if (ws.path().equals("/chat")) {
...
}
});