一、Netty4教程
Netty4是一款使用Java語言基於NIO框架構建的高性能非同步網路通信框架,它提供了一種新的方式在Java平台上開發可擴展的、模塊化的、高性能的、可維護的TCP/IP伺服器和客戶端。Netty4的特點是高性能、高清晰度,易於使用和靈活性。
在Netty4的教程中,我們可以學習如何使用Netty4來編寫TCP/IP伺服器、客戶端和代碼示例,如下所示:
public class NettyServer {
public static void main(String[] args) throws Exception {
//1.創建EventLoopGroup對象,是一個線程池,實際數量可以根據業務需求調整
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workGroup = new NioEventLoopGroup();
try {
//2.創建ServerBootstrap對象,是啟動服務的工具類
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workGroup)
//3.設置TCP協議的Channel,NioServerSocketChannel是對java.nio.*包的封裝
.channel(NioServerSocketChannel.class)
//4.設置對client連接的數據處理邏輯PipeLine
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new NettyServerHandler());
}
})
//5.設置TCP連接參數,SO_BACKLOG是指處於同一時刻待處理的連接隊列的最大長度,超出的新連接會被拒絕,jvm會拋出ConnectionRefusedException
.option(ChannelOption.SO_BACKLOG, 100)
//6.設置緩衝區大小,通常可以不設置,會根據操作系統自適應,如果出現流量控制異常,可以考慮增加緩衝區大小
.option(ChannelOption.SO_SNDBUF, 65535)
.option(ChannelOption.SO_RCVBUF, 65535)
//7.設置心跳檢測機制以及關閉保護機制,保證TCP的正常關閉,防止TCP連接個數增長到JVM的最大值時出現宕機和內存耗盡等問題
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.TCP_NODELAY, true);
// Bind and start to accept incoming connections.
//8.綁定埠
ChannelFuture f = b.bind(PORT).sync();
//9.監聽channel關閉事件並執行shutdownGracefully關閉伺服器和事件處理組
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
}
二、Netty4 Client Pool
在我們使用Netty4來編寫客戶端時,為了保證程序的高效性,需要使用連接池來減少重新建立連接帶來的開銷,使用連接池來管理大量的連接可以提高程序的並發量和性能。
下面是使用Apache Commons Pool結合Netty4實現連接池的代碼示例:
public class NettyClientFactory extends BasePooledObjectFactory<NettyClient> {
private String ip;
private int port;
public NettyClientFactory(String ip, int port) {
this.ip = ip;
this.port = port;
}
@Override
public NettyClient create() throws Exception {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(new NioEventLoopGroup());
bootstrap.channel(NioSocketChannel.class);
bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
//設置重連機制
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel channel) throws Exception {
channel.pipeline().addLast(new NettyClientHandler());
channel.pipeline().addLast(new IdleStateHandler(0, 5, 0, TimeUnit.SECONDS));
}
});
ChannelFuture channelFuture = bootstrap.connect(ip, port);
channelFuture.awaitUninterruptibly();
if (channelFuture != null && channelFuture.isSuccess()) {
return new NettyClient(channelFuture.channel());
}
return null;
}
@Override
public PooledObject<NettyClient> wrap(NettyClient nettyClient) {
return new DefaultPooledObject<>(nettyClient);
}
}
三、Netty4源碼
深入探究Netty4源碼可以大幅度提高我們對Netty4的理解和認識,方便我們更好的使用和維護Netty4。
Netty4的主要源碼結構如下:
+- common -- 通用的代碼 +- buffer -- 位元組緩存相關的代碼,包括ByteBuf的實現、池化等 +- codec -- 編碼和解碼相關的代碼 +- channel -- 整體框架代碼,包括Channel和EventLoop的實現 +- handler -- 處理器相關的代碼 +- transport -- 傳輸相關的代碼,包括網路傳輸和本地傳輸 +- resolver -- 解析器相關的代碼 +- resolver-dns -- DNS解析器相關的代碼
其中,參考使用ChannelInboundHandlerAdapter實現簡單的數據讀取處理,如下代碼所示:
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
private static final Logger log = LoggerFactory.getLogger(NettyServerHandler.class);
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf = (ByteBuf) msg;
byte[] data = new byte[buf.readableBytes()];
buf.readBytes(data);
String request = new String(data, "UTF-8");
log.info("Server received message: {}", request);
ByteBuf resp = Unpooled.copiedBuffer("Hello, I'm server!", CharsetUtil.UTF_8);
ctx.write(resp);
ctx.flush();
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
log.error("Exception caught: {}", cause.getMessage());
ctx.close();
}
}
四、Netty4 TCP開發
使用Netty的TCP開發,可以讓我們非常輕鬆、高效、安全地實現TCP協議方面的開發工作。
下面是一個基於Netty4實現的TCP客戶端代碼示例:
public class NettyTcpClient {
static final String HOST = System.getProperty("host", "127.0.0.1");
static final int PORT = Integer.parseInt(System.getProperty("port", "8080"));
public static void main(String[] args) throws Exception {
EventLoopGroup group = new NioEventLoopGroup(1);
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new NettyClientHandler());
}
});
ChannelFuture f = b.connect(HOST, PORT).sync();
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
}
五、Netty4核心原理
從底層分析Netty4的核心原理可以更好地幫助我們理解和使用Netty4。
Netty4的核心原理是基於NIO的非同步網路通信,NIO通過Selector機制在一組Channel中逐個輪詢事件,只有一個線程能夠輪詢並處理多個Channel,因此Netty4是通過NioEventLoop來負責I/O處理事件。
下面是NioEventLoop的源碼片段:
public void run() {
while (!Thread.interrupted()) {
try {
// 通過selector來取到Channel
int numReady = selectStrategy.calculateStrategy(selectNowSupplier, hasTasks());
// ...
// 通過selector方式來獲取I/O事件
processSelectedKeys();
// 處理Channel上的所有I/O任務和定時任務
runAllTasks();
// ...
} catch (Throwable t) {
// ...
}
}
// ...
}
六、Netty4和5有什麼區別
Netty5相比於Netty4在某些方面進行了較大的改變,比如在編解碼器方面進行不同程度的優化、非同步API使用更加靈活等。
下面是Netty4和Netty5對比的一些區別:
1、Netty4採用EventLoop和EventExecutor分離的設計思路,而Netty5採用非同步的ActiveObject計算模型; 2、Netty5新增了一些基於HTTP/2協議的組件; 3、Netty5提供了更加靈活的非同步API機制,可以更精細地控制非同步事件的執行邏輯; 4、Netty5的通信協議棧進行了重新設計,比如在編解碼器方面進行了不同程度的優化; 5、Netty5底層的非同步事件處理引擎也進行了改進,更加適配不同場景的使用;
結語
Netty4是一個功能強大、易於使用、高性能的非同步網路編程框架,它提供了豐富的網路協議支持和超高的吞吐量,是目前業界最為流行的非同步網路編程框架之一。通過對Netty4的全方位解析,更加深入地理解Netty4的使用、原理和優勢。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/241632.html
微信掃一掃
支付寶掃一掃