计算机基础
http
-
状态码
- 1XX 消息处理中
- 2XX 处理成功
3XX 重定向- 4XX 客户端有异常
- 5XX 服务器有异常
-
类型
- get
- post
- put
- delete
-
为什么要三次握手?
- 确保双法都有接收消息、发送消息的能力
- 举例:A:喂,听的到嘛B:嗯,我听的到,你听的到嘛?A:我也听的到
-
为社么要四次挥手?
- 确保双方都把消息传递完毕了
- 举例A:我讲完了,我准备挂了B:好的,我知道你讲完了,但是我还没讲完,你等下B:我也讲完了A:好的,我知道你讲完了
1.0之后是长连接,之前是短连接
Socket
- 是对TCP/IP协议的封装
io模型
-
解释
- IO就是把进程的内部数据转移到外部设备,或者把外部设备的数据迁移到进程内部。外部设备一般指硬盘、socket通讯的网卡
-
分类
-
阻塞io
- 一直问快递到了嘛?不到就不做其他事情
-
非阻塞io
- 一直问快递到了嘛?知道没到就去做别的事情,到了再签收
-
复用io
- 公司前台,帮忙问快递到了没有?到了再让本人认领
-
信号驱动io
- 做一个监听,快递到了,就发一个短信
- 不能送货上门,还是要自己去取
-
异步IO
- 告诉别人要读数据,数据处理好之后,直接送货上门
-
linux
- chmod
change mode
r 读权限
w 写权限
x 执行权限
chmod u+rwx, g+rw filename #说明对filename,赋予user用户read、write、excute权限;赋予group用户read、write权限 chmod u-rwx, g-rw filename #取消授权 chmod u=rwx, g=rw filename chmod o+rwx filename #授权其他人 chmod a+rwx filename #授权所有人 chown -R 1000:1000 /home/jenkins
- grep
搜索日志
- tail
- vim
- tail -f
- 循环展示日志
- vi
- 编辑文件
- mkdir
java
线程
- 线程池
核心参数
核心线程数:空闲了也不会被干掉
队列类型
太多类型的队列了……记不住
有界队列
可设容量的队列
有默认长度,所以可能会导致数据丢失
延迟队列
同步队列
优先级队列
- 最大线程数
- 能创建的最多的线程数,不是无限创建的
- 线程空闲时间
- 大于核心线程数的,空闲了就要干掉
- 拒绝策略
- 直接丢弃
- 丢弃并抛异常
- 丢最队列最前面的
- 当前线程直接处理
- 线程工厂
- 一般会自定义线程工厂,方便知道线程是哪个工厂创建的
- 常用方法
start
启动线程
sleep
线程睡眠,睡醒了就会被唤醒
不会释放锁
wait
线程等待,等notify唤醒
释放锁
join
等待当前线程执行完,其他线程才能执行
join()方法的作用就是让主线程等待子线程执行结束之后再运行主线程
- 状态
新建
还没有调start方法
可运行
调了start方法,还没有获得CPU执行权限
运行中
cpu开始执行
阻塞
sleep,join,wait等
死亡
- 创建线程的方式
继承Thread类创建线程类
实现callable接口
有返回值
可以抛异常
new Callable() { @Override public String call() throws Exception { return null; } } ;
实现runable接口
无返回值
不能抛异常
Runnable runnable = new Runnable() { @Override public void run() { } };
- CountDownLatch
倒数计数器
await
主线程等待CountDownLatch数归零
-
CountDown
- 计数器减1
public class countDownLatch { public static void main(String[] args) throws InterruptedException { CountDownLatch downLatch = new CountDownLatch(6); for (int i = 1; i { System.out.println(Thread.currentThread().getName() + "出去了"); downLatch.countDown(); }, String.valueOf(i)).start(); } downLatch.await(); System.out.println("主线程关门!"); }}
volatile
java关键字
每个线程都会有各自的线程栈,执行运算的时候,是从公共堆栈读取数据到线程堆栈中,线程操作的是线程堆栈的数据,结束后,再从线程堆栈回刷到公共堆栈,所以这种肯定会引起数据的不同步
volatile关键字保证了在多线程环境下,被修饰的变量在被修改后会立即同步到主存,这样该线程对这个变量的修改就是对所有其他线程可见的,其他线程能够马上读到这个修改后值
问题
-
总线风暴
volatile 的嗅探机制会引发总线压力山大
- 嗅探机制就是 现在每隔一段时间都要主线程获取最新的值
jvm
-
作用
java程序内存管理
-
class字节码加载
-
类加载器
-
作用
- 加载class文件导入到虚拟机
-
分类
- 启动类加载器
- 扩展类加载器
- 应用类加载器
- 用户自定义类加载器
-
双亲委派机制
不会直接自己加载,会先让父亲加载,一直往上,找到为止。实在找不到,再反向往下找
-
为啥需要双亲委派机制??
- 为了安全,要是程序员手写一个String基础类,大概率会出问题的啊
-
-
JVM 不会无故装载 Class 文件,那什么时候才会加载??
- new关键字
- java反射机制
-
-
组成
-
方法区
-
类的一些信息、类名、成员变量、静态变量、方法等
-
常量池
- 常量池,可以看做是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等类型。
-
全局共享的
方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区的溢出
-
-
堆
此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。
线程共享
-
组成
-
新生代
- 伊甸园区
- 幸存者1区
- 幸存者2区
老生代
永久代
-
-
程序计数器
通过控制程序计数器,控制下一行执行的命令、代码
-
线程独享
- 为了线程切换后,能恢复到之前执行的位置
- 随着线程创建,随着线程死亡
-
java虚拟机栈(栈)
-
组成
- 局部变量表
- 操作数栈
- 动态链接
-
线程独享
- 随着线程创建,随着线程死亡
-
-
本地方法栈
- 用来和系统底层做交互用的,可能非java代码
- native修饰的方法
-
-
指令
-
jinfo
- 查看jvm的配置
-
jps
- 查看当前java进程的小工具
-
jstat
- 对Heap size和垃圾回收状况的监控。
-
jstack
-
作用
- jstack用于生成java虚拟机当前时刻的线程快照
-
解决了什么问题?
- 可以快速找到出问题的线程
- 死循环,死锁等
-
jstack 14980
"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000221dc20d000 nid=0x3dc8 in Object.wait() [0x000000d294bff000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked (a java.lang.ref.ReferenceReferenceHandler.run(Reference.java:153)
Reference Handler 是线程名
prio=10 线程的优先级别
tid=0x00000221dc20d000 当前线程id
nid=0x3dc8 进程id
-
WAITING (on object monitor) 线程在等待
- on object monitor 就是在等待一个对象锁
-
-
jmap
-
作用
- 这个命令执行,JVM会将整个heap的信息dump写入到一个文件
-
解决了什么问题?
- 可以图形化的看到jvm堆栈信息
jmap -dump:live,format=b,file=dump.hprof 14980
-
-
-
OOM
-
解释
- jvm内存用完了
-
类型
-
堆内存用完了
-
解决
- 设置JVM参数-XX:+HeapDumpOnOutOfMemoryError,设定当发生OOM时自动dump出堆信息
- 使用JDK自带的jmap命令。"jmap -dump:format=b,file=heap.bin "
- jprofiler查看dump下的文件
- 调整 堆的最小值-Xms参数与最大值-Xmx参数
-
-
栈内存用完了
- 栈容量只能由-Xss参数来设定
-
方法区内存用完了
-
原因
- 方法区的主要职责是用于存放类型的相关信息, 如类名、 访问修饰符、 常量池、 字段描述、 方法描述等。
- 运行时产生大量的类去填满了方法区
- CGLib直接操作字节码运行时生成了大量的动态类
-
解决
- -XX:MetaspaceSize:指定元空间的初始空间大小,以字节为单位
-
-
-
数据结构
-
arrayList
- 基于数组实现
- 查询快,尾部插入也快,但是中间插入就慢
- 原始长度空,第一次扩容为10,后续1.5倍扩容
- 线程不安全
-
linkedList
- 基于链表实现
- 查询慢
- 插入快
- 线程不安全
-
hashMap
-
基于数组实现冲突数量小于8时,用链表存大于8转换为红黑树(链表 查询慢)
- 树最强大的功能是进行储存查询
-
扩容因子0.75
快到容量极限了,就提前扩容
-
默认16
-
16*0.75=12
- 达到12之后就开始扩容
-
2倍扩容
取key值的hashCode,然后再对数组长度取模,然后-1
线程不安全
-
hashmap为什么用红黑树
- 红黑树是一种特殊的二叉查找树,查询快
- 不追求绝对平衡,所有插入删除也快
-
-
concurrentHashMap
线程安全
-
jdk1.7
-
分成16段,每一段都是一个Segment继承了ReentrantLock
- 简单来讲就是hashMap
-
分段锁
- 细化锁的粒度
-
-
jdk1.8
-
新版就是hashMap
- 基于cas操作,保证线程安全
- 更加细腻
-
-
hashTable
- 线程安全
- 就是把hashMap的方法,都加上了 syc锁
-
hashSet
- 基于hashMap实现
- 线程不安全
-
树
-
定义
- 每个节点都只有有限个子节点或无子节点;
- 没有父节点的节点称为根节点;
- 每一个非根节点有且只有一个父节点;
- 树里面没有环路,意思就是从一个节点出发,除非往返,否则不能回到起点。
-
种类
-
二叉树
- 每个节点最多只有两个分支
- 二叉树节点是无序的,最坏情况可能要要遍历整个二叉树
-
二叉查找树
- 左子树上的节点都小于根节点,右子树上所有节点的值都大于根节点。
- 二叉查找树的查询复杂度取决于目标节点的深度,因此当节点的深度比较大时,最坏的查询效率是O(n),其中n是树中的节点个数
-
平衡二叉查找树
- 当左右子树的高度相差「不是特别多」
- 会反复的旋转,重新选举新的根节点
-
红黑树
- 特殊的二叉树
- 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长
- 不追求绝对平衡,所有插入删除也快
-
B树
- 一个节点可以有多个节点
-
-
原子类
原子变量类 比锁的粒度更细,更轻量级
-
基于cas操作
- 内存地址V,旧值A 新值B
java.util.concurrent.atomic
接口与抽象类的区别
- 抽象类可以有默认的实现
- 抽象类用来继承,接口用来实现
synchronized
基于jvm
非公平锁
-
方法
- 隐式的,生成acc_synchronize标记,线程执行时获得monitor对象
-
代码块
- 编译后会生成两个指令,monitorEnter monitorExit,监听器进入和退出
-
锁升级过程
-
偏向锁
- 大多数情况下锁不仅不存在多线程竞争,而且总是由同一线程多次获得
- 偏向锁的目的是在某个线程获得锁之后,消除这个线程锁重入(CAS)的开销,看起来让这个线程得到了偏护
- 直接判断对象头mark word的锁指针,要是指向当前线程就直接获得锁。否则就执行cas操作替换mark word的信息
-
自旋锁
频繁的阻塞和唤醒对CPU来说是一件负担很重的工作
所谓“自旋”,就是让线程去执行一个无意义的循环,循环结束后再去重新竞争锁,如果竞争不到继续循环,循环过程中线程会一直处于running状态
-
自适应
- 循环了10次就获取到了锁,下次就可以循环20次
- 循环了10次就获取不到了锁,下次就只能循环5次
-
轻量锁
- 用cas操作替换mark word的锁信息。失败,则自旋,自选多次之后还是获取不到就升级为重锁
-
重量锁
- 重量锁在JVM中又叫对象监视器(Monitor)
- 直接调操作系统底层,消耗大,比较重就是在操作monitor
- monitor(监听器)为0,则可以获取到锁反之获取不到锁
-
ReentrantLock
-
基于jdk
-
aqs(抽象队列同步器)
- lock时,设置state为1重入锁时再加1线程计为当前线程
- 解锁同理
-
默认非公平锁,但是也可以公平锁,更加灵活点
AQS
-
抽象队列同步器
- state变量
- 加锁线程
- 等待队列
cas
-
比较 和 交换
- 认为a的位置存在B,存在则替换为新值B
- 内存位置(V)、预期原值(A)和新值(B)
- CAS保存了V位置的原来A值,当再次去访问时,若还是旧A,则替换成B,否则,不替换
动态代理
-
分类
-
cgLib动态代理
-
基于java反射实现
- 被代理的类必须实现接口
-
-
jdk动态代理
-
基于字节码实现
- 被代理的类可以实现接口,也可以不实现
-
-
-
是啥?
- 静态代理是编译时就确定的
- 动态代理是运行时才确定的
ThreadLocal
线程变量
-
内存泄露
- ThreadLocal类 内部维护了一个map,key是ThreadLocal,value是值
- key是弱引用,只要GC就会里面被清理,但是value还在
String、StringBuffer、StringBuolder
string
-
StringBuffer
-
维护了一个char数组
- 按照2倍+2扩容
toString时new一个string
用syc关键字修饰
-
forkJoin
-
消息分治
- 把一个任务拆分成很多小任务,一起执行,最后合并结果
引用
-
强引用
- 正常new出来的
- 内存不够用,也不会被GC清理
-
软引用
- 内存不够用时,会被GC清理
-
弱引用
- 内存够用,也会被GC清理
spring
IOC
-
控制反转
- 就是把bean弄到ioc容器里面,用的时候直接从容器里拿
-
实例
- BeanFactory
- ApplicationContext是beanFactory的增强
DI
- 依赖注入
AOP
-
是什么?
- 面向切面编程
-
怎么实现?
-
jdk动态代理
- 必须实现接口
- 基于反射实现
-
cgLib动态代理
- 不必须实现接口
- 基于字节码实现
-
注入bean的方式
- 通过注解@controller等
- @bean
- xml配置
- bean工厂
bean的生命周期
-
实例化
- 调用构造方法实例化
-
属性赋值
- 调用set方法,对属性赋值
-
初始化
-
bean的initMethod方法
- init-method 用于在bean初始化时指定执行方法
- @PostConstruct
- 实现initializingBean接口,使用afterPropertiesSet
-
-
消亡
- 容器关闭时,调用bean的销毁方法
spring getway
作为请求的统一入口,保证服务安全
通过路由配置,把请求转发到各个子系统
-
路由中uri可以是网络地址,也可以是微服务的名字
- lb:serrviceName
-
负载均衡
- 与ribbon不一样,他通过服务注册中心的服务名/接口实现负载均衡的能力
spring security
-
UserDetailsService
- 认证
-
WebSecurityConfig
- 授权
open fegin
服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来是实现面向服务的接口调用。
-
和fegin的区别
- fegin不支持spring mvc的注解
-
超时
- OpenFeign 和 Ribbon 的超时时间只会有一个生效两者是二选一的,且 OpenFeign 优先
ribbon
-
负载均衡
- ribbon一般用于消费者的负载均衡
springBoot
-
启动原理
public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(Application.class); springApplication.run(args); } - 创建SpringApplication类 - 调用run方法,启动生产上下文
new SpringApplication - 判断当前webApplicationType应用的类型 - 通过spring.factories,找配置类 - 通过spring.factories,找ApplicationListener - 推断Main方法的类
springApplication.run(args) - 获取并启动监听器 - 生成监听器,事件 - 创建SpringApplicationContext - Spring 容器前置处理 - 刷新容器 - 执行Runners - 使得项目启动完成后立即执行一些特定程序。其中Sprng Boot提供的执行器接口有ApplicationRunner和CommandLineRunner两种
histry
-
作用
- 防止服务因为一个不可用,而导致所有服务都不可用
使用
分布式锁
mysql唯一索引来实现插入成功了就获取锁
redis set集合实现
-
setNX
- key不存在则setkey存在则不set
zookeeper临时顺序节点实现
方法执行时间>锁失效时间
- 找一个保姆,续命
- 启动一个watch线程,他是一个后台线程,会每隔10秒检查一下,如果客户端还持有锁key,那么就会不断的延长锁key的生存时间。
分布式事物
二次确认提交
最大消息通知,达成最终一致
MongoDB
建表
- db.createCollection(name, options)
删表
- db.collection.drop()
增加数据
- db.COLLECTION_NAME.insert(document)
增加字段
- db.col.update( { "count" : { set : { "test2" : "OK"} } );
redis
部署方式
-
主从模式
-
缺点
- master挂了,写的数据会丢失,要等master恢复,容灾能力太差了
- 很多从服务挂了之后,不能同时重启,不然会造成master数据同步压力
-
优点
- 1、读写分离,主负责写,从负责读,降低服务器的压力
-
-
哨兵模式
-
缺点
- 扩容比较麻烦所有的redis存的数据都一样,浪费内存
-
优点
- 1、master挂了之后,哨兵会选举新的master
-
-
集群模式
-
优点
- 更少的内存节点之前,通过网络高效传输
-
持久化
-
快照
-
每隔一段时间,生成一个备份文件
-
优点
- 生成的文件简洁,单文件
-
缺点
- 可能会丢失数据
-
-
-
追加文件
-
每次修改数据,就写入到追加文件里面
-
优点
- 不会丢失数据,可以设置每秒追加一次,也就是最多丢失1秒的数据
-
缺点
- 生成的文件会很大
-
-
缓存穿透
-
请求的数据是缓存里面一定没有的
-
解决
- 用布隆过滤器
- 对请求的数据加缓存
-
缓存击穿
-
缓存失效的同时,大量的请求进来
-
解决
- 加互斥锁,同一时间只能处理一个请求,加好缓存之后,再释放锁
- 设置永不失效
-
缓存雪崩
-
缓存同一时间大批量的失效
-
解决
- 随机设置失效时间,不要设置在同一时间
- 设置永不失效
-
如何保证redis数据和mysql数据同步?
- mysql监听器+mysql自定义函数(UDF函数)
- 监控mysql binglog,读取数据写入到redis
使用场景
缓存
-
计数器
- increment指令
-
分布式锁
-
set数据结构,setNX指令
-
setNotExist
- 不存在时,才会放入到集合里面
-
-
-
分布式session
-
spring-session-data-redis
- 配置redisSessionTemplate的bean
-
-
排行榜
- zset
-
布隆过滤器
-
bitmap
- 降低存储空间
- 加快查找效率
-
淘汰策略
- 对于写请求不再提供服务,直接返回错误(DEL请求和部分特殊请求除外)
- 从所有key中使用LRU算法进行淘汰(LRU算法:即最近最少使用算法)
- 从设置了过期时间的key中使用LRU算法进行淘汰
- 从所有key中随机淘汰数据
- 从设置了过期时间的key中随机淘汰
- 在设置了过期时间的key中,淘汰过期时间剩余最短的
mysql
数据引擎
myisam
-
innodb
-
行锁
能命中索引时,就之会锁一行数据
-
for update 是共享锁
- 共享锁:别的事务可读,不能写
-
insert、update、delete 是排他锁
- 排它锁:别的事务不可读,不可写
-
表锁
- 不能命中索引时,行锁就会上升为表锁
-
间隙锁
- 数据id:1、3、5过滤条件:where id<52、4 没有数据的行也会被加上锁
-
索引
-
失效
-
存在左likewhere name like '%张'
-
原因
- 索引是按照字段内容排序的,‘一张’‘二张’这样的数据就的全表扫描了
-
-
隐式转换
- where name=111
- mysql会把name转换成数字,然后和111比较
最左匹配原则
回表
-
对索引列使用函数
-
原因
- 索引存的是字段内容,不是函数的值
-
-
or
- index_merge
- 都加上索引,索引合并
-
-
结构
事物
-
级别
-
读未提交
-
问题
- 脏读
-
-
读已提交
-
问题
- 不可重复读着重于修改
-
-
可重复读
-
问题
-
幻读着重于增删数据
- 事务 A 根据条件查询得到了 N 条数据,但此时事务 B 删除或者增加了 M 条符合事务 A 查询条件的数据,这样当事务 A 再次进行查询的时候真实的数据集已经发生了变化,但是A却查询不出来这种变化,因此产生了幻读。
-
-
串行化
-
-
acid
-
原子性
是不可分割的,要么都成功,要么都失败
-
实现原理
- undo log
-
隔离性
事物之间是相互隔离的
-
实现原理
- mvcc、锁
-
一致性
事物前后,数据保持一致汇款场景,减的钱和加的钱,最终要一致
-
实现原理
- 原子性+隔离性+持久性 = 一致性
-
持久性
事物成功之后,就是不可再变的
-
持久性
- redo log
-
三大范式
- 第一范式:(确保每列保持原子性)
如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式
第二范式:(确保表中的每列都和主键相关)
第三范式:(确保每列都和主键列直接相关,而不是间接相关)
主从复制
-
主机
修改my.cat文件,添加一行当前服务器唯一识别 server-id=111
修改第12行 binary.log 日志文件名称可以随便起 log_bin=binary_log
```
```
-
从机
修改my.cat文件,添加一行 server-id=112
关闭slave(第一次操作不需要,但是以后如果修改该服务器为其他服务的从节点时,需要先停止slave服务) stop slave;
-
配置当前服务器为master(111)服务器的从机
change master to master_host='192.168.170.111', master_user='root', master_password='tiger', master_log_file='binlog.000001', master_log_pos=120;
读写分离
-
用中间件mycat
- Mycat 的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的 SQL 语句,首先对 SQL 语句做了 一些特定的分析:如分片分析、路由分析、读写分离分析(看是select 还是 insert,update,delete操作)、缓存分析等,然后将此 SQL 发往后端的真实数据库, 并将返回的结果做适当的处理,最终再返回给用户。
当前读,快照读
-
快照读,普通查询
- 通过mvcc实现
-
当前读 inster,update,select for update
- 通过锁实现
doubbo
协议
-
dubbo
- 单连接
- 长连接
- 异步io
- 数据建议小于100K
- 适用消费者多,数据少
- tcp协议
-
hessine
- 多连接
- 短连接
- 同步传输
- http协议
-
rmi
- 多连接
- 短连接
- 同步传输
- tcp
Activiti
26张表
- 流程部署相关
- 流程运行时相关
- 历史流程相关
api
- repositoryService
runTimeService
historyService
zookeeper
是啥?
- 类似于电脑目录的一个中间件
应用场景
- 配置中心
- 分布式锁
组成
- 持久节点
- 持久顺序节点
- 临时节点
- 临时顺序节点
负载、部署
随机
轮询
-
最小活跃数
- 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
-
一至hash
- 相同请求参数,请求同一台服务器
MQ
RabbitMQ
-
消息丢失
-
原因
-
生产者出了问题,消息没有投递到MQ
-
解决
-
MQ事物没有投递成功就会抛个异常
- 这个太影响性能了,一般不用
confirm机制消息投递成功,MQ会返回成功ack值
-
-
-
MQ出了问题,消息没存住
-
解决
-
MQ开启持久化
-
消息持久化
- channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
- 将推送消息时的参数设置为MessageProperties.PERSISTENT_TEXT_PLAIN,就表示消息持久化
-
队列持久化
- true
-
-
-
-
消费者出问题,消息没有消费
-
解决
- 默认是自动确认改成手动确认
-
-
-
-
四种交换机的区别
-
直连交换机:Direct exchange
- 完全匹配
-
topic 主题交换机
- 通过通配符匹配
-
header交换机
- 通过键值对匹配
-
扇形交换机
- 直接广播给所有队列
-
-
延迟队列
- 消息过期时间+死信队列
怎么避免重复消费?
-
怎么重复的?
- 生产者并发,重复生产了消息
- mq突然挂了,消费者还没来的及返回消费成功
- 消费者挂了,没有返回成功信息
-
解决
-
业务层面校验
-
幂等性
- 就一个数据,或者一个请求,给你重复来多次,你得确保对应的数据是不会改变的,不能出错。
-
-
死信队列
- 就是怎么消费都消费不掉的消息,就会挪到死信队列
消息堆积怎么办?
-
后果
-
消息被丢了
-
解决
- 不设置消息过时,存到磁盘里面
-
-
磁盘不够用,磁盘满了
-
解决
- 写个临时程序,搬到别的服务器上
-
-
消费者,处理不过来
-
解决
- 增加消费者
-
-
怎么保证MQ和DB的数据一致
- 建一个消息表,同业务一起保存,MQ发送成功之后删小消息表数据
- 提供接口个下游系统,做一致校验
集群
负载方式
随机
最小活跃数
轮询
加权
-
ip地址hash
- 确保同一请求,在同服务器
acp理论
定义
一致性(Consistency)
可用性(Availability)
-
分区容错性(Tolerance of network Partition)
- 指在某分区宕机或网络原因请求不到情况下,仍然能保证系统的可用性和数据一致性。
eureka AP
- 多个eureka,其中一个挂了,会去找其他可用节点处理
zookeeper CP
- zookeeper节点挂了,会重新选举,选举完了再处理数据
nacos
可cp,可ap
-
根据保护阈值控制
-
低于阈值时
- 不管服务健康与否,都直接返回信息给客户端
- 避免流量全部都压到健康的服务,导致服务压力过大
-
云计算服务三大模式
iaas
- 半成品材料,自己加工下,再搬个小板凳,就可以开饭了
paas
- 点了外卖,自己再搬个小板凳,就可以开饭
saas
- 去餐厅吃饭,坐下就可以开饭
线上问题排查
普通
日志
监控中心
问题复现
-
抓包
- 主要用来排查网络问题
危险方法
-
top指令等
- top -Hp pid 定位使用 CPU 最高的线程
- 找到该进程下cup占用比较多线程
- jstack pid | grep tid 找到线程堆栈
高级
- 代码走查
- 逻辑推理
rpc和http的区别
rpc传输的内容更加简洁
- 没有请求头,response头等
- rpc直接用对象序列化,http要更复杂些