SpringCloud - Eureka Server的数据同步过程?

step 1 - 启动时 

Eureka Server也是一个Client,在启动时,通过请求其中一个节点(Server),将自身注册到Server上,并获取注册服务信息;

Step 2 - 信息变更时

每当Eureka Server信息变更后(client发起注册,续约,注销请求时),就将信息通知给其他Server,来保持数据同步;

Step 3 - 解决Eureka Server之间的数据同步死循环

如果自己的信息变更是另一个Eureka Server同步过来的,这是再同步回去的话就出现数据同步死循环了。
在这里插入图片描述

Eureka Server 在执行复制操作的时候,使用 HEADER_REPLICATION 这个 http header 来区分普通应用实例的正常请求,说明这是一个复制请求这样其他 peer 节点收到请求时,就不会再对其进行复制操作,从而避免死循环。

Step 4 - 解决数据冲突

还有一个问题,就是数据冲突,比如 server A 向 server B 发起同步请求,如果 A 的数据比 B 的还旧,B 不可能接受 A 的数据,那么 B 是如何知道 A 的数据是旧的呢?这时 A 又应该怎么办呢?

数据的新旧一般是通过版本号来定义的,Eureka 是通过 lastDirtyTimestamp 这个类似版本号的属性来实现的
lastDirtyTimestamp 是注册中心里面服务实例的一个属性,表示此服务实例最近一次变更时间。

比如 Eureka Server A 向 Eureka Server B 复制数据(把A的数据同步到B),数据冲突有2种情况:

(1)A 的数据比 B 的新,B 返回 404,A 重新把这个应用实例注册到 B。

(2)A 的数据比 B 的旧,B 返回 409,要求 A 同步 B 的数据。

相关文章:

Eureka数据同步原理

Eureka Server 的数据同步过程?

Eureka集群没有主从概念,所有节点全部平等,集群间数据通过5个Http接口完成数据同步,下面介绍这几种接口以及同步流程。

同步流程

1) Get-获取注册列表

假设Eureka1服务最早启动,Eureka2服务启动时将Eureka1作为自己的上报服务(每个Eureka-Client只给一个Eureka-Server上报信息),首先调用GET /eureka/apps/获取已有注册列表。

GET /eureka/apps/ HTTP/1.1
Accept  application/json
DiscoveryIdentity-Name  DefaultClient
DiscoveryIdentity-Version   1.4
DiscoveryIdentity-Id    10.10.11.9
Accept-Encoding gzip
Host    10.10.11.9:8082
User-Agent  Java-EurekaClient/v1.6.2
Authorization   Basic ZGRzaHVhaToxMjM0NTY=
Connection  keep-alive

{
    "applications": {
        "versions__delta": "1",
        "apps__hashcode": "UP_1_",
        "application": [{
            "name": "ZUUL-DEV",
            "instance": [{
                "instanceId": "10.10.11.9:28723",
                "hostName": "10.10.11.9",
                "app": "ZUUL-DEV",
                "ipAddr": "10.10.11.9",
                "status": "UP",
                "overriddenstatus": "UNKNOWN",
                "port": {
                    "$": 28723,
                    "@enabled": "true"
                },
                "securePort": {
                    "$": 443,
                    "@enabled": "false"
                },
                "countryId": 1,
                "dataCenterInfo": {
                    "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
                    "name": "MyOwn"
                },
                "leaseInfo": {
                    "renewalIntervalInSecs": 30,
                    "durationInSecs": 90,
                    "registrationTimestamp": 1544160173785,
                    "lastRenewalTimestamp": 1544160173785,
                    "evictionTimestamp": 0,
                    "serviceUpTimestamp": 1544160173786
                },
                "metadata": {
                    "@class": "java.util.Collections$EmptyMap"
                },
                "homePageUrl": "http://10.10.11.9:28723/",
                "statusPageUrl": "http://10.10.11.9:28723/info",
                "healthCheckUrl": "http://10.10.11.9:28723/health",
                "vipAddress": "zuul-dev",
                "secureVipAddress": "zuul-dev",
                "isCoordinatingDiscoveryServer": "false",
                "lastUpdatedTimestamp": "1544160173786",
                "lastDirtyTimestamp": "1544160168179",
                "actionType": "ADDED"
            }]
        }]
    }
}

 2) Post-注册服务

获取到注册列表后,将自己添加到注册列表中,并发送注册信息到Eureka1上

POST /eureka/apps/EUREKA-SERVER HTTP/1.1
Accept-Encoding gzip
Content-Type    application/json
Accept  application/json
DiscoveryIdentity-Name  DefaultClient
DiscoveryIdentity-Version   1.4
DiscoveryIdentity-Id    10.10.11.9
Content-Length  877
Host    10.177.14.9:28721
User-Agent  Java-EurekaClient/v1.6.2
Authorization   Basic ZGRzaHVhaToxMjM0NTY=
Connection  keep-alive

{
    "instance": {
        "instanceId": "10.10.11.9:8082",
        "hostName": "10.10.11.9",
        "app": "EUREKA-SERVER",
        "ipAddr": "10.10.11.9",
        "status": "DOWN",
        "overriddenstatus": "UNKNOWN",
        "port": {
            "$": 8082,
            "@enabled": "true"
        },
        "securePort": {
            "$": 443,
            "@enabled": "false"
        },
        "countryId": 1,
        "dataCenterInfo": {
            "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
            "name": "MyOwn"
        },
        "leaseInfo": {
            "renewalIntervalInSecs": 30,
            "durationInSecs": 90,
            "registrationTimestamp": 0,
            "lastRenewalTimestamp": 0,
            "evictionTimestamp": 0,
            "serviceUpTimestamp": 0
        },
        "metadata": {
            "@class": "java.util.Collections$EmptyMap"
        },
        "homePageUrl": "http://10.10.11.9:8082/",
        "statusPageUrl": "http://10.10.11.9:8082/info",
        "healthCheckUrl": "http://10.10.11.9:8082/health",
        "vipAddress": "eureka-server",
        "secureVipAddress": "eureka-server",
        "isCoordinatingDiscoveryServer": "false",
        "lastUpdatedTimestamp": "1544159697067",
        "lastDirtyTimestamp": "1544164155198"
    }
}

3). Post-广播2步骤的节点新增信息

将Eureka2注册的事件写入自己的注册列表中,并以广播的形式通知剩余全部节点,收到通知的服务将Eureka2注册到自己的注册列表中

POST /eureka/peerreplication/batch/ HTTP/1.1
Accept  application/json
Content-Type    application/json
DiscoveryIdentity-Name  DefaultServer
DiscoveryIdentity-Version   1.0
DiscoveryIdentity-Id    10.10.11.9
Accept-Encoding gzip
Content-Length  1026
Host    10.177.14.9:28721
User-Agent  Java-EurekaClient-Replication/v1.6.2
Authorization   Basic ZGRzaHVhaToxMjM0NTY=
Connection  keep-alive

{
    "replicationList": [{
        "appName": "ZUUL-DEV",
        "id": "10.10.11.9:28723",
        "lastDirtyTimestamp": 1544160168179,
        "status": "UP",
        "instanceInfo": {
            "instanceId": "10.10.11.9:28723",
            "hostName": "10.10.11.9",
            "app": "ZUUL-DEV",
            "ipAddr": "10.10.11.9",
            "status": "UP",
            "overriddenstatus": "UNKNOWN",
            "port": {
                "$": 28723,
                "@enabled": "true"
            },
            "securePort": {
                "$": 443,
                "@enabled": "false"
            },
            "countryId": 1,
            "dataCenterInfo": {
                "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
                "name": "MyOwn"
            },
            "leaseInfo": {
                "renewalIntervalInSecs": 30,
                "durationInSecs": 90,
                "registrationTimestamp": 0,
                "lastRenewalTimestamp": 0,
                "evictionTimestamp": 0,
                "serviceUpTimestamp": 0
            },
            "metadata": {
                "@class": "java.util.Collections$EmptyMap"
            },
            "homePageUrl": "http://10.10.11.9:28723/",
            "statusPageUrl": "http://10.10.11.9:28723/info",
            "healthCheckUrl": "http://10.10.11.9:28723/health",
            "vipAddress": "zuul-dev",
            "secureVipAddress": "zuul-dev",
            "isCoordinatingDiscoveryServer": "false",
            "lastUpdatedTimestamp": "1544160173786",
            "lastDirtyTimestamp": "1544160168179",
            "actionType": "ADDED"
        },
        "action": "Register"
    }]
}

4) Get-获取注册列表变化信息

这次与第一步骤类似,但是这次只获取注册列表的变化信息。

GET /eureka/apps/delta HTTP/1.1
Accept  application/json
DiscoveryIdentity-Name  DefaultClient
DiscoveryIdentity-Version   1.4
DiscoveryIdentity-Id    10.10.11.9
Accept-Encoding gzip
Host    10.177.14.9:28721
User-Agent  Java-EurekaClient/v1.6.2
Authorization   Basic ZGRzaHVhaToxMjM0NTY=
Connection  keep-alive

{
    "applications": {
        "versions__delta": "167299",
        "apps__hashcode": "UP_20_",
        "application": []
    }
}

5) 每30s上报一次健康心跳

Eureka2之后每30s向Eureka1上报健康信息,也就是续约。

PUT /eureka/apps/EUREKA-SERVER/10.10.11.9:8082?status=UP&lastDirtyTimestamp=1544159712387 HTTP/1.1
DiscoveryIdentity-Name  DefaultClient
DiscoveryIdentity-Version   1.4
DiscoveryIdentity-Id    10.10.11.9
Accept-Encoding gzip
Content-Length  0
Host    10.177.14.9:28721
User-Agent  Java-EurekaClient/v1.6.2
Authorization   Basic ZGRzaHVhaToxMjM0NTY=
Connection  keep-alive

6.) Post-广播心跳信息

过程与第二步一致。

原文:Spring Cloud Eureka - 集群间数据同步

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值