ColdFusion客户端变量间歇性地显示过时值

时间:2013-09-03 14:45:48

标签: caching coldfusion session-state race-condition intermittent

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

问题是当代码使用新值(旧值)更新客户端变量时 即使新值在CData表中正确更新,仍在使用和显示。这种情况只会间歇性地发生在使用cfset标记对客户端变量进行的1000次更新中的1次。

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

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

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

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

非常感谢你的回复!

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

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

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

另外......

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