一、序言
Netty因其易编程,高可靠性,高性能的网络IO,在分布式开发中被广泛用于网络通信,比如RocketMQ,Dubbo底层都能看到Netty的身影,高性能的本质是其Reactor线程模型以及异步的编程处理。Reactor有三种模型,常用的有主从 Reactor多线程模式,具体表现如下:
在日常开发中,常见基于Netty实现TCP报文传输,本文则基于Netty实现一个HTTP服务器,了解Netty的另一种用法。跟Nginx类似,Netty在HTTP协议栈上也有优越的性能表现,不需要依赖Web容器,所以相比的Tomcat、Jetty等Web容器会更轻量和轻巧。
二、具体实现
新建一个Pom工程,引入Netty的相关依赖:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.42.Final</version>
</dependency>
定义Netty服务端NettyHttpServer用作HTTP服务端。创建bossGroup线程组和workerGroup线程组,bossGroup线程组分配一个线程用于轮询注册的通道,监听网络的连接事件,workerGroup用于处理网络的读写IO事件,不指定线程数则默认是CPU核数*2;
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
同时定义服务启动助手ServerBootstrap,用于管理bossGroup和workerGroup;设置服务端通道实现为NIO,全连接队列的大小为1024,同时增加心跳检测的配置,具体代码如下:
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE)
.childHandler()
接着初始化通道同时向pipeline中添加自定义的处理的handler,针对HTTP请求,Netty给我们提供了核心的HTTP编解码器HttpServerCodec,所以在通道初始化的时候增加HTTP编解码器,同时还有我们自定义的业务处理handler,具体代码如下:
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new HttpServerCodec());
// 自定义的业务处理handler
ch.pipeline().addLast(new NettyHttpServerHandler());
}
});
之后启动服务端并绑定端口,同时将异步改为同步,之后监听通道关闭的状态和关闭连接池,服务端完整代码如下:
public class NettyHttpServer {
private int port;
public NettyHttpServer(int port) {
this.port = port;
}
public void run() throws InterruptedException {
EventLoopGroup bossGroup = null;
EventLoopGroup workerGroup = null;
try {
bossGroup = new NioEventLoopGroup(1);
workerGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new HttpServerCodec());
ch.pipeline().addLast(new NettyHttpServerHandler());
}
});
// 将异步改为同步
ChannelFuture future = serverBootstrap.bind(port);
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
System.out.println("端口" + port + "绑定成功!");
}
}
});
future.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
new NettyHttpServer(8080).run();
}
}
剩下就是定义业务处理handler,NettyHttpServerHandler继承抽象类SimpleChannelInboundHandler用于接收数据的传入,类型为HttpObject。当服务端接收到HTTP的请求后,回一个响应”Hello! 我是Netty服务器“,具体代码如下:文章来源:https://www.toymoban.com/news/detail-424590.html
public class NettyHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
//1.判断请求是不是HTTP请求
if (msg instanceof HttpRequest) {
DefaultHttpRequest request = (DefaultHttpRequest) msg;
if ("/favicon.ico".equals(request.uri())) {
return;
}
//2.给浏览器进行响应
ByteBuf byteBuf = Unpooled.copiedBuffer("Hello! 我是Netty服务器 ", CharsetUtil.UTF_8);
DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, byteBuf);
//2.1 设置响应头
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html;charset=utf-8");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, byteBuf.readableBytes());
ctx.writeAndFlush(response);
}
}
}
三、实现效果
启动服务端,显示端口绑定成功则说明服务端正常
流量器请求指定端口,可以看到在浏览器页面显示服务端返回的数据。
到这里,就完成基于Netty实现一个HTTP服务端,主要还是依赖于HTTP的编解码器HttpServerCodec,用于处理浏览器的GET请求,如果要实现POST请求,则需要依赖HttpObjectAggregator编解码器。文章来源地址https://www.toymoban.com/news/detail-424590.html
到了这里,关于基于Netty实现一个HTTP服务器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!