Netty In Action中文版 - 第一章:Netty介绍
本章介绍
- Netty介绍
- 为什么要使用non-blocking IO(NIO)
- 堵塞IO(blocking IO)和非堵塞IO(non-blocking IO)对照
- Java NIO的问题和在Netty中的解决方式
Netty是基于Java NIO的网络应用框架,假设你是Java网络方面的新手,那么本章将是你学习Java网络应用的開始;对于有经验的开发人员来说,学习本章内容也是非常好的复习。假设你熟悉NIO和NIO2,你能够随时跳过本章直接从第二章開始学习。在你的机器上执行第二章编写的Nettyserver和client。
Netty是一个NIO client-server(clientserver)框架,使用Netty能够高速开发网络应用,比如server和client协议。Netty提供了一种新的方式来使开发网络应用程序,这样的新的方式使得它非常easy使用和有非常强的扩展性。Netty的内部实现时非常复杂的,可是Netty提供了简单易用的api从网络处理代码中解耦业务逻辑。Netty是全然基于NIO实现的,所以整个Netty都是异步的。
网络应用程序通常须要有较高的可扩展性,不管是Netty还是其它的基于Java NIO的框架,都会提供可扩展性的解决方式。Netty中一个关键组成部分是它的异步特性,本章将讨论同步(堵塞)和异步(非堵塞)的IO来说明为什么使用异步代码来解决扩展性问题以及怎样使用异步。
对于那些初学网络变成的读者,本章将帮助您对网络应用的理解,以及Netty是怎样实现他们的。它说明了怎样使用主要的Java网络API,探讨Java网络API的长处和缺点并阐述Netty是怎样解决Java中的问题的,比方Eploo错误或内存泄露问题。
在本章的结尾,你会明确什么是Netty以及Netty提供了什么,你会理解Java NIO和异步处理机制,并通过本书的其它章节加强理解。
1.1 为什么使用Netty?
1.1.1 不是全部的网络框架都是一样的
Choice Award(Duke's Choice奖)。
1.1.2 Netty的功能很丰富
Development Area | Netty Features |
Design(设计) |
|
Ease of Use(易于使用) |
|
Performance(性能) |
|
Robustness(鲁棒性) | 鲁棒性,能够理解为健壮性
|
Security(安全性) |
|
Community(社区) |
|
除了列出的功能外,Netty为Java NIO中的bug和限制也提供了解决方式。我们须要深刻理解Netty的功能以及它的异步处理机制和它的架构。NIO和Netty都大量使用了异步代码,而且封装的非常好,我们无需了解底层的事件选择机制。以下我们来看看为什么须要异步APIS。
1.2 异步设计
1.2.1 Callbacks(回调)
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;
}
}
上面的样例仅仅是一个简单的模拟回调,要明确其所表达的含义。Fetcher.fetchData()方法需传递一个FetcherCallback类型的參数,当获得数据或错误发生时被回调。对于每种情况都提供了允许的方法:
- FetcherCallback.onData(),将接收数据时被调用
- FetcherCallback.onError(),错误发生时被调用
由于能够将这些方法的运行从"caller"线程移动到其它的线程运行;但也不会保证FetcherCallback的每一个方法都会被运行。回调过程有个问题就是当你使用链式调用
非常多不同的方法会导致线性代码;有些人觉得这样的链式调用方法会导致代码难以阅读,可是我觉得这是一种风格和习惯问题。比如,基于Javascript的Node.js越来越受欢迎,它使用了大量的回调,很多人都觉得它的这样的方式利于阅读和编写。
1.2.2 Futures
另外一种技术是使用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;
}
} }
有时候使用Future感觉非常丑陋,由于你须要间隔检查Future是否已完毕,而使用回调会直接收到返回通知。看完这两个经常使用的异步运行技术后,你可能想知道使用哪个最好?这里没有明白的答案。其实,Netty两者都使用,提供两全其美的方案。下一节将在JVM上首先使用堵塞,然后再使用NIO和NIO2写一个网络程序。这些是本书兴许章节不可缺少的基础知识,假设你熟悉Java网络AIPs,你能够高速翻阅就可以。
1.3 Java中的Blocking和non-blocking IO对照
本节主要解说Java的IO和NIO的差异,这里只是多赘述,网络已有非常多相关文章。
1.4 NIO的问题和Netty中是怎样解决这些问题的
1.4.1 跨平台和兼容性问题
1.4.2 扩展ByteBuffer
1.4.3 NIO对缓冲区的聚合和分散操作可能会操作内存泄露
1.4.4 Squashing the famous epoll bug
even today the "famous" epoll- bug can lead to an "invalid" state in the selector, resulting in 100% CPU-usage and spinning. The only way to recover is to recycle the old selector and transfer the previously registered Channel instances to
the newly created Selector.
which is in the Javadocs of the Selector.select() method:Selector.select() must not unblock if nothing is selected.
while (true) {
int selected = selector.select();
Set<SelectedKeys> readyKeys = selector.selectedKeys();
Iterator iterator = readyKeys.iterator();
while (iterator.hasNext()) {
...
...
}
}
...
while (true) {
}
...
work.
Netty addresses them for you.
1.5 Summary
of the reasons to use a non-blocking framework. You learned how to use the JDK API to write network code in both blocking and non-blocking modes. This included the new non-blocking API, which comes with JDK 7. After seeing the NIO APIs in action,
it was also important to understand some of the known issues that you may run into. In fact, this is why so many people use Netty: to take care of workarounds and other JVM quirks. In the next chapter, you'll learn the basics of the Netty API and programming
model, and, finally, use Netty to write some useful code.
Netty In Action中文版 - 第一章:Netty介绍的更多相关文章
- Solr In Action 中文版 第一章(四、五)
1.1 功能概览1. 4 最后,让我们再依照以下的分类.高速的过一下Solr的主要功能: ·用户体验 ·数据建模 ·Solr 4的新功能 在本书中.为你的用户提供良好的搜索体验 ...
- Solr In Action 中文版 第一章(三)
3.1 为什么选用Solr? 在本节中.我们希望能够提供一些关键信息来帮助于你推断Solr是否是贵公司技术方案的正确选择.我们先从Solr吸引软件架构师的方面说起. 3.1 ...
- 《Getting Started with WebRTC》第一章 WebRTC介绍
<Getting Started with WebRTC>第一章 WebRTC介绍 本章是对WebRTC做概念性的介绍. 阅读完本章后.你将对下面方面有一个清晰的理解: . 什么 ...
- Java Persistence with MyBatis 3(中文版) 第一章 MyBatis入门
本章将涵盖以下话题: ž MyBatis是什么? ž 为什么选择MyBatis? ž MyBatis安装配置 ž 域模型样例 1.1 MyBatis是什么 MyBatis是一个简化和实现了Ja ...
- Netty In Action中文版 - 第五章:Buffers(缓冲)
本章介绍 ByteBuf ByteBufHolder ByteBufAllocator 使用这些接口分配缓冲和运行操作 每当你须要数据传输时,它必须包括一个缓冲区.Java NIO API自带的缓冲区 ...
- Netty In Action中文版 - 第六章:ChannelHandler
本章介绍 ChannelPipeline ChannelHandlerContext ChannelHandler Inbound vs outbound(入站和出站) 接受连接或创建他们仅仅是你的应 ...
- Netty In Action中文版 - 第四章:Transports(传输)
本章内容 Transports(传输) NIO(non-blocking IO,New IO), OIO(Old IO,blocking IO), Local(本地), Embedded(嵌入式) U ...
- Netty In Action中文版 - 第七章:编解码器Codec
http://blog.csdn.net/abc_key/article/details/38041143 本章介绍 Codec,编解码器 Decoder,解码器 Encoder,编码器 Netty提 ...
- Akka in action (第一章 介绍Akka)
在本章 概述Akka 了解Actors和Actor系统 Akka的适用范围 在第一章中,会介绍给你Akk的个方面,它能做什么,与现有的解决方案有那些不同.重点关注Akka有哪些功能和使用范围和强大的并 ...
随机推荐
- java的提取与替换操作
public class Demo02 { public static void main(String args[]){ String str = "java 技术学习班 2007032 ...
- Linux进程同步之记录锁(fcntl)
记录锁相当于线程同步中读写锁的一种扩展类型,可以用来对有亲缘或无亲缘关系的进程进行文件读与写的同步,通过fcntl函数来执行上锁操作.尽管读写锁也可以通过在共享内存区来进行进程的同步,但是fcntl记 ...
- Linux查看进程线程个数
1.根据进程号进行查询: # pstree -p 进程号 # top -Hp 进程号 2.根据进程名字进行查询: # pstree -p `ps -e | grep server | awk '{pr ...
- codeforces 459D - Pashmak and Parmida's problem【离散化+处理+逆序对】
题目:codeforces 459D - Pashmak and Parmida's problem 题意:给出n个数ai.然后定义f(l, r, x) 为ak = x,且l<=k<=r, ...
- Windows Phone开发(31):画刷
原文:Windows Phone开发(31):画刷 画刷是啥玩意儿?哈,其实画刷是用来涂鸦,真的,没骗你,至于你信不信,反正我信了. 本文通过价绍几个典型的画刷,使你明白画刷就是用来涂鸦的. 一.纯色 ...
- windows下cocos2dx3.0开发环境及Android编译环境搭建
cocos2dx更新到了3.x版本号,自己一直没有换,如今开发组要求统一换版本号,我就把搭建好开发环境的过程记录下来. 一.Windowns下开发环境搭建 1. 所需工具 1)coc ...
- 使用NaturalDuration获取音频的时长
#region customizeTime ) sec = " + mediaElement.Position.Seconds.ToString(); else sec = mediaEle ...
- UltraEdit-32 温馨提示:右协会,取消 bak文件
1.最近安装UltraEdit-32 无权协会,能够 高级 ->组态 ->文件关联 在 检查 继承到资源管理器 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkb ...
- accept功能
accept()功能 系统调用 accept() 这将是一个有点陌生的地方! 你可以想象发生 这种事情:这是非常远离你通过倾听 (listen()) 的port连接 (connect()) 你的机器. ...
- mediator pattern
20.4 中介者模式总结 中介者模式将一个网状的系统结构变成一个以中介者对象为中心的星形结构,在这个星型结构中,使用中介者对象与其他对象的一对多关系来取代原有对象之间的多对多关系.中介者模式在事件驱动 ...