netty入门小程序

  1. 云栖社区>
  2. 博客>
  3. 正文

netty入门小程序

yexx 2017-02-24 09:34:00 浏览1824
展开阅读全文

Netty的特性

  1. 设计统一的API,适用于不同的协议(阻塞和非阻塞)基于灵活、可扩展的事件驱动模型高度可定制的线程模型可靠的无连接数据Socket支持(UDP)
  2. 性能更好的吞吐量,低延迟更省资源尽量减少不必要的内存拷贝
  3. 安全完整的SSL/TLS和STARTTLS的支持能在Applet与Android的限制环境运行良好
  4. 健壮性不再因过快、过慢或超负载连接导致OutOfMemoryError不再有在高速网络环境下NIO读写频率不一致的问题
  5. 易用完善的JavaDoc,用户指南和样例简洁简单仅信赖于JDK1.5

Netty 在哪些行业得到了应用?

互联网行业

随着网站规模的不断扩大,系统并发访问量也越来越高,传统基于 Tomcat 等 Web 容器的垂直架构已经无法满足需求,需要拆分应用进行服务化,以提高开发和维护效率。从组网情况看,垂直的架构拆分之后,系统采用分布式部署,各个节点之间需要远程服务调用,高性能的 RPC 框架必不可少,Netty 作为异步高性能的通信框架,往往作为基础通信组件被这些 RPC 框架使用。  

典型的应用有

阿里分布式服务框架 Dubbo 的 RPC 框架使用 Dubbo 协议进行节点间通信,Dubbo 协议默认使用 Netty 作为基础通信组件,用于实现各进程节点之间的内部通信。它的架构图如下:

这里写图片描述

其中,服务提供者和服务消费者之间,服务提供者、服务消费者和性能统计节点之间使用 Netty 进行异步/同步通信。 

除了 Dubbo 之外,淘宝的消息中间件 RocketMQ 的消息生产者和消息消费者之间,也采用 Netty 进行高性能、异步通信。  

除了阿里系和淘宝系之外,很多其它的大型互联网公司或者电商内部也已经大量使用 Netty 构建高性能、分布式的网络服务器。

游戏行业

无论是手游服务端、还是大型的网络游戏,Java 语言得到了越来越广泛的应用。Netty 作为高性能的基础通信组件,它本身提供了 TCP/UDP 和 HTTP 协议栈,非常方便定制和开发私有协议栈。账号登陆服务器、地图服务器之间可以方便的通过 Netty 进行高性能的通信,架构示意图如下:

这里写图片描述

大数据领域

经典的 Hadoop 的高性能通信和序列化组件 Avro 的 RPC 框架,默认采用 Netty 进行跨节点通信,它的 Netty Service 基于 Netty 框架二次封装实现。  
大数据计算往往采用多个计算节点和一个/N个汇总节点进行分布式部署,各节点之间存在海量的数据交换。由于 Netty 的综合性能是目前各个成熟 NIO 框架中最高的,因此,往往会被选中用作大数据各节点间的通信。

企业软件

企业和 IT 集成需要 ESB,Netty 对多协议支持、私有协议定制的简洁性和高性能是 ESB RPC 框架的首选通信组件。事实上,很多企业总线厂商会选择 Netty 作为基础通信组件,用于企业的 IT 集成。

通信行业

Netty 的异步高性能、高可靠性和高成熟度的优点,使它在通信行业得到了大量的应用。

简单实现服务器端和客户端

NettyServer.java

package netty;

import org.jboss.netty.bootstrap.ServerBootstrap;    
import org.jboss.netty.channel.*;    
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;    
import org.jboss.netty.handler.codec.string.StringDecoder;    
import org.jboss.netty.handler.codec.string.StringEncoder;    

import java.net.InetSocketAddress;    
import java.util.concurrent.Executors;    

/**  
 * Author: yexx
 * 
 */    
public class NettyServer {    
    public static void main(String[] args) {    
        ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));    

        // Set up the default event pipeline.    
        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {    
            @Override    
            public ChannelPipeline getPipeline() throws Exception {    
                return Channels.pipeline(new StringDecoder(), new StringEncoder(), new ServerHandler());    
            }    
        });    

        // Bind and start to accept incoming connections.    
        Channel bind = bootstrap.bind(new InetSocketAddress(8000));    
        System.out.println("Server已经启动,监听端口: " + bind.getLocalAddress() + ", 等待客户端注册。。。");    
    }    

    private static class ServerHandler extends SimpleChannelHandler {    
        @Override    
        public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {    
            if (e.getMessage() instanceof String) {    
                String message = (String) e.getMessage();    
                System.out.println("Client发来:" + message);    

                e.getChannel().write("Server已收到刚发送的:" + message);    

                System.out.println("\n等待客户端输入。。。");    
            }    

            super.messageReceived(ctx, e);    
        }    

        @Override    
        public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {    
            super.exceptionCaught(ctx, e);    
        }    

        @Override    
        public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {    
            System.out.println("有一个客户端注册上来了。。。");    
            System.out.println("Client:" + e.getChannel().getRemoteAddress());    
            System.out.println("Server:" + e.getChannel().getLocalAddress());    
            System.out.println("\n等待客户端输入。。。");    
            super.channelConnected(ctx, e);    
        }    
    }    
}   

NettyClient.java

package netty;

import org.jboss.netty.bootstrap.ClientBootstrap;    
import org.jboss.netty.channel.*;    
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;    
import org.jboss.netty.handler.codec.string.StringDecoder;    
import org.jboss.netty.handler.codec.string.StringEncoder;    

import java.io.BufferedReader;    
import java.io.InputStreamReader;    
import java.net.InetSocketAddress;    
import java.util.concurrent.Executors;    

/**  
 * Author: yexx
 * 
 */    
public class NettyClient {    

    public static void main(String[] args) {    
        // Configure the client.    
        ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));    

        // Set up the default event pipeline.    
        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {    
            @Override    
            public ChannelPipeline getPipeline() throws Exception {    
                return Channels.pipeline(new StringDecoder(), new StringEncoder(), new ClientHandler());    
            }    
        });    

        // Start the connection attempt.    
        ChannelFuture future = bootstrap.connect(new InetSocketAddress("localhost", 8000));    

        // Wait until the connection is closed or the connection attempt fails.    
        future.getChannel().getCloseFuture().awaitUninterruptibly();    

        // Shut down thread pools to exit.    
        bootstrap.releaseExternalResources();    
    }    

    private static class ClientHandler extends SimpleChannelHandler {    
        private BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));    

        @Override    
        public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {    
            if (e.getMessage() instanceof String) {    
                String message = (String) e.getMessage();    
                System.out.println(message);    

                e.getChannel().write(sin.readLine());    

                System.out.println("\n等待客户端输入。。。");    
            }    

            super.messageReceived(ctx, e);    
        }    

        @Override    
        public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {    
            System.out.println("已经与Server建立连接。。。。");    
            System.out.println("\n请输入要发送的信息:");    
            super.channelConnected(ctx, e);    

            e.getChannel().write(sin.readLine());    
        }    
    }    
}   

运行可以自己试一试

需要jar包

netty jar包

网友评论

登录后评论
0/500
评论
yexx
+ 关注