操作场景
您在生产环境上已经使用了自建的 Eureka 集群,希望将其上已运行的服务迁移至腾讯云的 微服务平台(TSF)。TSF 提供北极星(Polaris)完全兼容 Eureka 注册中心。在功能完全对齐的基础上,北极星在性能上相比开源 Eureka 有突破性提升。
本文将通过一个 Demo 应用,通过 
spring-cloud-eureka-client 接入北极星的全流程操作演示,帮助您快速了解如何实现 Eureka 迁移。前提条件
兼容的 Eureka 版本为1.9.13,兼容的接口范围见附件。
已创建 Polaris 北极星网格,请参见 创建北极星(Polaris) 实例。
下载 GitHub 的 demo 源码 到本地并解压。
本地编译构建打包机器环境已安装了Java JDK、Maven,并且能够访问 Maven 中央库。
根据您自身的业务,已准备好业务部署的资源,选择
虚拟机部署或容器化部署其中一种方式即可:虚拟机部署已创建 CVM 虚拟机,请参见 创建 CVM 虚拟机。
容器化部署已创建 TKE 容器集群,请参见 创建 TKE 集群。
操作步骤
1. 登录 TSF 控制台,左侧导航栏选择 Polaris(北极星)。
2. 在北极星的实例列表页面,单击目标引擎的“ID”,进入实例信息页面。
3. 查看访问地址,Eureka-client 应用访问使用 eureka 端口(8761):


4. 修改 demo 中的注册中心地址
在下载到本地的 Demo 源码目录 下,分别找到
eureka/eureka-java/consumer/src/main/resources/application.yml和eureka/eureka-java/provider/src/main/resources/application.yml两个文件。添加微服务引擎北极星网格地址到项目配置文件中(以
eureka/eureka-java/consumer/src/main/resources/application.yml为例)。eureka:client:serviceUrl:defaultZone: http://10.0.0.133:8761/eureka/
5. 打包 Demo 源码成 jar 包
5.1 在 
eureka-java 源码根目录下,打开 cmd 命令,执行 mvn clean package 命令,对项目进行打包编译。5.2 编译成功后,生成如下表所示的2个 JAR 包。
| 软件包所在目录 | 软件包名称 | 说明 | 
| \\eureka-java\\provider\\target | eureka-provider-${version}-SNAPSHOT.jar | 服务生产者 | 
| \\eureka-java\\consumer\\target | eureka-consumer-${version}-SNAPSHOT.jar | 服务消费者 | 
6. 部署 provider 和 consumer 微服务应用,虚拟机部署方式、容器化部署或者本地运行,根据您业务实际的部署方式选择一种即可。
6.1 虚拟机部署方式部署 provider 和 consumer 微服务应用。
上传 JAR 包至 CVM 实例。
执行启动命令进行启动:
nohup java -jar [jar包名称] &
6.2 容器化部署方式部署 provider 和 consumer 微服务应用。
编写 Dockerfile 生成镜像,参考:
FROM java:8ADD ./eureka-provider-${VERSION}.jar /root/app.jarENTRYPOINT ["java","-jar","/root/app.jar"]
通过 TKE 部署并运行镜像。
7. 确认服务注册结果。
7.1 进入前面提到的微北极星网格实例页面。
选择服务管理 > 服务列表,查看微服务 EUREKA-CONSUMER-SERVICE 和 EUREKA-PROVIDER-SERVICE 的实例数量:
若实例数量不为0,则表示已经成功接入微服务引擎。
若实例数量为0,或者找不到具体服务的服务名,则表示微服务应用接入微服务引擎失败。


7.2 调用 consumer 的 HTTP 接口。执行 HTTP 调用,其中
${app.port}替换为 consumer 的监听端口(默认为20002),${add.address}则替换为 consumer 暴露的地址。curl -L -X GET 'http://${add.address}:${app.port}/echo?value=hello_world''预期返回值:echo: hello_world
附件:兼容的接口范围
服务实例注册接口
POST /eureka/apps/SPRING-CLOUD-EUREKA-SERVER2 HTTP/1.1Accept-Encoding: gzipContent-Type: application/jsonAccept: application/jsonDiscoveryIdentity-Name: DefaultClientDiscoveryIdentity-Version: 1.4DiscoveryIdentity-Id: 9.134.15.118Transfer-Encoding: chunkedHost: 127.0.0.1:9090Connection: Keep-AliveUser-Agent: Java-EurekaClient/v1.9.13{"instance":{"instanceId":"9.134.15.118:spring-cloud-eureka-server2:9091","hostName":"127.0.0.1","app":"SPRING-CLOUD-EUREKA-SERVER2","ipAddr":"9.134.15.118","status":"UP","overriddenStatus":"UNKNOWN","port":{"$":9091,"@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":{"management.port":"9091"},"homePageUrl":"http://127.0.0.1:9091/","statusPageUrl":"http://127.0.0.1:9091/actuator/info","healthCheckUrl":"http://127.0.0.1:9091/actuator/health","vipAddress":"spring-cloud-eureka-server2","secureVipAddress":"spring-cloud-eureka-server2","isCoordinatingDiscoveryServer":"false","lastUpdatedTimestamp":"1627029279467","lastDirtyTimestamp":"1627029280245"}}
URL 参数
/eureka/apps/<appId>| 参数名 | 类型 | 描述 | 是否必填 | 
| appId | string | 服务名,全大写 | 是 | 
Body 参数
| 参数名 | 类型 | 描述 | 是否必填 | 
| instanceId | string | 实例ID,唯一确定一个实例,一般生成格式为<ip>:<appId小写>:<port> | 是 | 
| hostName | string | 实例的域名信息 | 否 | 
| app | string | 服务名,对应URL的appId,大写 | 是 | 
| ipAddr | string | 实例的IP信息 | 是 | 
| status | string | 实例状态信息,可选值为"UP", "DOWN", "OUT_OF_SERVICE | 是 | 
| overriddenStatus | string | 覆盖实例状态,可选值为"UP", "DOWN", "OUT_OF_SERVICE,没有用到 | 否 | 
| port | struct | 非加密端口号,包含2个字段,$代表端口号,@enabled(字符串)代表是否启用 | 是 | 
| securePort | struct | 加密端口号,包含2个字段,$代表端口号,@enabled(字符串)代表是否启用 | 否(加密端口与非加密端口必须至少配置并启动一个) | 
| countryId | int | 国家标识 | 否 | 
| dataCenterInfo | string | 数据仓库反射类 | 否 | 
| leaseInfo | struct | 租约信息 | 是 | 
| leaseInfo.renewalIntervalInSecs | int | 客户端定时续约时间 | 是 | 
| leaseInfo.durationInSecs | int | 实例的TTL时间 | 是 | 
| registrationTimestamp | int | 注册时间戳 | 否 | 
| lastRenewalTimestamp | int | 最近一次续约时间 | 否 | 
| evictionTimestamp | int | 最近一次剔除时间 | 否 | 
| serviceUpTimestamp | int | 最近一次上线时间 | 否 | 
| metadata | map[string]string | 标签KV数据 | 否 | 
| homePageUrl | string | 首页地址 | 否 | 
| statusPageUrl | string | 状态页地址 | 否 | 
| healthCheckUrl | string | 健康检查地址 | 否 | 
| vipAddress | string | VIP地址 | 否 | 
| secureVipAddress | string | 加密协议VIP地址 | 否 | 
| isCoordinatingDiscoveryServer | string | 数据是否未同步给其他server | 否 | 
| lastUpdatedTimestamp | string | 最近一次更新时间 | 否 | 
| lastDirtyTimestamp | string | 最近一次状态变更时间 | 否 | 
服务实例反注册接口
DELETE /eureka/apps/SPRING-CLOUD-EUREKA-SERVER2/9.134.15.118:spring-cloud-eureka-server2:9091 HTTP/1.1DiscoveryIdentity-Name: DefaultClientDiscoveryIdentity-Version: 1.4DiscoveryIdentity-Id: 9.134.15.118Accept-Encoding: gzipHost: 127.0.0.1:9090Connection: Keep-AliveUser-Agent: Java-EurekaClient/v1.9.13HTTP/1.1 200Content-Type: application/xmlContent-Length: 0Date: Fri, 23 Jul 2021 08:35:42 GMTKeep-Alive: timeout=60Connection: keep-alive
URL 参数
/eureka/apps/<appId>/<instanceId>| 参数名 | 类型 | 描述 | 是否必填 | 
| appId | string | 服务名,全大写 | 是 | 
| instanceId | string | 实例ID,唯一确定一个实例,与服务注册的实例ID对应 | 是 | 
续约接口
PUT /eureka/apps/SPRING-CLOUD-EUREKA-SERVER2/9.134.15.118:spring-cloud-eureka-server2:9091?status=UP&lastDirtyTimestamp=1627029280245 HTTP/1.1DiscoveryIdentity-Name: DefaultClientDiscoveryIdentity-Version: 1.4DiscoveryIdentity-Id: 9.134.15.118Accept-Encoding: gzipContent-Length: 0Host: 127.0.0.1:9090Connection: Keep-AliveUser-Agent: Java-EurekaClient/v1.9.13HTTP/1.1 200Content-Type: application/xmlContent-Length: 0Date: Fri, 23 Jul 2021 08:35:10 GMTKeep-Alive: timeout=60Connection: keep-alive
URL 参数
/eureka/apps/<appId>/<instanceId>?status=<status>&lastDirtyTimestamp=<lastDirtyTimestamp>| 参数名 | 类型 | 描述 | 是否必填 | 
| appId | string | 服务名,全大写 | 是 | 
| instanceId | string | 实例ID,唯一确定一个实例,与服务注册的实例ID对应 | 是 | 
| status | string | 实例状态信息,可选值为"UP", "DOWN", "OUT_OF_SERVICE | 是 | 
| lastDirtyTimestamp | string | 最近一次状态变更时间 | 否 | 
拉取服务数据接口
GET /eureka/apps/ HTTP/1.1Accept: application/jsonDiscoveryIdentity-Name: DefaultClientDiscoveryIdentity-Version: 1.4DiscoveryIdentity-Id: 9.134.15.118Accept-Encoding: gzipHost: 127.0.0.1:9090Connection: Keep-AliveUser-Agent: Java-EurekaClient/v1.9.13HTTP/1.1 200Content-Encoding: gzipContent-Type: application/jsonContent-Length: 632Date: Fri, 23 Jul 2021 08:35:10 GMTKeep-Alive: timeout=60Connection: keep-alive{"applications":{"versions__delta":"1","apps__hashcode":"UP_2_","application":[{"name":"SPRING-CLOUD-EUREKA-SERVER2","instance":[{"instanceId":"9.134.15.118:spring-cloud-eureka-server2:9091","hostName":"127.0.0.1","app":"SPRING-CLOUD-EUREKA-SERVER2","ipAddr":"9.134.15.118","status":"UP","overriddenStatus":"UNKNOWN","port":{"$":9091,"@enabled":"true"},"securePort":{"$":443,"@enabled":"false"},"countryId":1,"dataCenterInfo":{"@class":"com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo","name":"MyOwn"},"leaseInfo":{"renewalIntervalInSecs":30,"durationInSecs":90,"registrationTimestamp":1627029280384,"lastRenewalTimestamp":1627029280384,"evictionTimestamp":0,"serviceUpTimestamp":1627029280386},"metadata":{"management.port":"9091"},"homePageUrl":"http://127.0.0.1:9091/","statusPageUrl":"http://127.0.0.1:9091/actuator/info","healthCheckUrl":"http://127.0.0.1:9091/actuator/health","vipAddress":"spring-cloud-eureka-server2","secureVipAddress":"spring-cloud-eureka-server2","isCoordinatingDiscoveryServer":"false","lastUpdatedTimestamp":"1627029280386","lastDirtyTimestamp":"1627029280245","actionType":"ADDED"}]}]}}
应答 Body 参数
| 参数名 | 类型 | 描述 | 是否必填 | 
| applications | struct | 服务应答的根节点 | 是 | 
| applications.versions__delta | string | 版本号信息 | 是 | 
| applications.apps__hashcode | string | hash信息,格式为<status>_<count>_ | 是 | 
| applications.application | struct | 服务列表 | 是 | 
| application.name | string | 服务名,大写 | 是 | 
| application.instance | struct | 实例列表 | 是 | 
| application.instance.actionType | struct | 实例的变更信息,支持 ADDED,MODIFIED, DELETED | 是 | 
| application.instance.* | 实例其他字段定义,可参考注册接口 | 
增量拉取服务接口
用于拉取实例的增量变更信息
GET /eureka/apps/delta HTTP/1.1Accept: application/jsonDiscoveryIdentity-Name: DefaultClientDiscoveryIdentity-Version: 1.4DiscoveryIdentity-Id: 9.134.15.118Accept-Encoding: gzipHost: 127.0.0.1:9090Connection: Keep-AliveUser-Agent: Java-EurekaClient/v1.9.13HTTP/1.1 200Content-Encoding: gzipContent-Type: application/jsonContent-Length: 642Date: Fri, 23 Jul 2021 08:35:39 GMTKeep-Alive: timeout=60Connection: keep-alive{"applications":{"versions__delta":"1","apps__hashcode":"DOWN_1_UP_1_","application":[{"name":"SPRING-CLOUD-EUREKA-SERVER2","instance":[{"instanceId":"9.134.15.118:spring-cloud-eureka-server2:9091","hostName":"127.0.0.1","app":"SPRING-CLOUD-EUREKA-SERVER2","ipAddr":"9.134.15.118","status":"DOWN","overriddenStatus":"UNKNOWN","port":{"$":9091,"@enabled":"true"},"securePort":{"$":443,"@enabled":"false"},"countryId":1,"dataCenterInfo":{"@class":"com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo","name":"MyOwn"},"leaseInfo":{"renewalIntervalInSecs":30,"durationInSecs":90,"registrationTimestamp":1627029339289,"lastRenewalTimestamp":1627029339289,"evictionTimestamp":0,"serviceUpTimestamp":1627029280386},"metadata":{"management.port":"9091"},"homePageUrl":"http://127.0.0.1:9091/","statusPageUrl":"http://127.0.0.1:9091/actuator/info","healthCheckUrl":"http://127.0.0.1:9091/actuator/health","vipAddress":"spring-cloud-eureka-server2","secureVipAddress":"spring-cloud-eureka-server2","isCoordinatingDiscoveryServer":"false","lastUpdatedTimestamp":"1627029339289","lastDirtyTimestamp":"1627029339279","actionType":"ADDED"}]}]}}
应答 Body 说明
与拉取服务数据接口的一致。
拉取单个应用的服务实例
GET /eureka/apps/EUREKA-SERVER HTTP/1.1Host: 109.244.197.190:8761User-Agent: curl/7.54.0Accept: application/jsonHTTP/1.1 200Content-Type: application/jsonTransfer-Encoding: chunkedDate: Sat, 28 Aug 2021 07:46:27 GMT{"application":{"name":"EUREKA-SERVER","instance":[{"instanceId":"11.160.104.72:8761","hostName":"eureka-0.eureka","app":"EUREKA-SERVER","ipAddr":"11.160.104.72","status":"UP","overriddenStatus":"UNKNOWN","port":{"$":8761,"@enabled":"true"},"securePort":{"$":443,"@enabled":"false"},"countryId":1,"dataCenterInfo":{"@class":"com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo","name":"MyOwn"},"leaseInfo":{"renewalIntervalInSecs":3,"durationInSecs":9,"registrationTimestamp":1628130660609,"lastRenewalTimestamp":1630136649648,"evictionTimestamp":0,"serviceUpTimestamp":1628130639520},"metadata":{"management.port":"8081"},"homePageUrl":"http://eureka-0.eureka:8761/","statusPageUrl":"http://eureka-0.eureka:8081/actuator/info","healthCheckUrl":"http://eureka-0.eureka:8081/actuator/health","vipAddress":"eureka-server","secureVipAddress":"eureka-server","isCoordinatingDiscoveryServer":"false","lastUpdatedTimestamp":"1628130660609","lastDirtyTimestamp":"1628130639502","actionType":"ADDED"}]}}
应答 Body 说明
与拉取全部应用服务实例接口一致,不再赘述。
拉取单个应用下的单个实例信息
GET /eureka/apps/EUREKA-SERVER/11.160.104.72:8761 HTTP/1.1Host: 109.244.197.190:8761User-Agent: curl/7.54.0Accept: application/jsonHTTP/1.1 200Content-Type: application/jsonTransfer-Encoding: chunkedDate: Sat, 28 Aug 2021 11:31:30 GMT{"instance":{"instanceId":"11.160.104.72:8761","hostName":"eureka-0.eureka","app":"EUREKA-SERVER","ipAddr":"11.160.104.72","status":"UP","overriddenStatus":"UNKNOWN","port":{"$":8761,"@enabled":"true"},"securePort":{"$":443,"@enabled":"false"},"countryId":1,"dataCenterInfo":{"@class":"com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo","name":"MyOwn"},"leaseInfo":{"renewalIntervalInSecs":3,"durationInSecs":9,"registrationTimestamp":1628130660609,"lastRenewalTimestamp":1630150297516,"evictionTimestamp":0,"serviceUpTimestamp":1628130639520},"metadata":{"management.port":"8081"},"homePageUrl":"http://eureka-0.eureka:8761/","statusPageUrl":"http://eureka-0.eureka:8081/actuator/info","healthCheckUrl":"http://eureka-0.eureka:8081/actuator/health","vipAddress":"eureka-server","secureVipAddress":"eureka-server","isCoordinatingDiscoveryServer":"false","lastUpdatedTimestamp":"1628130660609","lastDirtyTimestamp":"1628130639502","actionType":"ADDED"}}
应答 Body 说明
与拉取全部应用服务实例接口一致。