一,分布式|微服务
什么是分布式系统?
分布式系统是部署在同一网络下的多个通过网络来通信和协调的组件,对外而言,就如同一个系统。
有两种形式,一就是微服务架构,二就是集群。
就如图中所示,每一个板块就是一个小型服务,而各个服务只负责管理属于自己的数据库,而每个服务中,如service,controller,infra等也是互相分离的,模块化,最终由一个服务来进行http(okhttp,restTemplate等方法)的调度。
spring -cloud(微服务架构工具集)
简单讲,就是为开发者提供了许多用于搭建微服务所需要的各种常见的模式的实现工具。
各种常见的模式的实现工具:
- 服务发现
- 服务网关
- 负载均衡
- 服务容错
- 服务调用
- ……
二,服务发现
服务间需要通信,而在进行服务调用时,需要另一个服务的ip及端口等信息,这时就需要用到服务发现的组件。
如何进行服务发现?
所谓服务发现,就是找到服务实例的地址的过程。
流程:①A服务调用B服务时,B服务需要把自己的相关信息,注册到服务注册表。
②注册表就有B服务相关的数据,这时A服务就会向注册表拉取信息。
③而这期间,注册表会时不时的对注册的服务进行健康检测。
④如果发生异常会变更,则注册表会通知调用方
⑤调用方则会重新拉去信息。
三,负载均衡
通过不同的策略,将请求流量均衡的发送给服务提供方。(本篇选用netflix-ribbon作为负载均衡服务)
而相关的策略有:
①BestAvailableRule(最小并发数):选择一个最小的并发请求的服务
②WeightedResponseTimeRule(响应时间加权):响应时间越短,被分配的可能性越高
③RoundRobinRule(轮询):按顺序,平均
④RandomRule(随机):随机选
四,服务调用
服务调用,就是服务A调用服务B的接口,这时需要用到声明式服务调用组件(spring-cloud-openfeign),接口上需要@FeignClient注解
openfeign,相当于走完了三个模式(服务发现,负载均衡,服务调用)
实现原理:
①通过AOP,创建代理类(JDK动态代理,接口)
②通过反射,获取client接口上的注解,进一步获取到请求相关信息:请求方式、服务名、参数名、参数类型、返回值类型,再根据请求信息生成服务调用代码
五,服务划分
1.服务分层:①分布式微服务中各个服务中只能从上往下调,不能反向;如果实在需要,使用mq异步通信。②同层可以互相调。
2.分层:①聚合层:面对用户,每个用户端,提供一个服务。
②原子层:单纯的负责某一个特定的领域。
六,配置管理(nacos)
配置管理和服务发现的流程大同小异。
①服务创建时新建配置。
②服务启动时拉去配置。
③对配置在nacos上的配置进行时不时的变动检测。
④发生变动时,对目标服务进行变动通知。
⑤服务再重新拉取配置。
统一进行配置管理的需求:
①进行审计管理
②时时动态刷新
③也可以配置部分需要共享的配置
七,分布式事务
数据一致性问题:分布式事务
微服务架构下,一个业务操作必须经过多个服务,每个服务有自己独立的数据库,造成一个业务操作必然在多个数据库实例中执行,必须达到多个数据库实例同时成功或者失败的效果,才能实现这个业务操作,必须对数据库进行协调。
基本概念
1.全局事务:分布式事务本身,由参与的所有分支事务组成
2.分支事务:单个服务内部的事务
3.事务协调者:TC Transaction Coodinator 协调各个分支事务,同时提交,同时回滚
4.事务发起者:TM Transaction Manager 事务管理者 发起全局事务
5.事务参与者:RM Resource Manager 资源管理者 参与全局事务,维护分支事务
基于数据库一致性的分布式事务常见解决方案
1.XA协议
数据库层面解决,多个数据库,同步打开事务,不提交,等待TC协调,等所有事务确认提交之后,再提交。
弊处:数据库事务是非常耗性能的,通信数据本身时间较长,加上资源锁定时间长
2.TCC(Try-Confirm-Cancel)
Try:尝试阶段,锁定资源
Confirm:确认阶段,执行业务
Cancel:取消阶段,释放所有资源
TCC的实现,需要写三个接口,分别是冻结执行的逻辑(Try),另一个是执行正常的逻辑(Confirm),最后一个是发生错误执行的回滚逻辑(Cancel)。
弊处:所有业务都需要重新设计和重写
3.SAGAS
适用于长事务
事务执行的过程中,每一个事务参与者都提交本地事务,当执行的过程中,出现错误,则依次向后回滚数据。
4.AT模式
是由seata提供的
①正常执行业务,获取并持久化回滚数据,seata代理数据源,拦截所有的sql操作
②再获取到sql执行前后的数据镜像,生成插入(insert)的sql,到undo_log表,再加入到当前事务,最后提交
③如果正常提交,就删除undo_log的记录
④如果发生异常,则seata提取对应的undo_log表中的记录,计算出回滚的sql,再提交事务
弊处:需要在每一个数据库中建一个undo_log表。
5.重试和幂等性校验
①幂等性校验,区分请求是否是重复请求,一般通过外部的ID区分
②如果重试不能成功,需要告警,人工介入进行操作
八,服务网关
Service Gateway是整个分布式系统的唯一入口。
职责:提供一些通用的公共功能,如:ip黑名单(封禁ip),ip白名单(允许哪些ip通过),认证、授权(进行权限控制),动态路由(根据请求路径,转发给相应的服务),日志的记录,性能统计,协议转换,限流等。
路由转发:
1.predicate(匹配请求路径):①Path②Header③Query……
2.filter(处理操作)
3.uri(转发的目标服务)
两种过滤器:
1.GatewayFilter(网关过滤器)应用到某一个Route路由
2.GlobalFilter(全局过滤器)应用于所有,有顺序的(Ordered)
网关认证:
JWT由三部分组成(header,payload,signature)
加密:header和payload进行base64编码,加上私钥,进行HMAC算法的单向加密,得到私钥
验证:将传入的header和payload加上私钥,再次用hmac算法加密,得出签名串,与传入的signature比较,是否一致
JWT能防伪造,因为是单向加密,其中私钥是不公开的。
九,单点登录
同一个网站的多个不同的页面系统,只需要登陆一次,就可以访问任何其他的系统。
常用的实现方式:
①cas协议
②oauth2协议
③基于redis共享和cookie的方式 sa-token
十,服务容错(使用sentinel)
典型场景:服务雪崩
单个实例故障时,处理请求缓慢或者没有响应,导致上层调用它的服务实例也变慢,请求堆积,负载拉高。进一步导致更广泛的服务实例故障。最后整个分布式系统大面积出现服务实例故障,形同异常雪崩,突然全线崩溃。这种由单个服务实例引发的级联故障称为服务雪崩。
常见服务容错模式
1.调用方超时, 限制资源的占用,给资源(线程、cpu时间)的占用设置上限
2.提供方限流,控制进入系统的流量,不超过本机最大处理能力
3.仓壁模式(调用方/提供方),利用线程池或者信号量等其他手段进行资源隔离,确保不会产生级联故障
4.调用方利用断路器或熔断器,自动隔离故障实例,自动恢复。