热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:分布式系统浅谈

本文由编程笔记#小编为大家整理,主要介绍了分布式系统浅谈相关的知识,希望对你有一定的参考价值。一个tomcat
本文由编程笔记#小编为大家整理,主要介绍了分布式系统浅谈相关的知识,希望对你有一定的参考价值。




一个tomcat打天下的时代,不能说完全淘汰了,在一个管理系统,小型项目中还经常使用,这并不过分,出于成本的考虑,这反而值得提倡。但如果要延伸到高并发场景下就必然要了解分布式系统:


分布式系统特点


分布式系统:一个硬件软件组件分布在不同的网络计算机上,彼此之间仅仅通过消息传递进行通信和协调的系统 这是分布式系统,在不同的硬件,不同的软件,不同的网络,不同的计算机上,仅仅通过消息来进行通讯与协调 这是他的特点,更细致的看这些特点又可以有:分布性对等性并发性缺乏全局时钟故障随时会发生


1. 分布性

既然是分布式系统,最显著的特点肯定就是分布性,从简单来看,如果我们做的是个电商项目,整个项目会分成不同的功能,专业点就不同的微服务,比如用户微服务,产品微服务,订单微服务,这些服务部署在不同的tomcat中,不同的服务器中,甚至不同的集群中,整个架构都是分布在不同的地方的,在空间上是随意的,而且随时会增加删除服务器节点,这是第一个特性。


2. 对等性

对等性是分布式设计的一个目标,还是以电商网站为例,来说明下什么是对等性,要完成一个分布式的系统架构,肯定不是简单的把一个大的单一系统拆分成一个个微服务,然后部署在不同的服务器集群就够了,其中拆分完成的每一个微服务都有可能发现问题,而导致整个电商网站出现功能的丢失。比如订单服务,为了防止订单服务出现问题,一般情况需要有一个备份,在订单服务出现问题的时候能顶替原来的订单服务。这就要求这两个(或者2个以上)订单服务完全是对等的,功能完全是一致的,其实这就是一种服务副本的冗余。还一种是数据副本的冗余,比如数据库,缓存等,再比如大数据HDFS中的三个副本,都和上面说的订单服务一样,为了安全考虑需要有完全一样的备份存在,这就是对等性的意思。


3. 并发性

并发性其实对我们来说并不模式,在学习多线程的时候已经或多或少学习过,多线程是并发的基础。但是以前都是在一个JVM上实现的并发,但现在我们要接触的不是多线程的角度,而是更高一层,从多进程,多JVM的角度,例如在一个分布式系统中的多个节点,可能会并发地操作一些共享资源,如何准确并高效的协调分布式并发操作。分布式锁就是干这个事的。


4. 缺乏全局时钟

在分布式系统中,节点是可能反正任意位置的,而每个位置,每个节点都有自己的时间系统,因此在分布式系统中,很难定义两个事务纠结谁先谁后,原因就是因为缺乏一个全局的时钟序列进行控制,当然,现在这已经不是什么大问题了,已经有大把的时间服务器给系统调用


5. 故障随时会发生

任何一个节点都可能出现停电,死机等现象,服务器集群越多,出现故障的可能性就越大,随着集群数目的增加,出现故障甚至都会成为一种常态,怎么样保证在系统出现故障,而系统还是正常的访问者是作为系统搭建者应该考虑的。


大型网站架构图


分布式系统浅谈知道什么是分布式系统,接下来具体来看下大型网站架构图,首先整个架构分成很多个层,应用层,服务层,基础设施层与数据服务层,每一层都由若干节点组成,这是典型的分布式架构,后面一大把的时间就是系统的学习里面的每一个部分。


那么zookeeper在其中又是扮演什么角色呢,如果可以把zk扮演成交警的角色,而各个节点就是马路上的各种汽车(汽车,公交车),为了保证整个交通(系统)的可用性,zookeeper必须知道每一节点的健康状态(公交车是否出了问题,要派新的公交【服务注册与发现】),公路在上下班高峰是否拥堵,在某一条很窄的路上只允许单独一个方向的汽车通过【分布式锁】。如果交通警察是交通系统的指挥官,而zookeeper就是各个节点组成分布式系统的指挥官


分布式系统问题


如果把分布式系统和平时的交通系统进行对比,哪怕再稳健的交通系统也会有交通事故,分布式系统也有很多需要攻克的问题,比如:通讯异常网络分区三态节点故障等。


1. 通信异常

通讯异常其实就是网络异常,网络系统本身是不可靠的,由于分布式系统需要通过网络进行数据传输,网络光纤,路由器等硬件难免出现问题。只要网络出现问题,也就会影响消息的发送与接受过程,因此数据消息的丢失或者延长就会变得非常普遍。


2. 网络分区

网络分区,其实就是脑裂现象(参考Hadoop NameNode),举例来说:本来有一个交通警察,来管理整个片区的交通情况,一切井然有序,突然出现了停电,或者出现地震等自然灾难,某些道路接受不到交通警察的指令,可能在这种情况下,会出现一个零时工,片警来指挥交通。但注意,原来的交通警察其实还在,只是通讯系统中断了,这时候就会出现问题了,在同一个片区的道路上有不同人在指挥,这样必然引擎交通的阻塞混乱。这种由于种种问题导致同一个区域(分布式集群)有两个相互冲突的负责人的时候就会出现这种精神分裂的情况,在这里称为脑裂,也叫网络分区


3. 三态

三态是什么?三态其实就是成功,与失败以外的第三种状态,当然,肯定不叫变态,而叫超时态。在一个jvm中,应用程序调用一个方法函数后会得到一个明确的相应,要么成功,要么失败,而在分布式系统中,虽然绝大多数情况下能够接受到成功或者失败的相应,但一旦网络出现异常,就非常有可能出现超时,当出现这样的超时现象,网络通讯的发起方,是无法确定请求是否成功处理的。


4. 节点故障

这个其实前面已经说过了,节点故障在分布式系统下是比较常见的问题,指的是组成服务器集群的节点会出现的宕机僵死的现象,这种现象经常会发生。


CAP 理论


前面说了分布式的特点以及会碰到很多会让人头疼的问题,这些问题肯定会有一定的理论思想来解决问题的。接下来花点时间来谈谈这些理论,其中CAPBASE理论是基础,也是面试的时候经常会问到的 首先看下CAP,CAP其实就是一致性可用性分区容错性这三个词的缩写


一致性

一致性是事务ACID的一个特性【原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)】。


这里讲的一致性其实大同小异,只是现在考虑的是分布式环境中,还是不单一的数据库。


在分布式系统中,一致性是数据在多个副本之间是否能够保证一致的特性,这里说的一致性和前面说的对等性其实差不多。如果能够在分布式系统中针对某一个数据项的变更成功执行后,所有用户都可以马上读取到最新的值,那么这样的系统就被认为具有强一致性。


可用性

可用性指系统提供服务必须一直处于可用状态,对于用户的操作请求总是能够在有限的时间内访问结果。这里的重点是有限的时间返回结果。为了做到有限的时间需要用到缓存,需要用到负载,这个时候服务器增加的节点是为性能考虑;


为了返回结果,需要考虑服务器主备,当主节点出现问题的时候需要备份的节点能最快的顶替上来,千万不能出现OutOfMemory或者其他500,404错误,否则这样的系统我们会认为是不可用的。


分区容错性

分布式系统在遇到任何网络分区故障的时候,仍然需要能够对外提供满足一致性可用性的服务,除非是整个网络环境都发生了故障。不能出现脑裂的情况。


PS:


一个分布式系统不可能同时满足一致性、可用性和分区容错性这三个基本需求,最多只能同时满足其中的两项。设计者的精力往往就花在怎么样根据业务场景在A和C直接寻求平衡;



分布式系统浅谈


BASE理论



根据前面的CAP理论,设计者应该从一致性·和可用性之间找平衡,系统短时间完全不可用肯定是不允许的,那么根据CAP理论,在分布式环境下必然也无法做到强一致性。


BASE理论:


即使无法做到强一致性,但分布式系统可以根据自己的业务特点,采用适当的方式来使系统达到最终的一致性


Basically Avaliable  基本可用

当分布式系统出现不可预见的故障时,允许损失部分可用性,保障系统的基本可用;体现在时间上的损失功能上的损失


e.g:部分用户双十一高峰期淘宝页面卡顿或降级处理;


Soft state 软状态

其实就是前面讲到的三态,既允许系统中的数据存在中间状态,既系统的不同节点的数据副本之间的数据同步过程存在延时,并认为这种延时不会影响系统可用性;


e.g:12306网站卖火车票,请求会进入排队队列;




Eventually consistent 最终一致性

所有的数据在经过一段时间的数据同步后,最终能够达到一个一致的状态;


e.g:理财产品首页充值总金额短时不一致;


服务雪崩


假设存在如下调用链分布式系统浅谈而此时,Service A的流量波动很大,流量经常会突然性增加!那么在这种情况下,就算Service A能扛得住请求,Service BService C未必能扛得住这突发的请求。此时,如果Service C因为抗不住请求,变得不可用。那么Service B的请求也会阻塞,慢慢耗尽Service B的线程资源,Service B就会变得不可用。紧接着,Service A也会不可用,这一过程如下图所示分布式系统浅谈如上图所示,一个服务失败,导致整条链路的服务都失败的情形,我们称之为服务雪崩。


那么,服务熔断和服务降级就可以视为解决服务雪崩的手段之一。


服务熔断


服务熔断:当下游的服务因为某种原因突然变得不可用或响应过慢,上游服务为了保证自己整体服务的可用性,不再继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。需要说明的是熔断其实是一个框架级的处理,那么这套熔断机制的设计,基本上业内用的是断路器模式,如Martin Fowler提供的状态转换图如下所示





  1. 最开始处于closed状态,一旦检测到错误到达一定阈值,便转为open状态。



  2. 这时候会有个 reset timeout,到了这个时间了,会转移到half open状态。



  3. 尝试放行一部分请求到后端,一旦检测成功便回归到closed状态,即恢复服务。


业内目前流行的熔断器很多,例如阿里出的Sentinel,以及最多人使用的Hystrix,在Hystrix中,对应配置如下











//滑动窗口的大小,默认为20circuitBreaker.requestVolumeThreshold //过多长时间,熔断器再次检测是否开启,默认为5000,即5s钟circuitBreaker.sleepWindowInMilliseconds //错误率,默认50%circuitBreaker.errorThresholdPercentage


每当20个请求中,有50%失败时,熔断器就会打开,此时再调用此服务,将会直接返回失败,不再调远程服务。直到5s之后,重新检测该触发条件,判断是否把熔断器关闭,或者继续打开。


这些属于框架层级的实现,我们只要实现对应接口就好!


服务降级


什么是服务降级呢?这里有两种场景:






  1. 当下游的服务因为某种原因响应过慢,下游服务
    主动停掉一些不太重要的业务,释放出服务器资源,增加响应速度!



  2. 当下游的服务因为某种原因不可用,上游主动调用本地的一些降级逻辑,避免卡顿,迅速返回给用户!



其实乍看之下,很多人还是不懂熔断和降级的区别,其实应该要这么理解:






  1. 服务降级有很多种降级方式!如开关降级、限流降级、熔断降级!



  2. 服务熔断属于降级方式的一种!



可能有的人不服,觉得熔断是熔断、降级是降级,分明是两回事啊!其实不然,因为从实现上来说,熔断和降级必定是一起出现。因为当发生下游服务不可用的情况,这个时候为了对最终用户负责,就需要进入上游的降级逻辑了。因此,将熔断降级视为降级方式的一种,也是可以说的通的!


撇开框架,以最简单的代码来说明!上游代码如下












try{
xxRpc.helloWorld();}catch(Exception e){
doSomething();}


注意看,下游的helloWorld服务因为熔断而调不通。此时上游服务就会进入catch里头的代码块,那么catch里头执行的逻辑,你就可以理解为降级逻辑!什么,你跟我说你不捕捉异常,直接丢页面?OK,那我甘拜下风,当我理解错误!


服务降级大多是属于一种业务级别的处理。当然,我这里要讲的是另一种降级方式,也就是开关降级 这也是我们生产上常用的另一种降级方式!


做法很简单,做个开关,然后将开关放配置中心!在配置中心更改开关,决定哪些服务进行降级。至于配置变动后,应用怎么监控到配置发生了变动,这就不是本文该讨论的范围。那么,在应用程序中部下开关的这个过程,业内也有一个名词,称为埋点


那接下来最关键的一个问题,哪些业务需要埋点?一般有以下方法





  1. 简化执行流程 自己梳理出核心业务流程和非核心业务流程。然后在非核心业务流程上加上开关,一旦发现系统扛不住,关掉开关,结束这些次要流程。





  2. 关闭次要功能 一个微服务下肯定有很多功能,那自己区分出主要功能次要功能。然后次要功能加上开关,需要降级的时候,把次要功能关了吧!





  3. 降低一致性 假设,你在业务上发现执行流程没法简化了,愁啊!也没啥次要功能可以关了,桑心啊!那只能降低一致性了,即将核心业务流程的同步改异步,将强一致性改最终一致性!




可是这些都是手动降级,有办法自动降级么?在生产上没弄自动降级!因为一般需要降级的场景,都是可以预见的,例如某某活动。假设,平时真的有突发事件,流量异常,也有监控系统发邮件通知,提醒我们去降级!当然,这并不代表自动降级不能做,只是头脑大概想了下,如果让我来做自动降级我会怎么实现:






  1. 自己设一个阈值,例如几秒内失败多少次,就启动降级



  2. 自己做接口监控(有兴趣的可以了解一下
    Rxjava),达到阈值就走推送逻辑。怎么推呢?比如你配置是放在git上,就用jgit去改配置中心的配置。如果配置放数据库,就用jdbc去改。



  3. 改完配置中心的配置后,应用就可以自动检测到配置的变化,进行降级!(这句不了解的,了解一下配置中心的热刷新功能)



推荐阅读:









推荐阅读
  • 前言无论是对于刚入行工作还是已经工作几年的java开发者来说,面试求职始终是你需要直面的一件事情。首先梳理自己的知识体系,针对性准备,会有事半功倍的效果。我们往往会把重点放在技术上 ... [详细]
  • 深入剖析JVM垃圾回收机制
    本文详细探讨了Java虚拟机(JVM)中的垃圾回收机制,包括其意义、对象判定方法、引用类型、常见垃圾收集算法以及各种垃圾收集器的特点和工作原理。通过理解这些内容,开发人员可以更好地优化内存管理和程序性能。 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 并发编程 12—— 任务取消与关闭 之 shutdownNow 的局限性
    Java并发编程实践目录并发编程01——ThreadLocal并发编程02——ConcurrentHashMap并发编程03——阻塞队列和生产者-消费者模式并发编程04——闭锁Co ... [详细]
  • 优化Flask应用的并发处理:解决Mysql连接过多问题
    本文探讨了在Flask应用中通过优化后端架构来应对高并发请求,特别是针对Mysql 'too many connections' 错误的解决方案。我们将介绍如何利用Redis缓存、Gunicorn多进程和Celery异步任务队列来提升系统的性能和稳定性。 ... [详细]
  • 深入理解Java多线程并发处理:基础与实践
    本文探讨了Java中的多线程并发处理机制,从基本概念到实际应用,帮助读者全面理解并掌握多线程编程技巧。通过实例解析和理论阐述,确保初学者也能轻松入门。 ... [详细]
  • 本文深入探讨了MySQL中常见的面试问题,包括事务隔离级别、存储引擎选择、索引结构及优化等关键知识点。通过详细解析,帮助读者在面对BAT等大厂面试时更加从容。 ... [详细]
  • 深入理解 JMeter 定时器
    本文详细介绍了JMeter中定时器的功能和使用方法,探讨了其在性能测试中的重要性,并结合实际案例解释了如何合理配置定时器以模拟真实的用户行为。文章还涵盖了定时器的执行顺序及其与其他元件的相互作用。 ... [详细]
  • 本文探讨了如何通过一系列技术手段提升Spring Boot项目的并发处理能力,解决生产环境中因慢请求导致的系统性能下降问题。 ... [详细]
  • 深入解析Spring Cloud微服务架构与分布式系统实战
    本文详细介绍了Spring Cloud在微服务架构和分布式系统中的应用,结合实际案例和最新技术,帮助读者全面掌握微服务的实现与优化。 ... [详细]
  • 深入解析IGMP各版本特性及其演进
    本文详细探讨了Internet组管理协议(IGMP)的不同版本,包括IGMPv1的基础功能、IGMPv2的增强特性和IGMPv3的重要改进。特别分析了IGMPv3如何支持特定源组播(SSM)模型,并介绍了各版本之间的主要差异。 ... [详细]
  • Go语言以其简洁的语法和强大的并发处理能力而闻名,特别是在云计算和分布式计算领域有着广泛的应用。本文将深入探讨Go语言中的Channel机制,包括其不同类型及其在实际编程中的应用。 ... [详细]
  • MySQL锁机制详解
    本文深入探讨了MySQL中的锁机制,包括表级锁、行级锁以及元数据锁,通过实例详细解释了各种锁的工作原理及其应用场景。同时,文章还介绍了如何通过锁来优化数据库性能,避免常见的并发问题。 ... [详细]
  • 字节跳动夏季招聘面试经验分享
    本文详细记录了字节跳动夏季招聘的面试经历,涵盖了一、二、三轮面试的技术问题及项目讨论,旨在为准备类似面试的求职者提供参考。 ... [详细]
  • MapReduce原理是怎么剖析的
    这期内容当中小编将会给大家带来有关MapReduce原理是怎么剖析的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1 ... [详细]
author-avatar
mobiledu2502860957
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有