美文网首页
服务发现中心方案演进(二)

服务发现中心方案演进(二)

作者: 黄云斌huangyunbin | 来源:发表于2018-07-09 20:52 被阅读0次

上文说到mysql比较难以承受几万的tps,所以我们就选择了redis。

redis有key的失效机制,和服务发现的心跳超时失效非常贴合,天生适合啊。
问:redis做持久化吗,redis的持久化机制并不好,数据丢了怎么办
答:redis不做持久化,服务发现这种场景比较特殊,因为有心跳,数据会短时间内会恢复

方案整体架构:

image.png

方案描述:

1.service结点通过rest接口,定时(5s)向Luna server重新注册(包括结点信息和服务信息);

2.Luna server在本地维护每个服务的存活结点列表(loading cache,1分钟有效);每隔1S拉取有变更的服务列表(小于最大事件id的),并将本地loading cache失效

image.png
结点注册

结点通过注册接口每5秒重新注册一次(无状态);

a. 通过pipeline发送以下命令:getset(设置结点信息),expire(设置超时)和sadd(添加到服务结点key set),把结点注册进去;

b. 根据getset的结点决定是否需要生成一条服务列表改变事件,如果返回nil,则inc srv:event:id:max得到最大id,然后set svr:event:{maxid} 服务ID, hset [srv:info:xxx](http://srvinfoxxx/) version{maxid}

结点取消注册

a. srem 从key set中删除结点

b. del 删除结点

c. 生成服务列表改变事件: inc srv:event:id:max得到最大id,然后set svr:event:{maxid} 服务ID,hset [srv:info:xxx](http://srvinfoxxx/) version{maxid}

luna server获取服务列表

luna server定时(每1秒)读取srv:event:{min}至[srv:event](http://srveventxxx/):{max}之间的N条记录,并清除本地的loading cache,通知在等待该服务的long polling请求;

luna server在本地维护每一个服务列表的loading cache(有效期为1分钟);

当loading cache失效时,处理策略如下:

a. smembers srv:list:xxxx 获取结点列表;

b. mget node0 node1 xxx 获取全部结点信息,已经过期的结点,获取到nil;

c. 如果上一步获得到的结点信息中有nil,则将这个key从svr:list:xxxx中删除(srem node{x});

d. 对于已经删除的key,再次判断exists node{x} 如果存在,则把它再加回到svr:list:xxx中(sadd node{x});

方案的总体思路

心跳保持item节点,这个是源数据。我们关系是服务有哪些节点,就是srv:list,这个是结果数据。如果每次都要去比对这两个数据是否一致会比较麻烦。所以正常的注册 和反注册是通过产生事件,luna server和redis之间比对最大事件id就知道数据有无变化了。
但还是会有kill -9这种异常情况,所以loading cache的缓存时间不能太长,缓存失效后就会做一个检查,保证数据的一致性。

方案优化

主要的tps是心跳,心跳是 实例数 x服务数 /心跳间隔时间,如果这个能够优化,那效果就是很明显了。其实我们的实例数不是很多,就是1万左右,但是我们一个实例平均会有20个服务左右,从这个角度来说,确实是微服务了啊。但是这20个服务基本是同生共死的,因为都是同一个实例进程。
所以我们认为“实例对应服务的心跳” 可以用 “实例的心跳” 来取代。
这样tps就降低了一个数量级,1万实例/5秒心跳间隔=2000 tps,这个tps单台redis都没什么压力了。

问:loading cache失效的时候,发现服务列表数据不一致,会下线这个实例服务,如果这个实例正好上线,会有并发问题吧。

答:刚开始是想半夜3-4点的时候才会做下线操作,这个时候基本没有服务上线,这种做法并不好。选择的做法是下线完再检查一次,如果item节点又存在了,补偿注册。

问:可能多个luna server的loading cache同时失效,会有并发处理下线操作啊

答:是的,所以用loading cache的失效来做服务的下线操作是不合适的,读写应该分离,loading cache只负责读就好。

所以这就是最后采用的方案了吗?

并不是啊。这里有个重要的考虑点的。正常的注册和反注册都是1s就能告诉client,但是kill -9这种情况呢,最差是redis的key过期时间(20s)+lodingcache的失效时间(50s)=70s,这个时间太长了,已经不可以接受了。
如果用定时任务来下线失效的,上文已经算过其实tps还是挺高的,而且redis cluster没有事务,并发情况下数据一致性很难得到保证。

那要怎么解决呢?且看下文。

相关文章

  • 服务发现中心方案演进(二)

    上文说到mysql比较难以承受几万的tps,所以我们就选择了redis。 redis有key的失效机制,和服务发现...

  • 服务发现中心方案演进(三)

    上文说到时效性的问题,要怎么解决呢? redis是key失效通知的,这个正好是我们需要的啊。 这个功能经过我们的d...

  • 服务发现中心方案演进(一)

    最开始我们是打算用mysql来实现的。 考虑原因:服务的上下线是一个比较低频率的事情,mysql的qps应付这点q...

  • 四川泥腿农业科技有限公司

    方案一:泥腿AI智能体验中心 方案二:泥腿AI智能养殖体验中心 方案三:泥腿5S养殖服务中心 方案四:泥腿智能养殖...

  • 服务注册中心架构演进

    1. 概述 服务注册中心(下称注册中心)是微服务架构非常重要的一个组件,在微服务架构里主要起到了协调者的一个作用。...

  • Spring Cloud

    一、Spring Cloud架构与组件 EureKa Server: 服务注册中心和服务发现中心。 二、Sprin...

  • springBoot和springCloud关系

    SpringCloud,基于SpringBoot提供了一套微服务解决方案, 包括服务注册与发现,配置中心,全链路监...

  • 一、Dubbo框架源码分析:为什么要有dubbo?

    一、背景:架构的演进,微服务的盛行 随着微服务的盛行-服务拆分:那么跨服务间调用如何解决?每个公司有自己解决方案...

  • 服务发现:服务注册中心

    背景 服务的客户端采用客户端服务发现或者服务端服务发现来确定发送请求的实例地址。 问题 客户端服务发现 里的客户端...

  • 详解Spring Cloud Eureka多网卡配置总结

    在linux主机部署Eureka高可用方案的时候,发现注册到服务中心的服务IP是随机的,由于主机的网卡是多个,随机...

网友评论

      本文标题:服务发现中心方案演进(二)

      本文链接:https://www.haomeiwen.com/subject/pxnnuftx.html