在所有Web应用程序中实现Tomcat服务器范围的持久和可更改变量的方法



生产环境:Tomcat 9 on CentOS 7 x64,mysql/mariadb 5.5x

测试环境:Tomcat 9在Windows 7 x64上的Eclipse,mysql 5.5x

我是Tomcat的新手,正在寻找最好的方法,让服务器范围内的变量从所有Web应用程序中可读写,例如MaintenanceMode(打开/关闭)和MaintenanceMessage等。这些是我正在寻找的可变属性:

  • 可从所有web应用程序上的所有java servlet的所有实例读取/写入
  • 值在操作系统、Tomcat或Webapp重新启动后仍然存在
  • 我必须能够从一个网络应用程序中更改它的值,然后所有其他网络应用程序都能快速识别更改,理想情况下无需重新启动
  • 理想情况下,我不想在每次服务器请求时从磁盘读取变量。以防服务器被DDOSed或其他什么
  • 理想情况下,该解决方案与操作系统无关
  • 如果是磁盘文件解决方案,请为我推荐一个存储文件的地方

我是Tomcat的新手,所以希望您能提供任何答案中的一些细节或详细信息的链接。我可能会在它自己的"admin"Web应用程序上使用一个servlet来设置变量,该servlet只能通过SSH隧道等访问。然后,公共网络应用程序会对任何更改做出响应,比如在我备份数据库时显示维护消息。如果需要,我也可以使用linux命令更改变量。

如果我将服务器变量存储在数据库中,这可能很好,但我不想在每次请求时都读取数据库,而且当我更改变量时,我必须再次通知每个webapp/servlet有什么更改,并重新读取数据库。

谢谢你的帮助。

我最近以"系统消息"的形式实现了这一点,其中一些消息用于维护。但效果是一样的。我们有一些额外的"需求",这有助于我们形成解决方案。这些可能与您的期望/欲望匹配,也可能不匹配:

  1. 多服务器协调
  2. 不需要立即同步

我们使用关系数据库进行实际数据存储。一个包含"系统消息"和其他一些字段的表格,例如消息何时生效(not_before DATETIME)和消息何时无效(not_after DATETIME)。

启动时,应用程序读取系统消息表以查找当前有效的消息,并将其存储在application范围中,包括其有效日期。每当我们想在屏幕上显示它们时,我们都会检查内存中的每个项目,并驱逐任何过期的项目。这相当快。

每X分钟(例如,从cron),我们向一个特殊的servlet(在每个服务器上)发出一个请求,该servlet从数据库中重新加载系统消息。我们通过只允许来自特定IP的请求来保护servlet,所以DOS不是问题。

我们不仅可以从集群中的任何服务器添加系统消息,还可以通过直接写入数据库来添加系统消息。如果您不总是想使用应用程序来生成这些事件,那么这可能是有利的。

如果使用cron,则可以将X的值更改为低至1(分钟)的任何值。如果你使用其他类型的系统,你可能会更频繁地更新。我会认真考虑你对"立即"承认的要求,因为这需要一个性能更差的系统。

如果你能保证只有你的应用程序才能生成这些更改,并且你在集群中的某个地方有一个所有其他服务器的列表,理论上你可以用新消息对它们进行ping(或者通知它们存在新消息,是时候更新它们的消息列表了),但这种事情最好用协调工具来完成,比如Kubernetes,我们有点超出范围了IMO.

最新更新