为了减轻系统开发和运维的负担,引入Firebase并获得了相关经验

我是@eaglesakura。

因为在DroidKaigi 2018的申请中未能成功,所以我选择在Qiita上撰写。

为了成功完成一个(依据我的感觉)规模较大的项目,我们在整个项目中全面利用Firebase,大致上取得了成功,为了日后的记录,我会写下我们做了什么。

前提 = 条件

这是关于面向消费者的Android/iOS应用程序开发的讨论。

引入Firebase实时数据库的原因

根据应用程序的要求,在无数的Android / iOS设备上实时同步服务器上的主数据是必要的,因此Firebase实时数据库是一个可行的选择,我们决定引入它。

Firebase实时数据库是否值得信赖?

在示威活动当天,Firebase实时数据库出现故障。

我只是认为这是运气不好的事情罢了。因为Firebase RDB本来就经常断掉,所以我们进行了基于这一前提的系统设计。

我是如何生成Firebase数据的

在这个应用程序中,主要的要求是“主数据=多个角色的数据出现在应用程序内,所有终端实时了解”。

    サーバー側の処理
    1. 服务器生成主数据

 

    1. 这些主数据几乎每秒都会更新一次

 

    1. 在服务器上保存主数据

 

    服务器修改Firebase实时数据库的数据
    アプリ側の処理
    连接至Firebase实时数据库。当服务器修改实时数据库时,数据将被推送到应用程序,以便根据应用程序的需要进行处理。

由于这个机制,直到应用程序超过 Firebase 的最大同时连接数量 100k 之前,GAE/Go 端不必担心负载。

使用Firebase Functions与服务器进行协作

在这个应用程序中,需要从几台Android设备(业务设备)中收集数据以生成主数据。

当业务终端将数据写入Firebase实时数据库的 /${非公开数据路径}/${分配给每台终端的路径},Firebase 函数将启动并将数据输入到GAE/Go中。
GAE根据输入的数据生成主数据,并将其写入Firebase实时数据库的 /${主数据路径}。

功能的配额

業務端末的數據每秒寫入數次以上,每次寫入都會觸發Firebase Functions,並產生與服務器之間的https通訊。將通訊相關的配額像開水一樣使用,很快就會觸及配額限制。

这次我们通过与Google联系来解决,可以提高配额来应对,但是要注意,配额可能意外地很快就会被耗尽,因此在设计时要考虑这一点。

如果Firebase无法使用,应该怎么办?

如果设备检测到Firebase实时数据库已经宕机,应用程序将直接改变连接目标并调用服务器的API,然后每隔一定时间进行轮询。

由于服务器持续保留了已经写入Firebase实时数据库的数据本身,因此只需创建一个作为API的数据提取口即可。由于主数据始终会更新,所以几乎可以肯定地从Memcache快速获取。

尽管实时性大大减少,但我们努力避免了“完全无用”的情况。

无论是幸运还是Google的努力的结果,该应用程序在提供期间内备份处理并没有发挥作用。

我們如何檢測到即時數據庫發生故障?

如果实时数据库发生故障,会发生什么事情似乎是不确定的。此外,似乎很难再现出故障时的处理过程。

我们在应用内进行了以下检查,并采取了设置以避免其他情况在操作中可能发生的策略。

    検出チェック事項
    1. 如果/.info/connected被设为false一段时间,就判断为宕机。

参考链接:https://firebase.google.com/docs/database/android/offline-capabilities?hl=ja

如果主数据在一定时间内没有更新,则判断为宕机。

使用Firebase存储

大多数用于应用内使用的资源通过将其存储在Firebase存储中并在首次使用应用时下载的方式来进行管理。在这个过程中,我们需要解决一些Firebase存储软件开发工具包的问题。

无法检索文件列表的问题。

根据对Firebase Storage SDK的了解,似乎没有提供列举指定路径下所有文件的功能。

在GAE上创建类似于资源列表和版本获取,或者资源下载的API也是一种选择,但与其进行涉及数万台设备并且需要进行数据库访问的动作验证和测试,我们选择将开发资源集中在业务逻辑的重要部分。

因此,我们决定自动生成一个名为resources.json的文件,其中包含了要下载资源的路径列表,并将其上传到Firebase存储。

    1. 下载包含文件列表的 resources.json 文件。

 

    下载其中包含的所有文件。

由于resources.json文件是嵌入在部署过程中的,它会自动进行生成和重新配置。

下载时间太长的问题 de

由于将数据存储在Firebase Storage中,数据主要是图像,因此在创建时总计达到了大约100MB的PNG文件大小。由于该应用主要在室外下载和使用,当前情况下会导致用户需要等待多达几十分钟才能启动应用。

因此,我们将使用的所有图像都压缩为webp格式。这样一来,下载总大小就能减小到约10MB左右。webp压缩处理也已经纳入部署流程中,并且压缩率的调整也都可以通过CI进行。

资源更新检测问题

Firebase存储上传的数据基本上是固定的,但假设出现某种情况导致需要更新。

虽然通过SDK可以检测到更新,但是如果对所有文件通过API进行更新检查,处理时间会变得非常长。

因此,在这个应用程序中,我们给Remote Config添加了资源版本号,当资源版本被更新时,我们采取了重新下载所有资源的策略。

通过WebP转换,资源本身变得更小,并且通过简化机制,我认为总体上可以顺利解决问题。

在Firebase Remote Config中放了什么的东西?

除了应用程序所固有的功能外,我们在运营方面还在 Remote Config 中增加了一些方便的属性。

    1. 资源版本

从Firebase Storage重新下载资源更新后
先将一部分用户进行先行发布,如果没有问题再推广给所有用户

应用信任标志

通过Remote Config的A/B测试功能,执行了诸如”发生故障的版本将强制显示更新对话框,并无法继续进行”等的操作

Firebase Realtime Database连接许可标志

如果为false,将直接使用服务器API进行交互,而不使用Realtime Database
如果无法检测到Realtime Database出现故障,则可以通过该标志强制更改目标地址

此外,还考虑到当连接设备数量超过限制时,可以让其充当负载均衡器的角色。

使用Firebase Cloud Messaging来实现“复活的咒语”。

Firebase云消息传递(FCM)通常用于向用户发送新通知等(实际上,本次也是这样的用例),除此之外,我们还结合了Firebase实时数据库来监控Android企业设备的运行状态。

Android业务终端会不断向Realtime Database写入数据,但是如果终端在一定时间内没有更新,可以断定应用程序已经关闭。(实际上,在连接断开时可以修改RDB数据,通过这种方式来判断)

通常情况下,只需要重新启动应用程序就可以解决问题。但是,由于在此项目中使用的业务终端位于一个难以接触的物理位置上运行,我们需要远程检查和控制所有内容。因此,如果应用程序崩溃,我们会通过FCM发送设备ID和命令对,通过Google Play服务“唤醒应用程序”或“执行特定操作”。

    1. 在运营方面判断”业务设备的应用程序崩溃”

 

    1. 通过FCM发送应用程序重新启动命令

 

    应用程序进程重新启动,业务设备再次恢复功能。

利用Firebase身份验证的方法

为了保证安全性,Firebase实时数据库和存储要求进行身份验证。在此过程中,使用Firebase自定义令牌来实现默认的读/写不允许权限。Android和iOS只能以只读模式访问指定路径,而业务终端可以在指定路径上进行写入操作。

由于自定义令牌生成在服务器端进行,因此预计在用户集中的情况下会发生负载。然而,由于不涉及数据存储访问(全部在CPU/内存中完成),因此可以放心地交给GAE的扩展来处理问题。

Firebase测试实验室

这个句子的中文翻译如下:
尽管仅限于Android,但我们使用Firebase Testlab来进行Android应用的单元测试。对于本次应用来说,每个开发者每月将产生约500美元的费用。

此外,根据情况来看,Test Lab的设备启动速度较慢,有时甚至会无法启动而超时(不稳定)。初始状态下GPS是开启的,但蓝牙是关闭的,设置上存在一些小问题。
因此,如果遇到启动速度较慢或不稳定的Test Lab设备,可以考虑暂时切换到其他设备进行测试。

由于启动活动(Activity)的测试特别不稳定,当在25台终端(矩阵)上运行时,大约会有1到2台终端会崩溃。因此,我们调整了测试以涉及活动(Activity)和片段(Fragment),只在本机设备上(通过Android Studio)进行测试。

Firebase Analytics / Crash Reporting 火力地堡分析 / 崩溃报告

除了用于应用程序改进外,它还在调试方面非常有用。

通过在该应用程序中触发事件来处理稀有情况的异常和流程,从而作为分析信息的一部分获取故障等信息。

不过,我们同样可以准确确认那些在“正常情况下很少发生”的情况确实发生过。
无论如何,Analytics对于开发和持续改进也很有用,除了收集需求之外。

崩溃报告会自动收集和上传信息,可以发送除崩溃外的异常情况。

最终

Firebase是一个非常强大和出色的服务,作为GCP各种服务的封装(除了Realtime Database)。
它的稳定运行状况非常好(除了Realtime Database偶尔出现故障),如果您有适合的用例,请积极尝试引入。

广告
将在 10 秒后关闭
bannerAds