浅谈微服务
微服务概念
微服务来源
单体应用
微服务是相对于单体应用的,在介绍微服务之前,先简单介绍一下单体应用:通常是由三个重要部分组成:客户端界面(由HTML、JavaScript组成)、数据库(由许多的表组件构成一个通用的、相互关联的数据管理系统)、服务端应用。服务端应用处理客户端的HTTP请求、执行逻辑、检索并更新数据库中的数据、然后将处理后的数据返回给客户端。
一个单体应用被构建成一个系统时,业务中所有请求都要在单一的进程中处理完成,当访问量很高情况下服务器压力是很大的。当然可以水平扩展,利用负载均衡将实例布署到多台服务器中。
单体架构的缺点
云时代
在此之前单体应用也是很成功的,但是随着云时代的到来,单体应用就显得有些不妥了,特别是应用程序发布到云端的时候,一个功能的变更,需要统一的编译和发布。这样的架构模式很难使得一个模块的变更不影响到其他模块,而且在扩展方面也只能进行整体的扩展,不能根据正在运行的部分进行扩展。
微服务架构风格
云时代单体应用的尴尬导致了微服务架构风格的出现:以服务构建应用。
一个系统由多个服务组成,各服务可以被独立布署、独立扩展,每个服务也都提供了清晰的模块边界,甚至不同的服务都可以使用不同的编程语言来实现,也可以由不同的团队进行管理。
微服务介绍
微服务是SOA架构下的最终产物
SOA介绍
SOA架构即面向服务的架构,是一种组件模型,它将应用程序的不同功能单元进行拆分,并通过这些服务之间定义良好的接口和协议联系起来;这些不同功能的单元在被拆分后,就被称为服务。
在这种架构中,最重要的是接口的定义,这种定义是不依赖于实现服务的硬件平台、操作系统和编程语言的,即中立的。这样就可以使各服务可以与非本系统的服务以同样方式进行交互,使得各服务之间松耦合。它的优点就是非常灵活——当组成整个应用程序的每个服务的内部结构和实现逐渐地发生改变时,各服务能够继续存在并提供服务。
SOA的特征:
- 可从企业外部访问
- 随时可用
- 粗粒度的服务接口分级
- 松散耦合
- 可重用的服务
- 服务接口设计管理
- 标准化的服务接口
- 支持各种消息模式
- 精确定义的服务契约
分布式定义
旨在支持应用程序和服务的开发,可以利用物理架构,由多个自治的处理元素,不共享主内存,但通过网络发送消息合作。
微服务风格特征
-
组件化与服务
-
组件化的主要方式是把它拆分成服务,这些组件被链接到程序,并通过内存中函数调用来调用,而服务是进程外组件,他们利用某个机制通信,比如WebService请求,或远程过程调用。
-
把服务当成组件的一个主要原因是,服务可以独立部署。如果应用程序是由一个单独进程中的很多库组成,那么对任何一个组件的改变都将导致必须重新部署整个应用程序。但是如果把应用程序拆分成很多服务,只需要重新部署那个改变的服务。
-
另一方面,把服务当组件将拥有更清晰的组件接口。
-
-
围绕业务功能的组织
-
当寻找把一个大的应用程序拆分成小的部分时,通常管理都会集中在技术层面,UI团队、服务端业务逻辑团队和数据库团队。当使用这种标准对团队进行划分时,甚至小小的更变都将导致跨团队项目协作,从而消耗时间和增加沟通成本。
-
微服务的划分方法不同,它倾向围绕业务功能的组织来分割服务。这些服务实现商业领域的软件,包括用户界面,持久化存储,任何的外部协作。因此,团队是跨职能的,包含开发过程所要求的所有技能:用户体验、数据库和项目管理。
-
-
强化终端及弱化通道
微服务的应用致力松耦合和高内聚:采用单独的业务逻辑,基于互联网构建系统。Unix本身就是这样的哲学。
-
第一种做法是接受请求、处理业务逻辑、返回响应。侧重简单的REST风格,而不是复杂的协议。
-
第二种做法是通过轻量级消息总线来发布消息。这种的通信协议非常的单一,像RabbitMQ或者Kafka这样的实现,需要依赖产生或者消费消息的终端或者服务来处理这类问题。
在整体工风格中,组件在进程内执行,进程间的消息通信通常通过调用方法或者回调函数。从内存内部原始的调用变成远程调用,产生的大量的不可靠通信。因此需要把粗粒度的方法成更加细粒度的通信。
-
微服务定义总结
SOA 架构与微服务架构
微服务是由SOA演化而来,但是微服务与SOA架构有着太多不同了,微服务风格与SOA所提倡的一些优势非常相似,但是区别还是非常大:
-
ESB和API网关
-
SOA架构
:使用ESB(企业服务总线)来连接各个服务节点。为了集成不同系统,不同协议的服务,ESB做了消息的转化解释和路由工作,让不同的服务互联互通。 -
微服务架构
:微服务将API网关服务当作系统的唯一入口。所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。通常,网关提供Restful的访问API。服务端通过API-GateWay注册和管理服务。
-
-
架构特点不同:
-
SOA架构特点:
- 系统集成
- 系统的服务化
- 业务的服务化
-
微服务架构特点
- 通过服务实现组件化
- 按业务来划分服务
- 去中心化
- 基础设施自动化(devOps)
-
-
主要区别
功能 SOA 微服务 组件大小 大块业务逻辑 单独任务或小块业务逻辑 耦合 通常松耦合 总是松耦合 公司架构 任何类型 小型、专注于功能交叉团队 管理 着重中央管理 着重分散管理 目标 确保应用能够交互操作 执行新功能、快速拓展开发团队
服务拆分
服务拆分前提
-
首先要有一个持续集成的平台,使得服务在拆分的过程中,基于功能的一致性,并且持续的拆分,持续的演进,持续的集成,从而保证系统时刻处于可以验证交付的状态,而非闭门拆分一段时间。
-
在接入层,API和UI要动静分离,API由API网关统一的管理,这样后端无论如何拆分,对于前端来讲,可以保证统一的入口,而且可以实现拆分过程中的灰度发布,路由分发,流量切分,从而保证拆分的平滑进行。而且拆分后的微服务之间,为了高性能,要避免每次调用都进行认证鉴权的,应该在API网关上做统一的认证鉴权,一旦进入网关内,服务之间的调用就是可信的。
-
对于数据库,需要进行良好的设计,不应该有大量的联合查询,而是将数据库当成一个简单的key-value查询,复杂的联合查询通过应用层,或者通过Elasticsearch进行。
-
要做应用的无状态化,只有无状态的应用,才能横向扩展,这样拆分才有意义。
服务拆分的维度与策略
- AKF扩展立方体模型
-
x轴:代表无差别的克隆服务和数据,工作可以很均匀的分散在不同的服务实例上。
-
y轴:关注应用中职责的划分。
-
z轴:关注服务和数据的优先级划分。
理论上按照这三个扩展维度,可以将一个单体系统进行无限扩展。
-
业务与数据
服务拆分存在两大维度,即业务与数据。
-
业务体现在各种功能代码中,通过确定业务的边界,并使用领域与界限上下文、领域事件等技术手段可以实现拆分。
-
数据的拆分则体现在如何将集中式的中心化数据转变为各个微服务各自拥有的独立数据。
-
服务拆分的方法论
-
如何拆“功能”
- 单一职责,松耦合、高内聚
- 关注点分离
- 按职责
- 按通用性
- 按粒度级别
-
业务和数据的关系
- 先考虑业务功能,再考虑数据
- 无状态服务
微服务实现的支撑
一个微服务架构应用的实现,至少需要以下功能的支撑:
- 云端服务发现(用于定位服务,以实现云端中间层服务发现和故障转。)
- 统一配置中心(配置管理工具包,集中化管理集群配置)
- 消息总线(用于在集群中传播状态变化)
- 各服务之间的通信方式(中立的接口和协议)
- 容错管理工具(通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力)
- API网关(在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架)
- 分布式链路追踪(各链路状态信息收集)
- 日志收集工具(分布式日志收集)
基于SpringCloud的微服务实现
SpringCloud简介
Spring Cloud是一系列框架的有序集合。利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发(如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁,领导选举,分布式会话,集群状态)。
SpringCloud对微服务实现的支撑
-
云端服务发现 -->
Eureka
-
服务发现是基于微服务架构的关键原则之一。Eureka 采用了C-S的设计架构。Eureka Server作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server,并维持心跳连接。
-
Eureka由两个组件组成:Eureka服务器和Eureka客户端。Eureka服务器用作服务注册服务器。Eureka客户端是一个JAVA客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。
-
-
统一配置中心 -->
Spring Cloud Config
- Spring Cloud Config用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端与客户端两个部分。其中服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置仓库并为客户端提供获取配置信息、加密/解密信息等访问接口;而客户端则是微服务架构中的各个微服务应用或基础设施,它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。Spring Cloud Config实现了对服务端和客户端中环境变量和属性配置的抽象映射。
-
消息总线 -->
Spring Cloud Bus
- Spring Cloud Bus将分布式系统的节点与轻量级消息代理链接。这可以用于广播状态更改(例如配置更改)或其他管理指令。Bus就像一个扩展的Spring Boot应用程序的分布式执行器,也可以用作应用程序之间的通信渠道。
-
各服务之间的通信方式 -->
Feign
(RestFul)- Feign是一个声明式WebService客户端。Spring Cloud集成Ribbon和Eureka以在使用Feign时提供负载平衡的HTTP客户端。
-
容错管理工具 -->
Hystrix
- 在分布式环境中,许多服务依赖项中的一些必然会失败。Hystrix是一个库,通过添加延迟容忍和容错逻辑,控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、停止级联失败和提供回退选项来实现,以提高系统的整体弹性。
-
API网关 -->
Zuul
- Zuul相当于是第三方调用(app应用端和PC端)和服务提供方之间的防护门。作为边缘服务,Zull的作用是对后端服务做必要的聚合和裁剪后暴露给外部不同的设备,旨在实现动态路由,监控,弹性负载和安全性。
-
分布式链路追踪 -->
Spring Cloud Sleuth
- Spring Cloud Sleuth为SpringCloud应用实现了一种分布式追踪解决方案,可以跟踪一个用户请求的过程(包括数据采集,数据传输,数据存储,数据分析,数据可视化),捕获这些跟踪数据,就能构建微服务的整个调用链的视图,这是调试和监控微服务的关键工具。并兼容了Zipkin, HTrace和log-based追踪。
-
日志收集工具 -->
Graylog
(非Spring Cloud)- Graylog是强大的日志管理、分析工具,可以收集监控多种不同应用的日志。它基于 Elasticsearch, Java和MongoDB。可用于在分布式系统应用中,收集各节点日志整理并分析。
本文首发于我的个人博客左羽(一杯茶)