云原生、Serverless和Low-Code是程序员挥刀自宫的那把刀吗(云原生 serverless)
从一个玩笑说起
如果提起起开发工程师和测试工程师这两个角色,你会想到什么?相比与开发和产品之间和谐相处的世纪难题,开发和测试之间可能会相对好一点,但也并不总是那么亲密无间,在共同讨伐产品需求的时候两者可以枪口一致对外,但一旦到了提测和多轮测试的环节,一道无形的墙开始在两者之间竖立。究其原因,是测试希望开发能够eat their own dog shit,翻译成白话就是,你要对你自己写的代码质量负责,我只是辅助你把关质量而已。
于是乎,笔者在百度工作期间,百度的测试为了让百度的开发能够主动且高效地eat their own dog shit,测试同学重新定义了测试的工作,新时代的测试工作被定位为开发自动化的质量检查和测试工具,并coach开发同学熟练使用这些工具来完成质量保障工作。这里面蕴含的一层意思是,随着越来越多的自动化工具被开发出来,越来越多的质量保障工作会被自动化的完成。听起来很完美是不是?当百度的测试经理兴奋地面对一堆开发经理宣布这个宏伟计划的时候,只听开发经理堆里悠悠地冒出了一个声音:那你们还需要那么多测试hc吗?我只记得,当时那个测试经理的脸色不太好看。
要知道,百度的测试也是从大量的手工黑盒测试开始起步的,即使到了后期大量的测试自动化工具被启用,但测试团队的人员能力结构里,手工测试还是占据了大多数,而越来越多的测试自动化带来的,是对开发能力的升级要求,以及同时对人力资源的降级需求。
但不可否认的是,百度测试做的这个角色转型,是符合未来质量保障的发展方向的,要知道,随着业务越来越复杂,且随着下文所讲到的开发模式变革所带来的生产力的提升,测试工作量和测试资源之间的矛盾会越来越尖锐,因此测试自动化是必须要发展的方向,但越来越多的自动化带来的是对测试工程师能力模型和资源需求的强力冲击。所以,测试自动化是测试同学挥刀自宫的那把刀吗?
云原生时代是程序员们更好的时代吗
没有马云的时代,只有时代的马云。
任何技术的发展也正是因为时代的需求。随着国家在宏观政策上对数字经济的大力支持,越来越多的企业开始将数字化转型或升级作为提升竞争力的必须手段。而云计算则是帮助企业尤其是绝大多数的中小企业实现数字化转型的有利武器。
因此,为了响应时代的号召,云计算也提出了云时代的软件架构Cloud Native,其目的就是为了让广大中小企业可以实现最低门槛的上云和用云,为了达到这个目标,云计算架构开始将越来越多的基础技术工作下沉到云基础设施,从而让广大企业的开发人员可以将更多的关注点聚焦在自身业务上,非业务的通用技术能力则交给云基础设施来完成,而这也正是云原生(Cloud Native)架构的本意。
好了,在云原生时代,企业做好业务开发该做的事情,剩下的事情都交给Cloud Native来完成,准确的说,是交给容器、Service Mesh和k8s等云原生的基础设施来完成,我们来看看他们都帮助企业的开发者干了些什么?
- 容器带来的快速和低成本试错:
容器对于运行环境的极强适应性和快速启动的能力,配合云上动态扩展的庞大资源规模,让云端的容器应用可以在短时间内拓展到成千上万个实例。所以,云可以说是容器应用的最佳载体,容器应用也非常适合在云上运行和扩展。因此,随着业务服务被拆分成一个个轻量级的微服务并以容器的方式快速启动运行,极大地提升了业务试错的敏捷性。
同时因为云本身是多租户的,需要运行环境的隔离性,而容器正好能够提供必要的隔离性,在保障隔离性的同时也意味着高效地利用了云资源。因此,使用容器可以帮助企业以更高的资源利用率来使用云上资源,从而降低企业业务试错的成本。
好了,企业的开发者们,你们只需要闷头写微服务的业务代码就好了,云来帮你快速部署、启动、运行,从而快速探索市场反馈。
2. 不可变基础设施所带来的环境部署的安全和效率:
传统的服务器部署,服务器会不断更新和修改。使用这类基础设施的工程师和管理员可以SSH到他们的服务器,手动升级或降级软件包版本,逐个服务器调整配置文件,并直接将新代码部署到现有服务器上。换句话说,这些服务器是可变的;它们可以在创建后进行更改。由可变服务器组成的基础设施本身可以称为可变的、传统的或手工的;
而k8s所代表的不可变基础设施,其中服务器在部署后永远不会被修改。如果需要以任何方式更新、修复或修改某些内容,就先对公共镜像进行修改,然后用镜像构建新服务器来替换旧服务器。经过验证后,新服务器投入使用,旧的服务器就会下掉。
不可变基础设施的好处是在基础设施中有更多的一致性和可靠性,以及更简单、更可预测的部署过程。它可以缓解或完全防止可变基础设施中常见的问题,如 配置漂移(configuration drift)和 雪花服务器(snowflake servers)等。
好了,企业的开发者们,每次上线部署时服务器的各种环境和版本问题不用担心了,上线上通宵的日子不再有,可以有更多的时间睡觉,以及睡醒后写业务代码了。
3.声明式API所带来的资源管理效率:
声明式API就是当用户向 k8s 提交了一个 API 对象(资源)的描述之后,k8s 会负责为你保证整个集群里各项资源的状态,都与你的 API 对象描述的需求相一致。更重要的是,这个保证是一项“无条件的”、“没有期限”的承诺:对于每个保存在 etcd 里的 API 对象,k8s 都通过启动一种叫做“控制器模式”(Controller Pattern)的无限循环,不断检查,然后调谐,最后确保整个集群的状态与这个 API 对象的描述一致。
利用声明式API,我们可以实现服务故障时候的自动恢复、服务升级时的自动滚动更新以及服务遇到瞬时高峰压力时候的自动水平扩容。
所以,每次服务升级、线上故障和业务高峰,不用和运维一起oncall挑灯夜战解决问题了,可以有更多时间思考和写业务代码了。
4.Service Mesh、k8s和Serverless带来的分布式服务开发革命:
我们来回顾一下开发业务服务的历史:
- 早期:服务在实现业务需求的同时,为了实现服务间 RPC通信,还得实现一堆诸如序列化/反序列化、路由、负载均衡、流量控制(熔断、限流)、容错(超时、重试、降级)等功能;
- 微服务sdk模式时期:在这个时期,开发者在应用层添加一个胖客户端,在这个客户端中实现上述各种服务通信相关功能。但带来的问题是:语言绑定、学习和维护时间成本(开发时不透明)和应用侵入性(同进程);
- 微服务service mesh模式时期:在这个时期,SDK客户端的功能被剥离出来放到Service Mesh的Sidecar中,Sidecar是独立进程,在Sidecar中实现sdk的各种功能。其实就是把更多业务无关的事情下沉到基础设施中,业务开发者更多关注业务逻辑开发,从而解决了sdk模式带来的问题;
Service Mesh主要是为了解决服务间网络通信的问题,本质上是管理服务通信(代理)。所以,使用Service Mesh的企业开发者们不再需要关注服务间通讯的问题了。
但分布式服务面临的不仅仅是服务间通讯的问题,因此,甚至在整个分布式服务解决方案层面,k8s都希望在基础设施层实现语言无关的分布式服务基础设施。
我们来看看使用应用层解决方案的问题(比如spring cloud)
- 作为开发者,需要关注技术选型问题,比如决定是使用一个AP系统(consul, eureka等)还是CP系统(zookeeper, etcd等);
- 需要弄清楚如何监控和管理这些系统,有学习和运维成本;
- 需要为不同语言提供不同版本的客户端,以方便与服务注册发布中心通信,因为容器中可能运行的是不同语言的应用(Java/Node.js/Go);
基于以上问题,k8s希望在基础设施层面来提供语言无关的分布式服务基础设施,可以看一下k8s和spring cloud的解决方案对比,如下图:
好了,企业开发者甚至不用做分布式服务相关的技术选型了,更不用担心不同的编程语言问题了。
而Serverless则更近一步,所谓“无服务器”就是想让用户感觉不到服务器的存在,开发者可以完全专注于业务逻辑的编写,而不再关心任何基础设施,完全屏蔽了计算资源,是在真正地引导你不再去关心底层环境,你只要遵循标准方式来直接编写业务代码就可以了。你甚至可以把每一个具有独立功能的函数,来作为一个单独的服务进行部署和运行。这也是为什么,在有些云计算的分类方法下,无服务器计算能够单独“开宗立派”,被称为函数即服务(Function-as-a-Service,FaaS)的原因。“无服务器”计算,它会根据我们的负载情况,依托云端庞大的规模自动地进行支撑和扩展,你不需要为云函数事先划定资源池。
Severless主要包括两块内容:后端设施(Backend)和 函数(Function)
- 后端设施:是指数据库、消息队列、日志、存储等这类用于支撑业务逻辑运行,但本身无业务含义的技术组件,这些后端设施都运行在云中,在无服务中将它们称为“后端即服务”(Backend as a Service,Baas);
- 函数:指业务逻辑代码,这里函数的概念与粒度都已经很接近程序编码角度的函数了,其区别是无服务中的函数运行在云端,不必考虑算力问题,也不必考虑容量规划(从技术角度可以不考虑,从计费角度还是需要掂量一下),在无服务中将其称为“函数即服务”(Function as a Servcie)
无服务的愿景是让开发者只需要纯粹地关注业务:
- 不需要考虑技术组件,后端的技术组件是现成的,可以直接取用,没有采购、版权和选型的烦恼;
- 不需要考虑如何部署,部署过程完全托管到云端,由云端自动完成;
- 不需要考虑算力,有整个数据中心支撑,算力可以认为是无限的;
- 不需要操心运维,维护系统持续平稳运行是云计算服务商的责任而不再是开发者的责任;
看到这里,那些一直在企业里做业务开发的同学,你们是感到无比兴奋还是后脊梁发凉呢?
Low-Code和Zero-Code是程序员的低糖和无糖可乐
程序员说:让技术革新的浪潮来得更猛烈些吧!我不要你以为,我要我以为,我以为非技术人员应该也可以开发系统,于是,Low-Code和Zero-Code作为程序员最爱的低糖和无糖可乐,被送给了业务人员。
Low-Code和Zero-Code都属于aPaaS,可以把aPaaS理解为PaaS的一种子形式。aPaaS的全称是application Platform as a Service,即应用程序平台即服务。Gartner对其所下的定义是:“这是基于PaaS(平台即服务)的一种解决方案,支持应用程序在云端的开发、部署和运行,提供软件开发中的基础工具给用户,包括数据对象、权限管理、用户界面等
aPaaS(应用程序平台即服务)有以下2个特征:
- 提供快速开发的环境,用户在几个小时内就能完成应用的开发、测试、部署,并能够随时调整或更新;
- 低代码(low code)或 零代码(no code),非技术人员就能完成应用开发;
aPaaS和PaaS都可以完成软件的开发和部署,都支持云端访问,而两者的差异主要体现在用户人群和使用环境不一样:
- PaaS包含所有平台级别的服务,需要技术人员在本地完成应用程序的开发和数据提供,然后部署到PaaS平台上,再分发给用户使用;
- aPaaS是PaaS的一种子形式,在aPaaS模式下,非技术人员可以直接在云端完成应用程序的搭建、部署、使用、更新和管理;
好了,业务人员都可以拖拖拽拽开发系统了,甚至将来随着AIGC能力的越发成熟,机器人都可以写代码了,企业里还在一直写业务代码的开发者们,你们真的觉得低糖和无糖可乐喝起来快乐吗?
要等挥刀自宫的刀落下吗
回想起来是不是很可笑,随着技术的不断发展和进步,聪明的程序员们似乎在举起刀完成挥刀自宫的壮举。但其实这还真赖不了程序员们,这只是技术发展的必然而已。我们所能做的,就是快速调整来适应这个时代的需要。
在我看来,未来的程序员们,你们可以去向这些方向:
- 爱写业务代码的同学,可以深耕toB的企业级软件赛道,并在这个赛道深耕行业领域知识,成为行业里的技术专家,让行业经验成为你的壁垒;
- 致力于成为技术领域专家的同学,去做基础设施软件的开发吧,去做更有技术含量和挑战的事情,而且这也是国家政策大力鼓励支持的方向;
同时,我们也能看到,现阶段的Serverless和Low-Code还是有其弊端和局限性的,大家也不必过于恐慌。
比如,对Serverless来说,其“无限算力”的假设,决定了它必须按照使用量(函数运算时间和占用的内存)计费以控制消耗的算力的规模,因而函数不会一直以活动状态常驻服务器,请求到了才会开始运行,这就导致了函数不便依赖服务端状态、也导致了函数会有冷启动时间,响应性能可能不太好。目前无服务的冷启动过程大概是在数十到数百毫秒级别,对于java这类启动性能差的应用,甚至是接近秒的级别。因此其更擅长短连接、服务无状态、适合事件驱动的场景,不适合具备复杂业务逻辑、依赖服务端状态、响应速度要求高、需要长链接等特征的场景。
而低代码类的产品,它们的应用场景主要是 B 端中后台应用的搭建,且能力不是万能的。举个例子,很多低代码产品页面控件大概就几十种,如果你的需求是想超出这些控件,做一些新的更好看的样式,那低代码产品就无法满足。低代码解决的痛点问题是帮助客户高效率低成本的实现业务需求,并且一般都是针对中后台应用。如果你对界面、UI、交互要求很高,那低代码不一定合适,无可否认低代码是可以替代一些增删改查的工作。但这不是挺好吗?难道真的有工程师就喜欢每天在那里重复写增删改查,喜欢别人叫他码农吗?不应该这样。工程师是艺术家,是有灵魂的人,大家的志向应该是写更有创造力的代码,而不是每天浪费生命在增删改查之上。
写在最后
随着时代的发展,即使程序员们不自己举刀挥下,时代的浪花推动的技术发展,也会推动着程序员技术能力模型的更新迭代。我们所能做的,就是紧跟时代发展的方向,不断学习和提升自身的能力,甚至是革自己的命,才能让我们不断屹立于当下。
欢迎大家关注我的微信公众号:渝言家,我会不定期跟大家聊聊代码、架构、技术管理、行业和产品等话题。