本次直播课程是由京东云产品研发部中间件负责人李道兵从Cloud Native概念入手到实践出发,深度解析了Cloud Native年度热词背后所隐含的技术特征。
我们将整理后的视频及内容资料在这里分享给大家,没能到场的小伙伴可以通过这些资料来学习和了解课程内容。
课程从Cloud Native的服务治理、京东云助力中小企业Cloud Native所得出的实践经验以及Cloud Native与云平台之间密切的技术关联着眼,全面解读Cloud Native在服务高可用、可伸缩、易运维等方面的优势。
以下是李道兵老师分享的全部内容,希望给各位开发者带来更多帮助:
从理论走向实践,多角度详解Cloud Native
— 京东云产品研发部中间件负责人 李道兵—
(建议在Wi-Fi环境下观看)
众所周知2013年算是架构史上比较重要的年份之一,这一年我们看到有一些新名词逐渐涌现,例如Docker,随后出现的Docker Swarm以及各种Mesos,当然最近也有一些,其中Cloud Native就慢慢变成了热词之一。
针对热词,我的观点是,关注一个技术词汇之前首先要思考解决的问题、如何解决等层面,一个词汇会引入一个崭新的视角,以此为基础才能判断前后发生了怎样的变化,针对Cloud Native也是如此。
经过分析,其实Cloud Native与之前的很多热词本质不同,区别在哪里?例如Docker,它是一个很具体的软件,可以在Linux或者mac平台中探讨容器化的Linux,具备相对独立的环境,这一点同样适用于Docker Swarms、Mesos、k8s等。
相比之下,Cloud Native不是一个软件,也不是一种框架,而是一堆理念集合,以及围绕这些理念所产生的一些最佳实践的工具,最终究竟想解决什么问题呢?
首先就是分布式架构理念,例如SOA、EDS、EDA等。如何理解微服务是目前所见的一种很好的架构的形式?在整个架构形式下,会有一些比较好的服务分拆,那服务的治理方案究竟该怎么去做?第二,当我们提到分布式架构时,最初被认为是成品,但如何从源代码进化到可以运行的阶段,需要一套部署与运维的方法论,又是什么呢?第三,Cloud Native力推的是一套新的运行组织方法,本质上是容器化,实际上可以解决很多问题,例如如何提供一个一致的运行环境?
之前通常认为用镜像加上虚拟机也能解决一致性问题,但是虚拟机的启动速度非常慢,可能到分钟级别而且性能损失很大,解决快速启动效果并不出色。试想一下,如果采用容器是不是可以达到更高性能,甚至几乎无损?这就是Cloud Native。
讲到分布式架构的理念,可以从架构变化史方向探讨。
期初大部分人开始接触服务端编程都是单一组件的概念,也就是整个服务端服务可以视为一个大程序,然后在此基。础上链接数据库、缓存以及有些复杂的消息队列等,这一点与我们经常接触到的一些语言框架类似,例如早期比较流行的PHP等。总结来看,这类框架在给我们传达一个理念:除非有必要,我们都应当在单一组件提供某个服务,呈现的形态也是最常规的很多小程序聚合的形态。
从我自身出发,也是慢慢从小规模软件向大规模软件变化的。但在大规模软件的框架下就容易出现很多问题,例如单一软件需要单一团队来维护是最佳的状态,7人合适;但如果一个单一组件的维护需要扩充到20-30人,就必然出现很多管理问题。在此基础上进行人员拆分,又会出现边界冲突,工作重复,非常尴尬。也就是说从单一组件到SOA,面向服务的架构体系,纵然可以将整体服务按照功能拆分,服务之间再通过一些好接口实现调用,但是过程十分复杂。
另一方面,向SOA中迁移的时候,很重要的一点是可以复用这个模块;但当为一个单一组件的时候,复用也就不切实际了。
此外,这也是很多小团队在快速成长中经常遇到的问题。在已知架构出现问题时,但因为被业务驱动无法着手修改,所以选择使用SOA做一些拆分工作。拆分之后,上层业务模块就交付给了业务团队去做更多迭代;底层团队同样可以比较专注,进而完成一些稳定性以及性能优化方面的提升。
但与此同时就会发生随着业务规模持续增长,服务越来越多的同时,服务治理就会出现相应的问题。如果以多个APP相互调用来解决,就会出现很多痛点。
在授权问题上,计费模块或者用户模块中,自然不希望所有应用的权限被随便调用,但限制权限如何去做?此外,如果APP需要在线完成扩容以及收容的操作,又应该怎样通知调阅方呢?APP本身需要在接口方面做一些升级更新等,又将如何着手相应的管理工作?
这些问题的解决如果在SOA体系下,如果引入不适当的治理手段就会让整体变得异常混乱,还会导致大量的安全问题。
此时我们需要引入的第一个解决方手段通常被称为ESB,也就是企业级服务总线,Enterprise Service Bus来解决。针对刚才提到的诸多问题,例如A服务调用B服务,针对B服务来说哦,如何在A的配置中写入B的IP?
B服务在扩容之后,A中就有可能出现调用失效或者并未充分利用B资源等,导致扩容之后的新服务器用不上,收容之后的某些请求中断,甚至产生错误结果等,这是万万不能接受的。再者,如果用A的配置写入B的域名,再去解析,就很有可能出现延迟以及 故障点的问题,甚至解析域名还会出现均衡问题,而这些出现都是急需解决的。
作为技术人员,常规情况下当一个问题很难被解决,自然就会引入新词汇将复杂的问题简单化,ESB就是如此。
在服务总线指导下,A不管需要调用哪个服务都可以直接去调用服务总线;服务总线可以明确过载、扩容、收容节点等具体细节;此外调用ESB,首先需要明确身份对其进行总控的措施,例如认证、授权、审计等。
企业级ESB,也就是Enterprise Service Bus,通常成本不低。在考虑成本的基础上最简单的方法就是中间配置一个Nginx,用两台服务器做一个简单或者用LVS将它们链接起来,然后在上面配置一个后面挂服务的Nginx,再建立一套机制,力图做服务扩容的过程中得以于Nginx中自动做一些简单的动态调整。
但引入ESB之后本身就比较容易出现新的瓶颈。通常情况下企业内部服务在不接入大量外部服务的前提下,实际压力并不高,这对于低压力的企业问题不大,但对于互联网应用来说通常无法忍受。
当然如果解决此类服务调用采取注册机制的话,整个数据中心自然不经过中心节点,ESB中的压力就完全降低了,但是采用服务注册之后,服务治理方面就会有一定程度的退步,例如缺乏中心,这时我们引入合适的微服务框架来解决很多治理问题就完美了。
例如配置统一的注册中心,就相当于将之前提到的服务注册中心进行搬迁;另外使用同一的配置中心就相当于对依赖配置的部分可以不用手动部署就自动划归到中心里;之前涉及到的授权问题,就可以采用统一的授权以及鉴权体系来完成。针对过载,可以提供很多同意的熔断以及伸缩手段去解决,再通过统一日志来进行性能分析。
有了微服务这个平台后,我们可以把很多最佳实践整合进去。例如服务性能不够好就可以拆分成很多小服务;分析性能不好的关键点,例如调用链分析这类工具就出现了,作为微服务辅助工具来帮助大家解决这些方面问题。
微服务有了更强的治理能力,才有能力把服务拆到最小的粒度,因为更小粒度的时候,工程质量能够更好地去控制。
当然针对微服务还有许多值得学习的地方。例如微服务的调用很多,服务之间的调用协议设计就很重要,这可能会关乎到一些API设计的知识。所谓API设计,大家比较认同的有REST API的设计以及一些基础性理念,如何保证在API升级过程中,整个客户不受影响?又如何保证迁移成本更低?这些都需要实际解决。
另外一方面就是分布式事务。之前的单一组件事务非常简单,但当服务开始分布问题就不一样了 。分布式事务应该怎么去解决?这又是一个很独立的或者说很大的话题。
很重要的一点,服务究竟如何被拆分?从哪儿拆比较合适,哪儿是一些好拆分的边界点,怎么避免拆分时功能重叠、交叉?应该说其中有很多经验或者知识。对此我非常想推荐的一本书就是《领域驱动设计》,它会给你一个新视角去理解业务,只有很好地理解业务,才知道应该怎么去拆分业务,才能做到恰到好处。
总体来看,微服务很强大但其实还是有些遗留的问题,例如DevOps流程应该怎样?服务器上要运行大量异构服务,怎么避免互相干扰拆?微服务拆分多细颗粒度才较合适?这些问题有一些部分还是让Cloud Native着手解决吧!
针对部署和运维的方法论问题,例如部署形态是什么?其中最早的单机软件部署最简单,PHP都认为是部署最简单的,用SCP或者FTP上传,新的软件就部署好了。但也有隐患,这次部署与下次部署怎么保持完全一致?不一致的东西很多,例如运行时的版本、动态链接库的版本等,对此都是通过容器化的方式来解决。
从部署形态的集群来说,第一种最简单的就是无状态集群,有状态集群应该是少数特例。无状态集群一般都是同构的,没有特别关注只要水平部署就可以,只需要注意扩容与收容,这方面即便是在Cloud Native的概念出现之前,其实很多团队已经做得很好了,例如特定时间点的扩容,如何根据线上压力去做一些自动扩容等。
此外就是状态集群,之前部署过程中一个很大的问题就是非常依赖文档、部署的可在线性,导致同样装置一个数据库,例如MySQL5.6,不同人的实践结果都有差异;另外就是自研类,可能一些比较大的公司都会有一些自研的KV数据库、分布式数据库鞥,这类自研数据库非常依赖于开发和运维对系统的了解程度,以及整个升级务必要有各种回滚预案。
最麻烦的是什么?升级以后回滚其实超级难以创新,而k8s这类容器编排能很好地解决这些问题。如此看来K8s的出现帮助我们迎来了一个新的、怎样的运维状态?与之前有何不同?
首先在同一个服务中,所有节点都可以根据实际情况进行摘除和及时补充,这一点并不像之前很容易进入不一致的状态;另外在物理机的时代,线上的服务状态各种不一致,例如LINUX不一致,空间不一致,日志滚动的设置不一致,这都是有可能的,而如今做到严格一致利用K8s就好了。
还有一点,在K8s中取消了服务器的形态,这是运维工作或者是系统管理员工作的一大进步;没有服务器就意味着系统管理员之前在服务器中做的所有的工作没有了操作的对象,运维人员或者SRE人员就能够在一个更高的维度去保障服务质量。最后一点更安全。本身入侵到容器本身所造成的危害更小,还可以捉到可以定期重置,以此可以持续降低被攻击的风险。
首先对于新项目来说,如果技术实力稍弱,建议推荐采用微服务或者Spring Cloud这种方式落地。这种方式需要管理的事务较少,只要顺着思路写代码就可以了,如果能匹配云上的最佳服务实践就更赞。
对于技术实力稍强的可以考虑使用K8s,将整个业务管理起来,采用Service Mesh的方式落地,十分不错,当然这两种方式彼此并不排斥。对于一些特定的项目来说,例如事件驱动或者物联网项目、或者平时没有任何响应却突然有请求的,量大可以采用Serverless的架构,也就是函数服务的方式支持。
对于老项目,需要在逐渐演化的过程中循序渐进。对于技术实力相对较弱的情况,可以积极改善自动化的运维流程,尽可能达到容器化,充分利用云或者其他平台提供伸缩或者服务治理能力,然后根据团队情况考察K8s和Spring Cloud,逐步做一些迁移。
而技术实力比较强的可以直接利用Service Mesh逐步改造现有的项目。因为Service Mesh的一个好处就是对原来的服务器不侵入,也就是原来的服务可以不做任何迁移改造等,但是对技术能力要求较高。
京东云作为一个服务提供方,在微服务方面已经提供了一套微服务的服务框架,框架中支持Spring Cloud项目,也支持Dubbo项目。
围绕它来讲,会提供一些注册中心、配置中心、网关支持,还有调用链以及部署支持。也就是说用了京东云提供的微服务,Spring Cloud运维起来更轻松,关注点更多集中在业务领域;还有一个K8s方案,帮助完成资源的调度工作,相当于每个服务都会有一个新原生容器去承载服务。
第三个是基于Serverless的一些落地方案,京东云Serverless2018年才开始公测,现在只支持Python3,今年就会增加大量语言的支持,其中函数服务最大的好处是零成本启动。
最后是渐进式的落地方案,怎么落地呢?例如对一些无状态的服务要逐步做到容器化,对于有状态的服务尽可能替代为云提供产品;如果本身对k8s支持比较好,可以改造成一些高可用的形态;如果无法做到高可用,就尽可能做到自动化或者一键修复。
如果技术实力比较高的话,可以选择一些最佳的技术形态或者混合形态去做迁移,这方面更多是实际上对客户针对具体场景给出一些合理的建议来操作,然后进入Cloud Native的状态。
最后需要强调的是,Cloud Native就是一种理念,并不是一个具体的软件;使用Cloud Native系统管理员的工作可能就会消失掉,因为没有服务器,也就没有所谓的服务器管理员了;此外针对完美扩容的实现以及平滑的回滚流程,甚至包括各种部署等,Cloud Native都会提供一套合适的解决方案来帮助解决。
以上为公开课的所有内容。本周日(3月24日),我们会有一个线下沙龙,届时会详细讲一讲京东云的K8s,如何帮助落地,京东云的微服务提供了一些怎样的功能以及有关Serverless方面的技术实践,此外还会有一个关于开源软件的主题!
课程问答
云原生与前端技术开发的结合点可能会在哪些方向?
坦白讲这个问题还没有好好想过,应该说前端开发在哪个阶段,无论是基于API,还是服务端页面渲染等,其实都已经进入到一个崭新的状态,这个状态与云原生非常契合。
坦白讲,首先需要一个最佳形态的指导。现在云原生的落地形态实际上是一个相对分裂的状态,例如Service Mesh和K8s,究竟哪种技术会成为主导?现在还不确定。
从这个角度出发,其实对云原生并没有实质性的帮助,我们都希望可以从社区的角度解决此类问题。另外一个问题,K8s和Service Mesh的进入门槛还较高,怎么去解决这个问题?也许随着社区的进一步发展,大家对这个了解程度提高后就会有所改观。
使用Cloud Native能实现哪些简单的应用?
需要从K8s学起,如果你学会用K8s去开发一些小应用,对Cloud Native就有了一个最基本的理解。用好K8s之后,要去学习如何去做拆分,要学好如何在一个没有事务的情况下实现这个事务,也就是分布式事务一定要学,从这种角度入门比较合适。如果K8s这关过了,剩下的其实随着经验的慢慢提升也会慢慢学会的。
当我们讨论云原生时,其实对多云没有任何涉及,这应该算是另外一个问题。
如何想要实现多云或者多活,首先需要尽量减少有状态的组件;第二,要明确想实现的目标,是需要将云端SQL的修改同步到另一侧吗?关于这一点,主要还是一些基于事件或者日志方面的操作,或者直接通过分析驱动将MySQL映射到对面。第三,还要做好各种缓存更新以及清理工作,需要特别注意多云或者ADC多活。
其实Redis组件和MySQL组件非常希望被采用云上的版本,可以高效帮助解决传统问题、性能问题和运维问题。
如果是在私有化或者Open Stack上部署的话,要多看看这些组件有没有对已经配置好的一些K8s配置产生作用。因为K8s的配置能够帮助降低很多调优或者运维上的困难,例如Redis宕机了,究竟应该怎么处理?K8s可能已经把这些设置内嵌在配置中。