FaaS(无服务)架构的思考

/

无服务器(Serverless)并不意味着“没有服务”,而是平台帮我们托管运行环境和进程状态。过去一个月我在 Lambda 上的实践,让我对 FaaS 的优劣和适用场景有了更直观的认识,这里做个总结分享

无服务这个词可能存在歧义,常见的近义表述有 FaaS(Function as a Service)或云函数,但这些说法都不能完全覆盖其含义,为了表述统一,下面统一按照 FaaS 进行表述

FaaS 面临的挑战

  1. Lambda 环境由于是多进程的,一样面临和多线程差不多的问题,比如调试复杂(日志输出无序)缺乏直接通过 grep 进行快速筛查日志的问题
  2. 默认的 Hello Handler 由于为精简环境,无法获得完整的 Linux 环境,主要体现在了文件系统受到了限制, /var/task 只读,同时程序运行期间的文件只能保存在 /tmp 目录,对实际代码有影响,需要调整
  3. Lambda 冷启动一样面临 FaaS 的通病,程序的依赖每次都需要进行初始化,通过上下文可以缓解,但这个上下文只能当作 不可靠的缓存使用
  4. 对包的大小有限制,比如解压后的函数(程序)不能超过一定的大小(比如 Lambda 限制 250mb)
  5. 运行期间的异步是不可靠的(特指异步调用后,没有同步的获取执行情况,而非是完全不能异步,异步能提高程序的执行效率,是异步一定要结束才能回复给 Lambda 函数的服务),本质原因是 FaaS 已经主动放弃了进程的控制
  6. 运行期间的连接池也是不可控的,因为连接本身就是一种有状态的服务
  7. 如果程序运行还依赖一些底层库,可能会更复杂(可以使用 FaaS 提供的容器服务,不过这相当自己又在维护容器的可用性了)
  8. 无状态会引起内存的缓存,内存锁失效(单机应用可以用内存锁处理一些简单的并发问题),不过一般分布式应用都会主动规避这两个技术,要保证数据一致性,无服务要求的更加严苛,更复杂。(主要是应用进程状态被回收,缺乏同步机制了)

FaaS 的优势

编写更简单了

因为放弃了对进程的状态的维护,所以程序一定程度会变得更简单,及所有与进程强绑定的功能都会变得不可靠,比如 内存锁/内存缓存/上下文,都会较少使用,或者不使用,维护一个进程变成了维护好一个方法。这样的优势明显,比如一个请求耗时长/消耗的资源多,在传统的单体应用和分布式应用,这种问题会间接得拖慢其他请求,甚至会导致整体崩溃,然而在 FaaS 下,通常不会考虑这种问题,因为当平台发现有请求堆积的情况下,就直接会启动更多的进程来处理(比传统的分布式架构的扩容缩容更加及时),依赖平台的相对更稳定的调度策略

幂等性更重要了,在分布式系统里面可以通过分布式锁或者是事后补偿或者修正的方式将数据保持最终一致性,但 FaaS 下,因为缺少了服务状态的概念,所以函数一旦不能保证幂等性的情况,就可能出现重复处理导致,一些未预期的情况,比如重复插入数据。这就需要在通过一些特殊方式来保障幂等了,比如在新增数据的时候添加额外的字段,比如加入一次性 token 的方式,保障操作是幂等的

费用更合理

FaaS 都是按照资源的实际使用进行收费,比如就是按照申请的内存使用量加上实际的程序处理时间(CPU用时) ,而非传统的按照 vm 收费,即使一天只有 2/3 的时间 CPU 和内存处于有负载的情况。也需要支付一整天的费用

运维工作更轻松了

再也不用担心磁盘是不是被应用要写满了,为什么服务老是要在高峰期崩溃(解决不了就需要重启)。为什么都分配了 超大内存了,怎么进程还是频繁的 GC 呢,是不是服务器的又要打安全补丁了,这些运维的日常工作,都被平台给完全的接管了

比微服务更微服务了

当然微服务没有解决的问题的,FaaS 也没有解决,FaaS 更像是回避了微服务的问题,比如微服务被诟病的服务拆分和治理的问题的,拆的太碎,维护不过来,拆的不合理的,服务间的依赖也是问题, FaaS 也面临这种问题,就是不可能把一个方法就生成一个云函数,一个应用都是成百上千的接口,不可能维护这样多的代码库。而拆的太大,又面临了一个函数功能太多,难免遇到的数据共享的情况。进而导致了初看是 FaaS,结果还是变成了高阶的 PaaS 了

这些情况可以考虑用 FaaS

场景 原因
短时任务(≤15 分钟) Lambda 等服务有限时限制
突发/波动流量 平台弹性伸缩更快
单一依赖、逻辑简单 函数开发心智成本低
工具型请求(一次请求 -> 一次返回) 无状态特性适配

这些情况不要强上 FaaS

场景 原因
长时间运行任务 超过执行时长限制
重状态应用(缓存/会话) 无状态模型难以持久
复杂依赖/底层库 部署和兼容性复杂
强顺序需求 FaaS 调度并发不可控
高频调用 WebAPI 成本可能高于容器
缺乏日志体系 调试/观测困难

总结

FaaS 非万能解,它擅长轻量、无状态、突发型任务,能显著简化运维、优化成本。但在需要长时运行、大量状态管理或高频调用的系统里,容器化或 PaaS 往往更合适。实际落地时,常见的做法是 FaaS + 容器/PaaS 混合架构,各取所长。

转载请注明作者和出处,并添加本页链接。
原文链接: //xiaochun.zrlog.com/faas-thinking.html