注:本文涵盖了我在 2019 越南 Web 峰会(VNWS2019)上展示的所有内容——这是越南 IT 界最大的活动。
如今,“无服务器”这个词变得非常流行。它正在改变开发人员和企业使用公有云交付业务价值的方式。输入这个“关键词”,你很容易找到相关文章。但是,我确信,没有几篇文章会一步一步地向你介绍如何将本地应用程序迁移到无服务器环境,但是在本文中,我将这样做!
我会向你展示一个案例研究,介绍我和我的项目团队如何实现并交付给我们的一个客户。
本文要点:
客户存在的问题,为什么要采用无服务器?
通往无服务器解决方案之路;
我们的迁移方法;
我们面临的挑战。
一. 客户存在的问题
我们的客户提供了一个在线招聘平台。下图说明了该系统是如何工作的。
这是一个很传统的系统,有 2 个 Web 应用程序:
身份服务器 Web 应用程序:
用于身份验证和授权。这个 Web 应用程序提供了一些基本功能,比如用户管理(CRUD)、登录/注销、用户权限等等。除此之外,它还允许用户与他们的谷歌/Facebook 帐户进行集成。
招聘 Web 应用程序:
这是整个系统的核心。作为一个用户,我们可以使用求职功能来找工作,通过传文件来上传简历…作为一个管理系统,我们可以使用报表功能以及通过客户沟通发送电子邮件、短信…
这些 Web 应用程序使用相同的数据库,称为“招聘”数据库。除此之外,系统还包括了消息队列、发送通知的后台作业、报表的数据处理……
二.那么,问题在哪?
问题 1:庞大的代码库
遗留系统太大,无法完全理解,特别是对新开发人员来说。
我们的客户承认,有一次他们不得不编写一个新函数来修复 Bug,而不是重构,因为导致问题的函数与其他函数紧密耦合。
问题 2:高昂成本
此外,他们必须购买一个好的服务器来部署系统。运营开发成本不小。
问题 3:可伸缩性低
系统中的模块有冲突资源,所以如果他们想扩展特定功能,例如“JobSearch”,就必须扩展整个应用程序。
这造成资源浪费,即使接受了这种浪费,他们也无法迅速扩大规模。
问题 4:可用性低
一旦他们发布一个新功能或改进,甚至修复一个小错误,他们就必须部署整个系统。
问题 5:可靠性低
任何模块中的错误(如堆栈溢出)都可能导致系统崩溃。
此外,由于应用程序的所有实例都是相同的,因此 Bug 会影响整个应用程序的可用性。
问题 6:对新技术不开放
系统是用.NET 开发的,这意味着 Python、Java 的新特性永远都无法使用,因为采用新技术会破坏现有的系统。
我想,你可以在你的公司或者你的客户系统中找到类似的地方:)
三. 为什么要采用无服务器?
我不会直接给你答案,你可以通过以下事实找出答案:
据《财富》杂志报道,“车 95%的时间都是停着的”。
拥有一辆汽车与购买裸金属服务器并在该服务器上部署系统类似。日复一日,为了确保服务器正常工作而没有任何问题,你必须维护服务器。
租车类似于使用 VPS 服务。你可以短期租用 VPS。
例如:圣诞节要到了,你预测很多学生打算找份兼职。在此期间,你可以租用 VPS 来支持应用程序的扩展。
虽然租车有助于改善使用情况,但最好的选择是共享汽车,如优步、滴滴……
是的,这就相当于软件领域的无服务器。
四. 通往无服务器解决方案之路
随着云计算的发展,IT 基础设施经历了一场快速革命。为了给云上软件增加更多的灵活性和可伸缩性,无服务器应运而生。下图展示了 IT 基础设施的革命。
20 世纪 90 年代
为了在本地服务器上部署应用程序,我们曾经构建并操作过本地服务器。服务器是为长期使用(并存在多年)而构建的。
但是,安装、配置、操作都需要做大量工作。为扩展应用程序,我们需要扩展整个服务器。
2000 年以来
我们为部署服务器提供了一个新选项,虚拟机(VM)加入“游戏”中。
随着 VM 出现的是虚拟专用服务器(VPS)。这便于我们短期使用(几天或几周),而且几分钟内就可以完成部署。扩展以机器为单位。
2011 年 Docker 出现
docker 的推出,我认为是近十年来 IT 基础设施最大的变化之一。
它影响了我们设计软件架构和部署应用程序的方式。与虚拟机(VM)相比,容器不仅可以使用更少的资源来提高应用程序的运行速度,而且还能扩展,使用多个容器协作在生产环境中交付服务。
但是,容器的广泛使用极大地增加了管理它们的复杂性。
无服务器没有使用容器来运行应用程序,无服务器计算用另一个抽象层代替了容器,在这个抽象层中,云提供商充当服务器,动态地管理机器资源的分配。
五. 我们的迁移方法
注:希望当你读到这部分的时候,已经有了一些为什么我们应该采用无服务器的理由。如果没有,请回到第二节和第三节再读一遍,或者给我发信息。
下图是我们系统未来的样子,换句话说,这是我们和客户想要达成的目标。
虽然由于某些原因我们选择 Azure,但你也能很容易找到类似的 AWS 和谷歌云服务。
我们用 Azure Web 应用托管身份服务器,并使用 Azure SQL Server 为它创建独立的数据库。
此外,我们还用 Azure 流量管理器实现高可用性和故障转移计划。Azure 流量管理器是一个基于 DNS 的流量负载均衡器,它使你能跨全球 Azure 区域将流量以最优方式分配给服务。
未来系统中的求职 Web 应用程序将只包含 UI/UX,因为我们将把整个业务逻辑转移到 Azure 函数。Azure API 管理(API Gateway)将被用作一个单一的入口,以确保来自求职 Web 应用程序的每个请求都必须通过它才能访问 Azure 函数。
此外,Azure API 管理还集成了身份服务器来进行身份验证和授权。
与身份服务器类似,我们还将 Azure Web 应用程序和流量管理器应用于求职 Web 应用程序。Azure 应用网关是我们的求职 Web 应用的防火墙。
即使身份服务器和求职 Web 应用程序被迁移到云服务,但它们不是无服务器,它们只是 PaaS。
要了解关于 PaaS 和无服务器的区别,请阅读这篇文章
Azure 提供了两种无服务器架构方法:
Azure Function:这是一项无服务器计算服务,允许你运行事件触发的代码,而不必显式地提供或管理基础设施。
Azure Logic App:它有助于构建自动化的可伸缩工作流、业务流程和企业编排,以便跨云服务和本地系统集成应用程序和数据。
在未来的系统中,我们将包含以下 Azure 函数:
职位搜索
职位管理
客户沟通
报表
发送邮件
发送 SMS
此外,还有一个用于“文件上传”功能的 Azure Logic App。该功能需要使用不同的流来提供不同的文件类型。例如,excel 文件用于数据导入,jpeg/png 文件用于图像上传,需要调整大小……
此外,我们还有其他 Azure 服务,比如 Azure 服务总线、用于文件上传的 Blob 存储、用于存储日志数据的表存储。Azure Application Insight 用于监控。
六.迁移步骤
我们实现的新体系结构必须与遗留系统并行,以确保对当前业务没有影响。
第一步,我们必须选择迁移到无服务器的功能。
要说这不是一场噩梦可不容易。让我们设想一下,你必须深入研究遗留代码库(我在上面提到过——海量代码库),并在没有任何技术文档或功能规范的情况下选择对其他人影响较小的功能。
最后,经过业务分析团队、产品负责人和开发团队的多次讨论,我们决定将“职位管理”作为采用无服务器的第一个功能。
下一步,我们创建一个Facade层,它提供了对职位管理功能的高级抽象,重构了该功能的所有使用者以使用该 Facade。这为我们提供了一个单一的阻塞点,我们将从中限制功能。
现在,该做“快乐”的部分了——使用 Azure 函数和 Azure Cosmos 数据库创建新的实现。在创建新功能时,谨慎起见,我们使用了与构建 Facade 时相同的抽象。
在这一步中,最重要的事情是使用 Cosmos DB 在现有数据库和新数据库之间同步数据,我们称之为“回填”过程。
下一步,我们创建一个 Toggler——Facade 的第三个实现,它充当某种流量路由器,通过 Facade 层将请求转发给现有功能或新功能(Azure 函数)。
一旦 Azure 函数可以使用了。我们从 Canary Launch 开始,配置 Toggler 的特性标志,使 2%的请求被发送到 Azure 函数,而其余 98%的请求被路由到现有的实现。
假设一切顺利,我们可以慢慢地增加到新实现的流量,直到最终 100%的职位管理功能请求都是通过我们的新 Azure 函数交付。如果在新实现中发现任何问题,将触发回滚函数来回滚请求并将请求重定向到现有函数。
一旦我们觉得新实现令人满意了——Azure 函数正在按预期执行——我们就进入另一个有趣的部分——删除代码!现在,我们可以删除已经废弃的“职位管理”功能的实现。我们现在也可以移除 Toggler 了。
七. 我们面临的挑战
无服务器是个好主意!这是一种新范式,可以应用于在云中开发和运行的现代化应用程序,从而极大提高开发人员的注意力和工作效率。
但是在开发和交付阶段,我们必须克服一些挑战甚至“陷阱”。
1.新技术
在项目开始时,只有两个人曾经使用过云服务和无服务器。
我们组织了许多培训课程。要使新技术的应用在项目中获得成功,就需要说服团队成员使用它。
理想情况下,你可以让他们看到这些新技术的好处,让他们对这些好处感到兴奋。
2.调试
分布式应用程序意味着你更依赖日志跟踪来查找问题根源。
你可以下载 Azure 函数 CLI,这是一个帮助你在开发阶段调试 Azure 函数的工具。为调试云上的 Azure 函数,你必须安装远程调试,这也不容易。
3.集成
如上所述,我们需要实现新的 Azure 函数——与遗留系统并行的无服务器。因此,新的 Azure 函数与现有函数的集成存在很多问题。
4.测试
使用无服务器时测试非常困难,因为使用无服务器意味着你无法直接访问执行代码的环境。
请记住,单元测试必须完整而审慎地编写。
5.监控
无服务器允许将应用程序分解为更小的模块。但这可能会导致分布式监控的新问题。
通过将一组无服务器组件链接在一起,端到端跟踪请求/响应的能力变得非常重要,但是与遗留监控工具一起使用会非常麻烦。
虽然 Azure 应用程序洞察可以帮助我们监控 Azure 函数,但是熟悉度量标准并不容易。
八.小结
从单一服务器迁移到无服务器很不容易。它需要大量投资和管理层的参与。最重要的是,实际负责开发的团队需要具备难以置信的纪律和技能。
不过,这样做的好处很多。
通常,从小事做起是一个好主意。与其等待一个大的一次性动作,不如试着采取渐进步骤,从错误中学习、迭代、再试一次。另外,不要一开始就追求完美的设计。相反,你应该愿意进行迭代和改进。
最后请记住,无服务器不是一个目的地,而是一个旅程,一个持续改进的旅程。
本文最初发布于 Hackernoon 博客,由 InfoQ 中文站翻译并分享。
英文原文:
Migration On-Premises Application to Serverless
评论