极客时间已完结课程限时免费阅读

阿忠伯的特别放送 | 答疑解惑02

阿忠伯的特别放送 | 答疑解惑02-极客时间

阿忠伯的特别放送 | 答疑解惑02

讲述:胡忠想

时长10:51大小9.92M

你好,我是胡忠想。今天我继续来给同学们做答疑,第二期答疑主要涉及微服务架构、注册中心和负载均衡算法,需要一定的基础,如果对这些内容不了解,可以先返回专栏第 14 期第 17 期第 18 期复习一下。
专栏里我主要讲的是基于 RPC 通信的微服务架构,除此之外还有一种微服务架构是基于 MQ 消息队列通信的,下面我就从这两种架构不同的适用场景来给你讲讲它们的区别。
基于 RPC 通信的微服务架构,其特点是一个服务依赖于其他服务返回的结果,只有依赖服务执行成功并返回后,这个服务才算调用成功。这种架构适用于用户请求是读请求的情况,就像下图所描述的那样,比如微博用户的一次 Feed API 请求,会调用 Feed RPC 获取关注人微博,调用 Card RPC 获取微博中的视频、文章等多媒体卡片信息,还会调用 User RPC 获取关注人的昵称和粉丝数等个人详细信息,只有在这些信息都获取成功后,这次用户的 Feed API 请求才算调用成功。
而基于 MQ 消息队列通信的架构,其特点是服务之间的交互是通过消息发布与订阅的方式来完成的,一个服务往 MQ 消息队列发布消息,其他服务从 MQ 消息队列订阅消息并处理,发布消息的服务并不等待订阅消息服务处理的结果,而是直接返回调用成功。这种架构适用于用户请求是写请求的情况,就像下图所描述的那样,比如用户的写请求,无论是发博、评论还是赞都会首先调用 Feed API,然后 Feed API 将用户的写请求消息发布到 MQ 中,然后就返回给用户请求成功。如果是发博请求,发博服务就会从 MQ 中订阅到这条消息,然后更新用户发博列表的缓存和数据库;如果是评论请求,评论服务就会从 MQ 中订阅到这条消息,然后更新用户发出评论的缓存和数据库,以及评论对象收到评论的缓存和数据库;如果是赞请求,赞服务就会从 MQ 中订阅到这条消息,然后更新用户发出赞的缓存和数据库,以及赞对象收到的赞的缓存和数据库。这样设计的话,就把写请求的返回与具体执行请求的服务进行解耦,给用户的体验是写请求已经执行成功,不需要等待具体业务逻辑执行完成。
总结一下就是,基于 RPC 通信和基于 MQ 消息队列通信的方式都可以实现微服务的拆分,两者的使用场景不同,RPC 主要用于用户读请求的情况,MQ 主要用于用户写请求的情况。对于大部分互联网业务来说,读请求要远远大于写请求,所以针对读请求的基于 RPC 通信的微服务架构的讨论也更多一些,但并不代表基于 MQ 消息队列不能实现,而是要区分开它们不同的应用场景。
要回答上面这三个问题,需要我来详细讲讲微博在使用注册中心时遇到的各种问题以及解决方案,主要包括三部分内容。
1. 心跳开关保护机制。在专栏第 17 期,我讲过心跳开关保护机制是为了防止网络频繁抖动时,引起服务提供者节点心跳上报失败,从而导致注册中心中可用节点不断变化,使得大量服务消费者同时去请求注册中心获取最新的服务提供者节点列表,把注册中心的带宽占满。为了减缓注册中心带宽的占用,一个解决方案是,只给其中 1/10 的服务消费者返回最新的服务提供者节点列表信息,这样注册中心带宽就能减少到原来的 1/10。在具体实践时,我们每次随机取 10%,所以对于任意服务消费者来说,获取到最新服务提供者节点列表信息的时刻都是不固定的。在我的实践过程中,对于一个拥有上千个服务消费者的服务来说,某个服务消费者可能长达半小时后仍然没有获取到最新的服务提供者节点列表信息。所以说这种机制是有一定缺陷的,尤其是在服务正常情况下,心跳开关应该是关闭的,只有在网络频繁抖动时才打开。当网络频繁抖动时,注册中心的带宽就会暴涨,可以轻松把千兆网卡的前端机带宽打满,此时监控到带宽被打满时,就应该立即开启心跳开关保护机制。
2. 服务节点摘除保护机制。设计心跳开关保护机制的目的,就是为了应对网络频繁抖动时引起的服务提供者节点心跳上报失败的情况。这个时候,注册中心会大量摘除服务提供者节点,从而引起服务提供者节点信息的变化。但其实大部分服务提供者节点本来是正常的,注册中心大量摘除服务提供者节点的情况是不应该发生的,所以可以设置一个服务节点摘除的保护机制,比如设置一个上限 20%,正常情况下也不会有 20% 的服务节点被摘除,这样的话即使网络频繁抖动,也不会有大量节点信息变更,此时就不会出现大量服务消费者同时请求注册中心获取最新的服务提供者节点列表,进而把注册中心的带宽给占满。但这个机制也有一个缺陷,就是一些异常的节点即使心跳汇报异常应该被摘除,但也会因为摘除保护机制的原因没有从服务的可用节点列表中去掉,因此可能会影响线上服务。
3. 静态注册中心机制。心跳开关保护机制和服务节点摘除保护机制都是治标不治本的权宜之计,不能根本解决网络频繁抖动情况下,引起的注册中心可用服务节点列表不准确的问题。所以我们提出了静态注册中心的机制,也就是注册中心中保存的服务节点列表只作为服务消费者的参考依据,在每个服务消费者这一端都维护着各自的可用服务节点列表,是否把某个服务节点标记为不可用,完全取决于每个服务消费者自身调用某个服务节点是否正常。如果连续调用超过一定的次数都不正常,就可以把这个服务节点在内存中标记为不可用状态,从可用服务节点列表中剔除。同时每个服务消费者还都有一个异步线程,始终在探测不可用的服务节点列表中的节点是否恢复正常,如果恢复正常的话就可以把这个节点重新加入到可用服务节点列表中去。
当然服务消费者也不是完全不与注册中心打交道,在服务启动时,服务消费者还是需要去注册中心中拉取所订阅的服务提供者节点列表信息,并且服务消费者还有一个异步线程,每隔一段时间都会去请求注册中心以查询服务提供者节点列表信息是否有变更,如果有变更就会请求注册中心获取最新的服务提供者节点列表信息。所以在有节点需要上下线时,服务消费者仍然能够拿到最新的服务提供者节点列表信息,只不过这个节点上下线的操作,一般是由开发或者运维人员人工操作,而不是像动态注册中心那样,可以通过心跳机制自动操作。
关于最少活跃连接算法和自适应最优选择算法,它们的含义你可以返回专栏第 18 期回顾一下,本质上这两种算法都可以理解为局部最优解。
首先来看最少活跃连接算法,当客户端的请求发往某个服务端节点时,就给客户端同这个服务端节点的连接数加一;当某个服务端节点返回请求结果后,就给客户端同这个服务端节点的连接数减一,客户端会在本地内存中维护着同服务端每个节点的连接计数。从理论上讲,服务端节点性能越好,处理请求就快,同一时刻客户端同服务端节点之间保持的连接就越少,所以客户端每次请求选择服务端节点时,都会选择与客户端保持连接数最少的服务端节点,所以叫作“最少活跃连接算法”。但最少活跃连接算法会导致服务端节点的请求分布不均,我曾经在实践中见过一种极端情况,当服务端节点性能差异较大时,性能较好的节点的请求数量甚至达到了性能较差的节点请求数量的两倍。出现这种情况,一方面会导致某些服务端节点不能被充分利用,另一方面可能会导致请求量过高的服务端节点无法应对突发增长的流量而被压垮。
再来看下自适应最优选择算法,一方面客户端发往服务端节点每一次调用的耗时都会被记录到本地内存中,并且每隔一分钟计算客户端同服务端每个节点之间调用的平均响应时间,并在下一次调用的时候选择平均响应时间最快的节点。显然这样是收益最大的,尤其是服务跨多个数据中心部署的时候,同一个数据中心内的调用性能往往要优于跨数据中心的调用;另一方面客户端并不是每一次都选择平均响应时间最快的节点发起调用,为了防止出现类似最少活跃连接算法中服务端节点请求量差异太大的情况发生,把服务端节点按照平均响应时间进行排序,找出最差的 20% 的节点并适当降低调用权重,从而达到有效减少长尾请求的目的。
欢迎你在留言区写下自己学习、实践微服务的心得和体会,与我和其他同学一起讨论。你也可以点击“请朋友读”,把今天的内容分享给好友,或许这篇文章可以帮到他。
分享给需要的人,Ta购买本课程,你将得18
生成海报并分享

赞 2

提建议

上一篇
阿忠伯的特别放送 | 答疑解惑01
下一篇
微博技术解密(上) | 微博信息流是如何实现的?
unpreview
 写留言

精选留言(8)

  • 0xTang
    2020-03-29
    Rpc同步,mq异步,使用场景不一样。
    4
  • Jarvis
    2019-09-14
    最后一个问题,最少连接算法里面,客户端是只根据自己和服务端的连接数来算的吧?不需要知道服务端同所有客户端的连接数
    共 1 条评论
    2
  • 2019-03-01
    老师你好,对于MQ的架构方案有一些疑问。 以您说的“如果是赞请求,赞服务就会从 MQ 中订阅到这条消息,然后更新用户发出赞的缓存和数据库,以及赞对象收到的赞的缓存和数据库”为例,如果是这种异步的方式,当用户在点赞的时候,恰巧碰到作者删除了文章。用户认为点赞成功(发送完请求就显示成功),但其实"点赞服务"是执行失败的。对于写请求引入MQ的方案又会带来补偿、回滚的问题,该如何权衡? 实际方案中,对于写请求,采用接口同步调用是否真的会带来很大的性能影响。
    展开
    共 1 条评论
    2
  • 惘 闻
    2021-01-29
    所以在有节点需要上下线时,服务消费者仍然能够拿到最新的服务提供者节点列表信息,只不过这个节点上下线的操作,一般是由开发或者运维人员人工操作,而不是像动态注册中心那样,可以通过心跳机制自动操作。 文中这最后一句话代表什么含义呀,难道通过心跳机制导致的注册中心节点上下线,服务消费者就拿不到最新列表了吗? 应该和手工操作一样都可以拿到吧.. 那为什么加个转折..看的我好郁闷
    展开
    1
  • arebya
    2018-12-26
    自适应最优选择算法就是所谓的WeightedResponseTimeRule
    1
  • 小杨
    2022-10-22 来自北京
    这篇评论这么少
  • 信信
    2020-06-07
    请求量分布不匀,会引起长尾效应?耗时分布不匀才会引起长尾效应啊。。。 请求分布在上一段描述是由连接数决定的,是为了平衡响应时间吧?
  • 2019-06-16
    嗯,赞👍