java 核心
2024-08-28 14:19:08 1 举报
AI智能生成
java 核心知识点
作者其他创作
大纲/内容
InnoDb
表级别锁,插入与查询速度较快,更新速度慢,不支持事务。一般适合做报表类
MyIsam
数据存放内存,读写速度快,数据库重启崩溃会丢失数据,适合做临时表
Memory
数据存放CSV文件,不支持索引,适用于导入数据之类场景
CSV
存储引擎
左小右大
优点:结构简单 缺点:树深度不够平衡
二叉树
子树深度差值不能超过1
优点:解决二叉树问题 缺点:数据量大树太深,IO次数过多,innerDB加载page 16KB,空间浪费问题
平衡树
节点拥有子树数量叫度
页分裂/合并 保持树的平衡
频繁修改索引值,无序的值会导致页频繁分裂,合并
B 树
B树加强版
只有在叶子节点上存储数据
叶子节点之间是双向指针
B+树(innoDb)
数据结构(排序)
innoDb不能使用哈希索引,特殊引擎可以使用Memory
通过hashCode映射查找数据,效率快,但存在hashCode碰撞问题
无序索引,比较等操作都不支持
Hash索引
BTree索引
索引类型
通过*.myi文件找到地址,在*.MYD查找到相应的数据
*.myi(索引文件)
*.myd(数据文件)
myisam
叶子节点存储的数据(聚集索引)
叶子节点存储的是主键索引值(非聚集索引)
*.idb 数据跟索引
innodb
索引存储
2.个数不宜过多
3.离散度低的字段不宜建立索引 如性别
4.经常需要更新的字段
5.无序的值不宜建立索引
6.复合索引 离散度高的建立在前
7.过长的字段,使用前缀索引(字段长度截断)
使用原则
索引
作用:主从复制,数据恢复
提交事务时候追加写
优点:日志量少,IO少,性能好
缺点:不同版本SQL语句不兼容问题,master与slave执行相同函数不同结果问题
Statement(记录SQL语句)
优点:没有兼容性问题,无BUG
缺点:日志量大,性能差
Row(记录修改前后值)
Mixed(Statement与Row的混合)
模式
作用:服务异常崩溃,数据恢复
redolog效率高,顺序IO,安装目录lb_logfile
大小固定,默认48M,追加写,写满触发刷脏
redolog
作用:事务日志,回滚事务,保证原子性
undolog
内存缓冲区 提升读写性能 inner_buffer_pool
热数据区
冷数据区(新访问数据进入)
内存淘汰LRU算法
1.缓冲操作到change_buffer
2.数据在buffer_pool中直接更新
执行流程
change_buffer(非唯一性索引数据操作)
0 事务提交后 每1秒将数据刷到磁盘
1 事务提交立即刷新磁盘
2 事务提交 写入操作os系统缓冲区,os操作系统每隔1s刷到磁盘
innodb_flush_log_at_trx_commit参数
log_buffer(redolog缓冲区)
buffer pool
1.从buffpool查找数据,未查到从磁盘查找,加载到server执行器
2.更新Server执行器数据
3.记录undolog 更新前原数据
4.记录redolog 更新后数据
5. 更新buffpool 原数据更改成更新后数据
6.Server 层记录binlog
7.提交事务 , 刷脏
更新
执行顺序
日志
原子性A
隔离性I
持久性D
一致性C
特性
innoDb快照读
脏读(未提交读)
innoDb加行锁
幻读(已提交读,add)
不可重复读(已提交读,update/delete)
MVVC
脏读问题
幻读问题
不可重复读问题
RU(未提交读)
高并发推荐,不加行锁
RC(提交读)
幻读问题(innodb通过行锁解决幻读问题)
系统默认,并发小,强一致性推荐
RR(可重复读)
解决任何问题,效率差
SZ(串行化)
如何选择隔离级别
隔离级别
事务
=查询,命中记录
记录锁
=查询,未命中记录
间隙锁
临间锁
1.互斥
2.不可剥夺
3.持有并等待
发生条件
1.顺序访问
2.数据排序
3.申请足够级别的锁
4.避免没有where条件更新
5.事务拆分,大事务拆小
6.少用范围查询
如何解决
死锁
锁(锁定主键)
先大后小(3-2-1)
从上往下
id(查询序号)
简单查询
SIMPLE
包含子查询的主查询
PRIMARY
子查询
SUBQUERY
临时表
DERIVED
联合查询
UNION
select_type(查询类型)
table(查询的表)
partitions(分区)
主键索引/唯一索引查询
const
系统表查询
system
关联查询 匹配主键索引/唯一索引
eq_ref
匹配索引 最左匹配原则
ref
匹配索引 范围查询
range
索引全部扫描 返回所有索引
index
全表扫描
All
type
possible_keys(可能用到的索引)
key(实际用到的索引)
key_len(索引长度)
ref(索引比较的列)
rows(预估扫描行数)
filter(按表条件刷选行的百分比)
使用覆盖索引
using index
存储引擎拿到多余数据 需要过滤
using where
索引不能排序 需要额外排序
using filesort
索引使用临时表
using temporary
extra
执行计划(Explain)
是否启用慢sql查询日志 默认0 0-否 1-是
slow_query_log
指定慢sql日志位置以及文件名称
slow_query_log_file
慢sql执行阈值 默认10 单位s
long_query_time
慢sql 输出目标 默认是file 即输出到文件
log_ouput
输出文件显示时区 默认UTC 建议更改成SYSTEM
log_timestamps
是否记录未使用索引查询的语句 默认未off
log_queries_not_using_indexes
开启慢SQL日志(/etc/my.cnf)
mysqldumpslow
MySQL Enterprise Monitor
分析慢sql
慢sql
show VARIABLES like '%max_connection%'
服务端最大连接数
show variables like '%max_user_connections%';
每一个用户的最大连接数
show full processlist
数据库链接情况
当前连接中各个用户的连接数
当前连接中各个IP的连接数
当前连接中连接时间最长的的连接
show global variables like 'wait_timeout';
查询链接超时时间
性能监控
问题排查
mysql
缓存
分布式session
分布式锁setnx
分布式ID
限流Spring Cloud
应用场景
设置单个/多个Key的值
set/mset
获取单个/多个key的值
get/mget
获取单个Key对应值长度
strlen
在key的值末位添加Value
append
从start-end截取字符串
getrange
递增相应的值
incr/incrby/incrbyfloat
递减相应的值
decr/decrby
操作命令
String(KV结构)
一个key对应多个键值对
1.节省空间 2.减少key冲突 3.减少资源消耗
优点
1.无法单独设置TTL time 2.分片存储不适合
缺点
设置单个/多个哈希值
hset/hmset
获取单个/多个哈希值
hget/hmget
获取所有的key
hkeys
获取所有的value
hvals
获取所有键值对
hgetall
判断某个field是否存在
hexists
对某个字段递增
hincrby/hincrbyfloat
获取元素个数
hlen
删除某个元素
hdel
Hash
有序集合 从左到右
向左添加元素 添加 a b 生成b-a
lpush
向右添加元素 添加 a b 生成 a-b
rpush
向左取出元素 如 a-b 取出 a-b
lpop
向右取出元素如 a-b 取出 b-a
rpop
从index处取出元素
lindex
从start-end取出元素
lrange
List
存储的String的无序类型的集合 集合成员唯一
集合添加数据
sadd
获取集合数据
smembers
获取集合成员个数
scard
随机返回N条成员
srandmember
移除并返回集合中一个随机元素
spop
移除集合中元素
srem
判断元素是否存在集合中
sismember
返回一个集合不存在另外一个集合的元素
sdiff
返回相同元素 交集
sinter
返回不同元素 去重
sunion
Set
有序集合
添加多个元素 score 越小越靠前
zadd
zcard
获取score 在min与max之间成员个数
zcount
对key的field增加score分数
zincrby
列举索引在min与max之间所有字段
zrange
列举区间内的成员。的位置按分数值递减(从大到小)来排列
zrevrange
列举出score 为min与max之间所有字段
zrangebyscore
移除一个元素
zrem
获取一个元素下标索引位置
zrank
获取一个元素分值
zscore
ZSet
数据类型
优点:实时性高,清理内存
定时过期(redis 不采用)
平衡了系统cpu与内存问题
redis 默认是每隔一段时间就随机抽取一些设置了ttl的 key,检查其是否过期
定期过期
优点:不会消耗cpu
缺点:当大量key过期了一直没有被访问,就会占用大量内存
获取 key 的时候,如果此时 key 已经过期,就删除
惰性过期
过期策略
maxmemory 2GB设置最大内存
maxmemory-policy allkeys-lru 设置内存淘汰策略
操作配置
随机删除
random
每个key 都带有lru属性字段,包含访问时间
get key时候更新lru属性字段的访问时间
实现原理
最近最少使用(根据访问时间 推荐)
lru
Lru属性字段增加counter字段 计算字段访问频率
1. 首先根据数据的访问次数进行筛选,把访问次数最低的数据淘汰出去
2. 如果两个数据的访问次数相同,再比较两个数据的访问时效性,把距离上一次访问时间更久的数据淘汰出去
最不经常使用(根据访问次数)
lfu
优先淘汰更早过期的键值
ttl
从不淘汰
noeviction
内存淘汰策略
内存淘汰机制
内存淘汰
900s内有1个Key 发生了变更触发备份
save 900 1
生成的rdb文件
dbfilename dump.rdb
压缩rdb文件 节省空间 但是消耗cpu
rdbcompression yes
验证rdb文件完整性
rdbchecksum yes
内容紧凑 占用空间小
不影响主进程
恢复快
可能会丢失数据,可靠性低
优缺点
rdb(默认 记录视图)
开启AOF
appendonly yes
aof 文件名称
appendfilename “appendonly.aof”
每次同步 效率低 安全性高
always
一秒一次 性能均衡
everysec
不同步 安全性能差
no
appendfsync (内存同步磁盘)
重写aof 到达压缩文件大小目的,剔除重复的指令。
bgrewriteaof
aof文件重写最小的文件大小
auto-aof-rewrite-min-size
aof文件增长比例
auto-aof-rewrite-percentage
同步频率快
可靠性高
文件大 占用空间大
性能低
aof(记录命令)
持久化
1.修改从库redis.conf slaveof masterIp masterPort/masterauth password
2.重启从redis 生效。
配置流程
首次同步数据
场景
1.slave发送同步命令到master 并且与master建立长连接
3.生成rdb后 master 开始缓冲写命令
4.master发送rdb到slave
5.slave 清空脏数据,加载rdb 数据
6.master 将缓冲命令repl buffer发送给slave
7.slave接收repl buffer写命令,执行命令
8.master与slave 建立长连接,持续发送写命令
流程
全量复制
主从断开链接,期间有数据写入master
1.从节点断开master缓冲写命令以及数据
3.比较master与slave的offset偏移量,如果在master中 则将offset之后数据同步给master 否则全量同步
增量复制
原理解析
slave-read-only=yes
保证从节点只读
主节点产生的命令数据无论大小都会及时地发送给从节点,主从之间延迟变小
增加了网络带宽的消耗 适用于同机房
repl-disable-tcp-nodelay 关闭
主节点会合并较小的TCP数据包从而节省带宽,主从延迟会变大
节省了带宽但增大主从之间的延迟
repl-disable-tcp-nodelay 开启
主从延迟问题
子主题
问题
主从复制
见备注
Raft 算法
1.断开链接的时长
2.优先级
3.offset 数据备份越多
4.进程ID最小
影响因素
选举算法
sentinal节点每隔一段时间向master发送心跳请求,如果超时down-after-milliseconds未收到回复 则sentinal认为master 主观下线
主观下线
主观下线后 sentinal会向其他sentinal发送ismaster-down-by-addr命令 如果过半sentinal认为master主观下线,则master升级为客观下线
客观下线会重新发起master选举
客观下线
哨兵
jedis 实现数据分片 一致性哈希算法 不依赖中间件,逻辑可以自定义
客户端
Codis/twemproxy
代理端
数据分片
数据不在缓存,也不在数据库 比如请求一个不存在的订单号
本身是一个很长的二进制向量,存放的不是0就是1
定义
对数值进行多次哈希取得多个哈希值,并对数组小标取模 放在不同位置上
1 代表占位 0 代表未占位
原理
优点:高效 占用内存少
缺点:具有一定误判率 无法删除过期数据
1. 布隆过滤器 将所有数据缓存到redis 布隆过滤器中
解决方案
缓存穿透
同一时间段内,大量缓存失效/redis挂掉了
1. 分布式锁
2.设置不同过期时间
3.redis 高可用搭建
缓存雪崩
热点数据过期,大量并发请求同一个数据
分布式锁
缓存击穿
redis
MongoDB
数据存储
Broker->VHost->Exchange->Queue
发送消息
Connection->channel-Queue
接收消息
工作模型
Direct直连 1-1
Topic 主题 1-n
Fanout 广播 1-n
Headers 头部匹配
Exchange路由
消息过期ttl
消息超长
消费者拒绝reject/nack 并且requeue=false
死信队列
插件rabbitmq_delayed_message_exchange
延迟队列
发送消息效率低下(不建议使用)
Transaction模式
效率不高
单条Confirm
效率相对较高
批量提交数目问题,过大失败问题,过少效率低下
批量Confirm
效率高,回调机制
异步AsyncConfirm
Confirm模式
消息可靠性
不能保证高可用,数据分散分布
普通集群
高可用,性能低
镜像模式
集群高可用
rabbitMq
stream
高吞吐,低延迟
partion
高伸缩性
副本机制
持久性,可靠性
自动选举Leader
容错性,高并发
消息传递
网站活动跟踪
指标监控(实时数据分析)
日志聚合(log)
使用场景
基础介绍
手工指定ProducerRecord
自动指定 实现接口Partitioner
Leader操作数据
Follower 同步数据
partion0 分区
partion1 分区
Topic1 队列
Topic2 队列
kafka服务Broker0
kafka服务Broker1
生产者producer
效率低
单个消费者
offset 记录消费index
一个consumer 消费一个 partion
consumer:partion=1:1
存在空闲的consumer
consumer>partion
RangerAssignor 平均分配
RoundRobinAssignor 轮询分配
consumer<partion
消费者组consumer group
消费者consumer
原理:2PC
事务Topic:_transaction_state
事务ID:transaction_id
事务消息
架构分析
KafkaProducer
给消息增加自定义样式
拦截器ProducerInterceptor
序列化Serializer
分区器Partitioner
main线程
ProducerBatch 批量发送消息
sender线程
0 不需要服务端Ack 效率快 可靠性不高
1 leader落盘Ack 有丢消息风险
-1 所有Follower 全部落地Ack retries=0 消息重复发送问题
服务端acks
Leader 读写消息
Follower 同步消息
partition存储消息
接受消息
原理分析
kafka
Broker启动注册 定时发送心跳续约
NameServer 定时检测Borker 是否长时间未发送心跳
NameServer集群都会收到消息
服务注册
NameServer定时检测
服务剔除
NameServer存储相同数据
Cilent定时器刷新路由列表
路由发现
一致性
NameServer(服务中心)
0 2 4 6 8
Borker0
1 3 5 7 9
Borker1
存储部分数据 分片存储
Broker(主机)
slave 不参与读写
slaveReadEnable=true 可以让slave 参与读负载
Replica(副本)
存储并非按照Topic分目录
autoCreateTopicEnable=true Topic不存在自动创建
Topic(消息队列)
消息队列名称
Topic
主机名称
BrokerName
队列ID位置
queueId
0->对应queueId
3
BrokerA
1
2
BrokerB
队列多少个数据存储目录 默认4
写队列数量
代表从多少数据目录读取数据 如为 2,代表消费0 1目录消息 2 3消息不会被消费
读队列数量
MessageQueue(队列)
消息队列ID
topic
过滤消息
tags
索引键 多个空格隔开
key
Message
单条发送MessageQueue
批量发送Collection<MessageQueue>
必须ACK 返回sendResult
同步发送消息
onSuccess回调接受结果
异步发送消息
不需要Ack
单向发送消息
单向顺序消息
队列选择
Producer(生产者)
轮询消费
集群模式
重复消费所有消息
广播模式
消费模式(MessageModel)
Consumer(消费者)
对磁盘访问,完全的顺序写
顺序IO 提高写入性能
消息的offset
offset
消息大小size
size
tag的hashCode
hashcode
1.Broker 的ReputMessageService 定时轮询CommitLog 查找未添加ConsumeQueue的log
3.consumer消费 首先查找consumeQueue未消费的记录,根据OffSet 查找commitlog 消费消息
初始化过程
ConsumeQueue(索引)
commitLog
文件->内核缓冲区->应用程序Buffer
读取IO
应用程序Buffer->内核发送缓冲区->文件
发送IO
传统Copy
文件->Buffer(内存映射)
Buffer(内存映射)->文件
mmap
限制最大值2G
mmap 零拷贝
消息存储
CommitLog
ConsumeQueue
清理类型
MessageStoreCofig.FileReservedTime=72 小时
过期文件
MessageStoreCofig.deleteWhen=04 一天执行一次
删除策略
清理策略
自动清理过期文件
占用率>75%
按照设定规则清理文件,无论是否过期。默认会从最老的文件开始清理
占用率>85%
拒绝消息写入
占用率>90%
磁盘已满
文件清理
brokerClusterName 集群名字相同
NameServer 相同
0-matser
1-slave
brokerId (定义master)
主写入成功Ack
优点:效率高 缺点:可靠性低
异步复制
ASYNC_MASTER
主从均写入成功ACK
优点:效率低 缺点:可靠性高
同步复制(推荐)
SYNC_MASTER
brokerRole
写入内存PAGECACHE发送ACK
优点:效率高 缺点:消息丢失
异步刷盘(推荐)
ASYNC_FLUSH
每条message刷到磁盘 发送ACK
优点:效率低 缺点:消息不丢失
同步刷盘
SYNC_FLUSH
flushDiskType(刷盘类型)
配置说明
1.定时器 slave链接master 发送拉取请求 以及自己的commitLog的offset
2.master 接收请求,与master offset比较,生成要同步commitLog buffer,发送给slave
3.slave接收到master请求,写入本地commitLog
commitLog复制
定时任务处理
元数据的复制
流程解析
master->slave 不能够自动切换的问题
主从同步
Head
Body
DLedgerCommitLog
enableDlegerCommitLog=true 是否启用
dLegerGroup=brokerA 分组名称
dLegerPeers=n0-IP:PORT;n1-IP:PORT;n2-IP:PORT; 至少3节点
dLegerSelfId=n0 本节点ID
故障转移(DLedger)
通过Hash选择MessageQueue
SelectMessageQueueByHash(默认)
随机选择MessageQueue
SelectMessageQueueByRandom
未实现功能不可以用
SelectMessageQueueByMachineRoom
自定义选择 实现接口MessageQueueSelector
MessageQueueSelector(接口)
MessageQueue选择
SYNC:同步发送
ASYNC:异步发送
ONEWAY:单次发送 不需要服务端ACK
CommunicationMode
单线程发送
单线程消费
前提条件
指定唯一队列发送
全局有序
根据业务需求指定队列
局部有序
顺序消息
消息主题Topic:RMQ_SYS_TRANS_HALF_TOPIC
producer 设置Listener setTransactionListener
1.发送未确认消息给Broker 不可见
2.执行本地事务
3.发送Ack消息给Broker 消息可见
half Message
1.定时器 轮询未Ack的half Message,主动发送命令给producer
2.Producer检查本地事务 执行Commit/rollBack操作
事务状态回查
设置TRAN_MSG=true
写入CommitLog
发送half消息
获取事务消息commitLog
获取原Topic与queueId,重写组装CommitLog
写入Topic=**RMQ_SYS_TRANS_OP_HALF_TOPIC** 队列(打删除标记 op队列)
half消息打上删除标记
commit 事务
写入Topic=**RMQ_SYS_TRANS_OP_HALF_TOPIC** 队列(打删除标记 op队列)
rollBack 事务
messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
api 实现 msg.setDelayTimeLevel=0/1/2
不支持自定义时间 商业版本支持
1.获取commitLog 属性DelayLevel判断是否延迟消息
2.延迟消息重写Topic=SCHEDULE_TOPIC_XXXX,queueId 保存原有的Topic与queueId到Properties中
3.定时器扫描 获取要触发的commitLog 改写Topic与queue写入原有队列
写入Topic=**RMQ_SYS_TRANS_OP_HALF_TOPIC** 队列(打删除标记 op队列)
4.删除延迟队列commitLog(打标)
延迟消息
producer(生产者)
所有消费者消费所有消息
平均分配算法
AllocateMessageQueueAveragely(默认)
轮询
AllocateMessageQueueAveragelyByCircle
机房分配算法
AllocateMessageQueueByMachineRoom
一致性hash算法
AllocateMessageQueueConsistentHash
通过配置
AllocateMessageQueueByConfig
机房临近原则算法
AllocateMachineRoomNearby
rebalance
负载均衡
1.集群模式CLUSTERING
2.返回状态RECONSUME_LATER
3.非OneWay消息
consumer.setMaxReconsumeTimes=2 设置重试次数
1.获取待重试消息,重写Topic=%RETRY% + 消费者组名,重试次数+1 延迟级别+3 保存原信息到Properties
2.走延迟消息逻辑,写入延迟队列,执行消息
3.消费失败 重试次数+1,延迟级别叠加,重新再来一遍。超过最大次数写入死信队列Topic=%DLQ%+消费者组名
4.消费成功。删除commitLog(打标)
重试消息
消息会自动进行重试,达到最大重试次数后进入队列
角色分析
rocketMq
消息队列
Spring
SpringBoot
项目集成
失败自动切换
重试次数过多 容易造成雪崩效应
Failover Cluster(默认)
失败自动恢复,通过定时任务不断重试
Failback Cluster
快速失败,请求失败后返回异常,不进行任何重试
Failfast Cluster
失败安全,请求失败后忽略异常,不进行任何重试
Failsafe Cluster
并行调用多个 Provider 节点,只要有一个成功就返回
Forking Cluster
广播多个 Provider 节点,只要有一个节点失败就失败
Broadcast Cluster
找到可用节点调用
Available Cluster
请求多个结果,并将结果合并
Mergeable Cluster
集群容错
ConsistentHashLoadBalance 一致性哈希
RandomLoadBalance 随机权重算法(默认)
LeastActiveLoadBalance 最少活跃调用数
RoundRobinLoadBalance权重轮询
ShortestResponseLoadBalance最短响应时间
自定义负载均衡算法
Magic High
0~7位
与Magic High一起判断是否为Dubbo协议
Magic Low
8~15位
Req/Res标识,标识当前消息是请求还是响应
16位
2Way标识,用于标识当前消息是单向还是双向
17位
Event标识,用于标识当前消息是否为事件消息
18位
序列化类型的标志,用于标识当前消息使用哪一种序列化算法
19~23位
Status状态,用于记录响应的状态,当Req/Res为0时才有用
24~31位
Request ID,用于记录请求的唯一标识
32~95位
序列化后的内容长度,该值是按字节计算
96~127位
可变的数据
128~
结构
变长协议,适用于高并发 小数据传输,消费者比提供者个数多
常规远程服务方法调用
connections 连接数
accepts 限制最大接收连接数
默认单一链接
长链接 | TCP协议 | NIO异步传输 | Hessian 二进制序列化
dubbo协议(默认)
底层采用Http 通讯,采用 Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现
实现方式
传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件
页面传输,文件传输,或与原生hessian服务互操作
适用场景
默认 多连接
短连接 | Http协议 | 同步传输 | Hessian二进制序列化
hession协议
Thrift不支持null值,不能在协议中传null
thrift协议
grpc协议
rest协议·
采用JDK标准的java.rmi.*实现,采用阻塞式短连接和JDK标准序列化方式
传入传出参数数据包大小混合,消费者与提供者个数差不多,可传文件。
常规远程服务方法调用,与原生RMI服务互操作
默认多链接
短连接 | TCP协议 | 同步传输 | jdk序列化
参数及返回值需实现Serializable接口
特性·
rmi协议
基于 Apache CXF的 frontend-simple 和 transports-http 实现
系统集成,跨语言调用
默认:多连接
短连接 | Http协议 | 同步传输 | SOAP文本序列化
webService协议
基于http表单的远程调用协议
传入传出参数数据包大小混合,提供者比消费者个数多,可用浏览器查看,可用表单或URL传入参数,暂不支持传文件
需同时给应用程序和浏览器JS使用的服务
适用场景·
短连接 | Http协议 | 同步传输 | JSON表单序列化
http协议
memcached 协议
协议
不通过API调用dubbo接口
泛化
mock
熔断降级
注册中心地址
registry.address
多注册中心地址
registries.shanghai.address
注册中心
1.查找环境变量中是否存在启动参数DUBBO_IP_TO_BIND
2.读取配置文件dubbo.protocols.dubbo.host
3.InetAddress.getLocalHost().getHostAddress获取本机IP
4.socket.getLocalAddress().getHostAddress socket链接注册中心获取本机IP
5.轮询本机网卡 获取IP
IP获取流程
⽅法级优先,接⼝级次之,全局配置再次之
如果级别⼀样,则消费⽅优先,提供⽅次之
配置优先级
1.JVM System Properties JVM -D 参数
2.System environment,JVM进程的环境变量
3.Externalized Configuration,外部化配置,从配置中心读取
4.Application Configuration,应用的属性配置,从Spring应用的Environment中提取\"dubbo\"打头的属性集
5.API / XML /注解等编程接口采集的配置可以被理解成配置来源的一种,是直接面向用户编程的配置采集方式
6.从classpath读取配置文件 dubbo.properties
配置中心加载
服务提供者暴露服务配置
配置类:com.alibaba.dubbo.config.ServiceConfig
dubbo:service
服务消费者引用服务配置
配置类:com.alibaba.dubbo.config.ReferenceConfig
dubbo:reference
服务提供者协议配置
配置类:com.alibaba.dubbo.config.ProtocolConfig
dubbo:protocol
注册中心配置
配置类:com.alibaba.dubbo.config.RegistryConfig
dubbo:registry
监控中心配置
配置类:com.alibaba.dubbo.config.MonitorConfig
dubbo:monitor
应用信息配置
配置类:com.alibaba.dubbo.config.ApplicationConfig
dubbo:application
模块信息配置
配置类:com.alibaba.dubbo.config.ModuleConfig
dubbo:module
服务提供者缺省值配置
配置类:com.alibaba.dubbo.config.ProviderConfig
dubbo:provider
服务消费者缺省值配置
配置类:com.alibaba.dubbo.config.ConsumerConfig
dubbo:consumer
方法级配置
配置类:com.alibaba.dubbo.config.MethodConfig
dubbo:method
方法参数配置
配置类:com.alibaba.dubbo.config.ArgumentConfig
dubbo:argument
选项参数配置
配置类:java.util.Map
dubbo:parameter
配置手册
apollo
consul
etcd
nacos
zookeeper
配置中心插件
配置中心
本地缓存注册中心服务列表,防止注册中心Down导致服务不可用
缓存服务
Dubbo Admin
基础使用
该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现
Service 服务接口层
对外配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类
Config 配置层
服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory
Proxy 服务代理层
封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory、Registry和RegistryService
Cluster 服务注册层
RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory、Monitor和MonitorService
Monitor 监控层
封装RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter
Protocol 远程调用层
封装请求响应模式,同步转异步,以Request和Response为中心,扩展接口为Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer
Exchange .信息交换层
抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel、Transporter、Client、Server和Codec
Transport 网络传输层
可复用的一些工具,扩展接口为Serialization、 ObjectInput、ObjectOutput和ThreadPool
Serialize 数据序列化层
框架分析
Java SPI 规定在 classpath 下的 META-INF/services/ 目录里创建一个以服务接口命名的文件,记录此 jar 包提供的具体实现类名
ServiceLoader
实现解耦
可以不使用硬编码 import 导入实现类
懒加载浪费内存问题·
多线程不安全
JAVA SPI
接口添加@SPI注解,配置文件需放置在 META-INF/dubbo,通过键值对的方式进行配置
ExtensionLoader
Dubbo SPI
Spring Boot自动装配META-INF/spring.factories
SpringFactoriesLoader
Spring SPI
SPI
自适应扩展点 根据Url参数动态获取
@Adaptive
getAdaptiveExtension
指定名称扩展点
getExtension
激活扩展点/条件扩展 根据Condition 条件获取
getActivateExtension
服务消费
流程分析
dubbo
zk
中间件
xxlJob
Quartz
定时任务
背景:传统数据库面临问题性能,存储,分词
单实例全文搜索引擎 不支持分布式
lucece
全文检索·
文档Document的集合,相当于数据库的database
必须全部是小写字母
索引Index
类型 (type)
文档所属索引名称
_index
文档所属类型名
_type
文档的ID值
id+type+index 确保唯一性
_id
文档的版本信息。ES通过使用version来保证对文档的变更能以正确的顺序执行,避免乱序造成的数据丢失。
_version
文档的原始JSON数据,这才是我们储存在ES中的业务数据
_source
严格递增的顺序号,每个文档一个,Shard级别严格递增,保证后写入的Doc的_seq_no大于先写入的Doc的_seq_no。
_seq_no
primary_term也和_seq_no一样是一个整数,每当Primary Shard发生重新分配时,比如重启,Primary选举等,_primary_term会递增1
primary_term
found
文档Document
相当于是数据表的字段
字段Field
将索引划分成多份的能力,每一份就称之为分片
用于索引文档增删改查,数量创建不可修改,默认5个
主分片primary
冗余主分片数据,默认1个,可以指定多份,不可与主分片在同一个Node上
副本分片replica
分片类型
分片Shards
如果mapping没有创建,elasticsearch将会根据写入的数据的key自行创建相应的mapping,并写入数据
动态映射
若在数据写入索引前,映射(mapping)已经创建,那么在写入数据时,ES会根据映射和写入数据的key进行对比,然后写入相应的映射中;
静态映射
哪些字段需要定义成全文索引字段
哪些字段定义为精确值,例如日期,数字、地理位置等
哪些字段需要被索引(能通过该字段的值查询文档)
日期值的格式。
动态添加字段的规则定义等。
功能
映射mapping
集群是一个或多个节点(服务器)的集合,由一个唯一的名称标识
主/复分片都可用
green
主分片可用,复制分片部分不可用
yellow
主分片部分不可用
red
健康状态
集群cluster
默认名称随机UUID,可以自定义
可以参加选举成为Master Node
ode.master:false 可以禁止选举
Master-eligible Node(默认)
可以修改集群中节点信息
所有index
Mapping和Setting信息
分片的路由信息
Master Node
保存数据的节点,负责保存分片数据,对数据扩展有重要作用
Data Node
负责接受Client请求,将请求分发到合适的节点获取响应后,将结果最终汇集在一起,每个节点默认都有Coordinating节点的职责
Coordinating Node(每个节点)
负责运行机器学习的Job,用来做异常检测
Machine Learning Node
数据预处理的节点,支持Pipeline管道设置,可以使用Ingest对数据进行过滤、转换等操作
Ingest Node
节点类型
节点node
核心概念
ES为每个字段建立一个倒排索引
分类索引,二分查找
词典索引,存储前/后缀,存储在内存方便查找
节省内存空间
查找消耗CPU
FST 技术生成
term index
term dictionary
Term
倒排表,文档ID数组[int]
压缩算法,要求倒排表有序,增量算法,大数变成小数,仅存储增量值
节省posting list占用的磁盘空间和内存开销
Roaring Bitmaps 咆哮位图 压缩位图索引
short[] 存储数据,占用2B,方便使用二分查找,且不会存储重复数值
存储数据没有任何压缩,因此只适合存储少量数据子主题
DEFAULT_MAX_SIZE值为4096,当容量超过这个值的时候会将当前Container替换为BitmapContainer。
ArrayContainer
long[]存储位图数据,初始化大小1024,占用空间8KB
BitmapContainer
行程长度压缩算法,对连续数据有比较好的压缩效果
RunContainer
RoaringBitmap的Container
Filter缓存
Frame of Reference 索引帧
Posting List
利用跳表(Skip List)的数据结构快速做“与”运算
利用bitset这种数据结构按位“与”运算
有序链表Level0,挑出其中几个元素到level1和level2,每一个level越往上,选出来的指针元素就越少,查找时候从高level往低查找。
跳表数据结构
联合索引
ES默认是自动建索引的,不需要索引的字段,要明确定义出来
对于string类型默认是会进行analysis(分词)的,不需要analysis的需要定义出来
文档的ID需要选择有规律的ID,随机性太大,比如UUID不利于查询
注意事项
ES之所以查询很快,主要是依赖于倒排索引的设计,尽量将数据放在内存,加上各种压缩算法和缓存算法
由于索引数据量很大,不能直接将数据丢在内存,所以通过构建有序状态转换器FST放在内存中。
为了避免Posting List大量的文档ID占用太多磁盘空间,ES使用了索引帧(Frame of Reference)技术压缩posting list。
ES还采用了Roaring Bitmap技术来缓存使用频率比较高的Filter搜索结果
总结
倒排索引·
PUT /{index}/{doc}
自动生成ID
PUT /{index}/{doc}/{id}
自定义ID
增
DELETE /{index}/{doc}/{id}
根据ID删除
删
根据ID修改
改
GET /{index}/{type}/{id}
GET /{index}/{type}/{id}/_source
只返回source
GET /{index}/{type}/{id}/_source=field
只返回source某个字段
根据ID查询
其他查询
查
API操作
基础认识
vm.max_map_count = 262144
vim /etc/sysctl.conf
调整虚拟内存
hard nofile 6553/soft nofile 65536
/etc/security/limits.conf
调整文件描述符大小
es
https://www.elastic.co/cn/downloads/kibana 官网
与elasticsearch版本要对应
elasticsearch.hosts: [\"http://192.168.31.221:9200\"]/server.host: \"0.0.0.0\"
vim ./config/kibana.yml
绑定ES地址
kinbana
配置 Elasticsearch
数据存放目录
path.data
日志存放记录
path.logs
日志目录
锁定物理内存,在es运行后锁定使用的内存大小,锁定大小一般是服务器内存的50%
bootstrap.memory_lock
配置ES集群内的节点名称,同一个集群内的节点名称要具备唯一性。
node.name
设置临时文件的存储路径,默认是es根目录下的work文件夹
path.work
指定该节点是否存储索引数据,默认为true
node.data:true
指定该节点是否有资格被选举成为master
node.master:true
node.attr.rack: r1
当节点启动时,传递一个初始主机列表来执行发现
discovery.seed_hosts
写入候选主节点的设备地址,来开启服务时就可以被选为主节点
cluster.initial_master_nodes
是否开启es启动时更新地图相关的数据库
ingest.geoip.downloader.enabled
其他配置
是否开启跨域访问
http.cors.enable
开启跨域后,能访问es的地址限制,*号表示无限制
http.cors.allow-origin: “*”
跨域
配置ES集群名称,同一个集群内的所有节点集群名称必须一致。
cluster.name
防止同一个shard的主副本存在同一个物理机上。
cluster.routing.allocation.same_shard.host:true
设置一个节点的并发数量,两种情况,第一种是在初始复苏过程中,默认是4个
cluster.routing.allocation.node_initial_primaries_recoveries: 4
设置一个节点的并发数量的第二种情况,在添加、删除节点及调整时。默认是4个
cluster.routing.allocation.node_concurrent_recoveries: 4
设置一个集群中主节点的数量,当多于三个节点时,该值可在2-4之间。
discovery.zen.minimum_master_nodes: 1
设置ping其他节点时的超时时间,网络比较慢时可将该值设大
discovery.zen.ping.timeout: 3s
禁止当前节点发现多个集群节点,默认值为true
discovery.zen.ping.multicast.enabled: false
设置每个节点在选中的主节点的检查之间等待的时间。默认为1秒
cluster.fault_detection.leader_check.interval:2s
启动后30秒内,如果集群未形成,那么将会记录一条警告信息,警告信息未master not fount开始,默认为10秒
discovery.cluster_formation_warning_timeout: 30s
点发送请求加入集群后,在认为请求失败后,再次发送请求的等待时间,默认为60秒
cluster.join.timeout: 30s
设置主节点等待每个集群状态完全更新后发布到所有节点的时间,默认为30秒。
cluster.publish.timeout: 90s
集群内同时启动的数据任务个数,默认是2个。
luster.routing.allocation.cluster_concurrent_rebalance:32
集群配置
设置默认索引分片个数,默认为5片。主分片一经分配则无法更改。
index.number_of_shards:5
设置默认索引副本个数,默认为1个副本。
index.number_of_replicas:1
设置数据恢复时限制的带宽,默认0及不限制,代表是无限的。
indices.recovery.max_size_per_sec:0
限制从其它分片恢复数据时最大同时打开并发流的个数,默认为5。
indices.recovery.concurrent_streams: 5
是否允许通配符删除索引
action.destructive_requires_name: false
分片配置
为es实例绑定特定的IP地址。
network.host:
设置绑定的ip地址,可以是ipv4或ipv6的,默认为0.0.0.0,绑定这台机器的任何一个ip
network.bind_host
设置其他节点连接此节点的地址,若不设置,则自动获取,值必须是个真实的ip地址,也可以用不配
network.publish_host
IP绑定配置
设置对外服务的http端口,默认为9200
http.port:9200
设置集群节点之间交互的tcp端口,默认是9300
transport.tcp.port:9300
允许任何人连接HTTP API
transport.host: 0.0.0.0
端口配置
设置是否压缩tcp传输时的数据,默认为false,不压缩
transport.tcp.compress:true
设置内容的最大容量,默认100mb
http.max_content_length:100mb
是否使用http协议对外提供服务,默认为true,开启
http.enabled:false
设置gateway的类型,默认为本地文件系统,也可以设置分布式文件系统、Hadoop的HDFS或者AWS的都可以
gateway.type: local
在完全重新启动集群之后阻塞初始恢复,直到启动N个节点为止
gateway.recover_after_nodes: 3
设置初始化数据恢复进程的超时时间。默认是5分钟
gateway.recover_after_time: 5m
设置该集群中节点的数量,默认为2个,一旦这N个节点启动,就会立即进行数据恢复
gateway.expected_nodes: 2
交互配置
图形展示
xpack.graph.enabled
报表统计
pack.reporting.enabled
报警通知
xpack.watcher.enabled
安全认证
xpack.security.enabled
监控跟踪
xpack.monitoring.enabled
设备资源分配
xpack.ml.enabled
https传输层认证
xpack.security.transport.ssl
Xpack
elasticsearch.yml
java环境进行设置参数的配置文件
jvm.options
配置日志
log4j2.properties
配置文件
部署·
增删改都会对-version字段加+1
主分片写入成功,备份分片还未同步,主分片down机会有问题,版本号还未+1
主要用于ES内部并发控制
失败问题
-version
版本Version+分片No
if_seq_no+if_primary_term(6.7+)
乐观锁
主节点与其他节点响应不及时,重选主节点产生多个master
现象
集群网络问题 导致重新选举master
网络问题
负载量大导致ES操作延迟,其他节点会认为主节点挂掉
负载过高
ES占用内存过大 导致JVM垃圾回收时间过长
JVM垃圾回收
Master性能问题
超时分析
原因分析
增大具有master资格的节点的数量discovery.zen.minimum_master_nodes:6(默认是1) 官方的推荐值是(N/2)+1
慎用,如果增加服务器可能会导致数据丢失
增大触发条件
网络问题·
Master与Data节点不能为同一个,否则容易导致负载过高
角色分离
增加主节点的响应时间discovery.zen.ping_timeout 默认是3s
减少误判
脑裂问题
集群部署
shard = hash(routing)%分片数
PUT /{index}/{doc}/id(默认根据_id)
数据分布离散度好,查询需要每个shard上面获取数据
默认路由
PUT /{index}/{doc}/id?routing=field
数据分布业务性强,根据业务查询效率高
自定义路由
路由算法
路由原理
5.flush 磁盘(30m)
3.refresh File system cache(1s 可查询到)
4.清空.memory buffer
1.memory buffer(不可查询)
刷盘异常恢复用类似redo_log
commit point 记录最后刷盘位置
2.事务日志translog
写入数据
默认时间1s执行一次 可自定义index.refresh_interval修改刷新间隔
memory buffer写入segment ,segment被打开使得数据可以被查询到
清空memory buffer
refresh操作
1.把所有memory buffer写入到segment中
2.清空memory buffer
3.往磁盘里写入commit point信息
4.文件系统的page cache(segments) fsync到磁盘
5.删除旧的translog文件
执行多少次操作后执行一次flush,默认无限制
index.translog.flush_threshold_ops
translog的大小超过这个参数后flush,默认512mb
index.translog.flush_threshold_size
index.translog.flush_threshold_period
es多久去检测一次translog是否满足flush条件
index.translog.interval
index.translog.sync_interval
性能低 不会丢数据
request(默认值)
translog每隔{index.translog.sync_interval}fsync一次
性能高 可能会丢数据
async
index.translog.durability
参数
flush操作
背景:segment过多导致查询效率低下
1.合并零碎的segment
2.对合并的segment flush操作
3.删除零碎的segment 彻底删除
merge操作
存储流程
数据收集
ID唯一获取,只能声明一个
Id
name 可以声明多个 a1:a2 a1与a2均可获取
name
IOC容器只可以存在一个Bean
组合条件查找
primary=true 优先获取
Class
获取Bean
基本使用
IOC容器顶层接口
初始化时候不会实例化对象
BeanFactory
继承了BeanFactory接口,继承了其他接口 ,丰富了功能
初始化时候实例化对象
ApplicationContext
顶层接口
注入factory类 定义factory-method
静态工厂注入
实例化工厂对象
定义bean调用工厂对象初始化factory-bean/factory-method
动态工厂注入
工厂注入
name:属性名称
value:属性值
index:构造器下标
constructor-arg(构造函数)
property(属性)
对象引用注入
数组注入
array
List列表注入
list
HashMap注入
map
构造注入
声明一个类为配置类,用于取代bean.xml配置文件注册bean对象
@Configuration
用于注册bean对象
@Bean
单例 默认
singleton
获取时候创建对象
prototype
同一个请求创建一个实例
request
同一个session创建一个实例
session
声明该bean的作用域
@Scope
配置类注入
包名
base-package
是否使用默认注解
use-default-filters
包含注解
include-filter
剔除注解
exclude-filter
component-scan(xml)
要扫描的包路径
value
Filter[] 指定排除的组件
excludeFilters
Filter[] 指定包含的组件,要设置useDefaultFilters = false
includeFilters
按照注解过滤
ANNOTATION
ASSIGNABLE_TYPE
使用ASPECTJ表达式
ASPECTJ
正则表达式
REGEX
自定义规则
CUSTOM
FilterType
@ComponentScan(默认扫描当前目前以及子目录)
泛指注解,不好归类时候用
@Component
标注业务层组件
@Service
标注控制层组件
@Controller
标注数据访问组件如Dao
@Repository
属性赋值组件
@Value
按照类型装配
@Autowired
读取配置文件赋值
@PropertySource
多实例组件
@Qualifier
多个相同Bean 首选Bean组件
@Primary
默认按照名称匹配,匹配不到按照类型匹配
@Resource
@Lazy
实现condition接口 重写match方法
实现ConfigurationCondition接口
按照一定条件判断,满足给容器注册Bean
@Conditional
通过ImportSelector导入
通过 ImportBeanDefinitionRegistrar 导入 (其实是注册BeanDefintion)
导入外部资源,IOC容器初始化
@Import
用于初始化方法上
@PostConstruct
用于销毁方法上
@PreDestory
指定Bean 初始化以及销毁的顺序
@DependsOn
类或方法在特定的 Profile 环境生效
spring.profiles.active=prod 多环境
@Profile
注解
扫描注解
IOC
面向规则,具有相同规则的方法集合体
Aspect(切面)
回调函数
Advice(通知)
需要被代理的方法
Pointcut(切入点)
需要被代理的对象
Target Object(目标对象)
JDK或者CGLib
Aop Proxy(Aop 动态代理)
Before Advice(前置通知)
After Advice(后置通知)
After Return Advice(返回后通知)
只要触发就调用,织入的方法
Around Advice(环绕通知)
调用Pointcut抛出异常,织入的方法
After Throwing Advice(异常通知)
放开Aspectj使用
@Import(AspectJAutoProxyRegistrar.class)
@EnableAspectJAutoProxy
表示当前类是个切面类
@Aspect
定位目标对象方法上
execution(方法的修饰符 方法的返回值类型 方法所属的类 方法名 方法中参数列表 方法抛出的异常)
支持通配符*,可以省略
修饰符
支持通配符*,表示所有返回值,不可以省略
返回值类型
所属的类
支持通配符*,表示所有方法,不可以省略
方法名
支持通配符*,不可以省略
一个无参方法
()
表示任意数量和类型的方法
(…)
一个任意类型的方法
(*)
)接受二个参数的方法,第一个可以是任意类型,第二个必须是Integer类型
参数列表
异常
|| 或者 or
或
& 或者 and
与
!或者not
非
语法
*:接受任意返回值
com.baidu.dao.*:匹配方法名com.baidu.dao.任意方法名
(…):任意个方法列表
execution(* com.baidu.dao.*(..))
实例解析
execution
定位具体类型上
within
代理对象类型
this
目标对象类型
target
参数的类型
args
@target
参数修饰的注解
@args
类型修饰的注解
@within
方法修饰的注解
@annotation
reference pointcut
bean
切入点表达式
@Pointcut
@Before
AOP
@Controller + @ResponseBody
@RestController
@GetMapping
@PostMapping
restful风格
权限校验,日志记录,性能监控
返回ModelAndView之前执行
preHandle
返回ModelAndView之后执行
postHandle
渲染页面完成之后执行
afterCompletion
继承HandlerInterceptor
拦截器
MVC
1.PROPAGATION_REQUIRED(默认)
2.PROPAGATION_SUPPORTS
当单独调用methodB时,因为当前没有一个活动的事务,则会抛出异常。执行方法A时候会事务执行
3. PROPAGATION_MANDATORY
A执行到B事务时候,会将A事务挂起,执行完B事务之后恢复A事务执行完成
4.PROPAGATION_REQUIRES_NEW
A执行到B时候,B没有事务也会将A事务挂起,执行完B之后恢复A事务执行完成
5.PROPAGATION_NOT_SUPPORTED
总是非事务地执行,如果存在一个活动事务,则抛出异常
6. PROPAGATION_NEVER
外层事务A失败会回滚内层B事务,内层B事务失败不会回滚A事务
7. PROPAGATION_NESTED
事务传播
容器初始化或刷新时触发该事件
ContextRefreshedEvent
容器启动时触发该事件,即 Spring 容器启动时触发该事件。如使用命令行启动 Spring,则不会被触发。
ContextStartedEvent
容器停止时触发该事件,即当 Spring 容器调用 stop() 方法停止容器时触发该事件。
ContextStoppedEvent
容器关闭时触发该事件,当 Spring 容器调用 close() 方法关闭容器时,触发该事件。
ContextClosedEvent
一个 HTTP 请求结束时触发该事件。
RequestHandledEvent
ApplicationListener
java 安全框架,身份认证,授权,密码加密以及会话管理
主题 身份信息
Subject
安全
Security
领域范围 dataSource
Realm
认证器
Autherticator
认证
Authentication
授权器
Authorizer
授权
Authorization
密码,加密
Cryptography
证书,凭证
Credential
匹配器
Matcher
身份
Principal
概念
基础功能
shiro
判断用户合法性
控制用户可以访问的资源
用户权限信息
getAuthorities
用户凭证信息,一般指密码
getCredentials
用户详细信息
getDetails
用户身份信息,用户名、用户对象
getPrincipal
是否认证成功
isAuthenticated
Authentication authenticate(Authentication authentication)
多种认证方式
AuthenticationProvider[]
实现类ProviderManager
认证(AuthenticationManager)
框架说明
Spring Secuirty
权限
基础
初始化Environment
prepareRefresh()
解析XML/注解 生成BeanDefinitions
缓存BeanDefinitions到BeanFactory.beanDefinitionMap中
初始化BeanFactory
ConfigurableListableBeanFactory beanFactory=obtainFreshBeanFactory() (IOC beanDefintion初始化)
解析SpEL表达式,解析#{}
beanExpressionResolver
注册一些类型转换器(spring在进行值注入的时候,需要把字符串类型转换为其他类型)
propertyEditorRegistrars
去管理一些特殊的对象用来进行依赖注入。
resolvableDependencies
在Bean创建时,对Bean的功能进行一些扩展,对里面的注解进行一些识别
beanPostProcessors
prepareBeanFactory(beanFactory);
空实现,留给子类去实现。
postProcessBeanFactory(beanFactory);
beanFactory后处理器,充当beanFactory的扩展点,可以用来补充或修改BeanDefinition
ConfigurationClassPostProcessor-解析@Configuration、@Bean、@lmport、 @PropertySource
PropertySourcesPlaceHolderConfigurer -替换BeanDefinition中的${}
invokeBeanFactoryPostProcessors(beanFactory);
bean 后处理器,充当bean的扩展点,可以工作在bean的实例化、依赖注入、初始化阶段
AnnotationAwareAspectJAutoProxyCreator 功能有:为符合切点的目标bean自动创建代理
registerBeanPostProcessors(beanFactory);
实现国际化
initMessageSource();
发布事件给 监听器
可以从容器中找名为applicationEventMulticaster的bean作为事件广播器,若没有,也会新建默认的事件广播器
可以调用ApplicationContext.publishEvent(事件对象)来发布事件
initApplicationEventMulticaster();
空实现,留给子类扩展
onRefresh();
用来接收事件
实现ApplicationListener接口,重写其中onApplicationEvent(E e)方法即可
registerListeners();
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
ClassPathXmlApplicationContext.refresh()
AnnotationConfigApplicationContext
AbstractApplicationContext
返回Bean
非单例:createBean
存在:返回Bean
不存在:createBean 加入factoryBeanObjectCach
单例:factoryBeanObjectCach是否存在Key
AbstractBeanFactory.doGetBean
applicationContext.getBean
代理类
BeanWrapperImpl.setPropertyValue
populateBean
生成BeanWrapper
createBean
DI
封装:BeanWrapper
是:JDK动态代理
否:CGLib动态代理
继承接口:createBean
1.BeanFactory.createBeanInstance
2.initializeBean
1.AbstractAutoProxyCreator.wrapIfNecessary
1.getAdvicesAndAdvisorsForBean
2.FindEligibleAdvisors
3.sort
2.AbstractAdvisorAutoProxyCreator注册Advisor
3.createProxy
3.applyBeanPostProcessorsAfterInitialization
创建代理类
1.用户请求web->拦截->DispatchServlet
2.调用HandlerMapping->匹配->Controller与拦截器(HandlerExecutionChain)->返回DispatchServlet
3.调用HandlerAdapter->执行->Controller方法->生成->ModelAndView->返回DispatchServlet
4.调用ViewResolver->解析->ModelAndView->生成->View->HttpResponse
1.HttpSerlvertBean.Init
2.FrameworkSerlvert.onRefresh
3.configureAndRefreshWebApplicationContext.onRefresh
初始化文件上传组件
1.initMultipartResolver
初始化本地环境
2.initLocaleResolver
初始化模板
3.initThemeResolver
初始化HandlerMapping
4.initHandlerMappings
初始化HandlerAdapter
5.initHandlerAdapters
初始化异常拦截器
6.initHandlerExceptionResolver
初始化视图预处理器
7.initRequestToViewNameTranslator
初始化ViewReslovers
8.initViewReslovers
初始化FlashMap解析器
9.initFlashMapManager
4.dispatchSerlvert.initStrategies
Init初始化
1.返回HandlerExecutionChain->getHandler()->abstractHandlerMapping.getHandler()
2.返回ModelAndView->getHandlerAdapter()->RequestMappingHandlerAdapter.invokerHandlerMethod()
3.输出View->processDispatchResult->abstractView.Render()
dispatcherServlet.doService
运行阶段
源码分析
源码解析
createApplicationContext
obtainFreshBeanFactory
ConfigurableListableBeanFactory
createBeanFactory
扫描并完成BeanDefintions加载
loadBeanDefintions
refreshBeanFactory
refreshContext
SpringApplication.run
启动流程
表示当前类是个配置类
@SpringBootConfiguration
@EnableAutoConfiguration
初始化Spring容器会进行扫描,扫描路径为当前在解析的这个类所在的包路径
@ComponentScan
@SpringBootApplication
常见注解
实现selectImport方法 导入Bean
SPI方式从的META-INF/spring.factories中配置加载Bean
getCandidateConfigurations()->SpringFactoriesLoader.loadFactoryNames
AutoConfigurationImportSelector
实现registerBeanDefinitions 注册Bean
将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;
Registrar
@AutoConfigurationPackage
约定大于配置设计思想
自动装配
StandardServletEnvironment
StandardReactiveWebEnvironment
StandardEnvironment(默认)
1.getOrCreateEnvironment() 根据webApplicationType选择
String name
T source
List<PropertySource<?>> propertySourceList
获取MutablePropertySources
1.configurePropertySources
setActiveProfiles
2.configureProfiles
3.bindToSpringApplication()
MutablePropertySources都转换成了ConfigurationPropertySourcesPropertySource的形式,从而允许后面的方法能够对其进行统一调用
4.attach(environment)
prepareEnvironment()
SpringApplication.run()
BeanFactoryPostProcessor
MutablePropertySources 初始化
PropertySourcesPlaceholderConfigurer
PropertyPlaceholderAutoConfiguration
Load.load()完成对Spring Boot配置文件加载
ConfigFileApplicationListener.postProcessEnvironment
ConfigFileApplicationListener.onApplicationEvent
发布ApplicationEnvironmentPreparedEvent
Spring Boot SPI加载ConfigFileApplicationListener
Environment
PropertySource
属性占位符解析
Sping Boot
基于 Netflix Ribbon 实现的客户端负载均衡和服务调用工具
作用
LoadBalancerClient
@LoadBalanced
goods-service.ribbon.NFLoadBalancerRuleClassName=**.** 设置负载均衡策略
使用方法
线性轮询策略,即按照一定的顺序依次选取服务实例
RoundRobinRule
随机选取一个服务实例
RandomRule
按照 RoundRobinRule(轮询)的策略来获取服务,如果获取的服务实例为 null 或已经失效,则在指定的时间之内不断地进行重试
RetryRule
按照平均响应时间,来计算所有服务实例的权重,响应时间越短的服务实例权重越高,被选中的概率越大
WeightedResponseTimeRule
先过滤点故障或失效的服务实例,然后再选择并发量最小的服务实例。
BestAvailableRule
先过滤掉故障或失效的服务实例,选择并发较小的节点
AvailabilityFilteringRule
默认的负载均衡策略,综合判断服务在不同区域(zone)的性能和服务(server)的可用性,来选择服务实例。
ZoneAvoidanceRule(默认)
重写Choose方法
继承AbstractLoadBalancerRule
自定义负载均衡策略
负载均衡策略
其实就是@Qualifier注解,具备它的所有特性
@LoadBalanced解析原理
1.获取所有增加了@LoadBalanced注解的RestTemplate
2.为每个RestTemplate增加LoadBalancerInterceptor拦截器
LoadBalancerAutoConfiguration
注入LoadBalancerClient
intercept(拦截请求)
LoadBalancerClient.execute(处理请求)
继承ClientHttpRequestInterceptor
LoadBalancerInterceptor
1.存储并维护服务列表
2.根据路由规则,通过servicename获取一个服务地址
3.将请求数据发送到服务地址
初始化LoadBalancerClient
RibbonAutoConfiguration
1.获取负载均衡器ILoadBalancer
2.根据负载均衡器和规则选择服务(chooseServer)
3.执行request请求并返回结果
RibbonLoadBalancerClient
定时任务 30s执行一次
更新Server列表
UpdateAction.doUpdate
PollingServerListUpdater#start(UpdateAction)
enableAndInitLearnNewServersFeature
updateListOfServers
定时任务 Ping心跳检测
BaseLoadBalancer#setupPingTask
DynamicServerListLoadBalancer.restOfInit
ZoneAwareLoadBalancer
ILoadBalancer
IRule#choose(PredicateBasedRule)
chooseServer
1.封装ServiceRequestWrapper
2.重构请求URI
3.ClientHttpRequestExecution执行Http请求
execute
可以创建一个子容器(或者说子上下文),每个子容器可以通过 Specification 定义 Bean。
NamedContextFactory
Ribbon
服务端注册
@EnableEurekaServer
消费端注册
@EnableEurekaClient
可获取当前服务的相关信息
@EnableDiscoveryClient
关键注解
服务注册中心实例的主机名
eureka.instance.hostname
注册在Eureka服务中的应用组名
eureka.instance.app-group-name
注册在的Eureka服务中的应用名称
eureka.instance.appname
该实例注册到服务中心的唯一ID
eureka.instance.instance-id
该实例的IP地址
eureka.instance.ip-address
该实例,相较于hostname是否优先使用IP
eureka.instance.prefer-ip-address
用于AWS平台自动扩展的与此实例关联的组名
eureka.instance.a-s-g-name
部署此实例的数据中心
eureka.instance.data-center-info
默认的地址解析顺序
eureka.instance.default-address-resolution-order
该实例的环境配置
eureka.instance.environment
初始化该实例,注册到服务中心的初始状态
eureka.instance.initial-status
表明是否只要此实例注册到服务中心,立马就进行通信
eureka.instance.instance-enabled-onit
eureka.instance.namespace
该服务实例的子定义元数据,可以被服务中心接受到
eureka.instance.metadata-map.test
eureka.instance.lease-expiration-duration-in-seconds
该实例给服务中心发送心跳的间隔时间,用于表明该服务实例可用
eureka.instance.lease-renewal-interval-in-seconds=30
该实例,注册服务中心,默认打开的通信数量
eureka.instance.registry.default-open-for-traffic-count
每分钟续约次数
eureka.instance.registry.expected-number-of-renews-per-min
eureka.instance.health-check-url
eureka.instance.health-check-url-path
eureka.instance.home-page-url-path
https通信端口
eureka.instance.secure-port
https通信端口是否启用
eureka.instance.secure-port-enabled
http通信端口
eureka.instance.non-secure-port
http通信端口是否启用
eureka.instance.non-secure-port-enabled
该实例的安全虚拟主机名称(https)
eureka.instance.secure-virtual-host-name
该实例的虚拟主机名称(http)
eureka.instance.virtual-host-name
eureka.instance.status-page-url
eureka.instance.status-page-url-path
instance配置项
#该客户端是否可用
eureka.client.enabled=true
#实例是否在eureka服务器上注册自己的信息以供其他服务发现,默认为true
eureka.client.register-with-eureka=false
#此客户端是否获取eureka服务器注册表上的注册信息,默认为true
eureka.client.fetch-registry=false
#是否过滤掉,非UP的实例。默认为true
eureka.client.filter-only-up-instances=true
#与Eureka注册服务中心的通信zone和url地址
eureka.client.serviceUrl.defaultZone
#client连接Eureka服务端后的空闲等待时间,默认为30 秒
eureka.client.eureka-connection-idle-timeout-seconds=30
#client连接eureka服务端的连接超时时间,默认为5秒
eureka.client.eureka-server-connect-timeout-seconds=5
#client对服务端的读超时时长
eureka.client.eureka-server-read-timeout-seconds=8
#client连接all eureka服务端的总连接数,默认200
eureka.client.eureka-server-total-connections=200
#client连接eureka服务端的单机连接数量,默认50
eureka.client.eureka-server-total-connections-per-host=50
#执行程序指数回退刷新的相关属性,是重试延迟的最大倍数值,默认为10
eureka.client.cache-refresh-executor-exponential-back-off-bound=10
#执行程序缓存刷新线程池的大小,默认为5
eureka.client.cache-refresh-executor-thread-pool-size=2
#心跳执行程序回退相关的属性,是重试延迟的最大倍数值,默认为10
eureka.client.heartbeat-executor-exponential-back-off-bound=10
eureka.client.heartbeat-executor-thread-pool-size=5
#询问Eureka服务url信息变化的频率(s),默认为300秒
eureka.client.eureka-service-url-poll-interval-seconds=300
#最初复制实例信息到eureka服务器所需的时间(s),默认为40秒
eureka.client.initial-instance-info-replication-interval-seconds=40
#间隔多长时间再次复制实例信息到eureka服务器,默认为30秒
eureka.client.instance-info-replication-interval-seconds=30
#从eureka服务器注册表中获取注册信息的时间间隔(s),默认为30秒
eureka.client.registry-fetch-interval-seconds=30
#获取实例所在的地区。默认为us-east-1
eureka.client.region=us-east-1
#实例是否使用同一zone里的eureka服务器,默认为true,理想状态下,eureka客户端与服务端是在同一zone下
eureka.client.prefer-same-zone-eureka=true
#eureka服务注册表信息里的以逗号隔开的地区名单,如果不这样返回这些地区名单,则客户端启动将会出错。默认为null
eureka.client.fetch-remote-regions-registry
#服务器是否能够重定向客户端请求到备份服务器
eureka.client.allow-redirects=false
#客户端数据接收
eureka.client.client-data-ac
#改变eureka server中注册的服务的健康检测方式
eureka.client.healthcheck.enabled=true
#获取实例所在的地区下可用性的区域列表
eureka.client.availability-zones.china
client配置项
相互注册
高可用
在15min内超过85%的客户端节点都没有正常的心跳,Eureka进入自我保护机制
触发条件
不会剔除过期服务
可以接受新增或查询请求,但是不会同步到其他节点
网络故障恢复后,EurekaServer节点会自动退出自我保护模式
工作模式
自我保护机制(AP)
Eureka
声明式伪RPC的Rest客户端
扫描所有使用注解@FeignClient定义的feign客户端,并把feign客户端注册到IOC容器中
@EnableFeignClients
声明伪RPC的Rest接口,必需声明在Interface上
接口创建动态代理,然后通过这个代理发送HTTP请求到我们指定分服务端
@FeignClient
default
针对全部服务
serviceName
针对某个服务
GZIP 注意okhttp不生效
数据压缩
加载默认配置
registerDefaultConfiguration
加载FeignClient对应的配置
registerClientConfiguration
将标注@FeignClient 类加载到IOC容器
获取FeignContext上下文
FeignContext context = this.applicationContext.getBean(FeignContext.class);
从FeignContext中,根据contextId获取ApplicationContext,然后获取Feign.Builder
Feign.Builder builder = feign(context);
从FeignContext中,根据contextId获取ApplicationContext,然后获取Client
LoadBalancerFeignClient
从FeignContext中,根据contextId获取ApplicationContext,然后获取Targeter
创建并返回代理对象
getTarget
getObject
FeignClientFactoryBean
registerFeignClient
registerFeignClients
FeignClientsRegistrar.registerBeanDefinitions
实现ImportBeanDefinitionRegistrar接口
@Import({FeignClientsRegistrar.class})
OpenFeign
防止单个服务的故障耗尽系统中的所有线程资源
保护线程资源
当某个服务发生了故障,不让服务调用方一直等待,而是直接返回请求失败
快速失败机制
请求失败后,提供一个设计好的降级方案,通常是一个兜底方法,当请求失败后即调用该方法
提供降级(FallBack)方案
使用熔断机制,防止故障扩散到其他服务
防止故障扩散
提供熔断器故障监控组件 Hystrix Dashboard,随时监控熔断器的状态
监控功能
意义
单个服务降级
fallbackMethod
HystrixCommandProperties找到Key
@HystrixProperty
commandProperties
@HystrixCommand
全局服务降级
defaultFallback
@DefaultProperties
启用Hystrix断路器
@EnableHystrix
启用Hystrix断路器,允许使用@CircuitBreaker注解来标记需要使用断路器的方法,支持其他断路器实现
@EnableCircuitBreaker
注解说明
Hystrix Dashboard
监控
集成GateWay
一定的时间窗口内,当请求的次数达到一定的失败比率后,hystrix就会主动拒绝服务,一段时间内不会处理请求(即使服务恢复了)
熔断触发的最小个数,即在一定的时间窗口内请求达到一定的次数,默认20
hystrix.command.default.circuitBreaker.requestVolumeThreshold
时间窗口,默认10s
hystrix.command.default.metrics.rollingStats.timeInMilliseconds=5000
失败率达到多少百分比后熔断 默认值:50
hystrix.command.default.circuitBreaker.errorThresholdPercentage=50
熔断多长时间后,尝试放一次请求进来,默认5秒
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=5000
主要参数
THREAD(线程池 默认)
SEMAPHORE(信号量)
execution.isolation.strategy
支持超时直接返回
支持熔断,线程池达到maxSize会降级调用fallBack方法
每个服务单独用线程池
可以异步
线程切换造成CPU负载高
线程池
不支持超时,会一直阻塞
支持熔断,信号量达到maxConcurrentRequest会降级调用fallBack方法
通过信号量计数器实现
同步调用
单线程
信号量
模式对比
隔离模式
滑动窗口
熔断算法
熔断机制
Hystrix
API网关是一个服务器,是系统的唯一入口
鉴权,限流,日志,缓存等
client->Gateway->Gateway Handler Mapping->Gateway Web Handler->Filter->Service
工作流程
路由的ID
id
匹配路由的转发地址
uri
多个Predicate组合
各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配
一个请求满足多个路由的断言条件时,请求只会被首个成功匹配的路由转发
predicates
路由的优先级,数字越小,优先级越高
order
过滤器 过滤掉一些请求, 满足则转发
Filter
路由(Route)
作用:匹配http请求
After某某时间以后,断言才会进行匹配
After
在某某时间以前,断言才会进行匹配
Before
Between
name=regexp 匹配cookie名称为name,值为正则匹配
Cookie
header=regexp 匹配请求Header名称为header,值为正则匹配
Header
一组匹配的域名列表
Host
匹配一个或多个Http请求方式
Method
请求路径匹配,包含1个或者多个路径,matchTrailingSlash=true才会生效
Path
Query
RemoteAddr=192.168.1.1/24 IP地址匹配 比如匹配192.168.1.1-192.168.1.24地址
自定义获取remote address的处理器RemoteAddressResolver
返回始终采用标头中找到的第一个 IP 地址
trustAllRemoteAddressResolver
采用与在 Spring Cloud Gateway 前面运行的可信基础设施数量相关的索引
maxTrustedIndex
基于X-Forwarded-For请求头的XForwardedRemoteAddressResolver
部署在代理服务器(Nginx)获取不到真实请求IP
部署代理服务器应用获取不到真实请求的客户端IP,而是代理服务器IP
背景
HTTP代理会在HTTP协议头中添加X-Forwarded-For头,用来追踪请求的来源
发起请求时,请求头上带上一个伪造的X-Forwarded-For
proxy_set_header X-Forwarded-For $remote_addr;
最外层Nginx
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
里层Nginx
Nginx配置
从右向左遍历 剔除内网IP与本身服务器IP,获取可信任IP
RemoteIpValve
Tomcat服务器
指定代理层数,然后取X-Forwarded-For头中从右往左数第maxProxyCount个IP即为真实 IP 地址
maxProxyCount
Egg.js
伪造X-Forwarded-For
X-Forwarded-For
RemoteAddr
指定当前请求被路由的权重的,其接收两个参数:分组和比重,参与权重路由的地址必须在同一个分组,否则weight无效果,而权重为整型数字
Weight
继承AbstractRoutePredicateFactory重写apply方法
类必须加上RoutePredicateFactory作为结尾
自定义断言
断言(Predicate)
作用:可以修改输入输出请求
网关过滤器,需要通过spring.cloud.routes.filters配置在具体路由
通过spring.cloud.default-filters 配置在全局,作用在所有路由上
说明
给当前请求添加一个请求头
AddRequestHeader
当前请求头不存在Key时,给当前请求添加请求头,冒号分隔的 name 和 value 键值对的集合
AddRequestHeadersIfNotPresent
给当前请求添加请求参数 多个参数添加多次
AddRequestParameter
给响应的请求添加一个请求头
AddResponseHeader
集成hystrix 支持错误fallBack
CircuitBreaker
缓存请求Body key在ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR定义
CacheRequestBody
对指定响应头去重复。
RETAIN_FIRST保留第一个/RETAIN_LAST保留最后一个/RETAIN_UNIQUE保留唯一
去重策略strategy
DedupeResponseHeader
降级时在Header里面添加信息
FallbackHeaders
将一个JSON payload 转换为gRPC请求。
JsonToGrpc
过滤器允许缓存响应体和header,只能缓存Get
LocalResponseCache
接受 fromHeader 和 toHeader 参数 toHeader将匹配改写fromHeader 存在的值
MapRequestHeader
发送至网关之前修改请求body
ModifyRequestBody
修改响应体发送给客户端
ModifyResponseBody
给请求添加前缀/PrefixPath/url
PrefixPath
无参,在转发请求到服务提供者的时候,会保留host信息
PreserveHostHeader
跳转到指定位置
RedirectTo
移除Reponse的相关属性
RemoveJsonAttributesResponseBody
删除请求指定Header
RemoveRequestHeader
删除请求指定Parameter
RemoveRequestParameter
删除响应指定的Header
RemoveResponseHeader
限定请求Head的大小,超过Size发送431状态码
RequestHeaderSize
限流 令牌桶算法 可使用redis 实现
RequestRateLimiter
重写Location 响应头的值
RewriteLocationResponseHeader
重写请求路径
RewritePath
重写响应头的值
RewriteResponseHeader
强制保存Session
SaveSession
改写请求路径
SetPath
改写请求的header,将指定key改为指定value,如果该key不存在就创建
SetRequestHeader
改写响应的header,将指定key改为指定value,如果该key不存在就创建
SetResponseHeader
控制返回http状态码
SetStatus
改写/ path
StripPrefix
retries-重试次数/statuses-遇到什么样的返回状态才重试/methods-那些类型的方法会才重试/backoff-重试策略/exceptions-重试异常/series-series值重试
重试请求
Retry
控制请求大小,可以使用KB或者MB等单位,超过这个大小就会返回413错误
RequestSize
修改请求header中的host值
SetRequestHostHeader
将第三方的token转发到服务提供者那里去
TokenRelay
重写AbstractGatewayFilterFactory实现apply方法
自定义Filter
分类
GatewayFilter
全局过滤器,不需要在配置文件中配置,作用在所有的路由上
GlobalFilter
业务逻辑之前
pre
业务逻辑之后
post
生命周期
过滤器(Filter)
三大核心
引入redis依赖,配置端口 登录信息
自定义KeyResolver,定义限流标识(比如IP)
burstCapacity:令牌桶总容量
replenishRate:填充令牌速率 每秒
key-resolver 自定义Bean 的name
添加RequestRateLimiter配置
限流
引入注册中心Eureka/nacos
配置 uri:lb//serviceName
配置:discovery.locator.enabled= true
登录成功创建JWT令牌
登录请求
校验JWT令牌合法性,获取登录用户信息
非登录请求
定义全局过滤器AuthorizeFilter
鉴权
记录请求Body等日志存储在NOSQL
定义全局过滤器LogFilter
集成Actuator 具体操作查看actuator 官方API 动态创建 删除路由
实现RouteDefinitionRepository接口
持久化动态路由
动态路由
应用
Gateway
注册中心·
应用名-环境profile名.文件后缀(appName-dev.yaml)
Data ID(应用名)
分组
GROUP
默认是空串,公共命名空间
Namespace
基本组成
添加依赖nacos-spring-context
启用 Nacos Spring 的配置管理服务
serverAddr(配置服务地址)
@NacosProperties
@EnableNacosConfig
dataId=** 加载数据源为**
autoRefreshed 自动刷新配置
@NacosPropertySource
获取注解设置属性值
@NacosValue
添加依赖nacos-config-spring-boot-starter
nacos.config.server-addr=127.0.0.1:8848 配置服务地址
application.properties
@NacosPropertySource 同Spring
@NacosValue 同Spring
Spring Boot
添加依赖spring-cloud-starter-alibaba-nacos-config(需注意版本对应)
配置服务地址bootstrap.properties 优先加载配置
spring.cloud.nacos.config.server-addr
${prefix}-${spring.profiles.active}.${file-extension} 多环境
spring.cloud.nacos.config.prefix 配置
spring.application.name 默认 未配置
prefix
dataId
配置自动更新
@RefreshScope
spring.cloud.nacos.config.shared-configs
共享配置
spring.cloud.nacos.config.extension-config
扩展配置
主配置 > 扩展配置(extension-configs) > 共享配置(shared-configs)。
shared-configs[3] > shared-configs[2] > shared-configs[1] > shared-configs[0]
extension-configs[3] > extension-configs[2] > extension-configs[1] > extension-configs[0]
相同配置 优先级高的配置覆盖优先级低的配置
Spring cloud
derby数据库(默认)
版本要求:5.6.5+
修改conf/application.properties
执行conf/nacos-mysql.sql脚本,重启nacos
Mysql
大下标会覆盖小下标配置
共享配置shared-configs
扩展配置会覆盖共享配置
扩展配置extension-configs
1.先写某个节点缓存,写入MySql数据库
2.发布一个事件通知,其他节点接收通知,从mysql中重新拉取缓存
磁盘缓存同步
存储Mysql不存在集群问题
集群
服务发现
http请求的包装,对Http请求增强(记录请求时间)
HttpAgent
ThreadPool:newScheduledThreadPool->?
ThreadPool:newScheduledThreadPool->longPolling
1.checkLocalConfig 判断是否有更新
listener.receiveConfigInfo()
safeNotifyListener
2.cacheData.checkListenerMd5(); 比较MD5有更新触发NotifyListener
需要对比的配置关键信息拼接成字符串发送到服务端对比
3.checkUpdateDataIds
发送Http请求获取变化的groupKeys 长轮询请求
4.checkUpdateConfigStr
md5与cachData.listener.md5比较 ->listener.receiveConfigInfo()
5.safeNotifyListener
LongPollingRunnable
ThreadPool:scheduleWithFixedDelay->checkConfigInfo
ClientWork
NacosConfigService初始化
监听ApplicationReadyEvent事件
继承ApplicationListener
cachData->addListener
registerNacosListener
registerNacosListenersForApplications
onApplicationEvent
NacosContextRefresher
Nacos
面向分布式服务架构的轻量级流量控制组件
基于滑动窗口算法实现,Hystrix已停止更新,Sentinel功能更为丰富,灵活性可用性更高
功能介绍
https://github.com/alibaba/Sentinel/releases
jar包下载
指定启动的端口,默认8080
-Dserver.port
指定本服务的名称
-Dproject.name
指定sentinel控制台的地址,用于将自己注册进入实现监控自己
-Dcsp.sentinel.dashboard.server
用于指定控制台的登录用户名为 \"sentinel\",默认值为 “sentinel”
-Dsentinel.dashboard.auth.username=sentinel
用于指定控制台的登录密码为 \"123456\",默认值为 \"sentinel\"
-Dsentinel.dashboard.auth.password=123456
服务端 session 的过期时间
-Dserver.servlet.session.timeout
dashboard控制台
抛出异常BlockException的方式定义资源
Entry entry = SphU.entry(resourceName);
entry.exit();
SphU
返回布尔值的方式定义资源
if(SphO.entry(\"自定义资源名\"))
SphO.exit() 方法成对出现
SphO
硬编码
资源名称,必需项
entry 类型 可选项(默认为 EntryType.OUT)
entryType
指定函数负责处理 BlockException(限流)
blockHandler
指定处理BlockException异常的处理类 不指定默认本类
blockHandlerClass
指定的函数负责处理业务运行的异常(降级),指定blockHandler时候不生效
fallback
指定的类负责处理业务运行的异常
fallbackClass
默认的 fallback 函数名称,可选
用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
exceptionsToIgnore
@SentinelResource
资源名,即限流规则的作用对象,默认请求路径
resource
流控针对的调用来源,若为 default 则不区分调用来源,默认值default
limitApp
限流阈值
count
限流阈值类型
grade
流控模式
strategy
流控效果
controlBehavior
限流规则FlowRule
每S允许的QPS请求个数
1: QPS(默认)
当前请求上下文的线程个数,如果超出阈值,新的请求会被立即拒绝
0 :并发线程数
限流类型
接口达到限流条件时,直接限流
直接(默认)
当关联的资源达到阈值时,就限流自己(适合做应用让步)
高优先级资源触发阈值,对低优先级资源限流。
关联
只记录指定链路上的流量,指定资源从入口资源进来的流量,如果达到阈值,就可以限流
阈值统计时,只统计从指定资源进入当前资源的请求,是对请求来源的限流
链路
当 QPS 超过任意规则的阈值后立即拒绝,拒绝方式为抛出FlowException
快速失败(默认)
所有的请求按照先后次序排队执行,两个请求的间隔不能小于指定时长
排队等待
QPS超过阈值时,拒绝新的请求;QPS阈值是逐渐提升的,可以避免冷启动时高并发导致服务宕机
Warm Up
基于nacos
基于ZK
持久化规则
集群限流
Sentinel
1.接收TM指令发起全局事务的提交与回滚
2.负责与RM通信,协调各个分支事务的提交或回滚
TC
1.向TC发起全局提交或回滚指令
TM
接收事务协调器TC的指令,命令分支事务完成本地事务的提交或回滚。
RM
事务角色
1.TM向TC申请开启一个全局事务
2.TC创建全局事务,并将全局事务ID(称为XID)返回给TM
3.RM向TC注册分支事务,并且绑定XID
4.执行所有本地事务,记录undo_log,执行结果给TC
提交->删除日志文件
回滚->执行回滚语句
5.TC发送提交或回滚命令给RM(提交-删除回滚日志,回滚执行undo_log)
弱一致性
基于全局锁隔离
基于关系型数据库
AT(默认)
TC生成XID,执行自定义try方法
try
try 方法执行完成,执行自定义Confirm方法
confirm
try方法执行异常 执行cancel方法
cancel
try未执行/执行异常 调用了Cancel方法
空回滚
重复调用Confirm/Cancel方法
思路:执行方法check事务日志表status,校验Confirm/Cancel是否已执行
幂等
悬挂
存在问题
基于资源预留隔离·
代码侵入,需要写三个接口,性能非常好
性能要求高的事务,非关系型数据库事务
TCC
每个Tran都对应一个补偿动作Cancel
依照调用链路Tran调用补偿Cancel
重试失败事务,务必保证成功
向前恢复
补偿所有已完成的事务,执行结果返回失败
向后恢复
恢复策略
最终一致性
无隔离
代码侵入,需要写补偿业务,性能非常好
业务流程复杂,无法实现TCC的事务接口
SAGA
数据库必须实现并支持XA协议,基于数据库的XA协议来实现2PC
Register:XA Start->sql->XA End->XA Prepare 数据不可见
Report:Report Prepare Status->TC
TC->Commit/Rollback
强一致性
完全隔离
无代码侵入,性能差
适用于对一致性要求高,隔离性高的场景
XA
事务模式
本地事务提交前,先拿到全局锁
本地事务全部提交释放全局锁
全局锁限定超时时间
串行化保证写隔离
@GlobalTransactional
@GlobalLock+select for update
脏写问题
写隔离
默认未提交读
select for update 实现已提交读,性能开销大
读隔离
事务隔离(AT模式)
简单,易于部署和使用
高性能,低延迟
单点故障,文件系统故障导致数据丢失,无法使用等问题
扩展性较差,水平扩展时,需要考虑文件系统的共享和同步机制
数据备份和恢复的复杂性
File
可靠性,系统故障时候不会丢失数据·
ACID特性
技术成熟稳定
性能瓶颈,高并发处理性能存在问题
扩展性限制,水平扩展方面存在一定瓶颈
配置和管理复杂 需要初始化表
DB
性能较高
Seata-Server 1.3及以上版本支持
存在事务信息丢失风险
Redis
存储模式
可选nacos,作用: 存储和管理 Seata 事务参与者的信息的组件
SeataAutoConfiguration 自动装配注入
TMClient.init() 初始化TM
RMClient.init() 初始化RM
实现afterPropertiesSet
InitializingBean 接口
生成Aop代理对象
添加GlobalTransactionalInterceptor拦截器
扫描@GlobalTransactional/GlobalLock
添加TccActionInterceptor拦截器
TCC模式
继承AbstractAutoProxyCreator
GlobalTransactionScanner
继承MethodInterceptor,对增强的方法进行增强
1.创建全局事务(传播行为)
2.开启全局事务(锁资源)
3.执行业务逻辑
4.提交/回滚全局事务
5.释放资源
TransactionalExecutor.execute
handleGlobalTransaction
扫描@GlobalTransactional注解
select for update 申请本地锁
检查全局锁checkLock
GlobalLockExecutor.execute
handleGlobalLock
扫描@GlobalLock注解
invoke
GlobalTransactionalInterceptor
Seata 中的全局事务,默认实现类为DefaultGlobalTransaction
全局锁注解
@GlobalLock
Seata
Spring Cloud
XA协议
TCC协议
分布式事务
优劣势
无作用
1个标识位
记录时间戳,毫秒级
41位的时间戳
记录工作机器id 前5位为数据中心id(可以理解为机器库房id),后5位为机器id(可以理解为不同实例的id)
10位WorkerID
用来记录同毫秒内产生的不同id
12位序列号
组成
雪花算法
不依赖数据库 直接生成 速度快
优势
时钟错误导致ID重复问题
劣势
setnx
基本实现
常见问题
临界问题,不在特定区间内请求无法被统计到
传统计数器
解决临界问题,对大窗口切割小窗口,平滑移动窗口统计
滑动窗口计数器
无法应对短时间的突发流量
消费速率固定问题
漏桶算法
解决令牌桶问题
消费速率不受限
令牌桶算法
限流算法
1.历史热门数据
2.突发的热门数据 冷门变热门(口罩)
3.不存在的商品 变热门(新手机发布)
热门数据收集
秒杀设计
分布式
对修改关闭
对扩展开放
开闭原则(抽象定义框架,实现定义细节)
减少耦合性
提高可读性 可维护性 稳定性
依赖倒置原则(细节依赖抽象 针对接口编程)
降低复杂度
提高可读性 可维护性
降低变更风险
单一职责原则(一个类,接口,方法只负责一个职责)
多个专门接口替代单一总接口
接口隔离原则(细化接口)
迪米特法则(减少类之间耦合)
子类扩展父类,不能改变父类原有功能
子类可以增加独有方法
子类输入参数更加简洁宽松
子类输出参数更加全面
里氏替换原则(子类强化父类功能,不修改父类功能)
降低类的耦合度
合成复用原则(尽量使用对象的组合,聚合)
设计原则
逻辑简单,只需要传入参数即可
工厂类职责过重,不利于扩展
简单工厂模式(适用于创建对象少Calendar)
扩展性强,符合开闭原则
代码复杂,子类臃肿过多
工厂方法模式(定义创建对象接口,子类实现 ILoggerFactory)
抽象工厂模式(适用于一系列有关联系产品)
工厂模式(FactoryBean)
优点:执行效率高 无锁
缺点:浪费内存
饿汉式单例
优点:节省内存
缺点:线程不安全
懒汉式单例
优点:线程安全
缺点:效率问题
加锁懒汉式单例(double check)
性能高,无线程安全问题
能够被反射破坏
内部类单例
容器式单例(IOC)
单例模式
拷贝的是对象引用
浅拷贝
序列化对象,生成全新对象
深拷贝
原型模式(对象拷贝复制)
复杂的对象创建与使用分离,封装解耦优秀
内部结构变化 维护成本高
建造者模式(对象的创建Netty)
底层反射实现
被代理类必须实现接口
jdk动态代理
底层通过编码继承类实现
被代理类不需要实现接口,继承实现功能
cglib代理
代理模式(AOP)
JdbcUtils
Dao/Controller
门面模式(统一调度/工具类)
BeanWrapper
装饰器模式(扩展功能)
系统需要大量相似对象,需要缓冲池
常用于底层开发(Integer)
享元模式(资源共享)
目标角色(外部系统接口)
原角色(自己系统接口)
适配接口(适配接口)
角色定义
类适配器
对象适配器
接口适配器
适配器类型
适配器模式(适应不同接口开发的接口)
抽象与具体实现之间存在灵活多变的场景
一个类存在多个变化过程,这个过程需要独立扩展
不希望被继承 实现功能
Abstraction 抽象类
RefinedAbstraction 扩充抽象类
Implementor 实现类接口
ConcreteImplementor 具体实现类
主要角色
桥接模式(抽象与具体实现分离)
本身不处理任务逻辑,任务交给委派对象处理
ClassLoader
jdk
dispatchServlet
Springmvc
源码应用
任务细化,统一跟进管理任务
任务复杂情况下,容易造成代码紊乱
委派模式
模板方法模式
动态选择算法
动态选择实现类
动态加载Resource
动态选择代理
spring
(1)算法可以自由切换
(2)避免使用多重条件判断
(3)扩展性良好,增加一个策略只需实现接口即可
(1)策略类数量会增多,每个策略都是一个类,复用性很小
(2)所有的策略类都需要对外暴露
策略模式
多个对象处理一个请求,运行时动态决定哪个对象处理请求
动态指定一组对象处理请求
netty ChanelPipeline
java FilterChain
责任链模式
迭代器模式
命令模式
中介者模式
功能:主题对象被多个观察对象监听,主题对象发生变化,观察者对象做出相应的变化
被观察者或发布者,它维护了一个观察者列表,并提供方法用于注册、注销和通知观察者。
主题Subject
订阅者或监听器,它定义了一个接口或抽象类,包含了观察者所需实现的方法,通常包括更新方法,在主题状态改变时被调用
观察者Observer
核心角色
registerObserver(Observer observer);
unregisterObserver(Observer observer);
notifyObservers();
ISubject 接口
update()
IObserver接口
List.add(observer)
registerObserver
List.remover(observer)
unregisterObserver
List.foreach.update()
notifyObservers
ConcreteSubject 实现类
JAVA
被观察者
Observable接口
观察者
Observer接口
JDK
Guava
实现
观察者模式
访问者模式
设计模式
继承Thread 重写run方法
实现Runnable接口 实现run方法
实现Callable接口 实现call方法 带返回值
让当前线程睡一会
sleep
是等待调用join线程结束继续运行
join
短暂放弃CPU使用权,让其他线程优先执行
yield
打断线程,但当打断阻塞线程 sleep wait join 会中断服务,打断后打断标记仍为false,不会打断线程
interrupt
操作说明
Thread t=new Thread()
NEW 初始状态
Thread.yield()
Object.notify()
Object.notifyAll()
LockSupport.unpark()
t.start()等CPU调度
READY 就绪状态
CPU正在调度
RUNNING 运行状态
synchronized
BLOCKED 阻塞状态
Thread.join()
LockSupport.park()
Object.wait()
WAITING 等待
Thread.sleep(long)
Thread.join(long)
LockSupport.parkUntil(long)
Object.wait(long)
TIMED_WAITING 超时等待
TERMINATED 终止状态
线程状态
不推荐,会强制退出正在执行的任务
Thread.stop()
推荐使用,中断标志 判断是否结束线程
Thread.currentThread.isInterupted()
终止线程
锁定整个方法
方法上
锁定包含的代码块上
代码块上
类锁
静态方法/类对象
Object对象头部区域存储锁状态标记
JMM MonitorEnter 加锁/MonitorExit 释放锁 唤醒其他线程
锁升级:偏向锁-轻量级锁-重量级锁
获取::当一个线程获取该对象锁时候。对象头存储当前线程ID 单次CAS
释放:线程结束/其他线程获取偏向锁
偏向锁
CAS自旋退出,抢占到线程 多次CAS
轻量级锁
监视器锁(Monitor)来实现的
重量级锁
锁优化
锁定当前线程
wait
锁定当前线程 如果经过long(毫秒)时间后没有收到notify或者notifyAll的通知,自动从等待队列转入锁池队列 会释放锁
wait(long)
随机从等待队列中通知一个持有相同锁的一个线程唤醒
notify
通知等待队列中的持有相同锁的所有线程,让这些线程转入锁池队,唤醒全部线程
notifyAll
通信
内存中的值V、旧的预估值X、要修改的新值B 如果V=X 则将V改成B
while 循环比较直到V=X
原子更新整型变量
AtomicInteger
原子更新长整型变量
AtomicLong
原子更新布尔变量
AtomicBoolean
原子更新整型数组的某个元素
AtomicIntegerArray
原子更新长整型数组的某个元素
AtomicLongArray
原子更新引用类型数组的某个元素
AtomicReferenceArray
原子更新引用类型
AtomicReference
原子更新引用类型里的字段
AtomicReferenceFieldUpdater
原子更新带有标记位的引用类型
AtomicMarkableReference
原子更新整型字段
AtomicIntegerFieldUpdater
原子更新长整型字段
AtomicLongFieldUpdater
原子更新带有版本号的引用类型
AtomicStampedReference
原子类
ABA问题 用AtomicStampedReference解决问题
自旋时间太长 带来性能开销问题
只能保证一个共享变量的原子操作
CAS
如何保证互斥性--共享资源state 0-无锁 1-有锁
被拒绝访问的线程如何挂起--lockSupport.park
同一个线程重复访问如何处理--可重入性保存抢锁线程ID
设计思考
重入锁定义:一个线程多次抢占同一把锁,不需要抢占锁,只需要记录重入次数
Lock(接口)
AQS父类AbstractQueuedSynchronizer
跟NonfairSync大体一致, 区别 无抢锁过程 tryAcquire之前判断队列是否为空
lock
跟NonfairSync大体一致
unlock
FairSync(公平锁 子类 实现类)
CAS 抢锁 0-1 设置当前线程
0 无锁
exclusiveOwnerThread=currentThread当前锁定线程 记录重入次数
非当前线程 抢锁失败
1 有锁
getState 获取锁状态
tryAcquire
Node 存储线程节点Thread
表示当前结点已取消调度。当timeout或被中断(响应中断的情况下),会触发变更为此状态,进入该状态后的结点将不会再变化
CANCELLED(1)
表示后继结点在等待当前结点唤醒。后继结点入队时,会将前继结点的状态更新为SIGNAL。
SIGNAL(-1)
表示结点等待在Condition上,当其他线程调用了Condition的signal()方法后,CONDITION状态的结点将从等待队列转移到同步队列中,等待获取同步锁
CONDITION(-2)
共享模式下,前继结点不仅会唤醒其后继结点,同时也可能会唤醒后继的后继结点。
PROPAGATE(-3)
新结点入队时的默认状态
INITAL(0)
WaitStatus=0
构建双向链表Head-Node-Node-Tail
addWaiter
成功:退出循环
失败:Node.Pre<>Head流程
tryAcquire(抢锁)
Node.Pre=Head
是否要挂起抢锁失败线程
shouldParkAfterFailedAcquire
挂起线程
parkAndCheckInterrupt
Node.Pre<>Head
aquireQueued
acquire
失败
保存当前线程setExclusiveOwnerThread
成功
抢锁 state(CAS 0-1)
lock(加锁)
state=state-1
exclusiveOwnerThread=null
操作
LockSupport.unpark Head.next 线程节点
tryRelease
release(1)释放锁
unlock(释放锁)
NonfairSync(非公平锁 子类 实现类)
Sync(父类)
ReentrantLock(重入锁)
特性:写写互斥/读写互斥/读读不互斥
ReadLock(读锁)
WriteLock(写锁)
ReentrantReadWriteLock(重入读写锁)
StampedLock
阻塞当前持有锁的线程
await
唤醒处于condition阻塞状态下的线程
signal
唤醒处于condition阻塞状态下所有线程
signalAll
用法
构建condition单向链表,存储当前线程
addConditionWaiter
release(state)彻底的释放锁
unparkSuccessor 唤醒Lock 处于阻塞状态下线程
fullyRelease
阻塞当前线程
LockSupport.park
将condition队列 第一个线程移动到AQS队列
transferForSignal
唤醒condition队列中的线程
LockSupport.park(node.Thread)
condition
锁
保证内存的可见性
禁止指令重排序
volatile
作用:线程独有变量
获取当前线程currentThread.ThreadLocalMap.get(threadLocal)
get
获取当前线程currentThread
set
调用threadLocal.remove 删除弱引用
内存泄漏
线性探索,当前节点不为null 找下一个 若整个空间都找不到空余的地址,则产生溢出 扩容
哈希冲突解决
ThreadLocal
作用:线程安全的hashMap
jdk1.7 数组+Segment+分段锁
jdk1.8 数组+链表+红黑树 CAS+Synchronized保证线程安全
弱一致性 get可能获取到过期的值
ConcurrentHashMap
组件/关键字
功能:一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行
构造函数初始化state=n
countDown方法实现state=state-1,并且如果state=0唤醒await阻塞在AQS队列中线程
自循环阻塞latch线程 当state=0时候退出循环
CountDownLatch
功能:同一时间段只能有N个线程访问,其他线程等待挂起,等到线程释放,等待线程恢复访问(限流)
初始化 state=N N个线程可以同时访问
成功 线程继续执行
失败 线程保存在AQS阻塞队列
获得令牌 state=state-1
唤醒处于AQS阻塞队列中的线程
释放令牌state=state+1
release
Semaphore
功能:可循环使用(Cyclic)的屏障(Barrier)
初始化 state=n
condition.await
到达指定N个线程 condition.signalAll
reset 重新初始化
1.CyclicBarrier基于Lock+condition实现的,CountDownLatch继承AQS实现的
2.CyclicBarrier可以重复使用;而CountDownLatch是一次性的,不可重复使用
3.CyclicBarrier中操作计数和阻塞的是同一个线程,调用方法只有一个await方法;而CountDownLatch中操作计数和阻塞等待是N个线程,控制计数调用方法countDown
与CountDownLatch区别
CyclicBarrier
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
newFixedThreadPool
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务
newSingleThreadExecutor
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newCachedThreadPool
创建一个定长线程池,支持定时及周期性任务执行
newScheduledThreadPool
基本类别
线程池中的常驻线程数,即保持存活的线程数量
corePoolSize(核心线程数)
线程池中允许的最大线程数,即线程池中允许存在的最多线程数量。
maximumPoolSize(最大线程数)
由数组构成的有界阻塞队列
ArrayBlockingQueue
由链表构成的有界阻塞队列
LinkedBlockingQueue
支持优先级排序的无界阻塞队列
PriorityBlockingQueue
支持优先级的延迟无界阻塞队列
DelayQueue
单个元素的阻塞队列
SynchronousQueue
由链表构成的无界阻塞队列
LinkedTransferQueue
由链表构成的双向阻塞队列
LinkedBlockingDeque
用于保存等待执行的任务的队列,有多种实现方式BlockQueue
workQueue(任务队列)
当线程池中的线程数量大于核心线程数时,多余的空闲线程的存活时间
keepAliveTime(线程存活时间)
用于创建新线程的工厂,可以定制线程名、线程优先级等
threadFactory(线程工厂)
直接抛出 RejectedExecutionException 异常
AbortPolicy
在任务被拒绝添加后,会使用调用线程池的线程来执行该任务
CallerRunsPolicy
将等待时间最长的任务丢弃,然后尝试将当前任务添加到工作队列中
DiscardOldestPolicy
直接将任务丢弃,不作任何处理
DiscardPolicy
实现接口自定义策略
RejectedExecutionHandler
当任务队列满时,对新任务的处理策略
rejectedExecutionHandler(拒绝策略)
ThreadPoolExecutor参数
runWork执行线程
addWork(**,true)创建线程
corePoolSize未满
执行rejectedExecutionHandler拒绝策略
线程池已满
addWork(**,false)创建线程
线程池未满
workQueue队列已满
任务work存储队列
workQueue队列未满
corePoolSize已满
execute提交执行任务
true
true->reject(command)执行拒绝策略
false->
false->remove(command) 删除任务
true->isRuning判断线程running状态
true->
false->reject(command)执行拒绝策略
true->workQueue.offer(command)加入workQueue阻塞队列
false
isRuning(验证线程是否runing状态)
workerCountOf(c) <corePoolSize 线程池个数<核心线程数
thread.start()
true->HashSet.add(new Work(task))
回滚操作
false->addWorkerFailed
addWork
while(task=getTask())
runWorker
从阻塞队列workQueue拿数据 不用等
从阻塞队列workQueue拿数据 阻塞 死等
false->workQueue.take()
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize
getTask
processWorkerExit
重写beforeExecute方法
重写afterExecute方法
继承ThreadPoolExecutor
自定义线程池
ThreadPoolExecutor
功能:获取线程的执行结果
任务结束后返回一个结果,阻塞线程
停止一个任务
方法是否完成
isDone
方法是否取消
isCancel
调用callable.call方法执行线程获取返回结果
result=Callable.call()
CAS操作 将返回结果赋值共享变量
遍历waiters链表 unpark 唤醒线程
finishCompletion
outcome=set(result)
run
保存当前线程到waitNode 单项链表
addWait
挂起当前线程
park
awaitDone
未完成<=COMPLETING
report
已完成
原理分析(FutureTask)
Future
功能:异步执行、链式操作、任务编排 默认线程池ForkJoinPool.commonPool()
异步执行一个任务 无返回值
runAsync
有返回值
supplyAsync
获取前一个异步线程的结果和异常 无法修改返回结果
whenComplete
把whenCompleteAsync这个任务提交给线程池来执行
whenCompleteAsync
有返回值 ,可以处理任务异常
handle
handle中的任务提交到线程池运行
handleAsync
捕获范围包含前面的所有异步线程
exceptionally
不关心任务的处理结果,无返回值,无输入参数
thenRun
thenRun中的任务提交到线程池运行
thenRunAsync
thenApply
thenApply中的任务提交到线程池运行
thenApplyAsync
无返回值
thenAccept
thenAccept中的任务提交到线程池运行
thenAcceptAsync
获取上一步的结果,而且有自己的返回值,与thenApply()具有相同的功能
thenCompose
thenCompose中的任务提交到线程池运行
thenComposeAsync
组合两个CompletableFuture,两个任务结束后执行,无参数,无返回值
runAfterBoth
runAfterBoth中的任务提交到线程池运行
runAfterBothAsync
组合两个CompletableFuture,两个任务结束后执行,有参数(执行结果),无返回值
thenAcceptBoth
thenAcceptBoth中的任务提交到线程池运行
thenAcceptBothAsync
组合两个CompletableFuture,两个任务结束后执行,有参数(执行结果),有返回值
thenCombine
thenCombine中的任务提交到线程池运行
thenCombineAsync
两个异步任务相比较,有任何一个执行完成,就进行下一步操作,无参数,无返回值
runAfterEither
runAfterEither中的任务提交到线程池运行
runAfterEitherAsync
两个任务有一个执行完成,获取它的返回值,处理任务,有参数,没有返回值
acceptEither
acceptEither中的任务提交到线程池运行
acceptEitherAsync
两个任务有一个执行完成,获取它的返回值,处理任务,有参数,有返回值
applyToEither
applyToEither中的任务提交到线程池运行
applyToEitherAsync
阻塞当前线程,直到任务完成并返回结果
阻塞当前线程,直到任务完成并返回结果 会抛出InterruptedException和ExecutionException异常,需要进行异常处理。
当所有的CompletableFuture完成后执行计算
allOf
任意一个CompletableFuture完成后执行计算
anyOf
手动完成一个异步任务,并设置其结果
complete
待跟进
CompletableFuture
功能:大任务拆分小任务,最后统计结果
子任务ForkJoinTask线程池
记录工作线程以及为工作线程分配的任务
无返回结果的ForkJoinTask
RecursiveAction
有返回结果的ForkJoinTask
RecursiveTask
任务完成执行后会触发执行一个自定义的钩子函数
CountedCompleter
ForkJoinTask(集合)
WorkQueue(数组)
ForkJoinPool
向当前任务所运行的线程池中提交任务
fork
获取任务的执行结果。阻塞当前线程直到对应的子任务完成
ForkJoinTask
用法:
ForkJoin
BlockingQueue
线程组件
互斥 共享资源X与Y只能被一个线程占用
占用且等待 线程1占用资源X等待获取资源Y时候不释放X
不可抢占 其他线程不能抢占线程1占用资源X
循环等待 线程1等待线程2资源Y释放,线程2等待线程1资源X释放
产生条件
2. 锁顺序一致性 例如 线程A,B均是锁Obj1 然后锁Obj2
如何破坏
保持与CPU核心数量一直如8核CPU 可以设置8线程
CPU密集型
可以适当提高线程数量 一般是CPU核心数*2
IO密集型
线程数量选择
多线程
访问文件
FileInputStream
访问数组
ByteArrayInputStream
访问管道
PipedInputStream
缓冲流
BufferdInputStream
对象流(反序列化)
ObjectInputStream
抽象基类流
FilterInputStream
推回输入流
PushbackInputStream
特殊流
DataInputStream
InputStream(字节输入流)
FileReader
CharArrayReader
PipedReader
访问字符串
StringReader
BufferedReader
转换流 字节流转换为字符流 解决编码问题
InputStreamReader
FilterReader
PushbackReader
Reader(字符输入流)
输入流I
FileoutputStream
ByteArrayOutputStream
PipedOutputStream
BufferedOutputStream
对象流(序列化)
ObjectOutputStream
打印流
PrintStream
DataOutputStream
OutputStream(字节输出流)
FileWriter
CharArrayWriter
PipedWriter
StringWriter
BufferedWriter
转换流 字节流转换为字符流 解决编码问题
OutputStreamWriter
FilterWriter
Writer(字符输出流)
输出流o
8位的二进制数据
以字节为单位进行读写,不涉及字符编码转换
用于处理图像、音频、视频等二进制数据。
字节流
16位Unicode字符
对数据进行编码和解码,可以用来处理不同字符集的数据
处理文本数据
字符流
区别
减少IO次数
源文件10B buffer=6B只会2次IO
buffer
清空缓冲区,强制将缓冲区的数据写入文件或是读取
flush
一个中文3b 每次读取1b导致乱码问题
中文乱码
ObjectOutputStream 对象流(序列化)
ObjectInputStream 对象流(反序列化)
序列化
应用程序缓冲区
内核缓冲区
本地磁盘(DMA)
内核缓冲区无数据,会挂起请求的用户请求,加载到数据会唤醒用户请求
本地磁盘
应用程序
写入IO
client 端
获取输入流(接收消息)阻塞操作
getInputStream
获取输出流 发送消息
getOutputStream
Socket
Server 端
阻塞 获取客户端链接
accept
ServerSocket
网络IO
应用层->传输层->网络层->数据链路层->物理层
请求过程
http请求报文
应用层
tcp头
传输层
ip头
网络层
mac头
数据链路层
流传输
物理层
分层模型
Http协议
Https协议
网络协议
阻塞IO,ServerSocket.accept 阻塞后续请求
1.用户进程recvfrom
2.内核无数据包,准备接受数据
3.数据包接收完成
4.复制数据包
5.复制完成
6.处理成功 返回数据包
BIO
非阻塞IO 面向缓冲区
6.处理成功 返回数据包
从文件中读写数据
FileChannel
从UDP协议中读取数据
DatagramChannel
从TCP协议中读取数据
cofigureBlocking=false 非阻塞模式
SocketChannel
监听一个Tcp链接,每个Tcp链接都会产生一个SocketChannel
cofigureBlocking=false 非阻塞模式
ServerSocketChannel
实现类
Channel(通道)
创建和销毁效率高
工作效率低
在堆中创建缓冲区(间接缓冲区)
allocate(int capacity)
创建和销毁效率低
工作效率高
在系统内存创建缓冲区(直接缓冲区)
allocatDirect(int capacity)
=堆缓冲区
数组创建缓冲区
wrap(byte[] arr)
创建缓冲区
向当前可用位置添加数据
put(byte b)
向当前可用位置添加一个byte[]数组
put(byte[] byteArray)
添加一个byte[]数组的一部分
添加数据
Buffer所能够包含的元素的最大数量。定义了Buffer后,容量是不可变的
容量(capacity)
limit以及之后限制写入与读取,不能大于capacity
限制(limit)
当前可写入的索引位置,不能小于0 不能大于limit
位置(position)
调用reset position=mark
标记(mark)
重置postion
重置(reset)
position=0
limit=capacity
mark舍弃
还原(clear)
limit=position
mark丢弃
反转读写模式
缩小范围(flip)
mark 丢弃
重绕缓冲区(rewind)
缓冲区是否只读
只读(isReadOnly)
获取当前缓冲区是否为直接缓冲区
直接缓冲区(isDirect)
获取position与limit之间的元素数
获取元素数(remaining)
ByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
Buffer(缓冲区)
定义:管理多个NIO的channel通道是否为读写事件做好准备的组件
阻塞 所有注册事件
select()
返回所有可执行事件(解除阻塞)的Keys
连接就绪
OP_CONNECT
接收就绪
OP_ACCEPT
读就绪
OP_READ
写就绪
OP_WRITE
selectedKeys()
Selector(选择器)
核心组件
NIO
定义:多个IO请求可以注册到select上,liunx监控所有select注册的链接,数据准备好就会返回
弊端:支持连接数有限 一般支持1024个链接,内核会扫描所有注册的select 所有链接 会带来性能下降
1.用户IO请求注册select
2.内核无数据 不阻塞
3.数据包接收完成 select 返回状态 可读
4.复制数据包 系统调用 recvfrom
select/poll
定义:采用fd事件通知CallBack的方式,解决poll模式下轮询带来性能问题
优势:处理连接数不限制(受限于内存),连接数取决于最大句柄数,不需要轮询,性能得到提升 mmap复制内存 连接数少socket活跃情况下不如poll效率高
1.用户IO请求注册select fd注册信号处理程序
2.内核无数据 不阻塞
3.数据包接收完成 select 返回状态
4.mmap 映射内存区域
5.复制完成 调用fd的callback 通知应用程序处理后续逻辑
epoll(2.6内核之后)
1.应用程序调用sio_read 直接返回
2.系统接收数据完成 提交SIGIO信号
3.系统复制数据完成 递交aio_read 通知应用程序处理
aio
IO复用
原理解析:用户缓冲区与内核缓冲区 映射共享内存
拷贝过程:硬盘—>内核—>socket缓冲区—>网卡
API调用:MappedByteBuffer.map()
特点:用户可以修改内存,不能超过2G 适用于小文件 rocketMq
原理解析:用户进程发送指令,内核空间内部进行 I/O 传输 无法映射共享内存
API调用:FileChannel.transferFrom()/transferTo()
特点:用户不可以修改内存,适合大数据量的传输,kafka
sendFile
零拷贝
动态扩容
池化技术
读写索引区分
零拷贝机制
末尾读索引
已读字节
末尾写索引
可读字节
容量
可扩容容量
容量上限=Integer.MaxValue
可以被重用
高并发有很好的节约内存的效果
池化ByteBuf
非池化ByteBuf
-Dio.netty.allocator.type={unpooled|pooled} 不开启|开启
池化
扩容小于等于512,扩容为16的倍数大小
扩容大于512,扩容为2的n次方大小
扩容
读写性能高,创建和销毁代价大,不受JVM管控
ByteBufAllocator.DEFAULT.directBuffer()
直接内存ByteBuf
受JVM控制
ByteBufAllocator.DEFAULT.heapBuffer()
堆内存ByteBuf
内存类型
writeBytes(byte[] bytes)
writeBytes(ByteBuffer buffer)
writeBytes
writeInt
writeLong
writeFloat
writeChar
writeCharSequence(String s)
writeCharSequence(StringBuffer sb)
writeCharSequence
写入
readByte
readInt
readFloat
标记读取索引位置
markReaderIndex
重置读取索引
resetReaderIndex
不移动读指针
getByte
读取
setByte
修改
回收
对原始buf进行切片
slice是没有数据拷贝 浅克隆
slice
切片
copy
复制
逻辑上的组合 浅拷贝
ByteBuf
Component[] components
自己的读写索引
CompositeByteBuf组成
CompositeByteBuf.addComponents
逻辑上的组合 浅拷贝
支持多数据源 数据源的类型包括 byte[]、ByteBuf、ByteBuffer
Unpooled.wrappedBuffer
通过writeBytes方法组合多个ByteBuf。新组合的ByteBuf与之前的ByteBuf完全独立开
ByteBuf.writeBytes
组合
使用
发送 数据拷贝进入 Socket 的内核发送缓冲区
发送缓冲区SO_SNDBUF
发送缓冲区可以多次发送到接收缓冲区 window size>0
接收缓冲区SO_RCVBUF
Socket缓冲区
1.发送方每次写入数据 < 套接字缓冲区大小
2.接收方读取套接字缓冲区数据不够及时
粘包
1.发送方每次写入数据 > 套接字缓冲区大小
2.发送的数据大于协议 MTU,所以必须要拆包
拆包
原因
指定一个报文具有固定长度 空白部分补上空格
优点:实现简单
缺点:浪费带宽,超长报文会有问题
FixedLengthFrameDecoder
1.定长协议
在包的中添加指定的特殊字符
优点:
根据特殊字符进行解码
DelimiterBasedFrameDecoder
默认换行符
LineBasedFrameDecoder
2.特殊字符分割协议
报文长度+报文内容
发送的数据包最大长度
maxFrameLength
长度域的偏移量
lengthFieldOffset
长度域的所占的字节数
lengthFieldLength
长度值的调整值
=package.length- 长度域的值 – 长度域偏移 – 长度域长
lengthAdjustment
需要跳过的字节数
initialBytesToStrip
LengthFieldBasedFrameDecoder
3.变长协议
拆包粘包
小负载低并发模型
Reactor单线程模型
能满足大多数场景
高并发场景性能问题 ,单线程处理accept请求
Reactor多线程模型
Reactor主从多线程模型
Reactor模型
Channel
Pipeline
组件
Netty
IO
xx.java->javac->xx.class->jvm
xx.java->词法分析器->token流->语法分析器->语法树->语义分析器->注解语法树->代码生成器->xx.class字节码
javac
加载JAVA_HOME/jre/lib/rt.jar或Xbootclassoath选项指定目录jar包
Bootstrap ClassLoader
加载java平台扩展功能包JAVA_HOME/jre/lib/*.jar 或者 -Djava.ext/dirs指定目录下jar包
Extension ClassLoader
加载classpath下jar包以及Djava.class.path指定目录类或者jar
App ClassLoader
继承ClassLoader 自定义加载class
Custom ClassLoader
类加载器ClassLoader
类加载优先级Bootstrap ClassLoader>Extension ClassLoader>App ClassLoader>Custom ClassLoader
继承classLoader 重写 loadClass 方法
Thread.currentThread.setContextClassloader(mysql驱动)
如何破坏?
双亲委派模式
类加载
类的字节码文件流信息->jvm方法区
类文件中对象的class->jvm堆
装载
验证被加载的类的正确性
验证
静态变量分配内存空间,初始化默认值(static int a=10;为a分配内存空间,初始化为0)
准备
将类中符号引用转为直接引用(映射内存地址)
解析
链接
为静态变量初始化真正的值 (a=10)
初始化
卸载
内存加载
只有一个 线程共享 非线程安全 生命周期跟jvm虚拟机一样
类信息
常量
静态变量
即时编译器编译后的代码
存储结构(OOM)
方法区Method
对象
数组
堆Heap
一个线程创建一个 线程私有 线程安全 生命周期跟线程一样
局部变量表
操作数栈
动态链接
方法的返回地址
栈帧(1:n)
存储结构(StackOverflowError)
虚拟机栈stack
c语言方法 native 方法
本地方法栈native stack
线程私有,线程安全 记录线程代码运行位置
程序计数器pc resigter
运行时数据区
大对象 新生代放不下
youngGC>15次还没有被垃圾回收
老年代/元空间 old GC 2/3
eden区 8/10
空间不够可向old借用空间(担保机制)
s0 1/10
s1 1/10
s区(解决空间碎片问题)
新生代 young gc 1/3
内存结构
栈中本地变量
static 成员
本地方法栈中变量
类加载器
Thread[java线程]
引用不可达算法GCRoot
判断垃圾
空间碎片问题
标记清除算法
空间浪费问题,s区
复制算法
效率问题,老年代
标记整理算法
垃圾回收算法
单线程垃圾收集器 适用新生代 复制算法
Serial
Serial老年代版本 标记整理算法
Serial Old
多线程垃圾收集器 适用于新生代 复制算法
ParNew
与ParNew类似 更加关注吞吐量 复制算法
Parallel Scavenge
Parallel 老年代垃圾收集器 标记整理算法
Parallel Old
1.初始标记
2.并发标记(不会终止用户线程)
3.重新标记
4.并发处理(不会终止用户线程
3.最终标记
4.筛选回收(有选择性回收垃圾)
G1(新老年代,自设置停顿时间,标记整理算法,用户交互 web端)
当老年代的大小占据了堆内存的% Full GC
-XX:InitiatingHeapOccupancyPercent
young GC 多少次进入Old区
-XX:MaxTenuringThreshold
指定收集的停顿时间,默认是200ms
-XX:MaxGCPauseMillis
设置在一次混合回收的过程中 后续回收次数
-XX:G1MixedGCCountTarget
设置空闲内存达到多少停止回收
-XX:G1HeapWastePercent
G1参数
垃圾回收器
垃圾回收
jps 查询Java进程信息
jinfo查看jvm参数/修改jvm参数
jstat 查看jvm运行时状态信息, 包括内存状态、垃圾回收
jstack 查看jvm线程快照的命令
jmap 生成dump文件,查询堆内对象示例的统计信息、查看classLoader的信息以及finalizer队列
jhat 分析dump文件 用于离线分析
常用命令
jconsole
jvisualvm
MAT
arthas
堆内存分析
GCViewer
gceasy.io
GC日志
1.jstat 打印gc日志,查询内存空间大小
2.minor gc/major gc 工具gceasy查看
3.jmap 查询内存使用情况
1.堆内存空间不足
2.edm区域太小,频繁ygc 大量对象进入old区
3.代码问题 大对象
GC频繁
1.jstat 打印gc日志,查询内存空间大小
2.jmap 查询内存使用情况
3.jstack 查询线程,cpu请求情况
4.dump堆文件,mat工具分析
5.增大S区
1.大对象问题,系统创建了太多大对象进入了Old区域
2.高并发问题,S区太小,太多对象来不及销毁就进入了Old区域
3.Metaspace(永久代)因为加载类过多触发Full GC。
4.内存泄漏问题,垃圾对象无法被回收
5.错误调用System.gc()调用
6.垃圾收集器问题 空间碎片问题
Full GC频繁
1.top查询cpu使用率高的应用ID
2.jstack 查询线程使用情况,排除死锁问题
3.jinfo 查询JVM参数信息,jmap查询堆内存使用情况
4.jstat 统计FullGC情况
1.内存消耗过啊,导致Full GC次数过多
2.代码中有大量消耗CPU的操作,导致CPU过高,系统运行缓慢;
3.死锁
4.大量线程访问接口
CPU 飙升
1.确定是堆上OOM还是方法区/元空间上OOM
2.方法区OOM 查询代码有没有动态生成类加载类
3.jmap dump 堆上内存信息。mat 分析有没有大对象
4.jinfo 查询堆内存大小,比例情况。元空间大小。垃圾收集器的选择。
1.大对象问题,Old区域放不下
2.Metaspace 加载类过多触发OOM
3.本身内存空间过小问题,加大内存
4.高并发问题,太多对象创建来不及销毁回收
OOM
性能优化
JVM
add
delete
ArrayList
LinkedList
HashMap
TreeMap
HashSet
TreeSet
集合
泛型
反射
样例: (参数列表)->{}
小括号内的参数类型可以省略
如果有且仅有一个参数,则小括号可以省略
():参数列表
->:连接符
如果有且仅有一个语句,可以同时省略大括号,return 关键字及语句分号
{}: 方法体
语法结构
Lambda表达式只能用于接口中只有一个抽象方法的情境中@FunctionalInterface
必须为接口才能使用Lambda
Lambda表达式
Collection.stream()/parallelStream() 集合 parallelStream并行流 多线程处理
Arrays.stream(T[] array) 数组
Stream.of/iterate/generate
list.stream().forEach(x->System.out.println(x.getName()));
遍历(foreach)
list.stream().filter(x->x.getAge()==55).findFirst().orElse(null)
findFirst 返回匹配的第一条
findAny 返回匹配的任意一条 不能保证时第一条
查找(find)
list.stream().allMatch(x->x.getAge()>40)
allMatch 全部匹配返回true
anyMatch 匹配一条返回true
noneMatch 全部不匹配返回true
匹配(match)
过滤条件例:list.stream().filter(x->x.getAge()>10).findFirst().get()
条件匹配(filter)
max
min
统计总数例:list.stream().filter(x->x.getAge()>25).count()
聚合统计(max,min,count)
就是在Map的基础上,会将集合的数据结构给展开
flatMap
reduce
收集数据到集合或数组stream.collect(Collectors.toList());
计数:Long count = personList.stream().collect(Collectors.counting());
平均值:Double average = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));
最值:Optional<Integer> max = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));
求和:Integer sum = personList.stream().collect(Collectors.summingInt(Person::getSalary));
collect
分组 groupingBy
条件分2组partitioningBy
拼接字符:String result3 = list.stream().collect(Collectors.joining(\"||\
连接(joining)
正常排序:list=list.stream().sorted(Comparator.comparing(Person::getName)).collect(Collectors.toList());
倒序:list=list.stream().sorted(Comparator.comparing(Person::getName).reversed()).collect(Collectors.toList());
多次排序:list=list.stream().sorted(Comparator.comparing(Person::getName).thenComparing(Person::getAge)).collect(Collectors.toList());
排序(sorted)
合并concat
去重distinct
限制limit
跳过skip
Stream API
JDK8
java 核心
本地电脑上面的仓库 默认在当前系统用户.m2下
本地仓库
局域网搭建的仓库nexus
私服仓库
互联网上面的仓库 Apache维护
中央仓库
查找顺序:本地仓库->私服仓库->中央仓库
仓库类型
先定义优先使用
1.优先声明原则
路径最近优先使用
2.路径就近原则
显示声明不依赖Bean exclusions
3.排除依赖
依赖冲突
Properties 定义版本标签
${version}绑定指定版本标签
版本依赖
删除target目录及其目录下所有内容
clean(清理命令)
1.src/main/resources 文件->拷贝->target/classes目录下
2.src/main/java **.java->编译->**.class
3.**.class->拷贝->target/classes
compile(编译命令)
1.src/main/resources 资源->拷贝->target/classes目录下
2.src/main/java **.java->编译->**.class
4.src/test/resources资源->拷贝->target/test-classes目录下
5.src/test/java **.java->编译->**.class->拷贝->target/test-classes目录下
6.执行单元测试类
package(打包命令)
1.执行Maven package命令
2.maven 打成 jar 包或 war 包发布到本地仓库
install(安装命令)
执行src/test/java下的单元测试类
test(测试命令)
将项目发布到你配置的仓库位置
deploy(发布命令)
更新项目依赖的jar
update(更新命令)
常用命令·
定义:父项目的坐标。子项目中没有规定某个元素的值,那么父项目中的对应值即为项目的默认值。
定义:groupId是项目组织唯一的标识符,实际对应java包的结构,是main目录里java的目录结构
命名规则:一般是 域.公司名称 ,可以后面跟多个,域又分为org、com、cn等等许多,其中org为非盈利阻止,com为商业阻止
groupId
定义:artifactId就是项目唯一的标识符,实际项目的名称
artifactId
定义:版本管理
主版本: 表示项目的重大架构变化。如struts2和struts1采用不同的架构
次版本: 较大范围功能增加和变化,及bug修复,并且不涉及到架构变化的。
增量版本:表示重大bug的修复,如果发现项目发布之后,出现影响功能的bug,及时修复,则应该是增量版本的变化。
开发版本:SNAPSHOT
内部测试:alpha
外部测试:beta
测试版本:alpha、beta
稳定版:rc、final、stable、release
正式发布版:GA
里程碑版本:往往表示某个版本的里程碑,经常见到snapshot,另外还有alpha、beta
命名规则:<主版本>.<次版本>.<增量版本> - <里程碑版本>
version
从父级仓库查找依赖版本 查找顺序:relativePath元素中的地址–本地仓库–远程仓库 如果为空 直接从本地仓库找,只存在父模块中
relativePath
parent
描述这个POM文件是遵从哪个版本的项目描述符
modelVersion
见parent/groupId
见parent/artifactId
maven依赖文件
pom
java普通项目打包
jar
java web项目打包
war
定义:maven打包方式,有三种
packageing
见parent/version
声明一个对于用户更为友好的项目名称,非必须
项目地址或者公司地址
url
项目描述
description
定义的是构建该项目所需的最低maven版本号;默认值为2.0
maven
prerequisites
问题管理系统名称
问题管理系统Url
issueManagement
定义:项目持续集成信息
持续集成系统的名字,例如continuum
持续集成系统的URL
构建完成时,需要通知的开发者/用户的配置项
传送通知的途径
发生错误时是否通知
sendOnError
构建失败时是否通知
sendOnFailure
构建成功时是否通知
sendOnSuccess
发生警告时是否通知
sendOnWarning
通知发送到哪里
address
扩展配置项
configuration
notifier
notifiers
ciManagement
项目创建年份,4位数字。当产生版权信息时需要使用这个值
inceptionYear
定义:项目相关的所有邮件列表。自动产生的网站引用这些信息
邮件的名称
发送邮件的地址或链接
订阅邮件的地址或链接
subscribe
取消订阅邮件的地址或链接
unsubscribe
你可以浏览邮件信息的URL
archive
mailingList
mailingLists
定义:项目开发人员列表
开发者的唯一标识符
开发者的全名
开发者的email
email
开发者的主页url
开发者在项目中的角色
role
roles
开发者所属组织/公司
organization
开发者所属组织/公司的URL
organizationUrl
项目开发者属性,如即时消息如何处理等
dept
properties
开发者所在时区, -11到12范围内的整数
timezone
developer
developers
项目的其他贡献者 见developer
contributor
contributors
license用于法律上的名称
官方的license正文页面的URL
项目分发的主要方式:repo,可以从Maven库下载 manual, 用户必须手动下载和安装依赖
distribution
关于license的补充信息
comments
license
icenses
定义:源代码控制管理系统定义了该项目源代码控制管理的地址,例如git、svn等。
读取该项目资源版本库的地址
connection
类似于connection,使用去developer的地址
developerConnection
默认值为HEAD,当前源代码库的版本,开发过程中默认设置为HEAD
tag
通过浏览器等可以访问到的该项目的地址
scm
定义:描述项目所属组织的各种属性。Maven产生的文档用
组织的全名
组织主页的URL
主体源程序存放目录
sourceDirectory
脚本源程序存放目录
scriptSourceDirectory
测试源程序存放目录
testSourceDirectory
主体源程序编译结果输出目录
outputDirectory
测试源程序编译结果输出目录
testOutputDirectory
extension
extensions
defaultGoal
targetPath
filtering
directory
includes
excludes
主体资源文件存放目录
resources
testResource
测试资源文件存放目录
testResources
构建结果输出目录
finalName
filters
phase
goals
inherited
executions
plugin
plugins
pluginManagement
dependency
dependencies
build
activeByDefault
family
arch
os
property
exists
missing
file
activation
modules
repositories
profile
profiles
标签说明·
nexus
安装配置
基础操作
远程仓库
分支管理
git
jenkens
优势:虚拟硬件资源,直接使用容器引擎,所以速度快
Docker:App+Bin/Libs
VM:App+Bin/Libs+Os
与VM区别
提供容器运行时所需的程序、库、资源、配置等文件外,还包含一些配置参数(如匿名卷、环境变量、用户等)。
docker镜像
Image
轻量级的沙箱,docker利用容器来运行和隔离应用
docker容器
container
公开仓库Docker Hub
私有仓库:自己搭建
docker仓库
repository
docker run [OPTIONS] IMAGE [COMMOND] [ARGS...]
创建一个新的容器
为容器指定一个名称
--name
后台运行容器,并返回容器ID,也即启动守护式容器
-d/--detach
以交互模式运行容器,通常与 -t 同时使用
-i/--interactive
为容器重新分配一个伪输入终端,通常与 -i 同时使用
-t/--tty
随机端口映射
-P
指定端口映射 四种格式
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
-p
指定网络
--network
容器停止自动删除容器
--rm
挂在数据卷
-v/--volume
指定用户 (格式: <name|uid>[:<group|gid>])
-u/--user
指定工作目录
-w/--workdir
OPTIONS
XXX_IMAGE_NAME:XXX_IMAGE_VER
IMAGE
例:mvn -Duser.home=xxx -B clean package -Dmaven.test.skip=true
COMMOND
执行/bin/bash命令
/bin/bash
docker start [OPTIONS] CONTAINER [CONTAINER...]
启动一个或多个已经被停止的容器
附加到容器的标准输入、输出和错误输出
-a
以交互模式运行容器
-i
start
docker stop [OPTIONS] CONTAINER [CONTAINER...]
停止一个运行中的容器
指定停止容器前的超时时间(默认为10秒)
-t
stop
docker restart [OPTIONS] CONTAINER [CONTAINER...]
重启容器
restart
docker kill [OPTIONS] CONTAINER [CONTAINER...]
杀掉一个运行中的容器
指定发送的信号,默认为“KILL”
-s
docker stop命令给容器发送 SIGTERM 信号,默认行为是会导致容器退出,当然,容器内程序可以捕获该信号并自行处理
docker kill命令则是给容器的进程发送 SIGKILL 信号,该信号将必然使容器退出
与stop区别
kill
删除一个或多个容器
rm
创建一个新的容器但不启动它
create
运行的容器中执行命令
exec
暂停容器中所有的进程
pause
恢复容器中所有的进程
unpause
列出容器
ps
获取容器/镜像的元数据
inspect
查看容器中运行的进程信息
top
获取实时事件
events
获取容器的日志
logs
将文件系统作为一个tar归档文件导出到STDOUT
export
列出指定的容器的端口映射
port
从容器创建一个新的镜像
commit
用于容器与主机之间的数据拷贝
cp
检查容器里文件结构的更改
diff
登陆到一个Docker镜像仓库
login
登出Docker Hub
logout
从镜像仓库中拉取或者更新指定镜像
pull
push
从Docker Hub查找镜像
search
列出本地镜像
images
删除本地一个或多个镜像
rmi
标记本地镜像,将其归入某一仓库
docker build [OPTIONS] PATH | URL | -
用于使用 Dockerfile 创建镜像
--build-arg=[] :设置镜像创建时的变量
--cpu-shares :设置 cpu 使用权重
--cpu-period :限制 CPU CFS周期
--cpu-quota :限制 CPU CFS配额
--cpuset-cpus :指定使用的CPU id
--cpuset-mems :指定使用的内存 id
--disable-content-trust :忽略校验,默认开启
-f :指定要使用的Dockerfile路径
--force-rm :设置镜像过程中删除中间容器
--isolation :使用容器隔离技术
--label=[] :设置镜像使用的元数据
-m :设置内存最大值
--memory-swap :设置Swap的最大值为内存+swap,\"-1\"表示不限swap
--no-cache :创建镜像的过程不使用缓存
--pull :尝试去更新镜像的新版本
--rm :设置镜像成功后删除中间容器
--shm-size :设置/dev/shm的大小,默认值是64M
--ulimit :Ulimit配置
--squash :将 Dockerfile 中所有的操作压缩为一层
--network: 默认 default。在构建期间设置RUN指令的网络模式
查看指定镜像的创建历史
history
将指定镜像保存成 tar 归档文件
save
导入使用 docker save 命令导出的镜像
load
从归档文件中创建镜像
import
显示 Docker 系统信息,包括镜像和容器数
info
显示 Docker 版本信息
基础命令
安裝部署
docker
k8s
用户请求->目标服务器地址->代理服务器->目标服务器 例:VPN
正向代理
用户请求->代理服务器地址->目标服务器 例Nginx
反向代理
nginx/nginx -c config/nginx -g \"pid ***;\"
启动
kill -quit pid/kill -term pid/kill -9 pid
停止
配置用户和组,默认为nobody nobody,表示所有用户有启停权限
user
设置是否以守护进程模式运行,默认on。
daemon
设置是否启用主进程,默认on。
master_process
设置为数字,表示启动后就具有几个worker process,设置为auto则表示自动检测
worker_processes
设置每个用户能够发往worker进程的信号数量(信号队列的大小)
worker_rlimit_nofile
为worker进程绑定若干个CPU,OS为linux才能使用此参数。
worker_rlimit_sigpending
设置worker进程的优先级
worker_priority
指定nginx的运行日志存放路径,必须包含文件名称。
error_log
指定nginx的pid存放路径,必须包含文件名称。
pid
设置多长时间获取一次系统时间并更新nginx的缓存时钟。
timer_resolution
引入的其他配置文件路径。
include
全局块
设置事件驱动模动模型,建议让nginx自行选择。
use
设置指定的IP产生debug日志。
debug_connection
是否开启负载均衡锁
accept_mutex
设置负载均衡锁文件路径
lock_file
设置一个进程是否可以同时接受多个请求。
multi_accept
设置获得负载均衡锁的重试时间间隔。
accept_mutex_delay
允许每一个worker process同时开启的最大连接数,此值不能大于操作系统支持的打开的最大文件句柄数,默认512
worker_connections
events块
配置允许访问服务的ip
allow
配置不允许访问服务的ip
deny
默认为text/plain
default_type
是否允许sendfile方式传输文件,默认on。
sendfile
log_format
access_log
每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
sendfile_max_chunk
指定是否将用户请求体存储到一个文件里。
client_body_in_file_only
设置是否将完整的请求主体存储在单个缓冲区中。
client_body_in_single_buffer
指定用户请求体所使用的buffer的最大值。
client_body_buffer_size
设置存储用户请求体的文件的目录路径
client_body_temp_path
设置用户请求体的超时时间。
client_body_timeout
设置用户请求头所使用的buffer大小
client_header_buffer_size
设置用于读取大型客户端请求头的缓冲区的最大数量和大小
large_client_header_buffers
设置用户请求头的超时时间
client_header_timeout
设置所能接收的最大请求体的大小,默认1M。
client_max_body_size
send_timeout
设置用户会话连接的保持时间。
keepalive_timeout
设置TCP链接是否不推送,默认on。
tcp_nopush
设置TCP链接是否延迟,默认on。将tcp_nopush和tcp_nodelay两个指令设置为on用于防止网络阻塞。
tcp_nodelay
设置符合条件的网段,结合real_ip_header,设置新的$remote_addr
set_real_ip_from
结合set_real_ip_from,设置新的$remote_addr,如果设置X-Forwarded-For则为真实的ip
real_ip_header
是否开启gzip压缩。
gzip
设置允许压缩的页面最小字节数,默认0。
gzip_min_length
设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。
gzip_buffers
识别http的协议版本。
gzip_http_version
gzip压缩比,1压缩比最小处理速度最快,9压缩比最大但处理速度最慢(传输快但比较消耗cpu)。
gzip_comp_level
gzip_types
和http头有关系,加个vary头,给代理服务器用的
gzip_vary
指定版本浏览器不压缩。
gzip_disable
负载均衡的后端服务器
负载均衡策略权重, 默认为1
weight
在fail_timeout时间内检查这个服务器是否可用时产生的最多失败请求数
max_fails
在fail_timeout时间内经历了max_fails次失败后, 暂停服务
fail_timeout
备份服务器
backup
永久不可用
down
upstream
定义一个完整的缓存空间,指定缓存数据的磁盘路径、索引存放的内存空间以及一些其他参数
配置在该目录下再分两层目录,一层1个随机字符作为名称,二层2个随机字符作为名称,levels最多三层
levels
用来为这个缓存区起名,并设置大小;
keys_zone
指定最大缓存数据磁盘空间的大小;
max_size
在inactive指定的时间内,未被访问的缓存数据将从缓存中删除。
inactive
proxy_cache_path
开启缓存 off 关闭
proxy_cache
设置缓存唯一key
proxy_cache_key
设置不同响应代码的缓存时间,比如200 304 12h;
proxy_cache_valid
header中是否支持下划线,默认为off不支持,on为支持;
underscores_in_headers
http块
单连接请求上限次数
keepalive_requests
设置监听地址和端口
listen
虚拟主机名称,支持多个
server_name
为实现快速主机查找,nginx使用hash表保存主机名,该参数用来设置hash表大小。
server_name_hash_bucket_size
设置服务器收到请求后查找资源的根目录路径,最终路径拼接为:root路径+location路径。
root
设置服务器收到请求后查找资源的根目录路径,最终路径拼接为:root路径+location路径
alias
server全局块
设置response响应报文的header
add_header
是否开启认证功能,并设置提示信息,off关闭。
auth_basic
指定包含用户名信息的文件路径。
auth_basic_user_file
重写跳转地址,支持正则
重写完成后停止对当前URI在当前location中后续的其它重写操作,而后对新的URI启动新一轮(从第一个开始)重写检查,在循环中则提前重启新一轮循环;
last
重写完成后停止对当前URI在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;在循环中则结束循环,建议在location中使用;
break
临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;不能以http://或https://开头,使用相对路径,状态码:302;
redirect
重写完成后以永久重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求,状态码:301。
permanent
rewrite
是否把重写过程记录到错误日志中,默认为off,级别默认notice。
rewrite_log
后面可以跟多个文件名,表示逐个匹配文件,如果没有则继续往后一个文件匹配
try_files
用于结束rewrite规则,并且为客户端返回状态码204,400,402-400,500-504等
return
设置网站的默认首页。
设置网站的错误页面。
error_page
指定反向代理的服务器池,如:192.168.10.10 或使用upstream,服务器池是tomcat动态程序
proxy_pass
url中末尾是没有后缀:/ 的目录时,nginx内置了301重定向,重定向追加/,此参数可以修改反向代理重定向的url
proxy_redirect
设置发往后端请求头,参数有:
Host:指定反向代理到哪个主机名;
X-REMOTE-IP:上一跳的ip;
X-Forwarded-For:设置客户端ip;
http_user_agent:设置客户端OS;
proxy_set_header
设置客户端请求主体缓冲区大小,可以理解为先保存到本地在传给用户。
proxy_body_buffer_size
设置后端服务器连接的超时时间,即发起握手等候响应的超时时间。
proxy_connect_timeout
设置后端服务器的数据回传时间,即在规定的时间内后端服务器必须传完所有的数据,否则nginx将断开这个连接。
proxy_send_timeout
设置从后端服务器获取信息的时间,表示连接建立成功之后,nginx等待后端服务器的响应时间,其实nginx已经进入后端的排队之中等候处理。
proxy_read_timeout
设置缓冲区大小。
proxy_buffer_size
设置缓冲区的数量和大小。
proxy_buffers
设置系统忙碌时可以使用的proxy_buffers大小,官方推荐为proxy_buffers*2
proxy_busy_buffers_size
指定proxy缓存临时文件的大小
proxy_tmep_file_write_size
请求出错后,转向下一个节点
proxy_next_upstream
指定fastcgi进程监听的IP地址和端口
fastcgi_pass
设置请求fastcgi的请求头。
fastcgi_pass_header
fastcgi服务器的响应超时时间。
fastcgi_read_timeout
指定浏览器缓存失效时长,比如:30s
expires
location块
server块(就近原则)
当前请求的URI,不带参数
$uri
$document_uri
请求的uri,带完整参数
$request_uri
表示请求中的 URI 是否带参数,如果带参数,$is_args 值为 ?,如果不带参数,则是空字符串
$is_args
http请求的完整参数
$args
http请求中某个参数的值
$arg_[param]
http请求的完整参数,只读不可改变
$query_string
http请求报文中的host首部,如果请求中没有host首部,则以处理此请求的虚拟主机的主机名代替
$host
nginx服务运行在的主机的主机名。
$hostname
nginx对于upstream默认使用的是基于IP的转发,所以表示请求到对应的upstream配置的域名的ip
$proxy_host
客户端的ip地址,如果客户端有代理,则为最近的代理服务器的ip
$remote_addr
客户端的ip地址,如果客户端有代理,则为已设置的最新的代理服务器的ip
$http_x_real_ip
客户端的ip地址,默认是空。
$http_x_forwarded_for
$http_x_forwarded_for和$remote_addr,中间用逗号隔开
$proxy_add_x_forwarded_for
二进制格式的客户端地址
$binary_remote_addr
客户端端口
$remote_port
启用用户认证时,客户端输入的用户名
$remote_user
请求方法
$request_method
用户请求中的uri经过本地root或alias转换后映射的本地文件路径
$request_filename
表示http请求中的body体,该参数只在proxy_pass或fastcgi_pass中有意义
$request_body
表示http请求中的body体存储的临时文件名
$request_body_file
当请求已经全部完成时,其值为 “ok” 。若没有完成,就要返回客户端,则其值为空字符串;
$request_completion
服务器地址
$server_addr
服务器域名
$server_name
服务器向客户端发送响应时的协议,如http/1.1
$server_protocol
在请求中使用scheme,如https://www.magedu.com/中的https
$scheme
匹配请求报文中指定的HEADER,例如:$http_host匹配请求报文中的host首部
$http_[header]
匹配响应报文中指定的HEADER,例如:$sent_http_content_type匹配响应报文中content-type首部
$sent_http_[header]
当前请求映射到的root配置项
$document_root
访问时间与时区
$time_local
请求的url与http协议
$request
请求状态,成功是200
$status
发送给客户端文件主体内容大小
$body_bytes_sent
记录从那个页面链接访问过来的
$http_referer
记录客户端浏览器的相关信息
$http_user_agent
请求头部中的Content-Length字段
$content_length
请求头部中的Content-Type字段
$content_type
请求头部中的cookie字段
$cookie_COOKIE
表示当前连接的限速是多少,0表示无限速
$limit_rate
表示当前Nginx的版本号
$nginx_version
内置变量
严格匹配。如果请求匹配这个 location,那么将停止搜索并立即处理此请求
=
正则匹配 区分大小写
~
正则匹配 不区分大小写
~*
区分大小写不匹配
!~
不区分大小写不匹配
!~*
前缀匹配
^~
@
通用匹配,任何请求都会匹配到
/
匹配规则
1.= 精确匹配
优先级是从长到短(匹配字符越多,则选择该匹配结果)
2.^~ 前缀匹配
按照配置文件里的顺序(从上到下),成功就停止其他匹配
3.~/~* 正则匹配
4./ 通用匹配
匹配顺序
location匹配
proxy_pass http://www.baidu.com
proxy_method POST
proxy_set_header Host $host
proxy_set_header X-Real_IP $remote_addr
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
Ip:port
server
server已停用
备用服务器
负载权重 值越大 权重越高
轮询 默认
server ip:port weight=xx
权重(weight)
ip_hash;
IP哈希
fair;需第三方插件 后端服务器的响应时间来分配请求,响应时间短的优先分配。
fair
需第三方插件 访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
url哈希
负载均衡算法
配置 :location ~.*\\.(jpg|png|gif|css|js)$ { root static;}
expires 1d;过期时间1d
动静分离
Gzip压缩 详情见配置Http块
多进程模型 异步处理机制
接收外部信号
向各worker进程发送信号
监控worker进程的执行状态
master进程
处理用户请求
个数一般与CPU数量一致
work进程
进程模型
热部署
跨域问题
防盗链
nginx
运维/工具
mycat(代理端)
sharding(JAR端)
分库分表
算法
java 知识库
0 条评论
回复 删除
下一页