如果你项目的唯一问题是用户增长过快,那你大概只会欣喜若狂而非愁眉苦脸。但你也知道,这个问题会造成严重的性能影响,比如服务器速度下降,这是你迟早要面对的。当然,你也可以选择“活在当下”,享受增长的利润。通常来说,“更多用户=更高收入”,但之后你还是得回来解决这个问题。
如果解决不了呢?那就做好准备面对高昂的服务器收费,如果后来情况真的不妙,那么你的用户可能就要被市面上的竞争对手抢走了。不过别担心,你不需要一个人面对。在这篇文章中,你将得到一些优化并扩展 Meteor 项目的建议,不仅能节约你的时间还能省下一笔预算。
性能监控
在开始优化之前,你得先搞清楚有什么是需要被优化的。幸运的是,目前有不少工具可以选择:
应用性能管理(APM)工具检测诊断复杂的应用性能问题,让你可以监控分析系统中的任何问题。对于 Meteor 应用,除了常规的内存使用、会话连接等统计数据。在你的项目中,有几种 APM 服务可以与 Meteor 一起使用,下面列出了两个最常用的:
Meteor APM:顾名思义,这是由 Meteor 软件团队开发,可从银河开发者版中获取。
Monti APM:用于系统监控的独立系统。Monti 的免费版可保留八个小时的数据。和 Meteor APM 相比,Monti 更便宜。
不过,APM 并不是专门为 Meteor 私人定制的工具,如下这些技术场景中 APM 也有不错的应用:
Monti APM
Monti APM 提供了许多可以用来监测系统参数的工具,其中的常规主视图不仅可以展示发布的详细数据、使用的方法,还可以监测用户浏览器内前端及后端的故障。Monti APM 能做的事有很多,这篇文章中只会列出少数几种可能性做些铺垫。关于更多信息,可以查看Monti APM文档。
在开始收集数据分析统计分析之前,你得先创建一个账号,选择合适的收费方案,通过包含 API 密钥的单行模块配置将Monti APM软件包引入到你的项目中。
找到需要改进的方法
下面让我们看看现实生活中是如何通过服务改善产品的。有的方法可能非常耗时,因此花些时间仔细分析这些方法是比较明智的选择:
在“方法(Methods)”标签的详细视图中
按方法的响应时间进行分类排序
选择“方法分类”中的方法,查看优化改进后的影响
查看响应时间图表,找到痕迹
在合适的时机优化方法
不是每一个运行时间长的方法都是需要优化的,以下面这个情况为例:
X 方法:平均反应时间 1,515 毫秒,吞吐量为 10005 每秒
Y 方法:平均反应时间 34,000 毫秒,吞吐量为 0,03 每秒
这个 34 秒的响应时间在第一眼看上去非常引人注意,所以你或许认为 Y 方法更适合优化,但要知道这个方法可能只会每几小时被系统管理员或 cron 动作调用一次。
那 X 方法呢?它的反应时间明显更短,但是却有相对更高的使用频率,毫无疑问它更应该被优先优化。
优化示例
在性能测试中,你可能会注意到有些应用的部分性能还不够好,下面的例子中会告诉你该怎么做得更好:
不要忘记,这些例子只是通过参考并使用性能测试数据来找到问题并提出解决方案,有的优化问题可能与你的项目毫无关系,问题的根因可能在其他地方。
另外非常重要的一点在于,不要随心所欲地优化任何你想优化的,关键在于战略考量,将问题重要级与产品优先级相匹配。
低观察者模式复用
Meteor 中创建的订阅可以缓存结果。利用队列排序等参数相同的返回光标跳读数据库,从而在此基础上,计划 Meteor 订阅的开发,在每次获取中尽可能多地共享数据。
图中的应用有一个“用户通知”的订阅,可以同时向所有连接应用程序的用户,发送全局或针对具体用户的通知,这个功能需要为所有已登录的用户,获取大量各种类型的信息数据。
问题在于,这个发布只有 7%的观察者模式复用率,意味着只有 7%的用例能复用已缓存的结果。以下是这个功能的代码:
这意味着大多数用户所获取到的文件列表都会有些许不同,因此我们不能直接将上一次获取到的信息直接提供给其他用户。一个解决方案是将发布分成两个小部分:
针对用户:
全局提供:
这样一来,这个订阅在全局有 100%的观察者模式复用,另外在针对用户方面有 7%的复用率。后者在数字上虽然没什么变化,但每个用户获取的数据量都要更少。全局通知的复用比率更高,且可为所有用户复用。
复杂功能的优化
假设在一个场景中,应用需要在每天同一时间发送上千封电子邮件,提醒客户餐馆的服务或者他们第二天的就餐预定。
在 2021 年年初,每 24 小时团队都需要推送超过 200 封电子邮件,此时一切正常。但在随后的几个月内,需要发送的电子邮件数量逐渐增加到上万,邮件发送程序占用了系统的所有资源,导致了系统过载。
这种场景下,你会提供怎样的解决方案呢?
首先,我们可以扩展可用资源(垂直扩展),虽然会立刻拉高服务器成本,但确实也解决了问题,对吗?不一定。如果后续电子邮件数量再次增长,你还要再花更多钱扩容吗?如果答案是否定的,那么就必须分析代码以找到更合适的解决方案。
另一种简单的方案是将邮件分批次发送,在三小时而不是十五分钟内完成任务。基于邮件发送的复杂性,你还有几种可选的实现思路:可以用内存队列,或者用Redis、RabbitMQ等第三方的队列系统。
不可预测的加载时间
参考一个美容沙龙工时管理系统的例子。根据常识分析,沙龙的员工会轮班工作,一般会有早中晚三个班,对不对?客户和开发团队也是这么想的,并按照这种用户体验设计了网页应用发布模块。
但某天一个美容沙龙提交了问题反馈:网站主页加载速度太慢。猜猜看是什么导致了这个问题?这家沙龙把未来两年内的每日安排,一共三千五百个排班全加到系统里去了,所有发布同时加载,所以才会非常慢。
解决方案也很简单,不要同时加载所有发布。这类情况下,开发团队的任务就是随时监测并应对处理新出现的问题。这也是大多数性能问题的根因所在:对结果没有全面考虑就会导致问题的发生。
数据库索引
假设我们想要获取特定日期内线上商城中指定类别的订单列表,而 Mongo 数据库内数据量又非常之大,那么请求的处理速度自然会慢。
等等,你说“慢”?MongoDB 的索引来救场了!
索引是独特的数据结构,只保存文件集合中的一小部分,以及对原始数据在原集合中的引用。数据库中的数据经过预先排序和对特定参数的筛选后,让连续搜索可以速度更快。因此 Mongo 也不用再逐个文件地分析是否满足条件了。
在前面的例子中,索引大概长这样:
上面这行代码创建了一个多键的索引(category 和 createdAt)并以升序排列(-1 表示降序)。每个带参数的查询请求都会在这个排好序的元素中搜索,如果你通过索引更新了集合,那么 MongoDB 也会自动更新其索引。
扩展
应用优化不是一切,在不更换硬件的前提下你甚至还能做到更高的性能优化。如今,我们不用再手动更换可用内存或处理器内存了,云解决方案可以帮我们更有效地利用资源。
垂直及水平扩展
扩展有两条路可以走:垂直和水平扩展。
垂直扩展本质在于给服务器内添加更多的资源(CPU、RAM、磁盘),而水平扩展则是指向资源池内添加更多的机器或容器。
Meteor 项目的水平扩展通常是指在一台多核服务器或多个服务器上,运行应用的多个实例。
自动扩展
自动扩展是一个可以根据当前资源使用情况,自动增减服务器能力的工具,让你可以不用再为没用过内存、CPU 或容器掏钱了。唯一的问题就是,你得先在 Meteor 云上注册银河专业(Galaxy Professional)付费计划。
在 Meteor 云上,你可以手动配置两个参数:容器种类(垂直扩展)以及容器数量(水平扩展)。可以在项目主页修改这两个参数,短短几秒就能应用变更。
在这些的基础上,还可以展开性能统计图表,并根据使用情况手动修改容器的类型和数量。再进一步的自动化,比如根据一天中的时间自动更改配置,那就得靠自动扩展的触发器在满足的条件下自动执行了。具体条件如:如果 CPU 用量在每天晚 11:00 后低于 10%,则将容器数量从 6 缩减为 2。
写在最后
希望你的应用程序在市场上大受欢迎,知名度和收入都能直线上升,可惜你大概也遇上了不少性能难题。当然,不少人宁愿自己能享受你的痛苦。或许本文中的建议能帮你驱除这个美梦中酸涩回味。
简而言之,记得把应用性能管理工具连接到你的程序中,学会如何分析和使用这些工具中的高级统计数据,关注系统中的具体瓶颈。下一步要做的就是自动扩展。设置触发器有助于减少开销。
这些都完成后,我向你保证,你的应用性能应该能有非常明显的改善。如果你的应用程序情况要比文中描述得复杂,点击查看更多信息。
原文链接:
How to optimize and scale Meteor projects?
推荐阅读:
评论