2016-03-01 81 views
2

我一直在我的cfml应用程序中使用session作用域来执行诸如存储当前登录的user对象之类的操作。这很棒!如何管理群集环境中的cfcs状态

user.isLoggedIn()user.hasPremiumAccess()user.hasRole('admin')

在试图我的应用程序迁移到集群(云)的环境中,我认识到,依靠session范围小于理想的,因为正在运行的应用程序的每个实例都有自己的服务器记忆。我知道我可以使用“粘性会话”,但我宁可不要,因为这会限制Amazon Elastic Beanstalk等应用程序的实例(基于负载)自由旋转。

我也知道我可以使用client范围以集群友好的方式存储简单值,但是复杂数据如我描述的用户对象呢?你将如何存储用户对象,或者我可以使用什么其他方法?

我可以根据需要进行应用程序更改。

**编辑**要清楚,不是我不能使用粘性会话,而是我不想使用粘性会话(或会话复制)。原因是我可以充分利用不依赖服务器/实例内存来管理会话状态的全部可扩展性优势。这种方法允许诸如Elastic Beanstalk之类的服务自由地创建和拆除应用程序服务器实例,而不会影响用户。使用粘性会话不允许这样做。

一些可能的解决方案,我已经考虑的因素包括:

  1. 序列化用户对象用户/反序列化“状态”来存储客户范围并在每个页面加载
  2. 序列化/反序列化“重新初始化”用户用户对象用户的“状态”在的NoSQL数据库存储和在每个页面加载“重新初始化”用户
+0

如果你试图在Elastic Beanstalk上使用ColdFusion,然后阅读此错误信息 - [AWS Elastic Beanstalk拒绝ColdFusion WARs](https://bugbase.adobe.com/index.cfm?event=bug&id=3365388)以及相关文章 - http:// stackoverflow .com/q/12217424/1636917 –

+0

有趣。我试图在生产环境中运行Docker容器(是的,在Elastic Beanstalk上),所以如果所有的承诺都是真的,只要docker守护进程在EC2实例上运行(它就是这样),lucee应用就在Docker内部容器也应该运行。肯定通过一些障碍,但手指交叉。 –

+0

Lucee(Railo)没有这个问题,它只涉及Adobe CF我认为。 –

回答

4

如果你不/不能使用“粘性会话“,那么另一种选择是实现会话复制。这实际上将存储在内存中的会话复制到集群中的每个节点。而且,是的,这样做有开销。

从文档:

要实现对服务器实例的会话故障转移群集中,使每个服务器实例的会话复制。会话复制实时协调集群中的服务器实例之间的会话信息。如果当前服务器不可用,启用会话复制可让Tomcat自动将请求路由到正在运行的服务器。

注意:当群集使用会话复制时,会话数据会在每次修改时被复制到群集中的其他服务器。如果将大量信息存储在会话范围内,这可能会降低性能。如果您打算在会话范围内存储大量信息,请考虑将此信息存储在保存在数据库中的客户端变量中。

从 - Enabling clustering for load balancing and failover

被进一步提到那一页另一个警告:

如果使用会话复制,到内存变量页面,使J2EE会话。为群集中的所有服务器实例启用J2EE会话。如果ColdFusion Administrator中未启用J2EE会话,则会话复制将无法正常运行.CFC序列化使您可以在群集中使用J2EE会话复制,并可以访问群集中所有实例的会话数据中的CFC。会话复制还可确保跨范围变量在集群中进行复制。但是,会话复制不支持在会话范围CFC或变量中复制阵列。在会话故障切换的情况下,您还可以保留和访问CFC中的数据。存储在会话范围内的ColdFusion结构在会话范围内可用,即使在故障转移后也是如此。例如,如果您运行多个ColdFusion实例来平衡服务器负载,则可以在会话中存储有用的数据(包括CFC),以便可以访问该会话中提供的所有页面上的数据。

而且还要检查这个答案同样的问题而回(请注意,有早期版本的ColdFusion 10并没有让会话复制到工作中的错误) - https://serverfault.com/a/602373/135433

+0

谢谢你的回应Miguel!我宁愿让事情变得更简单,而不是更复杂,所以假设我愿意修改我的应用程序以使其变为无状态。在无状态环境中存储复杂对象的最佳方法是什么?以某种方式序列化和反序列化cfc状态并将其作为json存储在数据库中?在每个请求中“重新填充”该用户?还有别的吗? –

+0

我通常只在我们的负载平衡环境中使用粘性会话(以保持简单)。所以不知道我能对你的问题提供很多帮助。但我最初的想法是,如果你的应用程序是无状态的,那你为什么需要在它们之间共享任何东西? –

+0

谢谢米格尔。我可能会在一段时间内使用粘滞会话,但在一天结束时,必须存储的是会话数据,只是为了使应用程序“无状态”,它应该以不会存储的方式存储取决于运行它的服务器实例的服务器内存。这是我见过的客户端经常使用的范围......问题是客户端无法存储复杂的数据,而且没有一些骇客。只是在寻找创意。 –