4

我正在开发一个 MVC spring web 应用程序,我想将用户的操作(他们点击的内容等)存储在数据库中以进行离线分析。假设一个动作是一个元组(长 userId、长 actionId、日期时间戳)。我对用户的行为并不特别感兴趣,但我以此为例。

我期望很多(不同的)用户按分钟(秒)执行很多操作。因此,处理时间至关重要。

在我当前的实现中,我定义了一个带有连接池的数据源来将操作存储在数据库中。我从控制器的请求方法调用服务,该服务调用将操作保存到数据库中的 DAO。

这种实现效率不高,因为它等待来自控制器的调用一直到数据库完成以将响应返回给用户。因此,我正在考虑将这种“动作保存”包装到一个线程中,以便对用户的响应更快。线程不需要完成即可获得响应。

我在这些大规模、并发和时间关键的应用程序方面没有经验。因此,任何反馈/评论都会非常有帮助。

现在我的问题是:

  • 你会如何设计这样的系统?你会实现一个服务,然后将它包装到一个在每个动作中调用的线程中吗?

  • 我应该使用什么?我检查了 spring Batch 和这个 JobLauncher,但我不确定它是否适合我。

  • 当控制器、服务、DAO 和数据源级别存在并发访问时会发生什么?

更一般地说,设计此类应用程序的最佳实践是什么?

感谢您的帮助!

4

4 回答 4

2

通常,在 Java EE 应用程序中生成自己的线程被认为是不好的形式。

更好的方法是通过 JMS 写入本地队列,然后有一个单独的组件,例如,一个消息驱动的 bean(使用 EJB 或 Spring 很容易)将其持久化到数据库中。

另一种方法是只写入日志文件,然后让进程读取日志文件并每天或随时写入数据库一次。

要考虑的事情是: -

  • 您需要多长时间的最新信息?
  • 信息有多重要,你会丢失一些吗?
  • 订单需要有多可靠?

所有这些都将影响您处理队列/日志文件的线程数、是否需要持久 JMS 队列以及是否应该在主容器的远程系统上进行处理。

希望这能回答你的问题。

于 2013-03-15T15:08:17.643 回答
2

如果您对用户执行的操作感兴趣,您应该能够从他们发送的 HTTP 请求中弄清楚这一点,因此您最好将传入请求记录在转发到您的应用程序服务器的 Apache 网络服务器中。将一组 Web 服务器放在应用程序服务器前面是一种典型的做法(它们很适合提供静态内容),而且它们通常都会记录请求。这样,日志记录将很快,您的应用程序将不必处理它,最大的工作将是编写一个脚本来将日志记录到可以进行分析的数据库中。

于 2013-03-15T15:21:50.197 回答
2

这是我为此所做的:

使用 aspectJ 标记我要收集的用户的所有操作。然后我使用异步 dbAppender 将其发送到 log4j ...

这使您可以使用 log4j 日志记录级别打开或关闭它。

完美运行。

于 2013-03-15T15:31:06.660 回答
2

Take a singleton object @ apps level and update it with every user action. This singleton object should have a Hashmap as generic, which should get refreshed periodically say after it reached a threshhold level of 10000 counts and save it to DB, as a spring batch.

Also, periodically, refresh it / clean it upto the last no.# of the records everytime it processed. We can also do a re-initialization of the singleton instance , weekly/ monthly. Remember, this might lead to an issue of updating the same in case, your apps is deployed into multiple JVM. So, you need to implement the clone not supported exception in singleton.

于 2013-06-24T03:37:43.963 回答