gpt4 book ai didi

Java HttpsServer 多线程

转载 作者:可可西里 更新时间:2023-11-01 16:40:37 24 4
gpt4 key购买 nike

我已经用 Java 设置了一个 HttpsServer。我所有的沟通都完美无缺。我设置多个上下文,加载自签名证书,甚至基于外部配置文件启动。

我现在的问题是让多个客户端能够访问我的安全服务器。为此,我想以某种方式对来自 HttpsServer 的请求进行多线程处理,但不知道该怎么做。下面是我的基本 HttpsConfiguration。

  HttpsServer server = HttpsServer.create(new InetSocketAddress(secureConnection.getPort()), 0);
SSLContext sslContext = SSLContext.getInstance("TLS");

sslContext.init(secureConnection.getKeyManager().getKeyManagers(), secureConnection.getTrustManager().getTrustManagers(), null);

server.setHttpsConfigurator(new SecureServerConfiguration(sslContext));
server.createContext("/", new RootHandler());
server.createContext("/test", new TestHandler());
server.setExecutor(Executors.newCachedThreadPool());
server.start();

其中 secureConnection 是包含服务器设置和证书信息的自定义类。

我试图将执行器设置为 Executors.newCachedThreadPool() 和其他几个。然而,它们都产生了相同的结果。每个线程管理线程的方式不同,但第一个请求必须在第二个请求处理之前完成。

我也试过自己写Executor

public class AsyncExecutor extends ThreadPoolExecutor implements Executor
{
public static Executor create()
{
return new AsyncExecutor();
}

public AsyncExecutor()
{
super(5, 10, 10000, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(12));
}

@Override
public void execute(Runnable process)
{
System.out.println("New Process");

Thread newProcess = new Thread(process);
newProcess.setDaemon(false);

newProcess.start();

System.out.println("Thread created");
}
}

不幸的是,结果与其他执行者相同。

为了测试,我使用 Postman 来命中/Test 端点,该端点通过执行 Thread.sleep(10000) 来模拟长时间运行的任务。在运行时,我正在使用我的 Chrome 浏览器访问根端点。在 10 秒 sleep 结束之前,根页面不会加载。

关于如何处理对 HTTPS 服务器的多个并发请求有什么想法吗?

为了便于测试,我使用标准 HttpServer 复制了我的场景,并将所有内容压缩到一个 java 程序中。

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class Example
{
private final static int PORT = 80;
private final static int BACKLOG = 10;

/**
* To test hit:
* <p><b>http://localhost/test</b></p>
* <p>This will hit the endoint with the thread sleep<br>
* Then hit:</p>
* <p><b>http://localhost</b></p>
* <p>I would expect this to come back right away. However, it does not come back until the
* first request finishes. This can be tested with only a basic browser.</p>
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception
{
new Example().start();
}

private void start() throws Exception
{
HttpServer server = HttpServer.create(new InetSocketAddress(PORT), BACKLOG);

server.createContext("/", new RootHandler());
server.createContext("/test", new TestHandler());
server.setExecutor(Executors.newCachedThreadPool());
server.start();

System.out.println("Server Started on " + PORT);
}

class RootHandler implements HttpHandler
{
@Override
public void handle(HttpExchange httpExchange) throws IOException
{
String body = "<html>Hello World</html>";

httpExchange.sendResponseHeaders(200, body.length());
OutputStream outputStream = httpExchange.getResponseBody();

outputStream.write(body.getBytes("UTF-8"));
outputStream.close();
}
}

class TestHandler implements HttpHandler
{
@Override
public void handle(HttpExchange httpExchange) throws IOException
{
try
{
Thread.sleep(10000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}

String body = "<html>Test Handled</html>";

httpExchange.sendResponseHeaders(200, body.length());
OutputStream outputStream = httpExchange.getResponseBody();

outputStream.write(body.getBytes("UTF-8"));
outputStream.close();
}
}
}

最佳答案

TL;DR:没关系,用两个不同的浏览器,或者专门的工具测试一下就可以了。

您的原始实现没问题,并且按预期工作,不需要自定义执行器。对于每个请求,它都执行“共享”处理程序类实例的方法。它总是从池中获取空闲线程,因此每个方法调用都在不同的线程中执行。

问题似乎是,当您使用同一浏览器的多个窗口来测试此行为时...出于某种原因,请求以序列化方式执行(一次只有一个)。使用最新的 Firefox、Chrome、Edge 和 Postman 进行测试。 Edge 和 Postman 按预期工作。 Firefox 和 Chrome 的匿名模式也有帮助。

同时从两个 Chrome 窗口打开相同的本地 URL。首先页面在 5 秒后加载,我得到了 Thread.sleep(5000) 所以没关系。第二个窗口在 8,71 秒内加载响应,因此有 3,71 秒的不明原因延迟。

Chrome windows 1 Chrome windows 2

我猜?可能是某些浏览器内部优化或故障安全机制。

关于Java HttpsServer 多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43269178/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com