概述
应用已经跨入了云原生的时代。要写一个时髦的云原生应用,首先当然要了解什么是云原生。CNCF,也就是云原生计算基金会,作为目前人气最旺的云计算行业协会,在今年6月份给出了云原生的定义,阿里云牵头做了一个官方的翻译:
“云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。
这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。”
这个定义描绘了云原生应用的几大特点:可弹性扩展、容错性好、易于管理和观察、频繁变更,同时也列举了支撑这些特点的典型技术手段。下面我们就来聊聊如何用这些技术手段来编写一个云原生应用。
云原生应用之“形”
首先探讨下如何打造一个云原生应用的“形”。
应用分解
第一步,是用微服务的架构思想来定义应用的结构。传统的应用经常是一个单体的大雪球,随着功能越来越多,雪球也越滚越大,越来越笨重,越来越难以变更,终于再也跟不上业务演进的步伐。云原生的一大使命就是要使能业务的快速迭代、试错和创新,为此需要把应用分解为多个自包含的、能独立实现、演进和伸缩的个体,也就是微服务,从而大大提升整个体系的敏捷性。微服务的划分有点像艺术,通常的原则是按业务领域来进行划分,粒度可大可小,一种做法是找出主要的业务对象,每个业务对象用一个微服务来实现。以一个网上商店应用为例,可以分解为商品、用户、订单等多个微服务,如图1。
应用开发
第二步,自然是定义和编写每个微服务。定义微服务最重要的是定义其暴露的API,可以是HTTP协议的API例如REST风格的,也可以是RPC协议的。HTTP路线的好处是其被广泛接受和使用,放之四海而皆准(标准成熟完备、各种编程语言全都支持、各种编程框架和生态健全)、网络畅通无阻(负载均衡、防火墙、缓存优化等配套一应俱全),坏处是封装级别较高导致整链路overhead较多、性能较差;而RPC路线例如Thrift、Dubbo等性能和时延要好很多,虽然也能做到跨语言,但缺点是其并非广泛接受的标准。gRPC基于HTTP 2.0,算是两种路线的折衷。
在以前,选用哪种协议通常与你选择哪种微服务调用框架紧密相关。例如若采用HTTP路线,则可以考虑使用Netflix开源的一系列组件作为微服务的调用框架,包括Eureka、Ribbon、Zuul等,Spring做了很好的集成,融合到其Spring Boot体系中,对Java开发者是个不错的选择;若采用RPC路线,那么Dubbo完整的运行和管理体系也让其成为一个很好的选项,近年来其对多语言的支持也逐渐丰富。而服务网格(Service Mesh)技术的出现,使得微服务的数据面和管理面清晰解耦,从而让多协议支持和各种管理能力的插入更加容易;更重要的是,sidecar的方式让应用与微服务的管理体系独立运行,大大减少了对应用的侵入性。Istio是当下比较流行的服务网格实现,支持HTTP、gRPC、TCP等协议,Dubbo协议也在积极接入到Istio中。
微服务的API主要是面向内部即微服务之间的交互,而作为一个云上的原住民应用,还需要一个对外的公共API,否则就无法跟云上的其他应用和端上的各种设备灵活地沟通。这层API通常使用API网关来进行管理和暴露,对接到后端的微服务的API。API网关可以提供简单的编排,并实现访问控制、流控、度量、分析等多种能力。
应用部署和管理
第三步,就涉及到云原生应用的部署和管理了。容器无疑是现在云原生应用推荐的打包和部署方式,其最大的好处就是portability,不仅让开发环境和部署环境更加一致,而且能让应用更容易地在私有云、不同vendor的公有云之间迁移。每个微服务可以打包成一个或多个容器来进行部署。虽然你可以使用docker等较原子的工具来进行部署,但由于一个云原生应用通常包含数量较多的容器,采用Kubernetes等容器编排工具来对这些容器进行部署和管理会省事很多。同时,Kubernetes也通过Secrets和ConfigMaps支持配置外部化,这也是云原生的最佳实践之一,以遵循Immutable application的原则。主流的云厂商都提供了Serverless Kuberbetes服务,即用户无需管理运行容器所需的计算节点,只管按Kubernetes的规范来描述应用然后“一键”部署就好,资源按需使用,向着云原生的体验又进了一步。Cloud Foundry尝试的路径更加激进,它希望给开发者一个纯粹的以应用为中心的体验,只要推送代码,Cloud Foundry就会调用对应的buildpack来进行应用的打包最后以容器的方式来进行部署。这种方式比较适合拓补和依赖相对简单的应用特别是Web应用,所谓有得必有失,Cloud Foundry给了开发者更多便利,同时也限制了开发者对环境的控制和对应用的底层管理的能力。OpenShift试图为Kubernetes体系引入类似于Cloud Foundry的部署体验但同时保留开发者在Kubernetes层的控制能力,不过OpenShift的生态目前比较单一。
云原生应用之“神”
有了以上三步打下的基础,我们已经有了云原生的“形”了,下面我们就来聊聊如何打造云原生的“神”。
可弹性扩展
这要分三个层次来建设。第一层是应用逻辑本身Scale-out的能力,这个是基础,即每个微服务的应用逻辑部分可以通过横向扩展(即部署更多实例)来实现更强大的处理能力,应用数据和状态的外部化是重要手段,这可以借助于公有云上现成的各种云服务来支持,例如将数据放到RDS或者NoSQL服务中、将状态放到Redis服务中等。有了这个基础,就能进一步实现自动伸缩,即应用能根据负载自动地进行缩容或者扩容,Kubernetes提供了auto-scaling的能力,这样应用的每个微服务就可以独立地进行伸缩。第二层,应用管理的能力,即随着各个微服务实例的来来去去,前端接入层的负载均衡和微服务之间调用的路由要能即时更新,这一般借助于云厂商提供的负载均衡服务和微服务调用框架的能力。第三层,是应用依赖的云服务自身的弹性能力,要能匹配应用规模的变化,特别是应用Stateless之后,瓶颈就容易转移到数据层,此时就要考验云厂商的数据服务的弹性能力了,如果无法提供透明的弹性能力,应用的弹性能力也就无从谈起。像AWS的Aurora和阿里云的POLARDB这样的云原生数据库提供了更好的弹性能力,是面向未来的应用的首选。当然,针对业务的特点选用合适的事务模型也很重要。传统上开发人员习惯将所有数据都塞到关系型数据库,沿用ACID事务模型,编程简单但牺牲了性能和弹性;在云原生应用中,NoSQL数据库和BASE事务策略则提供了另一个选项,很多非交易型的数据(例如用户的评价、Tag等)完全可以使用这个选项,从而获得更好的性能和弹性。
容错性好
这也要从几个层次来建设。第一层,从宏观上,多AZ甚至多Region的容灾部署和备份早已经是云上应用的最佳实践,这样当某个AZ甚至Region发生系统性故障时,应用还能继续提供服务。第二层,应用的某个微服务或者某个外部依赖发生故障时,需要有容错和降级的能力。Netflix在这方面提供了宝贵的经验,其开源的Hystrix实现了较完善的熔断和降级能力。第三层,个别微服务实例必然会发生故障,这就要求它的工作能被别的实例接替,而无状态化是重要手段;同时,负载均衡服务和微服务调用框架需要即时更新路由;像Kubernetes这样的管理平台还可以自动创建新的实例以替换掉故障实例。最后,“避免故障的最好办法就是经常故障”,Netflix倡导的Chaos Engineering无疑给大家开了一个脑洞,通过故障演练,不断发现系统中的薄弱点,验证系统的容错性,从而不断加固应用。
易于管理和观察
这部分能力可以通过使用合适的工具和平台获得,例如Kubernetes、Dubbo、Istio等提供了很多方便的管理能力,特别是后二者,可以展示微服务的多项健康指标。现在时髦的人提AIOps,在这之前,visibility(看到应用的状态)和automation(根据状态自动执行特定操作)其实是基础;只有这两步做到一定程度,积累了足够多的数据和对数据的理解,才能去做智能化。
频繁变更
要做到这一点,自动化的持续构建和交付能力不可或缺,包括多环境验证、灰度发布等。好在主流的云厂商都提供了现成的DevOps工具链,作为一个云原生应用,最好第一天就是用这些工具来进行构建和发布。
云原生应用的未来
未来其实已经来到了,一个是无服务器化,一个是AI。
无服务器化(Serverless)
无服务器化将意味着应用形态的抽象层级会越来越高,使得开发者所要操心的事情越来越少。无服务器的容器服务让开发者不用再关心运行容器的资源,而无服务器的函数服务则让开发者只需关心片段的代码。从某种意义上讲,无服务器化是PaaS的纯粹化,而函数计算则更是现阶段PaaS的极致化。函数计算的威力不仅仅在于其轻巧的成本模型,更在于其将众多服务编织成一个事件驱动的体系,并且让应用逻辑的粒度切分到了极致,给应用演进带来了无与伦比的灵活性。当然,这种碎片化也给应用的管理带来更大的挑战,而我们今天还在与微服务化带来的应用管理和运维的复杂度搏斗。所以在现阶段,我的观点是函数计算可以用来实现小型的应用,也可以作为大型应用开发中的补充手段;但是未来,当越来越多的云服务接入事件体系,它是有可能会成为主角的,特别是很多开发人员已经适应了类似Node.js这样的纯事件驱动的编程模型。
AI
AI对于未来应用的重要性已经没有人再怀疑了,以至于有人说AI First。那么你的应用需要做些什么呢?我的建议是两个关键字:场景和数据。首先要识别出AI能给你的业务带来价值的场景,这里需要大开脑洞,去想以前不敢想的能力,去想如果你是神仙,你的业务你会作何改变?比如假设你能猜到你客户的心思,假设你能预测明天发生的事情,假设你可以去做某项看似不可能的优化……有了场景,再来看可行性:有没有数据?有没有模型或者算法?这其中,数据是最重要的。所以,要让你的应用多收集数据,今天不起眼的数据或许就成为明天的宝藏。比如,记录下你应用中的各种用户行为和业务事件,这些数据带来的可能性是不可估量的。
总结
云原生应用其实并不难写,对吗?随着公有云上云原生应用平台越来越完整和强大,云原生的各种理念、最佳实践和技术手段都已经内置在其中了,比如容器、微服务、服务网格、API等等,而函数计算、各种数据分析和AI服务也都日渐成熟。不过,应用的本质还是业务的数据模型和处理逻辑,这些还是要依赖开发者的人肉智慧,云原生只是让开发者能够在
总监课第四期热门产品:https://www.aliyun.com/product/ecs?tlog=out_aiticai_zongjianke_20181119
阿里云总监系列课重磅上线!聚焦人工智能、弹性计算、数据库等热门领域,首次集齐12位阿里云技术高管,耗时半年精心打磨,从理论到实践倾囊相授,从零开始绘制技术大牛成长路径,限时直播课程免费报名中!欢迎戳“http://click.aliyun.com/m/1000011882/”免费报名学习。
原文链接
本文为云栖社区原创内容,未经允许不得转载。