spring cloud alibaba不错的文章:https://blog.csdn.net/weixin_48922154/article/details/121228614
spring cloud不错的文章:https://blog.csdn.net/rfidgroup/article/details/89519577
Ribbon原理:
最核心的是 LoadBalancerlnterceptor.intercept 这个拦截器
拦截请求的url进行解析。
请求注册中心,例如:nacos,根据服务名称,会将ip、端口、等信息拿到本地来(注册表),然后去本地查询对应的服务信息,再去调用对应的服务,(ribbon调用服务 默认是轮询调用)

openFeign原理:
Feign的一个关键机制就是使用了动态代理。Feign会 针对定义了@FeignClient注解的接口创建一个动态代理,接着会根据接口上的@RequestMapping等注解,来动态构造出你要请求的服务的地址
最后针对这个地址,跟你指定的服务建立连接,构造请求,发起请求、获取响应、解析响应。

当调用某个接口的时候,底层代理对象会将@FeignClient(value =”stock-service”) 的value值和接口的@RequestMapping(“/stock/deduct/{productId}/{stockCount}”)值动态构造一个可以直接访问的url地址 :http://stock-service/stock/deduct/{productId}/{stockCount} image.png

底层借住ribbon实现服务发现,实现负载均衡去远端调用。
image.png
注意Feign的坑,就是在接口里面配置访问方法的是get时,不能使用 @GetMapping(“/simple/{id}”),而必须使用 @RequestMapping(value = “/simple/{id}”,method = RequestMethod.GET )
用@FeignClient的方法里的参数要用@RequestParam(“id”)

服务限流sentinel
降级后可以将这次信息记录到日志或者数据库单独一个表,通过定时任务去处理这个降级问题
image.png
sentinel会拦截或者过滤所有的请求,会获取到所有的http请求,对这个这些请求进行处理,放行或者流控
image.png
Sentinel 对于所有请求的拦截,主要得益于 SpringBoot 的 SentinelWebAutoConfiguration 的自动配置:

  1. public class SentinelWebAutoConfiguration implements WebMvcConfigurer {
  2. // 省略一些代码
  3. @Override
  4. public void addInterceptors(InterceptorRegistry registry) {
  5. if (!sentinelWebInterceptorOptional.isPresent()) {
  6. return;
  7. }
  8. SentinelProperties.Filter filterConfig = properties.getFilter();
  9. registry.addInterceptor(sentinelWebInterceptorOptional.get())
  10. .order(filterConfig.getOrder())
  11. .addPathPatterns(filterConfig.getUrlPatterns());
  12. log.info(
  13. "[Sentinel Starter] register SentinelWebInterceptor with urlPatterns: {}.",
  14. filterConfig.getUrlPatterns());
  15. }
  16. // 省略一些代码
  17. }

很容易看出,该配置为容器加入了一个拦截器,并且通过 /** 对所有请求进行拦截。然后使用 URLClean(如果有的话)进行路径的清洗,也就是路径资源的归类。然后对资源添加限流埋点,对流量进行统计。
通过这样的方式,整个系统的资源也就都变成了 Sentinel 的资源。

  1. private List<String> urlPatterns = Arrays.asList("/**");

限流总结
首先,Sentinel 整合 SpringBoot 的话,会为容器导入一个 SentinelWebAutoConfigration, 该配置类为容器增加了一个拦截器,会对所有资源进行拦截,进而转化为 Sentinel 的资源。
之后的请求就会进入 SphU.entry() 方法,该方法会对是否限流进行判断,不需要限流则会返回一个 Entry ,类似于通行的凭证。需要限流则会根据具体的策略执行。
该方法又会进入 CtSph 的 entryWithPriority 方法,该方法会得到一条单例的处理槽链,这是 Sentinel 的核心,再通过这条链条进行限流的具体处理。
限流相关的槽是 Statistic Slot 统计数据指标的槽以及 Flow Slot 进行流量控制的槽。
Statistic Slot:使用的是滑动窗口的统计算法,划分一个大窗口,内部又分割了很多小窗口,每次会获取对应的小窗口,再使用窗口包装的 MetricBucket 中的 LongAddr 数组对对应的统计指标进行累加。
Flow Slot:限流控制的槽,主要用于获取限流的策略,再对流量进行比对处理。

Nacos服务
Nacos服务注册表结构:Map>
通过namespace来区分是开发环境dev还是测试环境test还是生产环境product,通过两个嵌套的map来实现的,外map的key存放环境名称,内map的key是对应的服务名称(分组了)
image.png
nacos中服务启动停止的执行流程
image.png
nacos是基于spring boot写的一个web项目,其实就是通过暴露一些接口,供其他服务通过http的方式去调用。
nacos的服务与注册
对于服务的注册,主要包含两块的内容,本地 Nacos 客户端的操作,以及远程 Nacos 服务器的操作:
本地 Nacos 的客户端会将服务注册的信息封装为一个实例,检查如果需要心跳检测,则会启动一个定时任务,定时向服务端发送心跳检测包。之后,会使用 namingService 对远端 Nacos 服务器发送请求进行服务的注册。
远端服务器中的 InstanceController 会接收到该请求,使用 ServiceManager 进行服务的注册,对服务以及对应的实例进行初始化和添加,对应存储的数据结构是,所有的服务存放在一个 ConcurrentHashMap 里,一个服务的所有实例也存放在一个 ConcurrentHashMap。

我的理解:nocos客户端会将服务注册的信息封装为一个实例,检查如果需要心跳检测就会启动一个定时任务,定时向服务端发送心跳检测包,然后使用open api的形式向nacos服务器发送请求进行服务注册,服务器接收到该请求后对服务以及对应的实例进行初始化和添加,所有的服务存放在一个 ConcurrentHashMap 里
地址发现
对于地址的发现还是在 InstanceController 中的 list() 方法,该方法可以获得对应服务的全部地址信息,再通过相关的负载均衡的策略等,进行服务的调用
动态感知
Nacos 客户端会通过 subscribe() 方法,对Nacos 远端服务进行监听,NamingService 中组合了一个 HostReactor 类,该类初始化的时候,会开启一定定时任务的线程,每十秒钟向服务端 pull 一次最新的地址数据。并且服务端在检测到对应服务下线或者更新之后,也会主动推送消息给 Nacos 客户端,双方采用的是 UDP 协议。
心跳机制就是客户端通过schedule定时向服务端发送一个数据包(5秒) ,然后启动一个线程不断检测服务端的回应,如果在设定时间内没有收到服务端的回应,则认为服务器出现了故障。Nacos服务端会根据客户端的心跳包不断更新服务的状态。
nacos的配置持久化实现原理
Nacos 的客户端向服务器发送一次检查配置更新的请求,服务器端检查配置是否一致,如果不一致会直接返回更新的信息,如果一致,则会将请求保存住,添加到服务器端的 allSubs 队列中,设置一个定时 29.5 s 的定时任务,进行延时操作(该时间可能会由具体情况发生变动)。
如果在这 29.5s 内发生了配置的更新,服务器端则会触发对应时间,遍历 allSubs 队列,找到感兴趣的客户端,将配置信息的更新操作写入到响应中并返回。类似于完成了一次 PUSH 操作,但是不需要建立一个服务器端到客户端的 HTTP 连接。
如果在此时间内没有发生改变,则会进入自动检测机制,直接返回响应给客户端。

之后,在上下文准备完成之后继续进行应用的启动,应用准备完毕之后会触发一个应用准备完毕的事件,Nacos 的监听器会监听该事件,并注册一个监听器,对配置信息进行监听,从而实现配置文件的刷新,同样,该客户端和服务器之间的通信,也使用的是长轮询的机制。

hystix和sentinel的区别
hystix用线程池实现线程隔离,任何时刻大于线程池最大线程数的线程自然会被隔离,优点是支持异步、隔离性强(暂时不理解为啥隔离性强),缺点是一个service一个线程池,线程池相对更消耗资源,service多的话线程池也多扛不住啊;
sentinel基于信号量(计数器),来个请求信号量减一,优点是相比线程池轻量级,性能好,service多也无妨,缺点是不能异步。
[

](https://blog.csdn.net/rfidgroup/article/details/89519577)

Seata 服务端

分布式事务协调者,通过@GlobalTransactional开启全局事务,产生一个XID,向TC开启一个全局事务,其他子服务使用@Transactional使用本地事务,
image.png
Hystrix
Hystrix是隔离、熔断以及降级的一个框架。啥意思呢?说白了,Hystrix会搞很多个小小的线程池,比如订单服务请求库存服务是一个线程池,请求仓储服务是一个线程池,请求积分服务是一个线程池。每个线程池里的线程就仅仅用于请求那个服务。