首先,有人可能对 Martian-cloud 不了解,甚至是第一次听说,所以有兴趣的朋友可以先看下详细的原理
https://www.bilibili.com/read/cv8314554
好了下面切入主题,本次升级,所解决的问题正如标题所说,通过丢弃心跳机制,来解决网络压力
第一个点,仔细计算下来,其实并没太大的压力,原因如下:
首先,定时随机去别的服务拉取一次接口,这个是每个服务只会随机向一个服务发送拉取请求,也就是这个行为在整个一套微服务中可以产生的最大请求数为 N,有几台服务就最多可以产生几个请求,而且这些请求很难会刚好都请求到一台服务器,并且频率为 3 秒,所以我个人认为,这是在可接受范围内的。
其次,将自己的接口广播出去,这个虽然是广播给自己已知的所有其他服务,但是播过一次的服务就不会再播了,随着时间的累计,这个行为最终会停止,不再发起广播,而且这个过程很快。
那么,网络压力的大头,主要来自第二个点
第二个点,怎么解决呢?我思考了好几天,脑袋都大了,还是没想出解决方案。
后来心一横,干脆不要心跳了,但是不要心跳的话,服务下线了怎么通知其他服务啊? 这就是今天要分享的内容。
首先这个做法 只能保证每个服务本地的接口缓存数据 的最终一致性,而不是实时的,但是这并不是分布式存储,所以无伤大雅。
还有一点,可能会影响一些性能,这个性能的牺牲,能不能被接受,就要看具体的场景了。
所谓的自私机制,就是每个服务只顾自己,不管别人,每个服务如果发现自己本地缓存的接口连接不上,那就会从本地把他下掉,至于别人,他是不管的。
这是每个服务的内部投票,跟外面无关,如果一个服务发现他本地缓存的某个接口连接不上,那么他就会给这个接口指向的服务投一票,让它从本机下线,当调通后会把票数清 0,当票数积累到一定程度时,这个服务的所有接口都会被从当前服务上清理掉。 [每个服务都有一套这样的机制,来维护自己的本地接口缓存]
有一个补偿机制,就是每个服务在下掉别的服务的时候,都会给被下掉的那个服务发一个通知,让他把自己从已广播列表中移除(比如 A 服务调不通 B 服务的接口,当票数累积到一定程度后,A 会把 B 的接口全部清理掉,清理后 A 会给 B 发一个通知,让 B 把 A 从已广播列表移除,这样如果 B 服务没挂,那么 B 在下一次轮询时 会把接口重新广播给 A )
如果 B 服务明明没挂,但是 A 服务连续调不通,而且连下线通知都无法通知到 B 服务,那我只能说 B 服务活该了,即使是误判也比留着报错影响性能好吧。
很简单,当调用接口时,出现了以下三种异常,就会投票
垃圾回收很简单,就是定时去本地缓存中扫描出被下线的服务的接口,然后删除掉。
上面这这一套机制,可以保证当服务宕机以后,接口会自动从其他的服上下线
1
teawithlife 2020-11-15 16:08:21 +08:00
问题是心跳包为什么会造成网络压力呢?
PS:“网络压力”这个词听着挺奇怪的。。。 |
2
Joker123456789 OP @teawithlife 你看完我的 原理应该就会明白了。
我这套设计是 没有注册中心的,在整个微服务中,每个服务都需要向其余的所有服务发送心跳包,所以,在某个时间段,心跳包的消息数量会达到 n*n 条。 一旦微服务的机器扩大变多,这个压力还是需要重视的。 注:网络压力指的是内网压力 |