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有哪些功能和使用范围和强大的并 ...
随机推荐
- SE 2014年5月23日
两站点 A 和 B,由于业务往来需要,所以工程师提出vpn技术,同时需要保证业务流在internet上的安全性,同时在这里站点均为固定ip地址. 通过分析以上信息,确定这里使用 IPSec VPN的主 ...
- Ubuntu 使用中的问题总结
1.ibus输入法图标消失 #ibus-daemon -d 2.Ubuntu没有声音 #alsamixer 3.“对不起,ubuntu出现了内部错误” # nano /etc/default/appo ...
- 【c语言】模拟库函数strstr
// 模拟库函数strstr #include <stdio.h> #include <assert.h> const char* my_strstr(const char * ...
- iosclient暑期“动画屋“活动项目总结
入职实习的这个公司,第一天就分配了任务.从零開始写一个网页.之前尽管了解一些前端知识.但从头开写还是遇到了非常多问题,互联网公司讲求效率,有deadline还是比較有紧迫感的,与在实验室放羊状 ...
- MySQL命令行数据操作使用心得(总结版)
Char 0~255 Varchar 0~65535 text 0~65535(只能保存字符) Longtext 0~4294967295(只能保存字符) CMD登陆mysql mysql -u ro ...
- SVN 右下角各种符号
黄色感叹号(有冲突): --这是有冲突了,冲突就是说你对某个文件进行了修改,别人也对这个文件进行了修改,别人抢在你提交之前先提交了,这时你再提交就会被提示发生冲突,而不 允许你提交,防止你的提交覆盖了 ...
- 如何检测被锁住的Oracle存储过程及处理办法汇总(转)
1.查看是哪一个存储过程被锁住查V$DB_OBJECT_CACHE视图select * from V$DB_OBJECT_CACHE where owner='过程的所属用户' AND LOCKS!= ...
- oracle spfile和pfile文件(转)
--======================== -->Oracle 参数文件 --======================== /* 参数文件(10g中的参数文件) 主要用来记录数据库 ...
- Quasi-Newton Method--LBFGS
Quasi-Newton Method Quasi-Newton Method每一步计算过程中仅涉及到函数值和函数梯度值计算,这样有效避免了Newton Method中涉及到的Hessian矩阵计算问 ...
- webservice一片:其中在外线呼叫数据,查看返回数据
经Android数据被访问,返回的数据(json格公式,object数据类型:strJson) 业务需求:经webservice调用外部暴露数据并返回json数据序列化.阅读到数据库表:[SQ_Eve ...