awk命令
awk是shell进阶的重要命令,可以用来编排字段
awk把输入流看做一串记录的集合,每条记录都可以进一步细分为字段,一个awk程序是一对以模式和大括号框起来的操作组合而成的,awk每次从文件中读取一条记录
1 | awk [选项] '条件{动作} 条件{动作}' 文件 |
1 | pattern {action} 如模式匹配,则执行操作 |
有时候使用ssh连接服务器,只是一会儿没用就自动断开连接了,又得重新连,很烦人,那么有没有办法可以让连接保持很久不断开呢?那肯定是有的
1 | # *表示所有服务器 |
按照上述配置 120*30 = 3600s,也就是一小时,在客户端和服务器之间没有数据传输的情况下,可以存活一小时
windows一般都是使用ssh工具来进行连接的,找一下工具中有没有配置keepalive时间的地方
在/etc/ssh目录下的sshd_config就是用来配置ssh的,其对于客户端连接的配置默认是这样的
1 | # 给客户端发送TCP kepalive消息 |
按照上述配置 120*30 = 3600s,也就是一小时,在客户端和服务器之间没有数据传输的情况下,可以存活一小时
然后重启下ssh就可以了
1 | service sshd reload |
Netty提供了一个缓冲类ByteBuf来操作字节进行数据传输,ByteBuf可以看做是一个数据容器,其提供了两个索引,一个用来读,一个用来写
其实在java原生NIO中是有缓冲区ByteBuffer的,为什么netty还要再写一套呢?是因为原生的ByteBuffer有很多缺点
就像普通的字节数组一样,ByteBuf使用zero-based indexing,这意味着第一个字节的索引总是0,最后一个字节的索引是capacity - 1,例如,要迭代缓冲区中的所有字节,可以使用如下方式
1 | for (int i = 0; i < buffer.capacity(); i ++) { |
1 | * {@link ByteBuf} provides two pointer variables to support sequential |
ByteBuf提供两个指针变量来支持顺序读写操作,readerIndex作为读指针,writerIndex作为写指针。0到readerIndex之间为已经度过的缓冲区,可以调用discardReadBytes来重用这部分空间,节约内存;readerIndex到writerIndex之间的空间为可读的字节缓冲区;writerIndex到capacity之间为可写的字节缓冲区
1 | * +-------------------+------------------+------------------+ |
这个就是为什么ByteBuf不需要使用flip()方法来切换读和写模式的原因,而JDK中的ByteBuffer是只有一个方法来设置索引的
可读字节存储的是实际的数据,调用read..()或者skip..()方法会使得readerIndex增加
读取所有字节
1 | while (buffer.isReadable()) { |
可写字节是需要被填充的空间
填充随机整数
1 | while (buffer.maxWritableBytes() >= 4) { |
可丢弃的字节说明已经被读过了,可以使用discardReadBytes()来回收空间
调用前
1 | * BEFORE discardReadBytes() |
调用后
1 | * AFTER discardReadBytes() |
可以看到调用后由于空间被回收可用空间被增大
可以通过调用clear()方法来设置readerIndex和writerIndex为0,该操作不会清除缓存数据,仅仅是清除了两个指针
调用前
1 | * BEFORE clear() |
调用后
1 | * AFTER clear() |
netty创建缓冲区可以创建堆缓冲区、堆外缓冲区、复合缓冲区
1 | // 堆缓冲区 |
对于后端业务消息的编解码使用堆缓冲区,而在IO通信线程的读写缓冲区使用堆外缓冲区,组合使得性能最优
ByteBuf将数据存储在JVM的堆空间,通过将数据存储在数组的实现,优点是可以快速分配,当不使用时可以被JVM自动回收;缺点是如果进行Socket的IO读写,需要额外进行一次内存复制,将堆内存对应的缓冲区复制到内核Channel中,性能会有一定下降
直接缓冲区中的内存不是使用的堆内存,其目的是
-XX:MaxDirectMemorySize
来限制的其缺点是在内存空间的分配和释放会比在堆缓冲区更复杂
复合缓冲区可以创建多个不同的ByteBuf,然后提供一个这些ByteBuf的视图,可以动态的添加和删除其中的ByteBuf,由于复合缓冲区是一个视图,所以其hasArray方法总是返回false