Java架构之路
2021-09-25 18:09:21 0 举报
AI智能生成
Java架构之路,循序渐近
作者其他创作
大纲/内容
Zookeeper
功能
分布式锁
配置管理
集群管理
数据模型
属性的目录服务
命令
客户端命令
基础命令
1.连接Zookeeper服务端
./zkCli.sh -server ip:port
2.断开连接
quit
3.设置节点值
set /节点path value
4.help
查看帮助命令
5.删除单个节点
delete /节点path
6.显示指定目标下节点
ls 目录
7.删除带有子节点的节点
deleteall /节点path
8.创建节点
create /节点path value
9.获取节点值
get /节点path
高级命令
1.创建临时节点(会话关闭删除)
create -e /temp1 value
2.创建顺序节点
create -s /app1 value
3.创建临时的顺序系节点
create -es /temp_order1 value
4.列出子节点和附加信息
ls2 /节点path
ls -s /节点path
服务端命令
启动服务:./zkServer.sh start
查看服务状态:./zkServer.sh status
停止服务:./zkServer.sh stop
重启服务:./zkServer.sh restart
Curator
Apache Zookeeper 的客户端
其他Api
原生Api
ZkClient
集群
Leader
Follower
选举
投票
1. 基于编号大小投票
2.基于启动时间的大小
3.基于事务id,最新的代表能力越强
分布式锁
利用建立瞬时顺序节点
发布订阅节点状态,比较自己的顺序是不是所有节点中最小的,最小的获取锁成功
Redis
基本数据类型
String
List
Hash
Set
Zset
BitMap
Geo
HeperLoglog
Stream
发布与订阅的持久化,类似消息中间件
分布式锁实现原理
单机锁在分布式情况下,也会导致数据冲突问题
1.保证加锁互斥,由于天然单线程,使用setNx不会出现两个线程同时获取到锁
2. 防止死锁,需要带上健壮性,但防止宕机导致锁不能释放,需设置过期时间
3.设置过期时间可能不够业务执行,则需要进行过期时间异步守护线程续期
4.同时需要保证释放锁操作不能释放到别人的锁,所以需要增加本线程唯一标识来判断是否自身锁释放
5.为了保证续命守护线程被挂起不能续命,则需要防止其它线程进来,所以需要保证删除操作的原子性
6.保证原子性可以使用事务保证,也可以使用lua脚本保证
7.防止在集群模式下主从节点的不一致性,导致加锁失效,则需要保证一半以上的节点都加上锁,所以采用Redisson
8.Redisson释放锁的时候也需要进行是否为自身持有锁和锁定状态
Redis的过期策略
定时清除
可能导致CPU空转
惰性清除
极端情况下可能导致空间浪费
定期清除
结合上面两种进行随机部分扫描清除
也可能导致一些数据不能清除
内存淘汰策略
1.不排挤
2.新添加数据是内存不够用,则在设置了过期的key中LRU淘汰
3.新添加数据是内存不够用,则在所有的key中LRU淘汰
4.新添加数据是内存不够用,则在设置了过期的key中LFU淘汰
5.新添加数据是内存不够用,则在所有的key中LRU淘汰
6.新添加数据是内存不够用,则过期的key中淘汰即将过期的key
7.新添加数据是内存不够用,则在设置了过期的key中随机淘汰
8.新添加数据是内存不够用,则在所有的key中随机淘汰
事务
乐观锁:使用 Watch key监控字段变更配合事务完成
Multi开启事务、Exec提交事务
经典问题
缓存击穿/穿透
缓存雪崩
集群模式
主从复制:异步线程复制
不能达到数据强一致性
节点宕机需要手动选举
浪费空间,不利于扩容
读写分离,降低压力
利于容灾恢复
哨兵模式
自身集群化保证高可用
监控主从节点,选举主节点
集群模式
利于扩容
依然需要哨兵坚守
每个节点存储不同的数据。利于扩容
采用hash插槽
无中心化,超过半数ping超时认为某个节点宕机
发布与订阅
punlish
subscribe
持久化
RDB
采用定时持久化到磁盘
可能存在丢失数据
AOF
采用执行命令追加模式
实时性比较高,丢失数据缩小在1秒范围
分布式Session
高并发秒杀系统
追求目标
快(高性能)
快速响应处理请求
准(一致性)
处理准确无误
稳(高可用)
服务高可用
核心要点
并发读
并发写
分布式锁
优化
页面优化
页面缓存
URL缓存
对象缓存
静态资源化
服务优化
Redis缓存
内存标记减少redis访问
异步任务
中间件削峰
数据库性能优化
安全优化
秒杀之前隐藏地址
双层MD5加密
MD5(MD5('密码',SALT),SALT)
前端MD5加密再后端加密
分布式会话
用户登录
共享session
功能开发
商品列表
商品详情
秒杀
订单详情
系统压测
Jemeter
自定义变量
正式压测
中间件
Kafka
RabbitMQ
RocketMQ
作用
解耦
异步
削峰
场景
用户进行注册操作
注册信息存储之后需要发送邮件和短信通知
将邮件和短信通知改为异步消息队列,发送到对应微服务
组件
NameServer
Broker
接收消息
存储
投递
发送消息
步骤
1.创建生产者,指定生产者所属的组名
2.指定NameServer的地址
3.启动生产者
4.创建消息对象,指定主体,标签和消息体
5.发送消息
6.关闭生产者
类型
同步保证
异步保证
单向非保证
顺序消息
hash
事务消息
投递消息到Broker
发送给生产者半事务消息成功,
生产者执行本地事务发送给Broker进行成功投递还是回滚
如果Broker没有收到二次确认会保留三天然后删除
消费者消费
1.创建消费者对象,指定消费者所属的组名
2.执行NameServer地址
3.指定消费者订阅的主体和标签
4.设置回调函数,编写处理消息的犯法
5. 启动消费者
集群
1.多Master
2.多Master-Slave,异步复制
3.多Master-Slave,同步双写
4.多Master-Slave(2)
ZeroMQ
ActiveMQ
Kafka
概念
Topic
Partition
分配分区策略
轮询分配
写入的消息中key为null
指定key hash分区
随机分配
不推荐使用
Replica
leader
follower
机制
同步双写
选举:会维护一个ISR(In Sync Replicas),选取ISR中最好的(同步信息最靠前的)
OSR(Out of sync Replica):未同步的副本
AR: 所有的副本
OffSet
幂等性
避免多次生产
每个生产者有个pid和每个分区存在一个增序的number
组件
集群管理Zookeeper
Broker
Leader
管理Partition的选举
Flollwer
选举
下发通知到其它flollwer由各自到去Zookpeer建立临时节点
Producer
Consumer
Cousumer Group
消费者规则
一个消费者组中可以包含多个消费者,共同来消费Topic的数据
一个topic中如果只有一个分区,那么这个分区只能被某个组的消费者消费
有多少个分区,那么就被同一个组的多少个消费者消费
再均衡(Rebalance)
最好的高吞吐量,一个分区对应一个消费者
当消费者组消费者数量发生变化,会触发再平衡
消费分区分配策略
Range范围分配策略
公式
分区数量/消费者数量 = 每个消费者获取的分区数量
多余的分区依次分配给前面的消费者
轮询分配
轮询依次分配给每个消费者
粘性分配
减少:尽量再分配余下的消费者依次分配原来减少的消费负责的分区
增加:重新调整RangRound分配
问题
消息乱序问题
根据不同写入分区分配策略可能导致消息分配到不同的分区,导致了消息没有先后顺序
解决办法:使用keyhash分区策略,使得相同类型的消息分配到同一个分区,使得由同一个消费者进行消费
集群可视化管理工具
Kafka-Eagle
数据存储
每个topic有多个分区存储
每个分区下有多个Segment
每个Segment下有log、index、timeindex
数据丢失
Broker丢失
分区副本保证
生产者消息不丢失
ACK
1. 所有副本都完成存储
2.leader存储成功
3.不保证,只发信息
消费者消息不丢失
最多一次
消息丢失
最少一次
重复消费
仅有一次
利用自己维护offset与数据库事务保证
数据积压
如果是故障导致积压需解决故障,可以增加临时扩展
业务积压,临时增加消费者
数据清理
日志删除
基于时间的保留策略
基于日志的大小保留策略
基于偏移量的保留策略
日志压缩
相同key的不同值合并为最新的
分布式服务
服务架构演变
1.单体应用架构
所有的业务模块融合在一个应用系统中
系统耦合度较高,单点故障,不利于扩展(造成冗余)
2.垂直应用架构
在单体架构基础上大体拆分,前台服务,后台服务
3.分布式架构
服务按照模块拆分,比如用户模块、订单模块、商品模块、新闻模块
暴露服务依然是前台服务、后台服务
4.SOA架构
在分布式架构的基础上解决依赖错综复杂,加入了服务治理中心
5.微服务架构
将业务原子化拆分(垂直拆分)
所有微服务直接对外暴露
增加网关 APi GateWay
问题延伸解决
1.服务治理
2.服务之间调用,RPC、Http Resutful
3.服务容错
4.链路追踪
5.服务网关
Spring Cloud
Spring Cloud Alibaba
主要功能
服务限流降级
问题
服务雪崩
多个微服务之间存在依赖关系,一旦一个服务存在故障,可能导致连锁反应
原因
不合理的容量设计
高并发下某个方法响应变慢
资源耗尽
服务容错
隔离
线程池隔离
信号量隔离
超时
限流
熔断
组件
Hystrix
Netflix开源服务容错,可用性
Resilience4j
轻量、简单
Sentinel
功能
流量控制
控制线程数量
服务降级
负载保护
控制界面
DashBoard
概念
资源
保护东西:可以是系统,方法,代码片段
@SentinelResource
定义资源
blockHandler设置处理异常(BlockException)逻辑
本类定义异常方法处理
fallBack:定义发生异常后进入的方法
规则
如何是保护资源
分类
流控规则
流控模式
直接流控
关联流控:其它资源达到阈值触发
链路: 指定请求来源
流控效果
快速失败
排队等待
WarmUp
突然增大流量转为缓步增长
降级规则
平均响应时间(RT)
响应时间阈值
时间窗口:降级时间
异常比例
单位时间内异常数与通过比值
异常数
单位时间内(1分钟)的异常数量
热点规则
更加细粒度的控制
具体参数级别的控制
授权规则
控制请求来源
系统规则
面向整个系统整体的负载控制流量
核心思想
1. 保证自身不被下游拖垮
服务降级
服务熔断
2.保证不被上游压垮
服务隔离
服务超时
服务限流
3.保证自身不被外界影响
集群负载
保证平衡
规则持久化
定义持久化配置文件到客户端本地
Feign对Sentinel支持
在@FeignClient(fallBack=FallBackGHandler.class)
服务注册与发现
Zookeeper
Eureka
Consul
Nacos
Spring Cloud Ribbon负载均衡
自定义客户端负载均衡
Feign 基于http rest 服务之间调用,自定负载均衡
服务网关
功能
服务发现
服务认证、鉴权
服务跨域
实现组件
Nginx+Lua
Kong
Zuul
Spring Cloud Gateway(推荐)
依赖导入(spring-cloud-starter-gateway)
路由规则
断言(匹配)
日期
主机
请求方式
请求参数
过滤器(请求处理)
类型
请求之间(Pre)
请求之后(Post)
内置过滤器
鉴权
认证
网关限流
路由维度
自定义Api维度
链路追踪
微服务调用链路
实现组件
Cat
Zipkin
数据持久化
Mysql
ZipKin启动的增加存储方式为Mysql
ElasticSearch
ZipKin启动的增加存储方式为ES,及相关信息
Kibana
收集、存储,分析,展示
Sleuth(推荐)
采集
进行记录Trace、Span
Pinpoint
Skywalking
概念
Trace
一次完整的请求链路路径
Span
CS:客户端发出请求,开始一个请求的生命
SR:服务端接收到请求开始处理,SR-CS=网路延迟(服务调用时间)
SS:服务端处理完毕准备发送到客户端,SS-SR=服务端上的请求处理时间
CR:客户端接收到服务端的响应,请求结束,CR-SR=请求的总时间
分布式配置管理
实现组件
Apollo
携程开源
Disconf
SpringCloud Config
Nacos Config
分布式事务
微服务下的多个事务控制问题
解决方案思路
全局事务
提供一个第三者,全局事务管理器,各个事务进行预先提交,如果判断预提交可以成功,上报给全局事务管理器,如果全部事务都成功了,全局事务就下达真正提交事务,依然可能存在出错
基于可靠消息事务
RocktMq事务
最大努力通知
TCC
Try Confim Cancel
补偿型分布式事务
三个步骤
1.尝试执行业务
2.确认执行业务
3.取消待执行业务
实现组件
Seata
事务管理器
全局事务协调器
资源管理器
分布式任务调度
消息驱动
组件
1.Sentinel
把流量作为切入点、从流量控制、熔断降级、系统负载等多个维度保护服务的稳定性
2.Nacos
一个更加易于构建云原生应用的动态服务发现,配置管理和服务管理平台
3.RocketMQ
一个分布式的开源消息系统
4.Dubbo
一款高性能的RPC框架
5.Seata
阿里巴巴开源,一个易于使用的高性能微服务分布式事务解决方案
6.Alibaba Cloud ACM
一款在分布式价架构环境中对应用配置集中管理和推送的应用配置中心产品
7.Alibaba Cloud SchedulerX
阿里巴巴中间件团队开发的一款分布式任务调度产品、提供秒级、精准、高可靠、高可用的定时任务调度服务
8.Alibaba Cloud SMS
覆盖全球的短信服务、友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道
9.Alibaba Cloud OSS
对象存储服务
Apache Service Comb
数据结构与算法
算法
算法分析
时间复杂度分析
算法公式结论
1.算法函数中的常数可以忽略
2.算法函数中最高次幂的常数因子可以忽略
3.算法函数最高次幂越小,算法效率越高
大O表示
T(n) = O(f(n))
常见的大O阶
1.线性阶
一次循环
O(n)
2.平方阶
二次循环
O(n2)
3.立方阶
三次循环
O(n3)
4.对数阶
2x=n, x= x=log(n)
O(logn)
5. 常数阶
O(1)
最坏情况
当查询的数据不确定就需要考虑最坏的打算
最坏的时间复杂度为该算法的时间复杂度
空间复杂度分析
对象空间大小
对象头16个字节
引用8个字节
实例数据根据数据类型相加
对齐填充
8位的倍数
数组
除了对象头身大小和实例数据大小
还需要4个字节保存长度
算法分类
排序算法
冒泡排序
进行两次循环,双指针,一个指针定位参与比较的元素,另一个定位比较位置
总是在余下的元素中比较寻找最大或者最小的元素放置最后位置
选择排序
顺序遍历,在余下的元素中找到最小元素的索引与第一个元素交换
插入排序
顺序遍历获取余下的第一个元素,然后与前面已排序的集合倒序遍历比较并交换,直到找到比自己小的元素停止比较
希尔排序
插入排序的优化,先对元素进行分治插入排序,直到为分治进行常规插入排序,这时插入排序的比较交换过程就少了
归并算法
将集合进行分组,直到最小分组(一个组一个元素),从最小的每两组进行双指针比较添加到新的数组,然后写回
快速排序
取第一个作为临界值将集合一份为二,左边小于临界值,右边大于临界值,接着继续对分组后的每组进行再一分为二
堆排序
利用堆有序,将元素转换为堆,然后删除和下层获取的元素就是一个从大到小的顺序,或者将最大值放置最有一个位置,然后进行堆下层,相当于也找到剩余堆元素的最大值
初始化堆:从索引一半的位置进行倒序下层交换
数据结构
线性表
数组
链表
单向链表
双向链表
快慢指针
查找中间值
根据判定快指针是否结束,结束时慢指针即为中间值
查找是否有环
利用快慢指针是否相遇判定
查找环入口
利用快慢指针,先找到环,此时准备一个临时指针,指向链表的首节点,之后继续遍历直到慢指针与临时指针相遇,即为入口节点
约瑟夫问题
循环报数,数到三就自杀,然后又从1开始报数,数到三就自杀,依次自杀,总共41个人,16、31会最后自杀
符号表
有序符号
栈
头插法
解决括号匹配问题
逆波兰表达式
后缀表达式
队列
树
相关术语
节点的度
叶子节点
度为零的节点
分子节点
度不为零的节点
节点层次
从根节点开始,根节点的层次为1,根的直接后继层为2,依次类推
节点层次的编号
将树中的节点,按照从上层到下层,同层从左到右的次序排成一个线性序列,把他们编成连续的自然数
树的度
树中所有的节点的度最大值
深度
树中节点的最大层次
森林
二叉树
满二叉数
每一层都达到最大值:
完全二叉树
查找最大的键
递归向左走
查找最小的键
递归向右走
遍历
基础遍历: 广度优先
前序遍历
先父节点,然后左节点,最后右节点
中序遍历
先左节点,然后父节点,最后右节点
后续遍历
先左节点,然后右节点,最后父节点
层序遍历:深度优先
利用队列入队,然后每个节点的子节点入队,最后整体key队列遍历
利用递归判断左右子树得到大的数,进行累加
最大深度
折纸问题
平衡树
二三查找树
二树:两个子节点
三树:三个子节点
红黑树
目标达到完全二叉查找树
利用平衡树原理,二三查找树
采用红黑节点实现二三查找树
1. 利用红节点将本节点与父节点进行绑定为一个三树,达到一个元素层级提升
2.规定不允许连续的左红节点
3.不允许右红节点
4.根节点永远是黑节点
5.任何一个空节点到根节点的黑节点数量相等(红节点与绑定的父节点一起是为一个黑节点)
B树
扩展二三查找树,变成四、五或者更多阶的查找树
B+树
二三查找树,向上增长,叶子节点存储数据,非叶子节点存储索引,并且节点拆分的时候要保留索引和索引数据
mysql的索引
并查集
基本概念
元素值看作数组索引,索引值为元素的组标识
组标识不同,视为不同的组
默认情况下一个元素视为独立的一个组
不同分组可以进行合并,只需更改当前元素的所属分组标识即可
场景应用
网络中一台台的电脑为独立的元素,要想不同电脑之间能够通信,则需要把他们加入同一个组中(组网)
并查集优化1
起因:由于N个独立组元素,需要N-1次组合并才能达到所有的元素在同一个组
将索引值改为存储父节点,相同根节点视为同一个组
合并时,只需要将其中一个根节点所在的索引值改为另外一个组的根节点的值,即将两个组的根节点的父节点改为同一个
并查集优化2
进一步优化,合并时,将较小深度的根节点的父节点改为较大的组的根节点
目的是为了将树的层级缩小,减少元素查找根节点的次数
需要另外申请一个数组存放指定根节点所在树的元素个数
畅通工程
城市之间的路连通,已经连通多少条,剩余还需要多少条,完成所有城市连通
堆
存储结构
数组方式存储,层序从左到右按序存储
每一个节点都要比它的两个子节点要大于或者等于
两个子节点左右不区分谁大谁小
当前序号为k节点,它的左子节点是2k,右子节点是2k+1, 它的父节点是k/2
插入元素
先插入到数组最后一个位置,然后采用上浮算法进行交换调整位置,直到堆中合适的有序位置
上浮算法:依次与父节点比较,然后大于父节点就交换,然后交换完成后继续与父节点进行交换,直到小于父节点结束
删除最大元素
交换第一个元素(最大元素)和最后一个元素,然后采用下浮算法进行交换调整堆顺序
下浮算法:当前节点与它的子节点找出较大节点比较大于就交换,直到小于截至
优先队列
最大优先队列
利用堆特性,直接删除最大元素,就为优先级别
最大优先队列
将大顶堆进行反向
索引优先队列
采用三个数组进行存储元素
原始数组存储依次
在进行转换为堆结构数据,不直接调整原始数组,而是新加一个数组存储原始数组的索引位置,根据原始数组对应的大小进行跳转索引数组的顺序
第三个数组为存放第二个数组的索引反序,序号和原始数据序号一致,值就是第二个数组的序号
图
存储结构
邻接矩阵
V*2的存储结构,存在空间过多
邻接表(采用)
数组加链表(队列)
数组的索引表示顶点,值表示连接相邻顶点的边,多个边用队列进行一次存储
存在,相反指向,但空间复杂度要少于邻接矩阵
无向图
基本术语
相邻顶点
度
子图
路径
环
连通图
如果图中任意一个顶点都存在一条路径到达另外一个顶点
连通子图
一个非连通图由若干部分组成,每一个连通的部分都可以成为该图的连通子图
深度优先搜索
目标搜索指定元素元素
当搜索到指定顶点的相邻顶点后发现该相邻顶点还有子相邻顶点,则优先递归搜索子相邻顶点
需要另外一个数组标志存储是否已经搜索过
采用递归方式
广度优先搜索
非递归,需借助队列
路径查找
利用深度或者广度优先搜索算法查找从起点到终点,查找的过程记录下当前节点的上一个节点
利用记录下来节点的上一个节点记录,遍历依次存入栈中,然后再进行弹出栈就得到从起点到终点的路径节点
加权无向图
给边增加权重,将邻接表中存储为一个Node表示边
包含边的两个顶点
权重
最小生成树
将所有顶点连通的最少的边组成的图就是一个树
树的性质
1. 用一条边连接树中任意两个顶点都会产生一个新的环
2.从树中删除任意一条边,将会得到两颗独立的树
树的切分定理
1.切分:将树进行任意的切分为两个非空的集合
2.横切边:表示经过一次切分之后,连接两个集合的边叫做横切边
3.在所有横切边中最小权重的边必然属于最小生成树的一条边
4.最小权重的横切边并不是横切边中唯一的最小生成树的边
贪心算法
经过N-1次切分定理找到所有的最小生成树的边
Prim算法
同样是利用贪心算法寻找最小生成树的边
原理
kruskal算法
也是贪心算法的一种优化
原理:利用索引最小优先队列保存图中所有的边,然后依次遍历虽小的边,判断该边是否已经存在最小生成树中,如果存在则不处理,依次寻找所有最小权重的边,并且加入到已存在的最小生成树中。
有向图
基本术语
定义
出度
由某个顶点指出的边的个数称为该顶点的出度
入度
指向某个顶点的边的个数
有向路径
由一系列顶点组成,对于其中的每个顶点都存在一条有向边,从它指向序列中的下一个顶点
有向环
一条至少含有一条边,且起点和终点相同的有向路径
两个顶点
不相连
存在一条边指向它,v-->w
存在一条边指向它,w-->v
存在v-->w, 也存在w->v
拓扑排序
在众多依赖关系中找出依赖顺序,例如学习技术顺序
需要先排除图中存在环的问题
原理:利用深度优先搜索,将已经搜索过的顶点进行标记,当下次搜索到已经标记的顶点表示存在环
基于深度优先的顶点排序
加权有向图
在有向图的基础上增加边的权重
最短路径
最小路径定义和性质
松弛技术
边松弛
1、根据判断起点s到达目标顶点w的总权重是否小于从起点s到达另外一个顶点v的权重加上v到w边的权重之和
2、如果小于则不需要改变,如果大于,则将起点s到顶点v的权重加上顶点v到终点w的权重设置为目前起点s到到w的总权重,并且把从起点s到达终点w的最小路径中上一条边修改为顶点v到w这条边
顶点松弛
将顶点的所有出度的边进行依次松弛得到最小边
Dijkstra算法
1、需要借助索引最小优先队列,存放树中顶点与非树中顶点之间的有效横切边
2、初始化让所有的顶点到目标顶点的权重为无限大
3、让起点直接进入最小路径树中(把该顶点放入队列中),依次去判断获取最小边,然后将该边对应的另外一个顶点放入最小路径树中,接着再去寻找该顶点的所有出度的最小边,依次类推直到找到目标顶点
Java基础
多线程、高并发
1.继承Thread类
2.实现Runnable接口
3.线程池工具类
4.线程池原始类
JUC
集合框架
Collection
List
ArrayList
LinkedList
Vector
Stack
Set
HashSet
LinkedHashSet
SortedSet
TreeSet
Queue
Deque
AbstractQueue
LinkedList
BlockingQueue
ArrayBlockingQueue
数组实现的阻塞队列
LinkedBlockingQueue
多元素链表实现阻塞队列
LinkedTransferQueue
SynchronousQueue
单元素阻塞队列
Map
HashMap
LinkedHashMap
HashTable
TreeMap
IO、NIO、AIO
BIO
基于流的阻塞io,一次请求一次处理,需要开启新的线程去同时处理多个客户端请求
NIO
基于Selector多路复用器,将管理多个Channel,监听他们的状态变化,进而根据状态处理数据
AIO
在NIO多路复用器的基础上将写入或者写出异步化
IO多路复用
JVM虚拟机
JVM内存结构
JVM性能与调优
Mysql
常用SQL语句
查看创建表语句:Show Create Table 表名
查看创建数据库语句:Show Create Database 库名
查看表结构:Descible 表名
清空表数据:TRUNCATE 表名,会清空自增列计数器
优化
SQL和索引优化
1.索引
注意事项
经常作为条件查询的字段
小数据量不要加索引
经常变动的数据不要加索引
重复率高的数据不要加索引
索引命中查看关键字:Explain
分类
1.主键索引
保证主键不可以重复,只能是一个列
2.唯一索引
避免重复的列
可以多个列作为索引(组合索引)
3.常规索引
默认
4.全文索引
快速定位数据
查看索引:show index from 表名
2.代码优化
1.减少 IO 次数
3.降低 CPU 计算
数据库结构优化
字段设计最小化
引擎选择
分库分表
垂直拆分
将字段比较多的表拆分为主从表,提高主表的查询效率
将数据量比较大的表动态拆分(hash、日期、业务规则)多表存储
水平拆分
读写分离分库
系统硬件升级
网络
磁盘
内存
MyISAM和InnoDB区别
1.MyISAM不支持事务
2.MyISAM仅支持表级锁、InnoDB支持表级和行级
3.MyISAM支持全文索引,InnoDB不支持
4.MyISAM不支持外键约束、InnoDB支持外键
5.MyISAM存储了行数,InnoDB需要实时扫描查询
6.MyISAM存储空间较小,InnoDB较大
7.MyISAM清空表是重新建表,InnoDB是一条条删除
三范式原则
1.保证每个字段的原子性不可拆分
2.所有非主键字段必须与主键关联不能存在部分关列,保证单表
3.同一张表不要存在传递性依赖会存在冗余数据
事务
原子性(Automicity)
事务的执行要么都成功,要么都失败
一致性(Consistency)
最终一致性,最后的结果不会操作已有的最大值
隔离性(isolation)
问题
幻读
主要是针对或者删除,两次读取数据量不一致
脏读
一个事务读取到了另外一个事务还未提交的数据
不可重复读
一个事务两次读取某一条数据不一样
隔离级别
读未提交
读已提交
可重复读
串行化
持久性(Durability)
一旦提交就持久化到数据库,不可逆
备份
mysqldump -hlocalhost -uroot -p12345 库名 > 备份文件路径.sql
source 备份文件路径.sql
锁机制
行锁
针对一条记录进行加锁
如果范围查询将升级为表锁
查询时加锁
SELECT * from t_sys_user lock in share mode
SELECT * from t_sys_user for update
表锁
锁定整张表
默认情况,InnoDB如果判断需要加表锁,自行加锁
显示加锁
共享
lock table tablename read
独占
locck table tablename write
解锁
unlock tables
容器化
Docker
安装
在线安装
镜像
拉取镜像
删除镜像
镜像加载原理
Commit提交镜像
容器
运行创建容器:docker run -d -P ...
查看容器:docker ps -a
删除容器:docker rm -f <ContainerId/Name>
启动或停止容器:docker start/stop <ContainerId/Name>
查看日志:docker logs -f -t --tail [行数] <容器id>
查看容器元数据:docker inspectr <ContainerId/Name>
进入容器:docker exec -it <ContainerId/Name> /bin/bash
容器卷
查看容器卷:docekr volume ls
查看卷信息:docekr volume inspect <VolumeId/Name>
数据卷容器:--volumes-from <ContainerId/Name>
Dockerfille
构建命令:docker build -f /home/dockerfile/Dockfile -t lyscms/volume:1.0 .
Docker基本指令
查看镜像构建历史:docker history <镜像id>
发布镜像
登录:docker login -ulyscms
发布镜像
Docker网络
--link 连通各个容器
docker network 网络信息命令
查看网卡列表:docker network ls
查看网卡信息:docker network inspect <netId>
自定义网络
配置连接到指定网络
多个网络之间连接
Docker Compose
安装
授权
使用
Docker Swarm
部署集群
准备4台物理机(Linux)
各个物理机节点之间通信
初始化一个swarm
加入工作节点
创建一个管理节点令牌:docker swarm join-token manager
移除节点:docker swarm leave
查看集群节点:docker node ls
Raft协议
Service
创建服务
查看服务
访问服务
更新服务
修改副本数
扩缩容
删除服务:docker service rm nginx01
Docker Stack
Docker Config
部署SpringBoot
1.编写Springboot并打包
2.编写Dockerfile
3.构建镜像
4.运行容器
K8s
设计模式
模式分类
创建型模式
用于描述如何去创建对象
将对象的创建与使用分离
具体实现:单例、 原型、工厂方法、抽象工厂、建造者
结构型模式
用于描述如何将类或者对象按照某种布局组成更大的结构
具体实现:代理、适配器、桥接、装饰、外观、享元、组合
行为型模式
用于描述类或者对象之间怎么样相互协作共同完成单个独享无法完成的任务
具体实现:模板方法、策略、命令、责任链、状态、观察者、中介者、迭代器、访问者、备忘录、解释器
UML
类表示法
类表示方式
类名称、属性、方法
访问权限
+:公有访问权限
-:表示私有访问权限
#:表示保护访问权限
属性
访问权限 属性名称:属性类型
方法
访问权限 方法名称(参数列表)[:返回值类型]
类与类之间关系
关联关系
单项关联
双向关联
自关联
聚合关系
一对多
菱形指向整体(一)
组合关系
更加强烈的关系
组合双方缺一不可
实心菱形表示,指向整体一方
依赖关系
方法内部的局部变量或者形参
引用外部类,需要外部类支持
使用虚线箭头表示
继承关系
父类与子类之间的关系
空心箭头实线表示,指向父类
实现关系
实现接口
使用带空心三角箭头虚线表示
软件设计原则
开闭原则
扩展开放,修改关闭
里氏代换原则
子类只能扩展功能不能修改父类的的原有功能
所用引用基类的地方可以替换为子类
依赖倒转原则
两个类直接关联,尽可能的将关联部分进行抽象,共同继承抽象类
接口隔离原则
对接口的依赖,不要依赖不需要的接口
采用接口方法拆分
迪米特法则
最少知识法则
尽量减少与陌生人对话,具体实现:代理模式
合成复用原则
尽量先考虑聚合或者组合关系进行依赖,然后再考虑继承
具体实现
创建型模式(5)
单例模式
饿汉式
静态变量
静态代码块
懒汉式
1、静态方法判断为null进行构建,否则直接返回
2、判断过程可能发生多线程都通过,则也会创建多个实例,于是需要对静态方法增加类锁
3、由于类锁时比较重量级锁,所以会影响性能,于是需要将锁细化,进行双重检查锁
4、双重检查锁在外层判断对象是否为空的时候,有可能有一个线程已经在创建对象了,但是可能发生创建对象的指令发生指令重排序,导致外层可能存在线程判断对象不为null,但是该对象还未实例化,所以需要对静态变量对象增加volatile,防止指令重排序
5、利用静态内部类的懒加载特性,在静态内部类增加一个静态终态对象属性,在外部增加一个静态方法,在调用该方法的时候,静态内部类才会被加载,并且被final修饰防止指令重排序
破坏单例模式
序列化
利用ObjectOutprintStream写出,然后读回,会得到另个不同的实例
解决:在单例类中定义一个readResolve()方法
反射
利用反射获取类的构造方法,并且将私有构造权限通过,即可创建新的对象
解决:直接在构造方法中抛出异常,需要保证多线程问题,目前:如果新创建对象之前通过反射修改了标识字段,依然可以重复创建新的对象
工厂模式
简单工厂
定义具体产品, 需要定义产品接口规范
工厂封装创建产品方法,根据具体类型创建不同产品,但返回一样的接口
具体使用方再去根据客户的类型去调用工厂类创建产品
工厂类的创建产品的方法改为静态,使用方直接调用即可
工厂方法模式
相对于抽象工厂来说,只能生产同一级别的产品
抽象工厂模式
生成一个产品族的产品,也就是抽象工厂定义生产不同种类商品的接口,不同的具体工厂按照接口定义实现不同种类产品(属于一个产品族)
模式扩展
简单工厂+配置文件达到工厂类与具体产品进行解构
使用场景
将使用者与创建者解耦,使得使用者不用关系产品创建的细节
是对多个不同产品级的产品族的创建
利于新的产品族的创建
原型模式
用一个已经创建的实例对象作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象
浅克隆
在使用clone方法克隆的时候,新创建的对象本身是深克隆,但是其引用类型的属性还是浅克隆(依然指向原来的同一个对象)
深克隆
新对象的引用类型的属性也会复制一份(不是指向的同一个对象)
实现:采用序列化,然后反序列化回来就是一个深克隆
建造者模式
创建复杂对象
将组装和部件构建分离
扩展:lombok.builder
结构型模式(7)
代理模式
静态代理
动态代理
JDK代理
Proxy,newProxyInstance()
需要实现接口
CGlib代理
引入三方包
创建Enhancer
适配器模式
类适配器(违背合成复用):适配器类实现正常业务接口,并且继承被适配对象
对象适配器:将继承改为集合,通过构造器传入被适配者对象,在接口方法调用成员属性的方法达到接口适配的目的
装饰者模式
在原有的对象增加一点修饰或者说是扩展
实现
需要定义一个抽象装饰着类,需要继承原对象的抽象类
在抽象装饰者类聚合原有对象,并且实现抽象类方法
依赖倒转原则
桥接模式
用于在两个维度独立变化的场景
播放器需要支持在不同操作系统下播放,同时需要支持不同的视频格式文件播放
实现
1.将两个不同变化的维度户进行独立抽象化
2.在抽象层在一个抽象类聚合另外一个抽象类
3.不同的变化通过实现抽象类体现
4.使用时传入具体的实现类
外观模式
也叫门面模式
将多个子系统类用一个门面类进行一对多的组合关系依赖,到达在门面类统一管理
组合模式
将公有的方法或者属性进行抽象化,各个节点对外统一接口,部分类型接口部分实现,达到对外统一化,并且节点之间通过聚合关系进行组合
应用场景:树结构数据,公共的属性或者方法进行抽象,各个节点之间进行组合
享元模式
单例共享一个享元对象,共有使用
内部状态
共有
外部状态
形参传递动态
实例:Integer.valueOf()
行为型模式(11)
模板方法模式
将能复用的方法进行抽象
不能复用的方法进行具体类的实现
策略模式
多种算法:多态完成选择具体算法
使用多分支判断替换
命令模式
将命令发起者与命令执行者解耦
实现:利用命令类集成命令发起的信息与执行者聚合
责任链模式
链式处理
filterChain
状态模式
状态的变化与具体的动作具有影响作用
默认实现采用if判断或者switch
将分支判断进行对象化,将动作封装,每个状态类具有每个动作,自己判定当前状态的动作可执行
观察者模式
监听器
JDK java.util.Observable
中介者模式
多个之间依赖交错复杂
利用一个中介者来维护关联关系
迭代器模式
集合迭代器
迭代器用于遍历集合信息
访问者模式
将元素方法执行交由给访问者来执行
备忘录模式
快照模式
对一个类的内部状态进行快照存储,方便在需要的是时候进行恢复
解释器模式
MyCat
建立一个服务端模拟一个数据库引擎
由MyCat服务端去与真实的mysql服务接口,用户只需要与MyCat进行交互
实体数据库和表还是需要在对应的物理数据库中进行创建
配置文件
1.sever.xml
System标签
user标签
firewall标签
2.schema.xml
table
垂直拆分
不同的表结构分布到不同的物理数据库中
水平拆分
相同的表结构,数据按照不同的分片规则分布到不同的物理数据库中
3.rule.xml
范围分片
取模分片
范围取模分片
枚举分片
hash分片
4.sequence.xml
自定义id生成器
读写分离
mysql的主从复制:主数据库开启bin log日志将事务提交生成一个事件保存到日志
从数据库定期(单独线程)拉取日志数据,生成relay日志(中继日志),又开启一个读取日志写入到从数据库
双主双从
双主备
双主项目进行复制
mycat开始balance,进行负载双主或者单主替换
0 条评论
下一页