相关疑难解决方法(0)

Servlet-3异步上下文,如何进行异步写操作?

问题描述

Servlet-3.0 API允许分离请求/响应上下文并在以后回复它.

但是,如果我尝试编写大量数据,例如:

AsyncContext ac = getWaitingContext() ;
ServletOutputStream out = ac.getResponse().getOutputStream();
out.print(some_big_data);
out.flush()
Run Code Online (Sandbox Code Playgroud)

对于Tomcat 7和Jetty 8,它实际上可能会阻塞 - 并且它确实阻塞了琐碎的测试用例.教程建议创建一个可以处理这种设置的线程池 - 这通常是对传统10K架构的反作用.

但是,如果我有10,000个打开的连接和一个让我们说10个线程的线程池,那么即使1%的具有低速连接或仅阻塞连接的客户端阻塞线程池并完全阻止彗星响应或减慢其速度也足够了显著.

预期的做法是获得"写就绪"通知或I/O完成通知,而不是继续推送数据.

如何使用Servlet-3.0 API完成,即如何获得:

  • I/O操作的异步完成通知.
  • 通过写入就绪通知获取非阻塞I/O.

如果Servlet-3.0 API不支持,那么是否有任何特定于Web Server的API(如Jetty Continuation或Tomcat CometEvent)允许真正异步处理此类事件而无需使用线程池伪造异步I/O.

有人知道吗?

如果这不可能,您可以参考文档确认吗?

示例代码中的问题演示

我附上了模拟事件流的代码.

笔记:

  • 它使用ServletOutputStream该抛出IOException来检测断开连接的客户端
  • 它发送keep-alive消息以确保客户端仍在那里
  • 我创建了一个线程池来"模拟"异步操作.

在这样的例子中,我明确定义了大小为1的线程池来显示问题:

  • 启动一个应用程序
  • 从两个终端运行curl http://localhost:8080/path/to/app(两次)
  • 现在发送数据 curd -d m=message http://localhost:8080/path/to/app
  • 两个客户都收到了数据
  • 现在暂停其中一个客户端(Ctrl + Z)并再次发送消息 curd -d m=message http://localhost:8080/path/to/app
  • 观察到另一个非挂起的客户端没有收到任何信息,或者在传输消息后停止接收保持活动请求,因为其他线程被阻止.

我想在不使用线程池的情况下解决这样的问题,因为使用1000-5000个开放连接,我可以非常快地耗尽线程池.

下面的示例代码.


import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import …
Run Code Online (Sandbox Code Playgroud)

java comet servlet-3.0

50
推荐指数
2
解决办法
3万
查看次数

在ServletOutputStream中写入字节时断管

执行此代码时,

ServletOutputStream out = response.getOutputStream();
out.write(bytes, 0, bytes.length);
out.flush();  
out.close();  
Run Code Online (Sandbox Code Playgroud)

我经常得到这个例外,我无法弄清楚它为什么会发生.

Caused by: ClientAbortException:  java.net.SocketException: Broken pipe
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:358)
    at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:354)
    at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:381)
    at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:370)
    at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:89)
Run Code Online (Sandbox Code Playgroud)

我有一个在Linux服务器上运行的Web应用程序,在JBoss 4.2.3和MySQL下运行.

这是怎么造成的,我该如何解决?

java jboss servlets

13
推荐指数
1
解决办法
5万
查看次数

检测tomcat servlet中的客户端断开连接?

如何检测tomcat servlet请求的客户端是否已断开连接?我已经读过我应该做一个response.getOutputStream().print(),然后是一个response.getOutputStream().flush()并捕获一个IOException,但有没有办法可以检测到这个而不写任何数据?

编辑:

servlet发出的数据流不一定会结束,但不一定有任何数据流通过它(它是一个实时事件流).我需要实际检测客户端何时断开连接,因为我需要进行一些清理工作(要释放的资源,等等).如果我有可用的HttpServletRequest,如果客户端断开连接,是否会尝试从中读取抛出IOException?

java tomcat servlets

9
推荐指数
2
解决办法
9117
查看次数

标签 统计

java ×3

servlets ×2

comet ×1

jboss ×1

servlet-3.0 ×1

tomcat ×1