5.4.4 WebSocket未竟事宜
上述用例已覆盖大部分WebSocket接口测试需求,但仍有优化空间,留作读者实践:
- 异步连接创建:多线程并行创建WebSocket连接,缩短前置准备时间,使用
CountDownLatch同步任务。 - 验证结果统计:记录验证成功/失败次数,生成测试报告,提升用例精细度。
- 价格验证:校验响应中的价格字段,确保VIP用户和普通用户的价格差异正确。
- 延迟测试:记录请求发送和响应接收的时间戳,计算异步响应延迟。
- TPS模型引擎:基于事件驱动的TPS模型,替代线程模型,优化高并发场景。
这些优化点可进一步提升测试的全面性和准确性。例如,在延迟测试中,可模拟网络抖动场景,验证系统在不稳定网络下的表现。
5.4.5 Netty-WebSocket订阅测试
随着小八超市用户规模扩大,在线人数突破1万,需测试服务端推送能力,验证系统支持的订阅用户上限。Netty-WebSocket以其低资源消耗和高并发能力,成为理想选择。以下代码实现1万用户订阅商品价格和库存推送:
package org.funtester.performance.books.chapter05.section4;
import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.funtester.performance.books.chapter05.section3.NettyWebSocketClient;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
/**
* FunTester Netty-WebSocket订阅测试
*/
public class SubscribeTest {
public static void main(String[] args) throws URISyntaxException, InterruptedException {
String url = "ws://localhost:12345/websocket/FunTester"; // 服务端地址
URI uri = new URI(url);
List<ChannelPromise> promises = new ArrayList<>(); // 存储连接Promise
for (int i = 0; i < 10000; i++) {
NettyWebSocketClient client = new NettyWebSocketClient(uri); // 创建客户端
ChannelPromise connect = client.connect(); // 发起连接
promises.add(connect);
}
for (ChannelPromise promise : promises) {
promise.get(); // 等待握手完成
}
NettyWebSocketClient.channels.writeAndFlush(new TextWebSocketFrame("FunTester: 订阅蔬菜水果价格和数量频道")).sync(); // 批量发送订阅消息
System.out.println("FunTester: 订阅成功");
}
}
分析
Netty-WebSocket通过事件驱动和线程复用,支持1万连接的高效创建和消息发送。测试验证了服务端推送能力,适合评估系统在超大规模用户场景下的表现。实际场景中,可结合推送频率和消息大小,进一步压测服务端资源消耗。
5.4.6 连接保活
在海量连接订阅场景中,需通过心跳消息维持连接,防止服务端因超时剔除连接。以下分别展示Java-WebSocket和Netty-WebSocket的保活实现。
1. Java-WebSocket保活
通过异步线程定时发送ping消息,检查连接状态并利用重连机制处理异常:
package org.funtester.performance.books.chapter05.section4;
import org.funtester.performance.books.chapter05.section2.JavaWebSocketClient;
import org.java_websocket.enums.ReadyState;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
/**
* FunTester Java-WebSocket保活实践
*/
public class JavaWebSocketKeepAlive {
public static void main(String[] args) throws URISyntaxException {
String url = "ws://localhost:12345/websocket/FunTester"; // 服务端地址
URI uri = new URI(url);
List<JavaWebSocketClient> clients = new ArrayList<>(); // 存储客户端
new Thread(() -> {
while (true) {
try {
Thread.sleep(10000); // 每10秒发送心跳
for (JavaWebSocketClient client : clients) {
if (client.getReadyState() == ReadyState.OPEN) {
client.sendPing(); // 发送心跳
System.out.println("FunTester: 发送心跳");
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start(); // 启动心跳线程
for (int i = 0; i < 1000; i++) {
JavaWebSocketClient client = new JavaWebSocketClient(uri) {
@Override
public void onMessage(String s) {
// 忽略响应,仅保持连接
}
};
client.connect();
clients.add(client);
}
// 性能测试逻辑
}
}
2. Netty-WebSocket保活
利用ChannelGroup批量发送PingWebSocketFrame,简化保活逻辑:
















