首页 > 解决方案 > 由于服务器启动时 ecache 请求的负载过大,数据库服务器停止

问题描述

我有中型和流量电子商务网站。一次大约有 200-300 名游客。Webapp 的特点是:

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

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

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

解决方法是:ServletContextListener我们对与目录相关的大多数关键服务进行了虚拟打击,这些服务因过多的查询而占用了数据库服务器。由于这一变化,一旦应用程序被部署,我们就会在内存中获取与目录相关的所有数据,然后 ehcache 将它们全部缓存起来。此后,应用程序变为可供公众使用。虽然,当我们部署应用程序时,这种变化导致了大​​约 30 秒的启动延迟,但我们设法摆脱了 45 分钟的缓慢网站。

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

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

标签: javaspringjdbcehcache

解决方案


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

另一种方法是制定过期策略并定期 ping 缓存以删除过期条目。但这听起来更像是在浪费时间。

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

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


推荐阅读