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,你可以随时跳过本章直接从第二章开始学习。在你的机器上运行第二章编写的Netty服务器和客户端。
Netty是一个NIO client-server(客户端服务器)框架,使用Netty可以快速开发网络应用,例如服务器和客户端协议。Netty提供了一种新的方式来使开发网络应用程序,这种新的方式使得它很容易使用和有很强的扩展性。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 不是所有的网络框架都是一样的
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() {@Overridepublic void onError(Throwable cause) {System.out.println("An error accour: " + cause.getMessage());}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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() {@Overridepublic void run() {//do somethingSystem.out.println("i am task1.....");}};Callable<Integer> task2 = new Callable<Integer>() {@Overridepublic Integer call() throws Exception {//do somethingreturn 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 completedwhile(f1.isDone()){System.out.println("task1 completed.");break;}//waiting task2 completedwhile(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
while (true) {
int selected = selector.select();
Set<SelectedKeys> readyKeys = selector.selectedKeys();
Iterator iterator = readyKeys.iterator();
while (iterator.hasNext()) {
...
...
}
}
...
while (true) {
}
...
1.5 Summary
Netty In Action中文版 - 第一章:Netty介绍相关推荐
- Solr In Action 中文版 第一章(四、五)
1.1 功能概览1. 4 最后,让我们再依照以下的分类.高速的过一下Solr的主要功能: ·用户体验 ·数据建模 ·Solr 4的新功能 在本书中.为你的用户提供良好的搜索体验 ...
- Netty In Action中文版 - 第十二章:SPDY
Netty In Action中文版 - 第十二章:SPDY 本章我将不会直接翻译Netty In Action书中的原文,感觉原书中本章讲的很多废话,我翻译起来也吃力.所以,本章内容我会根据其他资料 ...
- Netty In Action中文版
第一章:Netty介绍 本章介绍 Netty介绍 为什么要使用non-blocking IO(NIO) 阻塞IO(blocking IO)和非阻塞IO(non-blocking IO)对比 Java ...
- Java Persistence with MyBatis 3(中文版) 第一章 MyBatis入门
本章将涵盖以下话题: ž MyBatis是什么? ž 为什么选择MyBatis? ž MyBatis安装配置 ž 域模型样例 1.1 MyBatis是什么 MyBatis是一个简化和实现了Ja ...
- 第一章网络介绍计算题及其解析[计算机网络]
总结一下计算机网络学期课程所学,方便以后的复习和补充. 本文主要是第一章网络介绍计算题部分.需要掌握的知识点如下图. 需要手写记录的笔记pdf和课本pdf可私信. 文章目录 第 ...
- 乐行学院RabbitMQ学习教程 第一章 RabbitMQ介绍(可供技术选型时使用)
乐行学院RabbitMQ学习教程 第一章 RabbitMQ介绍 RabbitMQ介绍 1.RabbitMQ技术简介 2.RabbitMQ其他扩展插件 2.1监控工具rabbitmq-managemen ...
- 第一章 Oracle介绍
Oracle 10.2 概念 第一章 Oracle介绍 1.Oracle介绍 本章提供了针对Oracle数据库服务器的概述,包含以下主题 l Oracle数据库体系结构 l Oracle数据库特点 l ...
- 学神python全栈学习笔记CMDB系统---第一章 python_cmdb_介绍,项目开始
第一章 python_cmdb_介绍,项目开始 本节所讲内容: 1.1 python cmdb系统介绍与需求分析 1.2 python cmdb数据库建模 1.3 python cmdb前端基础 ...
- 第一章, 介绍:挖掘twitter的数据
mahout_xb的专栏 http://blog.csdn.net/mahout_xb/article/details/7341477 第一章, 介绍:挖掘twitter的数据 分类: data mi ...
- 《Netty 实战》Netty In Action中文版 第2章——你的第一款Netty应用程序(一)
第2章 你的第一款Netty应用程序 本章主要内容 设置开发环境 编写Echo服务器和客户端 构建并测试应用程序 在本章中,我们将展示如何构建一个基于Netty的客户端和服务器.应用程序很简单:客户端 ...
最新文章
- CVPR2021直播|点云补全的方法梳理及最新进展分享
- Visual Studio 2017 图文安装流程
- (1) ebj学习:基本概念
- DAY5-小别-2018-1-15
- 服务器被攻击怎么修改,服务器一直被攻击怎么办?
- layui自定义ajax左侧三级菜单
- spring mvc中的拦截器
- [UI]实用案例--Shape绘制实用圆圈
- 160508Junit使用
- python测试脚本 进制转换_[python] 转换python脚本程序为二进制ELF
- linux设置定时关机命令,linux定时关机命令是什么?
- Mysql主从同步及主从同步延迟解决方案
- Phpstudy简介与使用教程
- WinDynamicDesktop下载慢解决方法
- ReentrantLock使用及其原理解析
- 树莓派系统安装和环境配置
- IM即时通讯-项目框架搭建(二)
- SMAA算法详解 - SearchTex
- java安装好了打不开机_Java安装以后为什么打不开?java打不开一闪而过如何解决?...
- R语言使用na.omit函数删除向量数据中的缺失值(NA值)