java分布式系统通信框架

1.Jboss Netty项目-优秀的NIO框架
下载 http://www.jboss.org/netty/downloads.html
简介 http://www.jboss.org/netty
Jboss的Netty项目旨在提供异步驱动的网络应用程序的框架和工具, 可以用于快速开发, 可方便维护的、高性能的、高扩展性的服务器/客户端之间的通迅协议。
Plurk是一个快速成长,并且已经成为互联网上最大的几个使用python语言的网站之之一,Plurk尝试了以下一些框架/web容器:
Python Twisted:太耗资源了
Jetty:iGoogle的web容器,可惜一万并发的时候用了2G的内存
Apache Tomcat:太吃内存了
Apache MINA:文档很糟糕,可扩展性很差
最后,Plurk发现Netty非常优秀, 在一台四核的服务器上,10万的并发只用了some GB的内存和20%左右的CPU
JBoss社区最近发布了Netty 3.1.0,为用户提供了编写客户/服务网络应用的另一选择。Netty自称是:

    一款异步的事件驱动的网络应用框架和工具,用于快速开发可维护的高性能、高扩展性协议服务器和客户端。也就是说,Netty是一个NIO客户端/服务器框架,支持快速、简单地开发网络应用,如协议服务器和客户端。它极大简化了网络编程,如TCP和UDP套接字服务器。

关于Netty的分类,它与Apache Mina和Grizzly属于同一舞台。该最新版本包含了一系列功能和性能、API可用性的增强。其中包括:

    * 更简单的大数据流(例子)
    * 更多可靠的OutOfMemoryError预防机制
    * 新的传输
          o 基于OIO和NIO的UDP传输
          o VM内传输
          o HTTP隧道
    * 与Google Protocol Buffers集成
    * 与JBoss Microcontainer、OSGI、Guice和Spring集成

HTTP隧道功能满足了用户的迫切需求,在早期发布说明中总结到:

    HTTP隧道传输(位于org.jboss.netty.channel.socket.http)是一种套接字传输,支持任意已经存在的套接字应用在HTTP之上通过代理传输。这种传输在需要越过防火墙而不修改现存服务器应用时特别有用。工作原理如下:

    Http隧道客户端套接字通道 --> 对HTTP友好的防火墙 --> Servlet容器 (如Tomcat、Jetty) --> Http隧道Servlet --> 你的服务器应用

当然在选择一个框架用于开发网络应用时,性能和可扩展性是重要因素。Netty团队在他们的网站上提供了性能信息。你也可以在Apache Mina网站上找到它的性能数据。Nicholas Hagen发布了一系列博文,记录了他如何选择 Mina、Grizzly或者Netty。最终他决定选用Netty,不过指出:

    总的来说,在性能、内存和功能使用方面,我倾向于Netty,而不是Mina和Grizzly。请注意你需要通过自己的分析来决定哪种框架适合你的需求。

Netty下一版本3.2.0,目前正在开发过程中。

JBoss社区最近发布了Netty 3.1.0,为用户提供了编写客户/服务网络应用的另一选择。Netty自称是:

    一款异步的事件驱动的网络应用框架和工具,用于快速开发可维护的高性能、高扩展性协议服务器和客户端。也就是说,Netty是一个NIO客户端/服务器框架,支持快速、简单地开发网络应用,如协议服务器和客户端。它极大简化了网络编程,如TCP和UDP套接字服务器。

关于Netty的分类,它与Apache Mina和Grizzly属于同一舞台。该最新版本包含了一系列功能和性能、API可用性的增强。其中包括:

    * 更简单的大数据流(例子)
    * 更多可靠的OutOfMemoryError预防机制
    * 新的传输
          o 基于OIO和NIO的UDP传输
          o VM内传输
          o HTTP隧道
    * 与Google Protocol Buffers集成
    * 与JBoss Microcontainer、OSGI、Guice和Spring集成

HTTP隧道功能满足了用户的迫切需求,在早期发布说明中总结到:

    HTTP隧道传输(位于org.jboss.netty.channel.socket.http)是一种套接字传输,支持任意已经存在的套接字应用在HTTP之上通过代理传输。这种传输在需要越过防火墙而不修改现存服务器应用时特别有用。工作原理如下:

    Http隧道客户端套接字通道 --> 对HTTP友好的防火墙 --> Servlet容器 (如Tomcat、Jetty) --> Http隧道Servlet --> 你的服务器应用

当然在选择一个框架用于开发网络应用时,性能和可扩展性是重要因素。Netty团队在他们的网站上提供了性能信息。你也可以在Apache Mina网站上找到它的性能数据。Nicholas Hagen发布了一系列博文,记录了他如何选择 Mina、Grizzly或者Netty。最终他决定选用Netty,不过指出:

    总的来说,在性能、内存和功能使用方面,我倾向于Netty,而不是Mina和Grizzly。请注意你需要通过自己的分析来决定哪种框架适合你的需求。

Netty下一版本3.2.0,目前正在开发过程中,路线图可以在这里查看。


此版本的主要更新:
处理大容量数据流更简单
处理协议编码和单元测试更简单
I/O超时和idle状态检测
应用程序的关闭更简单,更安全
更可靠的OutOfMemoryError预防
新的传输方式:
   1.基于OIO和NIO的UDP传输
  2.本地传输(又名 in-VM传输)
  3.HTTP通道,可绕过防火墙
新的编码器:
   1.HTTP客户端和服务器端
   2.用于实现各种专有协议的工具
与其他技术的整合:
   1.Google Protocol Buffers
   2.JBoss Microcontainer, OSGi, Guice以及Spring



package example.helloword.server;

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

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;

import example.helloword.NetConstant;

public class Server
{
    private static Server server = new Server();
    
    private ServerBootstrap bootstrap;
    
    private Server()
    {}
    
    public static Server getInstance()
    {
        return server;
    }
    
    public void start()
    {
        bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(
                Executors.newCachedThreadPool(), Executors
                        .newCachedThreadPool()));
        bootstrap.setPipelineFactory(new ServerPipelineFactory());
        bootstrap.bind(new InetSocketAddress(NetConstant.server_port));
    }
    
    public void stop()
    {
        bootstrap.releaseExternalResources();
    }
    
    public static void main(String[] args)
    {
        Server server = Server.getInstance();
        server.start();
    }
}
package example.helloword.server;

import static org.jboss.netty.channel.Channels.pipeline;

import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;

public class ServerPipelineFactory implements ChannelPipelineFactory
{
    public ChannelPipeline getPipeline() throws Exception
    {
        ChannelPipeline pipleline = pipeline();
        pipleline.addLast("encode", new StringEncoder());
        pipleline.addLast("decode", new StringDecoder());
        pipleline.addLast("handler", new ServerHandler());
        return pipleline;
    }
}
package example.helloword.server;

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

public class ServerHandler extends SimpleChannelUpstreamHandler
{
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
            throws Exception
    {
        System.out.println("recive message,message content:" + e.getMessage());
        e.getChannel().write("byte");
        
    }
    
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
            throws Exception
    {
        e.getChannel().close();
    }
}
package example.helloword.client22;

import static org.jboss.netty.channel.Channels.pipeline;

import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;
import org.jboss.netty.handler.codec.frame.LengthFieldPrepender;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;

public class ClientPipelineFactory implements ChannelPipelineFactory
{
    public ChannelPipeline getPipeline() throws Exception
    {
        ChannelPipeline pipleline = pipeline();  
        pipleline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));  
        pipleline.addLast("frameEncode", new LengthFieldPrepender(4, false));
        pipleline.addLast("encode", new StringEncoder());  
        pipleline.addLast("decode", new StringDecoder());  
        pipleline.addLast("handler", new ClinetHandler());  
        return pipleline;  
    }
}
package example.helloword.client22;

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

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;

import example.helloword.NetConstant;
import example.helloword.client2.ClientPipelineFactory;

public class ClientPool
{
    public static ClientPool clientPool = new ClientPool();
    
    private ClientBootstrap bootstrap;
    
    private ClientPool()
    {
        bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(
                Executors.newCachedThreadPool(), Executors
                        .newCachedThreadPool()));
        
        bootstrap.setPipelineFactory(new ClientPipelineFactory());
        bootstrap.setOption("tcpNoDelay", true);
        bootstrap.setOption("keepAlive", true);
    }
    
    public static ClientPool getInstance()
    {
        return clientPool;
    }
    
    public void getChannelFuture(String host, int port, String message)
    {
        ChannelFuture future = bootstrap.connect(new InetSocketAddress(host,
                NetConstant.server_port));
        future.awaitUninterruptibly();
        if (!future.isSuccess())
        {
            future.getCause().printStackTrace();
            future.getChannel().getCloseFuture().awaitUninterruptibly(); 
            return;
        }
        future.getChannel().write(message);
    }
    
    public static void main(String[] args) throws InterruptedException
    {
        for (int i = 0; i < 1000; i++)
        {
            ClientPool.getInstance().getChannelFuture("127.0.0.1", 0,
                    "test" + i);
            Thread.sleep(1000 * 3);
        }
    }
}

2、apache mina
下载 http://mina.apache.org/downloads.html
public class Test {
	public static void main(String[] args) throws IOException {
		HttpServer httpServer;
		httpServer = HttpServer.create(new InetSocketAddress(81), 5);
		httpServer.createContext("/", new Handler());
		httpServer.start();
	}

	static class Handler implements HttpHandler {
		public void handle(HttpExchange exchange) throws IOException {
			Headers requestHeaders = exchange.getRequestHeaders();
			Headers responseHeaders = exchange.getResponseHeaders();
			responseHeaders.set("Content-Type", "text/plain");
			exchange.sendResponseHeaders(200, 0L);
			OutputStream responseBody = new BufferedOutputStream(exchange.getResponseBody(), 64*1024);
			responseBody.write("Hello!".getBytes());
			responseBody.close();
			exchange.close();
		}
	}
}
import java.net.InetSocketAddress;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.example.echoserver.ssl.BogusSslContextFactory;
import org.apache.mina.filter.ssl.SslFilter;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

/**
 * (<b>Entry point</b>) Echo server
 *
 * @author The Apache MINA Project ([email protected])
 * @version $Rev: 677923 $, $Date: 2008-07-18 16:55:24 +0200 (Fri, 18 Jul 2008) $
 */
public class Main {
    /** Choose your favorite port number. */
    private static final int PORT = 8080;

    /** Set this to true if you want to make the server SSL */
    private static final boolean USE_SSL = false;

    public static void main(String[] args) throws Exception {
        SocketAcceptor acceptor = new NioSocketAcceptor();
        DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
        

        // Bind
        acceptor.setHandler(new EchoProtocolHandler());
        acceptor.bind(new InetSocketAddress(PORT));

        System.out.println("Listening on port " + PORT);
        
        for (;;) {
            System.out.println("R: " + acceptor.getStatistics().getReadBytesThroughput() + 
                ", W: " + acceptor.getStatistics().getWrittenBytesThroughput());
            Thread.sleep(3000);
        }
    }

 }
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.ssl.SslFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * {@link IoHandler} implementation for echo server.
 *
 * @author The Apache MINA Project ([email protected])
 * @version $Rev: 713957 $, $Date: 2008-11-14 10:27:16 +0100 (Fri, 14 Nov 2008) $,
 */
public class EchoProtocolHandler extends IoHandlerAdapter {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    
    @Override
    public void sessionCreated(IoSession session) {
        session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);

        // We're going to use SSL negotiation notification.
        session.setAttribute(SslFilter.USE_NOTIFICATION);
    }

    @Override
    public void sessionClosed(IoSession session) throws Exception {
        logger.info("CLOSED");
    }

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        logger.info("OPENED");
    }

    @Override
    public void sessionIdle(IoSession session, IdleStatus status) {
        logger.info("*** IDLE #" + session.getIdleCount(IdleStatus.BOTH_IDLE) + " ***");
    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause) {
        session.close(true);
    }

    @Override
    public void messageReceived(IoSession session, Object message)
            throws Exception {
        // Write the received data back to remote peer
        session.write(((IoBuffer) message).duplicate());
    }
}
public class Test {
	public static void main(String[] args) throws IOException {
		HttpServer httpServer;
		httpServer = HttpServer.create(new InetSocketAddress(81), 5);
		httpServer.createContext("/", new Handler());
		httpServer.start();
	}

	static class Handler implements HttpHandler {
		public void handle(HttpExchange exchange) throws IOException {
			Headers requestHeaders = exchange.getRequestHeaders();
			Headers responseHeaders = exchange.getResponseHeaders();
			responseHeaders.set("Content-Type", "text/plain");
			exchange.sendResponseHeaders(200, 0L);
			OutputStream responseBody = new BufferedOutputStream(exchange.getResponseBody(), 64*1024);
			responseBody.write("Hello!".getBytes());
			responseBody.close();
			exchange.close();
		}
	}
}

猜你喜欢

转载自itjiehun.iteye.com/blog/1165630