Java:IOUtils.toByteArray(输入)对某些请求占用的时间太长,导致TP99.9过高
我在记录我的请求时使用以下代码片段。大多数情况下,我的请求在100毫秒内送达。但是,有时读取缓冲区的时间太长,导致TP99.9过高Java:IOUtils.toByteArray(输入)对某些请求占用的时间太长,导致TP99.9过高,java,arrays,buffer,inputstream,bufferedreader,Java,Arrays,Buffer,Inputstream,Bufferedreader,我在记录我的请求时使用以下代码片段。大多数情况下,我的请求在100毫秒内送达。但是,有时读取缓冲区的时间太长,导致TP99.9过高 final HttpServletRequest rq = (HttpServletRequest) request; final BufferedReqWrapper brq = new BufferedReqWrapper(rq); 然后在BufferedReqWrapper中 private final BufferingIPStream bis; pu
final HttpServletRequest rq = (HttpServletRequest) request;
final BufferedReqWrapper brq = new BufferedReqWrapper(rq);
然后在BufferedReqWrapper中
private final BufferingIPStream bis;
public BufferedReqWrapper(final HttpServletRequest req, final Integer maxBytesToBuffer) throws IOException
{
super(req);
bis = new BufferingIPStream(super.getInputStream());
}
在BufferingIPStream中
public BufferingIPStream(final InputStream delegate) throws IOException
{
this.delegate = delegate;
buffer = fillBuffer(delegate);
}
而fillbuffer方法是
private byte[] fillBuffer(final InputStream input) throws IOException
{
return IOUtils.toByteArray(input);
}
此代码适用于大多数请求,但有时会花费很长时间,导致延迟超过1000ms(TP99.9变高)。这是由于
InputStream
read被阻塞,这意味着当调用read
时,该方法将被阻塞(等待数据可用)。IOUtils.toByteArray将以某种方式依赖于流的read
方法 当InputStream
read被阻塞时,这意味着当您调用read
时,该方法将被阻塞(等待数据可用)。IOUtils.toByteArray将以某种方式依赖于流的read
方法 原因有很多:
字节[]
字节[]
需要大量的内存分配,最大的内存分配是请求大小的2倍。大内存分配更有可能导致(更昂贵的)旧一代收集。在最坏的情况下,过大的收集可能触发“完全”垃圾收集,这(取决于GC选择和调优)可能导致显著的暂停
最后,你不应该忽视这样一种可能性,即长时间的请求实际上是由于你的webapp中发生了其他事情。。。或者另一个过程。。。或者与您的虚拟机监控程序位于同一虚拟机监控程序上的另一个虚拟服务器
我建议:
- 记录请求大小,查看它们是否与慢速请求相关
- 记录客户端IP并查找相关性
- 打开GC日志记录并查找相关性
- 如果您有系统负载图(CPU、磁盘I/O、网络I/O),请查找相关性
利用你的观察来尝试找出问题可能是什么。(在没有任何证据的情况下猜测原因从来都不是一个好主意…原因有很多:
字节[]
字节[]
需要大量的内存分配,最大的内存分配是请求大小的2倍。大内存分配更有可能导致(更昂贵的)旧一代收集。在最坏的情况下,过大的收集可能触发“完全”垃圾收集,这(取决于GC选择和调优)可能导致显著的暂停
最后,你不应该忽视这样一种可能性,即长时间的请求实际上是由于你的webapp中发生了其他事情。。。或者另一个过程。。。或者与您的虚拟机监控程序位于同一虚拟机监控程序上的另一个虚拟服务器
我建议:
- 记录请求大小,查看它们是否与慢速请求相关
- 记录客户端IP并查找相关性
- 打开GC日志记录并查找相关性
- 如果您有系统负载图(CPU、磁盘I/O、网络I/O),请查找相关性
利用你的观察来尝试找出问题可能是什么。(在没有任何证据的情况下猜测原因从来都不是一个好主意…有没有其他方法可以快速将InputStream转换为字节数组?没有,如果数据不可用,则无法更快地读取数据。为什么在我捕获请求并将其作为参数
final HttpServletRequest rq=(HttpServletRequest)请求发送时数据不在那里代码>?当我捕获请求时,我们会在这个变量中看到数据。它与机器容量或资源有关吗?HttpServletRequest
不包含数据。数据来自使用HttpServletRequest
对象打开的流。该流从远程客户端读取数据。是否有其他方法可以加快将InputStream转换为字节数组的速度?不是真的没有,如果数据不可用,则无法加快读取速度。为什么在我捕获请求并将其作为参数发送时数据不在那里最终HttpServletRequest rq=(HttpServletRequest)请求代码>?当我捕获请求时,我们会在这个变量中看到数据。它与机器容量或资源有关吗?HttpServletRequest
不包含数据。数据来自使用HttpServletReq打开的流