zoukankan      html  css  js  c++  java
  • 谈谈业务中使用分布式的场景.

    1. 谈谈业务中使用分布式的场景.

    首先, 需要连接系统为什么使用分布式.
    随着互联网的发展, 传统的单体项目的性能瓶颈越发凸显, 性能瓶颈可能存在于一下几个方面:

    • 应用服务层: 随着用户量的增加, 并发量增加, 单体项目难以承受如此之大的并发请求导致的性能瓶颈.
    • 底层数据库层: 随着业务的发展, 数据库的压力也越来越大, 导致的性能瓶颈.

    场景1: 应用系统集群的Session共享.

    应用系统集群最简单的就是服务器集群, 比如: Tomcat集群. 应用系统集群的时候, 比较凸显问题的就是Session共享, Session共享我们一是可以通过服务器插件去解决, 另一种也可以通过Redis等中间件解决( 一般采用Redis中间件, 使用服务器插件复制的话 将Session实时同步到每一个服务器上, 这样只能支持Session数量比较少的情况, 使用Redis中间件存储的话, 性能比较高, 而且稳定性也更好. ).

    场景2: 应用系统的服务拆分.

    服务化拆分, 是目前比较火热的一种方式. 现在都在说微服务. 通过对传统项目进行服务化拆分, 达到服务独立解耦, 单服务又可以横向扩容. 服务化拆分遇到的经典问题就是分布式事务问题. 目前, 比较常用的分布式事务解决方案有几种: 消息最终一致性, TCC补偿性事务等.

    场景3: 底层数据库的压力分摊

    如果系统的性能压力出现在数据库我们就可以采用读写分离, 分库分表等方案进行解决.

    2. Session分布式方案

    这里只介绍常用的两种.

    2.1 基于Cookie的Session共享

    将用户的session加密序列化之后, 以Cookie的方式保存在网站的根域名之下, 当用户访问所有二级域名的时候, 留恋其会传递所有匹配的根域名的Cookie信息, 这样实现了用户Cookie化Session的多服务共享. 此方案能够节省大量的服务器资源, 缺点是存储的信息长度将会受到http协议限制, 而且一个站点只能保存大约20条Cookie, 而且每次请求的时候都会带上session, 这样的话会造成一定的网络带宽浪费.

    2.2 基于Redis的Session共享存储

    这些键值对非关系型数据库有较高的性能, 可以轻松打到2000qps, 内置的过期机制正好满足Session的时效性特征.

    在单独的服务器或者是服务器集群上使用缓存技术, 使用Redis存储Session数据, 几种管理所有的Session, Redis可以做高可用集群, 所有的Web服务器都从这个存储介质中读取相应的Session, 实现Session共享.

    • 优点: 可靠性高, 在遇到性能瓶颈的时候可以横向扩展.
    • 缺点: 实现略微复杂.
    • 适用场景: Web服务器比较多, 可用性要求很高的状态.
    • 可用方案: 开源方案Spring Session, 也可以自己实现.

    3. 分布式锁的场景和实现.

    使用场景

    首先, 我们看这样一个场景, 客户下单的时候, 我们调用库存中心进行减库存, 那么我们的一般操作就是;

    update store set num=${num} where id = ${id} 
    

    这种通过设置库存方式的修改, 我们知道在并发量比较高的时候回存在数据库的丢失更新, 如果A,B两个事物, 查询出来的库存都是5, a下了三个单子吧库存改为2, b下了一个单子将库存改为4, 这个时候出现了a回覆盖b的更新. 最终结果出现错误, 剩余库存为2.

    这个时候我们需要采取CAS乐观锁去解决这个问题.
    这里的CAS不需要考虑ABA问题, 因为即使这个时候加了库存, 中间发生了变化, 但是对于最终结果是不会产生影响的.

    update store set num = ${num} where id = ${id} and num = ${query_num}
    

    这个是只更新一个表, 如果牵扯到多个表呢, 我们希望和这个单子关联的所有的表同一时间只能被一个线程来处理更新, 多个线程按照不同的顺序去更新同一个单子关联的不同数据的时候, 出现死锁的概率比较大. 如果是分布式项目的话, 我们需要保证多线程多进程同时只能有一个进行的一个线程去处理, 这个时候我们就需要用到分布式锁. 分布式锁的实现方式有很多种, 我们今天分别通过,Zookeeper, Redis以及Tair的实现逻辑.

    Zookeeper实现

    获取锁

    1. 现有一个锁根节点, lockRootNode, 这可以是一个永久的根节点.
    2. 客户端获取锁, 现在lockRootNode下面创建一个顺序的瞬时节点, 保证客户端断开连接, 节点也自动删除.
    3. 调用lockRootNode父节点的getChildren()方法, 获取所有的根节点, 并从小到大排序, 如果创建的最小的节点是当前节点, 则返回true, 获取锁成功.
    4. 谈谈业务中使用分布式的场景.

    首先, 需要连接系统为什么使用分布式.
    随着互联网的发展, 传统的单体项目的性能瓶颈越发凸显, 性能瓶颈可能存在于一下几个方面:

    应用服务层: 随着用户量的增加, 并发量增加, 单体项目难以承受如此之大的并发请求导致的性能瓶颈.
    底层数据库层: 随着业务的发展, 数据库的压力也越来越大, 导致的性能瓶颈.
    场景1: 应用系统集群的Session共享.

    应用系统集群最简单的就是服务器集群, 比如: Tomcat集群. 应用系统集群的时候, 比较凸显问题的就是Session共享, Session共享我们一是可以通过服务器插件去解决, 另一种也可以通过Redis等中间件解决( 一般采用Redis中间件, 使用服务器插件复制的话 将Session实时同步到每一个服务器上, 这样只能支持Session数量比较少的情况, 使用Redis中间件存储的话, 性能比较高, 而且稳定性也更好. ).

    场景2: 应用系统的服务拆分.

    服务化拆分, 是目前比较火热的一种方式. 现在都在说微服务. 通过对传统项目进行服务化拆分, 达到服务独立解耦, 单服务又可以横向扩容. 服务化拆分遇到的经典问题就是分布式事务问题. 目前, 比较常用的分布式事务解决方案有几种: 消息最终一致性, TCC补偿性事务等.

    场景3: 底层数据库的压力分摊

    如果系统的性能压力出现在数据库我们就可以采用读写分离, 分库分表等方案进行解决.

    1. Session分布式方案

    这里只介绍常用的两种.

    2.1 基于Cookie的Session共享

    将用户的session加密序列化之后, 以Cookie的方式保存在网站的根域名之下, 当用户访问所有二级域名的时候, 留恋其会传递所有匹配的根域名的Cookie信息, 这样实现了用户Cookie化Session的多服务共享. 此方案能够节省大量的服务器资源, 缺点是存储的信息长度将会受到http协议限制, 而且一个站点只能保存大约20条Cookie, 而且每次请求的时候都会带上session, 这样的话会造成一定的网络带宽浪费.

    2.2 基于Redis的Session共享存储

    这些键值对非关系型数据库有较高的性能, 可以轻松打到2000qps, 内置的过期机制正好满足Session的时效性特征.

    在单独的服务器或者是服务器集群上使用缓存技术, 使用Redis存储Session数据, 几种管理所有的Session, Redis可以做高可用集群, 所有的Web服务器都从这个存储介质中读取相应的Session, 实现Session共享.

    优点: 可靠性高, 在遇到性能瓶颈的时候可以横向扩展.
    缺点: 实现略微复杂.
    适用场景: Web服务器比较多, 可用性要求很高的状态.
    可用方案: 开源方案Spring Session, 也可以自己实现.
    3. 分布式锁的场景和实现.

    使用场景

    首先, 我们看这样一个场景, 客户下单的时候, 我们调用库存中心进行减库存, 那么我们的一般操作就是;

    update store set num=${num} where id = ${id}
    这种通过设置库存方式的修改, 我们知道在并发量比较高的时候回存在数据库的丢失更新, 如果A,B两个事物, 查询出来的库存都是5, a下了三个单子吧库存改为2, b下了一个单子将库存改为4, 这个时候出现了a回覆盖b的更新. 最终结果出现错误, 剩余库存为2.

    这个时候我们需要采取CAS乐观锁去解决这个问题.
    这里的CAS不需要考虑ABA问题, 因为即使这个时候加了库存, 中间发生了变化, 但是对于最终结果是不会产生影响的.

    update store set num = ${num} where id = ${id} and num = ${query_num}
    这个是只更新一个表, 如果牵扯到多个表呢, 我们希望和这个单子关联的所有的表同一时间只能被一个线程来处理更新, 多个线程按照不同的顺序去更新同一个单子关联的不同数据的时候, 出现死锁的概率比较大. 如果是分布式项目的话, 我们需要保证多线程多进程同时只能有一个进行的一个线程去处理, 这个时候我们就需要用到分布式锁. 分布式锁的实现方式有很多种, 我们今天分别通过,Zookeeper, Redis以及Tair的实现逻辑.

    Zookeeper实现

    获取锁

    现有一个锁根节点, lockRootNode, 这可以是一个永久的根节点.
    客户端获取锁, 现在lockRootNode下面创建一个顺序的瞬时节点, 保证客户端断开连接, 节点也自动删除.
    调用lockRootNode父节点的getChildren()方法, 获取所有的根节点, 并从小到大排序, 如果创建的最小的节点是当前节点, 则返回true, 获取锁成功.

    搜索文件

    1. 谈谈业务中使用分布式的场景.
  • 相关阅读:
    Go--指针
    Go--struct
    Go--函数
    Go基础
    流程控制
    Go前言
    变量与常量
    Django(三):HttpRequest和HttpResponse
    Django(二):url和views
    tensorflow(一):图片处理
  • 原文地址:https://www.cnblogs.com/A-FM/p/12010972.html
Copyright © 2011-2022 走看看