繁体   English   中英

记录从Servlet到数据库的请求的最佳方法?

[英]Best way to log requests from a servlet and to a database?

我正在提供一个Servletful服务(在Tomcat 7.0.X和Ubuntu Linux内部运行)提供的RESTful服务。 我已经每小时收到约2万条查询,并且它将增长得更高。 Servlet接收请求,准备响应,在MySQL数据库表中插入一条记录并传递响应。 数据库中的日志是绝对必需的。 直到最近,所有这些都是以同步的方式发生的。 我的意思是,在Tomcat线程传递响应之前,它必须在数据库表中创建记录。 问题在于该日志过去占用了总时间的90%以上,甚至更糟:当数据库变慢时,该服务花费了大约10-15秒而不是仅仅20毫秒。

我已经作了一个改进:每个Tomcat线程都创建了一个额外的线程,执行“(new Thread(new new Object))。start();”。 它以异步方式处理SQL插入,因此响应可以更快地到达客户端。 但是,当MySQL运行速度较慢且线程数量增加时,这些线程会占用过多的RAM,而数千个JVM Tomcat的内存将由这些线程占用。

我需要的是能够接受尽可能多的HTTP请求,以尽可能快的速度记录每个请求(而不是同步记录),并在MySQL变慢并插入时使所有事情都快速且RAM的使用率非常低需要排队。 我认为当http请求的速度高于数据库日志中插入的速度时,我需要某种队列来缓冲条目。

我正在考虑以下想法:

1-自己创建某种FIFO队列,也许使用其中一些Apache Commons集合,以及某种轮询该集合并创建数据库记录的线程。 但是我应该使用什么收藏呢? 我应该如何对轮询它的线程进行编程,以免它独占CPU? 我认为“ Do while(true)....”会占用CPU周期。 那关于使其成为线程安全的呢? 怎么做? 我认为自己动手做起来太费力了,很可能我会重新发明轮子。

2- log4J? 我从未直接使用过它,但是似乎该框架是根据算法设计的,用于创建与数据库对话的“追加程序”。 那是这样做的方式吗?

3-是否使用其他专门从事此工作的框架?

你有什么建议?

提前致谢!

马上想到的就是您所说的队列。 您可以使用ActiveMQ http://activemq.apache.org/或RabbitMQ http://www.rabbitmq.com/之类的东西。

这个想法只是开火而忘记。 发送消息应该几乎没有开销。

然后,您可以连接一些“脱机”以从队列中提取消息,并以所需的速度将其写入数据库。

我觉得我整天都在Stack Overflow上插电,但是我们在工作中使用了Mule(http://www.mulesoft.org/)。 Mule的一大优点是,您可以显式设置从队列读取的线程数和写入数据库的线程数。 它使您可以对节流消息进行精细控制。

绝对看看使用ThreadPoolExecutor。 您可以提供线程池的大小,它将为您处理所有并发和排队。 唯一可能的问题是,如果JVM由于任何原因崩溃,您将丢失池中所有排队的项目。

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html

我当然也会尽可能地优化MySQL数据库。 每小时20k条目可以很快变得多毛。 硬件,操作系统和索引的优化越好,插入越快,队列就越小。

首先:非常感谢您的宝贵建议!

到目前为止,我已经找到了满足我需求的部分解决方案,并且已经成功实现了它:

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html

现在,我正在考虑使用队列提供程序(如果已满)作为故障转移解决方案。 到目前为止,我已经考虑过亚马逊的队列服务,但这要花钱。 我还将检查Ryan建议的队列解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM