apache / servicecomb-service-center

A standalone service center to allow services to register their instance information and to discover providers of a given service
Apache License 2.0
1.34k stars 343 forks source link

自动生成的 instanceid 每次都不一样 #634

Open xy-github-issue opened 4 years ago

xy-github-issue commented 4 years ago

Describe the bug 用相同的 endpoints 注册服务实例,每次得到的 instanceid 都不一样

To Reproduce Steps to reproduce the behavior:

  1. curl -X POST \ http://127.0.0.1:30100/registry/v3/microservices \ -H 'content-type: application/json' \ -H 'x-domain-name: default' \ -d '{ "service": { "appId": "default", "serviceName": "DemoService", "version":"1.0.0" } }'
  2. 用上一步返回的 serviceid 做下面的请求 curl -X POST \ http://127.0.0.1:30100/registry/v3/microservices/a3fae679211211e8a831286ed488fc1b/instances \ -H 'content-type: application/json' \ -H 'x-domain-name: default' \ -d '{ "instance": { "hostName":"demo-pc", "endpoints": [ "rest://127.0.0.1:8080" ] } }' 得到一个 instanceid
  3. 重复上一次,又得到新的 instanceid

Expected behavior 接口文档中提到:

如果没定制,逻辑如下:系统自动生成id,如果endpoints内容重复,则使用原来的id

Platform And Runtime (please complete the following information):

Platform

Runtime

little-cui commented 4 years ago

期望instanceId不变的原因是什么?

xy-github-issue commented 4 years ago

期望instanceId不变的原因是什么?

首先其实是文档给到我的感觉,所以文档内容需要修正吧。

然后 endpoints 内容相同的情况下,倒底要不要生成相同的 instanceid ,我也有想不清楚的地方。一方面进程挂了,重新起来,换 instanceid 似乎是有一定的合理性的。但是,我明显可能想到的有问题的场景:如果有一个定时任务(作为consumer,一定需要一个instanceid吗?还是只需要一个consumer 的服务id?),每次启动都产生一个新的 instanceid,假设这个业务有问题,繁复地重启,就可能把 instanceid 耗尽。从而一个有问题的业务,可能把整个service-center搞挂。再结合下面的考虑,外部看到一个服务实例,肯定是不关心你的进程是什么(更具体的比如,肯定不关心你的进程id),我只看到你的endpoint及关联在服务id上的服务信息,从这一点上看,endpoint+serviceid 不变 ==> 相同的 instanceid 是很合理的,对于服务使用方来说,这个实例没有变。关于上面这一点,现在的实现给到我一个感觉比较意外的行为是,查询服务实例时,会得到有重复的endpoint列表(服务实例挂了,重启后注册产生了新的实例,还未过120秒原实例信息未清掉),但我使用服务的时候,相同的endpoint 就是相同的。当然我是对取到的 endpoint 列表去重了一下啦。

我也想了解下,出于什么考虑,你们需要针对相同的信息每次生成不同的instanceid,你们期待大家以什么样的姿势来使用?

little-cui commented 4 years ago

嗯,我了解你的意思了,文档内存在让人产生歧义的地方,也非常欢迎你指正,并提PR优化的。

回到正题,instanceId坚持变化的原因是,在商用大规模的容器场景时,出现了容器ip分配相同,但实际业务处理区域不相同的情况,比如,基础服务A被部署在业务平面和管理平面,分别被各自不同平面业务依赖消费,当进程重启时候,业务平面某个容器IP被分配到管理平面去了,如果instanceId不变,导致业务平面消费端不感知,继续消费;如平面间网络互通,则出现数据错乱,如不通,则出现访问异常,影响消费端消费策略。

综上原因,当前服务中心并不考虑instanceId跟endpoint的关系,注册则认为是新的id,至于所谓的id耗尽,暂时使用了UUIDv4逻辑生成,考虑到并发生成instanceId冲突概率是极低的

xy-github-issue commented 4 years ago

比如,基础服务A被部署在业务平面和管理平面,分别被各自不同平面业务依赖消费,当进程重启时候,业务平面某个容器IP被分配到管理平面去了

这个例子,我有点看不懂。这里说的,是否是有一个服务 A,A 同时有

  1. 服务实例 1 在业务平面
  2. 服务实例 2 在管理平面上 首先平面这个概念我不是很懂,它是service-center 中的概念?对应什么代码或界面里的什么英文命名? 看起来,在不同平面的实例是不等价的。 如果平面不是service-center中的概念,而业务自己的业务概念,那似乎不应该是 service-center 去处理的,service-center 最多只能为业务提供一些 meta-data,业务自己处理好自己的负载均衡规则。或者本来两个不同平面上的实例就应该是两个不同的服务?