在所有常见配置错误中,有一种情况是:当网站开始扩展到多台Web服务器时把会话状态放到SQL Server数据库中。

  错误背景

  为了照顾那些不理解会话状态是什么的朋友,我们退后一步讲起,以便他们也可以理解。会话状态允许Web开发人员在Web服务器上把值存储到变量中,但是要保存在共享的位置,这样不管终端用户连接的是哪一台Web服务器,这些保存的值都能访问到,Web服务器群彼此之间都会认可这些会话信息。对于B2C网上购物网站,或者其它带有登录提示的网站,或者被配置为发送用户连接到下一个可用Web服务器的负载均衡网站,这一点都非常重要。

  问题出在哪里?

  现在问题变成了,大多数人在需要扩展会话状态时会选择把会话状态放到SQL Server数据库中,因为这是一种非常简单的存储方式,有很多地方都已经按这种方式做了,更不用说在ASP.NET中有会话状态代码可以很容易地支持它。把会话状态信息放到SQL Server数据库中的出发点是,你不必再对关于把会话状态信息持久化保存到磁盘的问题废话。信息不只是保存一个小时左右,如果数据库中的信息丢了,影响是在会话变量中的所有值都丢了。

  还有别的选择吗?

  除了采用SQL Server存储会话状态,我们还有下面几种选择:

  ● 继续使用进程中处理。

  ● 使用ASP.NET会话状态服务。

  简单的方法是在IIS中为会话信息继续使用进程中处理方案。这意味着你将需要在负载均衡中配置关联会话,这样用户时时刻刻都会看到相同的Web服务器。一旦出现Web服务器故障问题,所有那些用户的会话信息都会丢失,他们需要用日志重新恢复网站,或许他们的购物车会清空,不管该网站做什么都会丢失。

  ASP.NET会话状态服务是一个Windows服务,提供一种只在内存中保留的会话状态库,这样会话信息永远不会写到磁盘上,它也不必保存在web服务器上。你既可以对指定的计算机这样设置,也可以设置多台计算机把服务手工集群,这样你的会话状态服务有了HA解决方案。如果你已经有SQL Server集群了,而且如果你没有其它更好的方案可以用,你可以对它应用该集群。只需要配置该集群,使SQL Server运行的节点作为节点,使会话状态运行在另一个节点上作为节点。这样该服务永远不会运行在同一个节点,除非另一个节点出现故障。会话状态服务不会占用太多CPU资源,而且它需要的存储器数量完全取决于你在web服务器上放入会话变量中信息量的多少。

  在这两种情况中,每种解决方案都比把会话状态信息放到SQL Server数据库中要好。这些信息甚至不需要被写到磁盘上。写到会话状态数据库中的信息是blob二进制格式,而不是任何排序相关格式,因此实际上你使用这些信息时也很不方便。