Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3ccd74d

Browse filesBrowse files
committed
add netty note
1 parent 15a47d2 commit 3ccd74d
Copy full SHA for 3ccd74d

File tree

Expand file treeCollapse file tree

5 files changed

+285
-0
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

5 files changed

+285
-0
lines changed
Open diff view settings
Collapse file

‎Spring-Netty/src/main/java/com/bruis/learnnetty/netty/demo01/NettyServerHandler.java‎

Copy file name to clipboardExpand all lines: Spring-Netty/src/main/java/com/bruis/learnnetty/netty/demo01/NettyServerHandler.java
+48Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import io.netty.channel.ChannelPipeline;
99
import io.netty.util.CharsetUtil;
1010

11+
import java.util.concurrent.TimeUnit;
12+
1113
/**
1214
* @author LuoHaiYang
1315
*/
@@ -35,6 +37,7 @@ public void handlerAdded(ChannelHandlerContext ctx) {
3537
*/
3638
@Override
3739
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
40+
/*
3841
System.out.println("服务器读取线程 " + Thread.currentThread().getName());
3942
System.out.println("server ctx = " + ctx);
4043
System.out.println("看看Channel和pipeline的关系");
@@ -46,6 +49,51 @@ public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exce
4649
ByteBuf byteBuf = (ByteBuf)msg;
4750
System.out.println("客户端发送消息是:" + byteBuf.toString(CharsetUtil.UTF_8));
4851
System.out.println("客户端地址:" + channel.remoteAddress());
52+
*/
53+
54+
// 自定义任务
55+
/*
56+
ctx.channel().eventLoop().execute(new Runnable() {
57+
@Override
58+
public void run() {
59+
try {
60+
Thread.sleep(5 * 1000);
61+
ctx.writeAndFlush(Unpooled.copiedBuffer("hello, client... task", CharsetUtil.UTF_8));
62+
System.out.println("channel hashcode = " + ctx.channel().hashCode());
63+
} catch (Exception e) {
64+
System.out.println("Exception" + e.getMessage());
65+
}
66+
}
67+
});
68+
69+
ctx.channel().eventLoop().execute(new Runnable() {
70+
@Override
71+
public void run() {
72+
try {
73+
Thread.sleep(5 * 1000);
74+
ctx.writeAndFlush(Unpooled.copiedBuffer("hello, client2... task", CharsetUtil.UTF_8));
75+
System.out.println("channel hashcode = " + ctx.channel().hashCode());
76+
} catch (Exception e) {
77+
System.out.println("Exception" + e.getMessage());
78+
}
79+
}
80+
});
81+
*/
82+
83+
// 自定义定时任务
84+
ctx.channel().eventLoop().schedule(new Runnable() {
85+
@Override
86+
public void run() {
87+
try {
88+
Thread.sleep(5 * 1000);
89+
ctx.writeAndFlush(Unpooled.copiedBuffer("hello, client3... task", CharsetUtil.UTF_8));
90+
System.out.println("channel hashcode = " + ctx.channel().hashCode());
91+
} catch (Exception e) {
92+
System.out.println("error" + e);
93+
}
94+
}
95+
}, 5, TimeUnit.SECONDS);
96+
4997
}
5098

5199
/**
Collapse file
+38Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
## 前言
2+
3+
在Netty中,抽象出线程组Group,它的类型为EventLoopGroup。在Netty服务端,有两组EventLoopGroup,一个是
4+
parentGroup,用于负责客户端的连接;另一个是childGroup,用于负责网络的读写。
5+
6+
## 1. EventLoopGroup
7+
8+
在Netty中,抽象出一种线程池EventLoopGroup,底层是ScheduledExecutorService。那么EventLoopGroup的作用是什么呢?
9+
10+
首先这里需要注意的是,EventLoopGroup是一个接口,接口中定义了register方法,用于注册通道Channel。那么EventLoopGroup作为线程池,当然是用于存储EventLoop的,这里可以大胆的猜想,EventLoop的作用类似于一个线程,接下来就去证实一下我们的猜想。EventLoop是什么?
11+
12+
### 1.1 EventLoop
13+
14+
这里先给出一个结论:EventLoop表示一个不断循环的执行处理任务的线程,在Netty中用的比较多的是NioEventLoop,每个NioEventLoop都有一个selector,用于监听绑定在其上的socket的网络编程。
15+
16+
每个NioEventLoop内部都有一个selector, 用于监听绑定在其上的socket的网络通讯。
17+
18+
NioEventLoop循环执行三件事:
19+
1. 轮询accept事件;
20+
2. 处理accept事件,与client建立连接,生成NioSocketChannel,并将其注册到某个worker NIOEventLoop上的selector。
21+
3. 处理任务队列的任务,即runAllTasks
22+
23+
任务队列中的task有3中典型使用场景:
24+
1. 自定义普通任务;
25+
2. 自定义定时任务;
26+
3. 非当前Reactor线程调用Channel的各种方法;
27+
28+
NioEventLoop内部采用串行化设计,从设计的读取->解码->处理->编码->发送,始终由IO线程NioEventLoop负责。
29+
30+
每个NioEventLoop中包含有一个Selector,一个taskQueue,taskQueue是在父类SingleThreadEventLoop中。
31+
32+
每个NioEventLoop的Selector上可以注册多个NioChannel。
33+
34+
每个NioChannel只会绑定在唯一的NioEventLoop上。
35+
36+
每个NioChannel都绑定有一个自己的ChannelPipeline。
37+
38+
## 2.
Collapse file

‎note/Netty/Netty源码包结构‎

Copy file name to clipboard
+31Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## 前言
2+
3+
要分析Netty源码,首先得搞清楚Netty源码包目录结构。
4+
5+
## 正文
6+
7+
Netty版本:4.1.43.Final
8+
9+
- netty-all
10+
11+
- netty-buffer
12+
13+
netty所有的buffer有关的jar包。
14+
15+
- netty-codec
16+
17+
netty关于二进制编码、序列化相关jar包。
18+
19+
- netty-common
20+
21+
netty核心包,包括netty工具类,netty的EventExecutor等抽象接口。
22+
23+
- netty-handler
24+
25+
netty内置的handler。
26+
27+
- netty-resolver
28+
29+
30+
- netty-transport
31+
Collapse file

‎note/Netty/二进制‎

Copy file name to clipboard
+157Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
## 前言
2+
3+
在学习框架源码底层时,有非常多的二进制运算,由于大学学习计算机基础时抓梦脚(jio),没有学习牢固,所以在看底层源码的算法逻辑时遇到二进制
4+
运算比较吃力,遂通过一篇博文来总结下二进制运算,记录一下。
5+
6+
## 正文
7+
8+
### 1. 二进制基础
9+
10+
因为计算机底层是通过二进制来进行计算的,所以在计算机底层会将十进制转换为二进制。十进制就是逢10进1,二进制就是逢2进1。
11+
12+
就十进制来说,比如一百可以分为三位,个位、十位、百位, 用位数在下列表示 101这个十进制数。
13+
14+
| 百位 | 十位 | 十位 |
15+
| ---- | ---- | --- |
16+
| 1 | 0 | 1 |
17+
18+
因此对于十进制来说,越往上进制为越大,比如千位、万位。
19+
20+
同理,对于二进制来说也有对应位数, 如果表示二进制的4。
21+
22+
| 4 | 2 | 1 |
23+
| ---- | ---- | --- |
24+
| 1 | 0 | 0 |
25+
26+
1 * 4 + 2 * 0 + 1 * 0 = 4
27+
28+
如果要表示二进制的5,则如下图
29+
30+
| 4 | 2 | 1 |
31+
| ---- | ---- | --- |
32+
| 1 | 0 | 1 |
33+
34+
4 * 1 + 2 * 0 + 1 * 1 = 5
35+
36+
如果要表示二进制的11,则如下图
37+
38+
| 8 | 4 | 2 | 1 |
39+
| ---- | ---- | --- | --- |
40+
| 1 | 0 | 1 | 1 |
41+
42+
8 * 1 + 4 * 0 + 2 * 1 + 1 * 1 = 11
43+
44+
在计算机中,1字节有8位二进制位。
45+
46+
### 2. 二进制运算
47+
48+
对于二进制运算,记住一个口诀:
49+
50+
1. 与(&)运算
51+
52+
运算规则:
53+
``` 0&0=0, 0&1=0, 1&0=0, 1&1=1 ```
54+
55+
二者为1则为1,否则都为0。
56+
57+
2. 或(|)运算
58+
59+
运算规则:
60+
``` 0|0=0,0|1=1,1|0=1,1|1=1 ```
61+
62+
遇1则1,否则为0。
63+
64+
3. 异(^)或运算
65+
66+
运算规则:
67+
``` 0^0=0, 1^0=1, 0^1=1, 1^1=0 ```
68+
69+
同为0,异为1。
70+
71+
72+
### 3. 二进制的源码、补码以及反码
73+
74+
> 二进制源码是什么?
75+
76+
由于数字有正负之分,所以在计算机中通过在一个数的二进制的最高位存放符号(0为正,1为负),而其他数值位存放着就是数值的二进制位, 这就是二进制源码。
77+
78+
源码有缺点,就是不能直接进行运算,因为运算会出错。源码是有符号数的最简单的编码方式,便于输入输出,但作为代码加减运算时较为复杂。
79+
80+
> 二进制反码是什么?
81+
82+
反码通常是用来由源码求补码或者由补码求源码的过度码,根据定义可以根据补码的整数和小数中"0"的表示形式各有2中,+0和-0不一样。以8位机器数为例,
83+
整数的"+0"源码为:0,0000000,反码为:0,0000000。整数的"-0"源码为:1,0000000,反码为:1,1111111。
84+
85+
反码跟源码是正数时一样,为负数是,除符号位外,其他为所有数值取反。
86+
87+
> 二进制补码是什么?
88+
89+
由于数字有正负之分,所以在计算机中通过在一个数的二进制的最高位存放符号(0为正,1为负),而这就是机器数的补码。
90+
91+
总结起来补码的作用就是:
92+
1. 使符号位能与有效值部分一起参加运算,从而简化运算规则.
93+
2. 使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计 所有这些转换都是在计算机的最底层进行的,而在我们使用的汇编、C等其他高级语言中使用的都是原码。
94+
95+
> 补码和反码之间怎么转换?
96+
97+
补码是反码加一。
98+
99+
100+
> 小结
101+
102+
对于源码、补码和反码,三者均有符号位和数值位两部分。符号位用0表示正,1表示负,而数值位三者表示方法都不同。在计算机系统中,数值一律用补码来
103+
表示和存储,原因在于补码可以将符号位和数值域统一处理,同时加法和减法也可以同一处理,此外源码和补码互相转换,其运算过程是相同的,不需要额外的硬件电路。
104+
一个负整数和其补数相加和为模,对一个整数的补码再求补码等于该整数自身,补码的正零与负零表示方法相同。
105+
106+
### 4. 示例
107+
108+
比如变量 a & (-a) 用二进制怎么运算:
109+
110+
&是按位与,首先在计算机中数字都是以补码的形式存在的,比如:
111+
112+
a = 10
113+
114+
以8位二进制位为例,
115+
116+
+10,它的源码为:
117+
118+
0000 1010
119+
120+
由于正数的源码和补码相同,所以它的补码为:
121+
122+
0000 1010
123+
124+
对于-10,
125+
126+
它的源码为:
127+
128+
1000 1010
129+
130+
它的反码是源码的数值域取反,即:
131+
132+
1111 0101
133+
134+
它的补码是反码+1,即:
135+
136+
1111 0110
137+
138+
由于二进制运算都是用补码来计算的,所以 a & (-a) ,就是:
139+
140+
0000 1010 & 1111 0110 = 0000 0010 换算为十进制为2。
141+
142+
所以如果a=10,则 10 & (-10) = 2
143+
144+
在Netty底层源码中,NioEventLoop的底层源码有一个方法, 就是通过 a & (-a)来运算的。
145+
146+
```
147+
/*
148+
* 用于计算val是否是2的幂,例如2、4、8、16
149+
* /
150+
private static boolean isPowerOfTwo(int val) {
151+
return (val & -val) == val;
152+
}
153+
```
154+
155+
### 总结
156+
157+
在计算机中,二进制的运算是比较重要的,可以看到在Java的许多开源框架底层就运用到了大量的二进制与或非运算,所以学好二进制的基础概念是非常重要的。
Collapse file

‎note/Netty/零拷贝‎

Copy file name to clipboard
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## 前言
2+
3+
零拷贝是网络编程的关键,很多性能优化都离不开零拷贝,本文就零拷贝分析下Java常用的零拷贝、NIO零拷贝。
4+
5+
## 正文
6+
7+
### 1. mmap和sendFile零拷贝
8+
9+
在Java程序中,常用的零拷贝有mmap(内存映射)和sendFile。让我们回到IO底层,在Java中,一次IO操作在操作系统底层都做了哪些工作。
10+
11+

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.