Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Vert.x多线程web套接字_Java_Vert.x - Fatal编程技术网

Java Vert.x多线程web套接字

Java Vert.x多线程web套接字,java,vert.x,Java,Vert.x,我有简单的vert.x应用程序: public class Main { public static void main(String[] args) { Vertx vertx = Vertx.vertx(new VertxOptions().setWorkerPoolSize(40).setInternalBlockingPoolSize(40)); Router router = Router.router(vertx); long main_pid = Threa

我有简单的vert.x应用程序:

public class Main {
public static void main(String[] args) {
    Vertx vertx = Vertx.vertx(new VertxOptions().setWorkerPoolSize(40).setInternalBlockingPoolSize(40));
    Router router = Router.router(vertx);
    long main_pid = Thread.currentThread().getId();
    Handler<ServerWebSocket> wsHandler = serverWebSocket -> {
        if(!serverWebSocket.path().equalsIgnoreCase("/ws")){
            serverWebSocket.reject();
        } else {
            long socket_pid = Thread.currentThread().getId();
            serverWebSocket.handler(buffer -> {
                String str = buffer.getString(0, buffer.length());
                long handler_pid = Thread.currentThread().getId();
                log.info("Got ws msg: " + str);
                String res = String.format("(req:%s)main:%d sock:%d handlr:%d", str, main_pid, socket_pid, handler_pid);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                serverWebSocket.writeFinalTextFrame(res);
            });
        }
    };
    vertx
        .createHttpServer()
        .websocketHandler(wsHandler)
        .listen(8080);
}
}
公共类主{
公共静态void main(字符串[]args){
Vertx Vertx=Vertx.Vertx(新的VertxOptions().setWorkerPoolSize(40).setInternalBlockingPoolSize(40));
路由器=路由器。路由器(vertx);
long main_pid=Thread.currentThread().getId();
Handler wsHandler=serverWebSocket->{
如果(!serverWebSocket.path().equalsIgnoreCase(“/ws”)){
serverWebSocket.reject();
}否则{
长套接字_pid=Thread.currentThread().getId();
serverWebSocket.handler(缓冲区->{
String str=buffer.getString(0,buffer.length());
long handler_pid=Thread.currentThread().getId();
log.info(“Got-ws-msg:+str”);
String res=String.format(“(请求:%s)主:%d套接字:%d句柄:%d”,str,主pid,套接字pid,处理程序pid);
试一试{
睡眠(500);
}捕捉(中断异常e){
e、 printStackTrace();
}
serverWebSocket.writeFinalTextFrame(res);
});
}
};
顶点
.createHttpServer()
.websocketHandler(wsHandler)
.听(8080);
}
}
当我将此服务器与多个客户端连接时,我看到它在一个线程中工作。但我想并行处理每个客户端连接。如何更改此代码以执行此操作?

此:

新建VertxOptions().setWorkerPoolSize(40).setInternalBlockingPoolSize(40)

看起来您正在尝试创建自己的HTTP连接池,这可能不是您真正想要的

Vert.x
和其他基于非阻塞
事件循环的框架的思想是,我们不尝试
1线程->1连接
关联,而是在请求时,当前由事件循环线程提供服务的线程正在等待IO(例如来自DB的响应),该事件循环线程将被释放以服务于另一个连接。然后,这允许单个事件循环线程以类似并发的方式为多个连接提供服务

如果您希望充分利用计算机上的所有核心,并且只运行一个
垂直卷
,则将实例数设置为部署垂直卷时的核心数

x是一个框架,这意味着它使用单线程模型来处理所有应用程序负载。此模型比线程模型具有更好的伸缩性

要知道的关键点是,放入处理程序中的所有代码必须永远不要阻塞(就像
线程.sleep
),因为它会阻塞主线程。如果您有阻塞代码(例如JDBC调用),则应将阻塞代码包装在
executingBlocking
处理程序中,例如:

serverWebSocket.handler(buffer -> {
  String str = buffer.getString(0, buffer.length());
  long handler_pid = Thread.currentThread().getId();
  log.info("Got ws msg: " + str);
  String res = String.format("(req:%s)main:%d sock:%d handlr:%d", str, main_pid, socket_pid, handler_pid);
  vertx.executeBlocking(future -> {
    try {
      Thread.sleep(500);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    serverWebSocket.writeFinalTextFrame(res);
    future.complete();
  });
});
现在,所有阻塞代码都将在线程池中的一个线程上运行,您可以对该线程池进行配置,如其他回复中所示

如果您希望避免写入所有这些执行阻塞处理程序,并且您知道需要进行多个阻塞调用,那么您应该考虑使用A,因为它们将在事件总线级别上缩放。


多线程的最后一个注意事项是,如果您使用多线程,您的服务器的效率将不如单个线程,例如,在现代机器上发生1000万线程事件后,它将无法处理1000万WebSocket(我们在2016年)将使您的操作系统调度程序屈服。

我会将其包装在一个
Verticle
中,并使用
DeploymentOptions.setInstances()
多次启动
Verticle
。我可以提供一个例子,如果这就是你想要的。谢谢你,这正是我已经做的)。只是犹豫。请考虑一下威尔的回答。您可能应该看看异步I/O。
serverWebSocket.handler(buffer -> {
  String str = buffer.getString(0, buffer.length());
  long handler_pid = Thread.currentThread().getId();
  log.info("Got ws msg: " + str);
  String res = String.format("(req:%s)main:%d sock:%d handlr:%d", str, main_pid, socket_pid, handler_pid);
  vertx.executeBlocking(future -> {
    try {
      Thread.sleep(500);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    serverWebSocket.writeFinalTextFrame(res);
    future.complete();
  });
});