• Nacos与Eureka中的高性能读写并发架构设计


    Nacos、Eureka都是微服务领域内熟知、常用的注册中心组件。只不过呢,Nacos还多了个功能身份就是配置中心。从目前流行与随着Spring Cloud Alibaba发展来看,Nacos使用得更加多,也是趋势所在。

    注册中心原理

    注册中心原理其实很简单,基本思想都是差不多的。就是生产者客户端在启动时,将当前服务实例信息封装上报给服务端。服务端进行解析处理存起来。这里的存储可以是在内存存储,也可以持久化存储(文件、数据库都行)。生产者与服务端维持心跳,达到服务健康状态检查。最后消费者客户端从服务端拉取服务信息。从而达到服务的注册与发现效果。网络通信这块可以用netty 也可以用http来做。最好netty性能会更加好些。

    一个好的注册中心必须要有很好的读写并发性能,不然在成千上万的服务,再加之服务集群部署时,注册中心怎么扛得住?

    读写并发问题

    注册中心的注册表的服务实例信息,会随着生产者的改变发生操作,而消费者会从注册中心拉取注册表信息,这是操作。当读写同时进行时,就会产生读写并发问题了。常见的解决方案有:

    • 加悲观锁同步。这种性能太差了,不推荐。如果加锁粒度比较小,还能凑合下。
    • 加读写锁。这种性能是比上一种方案好,但是一旦需要扯上锁,永远快不到哪里去。
    • COW 写时复制。这个技术不错,没有锁介入。写时复制一份副本出来操作,读操作还是操作原始数据。Redis的在bgsave 主从数据复制时,主实例继续接受处理指令,而数据又能同时复制传输,用到的技术就是这个COW写时复制。

    接下来我们细细了解Nacos与Eureka的在架构设计是如何提高其读写并发性能的

    Nacos读写并发架构设计

    Nacos客户端在向服务端注册时,将注册信息封装成instance对象,服务端接受后,存入一个内部阻塞队列,就返回成功响应给客户端完成注册了。这样可以极大提高客户端的注册速度以及启动速度,不会对客户端所属服务带来影响。

    Nacos服务端起了一个只有一个线程的线程池定时调度执行一个任务,那就是异步从阻塞队列里拉取注册信息进行处理,完成注册信息的注册。在注册时,是利用COW写时复制,拷贝一个副本出来进行写处理,之后再回写回原注册表,来提高读写并发性能。

    还有一个亮点就是 ,我们都知道 这么多服务集群实例,肯定会存在多个同时写并发问题,难道一个实例要完成写入注册,就COW拷贝一份,那这么多实例节点,Nacos服务端怎么能够扛得住呢?

    显然Nacos设计者考虑到了这一点,阿里中间件设计有这么一句话,解决问题的最好办法不是去解决他,而是规避他。所以Nacos在实现上,并没有去花精力在怎么解决同时写并发问题,而是选择了直接一个线程池里只有一个线程去解决处理。这样单个线程从阻塞队列里拉取一个处理一个。因为都是基于内存操作,这个处理速度是相当快的。所以不用担心一个线程消费能不能跟得上的问题。

    但是这样设计也不是十全十美,会存在一个问题 :虽然提高了Nacos注册表读写性能,但是也带来客户端(消费者)拉取到的注册表信息不是最实时或者说不是最新的。但是由于客户端会定时向Nacos拉取注册表信息,可以解决这个问题。顶多就是服务没那么及时被发现,并不影响整个系统的可用性。

    Nacos原理

    Eureka读写并发架构设计

    Eureka读写并发架构设计比较简单暴力,它是利用多级缓存来提高读写并发性能的。Eureka里的服务注册表发生变更时,同步readwrite缓存时,不是做相应条目的变更更新,而是直接把readwrite缓存清空。这点跟我们平时做业务缓存架构比较像,不去比较条目变更更新,而是直接清空它这个缓存。这样后台线程判断比较readwrite缓存与readonly缓存不一致时,就会同步更新空的给readonly缓存。这样客户端拉取时,发现readonly缓存也为空,就会从服务注册表拉取内容,再填充给这两个缓存。

    但是带来的弊端也是比较明显,那就是Eureka一直被吐槽的 服务发现太慢,太不及时了!检查同步都是30秒级别,三个一加就得1分半钟。所以Eureka部署时必须得调优,调低检查时间。但是调太低了 又会导致线程检查过于频繁,浪费CPU。要是注册表没啥变动情况下,就是“徒劳”在那里检查个寂寞。

    在这里插入图片描述

    好了 ,本文也要结束啦~ Nacos与Eureka读写并发设计上,都是抛弃了锁来实现的。两者各有千秋,都是优秀的,都是值得我们学习的架构思想。

  • 相关阅读:
    android 13/14高版本SurfaceFlinger出现VSYNC-app/VSYNC-appSf/VSYNC-sf剖析
    Android桌面回到应用 重新打开 android.intent.action.MAIN 的界面
    模式识别与图像处理课程实验二:基于UNet的目标检测网络
    框架安全-CVE 复现&Spring&Struts&Laravel&ThinkPHP漏洞复现
    dart系列之:集合使用最佳实践
    Multicycle Path
    CMD内存定位文件-2
    std : : vector
    Buffer I/0 error on dev dm-2, logical block 138823488, async page read CCSSDN
    Dom对象总结案例实操(第二十课)
  • 原文地址:https://blog.csdn.net/China_eboy/article/details/128020918