SpringCloud学习笔记

问题

1 如果注册中心Nacos宕机,那么服务还能调用另一个服务吗?

假如存在订单服务A、订单服务B、商品服务C,只允许订单服务调用商品服务。

简答:

  • 如果服务A在注册中心宕机前调用过服务B,那么服务A就会缓存服务B的url等信息。这时如果Nacos宕机,依然可以通过缓存调用。
  • 如果不存在上述缓存,则服务A就找不到服务B的地址,从而导致调用失败。

实验:

  1. 把所有服务和nacos正常启动,然后访问订单A,发现A可以成功调用商品服务C。
  2. 关掉nacos,再次访问订单A,订单A依然可以调用商品服务C。
  3. 访问订单B,发现无法调用订单C。

深究

  1. 由实验的步骤二和三可以看出,这个缓存似乎把调用者和被调用者绑定了,只有调用者才能使用该缓存?
    :这个缓存是存在于调用者(订单服务A)内部的,并且每个调用者服务实例都维护着自己的一份独立缓存。订单服务A的缓存和订单服务B的缓存是完全隔离的、互不相干的。所以,只有当一个调用者(如订单A)成功从Nacos拉取过某个服务(如商品C)的信息后,它自己的缓存里才会有数据。

  2. 这个缓存存在哪里?
    :这个缓存就存放在订单服务A这个Java进程的内存里,并且通常也会有对应的本地文件快照作为灾备。它不依赖任何外部组件,是服务发现客户端SDK的一个内置功能。

  3. 为什么订单A可以调用,而订单B不能调用?
    :因为订单A之前成功调用过商品服务C,所以自己有商品服务C的缓存。订单B没有。而缓存又是隔离的,所以有上述结果。

  4. 这个缓存保存了哪些信息?
    :这个缓存保存了服务名 (Service Name)、集群名 (Cluster Name)、实例列表 (Hosts/Instances)、最后刷新时间 (lastRefTime)等信息。实例列表是一个数组,包含了该服务所有健康实例的地址和元数据。
    一个缓存文件的例子:

    	{
     	 "name": "DEFAULT_GROUP@@product-service",
     	 "clusters": "",
      	"lastRefTime": 1678886400000,
     	 "hosts": [
        {
          "instanceId": "192.168.1.101#8080#DEFAULT#DEFAULT_GROUP@@product-service",
          "ip": "192.168.1.101",
          "port": 8080,
          "weight": 1.0,
          "healthy": true,
          "enabled": true,
          "ephemeral": true,
          "clusterName": "DEFAULT",
          "serviceName": "DEFAULT_GROUP@@product-service",
          "metadata": {
            "preserved.register.source": "SPRING_CLOUD",
            "version": "1.0.2"
          },
          "instanceHeartBeatInterval": 5000,
          "instanceHeartBeatTimeOut": 15000,
          "ipDeleteTimeout": 30000,
          "instanceIdGenerator": "simple"
        },
        {
          "instanceId": "192.168.1.102#8080#DEFAULT#DEFAULT_GROUP@@product-service",
          "ip": "192.168.1.102",
          "port": 8080,
          "weight": 1.0,
          "healthy": true,
          "enabled": true,
          "ephemeral": true,
          "clusterName": "DEFAULT",
          "serviceName": "DEFAULT_GROUP@@product-service",
          "metadata": {
            "preserved.register.source": "SPRING_CLOUD",
            "version": "1.0.3"
          },
          "instanceHeartBeatInterval": 5000,
          "instanceHeartBeatTimeOut": 15000,
          "ipDeleteTimeout": 30000,
          "instanceIdGenerator": "simple"
        }
      ],
      "cacheMillis": 10000,
      "useSpecifiedURL": false,
      "checksum": "e5a37213e84381f286b03df52f87d7f1",
      "env": "",
      "dom": "product-service"
    }
    
  5. 这个缓存何时会刷新(缓存一致性问题)?
    :一般有三个场景。
    a. 注册中心主动推送
    这是最主要、最实时的刷新方式。Nacos 采用了“发布-订阅”模型。

    触发条件:只要商品服务C的实例列表发生任何变化,例如:有新的商品服务实例上线注册。有商品服务实例正常下线(Deregister)。有商品服务实例因为心跳超时而被服务器标记为不健康。实例的元数据(Metadata)发生了变更。

    过程:一旦发生上述变化,Nacos Server 会立即将最新的、完整的商品服务C的实例列表主动推送给所有订阅了该服务的客户端(比如订单服务A和订单服务B)。

    b. 客户端(即各个服务)定时拉取 (Pull)
    这是一种兜底和校对机制,作为服务器主动推送的补充。

    触发机制:Nacos 客户端(即各个服务)内部有一个定时任务,会以一个固定的周期(这个周期可以配置,通常是几十秒)向 Nacos Server 发起一次拉取请求,询问它所订阅的服务列表是否有变化。

    过程:客户端向服务端请求数据的摘要(checksum),如果服务端的摘要与客户端本地缓存的摘要不一致,说明数据发生了变化,客户端就会拉取最新的全量数据来更新本地缓存。如果摘要一致,则不做任何操作。

    c.Nacos Server 从宕机中恢复后
    Nacos Server 从宕机中恢复后,缓存会立即进行一次全量同步和刷新。

    触发条件:Nacos 客户端在后台会有一个重连机制,不断尝试与 Server 建立连接。一旦客户端检测到与 Nacos Server 的连接恢复,它会立即发起一次对自己所有订阅服务的全量拉取请求。这个过程会用从 Server 获取到的最新、最准确的数据来覆盖掉本地的缓存,无论是内存缓存还是磁盘快照。同步完成后,客户端就正常工作模),重新开始接收服务端的实时推送和进行定时拉取。

基础

to be continued

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值