Java 发送大量POST请求

Java 发送大量POST请求,java,multithreading,performance,jakarta-ee,servlets,Java,Multithreading,Performance,Jakarta Ee,Servlets,在这种情况下,我将接收多个请求,处理来自请求的数据,然后使用POST将数据转发到另一台服务器。可能有数千个请求同时发送到服务器。我以前从未处理过这种音量,所以我不得不对如何继续进行进行某种(有教育意义的)猜测 我使用的是JAVEE应用服务器,数据通过org.apache.client.HttpClient作为POST请求进行转发。每个数据包都相对较小(每个数据包50-100kb),这是我当前的策略: 当一个请求传入时,我立即生成一个新线程来处理和发送数据(每个请求一个线程)。我使用java.ut

在这种情况下,我将接收多个请求,处理来自请求的数据,然后使用POST将数据转发到另一台服务器。可能有数千个请求同时发送到服务器。我以前从未处理过这种音量,所以我不得不对如何继续进行进行某种(有教育意义的)猜测

我使用的是JAVEE应用服务器,数据通过org.apache.client.HttpClient作为POST请求进行转发。每个数据包都相对较小(每个数据包50-100kb),这是我当前的策略:

当一个请求传入时,我立即生成一个新线程来处理和发送数据(每个请求一个线程)。我使用java.util.concurrent.ThreadPoolExecutor和java.util.concurrent.ArrayBlockingQueue来控制线程和队列。如果正在使用线程池中的所有线程,则传入数据将排队。如果队列已满,则会删除数据(我完全同意)。我正在使用org.apache.client.HttpClient关注关于线程的文档,因此所有线程都共享HttpClient对象,并且在每个请求上只创建HttpPost对象

我知道,在我自己对其进行基准测试之前,我不会完全了解我的实现的含义,但我想知道在达到这一程度之前是否存在任何危险信号。为了明确我的实际问题是什么:

  • 我的方法有危险信号吗?(我做错了任何明显的事情,可能会导致严重的性能损失,因为我对这方面还比较陌生)

  • 给每一个数据包分配它自己的数据包是不明智的吗 自己的线程知道将有数千个?(线 但是,计数将由线程池限制)

  • 将传入的请求排队并为每个线程发送多个数据包,而不是为每个线程发送一个数据包,这会更聪明吗


您是否在web servlet容器中运行

一般来说,大多数开发人员对异步处理和线程的了解比构建当今最受欢迎的web服务器的团队要少(tomcat、jetty、甚至glassfish都非常好),因此对我来说,您的方法的唯一问题是您自己实现线程

如果您接收的请求是通过HTTP发生的,那么我将研究Servlet3.0的异步功能,它允许在等待POST响应时正确管理HTTP请求而不阻塞。上有一篇很好的java世界文章

如果您的请求不是来自HTTP(即JMS或其他),那么队列和执行模式是好的,前提是您确保使用线程安全和性能良好的对象(即ConcurrentHashMap)

对于您所做的文章,同样对于HTTPClient,异步执行器非常有用——描述了如何执行


玩得开心

数据包处理需要多长时间?对于这种应用程序,我会使用嵌入式ActiveMQ服务器。我没有实际测量处理,但它似乎相对较小(执行JSON.parse,添加数据,然后转换为要发送的字符串)。与实际出站请求相比,可忽略不计。感谢您的建议。是的,我在一个容器中运行,需要澄清的是,容器正在处理传入请求的线程。然后,这些请求被转发到线程安全类,该类将生成新的线程。到目前为止,我们的来客流量还不错。我们关心的是新的线程和出站流量。需要注意的一点是,在出站呼叫中,帖子的开放时间有多长。如果停止响应,客户端线程可以保持挂起状态,直到超时为止(从内存来看,对于commons HTTP客户端,默认为5分钟)。从我过去看到的情况来看,大多数请求都可以在短时间内得到服务,即<5秒,大约10-20%在5秒和30秒之间,差距很大,然后在60秒、120秒和180秒左右得到响应。这些挂起的请求可能会引起很多麻烦哦,实际上,请评论上面的问题2和问题3:#2-是的,线程是昂贵的,正如@Richard-W提到的,带有消息驱动bean池的ActiveMQ队列可以很好地解决这一问题。您可以将入站请求发布到队列中,并让mdb在队列中搜索,前提是您不需要对原始入站请求提供响应,而只需要“我收到了您的消息”之类的响应