3

我们有一个旧的 ColdFusion 应用程序,它使用 150 个客户端变量来管理会话状态。客户端变量使用循环负载平衡器集中存储在 6 个应用程序服务器集群环境中的 SQL Server 数据库中。

问题是当代码用新值更新客户端变量时,即使新值在 CData 表中适当更新,旧值仍在使用和显示。这仅在使用 cfset 标记对客户端变量进行平均 1000 次更新时间歇性发生。

竞争条件和缓存问题是可能的解释。我们“怀疑”旧值仍然缓存在 6 个应用程序服务器之一上。Adobe 的文档明确指出客户端变量被缓存到内存中,但没有详细说明。

1)有没有人也遇到过这个问题并找到了一个好的解决方案?

2)当我们继续使用客户端变量时,移动到粘性会话有什么影响?

4

2 回答 2

1

我想我会先仔细看看你的数据库提交。客户端变量在请求的“开始”被检索,然后在请求的“结束”进行任何更改进行更新。考虑在请求结束时发生 cflocation 的情况。“下一个”请求是否有可能在提交更新之前从数据库中提取页面?在具有复制等的复杂系统中,可能会发生这种情况。6 个集群 Web 服务器是一个很大的数字。

至于在内存中缓存 - CF 将客户端 var 缓存在内存中,并且仅在客户端 var 更改(如果发生更新)时从存储(数据库)“读取”。所以你也可以在那里做一些事情。尽管如此,理论上缓存在内存中的客户端 var 应该与数据存储中的 var 相同. 因为它存储更改 - 这些更改也会写入数据存储区。这是实时完成的(据我所知),即在请求结束时。对客户端变量的所有更改都刷新到数据库。因此,理论上即使使用循环法,如果您的浏览器出现在内存中没有您的客户端变量的新服务器上,它只会将它们从数据库中取出。这就是为什么我认为数据库可能是这里的关键。注意:更新行为可能会根据全局变量是启用还是禁用而改变。查看每台服务器,看看此设置的使用方式是否有任何差异。

至于粘性会话:如果您使用的是基于硬件的负载平衡器,请确保并探索它的平衡选项。您想要的是使用粘性会话让 LB 在服务器之间分配负载。您希望它足够聪明,可以了解实际负载(通常是 CPU 使用率) ,而不仅仅是在服务器之间分配的请求总数。祝你好运。我喜欢这样的问题:)

于 2013-09-03T15:31:11.297 回答
0

非常感谢您的有用回复!

有可能其中一个应用程序服务器仍在尝试处理客户端变量的更新,而下一个应用程序服务器已经接收到“下一个”请求,然后使用缓存值而不是更新值。这表明我们的应用服务器存在负载问题。150 个客户端变量的序列化和反序列化可能是一个因素。但是,正如您所指出的,在应用程序服务器正常运行时,在某些条件下,数据库的提交时间可能比预期的要晚得多(或响应速度要慢得多)。客户端变量存储在它自己的数据库中,但与我们的主数据库位于同一数据库服务器上。

有趣的是,您提到所有更改的客户端变量在请求结束时都“刷新”到数据库中。但只是为了澄清一下,它们是否同时从内存(和数据库)和所有应用程序服务器上“刷新”出来?从而删除其他服务器上任何过时的缓存值,因此需要服务器从数据库中检索更新的值。或者,一旦数据库提交,ColdFusion 才会更新其余应用程序服务器上的客户端变量,无论内存中是否已经存在缓存值?

出于性能原因,我们在所有 6 个 (CF9) 生产服务器上都禁用了全局变量更新。我们在拥有 3 台 (CF9) 服务器的测试站点上启用了此功能,但间歇性事件仍在发生,甚至发生率更高。

此外 ....

CFApplication 标签中的 setDomainCookies 属性为“否”。自从 10 多年前编写遗留应用程序以来,此设置一直是相同的。但是,Adobe 的文档确实表明集群环境需要“是”。我们正在创建一个简单的测试页面,以进一步分析 Cookie.CFID 和 Cookie.CFTOKEN 值如何在应用程序服务器之间共享,并通过使用测试页面进一步研究缓存问题。

于 2013-09-07T11:36:34.077 回答