博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
分布式思维
阅读量:2245 次
发布时间:2019-05-09

本文共 4034 字,大约阅读时间需要 13 分钟。

说在前面的话

Java编程里有两座大山----高可用、高并发。而分布式无疑是翻越这两座大山最好的方式。

本篇文章讲的是分布式思维,目的是为了帮助大家在学习分布式之前对某些分布式领域里的一些概念做了解,在脑海里对分布式有个整体的认识。不会针对某一项技术做详细的讲解与介绍。

说明:以下图片均来自享学课堂http://www.xiangxueketang.cn:8013/forum.php

一、计算机与软件的发展历史

在这里插入图片描述

在这里插入图片描述

二、什么是分布式与集群的关系

集群:把代码复制一份,每台机器做一样的事情

分布式:两天机器分工合作,每台机器做的事情不一样。分布式里面会出现接力(业务流:业务A–>业务B–>业务C)
在这里插入图片描述

集群:前端用一个负载(一般用nginx)去把请求分流到三台机器去。

分布式:把用户模块拆成一个服务,把商品模块拆成一个服务,把订单拆成一个服务,这样就把本来一个单机服务拆成三台机器,再根据每个业务的承受能力来做每一个模块的集群。例如这里用户模块性能销耗较大,可以把用户模块做一个三个节点的集群(所以在Java高并发架构部署里,集群与分分布式一般是一起使用的)。
在这里插入图片描述

三、大型架构演进过程分析

B/S请求过程

在这里插入图片描述

题外:更改本地host文件可以达到欺骗浏览器的目的

3.1 架构演进一

在这里插入图片描述

解析本地html文件与解析服务器返回的网站内容,对浏览器解析渲染页面出来是没区别的。架构演进一其实就相当于把原本放在本地的htm静态文件放到了服务器上面。

3.2 架构演进二

在这里插入图片描述

做过jsp开发的都知道,数据有四个域:页面级/request/session/全局。在数据库开发里,就是把数据库里读到的数据放到了这四个变量中,jsp页面通过${name}来获取数据。

3.3 架构演进三

在这里插入图片描述

如下图,这种单机应用,在用到一定程度的时候会承受不了压力
在这里插入图片描述

3.4 架构演进四

如果图,把用户/商品/订单做了集群之后,应用可能可以撑住了,但是这个时候如果数据库撑不住了呢

在这里插入图片描述
数据库会面临增删改查操作,而压力最大的就是查询操作(多表联合,数据量膨胀 ),所以这里可以做读写分离。主从数据库之间的同步会有延迟,对读操作实时性要求不太高的可以从从数据库里查。
在这里插入图片描述
如何控制一个程序写的时候在一个数据库,读的时候又从另一个数据库读?业界公认的办法是自己定义一个读标签和一个写标签,然后在你的dao接口的方法上添加这个标签,例如:
在这里插入图片描述

3.5 架构演进五

在这里插入图片描述

上面这样把服务拆分出来会引入一个问题,例如用户和订单服务可能要调用商品服务,这个时候我们还要把一个个服务拆出来,如下图
在这里插入图片描述
分布式的拓展方案:从war包里把service层吃紧的service独立成单独的服务(jar包启动),如果这个service还是扛不住,可以复制成集群模式。
注意:这个不是微服务。

3.6 javaweb的微服务发展

在这里插入图片描述

微服务模式的拓展:把dao,service,controller都抽离出来,而不是仅仅抽离service,抽离出来后独立打个包,包括包括商品表也从数据库中独立出来称为单独的一个数据库。

四、如何架构一个系统

4.1 提及

4.1.1 dubbo和spring cloud是做什么的

由上面关于分布式及微服务的拆分可看出,不管是分布式还是微服务,都存在一个服务治理的问题。有很多框架可以处理服务之间的相互调用治理问题例如dubbo,spring cloud。

4.1.2 RPC调用

服务治理里面,首当其冲的一个问题是跨系统的调用(rpc调用),在dubbo(dubbo里面实现了RMI、webservice、http服务调度)和spring cloud(用http协议通信实现RPC调用)出现之前就有rpc调用。跨虚拟机、跨服务、跨系统、跨物理机器调用service都可以称为RPC调用。

4.1.3 RPC调用包含

  1. RMI调用(jdk里的)
  2. web service
  3. http请求
  4. 通过网络来达到服务间访问的目的就是rpc调用。

4.1.4 zookeeper的作用

我们上面说到把商品服务拆出来独立成一个服务,当商品服务扛不住的时候会把商品服务复制成集群,那么当一个请求过来的时候,我首先要知道有哪几个商品服务可以用,这里就有一个服务的发现(zookeeper来做)问题,当发现了有哪几个商品服务之后,就要决定交给商品服务集群中的哪个商品服务来处理,这里涉及到有负载路由问题。

4.1.5 mq方案

4.2 架构一个系统时的考量

4.2.1 架构系统时考量的两个指标(架构一个系统的依据)

并发数(tps:每秒处理的事务数)和数据量级(例如说要架构一个系统,百万级的系统用什么用的架构,千万级的系统用什么样的架构)

4.2.1.1 数据量太大时可考虑的解决方案(mycat)

**原因:**在数据库里,例如当订单服务的数据积累非常大,一张表放不下,这个时候在数据库里就有一系列的方案来解决。一般有分库、分区、分表。mysql数据库,单表数据量达到700w的时候,性能会急剧下降。
分库/分表:在mysql里做分库/分表,对我们业务代码里写的sql语句是有影响的(库的名字会变/表的名称会变),这也就是说有侵入性----->可以用mycat中间件解决这个问题。
**分区:**对sql语句是没有侵入性的,对库没有办法减压,因为不管你分多少个区,这些区始终是在一个库里面。能够解决分表的问题,不能解决分库的问题。

4.2.1.2 单个tomcat的tps承载量

tps里面有一个考量,一般单个tomcat能承受500tps(架构系统是追求稳定的,在500tps以下是稳定的,这不代表超过500就会出问题)。

在这里插入图片描述

4.3当系统超出它的承载能力之后,按以下顺序的解决方案考虑

在这里插入图片描述

五、前后端交互模式演进

5.1 整页提交

粗粒度,最原始的方式

在这里插入图片描述

5.2 页面+ajax混和

在这里插入图片描述

5.3 单页应用mvvm模式

前后端分离,前端人员只写静态的页面,把这些页面打成一个静态的文件包放在静态服务器上,然后首次通过url的形式访问服务器返回html页面,浏览器html页面再通过向webapp发送ajax请求获取json数据。

因为静态服务器与webapp服务器不在同一台服务器上,所以存在跨域问题(nginx有跨域的解决方案)。
在这里插入图片描述

六、架构问题解决方案

6.1跨域的解决方案

建议使用redis共享session,因为hash(ip) 负载不均衡,而且hash(ip)由4G切换到wifi的时候会有问题。

在这里插入图片描述

集群引起的负载问题方案,如何session共享:

1、tomcat自己插件,能够session共享
2、spring-session插件,实现session共享。

6.2 缓存方案

6.2.1 缓存在哪里

缓存在缓存服务器,例如redis、memcache
6.2.2 什么时候可以做缓存
网络cdn可以缓存静态资源;服务接口返回的时候,可以把接口返回的数据缓存,下一个用户又来查询同样的业务数据的时候就可以从缓存里取数据;数据库层面的缓存,例如很多电商系统会在用户登录的时候把用户的数据缓存起来。在这里插入图片描述

6.2.3 缓存方案

在这里插入图片描述

解决缓存击穿可以使用“布隆过滤器”

数据永久有效存在浪费内存的问题

6.3 mq方案

mq解决什么问题,mq消息总线的作用:例如在队列A里放进来的数据通过配置把它自动传递到队列C,通过这样的作用实现了服务A启动的时候会在消息总线注册一个队列,服务器C启动的时候也会注册一个队列,因为有了MQ,A和C之间的数据往来不需要A和C服务器之间发生任何关系。每台服务器只需要关心自己创建的队列,MQ就像一个传话筒,所有的服务它只需要关注自己对应的队列(不管是发送还是接受消息),例如A服务只需要关注队列A。如果A服务不用MQ,它想要向服务器B和C发送数据要分别各发送一次,如果有了MQ,服务器A只需要向自己的队列A发送数据,服务器A想拿其他服务器的数据,它只需要订阅其他队列的消息就能在队列A中拿到这些数据。

假如A、B、C、D四台服务器都已经上线了,这个时候例如队列A发送的某个消息不想给C传递了,在个时候C或其他的服务都不用变化,只需要变化一下MQ的配置,它自己就会把路由切断。

在这里插入图片描述

6.4 同步、异步

在这里插入图片描述

在JDK里,Future模式就实现了下图的架构

在这里插入图片描述

6.5 数据分片

可以使用Redis/es/fastdfs中间件,将数据按片切分,如下图(这个模式实现了集群的动态扩容):

例如有100万的数据,这100万的数据随着后面业务的扩增后面可能会变成1000万的数据,那么怎么实现平滑的扩充容量呢?1台redis存不了1000万的数据,如何通过加Redis机器的方式在后续系统上线之后不需要停机就能平滑的过度。思路就是:首先把数据切成6个数据柱(不一定是6个,这里是以下面图片为例讲解),1、2、3放在redisA上面,4、5、6放在redisB上面,假如两个redis共同能承受的数据的100万,当数据超过100万的时候又要再加一个RedisC,然后Redis就会动态漫游成1、2在redisA,3、4在redisB,5、6在redisC从而达到分布上的平衡,这个平衡的好处是它是发生在Redis集群的内部,对Redis的路由层是不变的。
在这里插入图片描述

  1. 切成6个片(6个数据柱),每个片存储总容量的1/6数据
  2. 则两个库,每个库分担3个片
  3. 若有三个库,则每个库分担2个片
  4. 路由管理,只记录数据与片柱的关系

数据路由的含义:例如当前有6个数据柱,有100万个用户,现在要查询一个叫张三的用户,这个时候首先是请求redis集群,redis集群就要知道张三的数据是存在集群的哪一个柱上,因为存数据的时候是有记录的,所以知道张三的数据在哪个柱上,这里面存在一个数据与柱的对应关系(扩容(扩容就是柱子的数量不变,柱子的容量变大)时此关系不变),这个对应关系就是路由数据的依据。

转载地址:http://qgqbb.baihongyu.com/

你可能感兴趣的文章
面试Java程序员需具备的11个技能
查看>>
HashMap 和 HashTable 到底哪不同 ?
查看>>
Java实现简单的递归操作
查看>>
Struts2工作原理和执行流程图
查看>>
在线预览Word,Excel~
查看>>
hibernate延迟加载(get和load的区别)
查看>>
关于文件拷贝效率问题
查看>>
MyBatis分页插件PageHelper的使用
查看>>
【MyBatis学习01】宏观上把握MyBatis框架
查看>>
【MyBatis学习02】走进MyBatis的世界
查看>>
【MyBatis学习03】原始dao开发方法及其弊端
查看>>
【MyBatis学习04】mapper代理方法开发dao
查看>>
【MyBatis学习05】SqlMapConfig.xml文件中的配置总结
查看>>
【MyBatis学习06】输入映射和输出映射
查看>>
【MyBatis学习07】动态sql
查看>>
【MyBatis学习08】高级映射之一对一查询
查看>>
【MyBatis学习09】高级映射之一对多查询
查看>>
【MyBatis学习10】高级映射之多对多查询
查看>>
【MyBatis学习11】MyBatis中的延迟加载
查看>>
【MyBatis学习12】MyBatis中的一级缓存
查看>>