我知道,出于可扩展性的原因,我们一般不喜欢在服务器上维护会话状态,但我只是不明白为什么 Play 2.0 采用的方法据说比老式的 HttpSession 更好。
我看到的一个主要区别是,HttpSession 实现是由容器提供的,因此 HttpSession 的扩展能力取决于它。
我知道,出于可扩展性的原因,我们一般不喜欢在服务器上维护会话状态,但我只是不明白为什么 Play 2.0 采用的方法据说比老式的 HttpSession 更好。
我看到的一个主要区别是,HttpSession 实现是由容器提供的,因此 HttpSession 的扩展能力取决于它。
这样做有很多优点。本质上,Play 中的会话模型促进了无共享架构。这意味着您执行的每个操作(如果您遵循 Play 推广的模式)都是 RESTful 请求,那么操作的执行完全是自包含的。这意味着每个请求都可以单独进行单元测试,并将您的应用程序构建为一组离散函数。
这里的原则是,每个动作之间的耦合越少,胖会话处理的会话状态越少,代码就会变得越干净、越健壮。
作为副作用,您还可以通过水平添加更多节点来轻松扩展,这通常比垂直扩展更便宜,并且比粘性会话更复杂和风险更低。
使用容器管理会话(及其封装状态)意味着当您想要水平扩展时,所涉及的系统还必须确保它们复制此状态,因为没有它您的应用程序将无法工作。使用您的应用程序的客户端有效地绑定到用户碰巧被定向到的特定节点。
相比之下; 当您的应用程序在任何时候都没有维护真正的会话状态时(正如您的 Play 应用程序应该那样),水平扩展非常容易:只需添加更多运行应用程序的节点并确保前端 HTTP 服务器知道新节点。没有花哨的算法和“企业平台”来复制和维护所有节点的会话。
不,实际上比这要复杂一些。Play 实际上推动了无状态的应用程序架构。这意味着,您没有在会话中存储任何数据。除了可以存储凭据之外,什么都没有。
第一条规则:会话存储被驱逐到数据库。不是从会话中获取数据,而是从数据库中获取数据。数据库的可伸缩性比 JVM 应用程序更容易。
第二条规则:除了凭据之外,什么都没有存储。这意味着,您将不得不为对话状态传输信息。有两种主要方法可以做到这一点。使用隐藏字段,我认为这不是最好的方法。其次使用绝对 URL。创建一个包含 ID、搜索和其他内容的URL 。