最后的话
最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!
资料预览
给大家整理的视频资料:
给大家整理的电子书资料:
如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
在我们开发的程序中,如果要实现通过网络来传输数据,需要用到开发语言提供的网络通信类库。大部分语言提供的网络通信基础类库都是同步的。一个 TCP 连接建立后,用户代码会获得一个用于收发数据的通道。每个通道会在内存中开辟两片区域用于收发数据的缓存。
发送数据的过程比较简单,我们直接往这个通道里面来写入数据就可以了。用户代码在发送时写入的数据会暂存在缓存中,然后操作系统会通过网卡,把发送缓存中的数据传输到对端的服务器上。
只要这个缓存不满,或者说,我们发送数据的速度没有超过网卡传输速度的上限,那这个发送数据的操作耗时,只不过是一次内存写入的时间,这个时间是非常快的。所以,发送数据的时候同步发送就可以了,没有必要异步。
比较麻烦的是接收数据。对于数据的接收方来说,它并不知道什么时候会收到数据。那我们能直接想到的方法就是,用一个线程阻塞在那儿等着数据,当有数据到来的时候,操作系统会先把数据写入接收缓存,然后给接收数据的线程发一个通知,线程收到通知后结束等待,开始读取数据。处理完这一批数据后,继续阻塞等待下一批数据到来,这样周而复始地处理收到的数据。
这就是同步网络 IO 的模型。同步网络 IO 模型在处理少量连接的时候,是没有问题的。但是如果要同时处理非常多的连接,同步的网络 IO 模型就有点儿力不从心了。
因为,每个连接都需要阻塞一个线程来等待数据,大量的连接数就会需要相同数量的数据接收线程。当这些 TCP 连接都在进行数据收发的时候,会导致什么情况呢?对,会有大量的线程来抢占 CPU 时间,造成频繁的 CPU 上下文切换,导致 CPU 的负载升高,整个系统的性能就会比较慢。
所以,我们需要使用异步的模型来解决网络 IO 问题。怎么解决呢?
你可以先抛开你知道的各种语言的异步类库和各种异步的网络 IO 框架,想一想,对于业务开发者来说,一个好的异步网络框架,它的 API 应该是什么样的呢?
我们希望达到的效果,无非就是,只用少量的线程就能处理大量的连接,有数据到来的时候能第一时间处理就可以了。
对于开发者来说,最简单的方式就是,事先定义好收到数据后的处理逻辑,把这个处理逻辑作为一个回调方法,在连接建立前就通过框架提供的 API 设置好。当收到数据的时候,由框架自动来执行这个回调方法就好了。
实际上,有没有这么简单的框架呢?
使用 Netty 来实现异步网络通信
在 Java 中,大名鼎鼎的 Netty 框架的 API 设计就是这样的。接下来我们看一下如何使用 Netty 实现异步接收数据。
// 创建一组线性
EventLoopGroup group = new NioEventLoopGroup();
try{
// 初始化 Server
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(group);
serverBootstrap.channel(NioServerSocketChannel.class);
serverBootstrap.localAddress(new InetSocketAddress("localhost", 9999));
// 设置收到数据后的处理的 Handler
serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new MyHandler());
}
});
// 绑定端口,开始提供服务
ChannelFuture channelFuture = serverBootstrap.bind().sync();
channelFuture.channel().closeFuture().sync();
} catch(Exception e){
e.printStackTrace();
} finally {
group.shutdownGracefully().sync();
}
这段代码它的功能非常简单,就是在本地 9999 端口,启动了一个 Socket Server 来接收数据。我带你一起来看一下这段代码:
- 首先我们创建了一个 EventLoopGroup 对象,命名为 group,这个 group 对象你可以简单把它理解为一组线程。这组线程的作用就是来执行收发数据的业务逻辑。
- 然后,使用 Netty 提供的 ServerBootstrap 来初始化一个 Socket Server,绑定到本地 9999 端口上。
- 在真正启动服务之前,我们给 serverBootstrap 传入了一个 MyHandler 对象,这个 MyHandler 是我们自己来实现的一个类,它需要继承 Netty 提供的一个抽象类:ChannelInboundHandlerAdapter,在这个 MyHandler 里面,我们可以定义收到数据后的处理逻辑。这个设置 Handler 的过程,就是我刚刚讲的,预先来定义回调方法的过程。
- 最后就可以真正绑定本地端口,启动 Socket 服务了。
服务启动后,如果有客户端来请求连接,Netty 会自动接受并创建一个 Socket 连接。你可以看到,我们的代码中,并没有像一些同步网络框架中那样,需要用户调用 Accept() 方法来接受创建连接的情况,在 Netty 中,这个过程是自动的。
为了做好运维面试路上的助攻手,特整理了上百道 【运维技术栈面试题集锦】 ,让你面试不慌心不跳,高薪offer怀里抱!
这次整理的面试题,小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。
本份面试集锦涵盖了
- 174 道运维工程师面试题
- 128道k8s面试题
- 108道shell脚本面试题
- 200道Linux面试题
- 51道docker面试题
- 35道Jenkis面试题
- 78道MongoDB面试题
- 17道ansible面试题
- 60道dubbo面试题
- 53道kafka面试
- 18道mysql面试题
- 40道nginx面试题
- 77道redis面试题
- 28道zookeeper
总计 1000+ 道面试题, 内容 又全含金量又高
- 174道运维工程师面试题
1、什么是运维?
2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?
3、现在给你三百台服务器,你怎么对他们进行管理?
4、简述raid0 raid1raid5二种工作模式的工作原理及特点
5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?
6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?
7、Tomcat和Resin有什么区别,工作中你怎么选择?
8、什么是中间件?什么是jdk?
9、讲述一下Tomcat8005、8009、8080三个端口的含义?
10、什么叫CDN?
11、什么叫网站灰度发布?
12、简述DNS进行域名解析的过程?
13、RabbitMQ是什么东西?
14、讲一下Keepalived的工作原理?
15、讲述一下LVS三种模式的工作过程?
16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?
17、如何重置mysql root密码?
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
朋友,可以点击这里获取!](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!