0%

复习项目难点:

2020年5月12日 下午10:15

单点登录的进化

本质是一个验证问题

  1. Client - 单服务器
    1. 方案一:每次都用username password到数据库中进行验证
    2. 方案二:使用SessionID作为验证的已登录用户的方法,client和server端有共同的ID,client保存在cookie中,server保存在tomcat的缓存中,一旦tomcat重启,那么缓存就消失了,我们必须做持久化到硬盘才可以
    3. 方案三:使用redis作为这个持久化的地方,解决重启需要重新验证的问题
  2. Client - 多服务器
    1. 方案一:跟上面一致
    2. 方案二:那么多台服务器之间无法共享登录状态,其实就是无法共享tomcat私有的sessionID
    3. 方案三:不仅解决了单服务器重启的问题,也做到了SessionID多服务器之间的共享
  3. Client - 多服务器 — redis集群
    1. 什么场景下缓存一致性:
      1. 主要考虑的是redis集群扩展的情况下,如何保证仍然有较高的缓存命中率的问题。也就是说本质问题是:缓存命中率的问题
    2. 一致性hash有哪些问题,如何解决:
      1. hash倾斜性:由于hash的倾斜,会导致hash结果分布不均匀
      2. 什么是hash倾斜性?
        1. 首先我们一致性哈希中有两个过程:
          1. 第一步:正常的hash操作,得到一个hash结果
          2. 第二步:数据的hash向redis的hash在环上进行靠拢
        2. 如果数据的hash和redis的hash结果在环上分布“不搭”,eg:数据hash密集的地方,redis的hash不密集。靠拢之后的结果就会倾斜
      3. 解决方法:
        1. 我们有一个直观的感受:如果redis越多,那么在环上的分布就越有可能均匀。
        2. 那么,我们就假设出更多的虚拟redis节点。然后再将虚拟节点二次hash到实在的redis节点中,注意这次的hash是直接hash到实在的redis节点,而没有了“靠拢”这一步骤。
        3. 二次hash就是最最普通的hash,反而不容器造成hash的倾斜性

什么场景下需要分布式锁

  1. 本质问题:对有限资源(仅一个)的争抢下,如何确定第一个获得者
    1. 这其中需要设计两个:
      1. 争抢时:需要设计一个游戏规则,争抢的人都遵守这个游戏规则
      2. 争抢完之后:需要设计一个条件,能区分出第一名和其他人。
    2. 一个好的锁条件 + 游戏规则 设计需要保证:有且只有一个被筛选出来
      1. 必须有,不能一个都没有
      2. 有,但只能有一个
  2. 我们虽然很难设计出这样一个锁条件,但是我们反过来验证一下是否满足有且只有一个:
    1. 我们可以想象一个图
    2. 我觉得这个问题本质和编程无关,更像是一道中学数学逻辑题:
      1. 问:你是否能够设计一个游戏规则,保证在资源争抢的时候,有且只有一个人获得资源
      2. 也就是说,所有参与游戏的人都遵循一套规则,并没有暗箱操作,就可以保证唯一性,这个游戏规则在并发的时候,会出现相互的制约,从而保证的结果的正确,也只有并发的时候才会体现出来
    3. 分析这种游戏规则的方法:就如图中所示的一样,在一条时间线上,我们假设一个人已经获得了锁,此时我们枚举出所有的可能情况,看是否能找到第二人再次获得锁,如果我们再所有的情况中都无法获得锁,那么说明这个规则有效。

架构思维:对问题的本质进行认识,做到举一反三

涉及到的java语法知识:

  1. 什么场景下需要static
    1. 场景一:在服务启动时,就默认初始化好redis的连接池
    2. 场景二:在使用的时候,不用声明对象,直接通过类来使用
  2. 什么场景下需要,多态,强制类型转换
  3. 什么场景下需要泛型
    1. 场景一:在对象序列化的时候,序列化函数的接口就需要满足各种类型进行序列化的要求,甚至在嵌套类型list中使用<?>,当代码中不使用这个类型的时候,可以指定为?,对于多类型的话,可以使用变长参数。