我有一个 Netty HTTP 服务器,用作 API 服务器。用户将事件发送到 API 服务器,然后 API 服务器使用执行器服务或 Akka 等并发框架在同一服务器中的其他线程上处理该事件。我有两种回应选择;当我将事件发送到另一个线程时,我可以等待响应并将其写入套接字,或者只是将确认消息写回套接字。
当我等待响应时,http 请求的延迟会增加,服务器可以处理的请求数量会减少。另一方面,没有对背压的控制,因此我们不知道服务器何时处理该事件,并且我无法通知用户服务器处理了该事件。但是,服务器可以处理的 http 请求数量会增加,因为几乎所有请求的延迟都非常低。
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof HttpRequest) {
executor.submit(new Event(msg));
// do not wait for the response
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, OK));
}
}
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof HttpRequest) {
Future<Object> future = executor.submit(new Event(msg));
future.after(x -> ctx.write(new DefaultFullHttpResponse(HTTP_1_1, OK)));
}
}
由于它是一个 API 服务器,因此我不必等待响应来通知用户事件已处理,因为它只是一个不返回响应的写入请求。那么对于 http 服务器来说,哪种方式最方便?您认为第二种方式的性能优势值得吗?
最佳答案
我认为答案取决于您的要求。一般来说,一个值得遵循的良好理念是让事情变得简单。这可能意味着完成所需的最少工作量,并且可能意味着留出可扩展性的空间。如果您的用例不提供状态返回是有意义的,那么您这样做的原因是什么?然而,在简单性和提供足够的系统可见性之间通常需要权衡。听起来您不确定什么是必需的,什么是不需要的?
问自己以下问题:
- 客户可以使用返回状态来做一些有意义的事情吗?如果没有这种状态,您的客户可以做什么?
- 您能否预见到客户需求将来会发生变化,要求对回复进行后期处理? (即返回状态、返回正文、错误代码等...)
- 您的服务器是否需要跟踪从获取客户端请求到将其转化为服务器上的操作的整个过程?
- 您调试问题的可见性和能力如何?
- 添加功能所需的额外复杂性和开销是多少?这可以接受吗?
这些只是在这种情况下您应该问自己的众多问题中的几个。根据您提供的信息,我不确定是否可以为您提供“您应该做 X”或“您应该做 Y”的答案。我认为重新评估您的要求并问自己一些诸如上面列出的问题对您来说是最好的选择。
关于java - 等待API服务器的响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26576386/