美文网首页
java面试基础之高并发

java面试基础之高并发

作者: 这一刻_776b | 来源:发表于2019-12-31 12:12 被阅读0次

问:Java的并发、多线程、 线程模型;

问:数据一致性如何保证;Synchronized关键字,类锁,方法锁,重入锁

问:如何控制某个方法允许并发访问线程的个数?

构造函数创建了一个Semaphore对象,并且初始化了 5 个信号。这样的效果是控件 test 方法最多只能有 5 个线程并发访问,对于 5 个线程时就排队等待,走一个来一下;

请求一个信号(消费一个信号),如果信号被用完了则等待;

释放一个信号,释放的信号新的线程就可以使用了.

问:JAVA高并发解决方案

[if !supportLists](1)[endif]应用和静态资源分离:静态文件放在专门的服务器上

[if !supportLists](2)[endif]页面缓存

[if !supportLists](3)[endif]集群与分布式

[if !supportLists](4)[endif]CDN

[if !supportLists](5)[endif]底层优化:网络传输

问:负载均衡策略

(1)轮询

给每个请求标记序号,之后把请求依次分发到服务器节点上。

适用集群各节点提供服务能力相等,且无状态的场景。

但是实际情况中各个节点所能提供服务的能力并不相同。

加权轮询,对每个节点加上了权重属性,

但是合适的权重难以随实际情况的改变而改变。

(2)随机

每次请求随机分发给服务器节点。

缺点是在同一截面上发生碰撞的概率比较高;

在非对等集群组网,或者硬件配置差异较大时,各节点负载不均匀

通过加权随机进行提升。

(3)服务调用时延(最小响应时间)

根据每个服务器处理请求的时间和平均时间的差值,来动态调整分发权重,

可以保证服务延时大的服务器,处理更少的请求。

该策略可以保证处理请求能力强的服务器接收到更多的请求。

通过动态权重缩小服务调用时延的震荡范围,是所有请求的处理时间接近平均值。

但计算平均响应时间会耗费时间,滞缓请求的分发。

改进的只计算最近若干次的平均时间的策略。

(4)一致性哈希

哈希值是32位的正整数,其值的分布范围按照一定规则分配给多个虚拟节点;

虚拟节点数量至少应是实际节点的两倍;

实际节点通过哈希值再对虚拟节点进行瓜分;

对“请求”取哈希值,分发到相应虚拟节点,虚拟节点对应的实际节点来处理“请求”。

相同参数的请求,总是发送到同一个服务提供者。

当某一台服务器宕机时,原本发往该节点的请求,基于虚拟节点,平摊到其他提供者,

从而避免引起集群剧烈变动。

(5)粘滞连接

主要适用于有状态的服务,同一客户端每次访问,处理请求的服务器为同一台。

客户端首次和服务端交互时,将链路与相应处理的服务器进行绑定。

当原有服务器宕机后,返回不可用消息,服务端重新为客户端绑定服务器。

问:负载均衡技术方案

基于DNS负载均衡

基于硬件负载均衡

基于软件负载均衡

问:kafka和rabbitmq对比

1、吞吐量

kafka吞吐量更高:

1)Zero Copy机制,内核copy数据直接copy到网络设备,不必经过内核到用户再到内核的copy,减小了copy次数和上下文切换次数,大大提高了效率。

2)磁盘顺序读写,减少了寻道等等的时间。

3)批量处理机制,服务端批量存储,客户端主动批量pull数据,消息处理效率高。

4)存储具有O(1)的复杂度,读物因为分区和segment,是O(log(n))的复杂度。

5)分区机制,有助于提高吞吐量。

2、可靠性

rabbitmq可靠性更好:

1)确认机制(生产者和exchange,消费者和队列);

2)支持事务,但会造成阻塞;

3)委托(添加回调来处理发送失败的消息)和备份交换器(将发送失败的消息存下来后面再处理)机制;

3、高可用

1)rabbitmq采用mirror queue,即主从模式,数据是异步同步的,当消息过来,主从全部写完后,回ack,这样保障了数据的一致性。

2)每个分区都可以有一个或多个副本,这些副本保存在不同的broker上,broker信息存储在zookeeper上,当broker不可用会重新选举leader。

kafka支持同步负责消息和异步同步消息(有丢消息的可能),生产者从zk获取leader信息,发消息给leader,follower从leader pull数据然后回ack给leader。

4、负责均衡

1)kafka通过zk和分区机制实现:zk记录broker信息,生产者可以获取到并通过策略完成负载均衡;通过分区,投递消息到不同分区,消费者通过服务组完成均衡消费。

2)需要外部支持。

5、模型

1)rabbitmq:

producer,broker遵循AMQP(exchange,bind,queue),consumer;

broker为中心,exchange分topic,direct,fanout和header,路由模式适合多种场景;

consumer消费位置由broker通过确认机制保存;

2)kafka:

producer,broker,consumer,未遵循AMQP;

consumer为中心,获取消息模式由consumer自己决定;

offset保存在消费者这边,broker无状态;

消息是名义上的永久存储,每个parttition按segment保存自己的消息为文件(可配置清理周期);

consumer可以通过重置offset消费历史消息;

需要绑定zk;

综上,kafka和rabbitmq适应场景不同,kafka适用于高吞吐量场景,rabbitmq适用于对可靠性要求高的场景,综合来讲kafka由于其超高的效率和offset、分区的灵活性,更多的得到了开发者的青睐。

问:如何设计好的消息中间件

(1)支持可伸缩性吧,就是需要的时候快速扩容,就可以增加吞吐量和容量。参照一下kafka的设计理念,broker -> topic -> partition,每个 partition 放一个机器,就存一部分数据。如果现在资源不够了,简单啊,给 topic 增加 partition,然后做数据迁移,增加机器

(2)考虑一下这个mq的数据要不要落地磁盘吧。那肯定要了,落磁盘才能保证别进程挂了数据就丢了。那落磁盘的时候怎么落啊?顺序写,这样就没有磁盘随机读写的寻址开销,磁盘顺序读写的性能是很高的,这就是kafka的思路

(3)mq的可用性啊?这个事儿,具体参考之前可用性那个环节讲解的 kafka 的高可用保障机制。多副本 -> leader & follower -> broker 挂了重新选举 leader 即可对外服务。

(4)数据0丢失啊?可以的,参考我们之前说的那个 kafka 数据零丢失方案

相关文章

网友评论

      本文标题:java面试基础之高并发

      本文链接:https://www.haomeiwen.com/subject/rfpmoctx.html