Martian-cloud 4.0.2, 丢弃心跳机制,解决网络压力问题

2020-11-14 15:00:25 +08:00
 Joker123456789

首先,有人可能对 Martian-cloud 不了解,甚至是第一次听说,所以有兴趣的朋友可以先看下详细的原理

https://www.bilibili.com/read/cv8314554

好了下面切入主题,本次升级,所解决的问题正如标题所说,通过丢弃心跳机制,来解决网络压力

网络压力主要来自两个方面

  1. 定时随机去别的服务拉取一次接口,并将自己的接口广播出去
  2. 发送心跳包

第一个点,仔细计算下来,其实并没太大的压力,原因如下:

首先,定时随机去别的服务拉取一次接口,这个是每个服务只会随机向一个服务发送拉取请求,也就是这个行为在整个一套微服务中可以产生的最大请求数为 N,有几台服务就最多可以产生几个请求,而且这些请求很难会刚好都请求到一台服务器,并且频率为 3 秒,所以我个人认为,这是在可接受范围内的。

其次,将自己的接口广播出去,这个虽然是广播给自己已知的所有其他服务,但是播过一次的服务就不会再播了,随着时间的累计,这个行为最终会停止,不再发起广播,而且这个过程很快。

那么,网络压力的大头,主要来自第二个点

第二个点,怎么解决呢?我思考了好几天,脑袋都大了,还是没想出解决方案。

后来心一横,干脆不要心跳了,但是不要心跳的话,服务下线了怎么通知其他服务啊? 这就是今天要分享的内容。

心跳机制丢弃后如何实现下线通知

首先这个做法 只能保证每个服务本地的接口缓存数据 的最终一致性,而不是实时的,但是这并不是分布式存储,所以无伤大雅。

还有一点,可能会影响一些性能,这个性能的牺牲,能不能被接受,就要看具体的场景了。

一、首先是自私机制

所谓的自私机制,就是每个服务只顾自己,不管别人,每个服务如果发现自己本地缓存的接口连接不上,那就会从本地把他下掉,至于别人,他是不管的。

二、 投票机制(最大票数可配置)

这是每个服务的内部投票,跟外面无关,如果一个服务发现他本地缓存的某个接口连接不上,那么他就会给这个接口指向的服务投一票,让它从本机下线,当调通后会把票数清 0,当票数积累到一定程度时,这个服务的所有接口都会被从当前服务上清理掉。 [每个服务都有一套这样的机制,来维护自己的本地接口缓存]

三、 如果(下线某个服务的决定)是误判怎么办

有一个补偿机制,就是每个服务在下掉别的服务的时候,都会给被下掉的那个服务发一个通知,让他把自己从已广播列表中移除(比如 A 服务调不通 B 服务的接口,当票数累积到一定程度后,A 会把 B 的接口全部清理掉,清理后 A 会给 B 发一个通知,让 B 把 A 从已广播列表移除,这样如果 B 服务没挂,那么 B 在下一次轮询时 会把接口重新广播给 A )

如果 B 服务明明没挂,但是 A 服务连续调不通,而且连下线通知都无法通知到 B 服务,那我只能说 B 服务活该了,即使是误判也比留着报错影响性能好吧。

四、 调不通的情况有很多,不一定是服务挂了,那么什么样的情况会给服务投下线票

很简单,当调用接口时,出现了以下三种异常,就会投票

五、 然后是垃圾回收机制

垃圾回收很简单,就是定时去本地缓存中扫描出被下线的服务的接口,然后删除掉。

上面这这一套机制,可以保证当服务宕机以后,接口会自动从其他的服上下线

官方网站

http://mars-framework.com/index.html

1548 次点击
所在节点    Java
2 条回复
teawithlife
2020-11-15 16:08:21 +08:00
问题是心跳包为什么会造成网络压力呢?

PS:“网络压力”这个词听着挺奇怪的。。。
Joker123456789
2020-11-15 21:00:26 +08:00
@teawithlife 你看完我的 原理应该就会明白了。

我这套设计是 没有注册中心的,在整个微服务中,每个服务都需要向其余的所有服务发送心跳包,所以,在某个时间段,心跳包的消息数量会达到 n*n 条。 一旦微服务的机器扩大变多,这个压力还是需要重视的。

注:网络压力指的是内网压力

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/725196

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX