我们有一个Web角色,它曾经在一个实例中运行过一段时间。为了应对更高的负载(并获得更好的SLA),我们目前正在迁移角色以支持多个实例。
该角色使用Forms Authentication(带有自定义成员身份提供程序),我们的理解是,我们必须在实例之间启用某种共享会话状态,因此,如果用户登录实例1并获得他的.ASPXAUTH
cookie,则实例2知道该cookie。
我们做到了,目前该角色在两个实例上运行,一切都很好。我们测试了用户是否保持登录状态,即使他的请求是在他登录的实例之外的另一个实例上处理的。如果用户不登录,访问将被拒绝。
我们还检查了TableStorageSessionStateProvider
是否在Azure表存储帐户中创建了一个表,事实上,有一个表Sessions
包含PartitionKey
、RowKey
和Timestamp
列。
但是,令我们惊讶的是,Sessions
表总是空着。无论有多少用户登录,表中都没有数据。
如果不通过Sessions
表,这些实例如何进行通信
您在这里混淆了两个不同的东西:身份验证和会话状态。
的确,为了在多个实例中使用会话状态,您需要一个共享存储(InProc不起作用)。在这种情况下,TableStorageSessionStateProvider
将起作用,因为所有实例都可以访问存储在此处的会话数据。会话状态用于在用户的当前会话中存储内容,如购物车。你可以这样称呼它:Session["UserShoppingCart"] = shoppingCart;
。
但您在问题中所描述的内容与会话状态无关,而是表单身份验证。当您在实例1上进行身份验证时,您将得到一个票证作为回报(存储在.ASPXAUTH cookie中)。此票证经过加密和签名,包含基本信息,如您的用户名、过期时间、自定义用户数据等。。。
既然您有多个实例,那么下一个请求可能会将您降落在实例2上。我想你的问题是,这些实例是如何交流的嗯,他们没有每当请求启动时,在它到达您的页面或控制器之前,FormsAuthenticationHttpModule就会启动并查找.ASPXAUTH cookie。它检查签名,对其进行解密,然后用cookie(票证)中的信息填充HttpContext.Current.User。
实例之间的唯一链接是machineKey(用于对cookie进行加密/解密/签名/验证)。无论何时在Windows Azure中部署多个实例,结构控制器都会确保所有实例都获得相同的machineKey。这样,实例2将能够解密和验证由实例1加密和签名的票证。