失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 微服务架构学习笔记

微服务架构学习笔记

时间:2021-07-21 06:45:05

相关推荐

微服务架构学习笔记

什么是微服务

一个或者一组相对较小且独立的功能单元,用户可以感知最小功能集。

微服务架构

一组小的服务独立的进程 :以进程的方式横向扩展轻量级通信 :使用轻量级协议基于业务能力 :基于不同的服务构建独立部署 : 团队之间不需要协调无集中式管理 :没有统一的架构团队,可以采用不同的技术栈

微服务特点

服务间松散耦合

服务面向架构

有界数据源:每个微服务有不同的数据源

微服务本质

微服务本质是系统提供一套基础的架构,这种架构使得微服务可以独立的部署、运行、升级,不仅如此,这个系统架构还让微服务与微服务之间在结构上“松耦合”,而在功能上则表现为一个统一的整体。这种所谓的“统一的整体”表现出来的是统一风格的界面,统一的权限管理,统一的安全策略,统一的上线过程,统一的日志和审计方法,统一的调度方式,统一的访问入口等等。

微服务的目的是有效的拆分应用,实现敏捷开发和部署 。

微服务提倡的理念团队间应该是 inter-operate, not integrate 。inter-operate是定义好系统的边界和接口,在一个团队内全栈,让团队自治,原因就是因为如果团队按照这样的方式组建,将沟通的成本维持在系统内部,每个子系统就会更加内聚,彼此的依赖耦合能变弱,跨系统的沟通成本也就能降低。

微服务的利弊

利:

强模块化边界 :以服务的方式做模块化可独立部署 : 不需要其他团队来协助技术多样性 : 可以使用不同的技术栈

弊:

分布式复杂性:整体来说,系统会变得复杂,难以理解整个系统的架构。

最终一致性: 数据源不同,数据的变更导致数据可能不一致。

运维复杂性 : 需要很多服务协同工作,对系统的可靠性有很大挑战。

测试复杂性 : 需要很多团队联合测试。

微服务的由来

在早期的IT行业软件大多都是各种独立系统的堆砌(单体架构),这些系统扩展性差,可靠性不高,维护成本高。在规模比较小的情况下工作情况良好,但是随着系统规模的扩大,出现了以下的问题:

复杂性逐渐变高:随着代码量的增多,项目的复杂性越来越高。

技术债务逐渐上升:有的员工在离职之前,疏于代码质量的自我管束,导致留下来很多坑,由于单体项目代码量庞大的惊人,留下的坑很难被发觉,这就给新来的员工带来很大的烦恼,人员流动越大所留下的坑越多,也就是所谓的技术债务越来越多。

部署速度逐渐变慢:单体架构模块非常多,代码量非常庞大,导致部署项目所花费的时间越来越多。

阻碍技术创新:由于各个模块之间有着千丝万缕的联系,代码量大,逻辑不够清楚,如果想用新技术来重构项目是非常困难的,付出的成本将非常大,所以更多的时候公司不得不硬着头皮继续使用老的struts架构,这就阻碍了技术的创新。

无法按需伸缩:所有的模块都在一个架构下,因此我们在扩展模块的性能时不得不考虑其它模块的因素,不能因为扩展某个模块的性能而损害其它模块的性能,从而无法按需进行伸缩。

微服务与单体架构区别

单体架构所有的模块全都耦合在一块,代码量大,维护困难,微服务每个模块就相当于一个单独的项目,代码量明显减少,遇到问题也相对来说比较好解决。

单体架构所有的模块都共用一个数据库,存储方式比较单一,微服务每个模块都可以使用不同的存储方式(比如有的用redis,有的用mysql等),数据库也是单个模块对应自己的数据库。

单体架构所有的模块开发所使用的技术一样,微服务每个模块都可以使用不同的开发技术,开发模式更灵活。

后来引入了SOA服务化,但是,由于 SOA 早期均使用了总线模式,这种总线模式是与某种技术栈强绑定的,导致很多企业的遗留系统很难对接,切换时间太长,成本太高,新系统稳定性的收敛也需要一些时间。

微服务与SOA(面向服务架构)区别

微服务,从本质意义上看,还是 SOA 架构。但内涵有所不同,微服务并不绑定某种特殊的技术,在一个微服务的系统中,可以有 Java 编写的服务,也可以有 Python编写的服务,他们是靠Restful架构风格统一成一个系统的。所以微服务本身与具体技术实现无关,扩展性强。

在什么时候引用微服务

在开发初期,单体架构的生产力更高;当开发规模逐步增大(开发人员超过百人)后,开始引用微服务,将服务一个一个拆分出来。

如果一开始就采用微服务:微服务前期的投入大于单体框架,前期对于业务的划分和见解还不够清晰,并且开发的成果还未受到市场的考验,风险会大很多。

微服务组织架构

一个微服务由一个跨职能团队全盘负责(包括产品、研发、测试、DBA、运维)。

不需要向传统的架构一样向每个团队交互沟通,减少了沟通成本,提高了开发效率。

微服务分层体系(逻辑上的划分)

基础服务(核心领域服务、公共服务、中间层服务):提供基础功能

聚合服务(适配服务、边界服务):适配不同设备;将多个基础服务聚合到一起,减少外部设备请求次数。

外部设备(pc、移动端等)

微服务技术架构体系

基础设施层 :计算、网络、存储、NOC监控、安全、IDC

平台服务层:发布系统、集群资源调度、资源治理、镜像治理、IAM

支撑服务层:注册发现、集中配置、容错限流、认证授权、日志聚合、监控警告、后台服务

业务服务层:基础层+聚合服务层

网关层:实现反向路由、限流熔断、安全等

接入层: 外部+内部LB

微服务的服务发现机制

传统LB:向运维申请一个域名以及LB,当用户访问域名时,会穿透LB,分配到合适的服务器。中间一跳会有性能损耗,如果LB挂掉了,整个服务都会挂掉。

进程内LB:服务器定期注册到服务注册表,用户通过带有LB的客户端,访问到合适的服务器。需要开发带有LB的客户端。

主机独立LB:将LB以独立进程的方式独立部署到每台主机(用户的主机)上,服务器定期注册到服务注册表,LB也会定期同步注册表信息。运维成本比较高,需要在用户主机上独立运行一个进程。

API网关(门卫)

在用户访问时,察觉不到微服务的存在。

网关层前一般会有负载均衡器,是为了部署无状态的网关,无状态的网关可以部署多台。

网关的作用:

反向路由:将外部请求转换为内部具体服务的调用

认证安全:外部请求安全验证

限流熔断:避免服务器过载。

日志监控:对流量进行日志分析。

开源网关Zuul:

运行流程:

HTTP请求 —— Zuul Servlet —— ZuulFilter Runner(管理过滤器:前置路由过滤器、路由过滤器、后置路由过滤器)—— 调用后台微服务 —— 以HTTP请求方式传回

前置路由过滤器:解析外部请求

路由过滤器:找到目标服务并且调用,经过后置路由过滤器回到客户端

后置路由过滤器:用来做日志、统计等。

所有过滤器都可以动态插拔。

通过Request Context可以实现过滤器信息共享。

过滤器上传加载机制:

将编译好的过滤器上传到过滤器存储数据库中,并且会定期向过滤器目录中增添新的过滤器,在过滤器目录中也会定期扫描,向网关load新的过滤器。

网关和服务发现机制的使用

服务注册中心将基础服务层、聚合服务层以及网关层联系起来。

集中式配置中心

为什么要用配置中心:

如果没有配置文件,要修改某些特殊变量(数据库密码、动态参数)时需要经历以下几个步骤:

0.从git pull那个代码(多人开发)

1.打开源代码

2.修改变量值

3.编译

4.测试

5.申请上线

6.上线

如果有配置文件,要修改某些特殊变量(数据库密码、动态参数)时需要经历以下几个步骤:

1.到服务器,把配置文件里的内容修改了

2.重启程序(重启后程序加载的是新的配置)

如果你的程序不止在启动时读取一次配置文件,而是每5秒读取一次看有没有变得,有变得则更新变量的值,那就只需要修改文件内容。

而一般操作服务器也是危险的,麻烦的

所以配置中心大多数时候是一个数据库,并在此基础上开发了好用的功能,比如历史回退等等。

早期人们将配置放在配置文件中,这样会导致:

配置不标准、不统一修改慢,影响业务没有审计功能,无法追溯配置修改信息

配置中心存放的配置包括:

数据库、缓存、消息队列的连接字符串动态参数业务开关

等等

配置中心与服务的交互

pull式:服务主动从配置中心拉取配置 (不是实时获取,但是保证更新到配置)

push:配置中心把配置push给服务(实时推送,但是网络问题会影响更新,导致更新不一定能送达)

Apollo配置中心

既推送、又定时拉取,保证更新的配置可以同步到客户端

同时将获取到的配置缓存到本地,即使配置中心无法连接也能确保高可用性。

微服务通讯方式RPC和REST

RPC的消息协议相比于REST会更加紧凑,性能更高,但对外一般需要转换成REST/文本协议。

GRPC支持HTTP2通讯协议

nacos:服务治理+配置中心

微服务的治理环节

服务治理就是治理各个服务的手段

服务注册发现:消费者发现生产者服务的负载均衡/路由日志监控metrics监控调用链监控限流熔断安全和访问控制REST/RPC序列化 XML/JSON/二进制代码生成(自动生成客户端和服务器端)统一异常处理文档配置集成后台服务集成

微服务框架实现上述治理环节,开发者只需要专注于业务逻辑即可。

注册发现

什么是注册发现:

注册发现指的是生产者注册到注册中心,消费者从注册中心发现服务(上面有三种服务发现机制)。

为什么要用注册发现:

如果不适用注册发现,想要调用微服务,需要依赖于微服务的IP(定位机器)以及端口(定位进程/服务),这样的话,微服务的更新调整会很麻烦,所以,使用注册发现,把对ip和端口的依赖转化为对服务注册中心的依赖。

怎么实现:

微服务会把自己的地址等信息报给服务注册中心,服务去注册中心上报自己的地址就叫服务注册。迁移以后,微服务会上报新的地址覆盖之前的旧地址,调用方要调用服务前,需要通过服务名到注册中心去找服务的地址,这个过程就叫服务发现。

服务负载均衡

一般一个服务会部署多台机器,一来分摊压力,负载均衡。二来保证不至于一台机器挂了服务就不能用,保持高可用性。

网关负责直接调用一个服务,这个服务也可能会再调用其他服务,服务可以不断上报自己的压力,服务发现的时候就挑压力小的地址下发。

健康检测

一个服务部署多台机器,如果有的机器挂掉了,就不能定期向注册中心上报自己是健康的,注册中心就认为它挂了,当请求方要请求时,就注册中心就不会给这些挂掉机器的地址,保证服务可用。

服务扩容

将服务部署到新增的机器上,服务会自己向注册中心注册(同一个服务在多台设备上可以多次注册到服务中心,服务=服务函数+运行设备)

微服务监控系统分层和监控架构

为什么需要监控体系

处理分散在各个服务器上的日志当业务流程出现问题,快速的定位问题发生位置跟踪业务流的处理顺序和处理结果实现事故的预警分析系统的性能瓶颈

微服务下监控体系的难点

单体应用环境下,所有的业务都在同一个服务器上,如果出现错误和异常,只需要聚焦于服务器这一点,往往就可以快速定位和解决问题。

微服务架构下,大部分功能模块都是单独部署、独立运行的,彼此通过接口交互,都是无状态的服务,业务流会涉及多个服务,复杂度会高很多。

监控系统的分层及相关信息

从底到上分为:

基础设施监控(网络、交换机):

监控网络流量、丢包、错包、连接数等

系统层监控(物理机、虚拟机、OS):

监控cpu、memory、network、disk等

应用层监控:

url、service、sql、cache可用率、相应时间、qps等

业务层监控:

核心指标监控、登录注册、下单、支付等

端用户体验监控:

性能、返回码、城市、地区、运营商、版本、系统等

监控的五个方面:

日志监控、metrics监控、健康检查、调用链监控、告警系统

监控架构

在微服务上启用agent搜集日志;通过Kafka消息队列缓冲日志、解耦消息发送,给ELK和InfluxDB+Grafana;

ELK(Elasticsearch + Kibana + Logstash) 查看日志

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。

Kibana是一个开源的分析与可视化平台,设计出来用于和Elasticsearch一起使用的。你可以用kibana搜索、查看、交互。

Logstash 是开源的服务器端数据处理管道,能够同时从多个来源采集数据、转换数据,然后将数据发送到您最喜欢的 “存储库” 中。

Elasticsearch索引里的数据,使用各种不同的图表、表格、地图等kibana能够很轻易地展示高级数据分析与可视化。

InfluxDB+Grafana 存放日志的数据库

InfluxDB:是一个开源的没有外部依赖的时间序列数据库。适用于记录度量,事件及执行分析。

Grafana:是用于可视化大型测量数据的开源程序,他提供了强大和优雅的方式去创建、共享、浏览数据。dashboard中显示了你不同metric数据源中的数据。一般与时序数据库(InfluxDB)结合使用。

Sensu 健康检查

健康检查端点,检查微服务健康情况。

调用链监控

调用链监控的作用

项目网络拓扑图:

我们可以根据「调用链监控」中记录的链路信息,给项目生成一张网络调用的拓扑图。

通过这张图,就可以知道系统中的各个服务之间的调用关系是怎样的,以及系统依赖了哪些服务。并且还可以起到监控全局服务的作用,便于架构师掌握系统的状态。

快速定位问题:

微服务架构下,问题定位就变得非常复杂了,一个请求可能会经过多个服务节点,那么有这么一套调用链监控系统就能让开发人员快速的定位到问题和相应模块。

优化系统:

优化系统也是「调用链监控」很重要的一个功能。

因为我们记录了请求在调用链上每一个环节的信息,就可以通过这个来找出系统的瓶颈,做出针对性的优化。

还可以分析这个调用路径是否合理,是否调用了不必要的服务节点,是否有更近、响应更快的服务节点。通过对调用链路的分析,我们就可以找出最优质的调用路径,从而提高系统的性能。

提高团队成员自律:

上面都是系统层面的作用。但如果有了「调用链监控」之后,对团队开发人员的帮助也是非常大的。因为团队所有成员都可以通过这个调用链监控系统看到系统各个模块的状态,开发同学慢慢的会对自己负责的模块有更多的责任感,也会很自觉的去优化自己的模块。这种习惯的养成,对研发团队而言,非常的重要。

调用链监控的原理

Span:

Span是指一个模块的调用过程,一般用span id来标识。在一次请求的过程中会调用不同的节点/模块/服务,每一次调用都会生成一个新的span id来记录。这样,就可以通过span id来定位当前请求在整个系统调用链中所处的位置,以及它的上下游节点分别是什么。

span携带span_id、Trace_id和parent信息

一次请求只有一个唯一的trace id=12345,在请求过程中的任何环节都不会改变。

在这个请求的调用链中,SpanA调用了SpanB,然后SpanB又调用了SpanC和SpanD,每一次Span调用都会生成一个自己的span id,并且还会记录自己的上级span id是谁。

通过这些id,整个链路基本上就都能标识出来了。

主流的调用链监控

CAT是由大众点评开源的一款调用链监控系统,基于JAVA开发的。

它有一个非常强大和丰富的可视化报表界面,这一点其实对于一款调用链监控系统而来非常的重要。在CAT提供的报表界面中有非常多的功能,几乎能看到你想要的任何维度的报表数据。

CAT有个很大的优势就是处理的实时性,CAT里大部分系统是分钟级统计。

微服务的容错限流

容错机制

当服务者无法正常为消费者提供服务时 ,如请求超时、后台服务无响应、后台服务异常等, 通过容错机制直接返回统一处理结果,并对下次请求进行同样处理,直到后台服务功能正常。

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。缓存、隔离、降级熔断和限流是保护微服务系统运行稳定性的利器。

缓存:缓存的目的是提升系统访问速度和增大系统能处理的容量。

隔离:防止一个请求的异常影响到其他请求

线程池隔离模式

使用一个线程池来存储当前的请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求堆积入线程池队列。这种方式需要为每个依赖的服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)。

信号量隔离模式

使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃该类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)。

降级当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。

熔断:熔断机制是应对雪崩效应的一种微服务链路保护机制。

在各种场景下都会接触到熔断这两个字。高压电路中,如果某个地方的电压过高,熔断器就会熔断,对电路进行保护。

股票交易中,如果股票指数过高,也会采用熔断机制,暂停股票的交易。

同样,在微服务架构中,熔断机制也是起着类似的作用。当链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后,恢复调用链路。

限流:防止爆发式流量直接压倒后台服务实例,造成资源耗尽、甚至应用崩溃。

控制访问流量,通过指定的策略消减流量(如网络层面限制访问流量、后服务实例使用技术手段限制并发数量等),使得落到后台服务实例的请求在能承受的范围内。

docker容器部署技术与持续交付流水线

容器技术区别于传统交付技术的优势:

解决环境一致性镜像部署:天然的抽象机制,不需要再根据不同的环境适配不同的依赖包(java、python等等都用一种依赖包)

基于docker的持续交付流水线

将整个交付流程规范化,保证微服务的质量,提高研发效率。

蓝绿部署、滚动部署和灰度发布

蓝绿部署

蓝绿部署是一种可以保证系统在不间断提供服务的情况下上线的部署方式。

蓝绿部署的模型中包含两个集群,就好比海豚的左脑和右脑。

在没有上线的正常情况下,集群A和集群B的代码版本是一致的,并且同时对外提供服务。

在系统升级的时候下,我们首先把一个集群(比如集群A)从负载列表中摘除,进行新版本的部署。集群B仍然继续提供服务。

当集群A升级完毕,我们把负载均衡重新指向集群A,再把集群B从负载列表中摘除,进行新版本的部署。集群A重新提供服务。

最后,当集群B也升级完成,我们把集群B也恢复到负载列表当中。这个时候,两个集群的版本都已经升级,并且对外的服务几乎没有间断过。

滚动部署

滚动部署,同样是一种可以保证系统在不间断提供服务的情况下上线的部署方式。

和蓝绿部署不同的是,滚动部署对外提供服务的版本并不是非此即彼,而是在更细的粒度下平滑完成版本的升级。

滚动部署只需要一个集群,集群下的不同节点可以独立进行版本升级。

比如在一个16节点的集群中,我们选择每次升级4个节点,以此类推逐步完成更新。

灰度发布

灰度部署是指先更新一小部分服务器比如2%,然后对应用进行测试验证。

如果验证通过,则继续更新剩余部分的服务器,否则进行回滚。

灰度部署的好处就是影响面小,且足够灵活。出现问题时只会影响很小一部分用户,适合对新功能信心不足或是对服务可用性要求比较高的场景。

容器集群调度和基于容器的发布体系

容器集群调度

将多台计算机抽象成一个大计算机,有足够多的内存和cpu资源,集中管理所有机器

framework调度所有机器(资源的分配使用,类似BOSS)

MasterLeader 管理下面的虚拟机(只管理资源调度,类似工头),同时是高可用的,一个MasterLeader挂掉后,会有新的MasterLeader接管它的任务。

slave(苦力)会定期返回机器资源使用情况给MasterLeader,MasterLeader继续返回给framework

基于容器的发布体系

发布流程

发布平台向资产治理中心查询配额发布平台向镜像治理中心查询应用镜像启动实例微服务框架从镜像治理中心拉取镜像微服务向服务注册中心注册服务发布平台可以直接对服务注册中心调拨流量网关从服务注册中心发现服务外部流量通过网关访问到微服务

如果觉得《微服务架构学习笔记》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。