我有一个 Spring Boot 1.2.7.RELEASE Web 应用程序(嵌入了 Tomcat),它需要处理非常高的负载峰值,一台服务器上 4 到 5 分钟内大约有 10k 个连接(实际上有一个服务器集群,但这是一个节点将看到的负载)。
它真的非常非常慢。如果我用 JMeter 在 10 秒内以 1,000 个线程运行它,但只是对 Thymeleaf 登录页面发出一个简单的 GET 请求 - 没有其他 - 平均响应很快就会超过 13 秒。该页面只是一个使用 Thymeleaf 的登录表单。
这是在装有 RHEL7、32GB RAM(JVM 堆设置为使用其中的 28GB)和 4 个 CPU 核心的 VM 上运行的。这里有足够的马力,但我很难让它在负载下做出响应。
作为测试,为了减少套接字和线程的数量,我注释掉了页面中的两个 css 链接:
<HEAD>
<!-- Other meta stuff omitted -->
<!-- I commented out these next two lines -->
<link rel="stylesheet" href="css/index.css"/>
<link href="css/gridset.css" rel="stylesheet"/>
</HEAD>
当我执行完全相同的负载测试时,它的平均响应时间为 277 毫秒!如果我将其中任何一个放回原位,速度又会变得缓慢。
因此毫不夸张地说,同一项测试的响应时间从 13 秒缩短到了不到 0.3 秒。
我尝试将 css 内联,但 Spring 在尝试解析它时抛出了各种错误。W3C Validator 显示两个文件都包含许多错误。
有人正在努力纠正 css 中的错误,但我不知道导致速度缓慢的原因是什么。是因为 css 损坏了,还是因为 Tomcat 从静态区域提供服务?几天内我都没有有效的 css 可以重新测试,所以我必须尽快完成这项工作。
我用 Firebug 加载它,单一登录页面加载时间为 437 毫秒。第一个 index.css 文件加载时间为 158 毫秒,gridset.css 文件加载时间为 53 毫秒。然后是 3 张图片,总共耗时 205 毫秒。图片总大小为 19kb。
我将在下面发布一个线程转储。这是由 New Relic 生成的。
我发现了一些关于 Tomcat 提供静态内容速度很慢的信息,但我无法想象它会这么慢,而其他人说最新版本的 Tomcat 和 httpd 一样好。
我主要是一名开发人员,因此非常感谢任何能够解决这个问题的帮助,谢谢!
75% java.lang.Thread.run() :745 70% org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run() :61
70% java.util.concurrent.ThreadPoolExecutor$Worker.run() :617
70% java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor.Worker) :1127,1142
69% java.util.concurrent.ThreadPoolExecutor.getTask() :1066
69% org.apache.tomcat.util.threads.TaskQueue.poll(long, java.util.concurrent.TimeUnit) :31
69% org.apache.tomcat.util.threads.TaskQueue.poll(long, java.util.concurrent.TimeUnit) :85
69% java.util.concurrent.LinkedBlockingQueue.poll(long, java.util.concurrent.TimeUnit) :462,474,467
69% java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(long) :2069,2083,2078
69% java.util.concurrent.locks.LockSupport.parkNanos(java.lang.Object, long) :215
69% sun.misc.Unsafe.park(boolean, long) :native