与 http 请求相比,一劳永逸
Posted
技术标签:
【中文标题】与 http 请求相比,一劳永逸【英文标题】:fire and forget compared to http request 【发布时间】:2010-03-28 05:20:53 【问题描述】:我正在征求大家的意见。我有一个需要将数据记录到另一个 Web 应用程序数据库中的 Web 应用程序。由于延迟问题,我不喜欢在第二个应用程序上使用 HTTP 请求 GET。我正在寻找快速保存第二个应用程序记录的快速方法,我遇到了“一劳永逸”的想法,JMS 是否适合这种情况?据我了解,JMS 会保证消息传递,保证消息是否 100% 传递并不重要,只要可以服务尽可能多的请求即可。假设我需要向第二个应用程序调用每秒至少 1000 个随机请求,我应该使用 JMS 吗? HTTP 请求?还是 XMPP?
【问题讨论】:
我认为您的意思是 JMS,而不是 JMX(因为您说的是“一劳永逸”、消息传递、ActiveMQ),我已经相应地更新了问题。 你怎么看?哪种方法更便宜? 【参考方案1】:我认为您总体上误解了网络。绝对没有理由 HTTP GET 必须比其他任何东西都慢,如果 HTTP 利用保持活动,它会比大多数选项更快。
JMX 不是一种协议,它是一种包含许多其他协议的规范,可能包括 HTTP 或 XMPP。
最后,在 Java 将运行的级别上,有 UDP 或 TCP。 TCP 通过保证交付(通过重传)和排序具有更多开销。 UDP 既不提供保证交付也不提供按顺序交付。如果你能处理 UDP 的限制,你会发现它“更快”,如果你不能,那么任何轻量级 TCP 包装器(HTTP 就是其中之一)都差不多。
【讨论】:
我的问题是当我在服务器端启用 keeplive 时。我是否需要专门更改客户端的编程以使用此功能(打开/关闭 HttpConnection.GET)? 我认为 OP 是指 JMS,而不是 JMX @pascal,你是对的,尽管我坚持我的分析。无论您是发送 TCP 还是 UDP,这是唯一能产生影响的决定。在 TCP 或 UDP 中,您会根据配置获得所有相同的行为。 @cometta Java 默认情况下在客户端启用了keepalives,并且您将使用的大多数服务器解决方案也是如此,因此您可能不需要做任何事情。您可以使用类似 wireshark/ethereal 的方法来验证这一点,您会注意到多个请求/响应对通过同一个 TCP 套接字。我确实认为 Java 的默认行为曾经是仅对 N 个请求/响应对重用 TCP 连接,其中 N 大约为 10,但可以通过属性进行调整。【参考方案2】:您的要求似乎是:
一个客户端和一个服务器(从您的第一句话推断), HTTP 是强制性的(从您谈论的 Web 应用程序 数据库推断), 每秒更新 1000 条或更多记录,并且 个别更新不需要同步确认(您愿意使用“一劳永逸”的方法。我的解决方法是让客户端线程在内部对更新进行排队,并实现一个客户端线程,该线程定期将排队的更新组合成一个 HTTP 请求并将其发送到服务器。如有必要,服务器可以发送响应以指示各个更新的状态。
批处理消除了延迟对客户端的影响,并有可能使服务器更有效地处理更新。
【讨论】:
【参考方案3】:HTTP 和 JMS 或 XMPP 之间的最大区别在于,JMS 和 XMPP 允许 异步 触发并忘记消息传递(客户端并不真正知道消息何时以及是否会到达其目的地,并且不知道期待接收者的响应或确认)。这将允许第一个应用程序快速响应,而不管第二个应用程序处理时间如何。
对于消息消费者比生产者慢的大容量分布式消息传递,异步消息传递通常是首选。我不能说这是否正是你的情况。
【讨论】:
我同意你的看法。但从其他 cmets 来看,http.get keepalive 更快? 我的情况和你描述的一样。多个生产者,一个慢消费者(较慢) @cometta 我想阅读@Stephen 和@Ry4an 对此的看法,但是 1. 对于 HTTP,客户端将不得不等到处理结束。 2. 如果处理时间远大于“网络”时间,那么后者并不重要 3. JMS 实现可能使用 UDP。【参考方案4】:如果您有完全控制权并且两个 Web 应用程序在同一个 Web 容器中运行,因此在同一个 JVM 中,我建议使用 JNDI 来允许两个 Web 应用程序访问一个公共数据结构(列表?)允许并发修改,即允许应用程序A添加新条目,而应用程序B同时使用最旧的条目。
这很可能是最快的方式。
请注意,您应该将列表中的信息保留在 JRE 中找到的类中,否则您很可能会遇到类转换异常。这些可以规避,但最简单的方法很可能只是在通用数据结构中传输字符串。
【讨论】:
在不同的 jvm 中。所以我不能这样做。 如果是这样,那么您将需要一些进程间连接。 http 很可能是最不复杂的。您可以考虑使用适合每秒大量连接的 servlet 容器,或者考虑像其他人建议的那样捆绑传输。以上是关于与 http 请求相比,一劳永逸的主要内容,如果未能解决你的问题,请参考以下文章
Spring 4.x/3.x (Web MVC) REST API 和 JSON2 Post 请求,如何一劳永逸?