数据库服务器在服务器启动时由于缓存请求负载过大而停止

DB server stalls due to excessive load of ecache requests while server startup

我有中型和流量电子商务网站。一次约有200-300名访客。 Webapp 功能是:

  1. 内置 Java,Spring 用于 MVC
  2. 使用Ehcache缓存来自数据库的多个数据请求
  3. 纯JDBC用于连接数据库(使用tomcat的连接池)
  4. 部署在 tomcat 上的 AWS EC2
  5. 使用RDS作为数据库服务器
  6. 大约 100 个数据库连接分配给 webapp

我广泛使用 Ehcache 来缓存大部分目录数据,因为网站上的所有流量都会请求这些数据。但是,当我在 tomcat 上部署新版本时,几乎总是数据库服务器因触发过多查询而停滞。 Ehcache 在这里无法提供帮助,因为到目前为止还没有缓存任何内容。最好的情况是大约需要 45 分钟,直到网站仍然非常缓慢并且 ehcache 设法缓存重要数据。最坏的情况是网站崩溃,应用程序停止 运行。

在开发环境中,它运行非常流畅,因为没有流量。为了快速找到解决此问题的方法,我们进行了快速修复。

修复方法是:ServletContextListener 中,我们对与目录相关的大多数关键服务进行了虚拟攻击,这些服务因过多的查询而耗尽了数据库服务器。由于这一变化,一旦部署了应用程序,我们就会在内存中获取与目录相关的所有数据,并将其全部缓存在 ehcache 中。此后,应用程序可用于 public。虽然,此更改导致我们部署应用程序时启动延迟大约 30 秒,但我们设法摆脱了 45 分钟的缓慢网站。

此修复确实解决了我们的问题,但感觉不是一个好的解决方案。因为与目录或其他重要数据相关的所有内容都在内存中,无论是否习惯。它大约有 3.5 GB 的数据。而且,现在在开发环境中工作简直就是一场噩梦。由于开发系统内存不足。

请提出解决此问题的好方法。

在启动时填充缓存感觉是个好主意。那就是我会做的。如果它适合内存,我不介意加载太多东西。

另一种方法是采用过期策略并定期对缓存执行 ping 操作以删除过期的条目。但这听起来更像是浪费时间。

分布式缓存也可以解决这个问题,但这意味着给您的架构增加一层复杂性。我只会在必要时这样做。我不这么认为。

然后,为了防止在开发中加载,只需使用 Spring 配置文件,使加载仅在生产中处于活动状态(理想情况下是暂存)。