并发编程-注册中心

 

注册中心核心就是两大功能

  • 服务注册与发现
  • 心跳与故障检测

 

bdc5978cc71d46b6ae0dc1ef6dfba198.png

c1ea035744234a8fa9da75a846bb275e.png 

为什么要弄两级缓存?

这个和MySQL用主从做读写分离很相似,数据库层面的读写分离是为了分摊主数据库的读压力;而Eureka的两级缓存也是为了做读写分离,使写操作不阻塞读操作

因为在写的时候,线程会持有ConcurrentHashmap相应Hash桶节点对象的锁,阻塞同一个Hash桶的其他读线程。
这样可以有效的降低对注册表的读写并发,避免读写读写争抢资源所带来的压力

如果是jdk1.7的ConcurrentHashmap实现,不是每个Hash桶节点对象一把锁,而是默认16个分段,那么并发读写时,锁争抢会更加明显一些

 

加了那么多缓存,如何保证缓存数据的最终一致性?

实际可能大部分都是在读ReadOnly缓存,后台线程每隔30s才会比对一次ReadWrite缓存和ReadOnly缓存,不一致才会修改ReadOnly缓存,修改ReadOnly缓存时才会不允许客户端读ReadOnly缓存

 

 

 

微服务的注册表定时拉取机制实现

核心就是有一个RegisterClient内部会起一个HeartbeatWorker线程,负责每隔30s往注册中心推送一次心跳、 内部会起一个后台线程,通过sleep 30s的方式,每30s去注册中心拉取一次注册表

 

基于synchronized解决注册表的并发读写问题

注册表的双层Map结构

三个场景

  • 每个服务会将自己注册给注册中心的注册表
  • 注册中心自己的微服务存活状态监控线程会扫描注册表,并剔除没有续约的服务
  • 消费者会定时从注册表拉取注册数据

当前的解决方案就是,给前两个场景都加上synchronized,

缺点,服务启动大量服务同时来注册时,可能会影响性能

 

HashMap线程不安全的原因

Java8中已经不再采用头插法,改为尾插法,即直接插入链表尾部,因此不会出现死循环和数据丢失,但是在多线程环境下仍然会有数据覆盖的问题

d0b06ec7a4204e7191060018203c72cc.png

注意红色框内的部分,如果插入元素没有发生hash碰撞则直接插入。

如果线程A和线程B同时进行put,刚好两条数据的hash值相同,如果线程A已经判断该位置数据为null,此时被挂起,线程B正常执行,并且正常插入数据,随后线程A继续执行就会将线程A的数据给覆盖。发生线程不安全。

 

HashMap 之所以存在线程安全性问题,本质上是因为 HashMap 的"增删改"操作均是多步操作的集合,或者说是非原子的。

在多线程环境下,非原子的操作可能因为线程调度的问题,引发各种线程不安全性问题。以 put() 方法为例:

public V put(K key, V value) {
    if (table == EMPTY_TABLE) {
        inflateTable(threshold);
    }
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key);
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

 

无论是 mod++,还是 addEntry() 操作,均是非原子的操作

 

 

 

微服务注册中心的自我保护机制

adb7ce85a78141a8b09ac7dbd4613c8c.png

8267684db9da47608fcdb3d9600af21a.png 

 

基于synchronized实现的统计每分钟内心跳次数的计数器

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值