Soul网关源码分析-12期(周总结)

文章目录

  • HTTP 服务探活
    • 服务注册
      • 后台缓存信息新增
      • 后台缓存信息新增 通知网关
      • 网关缓存信息新增
    • 服务下线
      • 后台缓存信息变动
      • 后台缓存信息变动 通知网关
      • 网关缓存信息更新
    • TIPS
    • 总结



HTTP 服务探活



目的

最终目的是搞清楚网关中服务节点缓存在各种情况下的变动, 这样在请求网关转发 HTTP 服务时, 才能做到心中有数.


拆分任务

看到最终目的, 我会有几个想法:

  1. 网关的缓存节点信息应该在何时变动 ?

  2. 后台数据会同步网关, 那后台数据如何变动, 如何通知网关 ?

根据这些问题, 就得到了要进行的任务 ==>

  • HTTP 服务注册时

    • 后台缓存的服务节点如何变动
    • 后台缓存加入新注册信息后, 如何通知网关
    • 网关如何新增服务缓存
  • HTTP 服务下线时 (探活)

    • 后台如何得知服务下线并更新缓存
    • 后台缓存更新后, 如何通知网关
    • 网关如何更新服务缓存



服务注册



后台缓存信息新增


UpstreamCheckService 的 UPSTREAM_MAP 中存放着后台服务节点信息

public class UpstreamCheckService {
     
  
	private static final Map<String, List<DivideUpstream>> UPSTREAM_MAP = Maps.newConcurrentMap();
}

UPSTREAM_MAP 中的数据有两个来源, 一是启动时从数据库拿, 二是服务注册时传入.

数据库获取方式相对简单, 在 UpstreamCheckService#setup 中有体现.


服务注册路径图:

SpringMvcClientBeanPostProcessor
SoulClientController
SoulClientRegisterServiceImpl
UpstreamCheckService

SpringMvcClientBeanPostProcessor(http服务端): 收集Controller层信息, 请求后台的路径: /soul-client/springmvc-register


SoulController: 后台对外暴露的 Http api, 供请求服务注册


SoulClientRegisterServiceImpl: 直接调用 UpstreamCheckService#submit 传入要新增的节点数据




后台缓存信息新增 通知网关


后台通知路径图 (Websocket模式):

SpringMvcClientBeanPostProcessor
SoulClientController
SoulClientRegisterServiceImpl
DataChangedEventDispatcher
WebsocketCollector

SoulClientRegisterServiceImpl: 发送自定义事件, 由订阅事件中心处理 (Spring 发布订阅模式)


DataChangedEventDispatcher: 事件接收和分发类, 根据事件类型调用监听类的对应方法


WebsocketCollector: 管理 Websocket 通信, 维护连接的 session 会话.




网关缓存信息新增


UpstreamCheckService 的 UPSTREAM_MAP 中存放着网关的 divide 插件服务节点信息

public final class UpstreamCacheManager {
     
    
  private static final Map<String, List<DivideUpstream>> UPSTREAM_MAP = Maps.newConcurrentMap();
}

服务信息变动路径图 (Websocket模式):

SoulWebsocketClient
WebsocketDataHandler
AbstractDataHandler
CommonPluginDataSubscriber
DividePluginDataHandler
UpstreamCacheManager

SoulWebsocketClient: 后台 wesocket 信息在这里被监听, 并发送给 WebsocketDataHandler 处理.


WebsocketDataHandler: 根据事件类型, 选择对应处理器 (PluginDataHandler、RuleDataHandler等)


AbstractDataHandler: 根据事件变动类型(refresh、update等), 调用处理器对应方法, 具体实现类会调用到 CommonPluginDataSubscriber 订阅器


CommonPluginDataSubscriber: 这里存有所有注册为 Bean 的事件处理器, 这些处理器来自各个扩展插件, 会调用他们的 handlerXXX() 方法


DividePluginDataHandler: 更新或移除缓存管理器中服务节点信息




服务下线



后台缓存信息变动


探活路径图:

UpstreamCheckService&init
this&scheduled
this&check

后台缓存管理器在初始化时, 会启动定时器 (间隔10秒) 检测缓存中节点服务的活性, 方式是尝试 Socket#connect 连接.




后台缓存信息变动 通知网关


通知路径图 (Websocket模式):

UpstreamCheckService&check
this&updateSelectorHandler
DataChangedEventDispatcher
WebsocketCollector

这块与 HTTP 服务注册时后台通知网关很相似, 最终都会流入到 DataChangedEventDispatcher 事件分发器, 并通过 Websocket 通信发出.


不同的是发起点, HTTP 服务注册时, 由具体的 HTTP 服务发起后台请求, 而 HTTP 服务下线时, 是由后台缓存管理器自身的定时探活模块发起.




网关缓存信息更新


网关的缓存更新有两种方式, 一个是接收到后台信息变更通知, 这点与服务注册时一致, 不再赘述.

第二种是 divide 的缓存管理器, 可开启如同后台的定时探活, 也是通过 Socket#connect 去判断服务是否可用, 但这块默认配置是关闭的, 且检测间隔时间为 30S.





TIPS



HTTP 服务注册时, 后台会将服务信息写入数据库.

public class SoulClientRegisterServiceImpl implements SoulClientRegisterService {
     
  
  private String registerSelector(final String contextPath, final String rpcType, final String appName, final String uri) {
     
    // ...
    if (RpcTypeEnum.DUBBO.getName().equals(rpcType)) {
     

    } else {
     
      //... is divide
      // 通知缓存管理器节点信息
      upstreamCheckService.submit(selectorDTO.getName(), divideUpstream);
    }
    // ...
    // 这里会将数据写入数据库
    return selectorService.register(selectorDTO);
  }
}




总结


引用 “进击的巨人” 里常看见的一句话, 根据现在可以公开的情报:

  • 后台的 UpstreamCheckService 类以及网关的 UpstreamCacheManager 类持有各自的服务节点缓存信息
  • UpstreamCheckService -> UpstreamCacheManager 可以通过框架提供的数据同步传输 (Websocket、Zookeeper 等)
  • 后台HTTP服务的探活是定时尝试 Socket 连接来完成, 而网关端可以接收到后台数据同步来的最新信息, 不用自己完成探活
  • 网关有可选项, 开启定时 Socket 连接完成探活 (肯定是不建议开的, 网关太累了…)

一点思考 : Socket 连接有些过重, 改进的话参考一些注册中心的实现, 比如 Eureka 会让服务节点引入 EurekaClient , 与服务端 EurekaServer 做心跳检测, 是一种比较轻的探活方式.

你可能感兴趣的:(网关,java)