发展背景
单一应用架构
当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。。
垂直应用架构
当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。
分布式服务架构
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
什么是分布式系统?
《分布式系统原理和范型》一书中是这样定义分布式系统的:“分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像是单个相关系统”。
从进程角度看,两个程序分别运行在两台主机的进程上,它们相互协作最终完成同一个服务(或者功能),那么理论上这两个程序所组成的系统,也可以称作是“分布式系统”。
当然,这个两个程序可以是不同的程序,也可以是相同的程序。如果是相同的程序,我们又可以称之为“集群”。所谓集群,就是将相同的程序,通过不断横向扩展,以提高服务能力的方式。
分布式和微服务
微服务架构偏向于业务,比如可以将微服务按子业务、数据库、接口等维度拆分成不同的微服务
分布式架构偏向于机器,目前,你可以说微服务架构都是分布式架构,因为目前大部分公司都是把每个服务单独部署的
分布式系统所遇到的挑战
分布式session
Session粘滞
即粘性Session、当用户访问集群中某台机器后,强制指定后续所有请求均落到此机器上
使用场景:机器数适中、对稳定性要求不是非常苛刻
优点:实现简单、配置方便、没有额外网络开销
缺点:网络中有机器Down掉时、用户Session会丢失、容易造成单点故障
方案:Nginx的ip_hash负载均衡方案
Session复制
将一台机器上的Session数据广播复制到集群中其余机器上
使用场景:机器较少,网络流量较小
优点:实现简单、配置较少、当网络中有机器Down掉时不影响用户访问
缺点:广播式复制到其余机器有一定廷时,带来一定网络开销
方案:开源方案tomcat-redis-session-manager,暂不支持Tomcat8
缓存集中式管理
将Session存入分布式缓存集群中的某台机器上,当用户访问不同节点时先从缓存中拿Session信息
使用场景:集群中机器数多、网络环境复杂
优点:可靠性好
缺点:实现复杂、稳定性依赖于缓存的稳定性、Session信息放入缓存时要有合理的策略写入
方案:开源方案Spring Session,也可以自己实现,主要是重写HttpServletRequestWrapper中的getSession方法
分布式配置中心
在分布式系统中,一次构建、发布、上线是非常非常重的一个过程,它不像单机时代那样重启一台机器、一个进程就可以了,在分布式系统中,它涉及到将软件包(例如war)分发到可能超过几千台机器,然后将几千台机器上的应用进程一一重启,这么一个过程,超过2000台机器的一个应用一次完整的发布过程需要很长时间。
那么如何在不停应用集群的情况下,调整整个集群的运行时的行为特征,是一个分布式系统必须回答的一个问题。从这个角度讲, 我们认为: 每一个大型分布式系统都应该有一个配置中心!
我们平时常见的分布式系统的配置变更,诸如:
- 线程池、连接池大小
- 开关、限流配置
- 数据源主备容灾切换
- 路由规则
开源解决方案
- disconf,百度开源,与spring集成的很好,有web管理,client只支持java。
- diamond,阿里开源,阿里内部应用广泛,由http server(nameservers), diamond-server ,web组成,diamond-server连接同一个mysql,数据同步通过mysql dump文件同步(同步效率?),支持订阅发布,client只支持java。
- doozer,已停止更新,设计倾向于实时的数据变更通知,数据全部放于内存,不会持久化文件。
- etcd,CoreOS开源,轻量级分布式key-value数据库,同时为集群环境的服务发现和注册而设计,它提供了数据TTL失效(通过TTL更新来判断机器下线,来避免一定的网络分区问题)、数据改变监视、多值、目录监听、分布式锁原子操作等功能,来管理节点状态。
- zookeeper,成熟的分布式配置解决方案。
分布式事务
分布式事务解决的用户最本质诉求是什么?数据一致。
大中企业有一个共同的诉求是数据一致,几乎覆盖到各个行业。
比如说零售行业,库存与出货的数据需要保持一致,出货量与库存数据不匹配,显而易见会出问题,拿到订单却没货了,或者有货却下不了订单。
比如说金融行业,转账数据搞错了,A扣款了,B没加上,马上该用户投诉了;A没扣款,B却加上了,产生资损;又比如从总账户中买了基金、股票后余额不对了,等等,都会导致严重问题。
随着互联网技术快速发展,数据规模增大,分布式系统越来越普及,采用分布式数据库或者跨多个数据库的应用在中大规模企业普遍存在,服务化也是广泛应用,由于网络的不可靠和机器不可靠,数据不一致问题很容易出现。
数据一致性问题是必须解决的,在很多大企业多年前就已经成为突出问题,他们是怎么解决的?有这么几个典型方案:
- XA事务方案
- 柔性事务
- 基于消息的最终一致
- 业务补偿与人工订正
分布式锁
目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题。
分布式的CAP理论告诉我们,任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance),最多只能同时满足两项。
所以,很多系统在设计之初就要对这三者做出取舍。在互联网领域的绝大多数的场景中,都需要牺牲强一致性来换取系统的高可用性,系统往往只需要保证“最终一致性”,只要这个最终时间是在用户可以接受的范围内即可。
在很多场景中,我们为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式事务、分布式锁等。有的时候,我们需要保证一个方法在同一时间内只能被同一个线程执行。在单机环境中,Java中其实提供了很多并发处理相关的API,但是这些API在分布式场景中就无能为力了。也就是说单纯的Java Api并不能提供分布式锁的能力。所以需要需要针对分布式环境提供锁的能力。
常见的分布式锁的实现方案
- mysql
- 内存数据库(redis、memcached等)
- zookeeper
CAP理论
一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性