面试集锦(八)分布式与高并发

2,355 阅读4分钟

分布式下的问题

1.session共享,使用redis存储session信息,主从复制慢可以在代码中手动写入

2.分布式事务

两阶段提交协议

使用消息中间件

3.负载均衡

4.分布式锁

一致性hash算法

用处:分布式缓存

算法描述:

先构造一个长度为232的整数环(这个环被称为一致性Hash环),根据节点名称的Hash值(其分布为[0, 232-1])将服务器节点放置在这个Hash环上,然后根据数据的Key值计算得到其Hash值(其分布也为[0, 232-1]),接着在Hash环上顺时针查找距离这个Key值的Hash值最近的服务器节点,完成Key到服务器的映射查找。

避免hash倾斜性方法:引入虚拟节点

将一个物理节点拆分为多个虚拟节点,并且同一个物理节点的虚拟节点尽量均匀分布在Hash环上

消息队列的应用场景

1.异步处理(如发送短信)

2.应用解偶

3.流量销峰(秒杀活动限流)

4.日志处理

5.消息通讯(点对点通信或聊天室)

高并发下的性能优化

1.调整项目结构,增加服务器资源,集群或分布式,负载均衡

2.数据库优化

3.代码优化(使用多线程+算法优化)

4.合理使用缓存

5.html静态化,图片存于服务器

接口如何处理重复请求

前端控制:当用户点击按钮后将按钮disable掉,后端不返回数据时不可点击

后端控制:uriPath+userId+MD5(JsonString(所有参数))作为key,用redis分布式锁,用spring aop来实现,对resource method 做aop拦截

主要是利用唯一Token值与提交参数相匹配验证。

接口限流算法

限流算法总结

1.计数器法(最简单最容易实现):假设要求某个接口一分钟之内不能超过100个请求:设置一个count,每次请求count++,在count>100时判断时间有没有超过一分钟,超过说明请求过多;如果没超过说明还在范围之内,那么重置count

缺陷:在临界值(如59秒时发送100个请求,在00时又发送100个请求,会认为是两个时间段,但其实2秒之间就会有200个请求,这样很容易击垮应用)

2.滑动窗口:将时间细分为很多格,每过n秒向右移动n格,可以避免上述问题

3.漏桶算法:设置一个容量固定的桶,流入的速率未知,流出去的速度恒定,多余的水会溢出

优点:使用了漏桶算法后我们可以保证接口会以一个常速速率来处理请求。

缺点:不能应对突发流量

4.令牌桶算法(使用最多):设置一个容量固定的桶,里面存放令牌(token),以一个恒定的速率往桶里放令牌,接口请求过来时,会从桶里取出一个令牌,有令牌才可以通过,没有令牌时无法通过,这就保证了接口的请求速率。

解决临界值问题:就算在一瞬间令牌全部被取完了,但是往桶里放令牌的速率是很慢的,这就保证了后面的请求不会在一瞬间通过。

分布式下的限流可以利用redis来实现

分布式缓存:

分布式缓存设计

缓存分级:本地缓存-->redis缓存-->tomcat堆缓存-->mybatis或DB缓存

分布式下要特别考虑的问题:不能多个进程同时写值,必须保证原子性,不能出现脏数据

redis缓存的负载策略:建议首先采用一致性hash算法(可以保证相同的请求会打在同一台服务器上,并且不随扩容而降低),当到达一定的阈值后切换为轮询算法,这样既能保证缓存命中又能保证服务的高可用