如何在 Web 应用程序中使用 ServiceStack Redis 以利用 pub/sub 范例
我对 Pub/Sub 范式感兴趣,以便提供通知系统(即:像 Facebook 一样),特别是在具有发布者的 Web 应用程序中(在多个 Web 应用程序中)在同一 Web 服务器 IIS 上)和一个或多个订阅者,负责在 Web 上向前端用户显示通知。
我发现 Redis,它似乎是一个很棒的服务器,提供了有趣的功能:缓存(如 Memcached)、Pub/Sub、队列。
不幸的是,除了 WebSockets 和 NodeJS 之外,我没有在 Web 上下文(ASP.NET,带有 Ajax/jQuery)中找到任何示例,但我不想使用这些示例(太早了)。我想我需要一个进程(订阅者)来接收来自发布者的消息,但我不知道如何在网络应用程序中执行此操作(发布/订阅可以很好地进行单元测试)。
编辑:我们目前使用.NET(ASP.NET Forms)并尝试ServiceStack.Redis库(http://www.servicestack.net/)
I am interested in the Pub/Sub paradigm in order to provide a notifications system (ie : like Facebook), especially in a web application which has publishers (in several web applications on the same web server IIS) and one or more subscribers, in charge to display on the web the notifications for the front user.
I found out Redis, it seems to be a great server which provides interesting features : Caching (like Memcached) , Pub/Sub, queue.
Unfortunately, I didn't find any examples in a web context (ASP.NET, with Ajax/jQuery), except WebSockets and NodeJS but I don't want to use those ones (too early). I guess I need a process (subscriber) which receives messages from the publishers but I don't see how to do that in a web application (pub/sub works fine with unit tests).
EDIT : we currently use .NET (ASP.NET Forms) and try out ServiceStack.Redis library (http://www.servicestack.net/)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
对于此应用程序,我强烈建议使用 SignalR,它是一个 .Net 框架可以实时推送到连接的客户端。
For this application, I would strongly suggest using SignalR, which is a .Net framework that enables real-time push to connected clients.
Redis 发布/订阅不是为这种情况设计的 - 它需要与 Redis 的持久连接,如果您正在编写工作进程,但在处理无状态 Web 请求时则不需要。
通过 http 为最终用户工作的发布/订阅系统需要更多的工作,但不会太多 - 最简单的方法是为每个通道使用排序集并记录用户上次收到通知的时间。您还可以使用记录每个频道的订阅者的列表来完成此操作,并在添加通知时写入每个用户的收件箱列表。
使用这两种方法中的任何一种,用户都可以非常快速地检索新通知。这将是一种轮询形式,而不是真正的推送通知,但由于 http 的性质,您并不能真正摆脱它。
从技术上讲,您可以将 redis pub/sub 与长时间运行的 http 连接一起使用,但如果每个用户都需要自己的线程与活动的 redis 和 http 连接,则可伸缩性不会很好。
Redis publish/subscribe is not designed for this scenario - it requires a persistent connection to redis, which you have if you are writing a worker process but not when you are working with stateless web requests.
A publish/subscribe system that works for end users over http takes a little more work, but not too much - the simplest approach is to use a sorted set for each channel and record the time a user last got notifications. You could also do it with a list recording subscribers for each channel and write to the inbox list of each of those users whenever a notification is added.
With either of those methods a user can retrieve their new notifications very quickly. It will be a form of polling rather than true push notifications, but you aren't really going to get away from that due to the nature of http.
Technically you could use redis pub/sub with long-running http connections, but if every user needs their own thread with active redis and http connections, scalability won't be very good.
实际上,Redis Pub/Sub 可以很好地处理这种情况,因为 Redis 是一个异步非阻塞服务器,它可以便宜地容纳许多连接,并且扩展性良好。
Salvatore(又名 Redis 先生 :) 描述了 O(1) 时间复杂度发布和订阅操作:
因此,Redis 的能力和设计是针对这种情况的,但是正如 Tom 指出的那样,为了维持持久连接,用户将需要长时间运行的连接(又名 http-push / long-poll),并且每个活动用户都会占用其自己的线程。持有线程对于可扩展性来说并不是很好,从技术上讲,您最好使用非阻塞 http 服务器,例如 Manos de Mono 或 node.js 是异步且非阻塞的,可以处理这种情况。注意:WebSockets 对于通过 HTTP 的实时通知更有效,因此理想情况下,如果用户浏览器支持它,则可以使用它,如果不支持,则回退到常规 HTTP (或在客户端上使用 Flash 进行 WebSockets)。
因此,并不是 Redis 或其 Pub/Sub 无法扩展,而是像 IIS 或 Apache 这样的线程 HTTP 服务器的并发连接数才是限制,也就是说您仍然可以支持相当数量的并发用户与 IIS (这篇文章建议 3000),并且由于 IIS 是瓶颈而不是 Redis,您可以轻松地添加一个额外的 IIS 服务器并分配负载。
Actually Redis Pub/Sub handles this scenario quite well, as Redis is an async non-blocking server it can hold many connections cheaply and it scales well.
Salvatore (aka Mr Redis :) describes the O(1) time complexity of Publish and Subscribe operations:
So Redis is more than capable and designed for this scenario, but the problem as Tom pointed out in order to maintain a persistent connection users will need long-running connections (aka http-push / long-poll) and each active user will take its own thread. Holding a thread isn't great for scalability and technologically you would be better off using a non-blocking http server like Manos de Mono or node.js which are both async and non-blocking and can handle this scenario. Note: WebSockets is more efficient for real-time notifications over HTTP, so ideally you would use that if the users browser supports it and fallback to regular HTTP if they don't (or fallback to use Flash for WebSockets on the client).
So it's not the Redis or its Pub/Sub that doesn't scale here, it's the number of concurrent connections that a threaded HTTP server like IIS or Apache that is the limit, with that said you can still support a fair amount of concurrent users with IIS (this post suggests 3000) and since IIS is the bottleneck and not Redis you can easily just add an extra IIS server into the mix and distribute the load.