一.数据库主从延迟
目前,做了一个登陆系统,数据库采用主从复制,偶尔会存在注册用户后,用户登陆却不存在,这是因为登陆的时候是从读库中去读取的数据,然而数据同步还没到位,因此我采用的方案是:
(1)在注册的时候将该条数据放入redis当中(需要注意的是,用户的登陆方式有几种,就需要把几种唯一标识符都放入进去,例如,手机,微信,qq等)。
(2)在登陆的时候,先从缓存当中读取,如果还是没有的话,就可以通知客服了。
二.缓存与数据库一致性问题。
先提问吧。假设现在有两个线程:线程A,读线程,已经读出数据,在set缓存的时候被挂起。线程B,写线程,这时候已经写入数据,然后进行缓存操作(可以删除,可以写入),当B执行完毕以后才会执行A。
那这个时候如果B选择删除,那么A就会写入缓存当中,这个时候缓存里面其实是脏数据,因此这种方式我认为不太合适。
那么就采用B写入缓存的方式,这样的原因就在于读线程A,在读缓存和写缓存不是一个同步操作,因此可以考虑把线程A的读写数据放入一个同步操作里面,例如redis的lua脚本if(get key ==null) set key value这样的形式即可
三.服务降级
springCloud并没有相关组件作为降级服务的提供,因此需要自己写一个相关组件,因此我考虑的方案:
(1)通过一个注解@Annotation(score=分数,method=降级的方法,exception=降级异常,ignoreException=降级忽略的异常)
(2)通过AOP调用,当降级服务关闭的时候,不操作。当断路器打开的时候,对比系统给的分数,如果小于就进入服务降级。
(3)当有method的时候,调用method方法,并把参数传递,忽略其中ignoreException。
(4)当没有method的时候直接抛出exception。
其中比较注意的一些问题:
(1)服务降级的分数和打开关闭如何传送到每个服务当中。可以利用MQ来实现监听事件,也可以利用http接口来监听事件
(2)该组件应该需要一个http接口来展示自己的开关的信息。
(3)当用户没有声明抛出异常的时候,组件需要自己说明会抛出什么异常。这点需要写在注解上