微服务 (Microservices) 是一种软件架构风格,将应用程序构造为围绕业务的小型自治服务的集合git
微服务以专一于单一责任与功能的小型功能区块 (Small Building Blocks) 为基础。每一个服务都是独立的,并实现单个业务功能github
微服务利用模块化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关的 API 集相互通讯算法
微服务运用了以业务功能为主导的设计概念,应用程序在设计时就能先以业务功能或流程设计先行分割,将各个业务功能都独立实现成一个能自主运行的个体服务,而后再利用相同的协议将全部应用程序须要的服务都组合起来,造成一个应用程序数据库
以购物车应用程序为例,当打开购物车应用程序时,您看到的只是一个网站。可是,在后台,购物车应用程序具备用于接受付款服务,客户服务等设计模式
假设此应用程序的开发人员使用了单体框架,架构以下图
服务器
如图,在单体架构中,全部功能都放在一个代码库中,并在一个基础数据库下网络
如今,假设市场上出现了一个新品牌,而且开发人员但愿将即将到来的品牌的全部详细信息放入此应用程序中架构
此时,不只须要处理新品牌的服务,并且还必须从新构建整个系统并相应地进行部署。为了不此类挑战,开发人员决定将其应用程序从单体架构转换为微服务app
开发人员为搜索,推荐,客户服务等建立了单独的微服务负载均衡
此微服务架构不只能够帮助开发人员克服之前的架构所面临的全部挑战,并且还能够轻松地构建,部署和扩展购物车应用程序
以旅游行业应用程序为例
总体服务包括了旅客关系管理、付款、消息通知等服务
传统的单体经常采用如上图所示的总体式架构,并采起MVC的设计模式
三层架构(MVC)的具体内容以下
表示层(view): 用户使用应用程序时,看到的、听见的、输入的或者交互的部分。
业务逻辑层(controller): 根据用户输入的信息,进行逻辑计算或者业务处理的部分。
数据访问层(model): 关注有效地操做原始数据的部分,如将数据存储到存储介质(如数据库、文件系统)及
从存储介质中读取数据等。
虽然如今程序被分红了三层,但只是逻辑上的分层,并非物理上的分层。也就是说,对不一样层的代码而言,通过编译、打包和部署后,全部的代码最终仍是运行在同一个进程中
单体架构在规模比较小的状况下工做状况良好,可是随着系统规模的扩大,它暴露出来的问题也愈来愈多,主要有如下几点:
复杂性逐渐变高
好比有的项目有几十万行代码,各个模块之间区别比较模糊,逻辑比较混乱,代码越多复杂性越高,越难解决遇到的问题
技术债务逐渐上升
公司的人员流动是再正常不过的事情,有的员工在离职以前,疏于代码质量的自我管束,致使留下来不少坑,因为单体项目代码量庞大的惊人,留下的坑很难被发觉,这就给新来的员工带来很大的烦恼,人员流动越大所留下的坑越多,也就是所谓的技术债务愈来愈多
维护成本大
当应用程序的功能愈来愈多、团队愈来愈大时,沟通成本、管理成本显著增长。当出现 bug 时,可能引发 bug 的缘由组合愈来愈多,致使分析、定位和修复的成本增长;而且在对全局功能缺少深度理解的状况下,容易在修复bug 时引入新的 bug
持续交付周期长
构建和部署时间会随着功能的增多而增长,任何细微的修改都会触发部署流水线。新人培养周期长:新成员了解背景、熟悉业务和配置环境的时间愈来愈长
技术选型成本高
单块架构倾向于采用统一的技术平台或方案来解决全部问题,若是后续想引入新的技术或框架,成本和风险都很大
可扩展性差
随着功能的增长,垂直扩展的成本将会愈来愈大;而对于水平扩展而言,由于全部代码都运行在同一个进程,没办法作到针对应用程序的部分功能作独立的扩展
将上面的总体架构改造为如上图所示的微服务
来自不一样设备的不一样客户端尝试使用不一样的服务,例如搜索,构建,配置和其余管理功能
全部服务均根据其功能进行分离,并进一步分离为单个微服务
这些微服务具备本身的负载均衡和执行环境以执行其功能,并在其本身的数据库中捕获数据
微服务之间经过无状态服务器(REST、GRPC或消息总线)进行通讯
微服务借助服务发现来了解其通讯路径并执行自动化,监控等操做功能
微服务执行的全部功能经过API网关传达给客户端
解耦
系统中的服务在很大程度上是解耦的。所以,整个应用程序能够轻松构建,更改和扩展
组件化
微服务被视为独立的组件,能够轻松替换和升级
专一业务功能
业务功能–微服务很是简单,专一于单一功能
独立自主
开发人员和团队能够彼此独立地工做,从而提升了速度
持续交付
经过自动化的构建、测试和部署,容许频繁发布软件
分散治理
重点是使用正确的工具完成正确的工做。这意味着没有标准化模式或任何技术模式。开发人员能够自由选择最有用的工具来解决他们的问题
敏捷开发
微服务支持敏捷开发。任何新功能均可以快速开发并丢弃
单一职责
微服务架构中的每一个服务,都是具备业务逻辑的,符合高内聚、低耦合原则以及单一职责原则的单元,不一样的服务经过“管道”的方式灵活组合,从而构建出庞大的系统
轻量级通讯
服务之间经过轻量级的通讯机制实现互通互联,而所谓的轻量级,一般指语言无关、平台无关的交互方式
对于轻量级通讯的格式而言,咱们熟悉的 XML 和 JSON,它们是语言无关、平台无关的;对于通讯的协议而言,一般基于 HTTP,能让服务间的通讯变得标准化、无状态化。目前你们熟悉的 REST(Representational StateTransfer)、GRPC是实现服务间互相协做的轻量级通讯机制之一。使用轻量级通讯机制,可让团队选择更适合的语言、工具或者平台来开发服务自己
提升容错性(fault isolation),一个服务的内存泄露并不会让整个系统瘫痪
独立性
服务独立测试、部署、升级、发布
在单块架构中全部功能都在同一个代码库,功能的开发不具备独立性;当不一样小组完成多个功能后,须要通过集成和回归测试,测试过程也不具备独立性;当测试完成后,应用被构建成一个包,若是某个功能存在 bug,将致使整个部署失败或者回滚
新技术的应用,系统不会被长期限制在某个技术栈上
能够根据市场需求,灵活多变的组合出新的业务场景
下降代码耦合度
服务实例水平扩展,服务单一职责,功能独立。保证可靠性与性能,提高资源利用
因为微服务是以业务功能导向的实现,所以不会受到应用程序的干扰,微服务的管理员能够视运算资源的须要来配置微服务到不一样的运算资源内,或是布建新的运算资源并将它配置进去
提高开发交流,每一个服务足够内聚,足够小,代码容易理解
进程隔离、故障隔离
单块架构中,整个系统运行在同一个进程中,当应用进行部署时,必须停掉当前正在运行的应用,部署完成后再重启进程,没法作到独立部署 有时候咱们会将重复的代码抽取出来封装成组件,在单块架构中,组件一般的形态叫作共享库(如 jar 包或者DLL),可是当程序运行时,全部组件最终也会被加载到同一进程中运行。
在微服务架构中,应用程序由多个服务组成,每一个服务都是高度自治的独立业务实体,能够运行在独立的进程中,不一样的服务能很是容易地部署到不一样的主机上
即便应用程序的一项服务不起做用,系统仍然能够继续运行
数据分区,数据独立,可靠性保证
微服务提升了系统的复杂度
开发人员要处理分布式系统的复杂性
服务之间的分布式事务问题
服务的注册与发现问题
数据隔离再来的报表处理问题
不一样服务实例的管理困难,持续自动化部署的要求
运维要求较高
对于单体架构来说,咱们只须要维护好这一个项目就能够了,可是对于微服务架构来说,因为项目是由多个微服务构成的,每一个模块出现问题都会形成整个项目运行出现异常,想要知道是哪一个模块形成的问题每每是不容易的,由于咱们没法一步一步经过debug的方式来跟踪,这就对运维人员提出了很高的要求
分布式的复杂性
对于单体架构来说,咱们能够不使用分布式,可是对于微服务架构来讲,分布式几乎是必会用的技术,因为分布式自己的复杂性,致使微服务架构也变得复杂起来
接口调整成本高
好比,用户微服务是要被订单微服务和电影微服务所调用的,一旦用户微服务的接口发生大的变更,那么全部依赖它的微服务都要作相应的调整,因为微服务可能很是多,那么调整接口所形成的成本将会明显提升
微服务的规划与单体式应用程序十分不一样,微服务中每一个服务都须要避免与其余服务有所牵连,且都要可以自主,并在其余服务发生错误时不受干扰
假若真有沟通,也应采用异步沟通的方式来避免紧密的相依性问题。要达到此目的,则可用下列两种方式:
事件存储中心(Event Store)
这可让你在服务集群中广播事件,而且在每一个服务中监听这些事件并做处理,这令服务之间没有紧密的相依性,而这些发生的事件都会被保存在事件存储中内心。这意味着当微服务从新上线、部署时能够重播(Replay)全部的事件。这也造就了微服务的数据库随时均可以被删除、摧毁,且不须要从其余服务中获取数据
消息队列(Message Queue)
可以在服务集群中广播消息,并传递到每一个服务中
比较有名的消息中间件如:NSQ、RabbitMQ、Nats、Kafka
A 服务上广播一个事件,此事件能够顺带一些数据。B 服务能够监听这个事件并在接收到以后有所处理。这些过程都是异步处理的
A 服务并不须要等到 B 服务处理完该事件后才能继续,而这也表明 A 服务没法获取 B 服务的处理结果
与事件存储中心不一样的是:消息队列并不会保存事件。一旦事件被消化(接收)后就会从队列中消失
单个微服务在上线的时候,会向服务注册中心注册本身的 IP 位置、服务内容
当服务须要调用另外一个服务的时候,会去询问服务探索中心该服务的 IP 位置,获得位置后便可直接向目标服务发起调用
这么作的用意是能够统一集中全部服务的位置,就不会分散于每一个微服务中
服务发现中心能够每隔一段时间就向微服务进行健康检查(TCP 调用、HTTP 调用、Ping)
假若该服务在时间内没有回应,则将其从服务中心移除,避免其余微服务对一个无回应的服务进行调用
即使微服务从新在其余ip上部署,其余服务也是无感知的
比较经常使用的服务发现有:etcd,consul,广泛都采用了raft等分布式算法
网络延迟
分布式事务
限流
例如一个服务挂掉后,上游服务或者用户通常会习惯性地重试访问。这致使一旦服务恢复正常,极可能由于瞬间网络流量过大又马上挂掉
所以服务须要可以自我保护——限流。限流策略有不少,最简单的好比当单位时间内请求数过多时,丢弃多余的请求。另外,也能够考虑分区限流。仅拒绝来自产生大量请求的服务的请求
熔断
当一个服务由于各类缘由中止响应时,调用方一般会等待一段时间,而后超时或者收到错误返回
若是调用链路比较长,可能会致使请求堆积,整条链路占用大量资源一直在等待下游响应。因此当屡次访问一个服务失败时,应熔断,标记该服务已中止工做,直接返回错误。直至该服务恢复正常后再从新创建链接
服务降级
当Service A调用Service B,失败屡次达到必定阀值,Service A不会再去调Service B,而会去执行本地的降级方法
降级服务其实就是牺牲掉一些逻辑处理,或者中止部分依赖服务的请求。以保障服务能够提供关键能力
权限控制
API网关
分布式追踪
分布式日志记录
配置中心