分布式微服务可以理解为,在同一网络下的多个组件通过网络通信协调,对外形成一个系统。
既然说分布式微服务是由多个组件,通过网络相互通信协调组成。那么他们是如何知道对方的ip并相互调用呢?
这里nacos为我们提供了一些帮助。我们在配置好nacos后,nacos会为我们提供服务发现功能,即获取注册在nacos上的各个服务的ip。我们知道这些ip后,就可以通过http,dubbo,grpc等自己设定好的方式去通信啦。我们讲这个功能称之为服务发现。
用一张图解释nacos服务发现的原理
只要配置好并启动nacos中间件后,我们在启动不同服务后,各个服务会将自己的ip注册到nacos的注册表中。别的服务,就可以通过这张注册表,去拉取对应服务的ip,从而实现服务发现。
既然已经发现了服务,那怎么去调用呢?
往往我们只需要在接口类上添加一个@FeignClient注解,在启动类上添加@EnableFeignClients即可实现服务调用
openfeign的底层其实是通过spring-aop+jdk动态代理来实现的。
简单来说就是将在加了@FeignClient注解的类,对应生成一个Proxy代理类,在外部调用这个接口时,会通过反射获取到接口的请求方法(get,post...),接口参数,返回值类型,请求地址等。
当然,nacos不仅仅这些功能。
他还为咱们提供了,负载均衡,配置管理
负载均衡指:部署多个相同服务后,请求到底进入那个服务。因为在高并发的情况下,部署一台服务肯定是不理智的,一旦它崩了,这个服务就崩了,同时也会牵连到其他需要调用这个服务的服务。所以这里引入了负载均衡,以对高并发情况下,减轻每一台服务的压力。同行情况下,必将常用的策略有(随机,轮询,响应时间加权,最小并发数)
配置管理指:我们可以把项目配置的yaml交给nacos来管理,一些重复的配置,不需要繁琐的重复操作,只需要针对不同服务配置其特有的配置即可。
当我们开始写分布式项目的业务逻辑时就会发现,既然微服务是通过网络来通信协调,那就不可避免地会遇到网络波动等问题,因为网络是不可靠的!那么一旦遇到这样的情况,在复杂业务执行时,一旦某一个环节出现差错,后续业务就无法继续执行。但微服务是吧一个完整的项目拆分成多个不同的子服务。每个服务之间互相调用,相互协调。这时候,我们单体项目的回滚就起不到作用了。因为你只能在自己的业务里回滚。
此时seata为我们提供了AT解决模式
分布式事务基本概念
全局事务:逻辑概念,指复杂业务这个整体
分支事务:单个服务内部的业务
事务协调者:TC协调每个分支事务的中间件,统一提交,统一回滚
事务发起者:TM发起全局事务的方法
事务参与者:RM参全局事务,维护分支事务
什么是AT模式?他有什么优势和劣势?
不需要像TCC模式针对业务定制接口,不像XA协议消耗大量资源
缺点就是每个数据库都需要建一张undo_log表
此模式分为两个阶段
阶段一:
1、执行业务
2、获取并持久化回滚数据
1).seata代理数据源,拦截所有数据库操作(sql)
2).获取数据操作前后的数据镜像,生成inster插入到undo_log表中
3).加入到当前事务,提交
阶段二:
1、正常提交:删除undo_log表中的记录
2、异常提交:
1).seata自动从各个分支事务对应的undo_log表中提取记录,计算生成回滚所需要的sql。
2).执行回滚sql,提交事务
用一张图简单描述:
此时我们引入服务网关的概念
什么是服务网关:服务网关就是整个分布式微服务系统的唯一入口。举个例子,就像古代的每个城池,都有一个供城内外百姓进出的关口,这个关口会有重兵把守,可不是什么人都能放你进来。
服务网关亦是如此,它可以拦截请求,设置黑白名单,同时可以对请求做处理,以及路由转发,也可以对系统性能做检测等等功能。
这里我们使用spring-cloud-gateway
需要特别注意的是:cloud-gateway是基于Reactive技术栈,底层是Netty,这里不允许有starter-web的依赖,不然会报错。
gateway底层由一个个过滤器组成。主要分成两种网关过滤器和全局过滤器
1.网关过滤器 GatewayFilter 针对某个route做请求的修改处理
2.全局过滤器 GlobalFilter 针对所有的route,提供一些功能,全局过滤器是有顺序的!
经典场景:服务雪崩
单个实例故障时,处理请求延时或者没有相应,会导致上层调用它的服务也变慢,从而引起请求堆积负载拉高,产生蝴蝶效应。
我们这里使用sentinel
我们可以在sentinel客户端这对不同接口,设定不同的容错规则
例如:限流,排队等待,熔断器,fallback(备胎模式)来实现服务出错时,依然不影响整个分布式系统。
详情请参看 Home · alibaba/Sentinel Wiki · GitHub
在分布式系统中,每个服务独立,在不同的域名登录后,不可能让用户重复登录,这样大大低了用户的体验。
这里我们主要介绍第三种sa-token模式
实现原理是:
通过新增cookie,将cookie的域名设置为父级域名,后续的每一个请求都会携带这个cookie,不同的页面系统拿到cookie后,回去redis中解析token,如果成功,则认为已登录。