云原生&微服务
近年来微服务与云原生、CI/CD这些概念被炒得很火,多数应用都会说自己利用了“云”资源,是一个云原生架构的应用。那么云原生到底是什么呢,或者说使用了什么样的技术的应用才能被称之为云原生应用呢?
云计算的兴起
首先云原生是和云计算分不开的,这里的云计算更多的指的是一种云上的资源,而云出现之前,市场还处在一个物理机时代,如果要启用一个新的应用,就得自己搭一台新的服务器,一直到2001年VM出现了,通过虚拟机可以在一台服务器上跑多个虚拟机来减少服务器的数量(同时也是减少了企业堆机子的钱)
而在虚拟化技术成熟之后,云计算才正式出现,第一个搞云的公司是AWS,在2008年证明了云计算是可行业务
云计算出租的模式有三种
IaaS:Infrastruture As A Service(基础设施及服务),是云服务的最低层,主要提供一些基础资源,比如服务器、存储和网络。我们常规用的云服务器就属于IaaS
PaaS:Platfrom as a Service (平台即服务),提供商为企业搭建网络基础设施及软件、硬件平台,将软件开发、管理、部署都交给第三方,开箱即用。除了底层的服务器之后,通常还具备相应的功能接口,比如阿里云可以给视频自动转码,给视频加速提高清晰度等。
SaaS:Software as a Service(软件即服务),开发者只需要关注自己的业务逻辑,不需要关心底层。使用这一层的云计算资源甚至不需要开发人员,供应商直接提供一站式服务。
火热的微服务
在我们开发一个应用服务时,有很多种架构供我们选择,而这些架构按照历史的时间线来看的话,其实能发现它们是在不断向低耦合,高性能,敏捷开发、快速发布、高度自治化这几个方面不断靠拢的
单体应用
单体应用通常是一个庞大的文件,部署在一台机器上,高耦合,对功能修改通常需要牵一发而动全身,想要增强单体应用的性能一般只能堆机子,不断增加服务器的数量
分层架构
最典型的就是MVC和MSC架构,分别是 model view controller和model service controller的缩写,随着时代的发展,人们发现单体应用很难抗住大流量,于是分层架构诞生了。分层架构就是将单体应用进行垂直分层,耦合依旧大,项目之间的接口大多数为数据同步,是一种很简单的架构。开发快速,经过垂直拆分之后项目不至于太大,每一层可以使用不同的技术。
SOA面向服务架构
当垂直架构的应用越来越多,就会出现多个应用都依赖的业务组件,比如数据库,而且各个应用交互越来越频繁,此时就需要把部分通用的组件拆分独立处理,于是SOA面向服务架构诞生了,它带来了模块化开发、分布式拓展部署和服务接口定义等概念。SOA需要建立企业服务总线,外部应用通过总线调用服务,有以下特征:可从企业外部访问、随时可用、标准化的服务接口等。一般是大型企业才考虑使用SOA架构
,当业务总线崩掉,所有的服务都会挂掉。可以说业务总线的吞吐量决定着整个系统的上限。
微服务架构
在吸取了SOA的思想之后,微服务诞生了,它具有以下特点
- 服务层完全独立 并将服务层抽离为一个个的微服务
- 遵循单一原则
- 使用RESTful等轻量协议进行通信
- 一般使用容器技术进行部署 运行在自己的独立进程中
架构如图:
在微服务架构下服务的拆分粒度更细小,有利于资源的重复利用,提高开发效率,采用去中心化思想,更加轻量级
缺点:如果服务实例过多,那么治理成本就会很大,不利于维护;且服务之间相互依赖,可能形成复杂的依赖链条,往往单个服务异常,其他的服务也会受到影响
在实际开发中一般通过DDD的思想对微服务进行拆分,既不能让服务实例太多(不好治理、部署成本大、调用关系复杂),也不能让服务实例太少(每个服务量级都很大,高度耦合),一般是通过各个服务的作用域进行划分。
微服务与SOA的区别 :
微服务继承了SOA的众多优点和理念
SOA更适合与许多其他应用程序集成的大型复杂企业应用程序环境,小型的应用并不适合SOA,微服务则更适合于较小和良好的分割式web业务系统,在微服务架构中没有SOA中的ESB进行集中化管理,而是通过轻量级通信机制相互沟通。SOA尝试采用中心化管理来确保每个应用之间能够协同运作,而微服务则尝试部署新功能。快速有效的拓展开发团队,注重于分散管理、代码再利用与自动化执行
主流的微服务框架
Java:Spring Cloud 和Dubbo
Go:Go-kit与Go-Micro
Go-Kit:
是一个Go语言工具包等级和,提供了实现系统监控和弹性模式组件的库,比如日志记录、跟踪、限流、熔断等
基于Go-Kit的应用程序架构由三个主要部分组成:传输层、接口层和服务层
传输层:网络通信,通常使用HTTP或者grpc等网络传输方式,Go-Kit还支持使用AMQP(提供同一消息维护的应用层协议)和Thift(接口描述语言与二进制通讯协议)等多种网络通信模式
接口层:服务器和客户端的基本构建块,在Go-kit中的每个对外提供的接口方法都会被定义成一个端点,以便在服务器和客户端之间进行网络通信
服务层:具体的业务逻辑实现,业务逻辑包括核心业务逻辑
Go-Micro
基于Go实现的插件化RPC微服务框架,提供了服务发现、负载均衡、同步传输、异步通信以及事件驱动等机制,尝试弱化分布式系统间的通信,让开发者可以专注与自身业务逻辑的开发
设计哲学:可查博士的架构理念,提供可快速构建微服务系统的组件
Go-Micro组件
- registy :服务发现组件 解析服务name至服务地址 支持consul etcd zookeeper dns和gossip等组件
- selector: 基于registry的客户端负载均衡组件 client使用selector组件从registry返回的服务列表中进行负载均衡选择
- broker: 发布和订阅组件 服务之间基于消息中间件的异步通信方式 一般使用MQ 比如kafka rabbitMQ等等
- transport: 服务之间同步通信方式
- codec: 服务之间消息的编码和解码
- server: 服务主体 该组件基于上面的registry selector transport和broker组件,对外提供一个同一的服务请求入口
- client:提供微服务的客户端
微服务六大准则
1.高内聚 低耦合 每个服务是针对于一个单一职责业务能力的封装 服务之间通过轻量级的通信方式进行通信
2.高度自治 每个服务能够独立部署并运行在独立的进程内 技术选型灵活 合适的业务问题可以选择合适的技术栈 服务与服务之间采取与语言无关的网络通信进行交互 也就是说服务之间可以用不同的语言、不同的版本、不同的工具、在不同的系统上运行
3.以业务为中心 每个服务代表了特定的业务逻辑 有明显的边界上下文
4.弹性设计 可容错、具有自我保护能力的系统,服务之间相互隔离,限制使用资源,防止级联的服务雪崩错误
5.日志与监控 必须用分布式日志系统进行日志的管理 不然每个微服务独自具有各自的日志 查找起来会很麻烦 监控各个服务的性能 比如Promethus,进行资源的弹性化扩张与收缩
6.自动化
云原生技术及十二因素
现在对于云原生的定义通常是:有利于各组织在公有云、私有云与混合云等新型动态环境中,构建和运行可弹性拓展的应用,代表技术有容器、服务网格、微服务、不可变基础设施即声明式API
云原生的基础架构
- 微服务:每个服务被独立部署,服务之间松耦合,这样就可以独立对每个服务进行升级、部署、拓展和重启,具有降低系统复杂度。独立部署,独立扩展和跨语言编程等优点。同时对于运维来说,难度提升,并且整个分布式系统变得更复杂,需要大量的测试机部署。还需要考虑网络延迟、容错性、消息序列化和不可靠网络等等
- 容器:轻量级的虚拟化技术,能够在单一主机上提供多个隔离的操作系统环境,通过一系列的namespace进行进程隔离,容器分为运行时和编排两层,运行时负责容器的计算、存储、网络等,编排层负责容器集群的调度,服务发现和资源管理。另外,仅仅有容器还是不够,这样的话运维部署成本太大,为了解决容器的管理和调度问题,又引入了Kubernetes(在1.20版本Kubernetes正式抛弃docker),可以实现容器化的自动化部署、自动化扩容缩容和维护等功能
- 服务网格(service mesh)主要有侵入式架构和非侵入式架构,侵入式指的是服务框架嵌入程序代码,开发者组合各种组件,如RPC、负载均衡。熔断等,实现微服务架构。非侵入式主要是以代理的形式和应用程序部署在一起,开发者只需要关注自身业务即可。service mesh使得系统架构的技术栈下移,解耦了应用程序的监控、追踪和服务发现。相关软件包括istio linkerd等,同时为了让service mesh有更好的底层支撑,我们又将servise mesh运行在kubernetes上
- DevOps:包含了开发、测试和运维第三个部分,由一个团队负责,不断的更新迭代,推进产品的开发进程,可以实现快速开发与快速部署
- 声明式API:Kubernetes的能力都是通过各种API来提供的,所谓的声明式API,就是会编写对应的API对象的YAML文件交给Kubernetes,而不是直接使用一些命令来操作API,这个YAML文件其实就是一种声明,而一个个提交命令,则是命令式API。通常声明式API具有以下特点:1.包含相对少量的相对较小的对象。2.这些对象定义应用程序或者基础结构的配置。3.对象相对更新不频繁
- 不可变基础设施:在传统的可变基础设施(服务器)中,服务器会不断的更新和修改,这类设施的管理员可以手动升级或者降级软件包版本,调整服务器的配置,这样的服务器我们认为是可变的。他们可以在创建后修改。不可变基础设施就是另一种基础设施模式,其中的服务器在部署之后永远不会修改,如果需要以任何方式更新、修复或者修改默写内容,需要先对公共镜像进行修改,然后利用镜像构建新服务器来替换旧服务器,验证之后新的服务器会投入使用,旧的服务器会被下掉。不可变基础设施能提供更高的一致性和可靠性,更简单、更可预测的部署过程。二者被比作宠物和牛,过去我们将服务器当做宠物,如果倒下了那么服务就无法运行,而在新的方式中,服务器被编号,就像一群牛
云原生十二因素
云原生的12因素是知道开发者如何利用云平台来构建更具可靠性和扩展性,更易维护的云原生应用
1.CodeBase:基础代码,一份基准代码,多份部署,用一个代码库进行版本控制和应用程序的多次部署
2.Dependencies:显示声明依赖关系,应用程序通过适当的工具隔离依赖性
3.Config:配置文件,在环境中存储配置
4.Backing Services:后端服务,把后端服务当做附加资源(很珍贵的资源),数据库、消息队列、换出系统都被当做附加资源在不同环境中被同等的调用。听说现在很多大厂都不会直接操作数据库了,咱也不知道具体是怎么实现的,数据存在哪里。
5.Build release run:构建、发布、运行 严格分离架构和运行
6.Processes:以一个或多个无状态进程运行应用,任何需要持久化的数据都被存储在后端服务中
7.Port binding:端口绑定,通过端口绑定提供服务
8.Concurrency:并发,通过进程模型进行拓展
9.Disposability:易处理、快速启动和优雅终止
10.Dev/pro parity:开发环境与线上环境等价,尽可能保持开发、预发布和线上环境的相似性
11.Logs:将日志当做事件流,允许执行环节通过集中式服务来收集、聚合和检索分析日志
12.Admin processes:管理进程,后台管理任务当做一次性进程运行
12因素已经提出很久了,有部分因素已经无法跟上时代的发展,只能作为参考
现如今的技术更迭是非常非常快的,很多东西作为学生你刚听说,觉得很新颖想去学,可能企业已经用过很久,甚至业界已经有更优的方案,把这个技术抛弃了。也有部分后端开发者自嘲道,这个东西我还没学,人家就不用了。因此,我建议大家不管什么技术,你如果感兴趣就先上手,对着官方文档看,其实任何高级、难的技术如果仅仅只是上手的话往往花不了太多时间。