`
youyu4
  • 浏览: 440097 次
社区版块
存档分类
最新评论

java Netty 之 Hello World

 
阅读更多

java Netty 之Hello World

 

先看看服务端和客户端的代码:

public class HelloServer {  
  
    public static void main(String args[]) {  
        // Server服务启动器  
        ServerBootstrap bootstrap = new ServerBootstrap(  
                new NioServerSocketChannelFactory(  
                        Executors.newCachedThreadPool(),  
                        Executors.newCachedThreadPool()));  
        // 设置一个处理客户端消息和各种消息事件的类(Handler)  
        bootstrap  
                .setPipelineFactory(new ChannelPipelineFactory() {  
                    @Override  
                    public ChannelPipeline getPipeline()  
                            throws Exception {  
                        return Channels  
                                .pipeline(new HelloServerHandler());  
                    }  
                });  
        // 开放8000端口供客户端访问。  
        bootstrap.bind(new InetSocketAddress(8000));  
    }  
  
    private static class HelloServerHandler extends  
            SimpleChannelHandler {  
  
        /** 
         * 当有客户端绑定到服务端的时候触发,打印"Hello world, I'm server." 
         *  
         * @alia OneCoder 
         * @author lihzh 
         */  
        @Override  
        public void channelConnected(  
                ChannelHandlerContext ctx,  
                ChannelStateEvent e) {  
            System.out.println("Hello world, I'm server.");  
        }  
    }  
}

 

public class HelloClient {  
  
    public static void main(String args[]) {  
        // Client服务启动器  
        ClientBootstrap bootstrap = new ClientBootstrap(  
                new NioClientSocketChannelFactory(  
                        Executors.newCachedThreadPool(),  
                        Executors.newCachedThreadPool()));  
        // 设置一个处理服务端消息和各种消息事件的类(Handler)  
        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {  
            @Override  
            public ChannelPipeline getPipeline() throws Exception {  
                return Channels.pipeline(new HelloClientHandler());  
            }  
        });  
        // 连接到本地的8000端口的服务端  
        bootstrap.connect(new InetSocketAddress(  
                "127.0.0.1", 8000));  
    }  
  
    private static class HelloClientHandler extends SimpleChannelHandler {  
  
  
        /** 
         * 当绑定到服务端的时候触发,打印"Hello world, I'm client." 
         *  
         * @alia OneCoder 
         * @author lihzh 
         */  
        @Override  
        public void channelConnected(ChannelHandlerContext ctx,  
                ChannelStateEvent e) {  
            System.out.println("Hello world, I'm client.");  
        }  
    }  
}

 

注意两点:

 

   1. 既然是分布式的,自然要分多个服务。Netty中,需要区分Server和Client服务。所有的Client都是绑定在Server上的,他们之间是不能通过Netty直接通信的。(自己采用的其他手段,不包括在内。)。白话一下这个通信过程,Server端开放端口,供Client连接,Client发起请求,连接到Server指定的端口,完成绑定。随后便可自由通信。其实就是普通Socket连接通信的过程。

 

   2. Netty框架是基于事件机制的,简单说,就是发生什么事,就找相关处理方法。就跟着火了找119,事故了找110一个道理。所以,这里,我们处理的是当客户端和服务端完成连接以后的这个事件。什么时候完成的连接,Netty知道,他告诉我了,我就负责处理。这就是框架的作用。Netty,提供的事件还有很多,以后会慢慢的接触和介绍。

 

 

 

 

代码实现

 

ServerSocketChannelFactory

 

ServerBootstrap用一个ServerSocketChannelFactory 来实例化。ServerSocketChannelFactory 有两种选择,一种是NioServerSocketChannelFactory,一种是OioServerSocketChannelFactory。 前者使用NIO,后则使用普通的阻塞式IO。它们都需要两个线程池实例作为参数来初始化,一个是boss线程池,一个是worker线程池。

 

 

bootstrap.setPipelineFactory()

 

这里设置ChannelpipelineFactory,factory中要new一个我们自定义的Handler,Handler中重写相应事件的方法,这样我们就能在方法中写我们的业务。同时,我们自定义的Handler是继承SimpleChannelHandler。

 

 

ServerBootstrap.bind(int)

 

负责绑定端口,当这个方法执行后,ServerBootstrap就可以接受指定端口上的socket连接了。一个ServerBootstrap可以绑定多个端口。

 

 

 

 

boss线程和worker线程

 

boss线程

 

      主要负责connet和accept

 

      可以这么说,ServerBootstrap监听的一个端口对应一个boss线程,它们一一对应。比如你需要netty监听80和443端口,那么就会有两个boss线程分别负责处理来自两个端口的socket请求。在boss线程接收了socket连接请求后,会产生一个channel(一个打开的socket对应一个打开的channel),并把这个channel交给ServerBootstrap初始化时指定的ServerSocketChannelFactory来处理,boss线程则继续处理socket的请求。

 

 

worker线程

 

      主要负责业务逻辑

 

      ServerSocketChannelFactory则会从worker线程池中找出一个worker线程来继续处理这个请求。其中分为:OioServerSocketChannelFactory 和 NioServerSocketChannelFactory。

 

  • OioServerSocketChannelFactory:就是IO,这个channel上所有的socket消息,从开始到channel(socket)关闭,都只由这个特定的worker来处理,也就是说一个打开的socket对应一个指定的worker线程,这个worker线程在socket没有关闭的情况下,也只能为这个socket处理消息,无法服务其他socket。
  • NioServerSocketChannelFactory:就是NIO,每个worker可以服务不同的socket或者说channel,worker线程和channel不再有一一对应的关系。

结果

 

显然,NioServerSocketChannelFactory只需要少量活动的worker线程及能很好的处理众多的channel,而OioServerSocketChannelFactory则需要与打开channel等量的worker线程来服务。

 

 

如何选择

 

线程是一种资源,所以当netty服务器需要处理长连接的时候,最好选择NioServerSocketChannelFactory,这样可以避免创建大 量的worker线程。在用作http服务器的时候,也最好选择NioServerSocketChannelFactory,因为现代浏览器都会使用 http keepalive功能(可以让浏览器的不同http请求共享一个信道),这也是一种长连接。

 

 

 

 

worker线程的生命周期(life circle)

 

 

   1. 当某个channel有消息到达或者有消息需要写入socket的时候,worker线程就会从线程池中取出一个。在worker线程中,消息会经过设定好的ChannelPipeline处理。ChannelPipeline就是一堆有顺序的filter,它分为两部分:UpstreamHandler和 DownStreamHandler。

 

 

   2. 客户端送入的消息会首先由许多UpstreamHandler依次处理,处理得到的数据送入应用的业务逻辑handler,通常用SimpleChannelUpstreamHandler来实现这一部分。

private static class HelloClientHandler extends SimpleChannelHandler {  
  
        /** 
         * 当绑定到服务端的时候触发,打印"Hello world, I'm client." 
         *  
         * @alia OneCoder 
         * @author lihzh 
         */  
        @Override  
        public void channelConnected(ChannelHandlerContext ctx,  
                ChannelStateEvent e) {  
            System.out.println("Hello world, I'm client.");  
	}  
}

 

 

   3. 对 于Nio当messageReceived()方法执行后,如果没有产生异常,worker线程就执行完毕了,它会被线程池回收。业务逻辑hanlder 会通过一些方法,把返回的数据交给指定好顺序的DownStreamHandler处理,处理后的数据如果需要,会被写入channel,进而通过绑定的 socket发送给客户端。这个过程是由另外一个线程池中的worker线程来完成的。

 

 

   4. 对于Oio来说,从始到终,都是由一个指定的worker来处理。

 

 

 

 

减少worker线程的处理占用时间

 

      worker 线程是由netty内部管理,统一调配的一种资源,所以最好应该尽快的把让worker线程执行完毕,返回给线程池回收利用。worker线程的大部分时 间消耗在在ChannelPipeline的各种handler中,而在这些handler中,一般是负责应用程序业务逻辑掺入的那个handler最占 时间,它通常是排在最后的UpstreamHandler。所以通过把这部分处理内容交给另外一个线程来处理,可以有效的减少worker线程的周期循环 时间。一般有两种方法:

 

  • 开启一个新的线程来处理业务逻辑
  • 另外构造一个线程池来提交业务逻辑处理任务(更优雅)

代码如下:

public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception{    
     ...    
     new Thread(...).start();    
}  

 

 

 

参考

http://blog.csdn.net/lichunan/article/details/45165783

分享到:
评论

相关推荐

    Netty之helloworld示列

    在本示例中,“Netty之helloworld”旨在为初学者提供一个简单的入门教程,帮助理解Netty的工作原理和基本用法。 首先,Netty的核心概念包括Bootstrap(引导类)、Channel(通道)、Handler(处理器)和EventLoop...

    netty之hello world

    在本文中,我们将深入探讨Netty的基本概念,通过“Hello World”范例来理解其工作原理。 首先,让我们理解Netty的核心概念。Netty基于Java NIO(非阻塞I/O)构建,提供了高级API来处理网络通信。它包含以下几个关键...

    Java Netty-入门教程.pdf

    ### Java Netty 入门教程知识点详解 #### 1. Netty 概览 ##### 1.1 Netty 是什么? Netty 是一款基于 Java 的高性能网络应用框架,支持多种协议,包括但不限于 HTTP、FTP、SMTP 等,并且特别擅长处理 TCP 和 UDP ...

    Java NIO框架Netty教程.pdf

    它是Netty中最重要的组件之一。 - **ChannelHandlerContext**:上下文对象,用来保存Channel的信息以及与其关联的操作。 - **ChannelPipeline**:一系列的处理器,用于处理入站和出站的数据。 - **...

    Java视频教程 Java游戏服务器端开发 Netty NIO AIO Mina视频教程

    01、Mina服务端helloWorld入门.flv 02、Mina客户端helloWorld入门.flv 03、Mina整体体系结构分析.flv 04、Mina学习之长短连接.flv 05、Mina学习之MinaIOService接口.flv 06、Mina学习之MinaIOFilter接口.flv ...

    一款基于Netty+Zookeeper+Spring实现的轻量级Java RPC框架。提供服务注册,发现,负载均衡,.zip

    标题中的“一款基于Netty+Zookeeper+Spring实现的轻量级Java RPC框架”揭示了这个项目的核心技术栈,它整合了三个在分布式系统中广泛使用的开源库:Netty、Zookeeper和Spring。让我们逐一深入探讨这三个技术以及它们...

    Netty网络编程视频教程

    近百节视频详细讲解,需要的小伙伴自行百度网盘下载,链接见附件,永久有效...2. Hello World 3. 组件 4. 双向通信 三. Netty 进阶 1. 粘包与半包 2. 协议设计与解析 3. 聊天室案例 四. 优化与源码 1. 优化 2. 源码分析

    Java_NIO框架Netty教程.pdf

    通常来说,Netty官方例子中并不包含传统的"Hello World"示例,但我们可以自定义一个简单的Netty服务器和客户端来快速上手。以下是一个简单的Netty服务器和客户端的代码示例,以帮助理解Netty的使用。 在Netty服务器...

    Netty中集成Protobuf实现Java对象数据传递示例代码.rar

    2. 生成Java类:使用Protobuf的编译器protoc将.proto文件编译为Java类,这里会生成HelloWorld类。 3. 编写Netty编码器和解码器:在Netty中,我们需要自定义编码器(Encoder)和解码器(Decoder),以便在数据发送前...

    Java-netty.io:HTTP 服务器 w netty.io 框架

    框架需要在netty框架( )上实现一个http服务器,功能如下: 根据对请求在 10 秒后给出“Hello World” 根据对请求,重定向到指定的 url 根据对请求统计信息: 请求总数唯一请求的数量(每个 IP 一个) 每个 IP 的...

    Netty大纲-同步netty专栏

    - **HelloWorld**:Netty的基本使用包括服务器端和客户端的搭建,以及事件驱动模型的理解。 - **组件**:Netty中的EventLoop负责事件处理,Handler处理不同类型的事件,ByteBuf作为缓冲区,提供了池化和直接内存的...

    netty学习教程

    本教程从基础概念出发,逐步深入到核心组件及其实现细节,并通过一个简单的“Hello World”示例,帮助读者理解如何构建一个完整的Netty应用。这不仅有助于初学者快速入门Netty,也为进阶学习打下了坚实的基础。

    netty代码demo.rar

    - **Hello World**:简单的服务器和客户端,展示最基本的建立连接和发送数据的过程。 - **心跳机制**:实现客户端与服务器之间的定期心跳检测,确保连接的有效性。 - **多路复用**:展示如何在一个Channel上处理多个...

    深入浅出Netty

    Netty的强大功能不仅仅停留在理论层面,下面通过一个简单的“HelloWorld”示例,展示如何使用Netty搭建网络通信服务。 #### HelloWorldServer 首先,创建一个`ServerBootstrap`实例,指定一个`...

    cassandra-netty-rest-simple:Netty上部署的Hello World REST Web服务在调用时将一个Person对象插入Cassandra

    cassandra-netty-rest-simple 集成了Cassandra,Netty和JBoss RESTEasy的简单应用程序。 它提供了一个Hello World REST Web服务,可以通过。 调用服务时,它将Person的实例持久化到名为DEMO的Cassandra键空间中。

    Test_netty_

    1. **Hello World 示例**:通常,Netty 的第一个示例会是“Hello World”,展示如何创建一个简单的服务器和客户端,它们之间能互相发送消息。 2. **协议编解码器**:Netty 提供了多种编解码器,如 ...

    Netty培训讲义.docx

    例如,"Hello World" 示例展示了如何使用 Netty 创建一个简单的服务器和客户端。在服务器端,我们创建一个 ServerBootstrap 实例,配置 ChannelPipeline,添加 StringDecoder、StringEncoder 和 ...

    Netty-Resteasy-Spring

    Test http://localhost:8082/resteasy/hello/world 教程 jax-rs规范用法: http://www.vogella.com/tutorials/REST/article.html resteasy 教程: http://code.freedomho.com/9541.html 名次解释 RESTEasy:RESTEasy...

    netty开发入门

    这个“netty开发入门”资料主要涵盖了如何使用Netty进行基础的网络通信,包括创建简单的"Hello World"示例以及实现服务器与客户端的交互。 一、Netty简介 Netty是由JBOSS提供的一个Java开源框架,它简化了网络编程...

    Netty_in_Action(第五版目录修正)

    - **Hello World示例**:通过一个简单的“Hello World”程序演示Netty的基本用法。 **第3章:Netty从底层构建** - **底层机制**:详细介绍Netty内部是如何工作的,包括事件循环、通道管理等关键概念。 - **高级...

Global site tag (gtag.js) - Google Analytics