Netty 是基于 Java NIO 的网络应用框架,Netty是一个NIO client-server(客户端服务器)框架,使用Netty可以快速开发网络应用,例如服务器和客户端协议。Netty提

供了一种新的方式来使开发网络应用程序,这种新的方式使得它很容易使用和有很强的扩展性。Netty的内部实现时很复杂的,但是Netty提供了简单易用的api从网络处理代码中解耦业务逻辑。Netty是完全基于NIO实现的,所以整个Netty都是异步的。

”作为一个NIO client-server框架,Netty提供了这样的一个间接的解决方法。Netty提供了高层次的抽象来简化TCP和UDP服务器的编程,但是你仍然可以使用底层地API。




Netty框架的组成

android netty 后台服务 netty 服务器_android netty 后台服务


Netty除了提供传输和协议,在其他各领域都有发展。Netty为开发者提供了一套完整的工具,看下面表格:

Development Area

Netty Features

Design(设计)

各种传输类型,阻塞和非阻塞套接字统一的API

使用灵活

简单但功能强大的线程模型

无连接的DatagramSocket支持

链逻辑,易于重用

Ease of Use(易于使

用)

提供大量的文档和例子

除了依赖jdk1.6+,没有额外的依赖关系。某些功能依赖jdk1.7+,其他特性可能有相

关依赖,但都是可选的。

Performance(性能)

比Java APIS更好的吞吐量和更低的延迟

因为线程池和重用所有消耗较少的资源

尽量减少不必要的内存拷贝

Robustness(鲁棒性)

鲁棒性,可以理解为健壮性

链接快或慢或超载不会导致更多的OutOfMemoryError

在高速的网络程序中不会有不公平的read/write

Security(安全性)

完整的SSL/TLS和StartTLS支持

可以在如Applet或OSGI这些受限制的环境中运行

Community(社区)

版本发布频繁

社区活跃




整个

Netty 的 API 都是异步的,异步处理不是一个新的机制,这个机制出来已经有一些时间了。对网络应用来说, IO 一般是性

能的瓶颈,使用异步

IO 可以较大程度上提高程序性能,因为异步变的越来越重要。


异步处理提倡更有效的使用资源,它允许你创建一个任务,当有事件发生时将获得通知并等待事件完成。这样就不会阻塞,不管事件完成与否都会及时返回,资源利用率更高,程序可以利用剩余的资源做一些其他的事情。 


NIO是一个比较底层的APIs,它依赖于操作系统的IO APIs。Java实现了统一的接口来操作IO,其在所有操作系统中的工作行为是一样的。使用NIO会经常发现代码在Linux上正常运行,但在Windows上就会出现问题。建议如果使用NIO编写程序,就应该在所有的操作系统上进行测试来支持,使程序可以在任何操作系统上正常运行;即使在所有的Linux系统上都测试通过了,也要在其他的操作系统上进行测试;若不验证,以后就可能会出问题。NIO2看起来很理想,但是NIO2只支持Jdk1.7+,若程序在Java1.6上运行,则无法使用NIO2。另外,Java7的NIO2中没有提供DatagramSocket的支持,所以NIO2只支持TCP程序,不支持UDP程序。Netty提供一个统一的接口,同一语义无论在Java6还是Java7的环境下都是可以运行的,开发者无需关心底层APIs就可以轻松实现相关功能。




java自带的NIO有两个版本,NIO版本1实现了非阻塞功能,JDK7之后出现NIO2,增加了异步功能和一些文件操作的api,但是无论NIO版本1和2都是有缺陷的,比如平台不兼容,ByteBuf扩展性差等,后来就出现了netty,netty对NIO进行了一下封装和优化设计,让我们用它提供的简单api就可以些出性能强大的服务器,但是踪其底层,都是一样的



回调一般是异步处理的一种技术。一个回调是被传递到并且执行完该方法。

代码:

package netty.in.action;    
public class Worker {    
    public void doWork() {  
        Fetcher fetcher = new MyFetcher(new Data(1, 0));  
        fetcher.fetchData(new FetcherCallback() {  
            @Override  
            public void onError(Throwable cause) {  
                System.out.println("An error accour: " + cause.getMessage());  
            }  
  
            @Override  
            public void onData(Data data) {  
                System.out.println("Data received: " + data);  
            }  
        });  
    }  
  
    public static void main(String[] args) {  
        Worker w = new Worker();  
        w.doWork();  
    }  
  
} 

package netty.in.action;  
public interface Fetcher {  
    void fetchData(FetcherCallback callback);  
}

package netty.in.action;  
public class MyFetcher implements Fetcher {  
  
    final Data data;  
  
    public MyFetcher(Data data) {  
        this.data = data;  
    }  
  
    @Override  
    public void fetchData(FetcherCallback callback) {  
        try {  
            callback.onData(data);  
        } catch (Exception e) {  
            callback.onError(e);  
        }  
    }  
}

package netty.in.action;    
public interface FetcherCallback {  
    void onData(Data data) throws Exception;  
  
    void onError(Throwable cause);  
}  
  
package netty.in.action;    
public class Data {  
  
    private int n;  
    private int m;  
  
    public Data(int n, int m) {  
        this.n = n;  
        this.m = m;  
    }  
  
    @Override  
    public String toString() {  
        int r = n / m;  
        return n + "/" + m + " = " + r;  
    }  
}



第二种技术是使用Futures。Futures是一个抽象的概念,它表示一个值,该值可能在某一点变得可用。一个Future要么获得计算完的结果,要么获得计算失败后的异常。Java在java.util.concurrent包中附带了Future接口,它使用Executor异步执行。例如下面的代码,每传递一个Runnable对象到ExecutorService.submit()方法就会得到一个回调Future,能使用它检测是否执行完成。  


代码:


package netty.in.action;

import java.util.concurrent.Callable;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Future;  
 
public class FutureExample {  
    public static void main(String[] args) throws Exception {  
        ExecutorService executor = Executors.newCachedThreadPool();  
        Runnable task1 = new Runnable() {  
               @Override  
               public void run() {  
                   //do something  
                   System.out.println("i am task1.....");  
               }  
        };  
        Callable<Integer> task2 = new Callable<Integer>() {  
               @Override  
               public Integer call() throws Exception {  
                   //do something  
                   return new Integer(100);  
               }  
        };  
       Future<?> f1 = executor.submit(task1);  
       Future<Integer> f2 = executor.submit(task2);  
       System.out.println("task1 is completed? " + f1.isDone());  
       System.out.println("task2 is completed? " + f2.isDone());  
       //waiting task1 completed  
       while(f1.isDone()){  
           System.out.println("task1 completed.");  
           break;  
       }  
       //waiting task2 completed  
       while(f2.isDone()){  
           System.out.println("return value by task2: " + f2.get());  
           break;  
       }  
    }  
}