最开始我们是打算用mysql来实现的。
考虑原因:
服务的上下线是一个比较低频率的事情,mysql的qps应付这点qps完全没问题
mysql还能持久化,多机房也容易保障。
方案整体架构:
image.png方案描述:
- service结点通过rest接口,定时(5s)向Luna server重新注册
- server在本地维护每个服务的结点存活结点列表;每隔1S拉取有变更的服务列表,并将本地缓存invalid
- server通过定时任务,清除过期的service结点(超过15S未上报)
方案就这么简单的做完了。是不是有点太简单的感觉,我擦,人家zookeeper那么复杂的一套系统,你就这么轻易的实现了。。
那我们来考虑一些细节问题:
问题一: 定时任务具体怎么做, 多台server是不要同时去做定时任务的。
办法:每台server都做一个定时任务,每分钟的第0,5,10,15,20,25,30,35,40,45,50,55秒执行,把当前时间转化为一个key:比如2018-5-17 18:30:05秒,可以用201805-17-18-30-5来表示,执行开始前,先往数据库插入一条key=201805-17-18-30-5的记录,如果插入失败(记录存在),则表示己由其它任务执行,否则自己执行。用数据库保证了任务执行的唯一性。
问:抢到了任务,但是没有执行server就挂了,这种情况怎么办
答:5秒后还是有下一个定时任务的,还是会执行的。
问:这样能保证不会出现并发执行吗
答:并不能,某次执行时长超过5s就会出现并发执行了。所以还是要用数据库的事务保证并发的执行安全。
问题二:定时任务发现节点失效,把服务下线,但是这个时候正好有服务上线,会不会出问题:
办法:这真的是个好问题,不过mysql有事务,不怕。
所以这就是最后采用的方案了吗?
并不是啊,对于qps的计算,我们太过于乐观:
1000个域,每个域10个服务,每个服务10台机器,每5秒一个心跳,
1000x10x10/5=2万,每秒2万的写请求对于mysql来说压力非常大了。
一台mysql按照2000来算,至少要10台,再加10台slave机器,就是20台机器了。
而且肯定是要分库分表了。
突然感觉简单的事情一点也不简单了。
网友评论