从部署到Tomcat 8的Spring Boot WAR应用程序写JSON时,我在并发性方面遇到问题。在AppDynamics的屏幕快照中,当杰克逊库执行_flushBuffer时,似乎要等待很长时间。
即使是少量(<10)用户,在负载测试下也会出现此问题。
我已经在我的配置类中配置了messageConverters。
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2HttpMessageConverter(
new Jackson2ObjectMapperBuilder().dateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ")).mixIn(LiquidAssignment.class,
InventoryProviderAssignmentMixin.class)
.deserializerByType(ActionData.class, new ActionDataDeserializer()).build()));
converters.add(new MappingJackson2XmlHttpMessageConverter());
}
我正在使用 春季启动1.5.4 Java 1.8 杰克逊2.9.7 Tomcat 8.5.33
答案 0 :(得分:1)
看着UTF8JsonGenerator._flushBuffer()
的{{3}},没有LockSupport.parkNanos()
的指示。因此,OutputStream.write()
的JIT编译器可能已经内联了它。
我的猜测是-对于您的应用程序-Tomcat通常在它可以关闭连接之前,等待客户端接受所有输出(期望最后一个适合典型连接缓冲区大小的输出)。
过去,我们在处理慢速客户方面经验很差。在获取所有输出之前,它们将阻塞Tomcat中的线程。并且在Tomcat中阻塞几十个线程会严重降低繁忙的Web应用程序的吞吐量。
增加线程数量不是最佳选择,因为被阻塞的线程也占用大量内存。因此,您想要的是Tomcat可以尽快处理请求,然后继续下一个请求。
我们已经解决了这个问题,方法是配置反向代理(我们一直在Tomcat前面),以立即使用Tomcat的所有输出并将其以客户机的速度传递给客户机。反向代理在处理慢速客户端方面非常有效。
在我们的例子中,我们使用了 nginx 。我们还查看了 Apache httpd 。但是当时,它无法做到这一点。
附加说明
意外断开连接的客户端对于服务器来说也似乎是缓慢的客户端,因为它需要一些时间才能完全确定连接断开。