- 不足之处
- 与生俱来的劣势
- 供应商控制
- 多租户问题
- 供应商锁定
- 安全顾虑
- 跨客户端平台重复实现相同的逻辑
- 丧失优化服务器的能力
- 无服务器FaaS不支持服务器内状态
- 实现方面的劣势
- 配置
- 自己对自己发起的DoS攻击
- 执行时间
- 启动延迟
- 测试
- 部署/打包/版本控制
- 发现
- 监控/调试
- API网关定义和“管太宽”的API网关
- 行动推迟
- 与生俱来的劣势
- 无服务器技术的未来
- 弥补劣势
- 工具
- 状态管理
- 平台的改进
- 教育
- 提高透明度/为供应商确定更清晰的预期
- 新兴模式
- 超越“FaaS化”
- 测试
- “可移植”的实现
- 针对供应商的实现进行的抽象
- 可部署的实现
- 社区
- 弥补劣势
- 结论
- 致谢
不足之处
亲爱的读者朋友们,希望上面提到的各种显著优势能让你满意,因为随后我们要用现实“打脸”了。
无服务器架构很多方面让人欣喜,如果不是感觉这种技术为我们做出了很多美妙承诺,我根本不愿意花时间介绍,但各种优势和收益都是需要付出代价的。其中一些代价是这种概念与生俱来的,无法通过进一步发展彻底解决,考虑使用无服务器技术时绝对不能忽略这些问题。另外有些代价来自无服务器技术目前的实现,随着进一步完善这些问题有望得到顺利解决。
与生俱来的劣势
供应商控制
与任何外包策略类似,你需要将某些系统的控制权拱手让给第三方供应商。此类控制力的缺乏可能体现为系统停机、非预期的限制、成本变动、功能缺失、强迫的API升级等。上文曾经提过的Charity Majors在这篇文章中“权衡”一节详细探讨了这个问题:
[供应商的服务]如果足够智能,会对你使用服务的具体方式施加非常强大的约束,这样供应商才能以符合自己可靠性目标的方式供应这些服务。用户获得灵活性和丰富选项的同时,也会导致混乱和不可靠。如果平台供应商需要在你的幸福和数千个其他客户的幸福之间做出选择,他们绝对会选择“大多数” — 这也是他们应该做的。
多租户问题
多租户是指用同一台硬件甚至同一个托管应用程序,为多个客户(或租户)运行多个软件实例的做法。这种策略是实现上文所提到规模经济效益的关键。服务供应商会尽一切努力为自己的客户营造一种感觉,让客户认为自己是这套系统唯一的用户,优秀的服务供应商在这方面通常都做得很好。但凡事不可能完美,有时候多租户解决方案可能会造成一些问题,例如安全(一个客户可以看到另一个客户的数据)、健壮性(一个客户的软件错误导致其他客户的软件出错)、以及性能(高负荷客户导致其他客户的系统运行缓慢)。
无服务器系统也会面临这类问题,很多其他类型的多租户服务也不例外。但因为很多无服务器系统是新出现的,相比其他已经逐渐成熟的系统,无服务器可能会遇到更多此类问题。
供应商锁定
所有涉及第三方的系统都会遇到类似的问题:无服务器供应商锁定。大部分情况下,无论你使用了某一供应商的哪些无服务器功能,在另一个供应商的环境中这些功能都会使用不同的实现方式。如果想要更换供应商,除了需要更新自己的运维工具(部署、监控等)外,八成还要更改代码(例如为了匹配不同的FaaS接口),甚至如果相互竞争的供应商在行为的实现上有差别,可能需要更改自己的决策或架构。
就算可以为生态系统的部分内容更换供应商,在其他架构组件上依然可能存在锁定。例如,假设你正在使用AWS Lambda对来自AWS Kinesis消息总线的事件做出响应,AWS Lambda、Google Cloud Functions以及Microsoft Azure Functions之间的差异可能非常小,但依然无法将后两个供应商的实现直接挂接到AWS Kinesis流。这意味着无法将代码从一个解决方案移动或迁移至另一个解决方案,除非同时移动基础结构中的其他组件。
最终就算能找到某种方法通过其他供应商的服务重新实现整个系统,取决于新供应商所提供的服务,可能依然需要进行迁移。举例来说,如果从某个BaaS数据库切换至另一个,源数据库和想要换为使用的目标数据库提供的导出和导入功能可以满足你的需求吗?就算能满足,又需要付出多少成本和精力?
目前新出现了一种也许能缓解此类问题的方法:对多个无服务器供应商的服务进行普适的抽象,下文将详细介绍。
安全顾虑
这个问题本身就足以单独撰文介绍,拥抱全新的无服务器方法会让你面临大量安全问题,例如下文列举了两个例子,除此之外需要考虑很多。
- 你使用的每个无服务器供应商会增加你自己生态系统内所需安全实现的数量,并会增加面对恶意行为时的攻击面,有可能导致攻击成功率增加。
- 如果直接通过移动平台使用BaaS数据库,将丧失传统应用程序在服务器端提供的防护屏障。虽然这并不会直接造成严重后果,但依然需要在应用程序的设计和开发过程中给予更充分的考虑。
跨客户端平台重复实现相同的逻辑
在使用“完整BaaS”架构后,不需要在服务器端编写任何自定义逻辑,所有逻辑都位于客户端。对于第一个客户端平台来说这也许不算什么问题,可一旦需要支持更多平台,就必须重新实现相关逻辑的子集,在传统的架构中是不需要这样做的。举例来说,如果在此类系统中使用了BaaS数据库,所有客户端应用(也许有Web,以及原生iOS和原生Android应用)都需要与供应商提供的数据库通信,此时就需要了解如何从数据库架构映射至应用程序逻辑。
此外如果任何时候想迁移到新数据库,还需要跨越所有不同客户端重复编写代码并对各种改动进行协调。
丧失优化服务器的能力
对于“完整BaaS”架构,无法为了提升客户端性能而对服务器端的设计进行优化。“前端的后端(Backend For Frontend)”这种模式会对服务器上整个系统的部分底层内容进行某种程度的抽象,这种做法在一定程度上可让客户端执行速度更快,对于移动应用程序还有助于降低能耗。目前“全面的BaaS”已经可以使用这样的模式。
需要澄清的是,这里以及上文提到的劣势适用于所有自定义逻辑都位于客户端,仅后端服务需要由供应商提供的“完整BaaS”架构。为了缓解这些问题可以考虑采用FaaS或其他类型的轻量级服务器端模式,以将某些逻辑转移到服务器上。
无服务器FaaS不支持服务器内状态
在介绍过几个有关BaaS的劣势后,再来谈谈FaaS吧。上文我曾提到:
在本地…状态方面FaaS函数会遇到很多局限。你需要假设对于函数的任何调用,自己创建的任何进程内或主机状态均无法被任何后续调用所使用…
另外还提过,为了克服这些局限可考虑采用“十二要素应用”中的第六个要素:
十二要素进程是无状态并且无共享(Share-nothing)的。任何需要持久保存的数据必须存储在有状态的后端服务中,通常可选择使用数据库。
-- 十二要素应用
Heroku建议考虑这种方法,在使用PaaS时这些规则可以放宽,但使用FaaS时往往无法通融。
那么如果无法保存在内存中,FaaS的状态要存储在哪里?上文的引言中提到可以使用数据库,大部分情况下可以使用速度足够快的NoSQL数据库、进程外(Out-of-process)缓存(例如Redis),或外部文件存储(例如S3)等选项。但这些方式的速度比内存中或计算机内持久存储的速度慢很多,因此还需要妥善考虑自己的应用程序是否适合这些方式。
这方面另一个不容忽视的问题是内存中缓存。很多需要从外部读取大量数据集的应用会将数据集的部分内容缓存在内存里。你可以通过数据库中的“参考数据”表读取数据并使用诸如Ehcache等技术,或者从指定了缓存头的Http服务读取,此时内存中的Http客户端即可提供本地缓存。对于FaaS实现,可以将这些代码保存在应用中,但缓存很少能提供太多收益(可能完全无用)。只要缓存在首次使用时完成“热身”,随着FaaS实例被撤销这些缓存将毫无用处。
为了缓解这个问题可以不再假设存在进程中缓存,并使用诸如Redis或Memcached等低延迟的外部缓存,但这样做(a)需要执行额外的工作,并且(b)取决于具体用例可能会对性能产生极大影响。
实现方面的劣势
上文提到的劣势很可能会伴随无服务器技术一生。虽然可以通过各种缓解解决方案加以改进,但很可能无非根除。
然而其他劣势纯粹是由于现阶段该技术本身不够完善所致。随着供应商继续重视并不断投入,以及/或在社区的帮助下,这些问题有望彻底得到解决。只不过目前这些问题还比较突出…
配置
AWS Lambda函数没提供任何配置选项。一个都没。甚至环境变量都无法自行配置。如何针对环境的某些特定本质用不同特征运行同一个部署构件?不行。你必须自行调整部署构件,甚至可能需要使用不同的嵌入式配置文件。这种“吃相”实在很丑。无服务器框架可以帮你完成必要的改动,但这样的改动依然必不可少。
我有理由相信亚马逊正在解决这个问题(可能很快就会搞定),不知道其他供应商是否存在类似问题,但将这个问题放在开头恰好是为了证明这一技术目前确实还比较先进,有各种不足之处。
自己对自己发起的DoS攻击
为什么说任何时候使用FaaS都需要购者自慎(Caveat Emptor)?有另一个很有趣的例子。目前AWS Lambda会对用户可并发执行的Lambda数量进行限制,假设上限是1000,这意味着任何特定时间点下你最多只能同时执行1000个函数,如果需要执行更多将开始受到限制,被加入等待队列,并/或导致整体执行速度放缓。
这里的问题在于这个限制会应用给你的整个AWS帐户。一些组织会为生产和测试环境使用同一个AWS帐户,这意味着如果组织内部某人在执行一种全新类型的负载测试,尝试执行超过1000个并发Lambda函数,这几乎等同于不小心对自己的生产环境发起了DoS攻击。晕…
就算为生产和开发环境使用不同的AWS帐户,一个超载的Lambda(例如正在忙于处理客户批量上传操作)将可能导致其他由Lambda提供的实时生产API变得响应速度缓慢。
其他类型的AWS资源可以通过不同的安全和防火墙等手段,针对环境上下文情境和应用范围进行分隔,Lambda也需要类似的机制,我相信很快就会有的,但目前只能自己小心了。
执行时间
上文提到过AWS Lambda函数如果执行时间超过5分钟将被终止,预计这个限制很快将被取消,但我更感兴趣的是AWS解决这个问题的方法。
启动延迟
上文提到过我的另一个顾虑,FaaS函数等待多久才能获得响应,如果时不时需要在AWS上使用通过JVM实现的函数,这一点将尤为重要。如果你用到这样的Lambda函数,可能需要十多秒才能启动。
希望以后AWS能通过各种缓解措施改善启动速度,目前这一问题可能妨碍到某些用例中JVM Lambda的使用。
关于AWS Lambda的具体问题就是这些。我相信其他供应商私底下肯定也隐瞒了很多类似的问题。
测试
无服务器应用的单元测试其实相当简单,原因上文已经说过了:你所编写的任何代码“仅仅是代码”,而不是要使用的各种自定义库,也不是需要实施的各种接口。
然而无服务器应用的集成测试过程较为困难。在BaaS的世界中只能使用外部提供的系统,而不能使用(举例来说)自己的数据库,那么集成测试也要使用外部系统吗?如果要,这些外部系统与测试场景的匹配程度如何?能否轻松地组建/撤销所需状态?供应商能否针对负载测试提供单独的计费策略?
如果想将多个外部系统桩(Stub)在一起用于集成测试,供应商是否提供了本地的桩模拟器?如果有提供,桩的保真度如何?如果供应商没有提供桩又该如何自行实现?
FaaS领域也存在类似的问题。目前大部分供应商并未向用户提供可用的本地实现,因此你只能使用普通的生产实现。这意味着所有集成/接受度测试都必须远程部署并使用远程系统执行。更糟糕的是,上文提到的问题(无法配置,跨帐户执行的限制)也会对测试方式产生影响。
说这个问题很严重,部分原因在于我们在无服务器FaaS中使用的集成单位(例如每个函数)远远小于其他架构,因此相比其他类型的架构,此时将更依赖于集成测试。
Tim Wagner(AWS Lambda总经理)在最近的无服务器大会上简单提到了他们正在解决与测试有关的问题,但听起来测试工作对云的依赖会更高。这也许是一个适合勇敢者的全新世界,但我会怀念在自己笔记本上脱机对整个系统进行完整测试的日子。
部署/打包/版本控制
这是FaaS面临最具体的一个问题。目前我们还缺乏一种将一系列函数打包成应用程序的足够好的模式。造成这个问题的原因在于:
- 对于整个逻辑应用程序中的每个函数,可能都需要单独部署一个FaaS构件。如果(假设)你的应用程序使用JVM实现,其中包含20个FaaS函数,那就需要将JAR部署20次。
- 同时这也意味着无法以原子级的方式部署一组函数。你可能需要关闭可能触发该函数的任何事件源,部署整个组,然后重新打开事件源。对零停机应用程序来说这是个很麻烦的问题。
- 最后这还意味着应用程序缺乏版本控制机制,无法实现原子级回滚。
再次需要提醒,目前有一些意在解决这类问题的开源项目,然而只有在供应商的支持下此类问题才能顺利解决。为了解决部分此类问题,AWS最近在无服务器大会上公布了一个名为“Flourish”的新技术,但具体细节尚未公布。
发现
与上文提到的有关配置和打包的问题类似,跨越不同FaaS函数的发现能力目前也缺乏一种足够好的模式。虽然这个问题不是FaaS独有的,但FaaS函数细化的本质,以及应用程序/版本定义的缺乏会让这个问题变得更严重。
监控/调试
目前只能使用供应商提供的监控和调试工具,无法使用第三方工具。某些情况下这样也可以接受,但对AWS Lambda来说,自带的工具功能过于简陋,这方面我们更希望有开放的API和第三方服务。
API网关定义和“管太宽”的API网关
最近一次ThoughtWorks Technology Radar活动讨论了API网关“管太宽”的问题。虽然这个链接主要讨论了一般意义上的API网关,但正如上文所说,这些内容也适用于FaaS API网关。这里的问题在于API网关提供了在自己的配置/定义等领域内执行大量特定应用程序的能力,通常很难针对这些逻辑执行测试和版本控制等操作,甚至有时逻辑本身的定义也很难。如果能像应用程序中的其他部分一样将此类逻辑留在程序代码中,这样的方式往往效果更好。
对于亚马逊的API网关,就算最简单的应用程序,目前也只能使用该网关特定的概念和配置。也正是因此出现了诸如无服务器框架和Claudia.js等开源项目,这类项目可以帮助开发者忽略具体实现的相关概念,更顺利地使用常规代码。
虽然API网关很容易会变得异常复杂,但随着技术的进一步完善,我们有望能用上帮助自己完成这些工作,并能通过推荐的使用模式帮我们远离这些陷阱的工具。
行动推迟
上文曾经提到,无服务器并不是指“无须运维”,在监控、架构伸缩、安全、网络等方面依然要做很多工作。但依然有一些人(也许我也算其中之一,这是我的错)会将无服务器描述为“无须运维”,主要原因在于当你开始使用之后,很容易会忽略掉与运维有关的活动:“瞧啊,都不用装操作系统!”这种想法的危险之处在于很容易陷入一种虚假的安全感中。也许你的应用可以顺利运行,但在不知情的情况下被Hacker News报道之后,突然激增十倍的流量产生了近乎于DoS的攻击,然后就没有然后了……
与上文列举的有关API网关的其他问题一样,教育是解决这类问题的良药。使用无服务器系统的团队需要提前考虑运维活动,供应商和社区需要通过各种教学内容帮助他们了解这一技术的真正意义。
无服务器技术的未来
这篇无服务器架构的介绍文章已经逐渐到达尾声。作为收尾,我将谈谈未来几个月甚至几年里,无服务器技术可能的发展方向。
弥补劣势
上文已经多次提到,无服务器技术是新事物。尽管上文已经列举了该技术的一些劣势,但写出来的仅仅只是一部分。无服务器后续发展的重要方向之一是弥补固有劣势,消除,或至少改善实施方面的不足。
工具
在我看来,无服务器FaaS目前最大的问题在于工具的缺乏。部署/应用程序捆绑、配置、监控/日志,以及调试,这些工具都存在严重不足。
亚马逊已公布但尚未公开技术细节的Flourish项目也许能起到一定帮助。这则消息让人期待的另一个原因在于,该技术将会是开源的,这样就可以对不同供应商的应用程序进行移植。就算没有Flourish,我们同样期待未来一两年里开源世界中能出现类似的技术。
监控、日志、调试,所有这一切都将由供应商负责实现,但对BaaS和FaaS领域都是巨大的促进。相比使用ELK等技术的传统应用,至少目前AWS Lambda的日志功能还很不能让人满意。但我们已经注意到在现在这样的早期阶段,这一领域已经出现了几个第三方的商用和开源工具(例如IOPipe和lltrace-aws-sdk),但是距离类似New Relic这样的技术还有很长的路要走。希望AWS除了为FaaS提供更完善的日志解决方案外,也能像Heroku和其他厂商那样让我们更容易地融入第三方日志服务。
API网关工具还有很大改进空间,其中一些改进可能来自Flourish,或依然在继续完善的无服务器框架等类似技术。
状态管理
FaaS缺乏服务器内状态,这一点对很多应用程序来说不是什么大问题,但也会对一些应用程序产生严重影响。例如很多微服务应用程序为了改善延迟会用到一定规模的进程中状态缓存。类似的连接池(连接到数据库,或通过持久的Http连接连接到其他服务)则又是另一种形式的状态了。
对于大吞吐率的应用程序,一种解决方法是让供应商延长函数实例的寿命,借此使用常规的进程中缓存方法改善延迟。但这种方法并非总是有效,因为不能为每个请求提供“温”缓存,而且用传统方式部署,并使用了自动伸缩能力的应用也面临类似的困扰。
另一种更好的解决方案是以延迟极低的连接访问进程外(Out-of-process)数据,例如用极低延迟的网络开销查询Redis数据库。考虑到亚马逊已经在自家的Elasticache产品中提供了托管式的Redis解决方案,并且他们已经使用置放群组(Placement Group)实现EC2(服务器)实例的相对共置(Relative co-location),这样的做法似乎无法获得足够的延展性。
我觉得更可行的情况是,我们将看到不同类型的应用程序架构会开始考虑非进程中状态的约束问题。对于低延迟应用程序实例,也许可以用普通服务器处理初始请求,通过本地和外部状态收集处理该请求所需的全部上下文,随后将包含完整上下文情境的请求交给自身无须查询外部数据的FaaS函数场来处理。
平台的改进
目前,无服务器FaaS的某些劣势主要源自平台本身的实现方式。执行时间、启动延迟、无法分隔的执行限制,这是目前最主要的三大劣势。也许可以通过新的解决方案解决这些问题,或可能需要付出额外的成本。例如我觉得启动延迟这个问题可以通过允许客户为FaaS函数请求2个始终可用,并且延迟足够低的实例的方式加以缓解,只不过客户需要为这样的可用性额外支付一笔费用。
当然,平台自身的继续完善不光是为了解决现有的这些问题,无疑还会提供更多让人激动的新功能。
教育
通过加强教育,也可以缓解不同供应商所提供的无服务器技术固有的一些劣势。每个使用此类平台的人都需要积极考虑将自己的生态系统托管在一个或多个应用程序供应商的平台上,这样的做法到底意味着什么。例如有必要考虑类似这样的问题:“是否有必要考虑使用来自不同供应商的平行解决方案,以防一个供应商的服务故障对我产生较大影响?如果部分服务故障,应用程序又该如何优雅地降级?”
技术运维方面也需要进行教育。目前有很多团队的“系统管理员”数量大幅减少,而无服务器技术还会让这种情况更严峻。但系统管理员的职责不仅仅是配置Unix服务器和Chef脚本,这些人通常也活跃在技术支持、网络、安全等一线领域。
在无服务器世界中,真正的DevOps文化变得愈加重要,因为依然有大量与系统管理无关的活动需要完成,并且通常将由开发者负责。但对大部分开发者和技术领导者来说,这些工作并非他们的本职任务,因此适当的教育以及与运维人员更为密切的合作将变得至关重要。
提高透明度/为供应商确定更清晰的预期
最后终于谈到了缓解措施方面,随着对供应商的托管能力愈加依赖,我们对不同供应商的平台会产生怎样的预期,供应商对此必须更加明确。虽然平台迁移工作很难,但至少是可行的,客户会逐渐带着自己的业务逃离不可靠的供应商。
新兴模式
除了半生不熟的底层平台,对于如何以及何时使用无服务器架构这样地问题,我们的理解依然还很浅显。目前很多团队会出于投石问路的考虑将各种想法付诸于无服务器平台,希望这些先驱们好运!
但是用不了多久我们就会开始看到各种推荐的实践模式日益涌现。
某些实践可能专注于应用程序的架构。例如FaaS函数在开始显得笨重之前能达到多大规模?假设能以原子级的方式部署一组FaaS函数,创建这种分组的最佳方式是什么?这种方式能否与目前我们将逻辑与微服务结合在一起所用的方法严格匹配?架构的差异是否要求我们转向截然不同的方向?
将这些问题进一步扩展,在FaaS和传统的“始终在线”持久运行的服务器组件之间创建混合架构的最佳方法是什么?将BaaS引入现有生态系统的最佳做法是什么?反过来看,哪些征兆意味着全面或大部分以BaaS为主的系统需要开始接受或使用更多自定义服务器端代码?
我们还会看到大量新兴的使用模式。媒体转换是FaaS的标准用例之一:“当有比较大的媒体文件存储到S3 Bucket后,自动运行进程在另一个Bucket中为该文件创建小体积的版本。”但为了确定某一具体用例是否适合无服务器方法,我们还需要进一步分析更多使用模式。
除了应用程序架构,一旦相关工具进一步完善后,我们还将看到各种推荐的运维模式。如何从逻辑上将FaaS、BaaS,以及传统服务器组成的混合架构中的日志汇总到一起?关于服务的发现有什么好办法?对于以API网关作为前端的FaaS Web应用程序该如何进行金丝雀发布?如何对FaaS函数进行最高效的调试?
超越“FaaS化”
目前我见到的大部分FaaS运用场景主要是将现有代码/设计想法用“FaaS”的方式实现出来,也就是将其转换为一系列无状态的函数。这种做法挺强大,但我也期待着能实现进一步的抽象甚至形成一种语言,使用FaaS作为底层实现为开发者提供FaaS收益,而无须实际将自己的应用程序看作一系列相互独立的函数。
例如我不知道谷歌是否在自己的Dataflow产品中使用了FaaS实现,但我完全可以设想有人创造了能实现类似作用的产品活开源项目,并使用FaaS作为实现。这里可以用Apache Spark作为类比。Spark是一种大规模数据处理工具,提供了非常高程度的抽象,可支持使用Amazon EMR/Hadoop作为自己的底层平台。
测试
正如上文“劣势”中所述,对无服务器系统来说,在集成和接受度测试方面还有很长的路要走。我们会看到不同供应商分别提出自己的建议,其中一些可能会用到云服务,同时我猜测可能还会有像我这样的“保守派”供应商会提出另一种方案,借助何种方案可以在自己的开发计算机上完成一切测试任务。估计最终我们将看到各种得体的解决方案,分别可用于联机和脱机测试,不过可能还要等几年。
“可移植”的实现
目前所有流行的无服务器实现都以部署到第三方供应商在云中的系统内为前提。这是无服务器的优势之一,可以减少需要我们维护的技术数量。但这就产生了一个问题,如果有公司希望在自己的系统中运行这些技术,并将其以一种内部服务的方式交付该怎么办?
类似的,目前的所有实现在集成点(Integration point)方面都有自己的偏好:部署、配置、函数接口等。这就会造成上文提到过的供应商锁定的局面。
为了缓解这些顾虑,期待能看到各种可移植的实现,下文将首先谈谈上面的第二点。
针对供应商的实现进行的抽象
我们已经开始看到类似无服务器框架和Lambada框架这样的开源项目。这些项目的想法在于让我们忽略实际部署位置和方法,以一种中立的开发方式编写和运维无服务器应用。就算目前仅仅在AWS API网关 + Lambda,以及Auth0 Webtask之间,如果能根据每个平台的运维能力轻松进行切换,那也是极好的。
我觉得只有在出现大量此类标准化产品之后才能实现这种程度的抽象,但好在这种想法可以通过循序渐进的方式逐步实现。我们可以从一些跨供应商的部署工具着手,甚至可以考虑上文提的AWS Flourish,并以此为基础逐渐构建出更多功能。
这方面有个比较棘手的问题:在尚未实现标准化的情况下对FaaS编码接口的抽象进行建模,预计这样的进展会首先出现在非专有的FaaS技术中。例如我认为在AWS S3或Kinesis Lambdas实现抽象之前,可能首先会完成对Lambda的Web请求和调度(“Corn”)的实现。
可部署的实现
使用无服务器技术,但不使用第三方供应商的服务,这样的做法听起来有些奇怪,但可以考虑这些情况:
- 也许有一家大型技术组织,希望开始为所有移动应用程序开发团队提供类似Firebase的数据库体验,但想使用现有的数据库架构作为后端。
- 希望为某些项目使用FaaS风格的架构,但出于合规性/法律等问题的考虑,需要在“本地”运行自己的应用程序。
上述任何一个用例都可以在不使用外部供应商托管服务的情况下通过无服务器的方式获得收益。这样的做法是有先例的,例如平台即服务(PaaS)。最初流行的PaaS都是基于云平台的(例如Heroku),但人们很快发现在自己系统中运行PaaS环境也能带来大量收益,这就是所谓的“私有PaaS”(例如Cloud Foundry)。
可以想象,与私有PaaS实现类似,开源和商用的BaaS和FaaS等概念的实现将愈加流行。Galactic Fog是在这一领域应用尚处在早期阶段的开源项目的典范,他们就使用了自己的FaaS实现。与上文提到的供应商抽象的观点类似,我们可能会看到一些循序渐进的方法。例如Kong项目是一种开源的API网关实现,虽然在撰写本文时尚未与AWS Lambda集成(但据说这个问题正在着手处理中),但实现后就可以为我们提供很多有趣的混合方法。
社区
真心希望无服务器社区能够发展壮大。目前全球范围内围绕该技术已经有一个大会以及大量聚会活动。希望这一领域也能像Docker和Spring那样在全球发展出更多更大规模的社区。更多大会,更庞大的社区,以及各种在线论坛,借此帮助大家跟上技术的发展。
结论
虽然名称容易让人产生歧义,但“无服务器”这种风格的架构可以帮助我们减少在自己服务器端系统上运行的应用程序代码数量。这是通过两种技术实现的:后端即服务(BaaS),借此可将第三方远程应用程序与我们的前端应用直接进行紧密的集成;以及函数即服务(FaaS),借此可将不间断运行的组件中执行的服务器端代码转移到短暂运行的函数实例中执行。
无服务器技术并不是所有问题的最终答案,如果有人跟你说这种技术将彻底取代现有架构,你需要小心对待。如果想现在就涉足无服务器,尤其是FaaS领域,也需要更加谨慎。虽然这种技术已经产生了累累硕果(伸缩、节约开发工作量等),但依然有(调试、监控等领域的)困难在下个角落等着你。
这些收益并不会被人们快速淡忘,毕竟无服务器架构的积极意义实在是太大了,例如降低运维和开发成本,简化运维管理,降低对环境的影响等。对我来说,影响力最大的收益依然是减少打造全新应用程序组件时的反馈环路(Feedback loop),我是“精益(Lean)”方法的铁粉,主要是因为我觉得尽可能先于最终用户从技术中获得反馈,这种做法可以为我带来大量价值,当无服务器技术能够与这样的理念相符后也可以缩短我将应用投放时长所需的时间。
无服务器系统依然处在襁褓中。未来几年里该技术还有很大的进步空间,我已经迫不及待想看看这个技术将如何融入现有的架构大家族中。
致谢
感谢下列人员对本文提出的宝贵意见:Obie Fernandez、Martin Fowler、Paul Hammant、Badri Janakiraman、Kief Morris、Nat Pryce、Ben Rady、Carlos Nunez、John Chapin、Robert Bagge、Karel Sague Alfonso、Premanand Chandrasekaran、Augusto Marietti、Roberto Sarrionandia。
感谢Badri Janakiraman和Ant Stanley针对这一术语的起源提供的意见。
感谢我之前就职于Intent Media时所在团队成员提供的帮助,他们适当的怀疑精神让我对这一新技术产生了更深入的理解,谢谢你们:John Chapin、Pete Gieser、Sebastián Rojas,以及Philippe René。
最后还要感谢所有对这一话题发表过感想的人,尤其是本文链接所引用内容的作者。
关于本文作者
Mike RobertsMike是一位工程主管,目前居住在纽约市。虽然目前大部分时间都在管理人员和团队,但他也负责管理代码,尤其是Clojure,他对软件架构有着深入的见解。他对无服务器架构抱有审慎乐观的态度,认为这种技术也许担的上目前所获得的一些炒作。
本文作者:Mike Roberts,阅读英文原文:Serverless Architectures