微服务概念
微服务的概念最早是在2014年由Martin Fowler和James Lewis共同提出,他们定义了微服务是由单一应用程序构成的小服务,拥有自己的进程与轻量化处理,服务依业务功能设计,以全自动的方式部署,与其他服务使用HTTP API通讯。同时,服务会使用最小规模的集中管理 (例如Docker)技术,服务可以用不同的编程语言与数据库等。
微服务是一种软件架构风格,是以专注于单一责任与功能的小型功能区块为基础,利用模块化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关的API集相互通信。
单体应用
早期的互联网公司应用技术栈主要分为LAMP(Linux+Apache+MySQL+PHP)和MVC(Spring+iBaits/Hibernate+Tomcat)两大流派,
以MVC架构为例,业务通常是通过部署一个WAR包到Tomcat中,然后启动Tomcat,监听某个端口即可对外提供服务
优点:
学习成本低,开发上手快,测试、部署、运维也比较方便,甚至一个人就可以完成一个网站的开发与部署。
缺点:
随着业务规模的不断扩大,团队开发人员的不断扩张,单体应用架构就会开始出现问题
部署效率低下,团队协作开发成本高,系统高可用性差,线上发布变慢
解决上诉问题提出微服务的思想
服务化
把传统的单机应用中通过JAR包依赖产生的本地方法调用,改造成通过RPC接口产生的远程方法调用。在编写业务代码时,对于一些通用的业务逻辑,尽力把它抽象并独立成为专门的模块
利用RPC接口的形式对外提供服务
通过服务化,可以解决单体应用膨胀,团队开发耦合度高、协作效率低下等问题
微服务
微服务相较于服务化出现了改变
- 服务拆分粒度更细
- 服务独立部署
- 服务独立维护
- 服务治理能力要求高
总结:
微服务架构是将复杂臃肿的单体应用进行细粒度的服务化拆分,每个拆分出来的服务各自独立打包部署,并交由小团队进行开发和运维,从而极大地提高了应用交付的效率,并被各大互联网公司所普遍采用。
什么样的服务才算是微服务?
单一职责:一个微服务应该都是单一职责的,一个微服务解决一个业务问题
面向服务:将自己的业务能力封装并对外提供服务,继承面向服务的核心思想,一个微服务本身也可能使用到其他微服务的能力。
微服务面临的问题
Q1:服务发现问题,一个微服务如何发现其他微服务?
每个微服务里面配置其他微服务的地址,当微服务数量众多时,使用:服务注册中心,所有服务都注册到服务注册中心,同时从服务注册中心中获取当前可用的服务清单。
Q2: 服务配置管理问题:服务数量超过一定程度后,需要在每个服务里面分别维护每一个服务的配置文件。
使用服务配置中心
Q3: 当客户端或外部应用调用服务的时候应该怎么处理?不同服务具有不同的服务地址,服务验证的相关工作应该在哪儿完成?
使用服务网关提供统一的服务入口,最终形成典型的微服务架构
微服务涉及的领域还包括:
通过熔断、限流等机制保证高可用
微服务之间调用的负载均衡
分布式事务
服务调用链跟踪
微服务框架
主流的微服务框架:Spring Cloud和Dubbo
微服务业务拆分
面向微服务的业务拆分:
单体到微服务的拆分:从非核心服务到核心业务完成拆分,基础设施按照优先级进行落地
粗粒度拆分微服务:按照质量(性能、复杂度、可用性)、交付频率拆分,重用现在的基础设施
服务拆分的粒度:能够维持2-4个人维护一个微服务最佳
网关
作为微服务的统一吐口,肩负着整个微服务的流量接入、管理、聚合、安全等,从服务分层的角度可以分为接入网关和业务网关
接入网关
接入网关提供最基础的流量接入和安全防护能力,侧重于全局,与业务无关
域名&DNS
负载均衡(LB):主要负责请求的转发代理,按机器负载进行分配流量,对外提供VIP,负载可以宽泛的理解为系统的压力,可以用CPU负载来衡量,也可用连接数、I/O使用率、网卡吞吐量进行衡量
网关同时负责服务整体的安全防护,SSL,IPV6
业务网关
业务网关作为业务最上层入口,一般承担起业务接入或BFF(Backend for Frontends)工作,
鉴权:验证用户、请求
限流:做流量控制,防止对系统产生过大压力从而影响整个服务
熔断:作为服务断路器,可防止应用程序重复尝试执行可能失败的操作,对整体链路起到保护作用。断路器内部会推断“打开”,“半打开”,“关闭”三种状态,来决定对请求的状态,同时结合降级策略提升服务的鲁棒性
降级:当限流、熔断、超时或系统故障发生时,通过丢弃一部分请求来减少系统的工作量,本质上是提供一种有损服务
重试:出现连接失误/超时-网络抖动,使用重试提高请求的最终成功率
插件化:为了集成技术人员编写的一些业务相关的通用能力
BFF:按照业务逻辑,以串行,并行和分支等结构编排多个服务API,为服务提供聚合、适配、裁剪功能。核心是API的动态编排用以满足日益增长的业务逻辑,降低前端与微服务之间的对接成本。
协议
微服务架构之间的服务间通信方式主要分为HTTP REST和RPC
HTTP REST,更确切的讲师指的是API设计风格,而不是协议标准
RPC,描述了客户端与服务端之间的点对点调用流程,包括RPC消息协议、序列化、通信等。可基于TCP,也可基于HTTP。目前RPC框架大致包括,偏向于服务治理(Dubbo、Mottan),另一种偏向于跨语言调用(Thrift/GRPC)
RPC相比HTTP REST的优点
更清晰的API定义
更好的传输效率
更合适的容错机制
服务注册
服务注册主要将微服务的后端机器IP、端口、地域等信息注册起来,并结合一定的发现机制使客户端的请求能够直连具体的后端机器。根据实现方式可分为服务端模式与客户端模式
服务端模式:传统模式,借助负载均衡器和DNS进行实现,负载均衡器负责健康检查,负载均衡策略,DNS负责实现访问域名到负载均衡器IP/VIP的映射关系,通过直接暴露域名和端口的方式提供客户端进行访问
服务端模式注册与发现都由服务端完成,这样可以使客户端专注在自身的业务实现,但是由于以来负载均衡器,使其成为系统瓶颈,可用性的高低直接决定了服务质量。
客户端模式:借助注册中心实现,注册中心负责服务的注册与健康检查,客户端通过监听配置变更的方式及时把配置中心维护的配置同步到本地,通过客户端负载均衡策略直接向后端机器发起请求
客户端模式注册与发现由配置中心和客户端共同完成,客户端先通过服务发现获取到真实的后端节点,再与后端节点直接通信,通过去中心化的方式,可以避免出现双向链接等proxy模式的性能问题,但可靠性容易出现在配置中心上,并且客户端的也需要一定的接入成本。
配置中心
配置中心除了基础的配置数据,一些情况下还要开放给非开发人员使用,完善的控制台,权限管理,dashbord支持,也非常重要
可观测性
可观测性围绕着Tracing(链路追踪)、Logging(日志)和Metrics(度量)展开
消息队列
消息队列是一种进程间通信或同一进程的不同线程之间的通信方式,软件的贮列用来处理一系列的输入,通常是来自用户。消息队列提供异步的通信协议,每一个贮列中的记录包括详细说明的数据,包含发生的时间,输入设备的种类,以及待定的输入参数,也就是说:消息的发送者和接受者不需要同时与消息队列进行交互。消息会保存在队列中,直到接收者取回它。
消息队列的选型主要侧重于:
HA: 自身的高可用性保障,避免消息队列的引入而影响整体服务的可行性
高吞吐:面对海量数据写入能否保持一个相对稳定、高效的数据处理能力
功能丰富性:是否支持延迟消息、事务信息、死信队列、优先级队列等
消息广播:是否支持将消息广播给消费者或则一组消费者
消息堆积能力:在数据量过大时,是否允许一定消息堆积到broker
数据持久性:数据持久化策略的采用,也决定着数据在宕机恢复后是否会丢失数据
重复消费:是否支持ack机制,在消费者未正确处理消息时,支持重新消费
消息顺序性:针对顺序消费的场景保证数据按写入时间的顺序性
常见的主要有:Redis、Rabbmq/Rocketmq、kafka、Plusar