zoukankan      html  css  js  c++  java
  • netty-学习笔记

    零、socket:

     http://haohaoxuexi.iteye.com/blog/1979837

    一、NIO(1.0)非阻塞

    • NIO的特点:
      1. Buffer,缓冲区
      2. Channel,管道
      3. Selector,多路复用选择器
    • NIO的步骤:

    二、AIO(NIO2.0)异步非阻塞

      使用了异步的channel,调用jdk底层的回掉函数,异步处理。

    三、什么是netty(基于NIO2.0)

        Netty is an asynchronous event-driven network application framework  for rapid development of maintainable high performance protocol servers & clients.

        Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programming such as TCP and UDP socket server.

    四、为什么使用netty

      远古:使用的是io,近代是nio,现在是netty(已经封装好了的,相对与nio,API更加的简单)

    • netty的特点:
    1. 责任链,和tomcat中的fitter类似(最后结果交给servlet)避免请求的发送者和接受者直接的耦合关系。
    2. 异步

         Netty的异步事件驱动模型主要涉及到下面几个核心的概念:

    1.  Channel:表示一个与socket关联的通道
    2.  ChannelPipeline: 管道,一个Channel拥有一个ChannelPipeline,ChannelPipeline维护着一个处理链(严格的说是两 个:upstream、downstream),处理链是由很多处理句柄ChannelHandler所构成,每个ChannelHandler处理完以 后会传递给链中的下一个处理句柄继续处理。
    3.   ChannelHandler:处理句柄,用户可以定义自己的处理句柄来处理每个请求,或发出请求前进行预处理,典型的有编码/解码器:decoder、encoder。
    4.  ChannelEvent:事件,是整个模型的处理对象,当产生或触发(fire)一个事件时,该事件会沿着ChannelPipeline处理链依次被处理。
    5.  ChannelFuture: 异步结果,这个是异步事件处理的关键,当一个事件被处理时,可以直接以ChannelFuture的形式直接返回,不用在当前操作中被阻塞。可以通过 ChannelFuture得到最终的执行结果,具体的做法是在ChannelFuture添加监听器listener,当操作最终被执行完 后,listener会被触发,我们可以在listener的回调函数中预定义我们的业务代码。

    五、如何使用netty,netty的demo

    1.  建立连接池
    2.  继承netty父类实现方法

    TimeServer

     1 package com.wanghongye.Netty;
     2 
     3 import io.netty.bootstrap.ServerBootstrap;
     4 import io.netty.channel.ChannelFuture;
     5 import io.netty.channel.ChannelInitializer;
     6 import io.netty.channel.ChannelOption;
     7 import io.netty.channel.EventLoopGroup;
     8 
     9 import io.netty.channel.nio.NioEventLoopGroup;
    10 import io.netty.channel.socket.SocketChannel;
    11 import io.netty.channel.socket.nio.NioServerSocketChannel;
    12 
    13 /**
    14  * @Description :netty服务端
    15  * @author :王红叶
    16  * @date(创建日期):2015年9月22日 下午5:15:22
    17  * @company(公司):深圳市彩讯科技有限公司
    18  * 
    19  * @History(修改历史):
    20  */
    21 public class TimeServer
    22 {
    23 
    24     public void bind(int port) throws Exception
    25     {
    26         EventLoopGroup bossGroup = new NioEventLoopGroup();
    27         EventLoopGroup workGroup = new NioEventLoopGroup();
    28 
    29         try
    30         {
    31             ServerBootstrap b = new ServerBootstrap();
    32             b.group(bossGroup, workGroup).channel(NioServerSocketChannel.class)
    33                 .option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChildChannelHandler());
    34             
    35             ChannelFuture f = b.bind(port).sync();
    36             
    37             f.channel().closeFuture().sync();
    38         }
    39         finally 
    40         {
    41             bossGroup.shutdownGracefully();
    42             workGroup.shutdownGracefully();
    43         }
    44     }
    45     
    46     private class ChildChannelHandler extends ChannelInitializer<SocketChannel>{
    47 
    48         @Override
    49         protected void initChannel(SocketChannel arg0) throws Exception
    50         {
    51             arg0.pipeline().addLast(new TimeChannelHandler());
    52         }
    53     }
    54     
    55     public static void main(String[] args) throws Exception
    56     {
    57         int port = 8080;
    58         if(args != null && args.length>0){
    59             port = Integer.valueOf(args[0]);
    60         }
    61         new TimeServer().bind(port);
    62     }
    63 }
    View Code

     TimeChannelHandler

     1 package com.wanghongye.Netty;
     2 
     3 import io.netty.buffer.ByteBuf;
     4 import io.netty.buffer.Unpooled;
     5 import io.netty.channel.ChannelHandlerAdapter;
     6 import io.netty.channel.ChannelHandlerContext;
     7 
     8 /**
     9  * Netty处理类
    10  * @Description :
    11  * @author :王红叶
    12  * @date(创建日期):2015年9月22日 下午4:54:06
    13  * @company(公司):深圳市彩讯科技有限公司
    14  * 
    15  * @History(修改历史):
    16  */
    17 public class TimeChannelHandler extends ChannelHandlerAdapter
    18 {
    19     public void channelRead(ChannelHandlerContext ctx, Object msg)
    20         throws Exception
    21     {
    22         ByteBuf byteBuf = (ByteBuf) msg;
    23         byte[] req = new byte[byteBuf.readableBytes()];
    24         byteBuf.readBytes(req);
    25 
    26         String body = new String(req, "UTF-8");
    27         System.out.println("*********" + body);
    28         String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new java.util.Date(
    29             System.currentTimeMillis()).toString() : "BAD ORDER";
    30         ByteBuf byteBufReps = Unpooled.copiedBuffer(currentTime.getBytes());
    31         ctx.write(byteBufReps);
    32 
    33     }
    34 
    35     public void channelReadComplete(ChannelHandlerContext ctx)
    36     {
    37         ctx.close();
    38     }
    39 
    40     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
    41         throws Exception
    42     {
    43         ctx.close();
    44     }
    45 
    46 }
    View Code

    TimeClient

     1 package com.wanghongye.Netty;
     2 
     3 import io.netty.bootstrap.Bootstrap;
     4 import io.netty.channel.ChannelFuture;
     5 import io.netty.channel.ChannelInitializer;
     6 import io.netty.channel.ChannelOption;
     7 import io.netty.channel.EventLoopGroup;
     8 import io.netty.channel.nio.NioEventLoopGroup;
     9 import io.netty.channel.socket.SocketChannel;
    10 import io.netty.channel.socket.nio.NioSocketChannel;
    11 
    12 
    13 
    14 /**
    15  * @Description :netty的客户端
    16  * @author :王红叶
    17  * @date(创建日期):2015年9月22日 下午5:09:54
    18  * @company(公司):深圳市彩讯科技有限公司
    19  * 
    20  * @History(修改历史):
    21  */
    22 public class TimeClient
    23 {
    24     public void connet(int port, String host) throws Exception
    25     {
    26         EventLoopGroup group = new NioEventLoopGroup();
    27         try
    28         {
    29             Bootstrap bootstrap = new Bootstrap();
    30             bootstrap.group(group).channel(NioSocketChannel.class)
    31                 .option(ChannelOption.TCP_NODELAY, true)
    32                 .handler(new ChildChannelHandler());
    33 
    34             ChannelFuture f = bootstrap.connect(host, port).sync();
    35             f.channel().closeFuture().sync();
    36         }
    37         finally 
    38         {
    39             group.shutdownGracefully();
    40         }
    41     }
    42 
    43     private class ChildChannelHandler extends ChannelInitializer<SocketChannel>
    44     {
    45 
    46         @Override
    47         protected void initChannel(SocketChannel arg0) throws Exception
    48         {
    49             arg0.pipeline().addLast(new TimeChannelClientHandler());
    50         }
    51     }
    52 
    53     public static void main(String[] args) throws Exception
    54     {
    55         int port = 8080;
    56         if (args != null && args.length > 0)
    57         {
    58             port = Integer.valueOf(args[0]);
    59         }
    60         new TimeClient().connet(port, "127.0.0.1");
    61     }
    62 }
    View Code

    TimeChannelClientHandler

     1 package com.wanghongye.Netty;
     2 
     3 import io.netty.buffer.ByteBuf;
     4 import io.netty.buffer.Unpooled;
     5 import io.netty.channel.ChannelHandlerAdapter;
     6 import io.netty.channel.ChannelHandlerContext;
     7 
     8 public class TimeChannelClientHandler extends ChannelHandlerAdapter
     9 {
    10     private final ByteBuf buf;
    11 
    12     public TimeChannelClientHandler()
    13     {
    14         byte[] req = "QUERY TIME ORDER".getBytes();
    15         buf = Unpooled.buffer(req.length);
    16         buf.writeBytes(req);
    17     }
    18 
    19     public void channelActive(ChannelHandlerContext ctx)
    20     {
    21         ctx.writeAndFlush(buf);
    22     }
    23 
    24     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
    25     {
    26         ByteBuf byteBuf = (ByteBuf) msg;
    27         byte[] req = new byte[byteBuf.readableBytes()];
    28         byteBuf.readBytes(req);
    29 
    30         String body = new String(req, "UTF-8");
    31         System.out.println("###########" + body);
    32     }
    33 
    34     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
    35         throws Exception
    36     {
    37         ctx.close();
    38     }
    39 }
    View Code

      (NO RUN SUCCESS)

    六、项目中如何使用netty

      在pns(TCP是同步的)和统一配置中使用netty,主要使用了netty的异步和socket。

    七、关于netty的资料

    1. 《netty权威指南》 
    2. http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html
    3. http://www.cnblogs.com/NanguoCoffee/archive/2010/12/10/1902491.html

    八、netty的相关讨论

    1. 为什么说netty是异步的?允许客户端最大的同时连接数:服务器有开放那么多文件句柄数 支持那么多长连接 只要服务器资源够就行,另外tomcat自己也会限制连接数。netty的异步体现在:1、服务端不持有连接,使用的是轮询的方法2、channel通道是异步的3、使用了channel future回调
    2. netty如何编码解码,TCP自带了拆包粘包的功能,netty把他们封装好了,然后处理内容我们需要自己实现
  • 相关阅读:
    #研发中间件介绍#定时任务调度与管理JobCenter
    分享一个分布式定时任务系统 ( python)
    APScheduler + Gearman 构建分布式定时任务调度-std1984-ITPUB博客
    分布式缓存的一起问题 – 后端技术 by Tim Yang
    新兵训练营系列课程——Feed架构介绍
    Mysql分库分表方案
    可扩展性设计之数据切分
    你的数据库数据量上亿,为了提高效率,要分库还是分表?具体怎么做
    58同城mysql分库分表实践-沈剑
    可动态扩展的分库分表策略浅谈
  • 原文地址:https://www.cnblogs.com/wanghongye/p/4809226.html
Copyright © 2011-2022 走看看