背景
服务器客户端架构的程序,服务器端如何处理业务?
三种解决方案:
1.单线程 一个线程处理所有任务
2.多线程 每个线程处理一个任务
3.还是单线程处理多个任务,但是使用多路复用选择器
优缺点
1.单线程
优点
简单易用
缺点
阻塞。只有当前面一个任务执行完之后,才能执行下一个任务,cpu被闲置。
2.多线程
优点
解决了单线程的缺点。
缺点
1)需要创建多线程,线程是很重的资源(即占内存空间很多,一个线程0.5~1M)
2)创建完之后,还需要维护线程的各种数据/状态
3)cpu在不同线程之间切换是很累的,就像人的脑子工作的时候被人打扰会很烦一样
3.多路复用
优点
解决多线程的缺点。
缺点
编程复杂
与单线程处理任务的区别?
1.单线程阻塞。浪费CPU。
2.多路复用,非阻塞。服务器轮训连接和事件。
应用场景
1.单线程
简单的小程序,用户量很多的话不适用。
2.多线程
web服务器。例子tomcat等。
3.多路复用
1)java nio-Selector
2)基于java nio的通信框架。例如netty mina。
3)基于通信框架的rpc框架。例如grpc dubbo ice。
实现原理?如何实现?
基于操作系统提供的功能-select()/epoll()函数。
select和epoll的区别?
一样。epoll优化多路复用选择器。
总结
多路复用 入口?
socket 服务器端套接字.accept()方法?
多路复用是怎么接受客户端连接的?
思考问题的时候,把多路复用和socket的流程一一对应起来,很多流程被多路复用/框架封装起来了。
java nio
步骤
while(true){
1.阻塞获取事件 //获取一个或多个事件
2.循环处理获取到的事件集合
}
复制代码
netty
步骤
1.注册事件处理器类
2.当有新的事件到来,事件处理器类自动处理
总结
没有显式地循环获取和处理事件集合的过程,而是被netty框架封装了
和nio的区别?
1.注册事件
事件处理器
2.处理事件
事件处理器处理事件
redis
类似netty
架构图
主要包含四部分
1.套接字
2.多路复用(即可以同时监听多个客户端套接字的事件)
3.事件分发 //所谓事件分发,其实就是while(true){1.阻塞获取事件集合2.遍历处理事件集合}
分发给谁?事件处理器。
4.事件处理器
linux epoll 多路复用 事件驱动机制
多路复用-研究API的输入数据和输出数据?
面试题1
是什么
拨动开关
代码具体怎么实现拨动开关?
1.select
代码实现?
2.poll
解决了连接数量上限问题。
select上限1024个连接。
代码实现?
3.epoll
解决了查找哪个连接速度慢的问题。
代码怎么实现?
参考
zhuanlan.zhihu.com/p/45872289
linux编程接口-63章
面试题2
发展史
1.单线程-阻塞
2.多线程-非阻塞
3.单线程-非阻塞
多路复用
单线程-非阻塞
一个请求来了,还可以继续多个请求。同时,其他请求的事件被监听处理。总之,接受客户端连接和监听已有连接的事件都是轮训/循环执行的。
解决方案
有三种
1.select
2.poll
3.epoll
最佳实践
epoll
三种解决方案的区别
主要是速度。
12是N
3是logN
为什么?这个速度具体指什么?
操作系统层面到底如何实现?
处理流程图?
多个请求-单线程-分发。不要管这个流程图,还有分发这个关键字,容易误解人,也不容易理解。其实就是非阻塞处理所有的连接和读写事件。具体实现方法就是使用循环。
设计模式-反应堆模式Reactor
注册事件,然后分发给各种不同处理器类的一种设计模式。
redis
ae.c ,以及任意一个 ae_*.c 文件(取决于你所使用的多路复用库)。 Redis 的事件处理器实现(基于 Reactor 模式)。