我在生产中使用scala-play app。几天后我发现,由于数据库端的高CPU,播放应用程序开始起作用,响应时间增加到几分钟。 Play应用程序部署在3个EC2实例上,所有这些实例都附加到ELB。在此期间,两个进程无响应,响应时间上升至600分钟(通常响应时间低于200毫秒)。由于两个进程的响应时间很长,ELB将它们标记为不健康,并且所有请求都被路由到单个进程(响应时间为20秒)。通过日志并没有多大帮助。在探讨了一些文章之后,我明白线程池中的死锁可能是其中一个原因。我们使用线程池来阻止S3调用和非阻塞数据库调用。不同的线程池用于这些目的。
executor { sync = { fork-join-executor { parallelism-factor = 1.0 parallelism-max = 24 } } async = { fork-join-executor { parallelism-factor = 1.0 parallelism-max = 24 } } }
任何人都可以帮助理解可能出错的地方吗?所有3个节点都部署了相同的构建,但只有两个节点没有响应。这些无响应节点的CPU低于10%。
游戏:2.5.14比例:2.11.11
有很多事情可能出错,这只是一个猜测游戏,提供您提供的信息。
我首先创建没有响应的JVM的线程转储。如果您确实捕获了应用程序的控制台日志,那么获取转储的一种方法是将信号3
发送到jvm进程。
假设您在unix环境中运行服务,
ps aux | grep java
找到运行你的播放应用程序的java pid。
kill -3 <pid>
通过发送信号3
,jvm在控制台中生成线程转储。
如果控制台不可用,请执行
jstack -l <pid> >> threaddumps.log
现在,您将能够看到线程的快照状态以及阻塞线程时阻塞的位置。