在具有单个 HTTP 请求的 servlet 线程上运行长时间运行的进程是否总是不好? [英] Is running a long-running-process always bad on a servlet thread having a single HTTP request?
问题描述
我有一个 Java 应用程序(在 WAS 8.5 上运行),它充当客户端的一种服务器清单.该应用程序有一个 servlet,可触发长时间运行的进程.
I have a Java application (running on WAS 8.5) which acts as a kind of server inventory for the client. The application has a servlet that triggers a long running process.
过程:从第三方数据库获取数据,执行 Java 逻辑,将记录写回应用程序自己的数据库(这些数据库连接是池连接).
The process: fetches data from a third party DB, executes Java logic, writes records back to the application's own DB (these DB connections are pooled ones) .
servlet 不是在启动时加载,并且仅由单个操作人员每月手动触发一次(根据客户每月的选择在某个特定日期).servlet 过去一直以这种方式使用 Timer 和 TimerTask:
The servlet is not load-on-startup and is manually triggered only once a month by a single Operations guy (on some particular date based on the client's choice each month). The servlet had been historically using Timer and TimerTask in this way:
public class SyncMissingServlet extends HttpServlet implements Servlet{
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
try{
SyncMissing.runSync();
}catch(Exception ex){
logger.error(new LogMessage("ERROR: "), ex);
this.sendReply(printWriter, "ERROR: " + ex.toString());
}
}
}
public class SyncMissing
{
public static void runSync() throws Exception
{
Timer t = new Timer(true);
SyncMissingTask task = new SyncMissingTask(); //SyncMissingTask is an instance of TimerTask
// Start the synchronization 5 secs from now, and run it every 30 days.
t.schedule(task, 5000, 2592000000l); //this 30 day timings never really worked out for the client,
//since the app server is restarted frequently for deployments.
}
}
当前代码中没有使用 Timer.close() 或 TimerTask.close() .最近,在系统重新启动并重新启动系统上的 WAS 服务后,此 Servlet 似乎已自动触发……这就是问题所在.
There is no use of Timer.close() or TimerTask.close() in the current code. Recently this Servlet seems to have got auto-trigerred, after a system reboot and restart of the WAS services on the system...and that's the worry.
虽然我无法向客户解释自动触发,但我提出了以下选项:
1. 停止使用 Timer 和 TimerTask(长时间运行的进程然后在 servlet 的线程本身上运行)
2. 将 TimerTask 改为常规 Runnable 并在 servlet 线程内的单独线程中运行.
3.利用Java的Executor Service
4. 迁移到 Servlet 3.0 并将 servlet 变成异步 servlet.
5. 完全删除 servlet,并用批处理作业替换它.
While I couldn't explain the auto-trigger to my client, I proposed the following options:
1. drop off the use of Timer and TimerTask (the long-running process then runs on the servlet's thread itself)
2. instead of TimerTask, make it a regular Runnable and run it in a separate thread within the servlet thread.
3. make use of Java's Executor Service
4. migrate to Servlet 3.0 and turn the servlet into a Async servlet.
5. drop off the servlet altogether, and replace it with a batch job.
我知道选项 3 和 4 确实是推荐的选项(或者可能是选项 5).但我有一种感觉,在我的业务场景中 - 选项 3 &4 可能有点矫枉过正.
I understand that options 3 and 4 are really the recommended ones (or possibly option 5). But I have a feeling, that in my business scenario - Options 3 & 4 may be an overkill.
如果确实需要每月只有一个用户手动调用 servlet,那么选项 1 和选项 2 是否很糟糕?(我的客户想要最快的解决方案,当然不会资助选项 5)
If the need is really a manual invocation of the servlet by only one user per month, are options 1 and 2 that bad? (my client wants the quickest solution and would certainly not fund option 5)
推荐答案
好吧,如果 servlet 应该一个月只运行一次,并且只有一个客户端触发它,那么在 servlet 的线程本身或在 servlet 内创建一个新线程并让它完成任务.当您有很多客户端同时发出请求时,就会出现加载和响应时间的问题,此时您可能想要使用 Executor 服务或异步 servlet.
Well, if the servlet is supposed to be run only once in a month and there is only one client triggering it, it is fine to run it in the servlet's thread itself or create a new thread inside the servlet and let that do the task. The question of load and response times arises when you have a lot of clients making simultaneous requests, at which point you might want to use an Executor service or an async servlet.
这篇关于在具有单个 HTTP 请求的 servlet 线程上运行长时间运行的进程是否总是不好?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!