博客
关于我
Netty框架用法介绍&&RPC应用实践
阅读量:177 次
发布时间:2019-02-28

本文共 5266 字,大约阅读时间需要 17 分钟。

Netty技术文档

一、I/O机制简介

计算机中的信息交换主要通过网络I/O和本地I/O实现。网络I/O负责数据在不同计算机之间的传输,本地I/O则负责数据在本地设备(如磁盘、内存)之间的读写。理解I/O机制的演变对于掌握Netty框架至关重要。

I/O的演变历史

I/O的实现方式经历了多次演变:

  • BIO:传统的阻塞I/O模型,单线程处理所有连接,效率较低。
  • NIO:引入了多线程模型,可同时处理多个I/O操作,提升了性能。
  • AIO:基于异步I/O模型,进一步提升了非阻塞操作的效率。
常用框架的通信机制

Netty作为高性能框架,常用于以下系统的通信:

  • Dubbo、RocketMQ、Spring、ElasticSearch、GRPC
  • Spark、Hadoop、Flink

二、环境准备

Netty的依赖管理非常简单,基本配置如下:

io.netty
netty-all
4.1.36.Final

三、Netty RPC示范代码

以下是一个简单的Netty RPC客户端和服务器实现:

服务器代码
public class MyServer {    public static void main(String[] args) throws Exception {        EventLoopGroup bossGroup = new NioEventLoopGroup();        EventLoopGroup workerGroup = new NioEventLoopGroup();        try {            ServerBootstrap serverBootstrap = new ServerBootstrap();            serverBootstrap.group(bossGroup, workerGroup)                         .channel(NioServerSocketChannel.class)                         .childHandler(new MyServerInitializer())                         .localAddress(8899)                         .option(ChannelOption.SO_BACKLOG, 128)                         .childOption(ChannelOption.SO_KEEPALIVE, true);            ChannelFuture channelFuture = serverBootstrap.bind().sync();            channelFuture.channel().closeFuture().sync();        } finally {            bossGroup.shutdownGracefully();            workerGroup.shutdownGracefully();        }    }}class MyServerHandler extends SimpleChannelInboundHandler {    @Override    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {        System.out.println(ctx.channel().remoteAddress() + ", " + msg);        // 业务逻辑处理        Student student = ServiceUtil.query(msg.toString());        IJacksonSerializer serializer = new JacksonSerializer();        byte[] serialize = serializer.serialize(student);        ctx.channel().writeAndFlush(serialize);    }    // 其他事件处理方法可以根据需求添加}class MyServerInitializer extends ChannelInitializer
{ @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)); pipeline.addLast(new LengthFieldPrepender(4)); pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8)); pipeline.addLast(new ByteArrayEncoder()); pipeline.addLast(new MyServerHandler()); }}
客户端代码
public class MyClient {    public static void main(String[] args) throws Exception {        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();        try {            Bootstrap bootstrap = new Bootstrap();            bootstrap.group(eventLoopGroup)                    .channel(NioSocketChannel.class)                    .remoteAddress(new InetSocketAddress("localhost", 8899))                    .handler(new MyClientInitializer());            ChannelFuture channelFuture = bootstrap.connect().sync();            channelFuture.channel().closeFuture().sync();        } finally {            eventLoopGroup.shutdownGracefully().sync();        }    }}class MyClientHandler extends SimpleChannelInboundHandler {    @Override    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {        System.out.println("client output: " + msg + " time: " + System.currentTimeMillis());        ctx.writeAndFlush("C");    }    @Override    public void channelActive(ChannelHandlerContext ctx) throws Exception {        ctx.writeAndFlush("客户端与服务端通道已激活:" + ctx.channel().localAddress());    }}class MyClientInitializer extends ChannelInitializer
{ @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)); pipeline.addLast(new LengthFieldPrepender(4)); pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8)); pipeline.addLast(new JacksonDecoder(Student.class)); pipeline.addLast(new MyClientHandler()); }}

四、Netty RPC支持的编解码

Netty提供了丰富的编解码组件,支持多种协议:

自定义编解码

以下是基于Jackson的自定义编解码实现:

public class JacksonDecoder extends MessageToMessageDecoder {    private Class
clazz; public JacksonDecoder(Class
clazz) { this.classtype = clazz; } @Override protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List list) throws Exception { byte[] data = new byte[msg.readableBytes()]; msg.getBytes(0, data); IJacksonSerializer serializer = new JacksonSerializer(); Object obj = serializer.deserialize(data, clazz); list.add(obj); }}public class JacksonEncoder extends MessageToMessageEncoder { public JacksonEncoder() {} @Override protected void encode(ChannelHandlerContext ctx, byte[] data, List list) throws Exception { // TODO 实现具体的数据编码逻辑 }}

五、ByteBuf介绍

Netty框架内置了高效的数据缓冲类ByteBuf,支持零拷贝操作。以下是常用的操作示例:

byte[] array = new byte[byteBuf.readableBytes()];byteBuf.getBytes(0, array);

六、线程池机制

Netty的EventLoopGroup基于ServerSocketChannel实现,适用于Linux的epoll和Windows的io.wildcards模型。以下是线程池的使用示例:

EventLoopGroup group = new NioEventLoopGroup();// 创建多个事件循环组以应对不同类型的连接

七、总结

Netty框架以其高效的I/O处理能力和灵活的扩展性,成为现代网络应用的首选工具。通过合理配置和自定义编解码,开发者可以根据具体需求实现高性能的网络通信方案。

转载地址:http://kosn.baihongyu.com/

你可能感兴趣的文章
Node.js 在个推的微服务实践:基于容器的一站式命令行工具链
查看>>
Node.js 实现类似于.php,.jsp的服务器页面技术,自动路由
查看>>
Node.js 异步模式浅析
查看>>
node.js 怎么新建一个站点端口
查看>>
Node.js 文件系统的各种用法和常见场景
查看>>
Node.js 的事件循环(Event Loop)详解
查看>>
node.js 简易聊天室
查看>>
Node.js 线程你理解的可能是错的
查看>>
Node.js 调用微信公众号 API 添加自定义菜单报错的解决方法
查看>>
node.js 配置首页打开页面
查看>>
node.js+react写的一个登录注册 demo测试
查看>>
Node.js中环境变量process.env详解
查看>>
Node.js之async_hooks
查看>>
Node.js升级工具n
查看>>
Node.js卸载超详细步骤(附图文讲解)
查看>>
Node.js基于Express框架搭建一个简单的注册登录Web功能
查看>>
Node.js安装与配置指南:轻松启航您的JavaScript服务器之旅
查看>>
Node.js安装及环境配置之Windows篇
查看>>
Node.js安装和入门 - 2行代码让你能够启动一个Server
查看>>
node.js安装方法
查看>>