Netty在Firbase中的使用

news2024/11/27 0:38:48

1.1前言

实时更新是现代应用程序中用户体验的一个组成部分。随着用户期待这样的行为,越来越多的应用程序都正在实时地向用户推送数据的变化。通过传统的3层架构很难实现实时的数据同步,其需要开发者管理他们自己的运维、服务器以及伸缩。通过维护到客户端的实时的、双向的通信,Firebase提供了一种即使的直观体验,允许开发人员在几分钟之内跨越不同的客户端进行应用程序数据的同步——这一切都不需要任何的后端工作、服务器、运维或者伸缩。

实现这种能力提出了一项艰难的技术挑战,而Netty则是用于在Firebase内构建用于所有网络通信的底层框架的最佳解决方案。这个案例研究概述了Firebase的架构,然后审查了Firebase使用Netty以支撑它的实时数据同步服务的3种方式:长轮询、HTTP 1.1 keep-alive和流水线化、控制SSL处理器

2.1、Firebase的架构

Firebase允许开发者使用两层体系结构来上线运行应用程序。开发者只需要简单地导入Firebase库,并编写客户端代码。数据将以JSON格式暴露给开发者的代码,并且在本地进行缓存。该库处理了本地高速缓存和存储在Firebase服务器上的主副本(master copy)之间的同步。对于任何数据进行的更改都将会被实时地同步到与Firebase相连接的潜在的数十万个客户端上。

Firebase的服务器接收传入的数据更新,并将它们立即同步给所有注册了对于更改的数据感兴趣的已经连接的客户端。为了启用状态更改的实时通知,客户端将会始终保持一个到Firebase的活动连接。该连接的范围是:从基于单个Netty Channel的抽象到基于多个Channel的抽象,甚至是在客户端正在切换传输类型时的多个并存的抽象。

因为客户端可以通过多种方式连接到Firebase,所以保持连接代码的模块化很重要。Netty的Channel抽象对于Firebase继承新的传输来说简直是梦幻般的构件块,此外,流水线和处理器模式使得可以简单地传输相关的细节隔离开来,并为应用程序代码提供了一个公共的消息流抽象。同样的,这也极大地简化了添加新的协议支持所需要的工作。Firebase只通过简单地添加几个新的ChannelHandler到ChannelPipeline中,便添加了对一种二进制传输的支持。对于实现客户端和服务器之间的实时连接而言,Netty的速度、抽象的级别以及细粒度的控制都使得它成为了一个卓绝的框架。

2.2、长轮询

Firebase同时使用了长轮询和WebSocket传输。长轮询传输是高度可靠的,覆盖了所有的浏览器、网络以及运营商;而基于WebSocket的传输、速度更快,但是由于浏览器/客户端的局限性,并不总是可用的。开始时,Firebase将会使用长轮询进行连接,然后在WebSocket可用时再升级到WebSocket。对于少数不支持WebSocket的Firebase流量,Firebase使用Netty实现了一个自定义的库来进行长轮询,并且经过调优具有非常高的性能和响应性。

Firebase的客户端库逻辑处理双向消息流,并且会在任意一端关闭流时进行通知。虽然这在TCP或者WebSocket协议上实现起来相对简单,但是在处理长轮询传输时它仍然是一项挑战。对于长轮询的场景来说,下面两个属性必须被严格地保证:

——保证消息的按顺序投递

——关闭通知

1-保证消息的按顺序投递

可以通过使得在某个指定的时刻有且只有一个未完成的请求,来实现长轮询的按顺序投递。因为客户端不会在它收到它的上一个请求的响应之前发出另一个请求,所以这就保证了它之前所发出的所有消息都被接收,并且可以安全地发送更多的请求了。同样,在服务器端,直到客户端收到之前的响应之前,将不会发出新的请求。因此,总是可以安全地发送缓存在两个请求之间的任何东西。然而,这将导致一个严重的缺陷。使用单一请求技术,客户端和服务器端都将花费大量的时间来对消息进行缓冲。例如,如果客户端有新的数据需要发送,但是这是已经有了一个未完成的请求,那么它在发出新的请求之前,就必须得等待服务器的响应。如果这时在服务器上没有可用的数据,则可能需要很长时间。

一个更加高性能的解决方案则是容忍更多的正在并发进行的请求。在实践中,这可以通过将单一请求的模式切换为最多两个请求的模式。这个算法包含了两个部分:

——每当客户端有新的数据需要发送时,它都将发送一个新的请求,除非已经有两个请求正在被处理

——每当服务器接收到来自客户端的请求时,如果它已经有了一个来自客户端的未完成的请求,那么即使没有数据,他也将立即回应第一个请求。

相对于单一请求的模式,这种方式提供了一个重要的改进:客户端和服务器的缓冲时间都被限定在了最多一次的网络往返时间里。

当然,这种性能的增加并不是没有代价的;它导致了代码复杂性的相应增加。该长轮询算法也不再保证消息的按顺序投递,但是一些来自TCP协议的理念可以保证这些消息的按顺序投递。由客户端发送的每个请求都包含一个序列号,每次请求时都将会递增。此外,每个请求都包含了关于有效负载中的消息数量的元数据。如果一个消息跨越了多个请求,那么在有效负载中所包含的消息的序号也会被包含在元数据中。

服务器维护了一个传入消息分段的环形缓冲区,在它们完成之后,如果它们之前没有不完整的消息,那么会立即对它们进行处理,下行要简单点,因为长轮询传输响应时HTTP GET请求,而且对于有效载荷的大小没有相同的限制。在这种情况下,将包含一个对于每个响应都将会递增的序列号,只要客户端接收到了达到指定序列号的所有响应,他就可以开始处理列表中的所有消息;如果它没有收到,那么它将缓冲该列表,直到它接收到这些为完成的响应。

2-关闭通知

在长轮询传输中第二个需要保证的属性是关闭通知。在这种情况下,使得服务器意识到传输已经关闭,明显要重要与使得客户端识别到传输的关闭。客户端所使用的Firebase库将会在连接断开时将操作放入队列以便稍后执行,而且这些被放入队列的操作可能也会对其它仍然连接着的客户端造成影响。因此,知道客户端什么时候实际上已经断开了是非常重要的。实现由服务器发起的关闭操作是相对简单的,其可以通过使用一个特殊的协议级别的关闭消息响应下一个请求来实现。

实现客户端的关闭通知是比较棘手的。虽然可以使用相同的关闭通知,但是有两种情况可能会导致这种方式失效:用户可以关闭浏览器标签页,或者网络连接也可能会消失。标签页关闭的这种情况可以通过iframe来处理,iframe会在页面卸载时发送一个包含关闭消息的请求。第二种情况则可以通过服务器超时来处理。小心谨慎地选择超时值大小很重要,因为服务器无法区分慢速的网络和断开的客户端。也就是说,对于服务器来说,无法知道一个请求是被实际推迟了一分钟,还是该客户端丢失了它的网络连接。相对于应用程序需要多快地意识到断开的客户端来说,选取一个平衡了误报所带来的成本的合适的超时大小是很重要的。

下图演示了Firebase的长轮询传输是如何处理不同类型的请求的。 

在这个图中,每个长轮询请求都代表了不同类型的场景,最初,客户端向服务器发送了一个轮询(轮询0)。一段时间之后,服务器从系统内的其它地方接收到了发送给客户端的数据,所以它使用该数据响应了轮询0。在该轮询返回之后,因为客户端目前没有任何未完成的请求,所以客户端有立即发送了一个新的轮询(轮询1)。过了一会儿,客户端需要发送数据给服务器。因为它只有一个未完成的轮询,所以它有发送了一个新的轮询(轮询2),其中包含了需要被递交的数据。根据协议,一旦在服务器同时存在两个来自相同的客户端的轮询时,它将响应第一个轮询。在这种情况下,服务器没有任何已经就绪的数据可以用于该客户端,因此它发送回了一个空响应。客户端也维护了一个超时,并将在超时被触发时发送第二次轮询,即使它没有任何额外的数据需要发送。这将系统从由于浏览器超时缓慢的请求所导致的故障中隔离开来。

2.3、HTTP 1.1 keep-alive和流水线化

通过HTTP 1.1 keep-alive特性,可以在同一个连接上发送多个请求到服务器。这使得HTTP流水线化——可以发送新的请求而不必等待来自服务器的响应,成为了可能。实现对于HTTP流水线化以及keep-alive特性的支持通常是直截了当的,但是当混入了长轮询之后,他就明显变得更加复杂起来。

如果一个长轮询请求紧跟着一个REST(表征状态转移)请求,那么将有一些注意事项需要被考虑在内,以确保浏览器能够正确工作。一个Channel可能会混和异步消息(长轮询请求)和同步消息(REST请求)。当一个Channel上出现了一个同步请求时,Firebase必须按照顺序同步响应该Channel中所有之前的请求。例如,如果有一个未完成的长轮询请求,那么在处理该REST请求之前,需要使用一个空操作对该长轮询传输进行响应。

下图说明了Netty是如何让Firebase在一个套接字上响应多个请求的。 

 如果浏览器有多个打开的连接,并且正在使用长轮询,那么它将重用这些连接来处理来自这两个打开的标签页的消息。对于长轮询请求来说,这是很困难的,并且还需要妥善地管理一个HTTP请求队列。长轮询请求可以被中断,但是被处理的请求却不能。Netty使服务于多种类型的请求很轻松。

——静态的HTML页面:缓存的内容,可以直接返回而不需要进行处理;例子包括一个单页面的HTTP应用程序、robots.txt和crossdomain.xml

——REST请求:Firebase支持传统的GET、POST、PUT、DELETE以及OPTIONS请求

——WebSocket:浏览器和Firebase服务器之间的双向链接,拥有它自己的分帧协议

——长轮询:这些类似于HTTP的GET请求,但是应用程序的处理方式有所不同。

——被代理的请求:某些请求不能由接收它们的服务器处理。在这种情况下,Firebase将会把这些请求代理到集群中正确的服务器。以便最终用户不必担心数据存储的具体位置。这些类似于REST请求,但是代理服务器处理它们的方式有所不同。

——通过SSL的原始字节:一个简单的TCP套接字,运行Firebase自己的分帧协议,并且优化了握手过程。

Firebase使用Netty来设置好它的ChannelPipeline以解析传入的请求,并随后适当地重新配置ChannelPipeline剩余的其它部分。在某些情况下,如WebSocket和原始字节,一旦某个特定类型的请求被分配给某个Channel之后,它就会在它的整个生命周期内保持一致。在其他情况下,如各种HTTP请求,该分配则必须以每个消息为基础进行赋值。同一个Channel可以处理REST请求、长轮询请求以及被代理的请求。

2.4、控制SslHandler

Netty的SslHandler类是Firebase如何使用Netty来对它的网络通信进行细粒度控制的一个例子。当传统的Web技术栈使用Apache或者Nginx之类的HTTP服务器来将请求传递给应用程序时,传入的SSL请求在被应用程序的代码接收到的时候就已经被解码了。在多租户的架构体系中,很难将部分的加密流量分配给使用了某个特定服务的应用程序的租户。这很复杂,因为事实上多个应用程序可能使用了相同的加密Channel来和Firebase通信(例如,用户可能在不同的标签页中打开了两个Firebase应用程序)。为了解决这个问题,Firebase需要在SSL请求被解码之前对它们拥有足够的控制来处理它们。

Firebase基于带宽向客户进行收费。然而,对于某个消息来说,在SSL解密被执行之前,要收取费用的账户通常是不知道的,因为它被包含在加密了的有效负载中。Netty使得Firebase可以在ChannelPipeline中的多个位置对流量进行拦截,因此对于字节数的统计可以从字节刚被从套接字读取出来时便立即开始。在消息被解密并且被Firebase的服务器端逻辑处理之后,字节计数便可以被分配给对应的账户。在构建这项功能时,Netty在协议栈的每一层上,都提供了对于处理网络通信的控制,并且也使得非常精确的计费、限流以及速率限制成为了可能,所有的这一切都对业务具有显著的影响。

Netty使得通过少量的Scala代码便可以拦截所有的入站消息和出站消息并且统计字节数成为了可能。

2.5、Firebase小结

在Firebase的实时数据同步服务的服务器端架构中,Netty扮演了不可或缺的角色。它使得可以支持一个异构的客户端生态系统,其中包括了各种各样的浏览器,以及完全由Firebase控制的客户端。使用Netty,Firebase可以在每个服务器上每秒钟处理数以万计的消息。Netty之所以非常了不起,有以下几个原因:

——他很快:开发原型只需要几天时间,并且从来不是生成瓶颈

——它的抽象层次具有良好的定位:Netty提供了必要的细粒度控制,并且允许在控制流的每一步进行自定义。

——它支持在同一个端口上支撑多种协议:HTTP、WebSocket、长轮询以及独立的TCP协议

——它的GitHub库是一流的:精心编写的javadoc使得可以无障碍地利用它进行开发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1169267.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

会声会影2024对比2023变化以及功能对比

全新会声会影2024版本现已登场,小伙伴们相信已经急不可待地想知道2024版到底有哪些新功能。对比2023版本,会声会影2024版本有没有功能的增强?事不宜迟,现在就让我们一起来看看会声会影2024对比2023的变化,包括功能对比…

Spring Boot整合Swagger

🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开心好久好久😎 📚系列专栏:Java全栈,…

Java 为什么不推荐在 while 循环中使用 sleep() 我悟了

文章目录 前言原因是否正确方案是否合理定时轮询场景事件机制等待和唤醒 个人简介 前言 最近逛 CSDN 看到一篇文章,文章大意是说为什么在循环中不推荐使用 sleep 操作,原因在于线程挂起和唤醒会有很大的性能消耗,并推荐使用 Timer 及 Schedu…

描述低轨星座的特点和通信挑战,以及它们在5G和B5G中的作用。

文章目录 2章4 章5章(没看)6章(没看) 2章 将卫星星座中每个物理链路中可实现的数据速率、传播延迟和多普勒频移与3GPP技术报告中的参数进行分析和比较[3]。 相关配置 面向连接的网络,预先简历链路 卫星和地面终端有…

能卷死同行的收银系统源码--服装店收银系统+进销存、PHP+mysql

涉及零售服装门店收银系统源码 超市务管理系统源码 便利店收银系统源码 进销存erp/scrm的供应链订货系统源码 saas门店连锁加盟收银系统源码 走过路过不要错过。 整理采用ThinkPHPmysql,二开门槛低, 模块化设计,前后端分离。 前端&…

使用JMeter进行接口压力测试

1.我首先创建一个线程组 2.创建好之后如图所示 3. 进行配置 4. 然后添加一个https请求 5.创建好之后设置请求方法和对应参数 6.设置表格监听器 7.创建好之后如图所示 8.保存jmx文件后点击运行进行测试,结果反馈如下图

Maxwell for 3dMax渲染器的安装方法

Maxwell渲染器的安装方法 Maxwell Render是一个基于控制光传输的数学方程的渲染引擎,这意味着所有元素,如发射器材料和相机,都是从物理精确的模型中导出的。Maxwell Render是无偏的,因此不使用任何技巧来计算场景中每个像素的照明…

信息论基础知识1

1.1 自信息定义:把某个消息出现的不确定性大小,用这个消息出现的概率的对数表示: I(X)-logp(x) 1.2 在任何一个信息流通的系统中,都有一个发出信息的发送端(信源),有一个接收信息的接收端…

我的计算机启蒙书:信息学竞赛入门书提高篇

你是否曾读过一本让你欲罢不能的计算机书籍?它可能为你打开了新的技术世界大门,或者是帮助你解决了棘手的编程难题。 我从百度上搜到其相关介绍: 信息学奥赛一本通,是一本系统性、综合性的信息学竞赛教材,由著名信息学…

[架构之路-254/创业之路-85]:目标系统 - 横向管理 - 源头:信息系统战略规划的常用方法论,为软件工程的实施指明方向!!!

目录 总论: 一、数据处理阶段的方法论 1.1 企业信息系统规划法BSP 1.1.1 概述 1.1.2 原则 1.2 关键成功因素法CSF 1.2.1 概述 1.2.2 常见的企业成功的关键因素 1.3 战略集合转化法SST:把战略目标转化成信息的集合 二、管理信息系统阶段的方法论…

Ubuntu20.04下安装Redis环境

apt安装Redis环境 更新apt-get安装镜像源 安装Redis sudo apt-get install -y redis-server设置密码 # 编辑Redis的配置文件redis.conf,如果不知道配置文件的位置可以执行whereis redis.conf查看 sudo vim /etc/redis/redis.conf取消文件中的requirepass注释&am…

draw.io与项目管理——如何利用流程图工具提高项目管理效率

draw.io 是一款强大的图形绘制工具,用于创建各种类型的图表、流程图、组织结构图、网络图和平面设计等。它提供了丰富的绘图工具和预定义的图形库,使用户能够轻松创建专业水平的图形作品。 draw.io具有直观的界面和简单易用的功能,适合各种用…

Windows 安全

Windows sec study N F T S 文件系统 \color{#FC5531}{NFTS 文件系统} NFTS文件系统 常用命令 \color{#FC5531}{常用命令} 常用命令 磁盘管理 \color{#FC5531}{磁盘 管理} 磁盘管理 文件备份 \color{#FC5531}{文件备份} 文件备份 安全策略管理 \color{#FC5531}{安全策略管理} 安…

旧手机搭建linuxcentos

centos服务器搭建termux搭建centos旧手机搭建linux服务器ubuntu旧手机搭建网站旧手机搭建linux debian ubuntu centos 旧手机搭建宝塔搭建 32位Linux搭建宝塔 Linuxdeploy搭建宝塔 旧手机搭建服务器有需要的来 包答疑包售后 Linuxdeploy需要root mobile搭建服务器 脚本/工具

基于python+django+vue开发的酒店预订管理系统 - 毕业设计 - 课程设计

文章目录 源码下载地址项目介绍项目功能界面预览项目备注毕设定制,咨询 源码下载地址 点击这里下载源码 项目介绍 该系统是基于pythondjango开发的酒店预定管理系统。适用场景:大学生、课程作业、毕业设计。学习过程中,如遇问题可在github…

【【嵌入式开发 Linux 常用命令系列 10 -- Linux 修改终端下 ls 各种类型文件的显示颜色】

文章目录 Linux 修改终端下各种类型文件的显示颜色LS_COLORS 详细介绍 Linux 修改终端下各种类型文件的显示颜色 在 ~/.bashrc 文件最下面添加如下内容,就可以配置目录、文件、sh类型文件的颜色了。 export LS_COLORSdi1:fi0:*.sh33:$LS_COLORS这句话的意思就是在…

Portraiture(PS磨皮滤镜) V4.5.3 免费版

Portraiture4.5.3免费版 是一款闻名已久的人像磨皮滤镜,用户只需要在PS软件中添加插件,就能进行智能的磨皮精修图片,节省了用户繁琐的手工劳动,并且效果十分理想,保持皮肤的纹理,去除瑕疵,功能十…

Ps:PSDT 模板文件

自 Photoshop CC 2015.5 版以后,Ps 中新增了一种文件格式:.PSDT。 说明: PSD、PDD、PSDT 都是 Ps 的专用文件格式,需要继续在 Ps 中进行编辑的文件可存为此类格式。 PSD Photoshop document Photoshop 默认文档格式,支…

学习LevelDB架构的检索技术

目录 一、LevelDB介绍 二、LevelDB优化检索系统关键点分析 三、读写分离设计和内存数据管理 (一)内存数据管理 跳表代替B树 内存数据分为两块:MemTable(可读可写) Immutable MemTable(只读&#xff0…

本地部署Jellyfin影音服务器并实现远程访问影音库

文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 1. 前言 随着移动智能设备的普及,各种各样的使用需求也被开发出来&…