云原生软件设计-以客户需求为中心

May 1, 2023

商业业务逻辑中,数据和流程是根本,一切技术手段都是为其服务的。今天的所谓“高科技”,可能很快就会过时,所以“云原生”和之前出现过的每一波技术都没有本质区别。只是在这个时间点上,针对一种类型的需求最合适的技术选择。

现在国内各个行业、地域都有云计算平台了,上千万上亿的上云大单在天上飞。我还清楚的记得之前和国内某大云负责人交流时其描述的场景历历在目:“看到客户上云就是使用Weblogic(应用服务)进行虚拟机部署,乌央乌央的”。 如今情况“好转”些了么?很多团队使用SpringBoot微服务全部重写了业务逻辑?企业信息化负责人究竟怎么把握软件架构设计符合业务需求和发展需要?

之前写过一篇文章,“云原生技术演进的逻辑”,分析云原生相关技术演进发展过程。本文再从业务角度,结合需求和技术进一步来解析。 分为上下两篇,上篇更偏重于业务,下篇更偏重技术。

一、企业应用软件根本驱动源头是什么?

首先,本文是站在客户(即软件使用方)的角度来考虑的。 我始终认为“企业信息化“”就是一个很准确定义企业和软件关联关系的词语,后面出现的两化融合、数字化转型、数字XX甚至元宇宙都脱离不了信息化的基础。现在提出的“应用现代化“”,也可以认为是一种信息化方式,迁移软件系统的过程。

最通俗的理解方法为,假设没有计算机、网络,企业也可以正常经营,现代企业用软件技术来复现、加强业务的方法。 比如说,大家知道会计工作有记账,做报表,利用算盘也能算好几千人的大账,而如今在大型企业,除了原始凭证单据是纸质的,其他都是电子化票据。 如今涉及到的工作、学习、生活,各个环节都尽量用信息化方式联网处理,我们乘车,支付,交作业,通过手机或电脑和网络来完成操作。

企业(或者组织)的业务,有两个明显特点,一是围绕数据,二是存在流程。

数据是体现业务信息的,包含是当前数据和历史发生的,我们还是以财务为例,三张报表(资产负债,利润,现金流量),再加上总账明细账,基本就可以还原一个企业的一段时期的经营过程,也就是说,通过期初余额,重放记账过程,就可以推算出期末余额,三张重要报表也产生了。 业务软件就是快速准确的处理业务逻辑,算出数据。

软件可以解放会计出纳人员机械性运算的劳动,但无法完全替代财务人员。 企业业务和采用的计算机技术无关,只是技术的发展可以更好的帮助业务开展。比如利用OCR,可以直接扫描发票上的信息而不用手工填入;有了互联网,可以随时随地的查看工资,提交报销单。

所以,软件、硬件、云计算、架构设计等选型,对于成熟的业务而言,都不是最主要的。 数字化转型的核心不是用了各种新技术如微服务云原生,而是业务流程效率的优化和对应组织的调整。

那么疑问来了,如果企业业务是根本,软件和技术不是那么重要,无差别的购买或者开发一套软件系统是不是也OK呢?

这里有3点问题:

  1. 企业中不是所有岗位的人员都对业务熟悉并能很好运用软件系统;
  2. 不同的企业业务有很强的差异性;
  3. 现代企业业务会面向海量互联网用户。

应对以上,采用先进功能、优良架构的业务软件有以下好处:

  1. 良好软件蕴含先进流程和数据处理过程,凝结了同类型行业企业的优秀管理经验;
  2. 富含大量的可配置项,可以定制以及进行扩展;
  3. 基于云计算架构,也就是我们要探讨的“云原生”。

二、软件架构设计云原生方向的取舍

还是这个问题,什么是云原生架构?目前多数人认可的答案是应用软件可以在各种云计算环境中无差别的部署运行。

所采用的操作系统,所使用的开发语言,所部署的云等等都不重要,用户需要时,可以随时在任何一朵云上部署软件应用。 现在主流技术,就是采用容器技术和K8s等软件工具。 前面我们说过企业业务是和技术无关的,那么我们为什么要用K8s呢? 这里的逻辑是,业务需求到了一定程度,需要采用某种技术,当前最好最成熟的选择是K8s;而不是必须用K8s,满足企业云原生架构要求。这个因果关系不能倒置。

很多“云原生布道师”和其公司,往往把“云原生架构”描绘的无比美好,各种灵活、敏捷、弹性、可扩展性,俨然一个银弹,无所不能。 但请各位记住两点: 1.不能方便迁移应用基本都是耍流氓;2.忘记过去也是背叛未来。

对于企业客户,业务才是最大,任何超出核心需求的软件能力都是多付出的成本。 姑且不论软件用不上的功能,云原生运维对于技术人员的要求比一般的企业软件高出太多了吧。有些团队领导认为考一个CKA就可以应对,其实是远远不够的。 更重要的,“云原生架构”基于微服务体系,对于开发人员的技术要求也大大增加,除了经典的Spring全家桶,还有响应式编程,服务治理,容器技术,需要掌握一箩筐。

建议只有业务需求真的达到需要云原生软件架构时,企业信息化决策者再真正全方位考虑运用这个技术!

其中最直观的业务指标就是用户访问并发量。海量用户意味着需要更多的服务实例,运维成千上万的服务实例和各种软件工具和环境,就需要“云原生计算环境”。 我国人口众多,互联网用户数十亿,很多大型企业甚至网红的粉丝都有上千万用户。 也就是说,实际需要云原生技术的企业和技术团队也是个庞大的数目。移动应用,微信小程序,Saas服务等都有可能高流量。所以在我国,云原生应用设计还是很有市场的。

这里需要注意的是,用户访问量和软件复杂度,基本上可以认为是两个维度。也就是说,一个只有几百用户的软件,也有可能异常复杂,这时采用“云原生”甚至“微服务”都不是必须的。也就是前面说的不能“忘记过去”。 我国科技跨越式发展发生在近20年,可以发现一个现象就是基础领域的薄弱。因为有了互联网,开源软件,资本加持等因素,在某些互联网领域出现了巨型企业,但必须清楚的认识到,基础软件还是要步步发展,存在的坑还是要逐个去解决。技术演进过程中出现的“过时”技术,都有一定的历史背景和客观存在,也有适用的环境,希望国内技术圈更客观的看待。 软件用户也是如此,如果业务场景适合,就毫不犹豫的采用单体应用,或者CS架构的富客户端。业务软件解压缩就能运行,几个工程师就能维护和二次开发,难道不香么?如果要“重写”软件应用,那么也是以功能通用性,可维护性为主要目标,并不需要追求所谓最新“架构”。

上面分析了商业公司对云原生架构的业务需要,以下则从技术的角度来进行阐述。

三、云环境中的良好架构设计

之前撰文写过《云原生5大支柱带来的启示》以及《可持续性对软件开发的启示》,阐述AWS、Azure、GCP三大公有云软件设计方面的良好架构定义。

套用对业务需求和技术实现的分类,架构设计的6个支柱(pillar),可以看做是“技术层面的业务需求”。通俗解释是:针对业务使用技术进行实施,但并不选定某项技术以及怎么去做;而在完成业务需要的前提下使用某种技术,至于怎么实现的并不重要。

运作一个商业公司,首先是让其运营起来。比如我们开立一个打印服务公司,很简单,开发一个微信小程序,上传要打印的pdf文件并支付,联网的打印机就打印好,快递给预留的地址中。这个“简单”的流程,通过互联网上的软件程序,就运作起来了。 可以快速小幅度的修改代码,比如客户可以选择纸张;可以优化业务流程,微信用户填过地址后,以后就可以直接使用。 以上就是第一大支柱卓越运营的内容,可以看到并没有任何技术要求,业务实现在修改代码后立刻生效,任何一种解释语言或者动态加载方式实现的模块都可以做到。

接下来这个小型业务面临的问题就是安全性。需要通过技术手段来限制所打印文件无危害,也不会无限制的长时间占用打印机资源。除了微信,还可以接入其他平台,要处理认证和授权,保证所打印文件传输过程的安全性,并不会被非法访问。安全是第二大支柱,在软件体系中,操作系统、编程语言、开发框架都有安全的实现,合理的利用平台和语言提供的安全能力。

接下来是可靠性,即业务需要不间断的保障运行。一台打印机缺墨时,可以自动切换到另外一台。可靠性对于现实商业公司来说非常重要,这个需求被整合为软件的“高级”能力,可以卖出高的多的价钱。

互联网时代,使用业务的用户从数千陡然增加到上亿数量级,又有秒杀、抢红包这样短时间集中的业务。原有软件的架构就需要进行调整,比如经典的Apache Http Server和Java实现的Tomcat都是按线程进行访问处理的,现在一台机器突然来了上亿的请求,自然就会无足够线程资源分配处理。 但高并发多线程开发工作接下流量之后,真正的业务还是会带有状态信息、按部就班的走流程的。事实上数亿个请求,远远超出一般公司的业务承担能力的,不可能、也没必要提供那么多业务处理软件资源。所以,我们需要的是弹性处理机制,业务流量上来时,扩展业务程序实例满足访问请求,平静时再回弹来释放资源。

可靠性在应用服务器时代就是重点功能了,EJB技术在设计和具体实现中,业务实例都可以进行扩展和回收,只是数量级只有数十个,上百就有点力不从心不好管理了。如今的K8s,诞生的目标就是满足这个需求,Pod包含容器运行单元,可以在机器节点间调度,同时定义了Service,DNS发现机制,来保证服务的可靠性。在一些公有云上,同样的功能,也有用不同于K8s的方法来实现的,同样好用而且效率很高。

下一个关注的支柱是性能效率。我们希望打印服务尽可能高效的完成,可以优化打印算法,甚至可以花钱委托给更专业的打印机构。使用合适的软件技术来完成业务目标,多种语言协同工作,使用不同种类的数据库更合适的完成任务。通过事件驱动和无服务器这些技术方式,减少服务之间的耦合性,提升系统整体效率。

通过合理的利用云资源,可以优化成本,只在使用服务时为用到的资源付费。同时可以量化支出,变间隔性的大额支出为持续性小额花费。 业务系统中用到的专业付费软件和专业服务,通过云平台订阅租用。 最后是更高层面的可持续性,目标是评估对于环境的影响。大家可以思考,多数资源使用理想情况下,都是在共享时消耗最小、效率最优。关于可持续性的分析讨论已经超出IT的范畴。

对于我们的打印业务也是如此,前面已经提到了并不一定要自购打印机,可以采用云端资源。那么是否可以优化业务来可持续性发展呢?纸张打印是一个不环保的行为,我们需要思考打印文件的目的是什么?如果是签名、盖章的需要,则电子签章具有同等法律效力,可以接入相应的云服务来满足客户需求。 也许有一天,我们根本不会再购买电脑,甚至手机这些电子设备,所有信息,算力,数据都在云端,信息来源于视网膜的投影、耳膜直接接收的信号,甚至神经系统的直接感应。科技和文明的发展比现在的最强人工智能还提升的若干维度,一切皆有可能。

四、分析云原生设计现阶段的落地技术

在大概10年前,业务软件的主流架构转向微服务体系,按照三个维度进行服务分拆。与此同时,容器技术也快速发展成熟得到广泛应用。 微服务软件设计需要重点考虑服务治理,即服务注册、发现、负载均衡、路由、重试、熔断等问题,Java领域最有代表性的就是Spring Boot微服务开发框架和Spring Cloud服务治理。也是现阶段国内企业软件开发的主流技术栈。

写好的Java微服务使用容器Docker进行封装和部署,就可以很好的工作。可以很方便的启动多个服务实例并管理,部署在各个公有云或者私有云之上。

这样是不是“云原生”呢?反正国内的很好软件企业就号称是的,我也觉得想叫什么都是自己的自由。 关键点在于:

  1. 是否生于云端,长于云端;
  2. 是否具备上述云架构设计六大支柱的能力(或者为最核心的四大)。

可靠性要求多个服务实例可以弹性扩展,如果系统平台能做到这一点就没问题,但若您的系统还需要手工维护容器部署的节点,监控程序并配置网络,直接依赖于操作系统的能力,甚至无法迁移,这样就不是“云原生”了。

K8s最核心的功能,就是pod中包含的微服务,可以方便的在若干节点间迁移,同时服务注册和发现会自动变化,对于服务使用者完全透明。微服务用容器进行封装,可以使用任何语言开发,相互通信协作。业务微服务建议为无状态,便于弹性伸缩,但K8s同时提供了StatefulSet,可以定义有状态的工作负载。在实际业务开发中,业务状态信息是无处不在的,可以存放在各种数据库或缓存服务中,也有K8s统一管理维护。 业务服务程序会提供生存、健康信息端点,告诉外界自身的运行状态。如SpringBoot通过简单定义就可以提供这样的信息端点,而K8s会实时监控这些信息,如果工作不正常了,就销毁重新创建一个Pod。

这就是“云原生”之道。K8s包含的工作负载可以数十万计甚至更多,像一支纪律严明的军队,各自为战又协作配合的完成军事任务。

在操作系统层面,应用数据可以存在文件系统中,或者通过数据库等,云计算中有S3等块存储。在K8s中,数据存储通过PV,PVC,StorageClass等抽象定义,业务程序可以直接使用存储,而后台可能是主机上的文件系统,也有可能是AWS的S3。为应用开发屏蔽差异性,方便云计算环境的迁移,运维人员也便于管理维护。

同样的网络也是如此,平台将一个个比较复杂的硬件相关概念,转换为相对没那么复杂的抽象软件定义,使得不同角色的技术人员可以相对从一个角度去思考业务软件。

对应微服务开发,K8s还定义了ConfigMap, Secret, ServiceAccount等,抽象配置信息和安全等。容器管理平台和软件开发框架不断相互迎合,形成了和谐较完美的开发生态。

然而,对于平台的需求是无止境的,社区K8s包含了最核心的内容,同时提供了扩展能力CRD,业内各厂商各自发挥才智和优势,基于K8s扩充和完善。

K8s提供的Deployment,可以对Pod进行滚动部署,但实际生产系统升级过程要复杂的多。同时对于微服务的治理,提供一套“标准化”的跨语言的治理框架。Istio项目作为“嫡系”已经发展了很多年,通过VirtualService和DestinationRule的组合使用,可以方便切换流量和定义路由,支持服务治理和混沌工程的能力,还实现了很多安全方面的功能。效率的问题也会在新的架构下得以改善。

微服务开发领域中有事件驱动的架构设计,我们在上篇讨论过。对于大多数业务,基于事件设计是一种更合理的方式,尤其是较大规模的企业和面向数据处理的应用。

企业流程间,由服务交互式的沟通协作,变成基于类似“工单”的事件通知,只要有合理高效的管理机制保证,面向事件驱动可以工作的很好。 但技术变化的前提是业务流程的优化变更,比如对于订票网站,普通消费者可以接受订票时延,出票完成后再通知。但VIP呢,领导呢?是设置单独的服务通道,还是某种优先机制?所以还是那句话,企业软件核心取决于业务流程和需求定义。

越是企业管理软件,单笔事务处理“价值”可能会更高,而互联网是面对芸芸大众,网民在秒杀通道中都是乖乖排队的。 事件+函数处理,以及触发器,可以覆盖大多数高容量业务请求,但同时对于开发者的要求也会更高(现阶段而言)。云计算厂商推广Serverless,是希望更细粒度的管理计算资源。

云原生设计方面,目前可以通过KNative管理。在Service和Eventing的基础上,又增加了Function函数,对函数服务进行抽象定义。而主流的开发框架,如Spring,Quarkus都提供了对于函数、无服务器编程的支持。

在当前,可以认为云原生技术最核心的就是K8s和容器。对于运维人员,管理、监控、Devops等技术都会涉及;而对于开发人员,微服务、服务治理、响应式编程方法、编程语言适应、EDA等也都需要熟悉。云原生的确是一个庞大的技术体系,对技术人员的要求,远远高出Windows软件或者单体应用的运维和二次开发技术人员的能力。所以最终客户是否采用云原生技术管理部署应用软件,还是要慎重考虑好。

不过,对于爱好技术研究的软件匠人,也是一道饕餮盛宴,希望大家能吃的开心。