EJB定时器性能

发布于 2024-11-26 17:14:26 字数 414 浏览 1 评论 0原文

我正在尝试决定是否在我的应用程序中使用 java-ee 计时器。我使用的服务器是 Weblogic 10.3.2

需求是: 从 EJB 调用异步 Web 服务一小时后,如果尚未调用异步回调方法,则需要执行一些操作行动。有关回调方法是否已被调用以及调用执行日期的信息存储在数据库中。

我看到的两种可能性是:

  1. 使用批处理过程,每半小时查找所有超过一小时没有响应的调用并执行所需的操作。
  2. 在每次调用 ws 后创建一个一小时的计时器,并在 @Timeout 方法中检查答案是否已经到来,如果没有,则执行所需的操作。

从纯粹的编程角度来看,第二个看起来更简单、更干净,但我担心如果假设在某一时刻创建了 100.000 个计时器,可能会出现性能问题。

有什么想法吗?

I am trying to decide if use a java-ee timer in my application or not. The server I am using is Weblogic 10.3.2

The need is: After one hour of a call to an async webservice from an EJB, if the async callback method has not been called it is needed to execute some actions. The information regarding if the callback method has been called and the date of the execution of the call is stored in database.

The two possibilities I see are:

  1. Using a batch process that every half hour looks for all the calls that have been more than one hour without response and execute the needed actions.
  2. Create a timer of one hour after every single call to the ws and in the @Timeout method check if the answer has come and if it has not, execute the required actions.

From a pure programming point of view, it looks easier and cleaner the second one, but I am worry of the performance issues I could have if let's say there are 100.000 Timer created at a single moment.

Any thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

终难愈 2024-12-03 17:14:26

如果您拥有更专业的流程,效果会更好。真正的问题是10万的问题。这取决于你的行动需要多长时间。

因为很容易看出,EJB 计时器每秒都会启动 30 个线程来处理所有当前待处理的作业,因为这就是它的工作原理。

此外,计时器是持久的,因此您的 EJB 管理的计时器表将每秒保存和删除 30 行(总共 60 行),假设每小时有 100K 事务。

因此,大量工作发生得非常快。我可以很容易地看到该系统只是“落后”并且永远无法赶上。

专门的进程会轻得多,也许可以对操作调用进行批处理(每个线程调用 5 个操作,而不是每个线程一个)等。如果您不必保留计时器事件,那就太好了,但这就是这是。为了安全起见,您几乎可以轻松地将计时器事件附加到文件中,并将它们保存在内存中。系统重新启动时,您可以重新加载该文件,然后滚动该文件(每小时创建一个新文件,在全部使用完后删除旧文件等)。这将节省大量数据库流量,但您可能会失去数据库的事务性质。

不管怎样,我认为您不想为此使用 EJB 计时器,我认为它并不是真正为这种流量而设计的。但你总是可以测试一下看看。确保测试重新启动容器,看看它在表中处理 100K 待处理计时器作业时效果如何。

You would be better off having a more specialized process. The real problem is the 100,000 issue. It would depend on how long your actions take.

Because its easy to see that each second, the EJB timer would fire up 30 threads to process all of the current pending jobs, since that's how it works.

Also timers are persistent, so your EJB managed timer table will be saving and deleting 30 rows per second (60 total), this is assuming 100K transactions/hour.

So, that's an lot of work happening very quickly. I can easily see the system simply "falling behind" and never catching up.

A specialized process would be much lighter weight, could perhaps batch the action calls (call 5 actions per thread instead of one per thread), etc. It would be nice if you didn't have to persist the timer events, but that is what it is. You could almost easily simply append the timer events to a file for safety, and keep them in memory. On system restart, you can reload that file, and then roll the file (every hour create a new file, delete the older file after it's all been consumed, etc.). That would save a lot of DB traffic, but you could lose the transactional nature of the DB.

Anyway, I don't think you want to use the EJB Timer for this, I don't think it's really designed for this amount of traffic. But you can always test it and see. Make sure you test restarting your container see how well it works with 100K pending timer jobs in its table.

强者自强 2024-12-03 17:14:26

一切都取决于容器使用的内容。例如,JBoss 使用 Quartz Scheduler 来实现 EJB 计时器功能。当您有大约 100 000 个计时器实例时,Quartz 就相当不错了。

All depends of what is used by the container. e.g. JBoss uses Quartz Scheduler to implement EJB timer functionality. Quartz is pretty good when you have around 100 000 timer instances.

没有心的人 2024-12-03 17:14:26

@Pau:为什么你需要为每次调用创建一个计时器......相反,你可以在应用程序启动时创建一个计时器线程,该线程每半小时(可配置)时间段运行一次,并在数据库中查找尚未收到响应且请求时间超过 1 小时的所有 Web 服务调用。对于选定的记录,在for循环中,它可以执行所需的操作。

如果您要执行时间紧迫的活动,那么上述设计可能没有用。

如果您的应用程序中有 spring 框架,您还可以查找其计时器服务。http://static.springsource.org/spring/docs/1.2.9/reference/scheduling.html

@Pau: why u need to create a timer for every call made...instead u can have a single timer thread created at start up of application which runs after every half-hour(configurable) period of time and looks in your Database for all web services calls whose response have not been received and whose requested time is past 1 hour. And for selected records, in for loop, it can execute required action.

Well above design may not be useful if you have time critical activity to be performed.

If you have spring framework in your application, you may also look up its timer services.http://static.springsource.org/spring/docs/1.2.9/reference/scheduling.html

靑春怀旧 2024-12-03 17:14:26

也许您可以使用其中一些想法:
在我这里,我们构建了一个类似 cron 的调度程序,它由单个计时器提供支持。当计时器触发时,系统会使用 Quartz CronTrigger 检查哪些 cron 需要运行。一般来说,这些 cron 有很多工作要做,我们处理的方式是每个 cron 将其单独的任务作为 JMS 消息进行分离,然后 MDB 处理这些消息。目前,它在单个 Glassfish 实例上运行,随着我们的任务负载增加,我们应该能够通过集群对其进行扩展,以便多个节点正在处理 jms 消息。我们通过在 glassfish-ejb-jar.xml(也称为 sun-ejb-jar.xml)中设置 max-pool-size 来平衡每种类型任务的 jms 消息处理负载。

构建这样的系统并确保所有细节正确并非易事,但事实证明它确实有效。

Maybe you could use some of these ideas:
Where I'm at, we've built a cron-like scheduler which is powered by a single timer. When the timer fires the system checks which crons need to run using a Quartz CronTrigger. Generally these crons have a lot of work to do, and the way we handle that is each cron spins its individual tasks off as JMS messages, then MDBs handle the messages. Currently this runs on a single Glassfish instance and as our task load increases, we should be able to scale this up with a cluster so multiple nodes are processing the jms messages. We balance the jms message processing load for each type of task by setting the max-pool-size in glassfish-ejb-jar.xml (also known as sun-ejb-jar.xml).

Building a system like this and getting all the details right isn't trivial, but it's proving really effective.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文