我正在构建一个通知系统,该系统允许客户端连接到Web服务器,然后通过服务器端事件得到通知。我目前将Wildfly 16.0独立版(在Windows上)用作Web服务器。我在服务器端事件中使用下面的示例代码。
@GET
@Path("register")
@Produces("text/event-stream")
public void subscribe(@Context SseEventSink sseEventSink,
@HeaderParam(HttpHeaders.LAST_EVENT_ID_HEADER)) {
while (true) {
OutboundSseEvent sseEvent = this.eventBuilder
.data("some data")
.reconnectDelay(3000)
.build();
CompletionStage<?> cs = sseEventSink.send(sseEvent);
cs.whenComplete((x, y) -> {
System.out.println("Completed " + x);
if (y != null) y.printStackTrace();
});
Thread.sleep(5 * 1000);
}
sseEventSink.close();
}
此解决方案可在不建立新连接的情况下,以最少的服务器负载为最多120个已连接的客户端工作。
我使用ApacheBench 2.3版进行测试。
ab -A 123:123 -c 120 -n 120 http://127.0.0.1:8080/
如果我的并发连接数超过120,则没有其他人可以连接。在我看来,这是一个活动的连接,流或线程限制。如果一个用户断开连接,则另一个用户可以连接。我试图在standalone.xml中的http-listener上设置最大连接数。这没有效果。我不只是简单地在可以找到的每个连接/线程/池选项中添加零。仍然没有变化。
下一步去哪里?
答案 0 :(得分:1)
我认为您没有遇到连接限制问题,但是wildfly用完了I / O线程。如果您运行的是8核CPU,它将与您提到的约120个并发客户端相匹配:来自https://wildscribe.github.io/WildFly/18.0/subsystem/io/worker/index.html#attr-task-max-threads
指定辅助任务线程池的最大线程数。如果未设置,则使用默认值,该默认值由公式cpuCount * 16
计算
使用jboss-cli.sh增加值:
<button class="Button"><span>hover me</span></button>
或者在standalone.xml中:
/subsystem=io/worker=default:write-attribute(name=task-max-threads, value=1024)
答案 1 :(得分:0)
您可以将max-connections
个连接属性添加到http-listner
标记中。例如
<http-listener name="default" max-connections="1000" socket-binding="http" redirect-socket="https" enable-http2="true"/>
以此,您将能够增加最大连接数。
答案 2 :(得分:0)
我相信您用尽了连接,因为您的subscribe
方法永远不会因为该while (true) { ... }
循环而返回。
以下对我有用:
@Singleton
@Path("")
public class BroadcastService {
@Context
private Sse sse;
private SseBroadcaster broadcaster;
@PostConstruct
void initialise() {
this.broadcaster = sse.newBroadcaster();
}
@PreDestroy
void shutdown() {
this.broadcaster.close();
}
@GET
@Path("register")
@Produces(MediaType.SERVER_SENT_EVENTS)
public void subscribe(@Context SseEventSink sseEventSink) {
this.broadcaster.register(sseEventSink);
}
@Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
public void broadcastData() {
OutboundSseEvent sseEvent = this.sse.newEventBuilder()
.data("some data")
.reconnectDelay(3000)
.build();
this.broadcaster.broadcast(sseEvent);
}
}
我测试过:
ab -c 2000 -n 4000 http://127.0.0.1:8080/sse-demo/register
并且仍然能够:
curl http://127.0.0.1:8080/sse-demo/register
retry: 3000
data: some data
retry: 3000
data: some data