微服务出现的意义在哪里呢?它的优势有哪些呢?如何保障业务演进但是系统架构还是依然往好的方向发展呢 ?
一般而言,随着公司产品线的不断扩大,业务系统会越来越多,功能逻辑也越来越复杂,另外当前云服务的发展势头很好,服务必然就会倾向于服务化的部署方式,这样可以用来解耦服务之间的依赖,利于多团队的协作,利于业务系统的优化和管理,也利于后续的服务调度和资源的精细化管理。
【资料图】
对我们后端服务而言,目前常见的开发语言: Golang、Java、C/C++、Lua 、PHP,并且各个部门所使用的语言种类不一。如果公司没有一套规范化的流程和服务化框架,那么公司内部的各个业务团队、部门之间的技术体系就会越走越远,从而会给公司的服务端系统的稳定性和可运维性带来很大的挑战,所以就需要一个统一的微服务架构的实践统一解决当前的架构问题,防止架构腐化,从而提升我们后端系统的稳定性。这也是大多数互联网公司微服务化的意义所在。
ThoughtWorks 的首席科学家,马丁-福勒先生对微服务的一段描述,可以当做微服务的一个比较合适的定义:
微服务架构(Microservice Architect)是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。 -- James Lewis and Martin Fowler
对于这段话,我个人的理解是,微服务是一种架构设计的风格,它的核心思想是进行服务模块化,是构建分布式系统的一种非常合适的方式。微服务需要具备如下特性:
微服务架构中的每个服务,要保持功能的职责单一,并且是可以独立部署运行的。微服务架构中的每个服务,可以选择自己不同的合适自己团队的语言,并且可以独立管理,然后服务之间通过 RPC 或者 HTTP 协议进行交互整个业务系统通过各个服务之间的组合调用来形成一套完整的业务流程微服务架构本身并没有特别的先进之处,关键在于当微服务、容器化、DevOps 这三者相结合之后,在业务规模很大时,通过拆分出多个独立的服务进行开发、测试和运维,能够快速迭代,加快业务研发的速度,这才是传统架构向微服务架构转变的最大价值。
整个系统分为几个层次,比如逻辑应用层、核心功能层、通用组件层,然后把这些通用组件层、核心功能层剥离出来,进行微服务化的拆分。
然后把每一层中,那些相对稳定的、可扩展的也要剥离出来,进行微服务化的拆分。
首先要说明的一点就是微服务落地有很多难点要解决,在微服务推进面临的一些挑战有:
差异化的业务架构模型:公司现有的各个部门使用的框架不一样、产品形态多,比如有如下这些DoubboYARHTTP多语言化的架构形态:公司涉及到所有常见的开发语言:Java、C++、 PHP、 Golang、 Lua、 Python等性能和可行性要求:如何提高性能、如何尽可能少的嵌入业务等微服务拆分后如何部署、如何治理需要结合容器平台需要结合服务化框架系统服务之间的通信、链路追踪、log日志收集、问题排查定位如何运维管理:微服务大大增加了运维难度和复杂度微服务概念的提出者Martin Fowler其实在很早之前就说明了使用微服务需要具备的三个核心能力,分别是服务器的快速扩容、监控和应用的快速部署。针对我自己的理解以及以往实际开发服务化框架中的一些经验,我个人觉得,微服务化框架的落地,需要考虑并设计好如下一些需求点:
在云原生时代,所有的云服务厂商都有自己的 PaaS 产品,这样也让我们的微服务化体系建设的可执行落地带来的极大的优势和便利。
PaaS(平台即服务)提供了一个用于开发、运行和管理应用程序的完整、灵活且经济高效的云平台,PaaS 平台具备分布式、服务化、服务治理、自动化运维、高可用、服务编排等一些优势和特征,并且可以很好的和 IaaS 平台实现联动。
微服务体系下,有大量的服务需要进行运维管理,包括测试、发布上线、灰度放量、扩缩容等,那我们怎么合理的去处理好这些运维能力呢,这里就必须要有一套自动化运维管理体系,而这套东西,在业界,有一个叫做 DevOps 的文化,基于 DevOps 可以方便快捷的实现 CICD。CI 就是持续集成,是一种质量反馈机制,目的是尽快发现代码中的质量问题,CD 就是 持续部署,是指能够自动化、多批次、可控的实现软件部署,控制故障的影响范围或方便轻松的解决故障问题。通过 DevOps 的建设,可以实现软件生产流水线和软件运维自动化。
微服务化会带来服务模块增多的问题,会在一定程度上带来开发成本的提升,所以需要通过配套的工具链来减少服务化后的开发成本。
自动化测试平台的建设,可以有助于我们在开发测试阶段就尽可能的减少系统出现的问题,提供一层保障。自动化测试平台主要的目的是用来进行接口测试和接口拨测,后续也可以进一步去整合 流量录制和回放、全链路压测等相关功能。
落地微服务化框架之前,公司内部肯定有多种不同的语言去实现各自的业务,比如常见的 Java、Golang、PHP、C/C++ 等,那么我们如果想要推动进行改造,必然需要能够支撑各自的语言,需要根据公司大众语言各自实现一套对应语言的框架,然后不同语言之间,要能够进行互通,也就是 A 语言实现的接口,B 语言是可以调用的。
互通方式的思路包括两种:
第一种,简单的通过 HTTP 协议,也就是各自语言都通过 HTTP 协议来调用第二种,实现类似 gRPC 这种语言互通的服务化框架,通过 PB 进行 IDL 定义,然后内部的协议实现可以支撑不同的语言多语言互通的必要性是非常大的,能够实现多语言互通的话,推动落地的时候是一个大大的加分项,大家都会有意愿去迁移改造,否则就很难推动,你总不能随便就让别人去换一种编程语言吧。
服务的治理和管控是服务高可用的必备手段,服务治理与管控包括几大块:服务的治理、服务的监控、服务的可用性保障
服务的治理: 服务提供方的管理、服务使用方的管理、服务依赖的管理、服务的调用管理、服务的注册和发现、服务的部署和升级、服务的版本化管理服务的监控:数据采集、数据处理、链路跟踪、白盒化的报表展示、系统级的监控服务的可用性: Failover、Failfast、负载均衡、过载保护、服务降级、频率限制服务化框架需要去解决标准化的问题,因为只有标准化后,才方便去解决问题,进行统一规范,不然面临各种方案很容易导致解决问题的成本倍增。同时标准化后也更有利于后续统一化的工具链建设。这些标准化包括如下一些点:
标准化服务的拆分方式。标准化服务的调用方式标准化服务的治理策略标准化服务的性能和监控指标在服务化框架落地实施的时候,我们要考虑整体架构的平滑迁移和演进。因为原有不是微服务和统一服务化框架的体系下,大家都是各自为战,那么在进行统一的时候,我们必须要考虑到各个业务部门内部的迁移成本和服务的稳定性。如果我们退出一套框架,然后让业务部门之间全部重构,那么成本必然会很高,就会导致难以推进,可落地性就会面临问题。因此我们要尽可能的使我们的框架可以在不同的协议之间相互调用,兼容的目的是为了更好的落地而非更优雅的架构,这种兼容性并逐步演进的思路尤其是在大业务体量之下,更为重要。比如在大公司,如果内部要统一一套框架,而这套框架的协议不能兼容大部分已有服务架构,那么一定是很难推动的。我在公司内部实际经历各种框架、组件的处理姿势都是这个套路
微服务化后,我们首先要面临的一个问题就是成千上万个服务如何进行管理、如何部署、部署在哪里、服务之间如何解耦、如何进行环境隔离、如何保证同一个业务中的多个微服务实例能够运行在相同的环境、每个服务所需要的资源如何分配、如何保证资源的利用率。
试想一下? 直接部署在物理机上可行么? 部署在虚拟机上可行么 ?答案是都不行的!为啥? 虚拟机的粒度太大,即便是最小的物理机,至少也会有一个CPU核,但是微服务被拆分的非常小,这样才能成为微服务,我们的微服务也许根本就用不到一个核,这样对资源是一种极大的浪费。同时,虚拟机的创建、销毁相对比较耗时。 如果直接部署在物理机上,那么就更不行了,无法进行环境隔离、无有效利用资源。
这个时候,我们的容器化平台就要出场了,Docker,这个大家都很熟悉的词就是我们的突破口,Docker的创建和消耗可以在秒级别进行,同时Docker可以将运行环境进行隔离并且可以限制所使用的资源,计算粒度可以很小,可以是0.1个cpu,0.2个cpu这样的粒度,也可以是100M、101M、1000M这样任意值的内存。更为重要的是,业界出了很多容器编排管理的工具,如SwarmKit、Kubernetes、Mesos、Rancher等,可以对Docker进行全方位管理、监控,当然,现在最佳的肯定就是 Kubernetes 了。
所以,Kubernetes 容器化 和 微服务结合的优势具体来说体现在以下几个方面:
运行环境的隔离:容器为每个服务提供隔离、独立的运行环境,在同一个服务器上运行多种运行时相互有冲突的服务也不会出问题。细粒度的资源分配:容器能够很好的实现面向资源池的服务管理,每个服务可以更加精细化的分配 CPU 和内存等资源。快速创建和销毁: 容器可以在秒级进行创建和销毁,非常适合服务的快速构建和重组。完善的管理工具: 通过 kubernetes 可以很好的对服务进行编排和管理、调度微服务框架 + K8s 容器平台 是当今互联网业务的黄金标准
推荐阅读我的其他文章:
《高并发架构和系统设计经验》《TCP 长连接层的设计和 在 IM 项目中实战应用》《万字解读云原生时代,如何从 0 到 1 构建 K8s 容器平台的 LB(Nginx)负载均衡体系》《我终于统一了团队的技术方案设计模板》