This is the final article in the trilogy series ‘Building a Browser Push Notification Service’, you can find the previous article that talks about the implementation of a websocket server here.
这是三部曲系列“构建浏览器推送通知服务”中的最后一篇文章,您可以在 此处 找到有关Websocket服务器实现的上一篇文章 。
What are websocket servers, you ask? You can read all about it here.
您问什么是websocket服务器? 您可以在这里阅读所有内容。
What’s so different here? WebSocket Servers are typically different than our HTTP servers. You remember the coding wizards always telling you to keep your servers stateless? Well, that’s what simplifies certain aspects of the HTTP server. Now that we have introduced a state in the server, here are the challenges.1. Horizontal Scalability — The websocket server stores the connections. So now, say for example, our server ‘s1’ and server ‘s3’ have some active connections with the target ‘t’. Now, if we receive a notification ‘n’ that is to be sent to target ‘t’, we’ll have to somehow figure out and forward this notification to the servers ‘s1’ and ‘s3’, since these are the ones that have active connections with the target ‘t’. If it were stateless servers, a request could be simply routed to any of the servers, but since the servers have states, we’ll have to forward the requests on the particular servers. See the challenge here?2. New Connection Request Routing — For websocket servers, ideally we would want to equally distribute the active websocket connections handled by any server. This poses a challenge as a simple ‘Round-Robin’ algorithm would not help here. Say for example, we have 3 WS servers at this instant each handling about a few 100k connections. At this instant, a new WS server comes up. Now, to equally distribute the load, we would want to route all the incoming connection requests to the newly brought up server, until the active connection on this server matches the count on the other servers. See the challenge here?Let’s look at how we can solve these.
这里有什么不同? WebSocket服务器通常与我们的HTTP服务器不同。 您还记得编码向导总是告诉您使服务器保持无状态吗? 好吧,这就是简化HTTP服务器某些方面的事情。 现在我们已经在服务器中引入了一种状态,这是挑战1。 水平可伸缩性 — Websocket服务器存储连接。 例如,现在我们的服务器“ s1”和服务器“ s3”与目标“ t”具有一些活动连接。 现在,如果我们收到要发送给目标“ t”的通知“ n”,则我们必须以某种方式找出该通知并将其转发到服务器“ s1”和“ s3”,因为这些是与目标“ t”具有有效连接。 如果它是无状态服务器,则可以将请求简单地路由到任何服务器,但是由于服务器具有状态,因此我们必须在特定服务器上转发请求。 在这里看到挑战了吗? 2. 新的连接 请求路由 -对于websocket服务器,理想情况下,我们希望平均分配由任何服务器处理的活动websocket连接。 这带来了挑战,因为简单的“ Round-Robin”算法在这里无济于事。 例如,现在我们有3个WS服务器,每个服务器处理大约100k个连接。 此时,将出现一个新的WS服务器。 现在,为了平均分配负载,我们希望将所有传入的连接请求路由到新启动的服务器,直到该服务器上的活动连接与其他服务器上的计数匹配为止。 在这里看到挑战了吗? 让我们看一下如何解决这些问题。
Case in Point : So this is what we’re going to do, we’ll pick the same example as in the previous blogs. We’ll have a notification message ‘Hello, Alexander Hamilton!’ that we have to send to our target client named Alexander(’s browser client). We’ll assume this person has a laptop, a tablet and a desktop. He has our website ‘thefoundingfathers.com’ opened on a browser tab in all of these three devices. Going to this website has created websocket connections with our servers. We’ll assume we have three websocket servers. The target client ‘Alexander’ has three connections, connection 1 with WS (websocket) Server 1, and connection 2 and connection 3 with WS server 2, and no connections with WS server 3. So, as soon as our websocket service receives any notification for our target ‘Alexander’, we are to send the notification forward to all these three browser tabs (three connections).
案例: 这就是我们要做的,我们将选择与以前的博客相同的示例。 我们将收到一条 通知 消息:“ 您好,亚历山大·汉密尔顿! 我们必须将其发送到 名为 Alexander (浏览器客户端)的 目标客户 端。 我们假设这个人有一台笔记本电脑,一台平板电脑和一台台式机。 他 在所有这三种设备的浏览器选项卡上打开了 我们的网站“ thefoundingfathers.com ”。 转到该网站已与我们的服务器建立了websocket连接。 我们假设我们有三个websocket服务器。 目标客户端“ Alexander ”具有三个连接,即与WS(websocket)服务器1的连接1,以及与WS服务器2的连接2和连接3,与WS服务器3的连接。因此,只要我们的websocket服务收到任何通知,对于目标“ Alexander ”,我们将 通知 转发到所有这 三个浏览器选项卡(三个连接) 。
The Setup — This setup here basically would have two kinds of incoming requests. One, the websocket connection requests (the right side)., and two, the push notification requests (on the other side). Both of these will be tagged with a target id.Use Case : So, for our case, the websocket side load balancer received three connection requests all tagged with target id ‘Alexander’. It forwarded the 1st connection request to WS server 1. It forwarded the 2nd and the 3rd request to WS server 2. The notification side load balancer received one request for the notification ‘Hello, Alexander Hamilton!’, which was forwarded to the application service.
设置-此 在这里设置基本上将有两种传入请求。 一个是websocket连接请求 (在右侧),另一个是推送通知请求 (在另一侧)。 这两个标签都将标有目标ID。 用例: 所以,我们的情况下,WebSocket的侧负载平衡器收到了三个连接请求都标有目标ID“ 亚历山大 ”。 它将第一个连接请求转发到WS服务器1。将第二个和第三个请求转发到WS服务器2。通知端负载均衡器收到了一个关于通知“ Hello,Alexander Hamilton!”的 请求,该请求 已转发到应用程序服务。 。
In between the two load balancers, we would have three components, each horizontally scalable.
在两个负载平衡器之间,我们将具有三个组件,每个组件都可以水平扩展。
The cached storage system — This system stores the mapping between the target ids and the servers, i.e. the servers that hold an active connection with the target.
缓存的存储系统-该系统存储目标ID与服务器(即与目标保持活动连接的服务器)之间的映射。
The cached storage system — This system stores the mapping between the target ids and the servers, i.e. the servers that hold an active connection with the target.Use Case : The cached storage system has the mapping, which was populated by the websocket servers when they received the connection requests. ‘Alexander’ <-> WS Server 1, WS Server 2.
缓存的存储系统-该系统存储目标ID与服务器(即与目标保持活动连接的服务器)之间的映射。 用例: 缓存的存储系统具有映射,由websocket服务器在接收到连接请求时填充。 ' Alexander '<-> WS服务器1,WS服务器2 。
The application service — This service is used to query the cache system. All notification requests reach this service, to figure out the servers that hold a connection / multiple connections with the intended target. This service then forwards the requests to all these websocket servers.
应用程序服务-此服务用于查询缓存系统。 所有通知请求都到达此服务,以找出与预期目标建立连接/多个连接的服务器。 然后,该服务将请求转发到所有这些websocket服务器。
The application service — This service is used to query the cache system. All notification requests reach this service, to figure out the servers that hold a connection / multiple connections with the intended target. This service then forwards the requests to all these websocket servers. Use Case : The service, when it received the notification ‘Hello, Alexander Hamilton!’ for the target ‘Alexander’, it queried the cache system for the target and received WS Server 1, WS Server 2 in the response.
应用程序服务-此服务用于查询缓存系统。 所有通知请求都到达此服务,以找出与预期目标建立连接/多个连接的服务器。 然后,该服务将请求转发到所有这些websocket服务器。 用例: 服务在收到通知时通知 您好,亚历山大·汉密尔顿! 对于目标“ Alexander ”,它查询目标的缓存系统并 在响应中 接收到 WS Server 1,WS Server 2 。
The websocket servers — This is the server cluster that actually maintains all the active connections and pushes all the notification requests to the targets. Additionally, any time this server successfully registers or deregisters a websocket connection request, it accordingly updates the cache system to add / remove itself against the specific target.
websocket服务器-这是服务器集群,实际上维护所有活动连接并将所有通知请求推送到目标。 此外,该服务器每次成功注册或注销Websocket连接请求时,都会相应地更新缓存系统,以针对特定目标添加/删除自身。
The websocket servers — This is the server cluster that actually maintains all the active connections and pushes all the notification requests to the targets. Additionally, any time this server successfully registers or deregisters a websocket connection request, it accordingly updates the cache system to add / remove itself against the specific target.Use Case : These servers, specifically the WS server 1 and the WS server 2, when they received the connection request from the target ‘Alexander’, they updated the cache map for the target. Later, the server 1 and 2, when they received the notification ‘Hello, Alexander Hamilton!’, they pushed it over the active connections against the target ‘Alexander’.
websocket服务器-这是服务器集群,实际上维护所有活动连接并将所有通知请求推送到目标。 此外,该服务器每次成功注册或注销Websocket连接请求时,都会相应地更新缓存系统,以针对特定目标添加/删除自身。 用例: 这些服务器,特别是 WS服务器1 和 WS服务器2 ,当它们从目标“ Alexander ” 接收到连接请求时,将 更新目标的缓存映射。 稍后,服务器1和2收到通知时:“ 您好,亚历山大·汉密尔顿! ”,他们将其推向目标“ 亚历山大 ” 的主动联系 。
The Connection Request Routing concerns — For the new connection requests, the connection request Load Balancer can simply forward the request to the WS server that has the least active connection count. This way we can make the best effort that the load is equally distributed among the WS servers.
连接请求路由问题 -对于新的连接请求,连接请求负载均衡器可以简单地将请求转发到活动连接数最少的WS服务器。 这样,我们可以尽最大努力使负载在WS服务器之间平均分配。
With these implementation in place, we can horizontally scale to handle any number of websocket connections and notifications.
有了这些实现后,我们可以水平扩展以处理任意数量的websocket连接和通知。
In conclusion, the websocket connections for long now, have been present in the technology basket. Still, for reasons, there are a lot of problems thatpeople face and end up designing sub optimal systems. These series of articles is an attempt to help people avoid some of these.Got more suggestions or ideas even better? Reach out to me and let’s have a conversation! Happy developing!
总之,很长一段时间以来,websocket连接一直存在于技术领域。 尽管如此,由于某些原因,人们仍然面临许多问题,最终设计出次优系统。 这些系列文章旨在帮助人们避免其中一些问题。 与我联系,让我们开始对话! 发展愉快!
翻译自: https://medium.com/@singhania94/building-a-browser-push-notification-service-the-challenges-with-the-websocket-server-8cf9b1827e24
相关资源:jdk-8u281-windows-x64.exe