首次注册
假如有服务B有分布式两台(192.168.31.107:8080)、(192.168.31.121:8080),就会选与到服务注册表, 同时立马同步写缓存。这时,不会立刻到同步到读缓存,当服务A每隔一段时间进行服务发现时,这时读的缓存是空的,再会从写缓存同步过去。
再增加一台服务器
比如再增加一台服务B(192.168.31.121:8080),这时读缓存还是旧的,这时,在写缓存会有一个线程,定时对比写缓存和读缓存的数据,进行定时同步,这样服务A再次拉取时,数据就全了。
停一台服务器
每台注册的服务都有心跳机制,如果长沙时间无法感知,服务注册表就会删除这台服务,比如(192.168.31.121:8080),然后操作同步时,发现数据不一致,就会清空所有数据。这时写缓存的线程会同步读缓存,发现数据不一样,也会清空读缓存。然后服务A再次拉取时,发现读的缓存没有数据,再取写的缓存,写的缓存没有数据,就把当前最新的注册表同步过来。
再新增一台服务器
比如再重启刚停了的服务B(192.168.31.121:8080),这时服务注册表变动了,加上了这服务,这时写缓存和注册表数据不一样,同步时就会清空写缓存, 当写缓存的同步线程每隔30秒,同步读缓存时,因写缓存数据空了,和写缓存数据不一样,读缓存数据也会被清空。服务A再次拉取时,发现读写缓存没数据时,就会同步最新的注册表。
为什么要弄读缓存和写缓存二级缓存呢
这样是为了避免服务注册表示繁忙,都在一个地方进行读写,就如同mysql读写分离。同时,读的操作和写的操作隔离开,避免了并发锁的冲突。 也就是只有一个注册表的话,在读的时候要加锁,在读的时候不能写;写的时候也要加锁,在写的时候不能读。大量的并发冲突会影响性能。
但用了上面二级缓存,因为服务A基本上只会用到读的级存,写的线程可能几十秒才发会对读缓存发启一次写,只有在写的时候服务A才不会来读,这里写的频率是很低很低的。