0

我们有一个曾经在单个实例中运行一段时间的 Web 角色。为了应对更高的负载(并获得更好的 SLA),我们目前正在迁移角色以支持多个实例。

该角色使用表单身份验证(带有自定义成员资格提供程序),我们的理解是我们必须在实例之间启用某种共享会话状态,因此如果用户在实例 1 上登录并获取他的.ASPXAUTHcookie,那么实例 2知道这个cookie。

我们这样做了,目前该角色在两个实例上运行,并且一切正常。我们测试了用户保持登录状态,即使他的请求是在他登录的实例之外的另一个实例上处理的。如果用户没有登录,访问将被拒绝。

我们还检查了是否TableStorageSessionStateProvider在 Azure 表存储帐户中创建了一个表,并且确实有一个Sessions包含PartitionKey,RowKeyTimestamp列的表。

但是,令我们惊讶的是,Sessions桌子总是空着。无论有多少用户登录,表中都没有数据。

如果不通过Sessions表,这些实例如何通信?

4

1 回答 1

2

您在这里混合了两个不同的东西:AuthenticationSession State

确实,为了在多个实例中使用 Session State,您需要一个共享存储(InProc 不起作用)。在这种情况下TableStorageSessionStateProvider会起作用,因为所有实例都可以访问存储在此处的会话数据。当您在用户的当前会话中存储某些东西时使用会话状态,例如购物车。你会这样称呼它:Session["UserShoppingCart"] = shoppingCart;.

但是您在问题中描述的内容与会话状态无关,这完全与表单身份验证有关。当您在实例 1 上进行身份验证时,您将获得一张票作为回报(存储在 .ASPXAUTH cookie 中)。此票证经过加密和签名,包含您的用户名、到期时间、自定义用户数据等基本信息...

既然您有多个实例,那么下一个请求可能会让您进入实例 2。我认为您的问题是,这些实例如何通信?好吧,他们没有。每当请求开始时,在它到达您的页面或控制器之前,FormsAuthenticationHttpModule 就会启动并查找 .ASPXAUTH cookie。它检查签名,对其进行解密,然后用来自 cookie(票证)的信息填充 HttpContext.Current.User。

实例之间的唯一链接是 machineKey(用于加密/解密/签名/验证 cookie)。每当您在 Windows Azure 中部署多个实例时,Fabric Controller 都会确保所有实例都获得相同的 machineKey。这样,实例 2 将能够解密和验证由实例 1 加密和签名的票证。

于 2012-10-16T11:40:41.027 回答