Session Coldfusion:在会话中只保留用户id,还是保留整个用户对象更好?

Session Coldfusion:在会话中只保留用户id,还是保留整个用户对象更好?,session,coldfusion,Session,Coldfusion,我有一个cfc来处理用户对象。我的问题是:在会话中只存储user_id并在每个请求中重新创建user对象是否更好?还是最好将整个用户对象存储在会话中 以下是我的想法: 如果我将整个对象存储在会话中: 处理器开销可能会减少 可能会有更多的内存开销 所有方法/函数都存储在实际对象中,我在cfc中更新的新函数将不可用,除非用户注销并重新登录,或者如果我想出某种方法使其自身刷新 如果我通过并发ajax调用处理对象,可能会出现互斥或锁问题 如果我只在会话中存储用户id: 我必须为每个页面请求创建用

我有一个cfc来处理用户对象。我的问题是:在会话中只存储user_id并在每个请求中重新创建user对象是否更好?还是最好将整个用户对象存储在会话中

以下是我的想法:

  • 如果我将整个对象存储在会话中:

    • 处理器开销可能会减少
    • 可能会有更多的内存开销
    • 所有方法/函数都存储在实际对象中,我在cfc中更新的新函数将不可用,除非用户注销并重新登录,或者如果我想出某种方法使其自身刷新
    • 如果我通过并发ajax调用处理对象,可能会出现互斥或锁问题
  • 如果我只在会话中存储用户id:

    • 我必须为每个页面请求创建用户对象(可能会增加处理器开销)
    • 可能会有更少的内存开销
    • 不会出现互斥/锁定/竞争条件,因为每个请求都有自己的用户对象副本
    • CFC模型本身的更新将立即在整个系统中被识别,用户无需注销和重新登录

这类事情有正常的做法吗?我考虑过了吗?

您没有指出是否正在使用ORM,所以这是一个一般性的答案

对于典型的应用程序,我建议将用户对象实例化到会话范围中。使用列表中未包含的每个请求重新创建对象有一个很大的缺点:对用户对象的属性和状态的更改不会在请求之间持久化,除非您打算在每次命中时将用户对象的状态刷新到持久化层(例如数据库)。这可能是一个比对象实例化昂贵得多的操作,而且它不一定能将您与您正在考虑的ajax调用、竞争条件等问题隔离开来--它只是将这些问题的表现形式转移到持久性层,对象的数据可能处于不可预测的状态

由于每个新请求都是“隐式保存”,因此您还必须设计“临时”对象,使其能够保持自身,而不管其是否处于有效状态(想象一下修改用户对象某些方面的多页表单的情况)

对于会话存储对象,可以通过仔细的设计实践来缓解对内存的担忧。例如,如果您的用户有许多任务,并且每个任务都有许多项,那么实例化所有这些对象并将其组合到您的用户对象中可能不是一个好主意(即,延迟加载比快速加载更好)


如果您确实必须能够动态更改CFC,那么即使使用会话存储对象,您也可以实现该目标。一种方法是在应用程序和会话中存储版本标志。对于每个请求,您的应用程序都会比较这些标志。当它们不同时,应用程序将运行会话重新加载例程,快照当前属性,重建会话存储的对象,并最终更新会话标志以匹配应用程序标志。

这是piggy对Ken Redler的部分回答的补充,但我没有足够的声誉发表评论

我们这样做的方式,也是我更喜欢的方式,是将用户数据作为结构存储在会话中。然后在请求启动时,我们的身份验证模型在请求范围内创建用户对象,并用会话数据覆盖任何默认值。这有几个好处:

  • 对数据库的点击次数越少,CPU就越少
  • 始终在没有复杂自定义系统的情况下运行最新代码,以确保
  • 群集环境友好(会话中的复杂对象不能群集)
  • 可以添加或删除属性而不会损坏(假设您的用户对象仅更新脏列)

此外,如果您使用的是CF9,那么他们真正引以为豪的一个特性就是他们优化了对象实例化的程度。如果没有,请自己测试

我写的所有CF应用程序都是针对高流量和高可用性的,因此我们从来没有考虑过单服务器实践的奢侈

因此,根据我的经验,我总是必须a)允许多个负载平衡的服务器,b)避免负载平衡器上的粘性会话,原因有很多。因此,我们至少需要让服务器动态地成为集群的一部分,并接收会话中的流量

因此,每次请求时,我们总是从共享数据存储中提取“会话”数据

我的建议是实施一个会话facade

这使您可以选择更改会话数据(如用户记录)的持久化方式,而无需更改应用程序的其余部分

您可以选择在幕后存储会话范围中的所有内容,为每个请求加载它,进行混合,使用键值存储等等

你可以选择是快速加载数据,还是延迟加载数据,或者两者之间的任何混合,应用程序的其余部分不需要知道你做了什么

论竞赛条件
如果您担心竞争条件,那么我建议在数据提交和访问时使用命名锁。这是使用facade的另一个好处-您的应用程序代码不需要知道这一点,您可以选择在某些对象周围设置锁,而不是锁定整个会话。

这取决于您的应用程序

如果您有大量的流量(每分钟数千个独立访客),那么在会话中存储User.cfc的内存开销最终会让您感到压力。这可以很容易地通过向它扔硬件来克服(暂时增加内存,最终增加内存)