导图社区 Java知识体系
整理的Java知识体系主要包括基础知识,工具,并发编程,数据结构与算法,数据库,JVM,架构设计,应用框架,中间件,微服务架构,分布式架构,程序员的一些思考,团队与项目...
编辑于2022-10-11 10:12:31 北京市Java知识体系
java基础
jvm
Java内存模型(JMM)
基于传统计算机硬件内存模型的抽象
一套多线程读写共享数据时, 对数据的可见性,有序性和原子性的规则
可见性
当一个线程修改了某个共享变量的值, 其他线程是否能够马上得知这个修改的值
加volatile关键字保证可见性
修改的值立即更新到主存中,当其他线程需要读取时, 它会去内存中读取新值
使用synchronized和Lock保证可见性
保证任一时刻只有一个线程能访问共享资源 ,并在其释放锁之前将修改的变量刷新到内存中
有序性(重排性)
定义:在线程内部的两行代码的实际执行顺序和代码在Java文件中的逻辑顺序不一致,代码指令并不是严格按照代码语句顺序执行的,他们的顺序被改变了,这就是重排序。
意义:VM能根据处理器特性(CPU多级缓存系统、多核处理器等)适当的对机器指令进行重排序,使机器指令能更符合CPU的执行特性,最大限度的发挥机器性能
原子性
使用synchronized或Lock加锁实现,保证任一时刻只有一个线程访问该代码块
使用原子操作
除long和double之外的基本类型的赋值操作
所有引用reference的赋值操作
java.concurrent.Atomic.*包中所有类的原子操作
java内存结构
运行时数据区域
程序计数器
当前线程所执行的字节码的行号指示器
虚拟机栈
定义:
生命周期:线程私有,生命周期和线程保持一致
java方法执行的内存模型
包含
局部变量表
操作栈
方法出口
参数
-Xss128K 栈内存设置为128K
堆
各个线程共享
线程共享,存放对象实例
垃圾管理的主要区域
通过参数-Xmx和-Xms设定
当堆中没有足够的内存完成实例的分配时,会抛出OutOfMemoryError异常
分区
年轻代
分区
eden
from survivor
to survivor
内存占比默认:8:1:1
-XX:SurvivorRatio设置eden区的占比, from survivor 和 to survivor占比一样
相关参数:
-XX:Xmn 新生代内存大小
-XX:NewRatio 新生代占堆内存大小
老年代
方法区
用于存储被虚拟机加载的类的信息,常量,静态变量等
运行时常量池
参数
-XX:PermSize=10M 方法区最小内存为10M
-XX:MaxPermSize=10M 表示最大内存10MB
相关参数
-XX:Xms:最小堆内存大小
-XX:Xmx:最大堆内存大小
本地方法栈
不是给Java方法用的,是给Native方法使用的
垃圾回收
判断对象是否存活
引用计数器算法
无法解决循环引用问题
优点
实现简单,判定效率高,大部分情况下是一个不错的算法
缺点
很难解决对象之间相互循环引用的问题
根搜索算法
通过一系列名为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所有走过的路径成为引用链,当一个对象到GC Roots没有任何引用链相连,则说明改动想不可用,会被判定为可收回对象
垃圾清除算法
标记清除算法
缺点
效率不高
容易产生内存碎片
复制算法
将内存划分为相等的两块,每次只用其中的一块,当这一块用完了,将还存活的对象复制到另一块,然后把已使用的内存空间一次性清理掉,目前现代商业虚拟机都使用该种算法,但是并不是按照1:1的比例进行划分,将内存划分为一块较大的eden空间和两块较小的survivor空间,
新生代算法
特点
优点
实现简单
效率高
缺点
内存减少为原来的一半
标记整理算法
于标记清除算法类似,只是不进行清除,而是向一端移动,然后直接清理
分代收集算法
根据对象的存活周期,将内存划分为不同的区域,根据各个区域的不懂特点选择合适的算法
垃圾收集器
针对垃圾清除算法的具体实现
Serial收集器(复制算法的单线程的收集器)
缺点
停顿时间长,stop the world
优点:
高效,对于单个CPU而言,没有线程交互的开销,获取最大的收集效率
ParNew收集器(serial的多线程版本)
Parallel Scavenge收集器(比ParNew收集器多了自适应调节策略)
-XX:MaxGCPauseMillis和-XX:GCTimeRatio两个参数来精确控制最大垃圾收集停顿时间和吞吐量大小
CMS(Current Mark Sweep)收集器
已获取最短回收停顿时间为目标的收集器
特点
优点
并发收集
低停顿
缺点
占用CPU资源,导致应用变慢
无法处理浮动垃圾(清理期间产生的垃圾)
容易产生内存碎片(标记清除算法)
G1
与其他收集器的差异
在G1之前的垃圾收集器,收集的范围都是整个新生代或者老年代,而G1不再是这样。使用G1收集器时,Java堆的内存布局与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分(可以不连续)Region的集合。
优点
并行和并发。使用多个CPU来缩短Stop The World停顿时间,与用户线程并发执行。
分代收集。独立管理整个堆,但是能够采用不同的方式去处理新创建对象和已经存活了一段时间、熬过多次GC的旧对象,以获取更好的收集效果。
空间整合。基于标记 - 整理算法,无内存碎片产生。
可预测的停顿。能简历可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。
内存分配
分配策略
对象优先在eden区分配
如果eden区没有足够的空间,则发生一次新生代GC(Minor GC)
大对象直接进入老年代
长期存活的对象将进入老年代
空间分配担保
虚拟机执行子系统
Class文件结构
一组8位字节为基础单元组成的二进制流,class文件结构采用类似于C语言的结构体的方式来存储
数据结构
无符号数
组成:U1,U2,U4,U8,分别表示1个,2个,4个,8个字节
表
组成:多个无符号数或者其他表作为数据项的复合数据类型
class文件格式
魔数(magic):U4
作用:判断这个文件是否为一个能被虚拟机接受的class文件
版本号:U4
次版本号(Minor Version):U2
主版本号(Major Version):U2
常量池
常量池计数器:U2
虚拟机类加载机制
类加载过程
加载
1.通过类的全限定名来获取定义此类的二进制字节流
2.将这个字节流所代表的的静态存储结构转化为方法去的运行时数据结构
3,在java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这些数据的访问入口
验证
文件格式验证
1.是否以魔数(0XCAFEBABE开头)
2.主次版本是否在虚拟机处理范围之内
3.常量池中的常量是否有不被支持的类型
4.class文件是否有被篡改的其他信息
元数据验证
1.是否存在父类
2.是否继承了不允许被继承的类
3.如果不是抽象类,是否实现了其父类或者接口中要实现的方法
4.类中的字段是否和父类存在冲突(覆盖父类的final字段,不合规定的方法重载等)
字节码校验
主要进行数据流和控制流分析
验证最核心阶段
1.保证任何时刻操作数栈的数据类型与指令代码序列能够配合工作
2.跳转指令不会跳转到方法体外的字节码上
符号引用验证
符号引用验证可以看做是对类自身以外的信息进行匹配性的验证
准备
准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存将在方法去中进行分配
解析
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程
链接
初始化
立即进行初始化的情况
1.遇到new,static,
2.使用反射调用的时候
3,当初始化一个类的时候,如果其父类没有初始化,则需要先出发父类的初始化
4,当虚拟机启动时,需要制定一个要执行的主类,
使用
卸载
类加载器
分类
启动类加载器
无法被java程序直接引用
扩展类加载器
应用程序类加载器
双亲委派模型
并发编程
定义
基础定义
进程
资源分配的最小单元
线程
CPU调度的最小单元
线程状态
新建状态
就绪状态
运行状态
阻塞状态
失去CPU的使用权
等待阻塞
调用wait,需要notify进行唤醒
同步阻塞
获取对象的同步锁时,同步锁被其他线程占用
其他阻塞
sleep
sleep不会释放锁
join
死亡状态
程序执行完成或者异常退出
主要问题
通信
消息传递:没有公共状态,必须通过发送消息来显式通讯
共享内存:线程之间共享程序的公共状态,通过写-读内存中的公共状态进行隐式通讯
java并发采用的方式
同步:控制不同线程间操作发生相对顺序的机制
重排序
编译器优化重排序
编译器
指令级并行的重排序
内存系统的重排序
处理器
线程安全
级别
不可变(final关键字修饰)
绝对线程安全
相对线程安全
Vector
HashTable
Collections
线程兼容
线程对立
实现方法
互斥同步
在多个线程并发访问共享数据时,保证同一个时刻只能被一条线程使用
定义
互斥
手段
多线程并发访问共享数据时,保证共享数据只能在同一时刻被同一个线程调用
同步
目的
实现方法
Synchronized
非公平,悲观,独享,互斥,可重入的重量级锁
在编译之后,会在同步代码前后分别生成:monitorEnter和monitorExit的字节码指令
原生语法层面的互斥
ReentrantLock(可重入锁)
默认非公平但可实现公平的,悲观,互斥,可重入的重量级锁
readwriteLock(读写锁)
默认非公平但可实现公平,悲观,写独享,读共享,可重入的重量级锁
非阻塞同步
CAS:
CAS需要三个操作数,分别是内存地址(V),旧的预期值(A)和新的预期值(B),CAS指令执行时,当且仅当V符合A时,处理器用新值B更新V的值,否则就不执行更新,但是不管是否更新了V的值,都会返回V的旧值,而且上述过程是原子操作
无同步方案
可重入代码
线程本地存储
ThreadLocal
锁优化
按照性质分类
公平锁/非公平锁
乐观锁/悲观锁
独享锁/共享锁
互斥锁/读写锁
可重入锁
按照设计方案分类
自旋锁
如果物理机有一个以上的处理器,能让两个或者以上的线程同时执行,我们就可以让后面请求锁的那个线程稍等一会儿,但不放弃处理器的执行时间,看看持有锁的线程是否能够很快就会释放锁,为了让线程等待,我们只需让线程执行一个循环(自旋),这项技术就是所谓的自旋锁
如果锁被占用时间很短,自旋等待效果较好,如果锁被长时间占用,则会白白消耗CPU资源
特点
优点
减少线程上下文切换的消耗
缺点
消耗CPU
轻量级锁
偏向锁
锁升级
无锁状态
偏向锁
依据是“大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得”。它是通过记录第一次进入同步块的线程id来实现的,如果下一个要进入同步块的线程与记录的线程id相同,则说明这个锁由此线程占有,可以直接进入到同步块,不用执行CAS。
执行过程
子主题
轻量级锁
当锁时偏向锁的时候,被另外一个线程访问,偏向锁会升级为轻量级锁,其他线程会通过自旋的方式尝试获取锁,不会阻塞,提高性能
乐观锁
重量级锁
当锁为轻量级锁时,另外一个线程虽然是自旋,但是当自选达到一定次数之后,还没获取到锁,就会进入阻塞,膨胀为重量级锁
互斥量(Mutex)
之所以称它为重量级锁,是因为Java线程是映射到操作系统的原生线程上的,如果要阻塞或唤醒一个线程,都需要依靠操作系统从当前用户态转换到核心态中,这种状态转换需要耗费处理器很多时间,对于简单同步块,可能状态转换时间比用户代码执行时间还要长,导致实际业务处理所占比偏小,性能损失较大。
悲观锁
分段锁
通过分段锁的形式来实现高效的并发操作,细化锁的粒度,当操作不需要更新整个数组的时候,仅仅针对数组中的一项进行加锁。ConcurrentHashMap
锁优化
锁粗化
锁消除
减少不必要的锁操作
算法
查找
顺序查找j
二分查找
有序查找
排序
中间件
消息中间件
组成
Broker
消息服务器,提供核心服务
produce
消息生产方,负责生产消息给broker
consumer
消息消费方,负责从broker获取消息并进行处理
topic
主题,发布订阅模式下消息的统一汇聚地,不同的生产者想topic发送消息,由MQ发送到不同的订阅者,实现消息广播
queue
队列,PTP模式下,特定生产者向特定的Queue发送消息,消费者订阅特定的queue完成指定消息的接收
message
消息体,根据不同的通信协议定义的固定格式进行编码的数据包,用来封装业务数据,实现消息的传输
模式分类
点对点
queue作为通信载体
发布订阅
topic作为通信载体
应用场景
异步
解耦
削峰
主要的消息中间件比较
activeMQ
RocketMQ
RabbitMQ
Kafka
架构设计
基本概念
定义:整体与局部关系的抽象描述
架构域的分类
业务架构
问题域:产品能够解决的所有问题的集合 经过问题域的罗列,可以得到一个模糊的产品方向和功能范围,把这些问题域的答案抽象总结从一个确定的产品需求,根据核心需求和问题域的大拿,梳理出业务流程 所以业务架构的作用就是在业务需求初期,将模糊的需求描述转化为轻器械的问题域,梳理出清晰的业务流程,为产品架构提供输入
内容
业务规划
业务模块
业务流程
输出
企业战略方向
问题域列表
业务流程图
数据架构
企业脚骨有业务架构驱动,从业务架构分析业务流程,定义数据架构,流程和数据结合定义产品架构
主要解决的问题
系统需要什么样的数据
静态数据
元数据
主数据
业务对象模型
共享数据
动态数据
数据流转
ETL
数据全生命周期管控治理
如何存储这些数据
集中式存储
分布式存储
如何进行数据架构设计
ER图
实体
属性
联系
产品架构
基础的产品框架脱胎于业务流程,但相比业务流程,更加注重产品功能的美剧,功能模块之间的划分
应用架构
应用架构是说明产品架构分哪些应用系统,应用系统间如何集成
原则
简单性
灵活性
整合性
技术架构:技术架构是应接应用架构的技术需求,并根据识别的技术需求
微服务
核心关键点
服务治理
服务注册与发现
CAP定理
概念
(Consistency)一致性(数据)
(Availability)可用性(服务)
(Partition tolerance)分区容忍性(是否允许节点之间无法通讯)
应用
Zookeeper:CP原则
eureka:AP原则
实现原理
服务注册(Register)
服务续约(renew):心跳检测
服务下线与剔除
服务获取
负载均衡
核心
服务发现
服务监听
服务选择策略
组件(Ribbon)
服务器列表
静态服务列表
基于名字发现服务的服务器列表(默认方式)
服务器列表过滤器
ZoneAffinityServerListFilter(基于区域感知)
ServerListSubSetFilte(基于区域感知并返回固定大小的列表)
服务实例存活探测
pingURL:通过定期访问指定url判断服务是否存活
pingConstant:不做任何处理,只返回一个固定值,默认true,
NoOpPing:直接返回true
负载均衡策略
轮旋策略(RoundRobinRule)
随机选择(RandomRule)
最大可用策略(BestAvailableRule):过滤掉不可用服务之后,选择当前并发量最小的服务
根据相应时间加权(WeightedResponseTimeRule):
可用过滤策略AvailabilityFilterRule
区域感知策略(ZoneAvoidanceRule)
负载均衡器
服务调用器
服务状态监控
服务网关
服务容错
服务间通信
服务监控
统一配置
服务安全
服务部署
数据库
关系型数据库
mysql
事务
特性(ACID)
原子性(Atomicity)
不可分割的操作单元,事务中所有操作,要么全部成功,要么全部失败撤回到执行前的状态
一致性(Consistency)
如果在执行事务之前数据库是一致的,那么执行结束之后数据库也是一致的
隔离性(Isolation)
事务操作之间彼此独立和透明,不会互相影响,
持久性(Durability)
事务一旦提交,结果就是永久的,即使系统发生故障,也能恢复
事务隔离级别
读未提交
脏读
读已提交
可重复读
可串行化
实现原理
重做日志文件(redo log)
回滚日志文件(undo log)
异常情况
脏读
幻读
不可重复读
锁
类型
表级锁
意向锁
类型
意向共享锁
意向排它锁
作用
快速判断表锁和之前可能存在的行锁冲突
实现
行锁在加锁之前必须先添加意向锁
页级锁
行级锁
排他锁(写锁)
共享锁(读锁)
间隙锁
当使用范围条件检索数据并请求锁时,innoDB会给符合条件的已有数据记录的索引项加锁,对于存在在条件范围以内但是并不存的记录也会加锁
如果使用相等条件请求给一个不存在的记录,那么该记录也会加锁
优点
主要是为了防止幻读
缺点
子主题
实现
innoDB行锁是通过给索引上的索引项加锁来实现的
如果不通过索引条件查询时,innoDB会使用表锁,而不是行锁
虽然是访问不同行的记录,但是如果使用相同的索引键会导致锁冲突
当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行
即使在条件中使用了索引字段,但是是否使用索引来检索数据还是有mysql通过不同的执行计划决定
ORACLE是通多在数据块中对应的数据加锁来实现
索引
索引类型
主键索引(Primary Key)
唯一索引(unique Key)
组合索引
索引数据存储方式
聚簇索引
在同一个Tree上同时保存索引列和数据列
优点
索引和数据存储在一个B-tree,通过聚簇索引可以直接获取数据,不用进行二次查询
对于范围查找效率很高,因为数据都是从小到大排列
缺点
更新代价较大
插入速度严重依赖插入顺序
辅助索引()
叶子节点上保存的是行的主键值而不是行的物理地址
子主题
索引失效
使用<>查询
索引列使用函数
like没有用到最左匹配
联合索引没有遵循最左匹配
存储引擎
MyiSAM
支持表锁
特点
不支持事务
存储方式
存储表定义.FRM
存储数据文件.MYD
存储索引.MYI
索引实现
非聚餐索引
叶子节点存放数据的地址
innoDB
使用行锁
特点
支持事务
自增长列
必须是索引
如果是组合索引,比如是组合索引的第一列
外键索引
存储方式
innodb_file_per_table参数控制
共享表空间(默认方式)
每一个数据库所有表数据,索引都存储在一个文件中
优点
可以将表空间分为多个文件存储在不同的磁盘上, 分布IO,提高性能
表数据和表结构在一起,方便管理
缺点
由于数据和索引都存储在一个文件,导致如果一个表缩 了大量的删除之后,表空间会产生大量的空隙
独占式表空间
每张表对应独立的表空间,表结构存储在.frm文件中, 数据和索引保存在.idb中
优点
每张表都有独立的表空间,可以实现单表在不同数据库之间移动
空间可回收
drop table 会自动回收
数据删除后,可通过alter able emp engin=innodb回收不用的表空间
缺点
由于每个表的数据都是单独文件存储,会受到文件系统大小的限制
索引的实现
主键索引(聚簇索引)
主键索引的叶子节点存储的是key和数据
叶子节点载入内存时数据一起载入
辅助索引(二级索引)
辅助索引的叶子节点存储的是ey和对应的记录的主键值
使用辅助索引查询,首先检索辅助索引获取主键, 然后根据主键索引到主索引中获取记录
MVCC (多版本并发控制)
允许非阻塞读
写操作只阻塞必要的记录
innerDB实现
存储了每一行的两个(1)额外的隐藏字段,这两个隐藏字段分别记录了行的创建的时间和删除的时间。在每个事件发生的时候,每行存储版本号,而不是存储事件实际发生的时间。每次事物的开始这个版本号都会增加。自记录时间开始,每个事物都会保存记录的系统版本号。依照事物的 版本来检查每行的版本号。
锁类型
共享锁
排他锁
表级意向锁
锁算法
record lock
单行加锁
行锁实现
在不使用索引的情况下,使用表锁
由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。
当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁。
即便在条件中使用了索引字段,但是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的
不同索引
主键索引
查询条件存在数据的情况锁住一行记录
唯一索引
查询条件存在数据的情况下,锁住一行记录
子主题
gap lock
间隙锁,锁定范围
当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁
目的
防止幻读
为了满足其恢复和复制的需要
next-key
锁定一个范围并锁定记录本身
insert intention
日志文件
特性
重做日志
redo log
作用:确保事务的完整性,在事务开启之后产生,写入物理数据页面修改的信息,当事务的脏页写入磁盘之后结束,
回滚日志
undo log
确保事务的一致性,保存事务发生之前的数据版本,可用于回滚,也可以提供mvcc模式下的读,及非锁定读,在事务开始之前产生,
非锁定读:当用户读取某一条记录的时候,如果该记录被其他事务占用,当前事务可以通过undo读取之前的版本信息
二进制日志
binlog
1.用于复制,主从同步,2.基于时间点的数据还原
错误日志
慢查询日志
一般查询日志
中继日志
对比
redo log 和undo log都是一种恢复操作,redo恢复事务修改的页操作,undo回滚记录到某个特定的版本,
子主题
子主题
memory
数据存储在内存中
子主题
内存数据库
redis
redis实现原理
支持的数据类型
String
Hash
List
Set
zset
通过score进行排序
底层数据结构
字符串对象
int
普通字符串
raw
子主题
子主题
sds简单动态字符串
embstr
3.0新增,如果字符串长度小于39,使用embstr,否则用raw
优点
只需要分配一次内存(raw需要两次,一次为sds分配对象,第二次为object分配对象,embstr只有第二次)
缺点
只读形式,如果要修改,需转化为raw进行修改
列表对象
ziplist
压缩列表
优点
节省内存空间,连续的内存区域
缺点
为了保证连续,插入复杂度O(N),每次插入需要重新分配空间
linkedlist
双向链表
哈希对象
ziplist
当数据量较小的时候,按照key1,value1,key2,value2这样的顺序存储,数据量较小时,效率很高
hashtable
集合对象
intset
整数集合
集合
16位
32位
64位
特点
通过标记类型来自动升级底层数组
节约内存,超出才升级类型
不支持降级
hashtable
有序集合对象
ziplist
子主题
skiplist
跳跃表
有序集合的快速查找
dict
过期策略
定时删除
在设置过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,对键采取删除操作
优点
保证过期键会尽可能快的被删除,释放占用的空间
缺点
比较耗CPU,需要占用一部分的CPU时间
惰性删除
在每次从键空间中获取时,检查获取的键是否过期,如果过期,则删除,否则返回该键
优点
对CPU友好,只在取出的时候,对过期键进行检查
缺点
对内存不友好,如果一个键已经过期, 但是一直未被调用,则不会进行清理,会一直占用内存
定期删除
每隔一段时间,会对数据库进行一次检查,如果存在过期,则删除
内存淘汰策略
noeviction
当空间不够时,新写入报错
allkeys-lru
最近最少使用
allkeys-random
随机移除
volatile-lru
当空间不够的时候,在设置了过期时间的键空间中,移除最近最少使用的key
volatile-random
当空间不够时,在设置了过期时间的键空间中,随机移除某个key
volatile-ttl
在空间不够的时候,在设置了过期时间的键空间中,有更早过期时间的key优先移除
数据持久化
类型
RDB(快照)
核心函数
rdbSave
rdbLoad
AOF(增量)
核心函数
flushAppendOnlyFile
混合型持久化
集群
分类
主从模式
特点
主数据库可以进行读写操作,当读写操作导致数据变化是会自动同步到从数据库
从数据库只读,接受主数据库同步过来的数据
一个master可以有多个slaver,单一个slaver只能有一个master
工作机制
slave启动之后,会主动向master发送SYNC命令,
子主题
哨兵模式
实现原理
三个定时监控任务
每个10s,每个哨兵节点会向主节点和从节点发送info命令获取最新的拓扑结构
每隔2s,每个哨兵节点会向某频道发送该节点对于主节点的判断以及当前哨兵节点的状态
每隔1s,每隔哨兵节点向主节点,从节点和其余哨兵节点发送一个命令做一次心跳检测,来确认这些节点是否可达
集群模式
应用场景
缓存
队列
计数器
发布/订阅
memcache