我一直在我的cfml应用程序中使用session
范围来执行存储当前登录的user
对象的操作。太棒了!
user.isLoggedIn()
,user.hasPremiumAccess()
,user.hasRole('admin')
在尝试将我的应用程序迁移到集群(云)环境时,我意识到依赖于session
范围并不理想,因为正在运行的应用程序的每个实例都有自己的服务器内存。我知道我可以使用"粘性会话,"但是我不愿意这样做,因为这会限制像Amazon Elastic Beanstalk这样的东西自由地旋转和关闭应用程序的实例(基于负载)。
我也知道我可以使用client
范围以集群友好的方式存储简单值,但复杂数据又如我描述的用户对象呢?您将如何存储用户对象,或者我可以使用其他方法?
我可以根据需要更改应用程序。
**编辑**要清楚,不是因为我不能使用粘性会话,而是我不想使用粘性会话(或会话复制) )。原因是我可以充分利用不依赖服务器/实例内存来管理会话状态的完全可扩展性优势。这种方法允许诸如Elastic Beanstalk之类的服务自由地创建和拆除app-server实例,而不会影响用户。使用粘性会话不允许这样做。
我考虑过的一些可能的解决方案包括:
答案 0 :(得分:4)
如果您不能/不能使用“粘性会话”,则另一个选项是实现会话复制。这实际上将存储在存储器中的会话复制到集群中的每个节点。而且,是的,这样做会产生开销。
来自文档:
要为群集中的服务器实例实施会话故障转移,请为每个服务器实例启用会话复制。会话复制在群集中的服务器实例之间实时协调会话信息。如果当前服务器不可用,则启用会话复制可让Tomcat自动将请求路由到正在运行的服务器。
注意:当群集使用会话复制时,会话数据每次修改时都会复制到群集中的其他服务器。如果在会话范围中存储大量信息,则会降低性能。如果您计划在会话范围中存储大量信息,请考虑将此信息存储在保存在数据库中的客户端变量中。
在该页面下面进一步提到的另一个警告:
如果您正在使用会话复制,请转到“内存变量”页面并启用J2EE会话。为集群中的所有服务器实例启用J2EE会话。如果未在ColdFusion Administrator中启用J2EE会话,则会话复制将无法正常运行.CFC序列化允许您在群集中使用J2EE会话复制,并且可以跨群集中的所有实例访问会话数据中的CFC。会话复制还确保在整个群集中复制会话范围变量。但是,会话复制不支持在会话范围CFC或变量中复制数组。在会话故障转移的情况下,您还可以保留和访问CFC中的数据。存储在会话范围内的ColdFusion结构在会话范围内可用,即使在故障转移之后也是如此。例如,如果您正在运行多个ColdFusion实例来平衡服务器负载,则可以在会话中存储有用的数据(包括CFC),以便您可以访问该会话中所服务的所有页面上的数据。
同时回答同一个问题的答案(注意早期版本的ColdFusion 10中存在一个错误,它不允许会话复制工作) - https://serverfault.com/a/602373/135433