如何防止Spring Boot Tomcat Jackson中并发锁定flushBuffer? [英] How to prevent concurrency lock on flushBuffer in Spring Boot Tomcat Jackson?

查看:91
本文介绍了如何防止Spring Boot Tomcat Jackson中并发锁定flushBuffer?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从部署到Tomcat 8的Spring Boot WAR应用程序写出JSON时,我在并发性方面遇到问题.在AppDynamics的屏幕截图中,当杰克逊库执行_flushBuffer时,似乎有相当大的等待时间.

I am having issues with concurrency when writing JSON out from my Spring Boot WAR app deployed to Tomcat 8. In the screenshot from AppDynamics there seems to be a considerable wait when the jackson library is performing _flushBuffer.

即使是少量(<10)用户,在负载测试下也会出现此问题.

This issue arises under load testing for even a small amount (< 10) users.

我已经在我的配置类中配置了messageConverters.

I have configured the messageConverters in my configuration class.

    @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

I am using Spring Boot 1.5.4 Java 1.8 Jackson 2.9.7 Tomcat 8.5.33

推荐答案

查看

Looking at the source code of UTF8JsonGenerator._flushBuffer(), there is no indication of LockSupport.parkNanos(). So it has probably been inlined by the JIT compiler from OutputStream.write().

我的猜测是-对于您的应用程序-Tomcat通常在它可以关闭连接之前,等待客户端接受所有输出(期望最后一个适合典型连接缓冲区大小的输出).

My guess is it's the place where – for your application – Tomcat typically waits until the client has accepted all the output (expect for the last piece that fits into the typical connection buffer size) before it can close the connection.

过去,我们在处理慢速客户方面经验很差.在获取所有输出之前,它们将阻塞Tomcat中的线程.并且在Tomcat中阻塞几十个线程会严重降低繁忙的Web应用程序的吞吐量.

We have had bad experience with slow clients in the past. Until they have retrieved all the output, they block a thread in Tomcat. And blocking a few dozens threads in Tomcat seriously reduces the throughput of a busy web app.

增加线程数量不是最佳选择,因为被阻塞的线程也占用大量内存.因此,您想要的是Tomcat可以尽快处理请求,然后继续处理下一个请求.

Increasing the number of threads isn't the best option as the blocked threads also occupy a considerable amount of memory. So what you want is that Tomcat can handle a request as quickly as possible and then move on to the next request.

我们已经解决了该问题,方法是配置反向代理(该代理一直在Tomcat之前),以立即使用Tomcat的所有输出并将其以客户机的速度传递给客户机.反向代理在处理速度较慢的客户端方面非常有效.

We have solved the problem by configuring our reverse proxy, which we always had in front of Tomcat, to immediately consume all output from Tomcat and deliver it to the client at the client's speed. The reverse proxy is very efficient at handling slow clients.

在我们的例子中,我们使用了 nginx .我们还查看了 Apache httpd .但是当时,它无法做到这一点.

In our case, we have used nginx. We also looked at Apache httpd. But at the time, it wasn't capable of doing it.

附加说明

意外断开连接的客户端对于服务器来说也像是缓慢的客户端,因为它需要一些时间才能完全确定连接断开.

Clients that unexpectedly disconnect also look like slow clients to the server as it takes some time until it has been fully established that the connection is broken.

这篇关于如何防止Spring Boot Tomcat Jackson中并发锁定flushBuffer?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆