在Windows Azure中进行Web角色的扩展

3
我已经在WebRole.cs中实现了一个websocket服务器,目前它可以工作,用户可以使用网站的URL和指定的端点连接到服务器。现在假设我有50,000个用户想要连接到websocket服务器,我需要更多的Web角色实例来处理负载。
我的问题是,如果有多个Web角色实例,这是否会导致多个websocket服务器?即,用户仍然只使用单个URL / IP进行连接,并且所有用户都相互连接(例如,在广播消息时),还是用户需要输入不同的IP地址以连接到不同的websocket服务器(每个实例一个),并且仅与同一服务器/实例上的用户相连?
编辑:具体问题
因此,如果在连接时将用户添加到:
private static List<UserContext> Users = new List<UserContext>();

在WebRole.cs文件中,我有一个广播方法:

private static void Broadcast(String message)
        {
            foreach (UserContext uc in Users)
            {
                uc.Send(message);
                Console.WriteLine("Broadcasting to: " + Users.IndexOf(uc));
            }
        }

消息会广播给网站上的所有用户,还是每个实例都有自己的用户列表,因此只会向连接到特定实例的用户广播?

你正在使用哪个UserContext(Web套接字库)? - Simon Munro
Alchemy Web Sockets - http://alchemywebsockets.net/ - Matt
2个回答

4
虽然Simon说负载均衡器会处理所有请求(您不需要担心需要连接的实例),但还有其他事情需要考虑。从您的问题中,我了解到您想要广播消息。
假设您将应用程序扩展到2个实例:
- 实例1 - 实例2
负载均衡器将确保所有对yourapp.cloudapp.net的请求都转到这些实例之一(轮询)。现在假设用户A、B和C被路由到实例1,而用户D、E和F被路由到实例2:
- 实例1:用户A、用户B、用户C - 实例2:用户D、用户E、用户F
因此,假设用户A在您的应用程序中执行某些操作,并且您希望将此广播给所有用户。实例1只会看到另外2个已连接的用户:用户B和C,并将消息发送给这些用户。问题在于,即使这些用户位于不同的实例上,您也希望将消息发送给用户D、E和F。
这就是为什么你的WebSocket/broadcast/...框架(例如SignalR)需要使用像服务总线这样的东西,该总线可从所有实例访问。看一下SignalR如何通过使用Windows Azure Service Busredis解决此问题。

好的,根据我在Azure Service Bus上阅读的内容,我可以在我的Web套接字服务器(webrole.cs)类中创建一个主题并订阅它。每当从Web套接字接收到消息时,就会在服务总线上发送一条消息。每当在总线上接收到消息时,它都会调用广播。通过这种方式,所有实例都应该订阅了服务总线并广播所有消息。我会尝试一下并告诉你结果如何。感谢建议Sandrino,你的答案真的帮助了我解决所有关于Azure的问题 :) - Matt

3
你正在连接的网站URL实际上是负载均衡器的URL,而不是特定实例的URL(公共IP也是负载均衡器中的虚拟IP)。随着你增加更多实例,负载均衡器会通过轮询将流量引导到底层实例。除了公共URL和IP地址之外,你不必担心其他任何事情(例外是虚拟网络,不使用负载均衡器)。
Alchemy UserContext具有Endpoint ClientAddress。单个服务器只会保存与之连接的用户的源地址,而不是其他服务器的用户。你需要从两个服务器广播。因此,如果在所有服务器上进行广播(broadcast()),你将捕获所有用户。但要小心重复消息。单个用户可能存在于多个服务器上,因为NLB不执行粘性会话。确保你的客户端代码能够处理来自多个服务器的相同消息。

那么就好像所有用户都连接到同一个服务器上了?例如,如果我写:'对于服务器上的每个用户发送广播',每个实例上的每个用户都会收到消息? - Matt
可能不行。单个服务器只有连接到该服务器的用户的源地址,没有其他服务器的源地址。您需要从两个服务器广播。但是可能会出现重复,因为单个用户可以在每个请求之间在两个服务器之间切换。 - Simon Munro
谢谢你迄今为止的帮助!最后一件事,我编辑了我的原始问题,以给出更具体的广播示例,你能否再看一下确认一下。再次感谢 :) - Matt
Alchemy UserContext具有Endpoint ClientAddress。如果在所有服务器上广播(broadcast()),您将捕获所有用户。但要小心重复项。单个用户可能会存在于多个服务器上,因为NLB不会进行粘性会话。确保您的客户端代码能够处理来自多个服务器的相同消息。 - Simon Munro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接