有时,在计划任务中时,不会将任何内容打印到 servlet 的输出流中



我需要限制与某些外部服务的连接速率(在我的servlet中),我决定尝试一下ScheduledExecutorService。调度本身似乎运行良好,但输出只是偶尔打印 - 在大多数情况下,不会输出任何内容。为什么会这样?我正在使用Tomcat 7作为测试服务器。

int waitingtimeinmilliseconds = 5000;
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture scheduledFuture = scheduledExecutorService.schedule() {
    public void run() {
        Fetcher fetcher = new Fetcher(loginname, password);
        List<Item> items = fetcher.fetchItems();
        // do something with the results
        //ServletOutputStream
        out.print("teststring" + items.size());
    }
}, waitingtimeinmilliseconds, TimeUnit.MILLISECONDS);
scheduledExecutorService.shutdown();

您将在以下位置找到对导致问题的原因的非常详尽的描述: HttpServletResponse 似乎会定期过早发送(另请检查:在 servlet 中启动一个新线程)。

基本上你不能使用外部线程来写入 servlet 输出。一旦你离开doGet()/doPost(),servlet 容器就会假设你已经完成了,并在将输出刷新到客户端后丢弃输出。但是,由于您是异步写入流的,因此有时输出会通过,而其他时候会被丢弃。

如果您希望速率限制具有很强的可扩展性,请考虑async servlet(从 3.0 开始)。如果您只想限制某些客户端,番石榴RateLimiter将为您工作1.

1 - 请参阅速率限制器 - 在我的博客上发现谷歌番石榴。