数据库服务器在服务器启动时由于缓存请求负载过大而停止
DB server stalls due to excessive load of ecache requests while server startup
我有中型和流量电子商务网站。一次约有200-300名访客。 Webapp 功能是:
- 内置 Java,Spring 用于 MVC
- 使用Ehcache缓存来自数据库的多个数据请求
- 纯JDBC用于连接数据库(使用tomcat的连接池)
- 部署在 tomcat 上的 AWS EC2
- 使用RDS作为数据库服务器
- 大约 100 个数据库连接分配给 webapp
我广泛使用 Ehcache 来缓存大部分目录数据,因为网站上的所有流量都会请求这些数据。但是,当我在 tomcat 上部署新版本时,几乎总是数据库服务器因触发过多查询而停滞。 Ehcache 在这里无法提供帮助,因为到目前为止还没有缓存任何内容。最好的情况是大约需要 45 分钟,直到网站仍然非常缓慢并且 ehcache 设法缓存重要数据。最坏的情况是网站崩溃,应用程序停止 运行。
在开发环境中,它运行非常流畅,因为没有流量。为了快速找到解决此问题的方法,我们进行了快速修复。
修复方法是: 在 ServletContextListener
中,我们对与目录相关的大多数关键服务进行了虚拟攻击,这些服务因过多的查询而耗尽了数据库服务器。由于这一变化,一旦部署了应用程序,我们就会在内存中获取与目录相关的所有数据,并将其全部缓存在 ehcache 中。此后,应用程序可用于 public。虽然,此更改导致我们部署应用程序时启动延迟大约 30 秒,但我们设法摆脱了 45 分钟的缓慢网站。
此修复确实解决了我们的问题,但感觉不是一个好的解决方案。因为与目录或其他重要数据相关的所有内容都在内存中,无论是否习惯。它大约有 3.5 GB 的数据。而且,现在在开发环境中工作简直就是一场噩梦。由于开发系统内存不足。
请提出解决此问题的好方法。
在启动时填充缓存感觉是个好主意。那就是我会做的。如果它适合内存,我不介意加载太多东西。
另一种方法是采用过期策略并定期对缓存执行 ping 操作以删除过期的条目。但这听起来更像是浪费时间。
分布式缓存也可以解决这个问题,但这意味着给您的架构增加一层复杂性。我只会在必要时这样做。我不这么认为。
然后,为了防止在开发中加载,只需使用 Spring 配置文件,使加载仅在生产中处于活动状态(理想情况下是暂存)。
我有中型和流量电子商务网站。一次约有200-300名访客。 Webapp 功能是:
- 内置 Java,Spring 用于 MVC
- 使用Ehcache缓存来自数据库的多个数据请求
- 纯JDBC用于连接数据库(使用tomcat的连接池)
- 部署在 tomcat 上的 AWS EC2
- 使用RDS作为数据库服务器
- 大约 100 个数据库连接分配给 webapp
我广泛使用 Ehcache 来缓存大部分目录数据,因为网站上的所有流量都会请求这些数据。但是,当我在 tomcat 上部署新版本时,几乎总是数据库服务器因触发过多查询而停滞。 Ehcache 在这里无法提供帮助,因为到目前为止还没有缓存任何内容。最好的情况是大约需要 45 分钟,直到网站仍然非常缓慢并且 ehcache 设法缓存重要数据。最坏的情况是网站崩溃,应用程序停止 运行。
在开发环境中,它运行非常流畅,因为没有流量。为了快速找到解决此问题的方法,我们进行了快速修复。
修复方法是: 在 ServletContextListener
中,我们对与目录相关的大多数关键服务进行了虚拟攻击,这些服务因过多的查询而耗尽了数据库服务器。由于这一变化,一旦部署了应用程序,我们就会在内存中获取与目录相关的所有数据,并将其全部缓存在 ehcache 中。此后,应用程序可用于 public。虽然,此更改导致我们部署应用程序时启动延迟大约 30 秒,但我们设法摆脱了 45 分钟的缓慢网站。
此修复确实解决了我们的问题,但感觉不是一个好的解决方案。因为与目录或其他重要数据相关的所有内容都在内存中,无论是否习惯。它大约有 3.5 GB 的数据。而且,现在在开发环境中工作简直就是一场噩梦。由于开发系统内存不足。
请提出解决此问题的好方法。
在启动时填充缓存感觉是个好主意。那就是我会做的。如果它适合内存,我不介意加载太多东西。
另一种方法是采用过期策略并定期对缓存执行 ping 操作以删除过期的条目。但这听起来更像是浪费时间。
分布式缓存也可以解决这个问题,但这意味着给您的架构增加一层复杂性。我只会在必要时这样做。我不这么认为。
然后,为了防止在开发中加载,只需使用 Spring 配置文件,使加载仅在生产中处于活动状态(理想情况下是暂存)。