netty

作者: 云烟1f3bca320ba6 | 来源:发表于2016-12-21 21:23 被阅读0次

netty

高性能,异步,事件驱动库

Unix io模型

  • 阻塞io
  • 非阻塞io,netty主要就是基于epoll的多路复用技术。
  • io复用模型
  • 信号驱动io模型
  • 异步io

linux io多路复用的调用:select,pselect,poll,epoll

epoll改进

  • 进程打开的socket 描述符(fd)不受限制
  • io效率不会随着fd增加而下降
  • 使用mmap加速内核与用户空间的消息传递
  • api简单

各种io对比


io.png

为什么使用netty

  • java原生nio库难用,netty开发门槛低
  • 功能强大,内置多种编解码功能
  • 稳定,性能强
  • bug少

Example

echo服务器

<dependency>
  <groupId>io.netty</groupId>
  <artifactId>netty</artifactId>
  <version>3.10.6.Final</version>
</dependency>

EchoServer.java

package com.netty;

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

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
import org.jboss.netty.handler.codec.frame.Delimiters;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;

public class EchoServer {
    
    public static void main(String[] args) {
        ServerBootstrap bootstrap = new ServerBootstrap(
                new NioServerSocketChannelFactory(
                        Executors.newCachedThreadPool(),
                        Executors.newCachedThreadPool()));

        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() {
                ChannelPipeline pipeline = Channels.pipeline();
                pipeline.addLast("framer", new DelimiterBasedFrameDecoder(
                                          8192, Delimiters.lineDelimiter()));
                pipeline.addLast("decoder", new StringDecoder());
                pipeline.addLast("encoder", new StringEncoder());
                          
                pipeline.addLast("echo", new EchoServerHandler());
                return pipeline; 
            }
        });
        bootstrap.bind(new InetSocketAddress(8090));
    }
     
}

EchoServerHandler.java

package com.netty;

import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;

public class EchoServerHandler extends SimpleChannelUpstreamHandler {
  
      @Override
      public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
          e.getChannel().write("connect success.");
      }
    
      @Override
      public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
          e.getChannel().write(e.getMessage());
      }
  
      @Override
      public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
          e.getCause().printStackTrace();
          e.getChannel().close();
      }
 }

TCP粘包拆包

发生原因:

  • 应用程序写入的字节大小大于套接字发送缓冲区大小
  • 进行MSS大小的tcp分段
  • 以太网帧的payload大于MTU进行ip分片

解决办法

  • 消息定长
  • 增加特殊字符比如回车换行进行分割,示例中就使用的这种方法
  • 消息头记录长度

编解码技术

  • protobuf
  • Marshalling
  • json,xml 跨语言

参考

http://netty.io/index.html

相关文章

网友评论

      本文标题:netty

      本文链接:https://www.haomeiwen.com/subject/pcfcvttx.html