V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Joker123456789
V2EX  ›  Java

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

  •  1
     
  •   Joker123456789 · 2020-11-14 15:00:25 +08:00 · 1401 次点击
    这是一个创建于 1260 天前的主题,其中的信息可能已经有所发展或是发生改变。

    首先,有人可能对 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 服务活该了,即使是误判也比留着报错影响性能好吧。

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

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

    • ConnectException,连接不上,这不是 404 之类的,而是根本连不上这个 ip:port
    • UnknownHostException,无法解析地址,提供的 ip:port 无法被解析识别
    • SocketTimeoutException,连接超时,不是 read time out,而是 connect time out

    五、 然后是垃圾回收机制

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

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

    官方网站

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

    2 条回复    2020-11-15 21:00:26 +08:00
    teawithlife
        1
    teawithlife  
       2020-11-15 16:08:21 +08:00
    问题是心跳包为什么会造成网络压力呢?

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

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

    注:网络压力指的是内网压力
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1286 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 17:42 · PVG 01:42 · LAX 10:42 · JFK 13:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.