netty学习04
来源:互联网 发布:淘宝扣24分怎么办 编辑:程序博客网 时间:2024/06/05 16:21
1.网络服务一般的结构:
读取请求--->解码请求--->处理服务--->编码响应--->发送响应
经典的服务设计是“每一个请求一个线程”,如下图
2.Reactor模式
Reactor响应I/O事件,分发到合适的Handler处理。
Handler执行非阻塞的动作。
基本的Reactor设计,单线程版本
示例代码:
- package com.zhang.nio;
- import java.io.IOException;
- import java.net.InetSocketAddress;
- import java.nio.channels.SelectionKey;
- import java.nio.channels.Selector;
- import java.nio.channels.ServerSocketChannel;
- import java.nio.channels.SocketChannel;
- import java.util.Set;
- public class Reactor implements Runnable {
- final Selector selector;
- final ServerSocketChannel serverSocketChannel;
- public Reactor(int port) throws IOException {
- selector = Selector.open();
- serverSocketChannel = ServerSocketChannel.open();
- serverSocketChannel.socket().bind(new InetSocketAddress(port));
- serverSocketChannel.configureBlocking(false);
- SelectionKey key = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
- key.attach(new Acceptor());
- }
- @Override
- public void run() {
- while (!Thread.interrupted()) {
- try {
- selector.select();
- Set<SelectionKey> selectionKeys = selector.selectedKeys();
- for(SelectionKey selectionKey : selectionKeys){
- dispatch(selectionKey);
- }
- selectionKeys.clear();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- private void dispatch(SelectionKey selectionKey) {
- Runnable run = (Runnable) selectionKey.attachment();
- if(run != null){
- run.run();
- }
- }
- class Acceptor implements Runnable{
- @Override
- public void run() {
- try {
- SocketChannel channel = serverSocketChannel.accept();
- if(channel != null){
- new Handler(selector,channel);
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- import java.io.IOException;
- import java.nio.ByteBuffer;
- import java.nio.channels.SelectionKey;
- import java.nio.channels.Selector;
- import java.nio.channels.SocketChannel;
- public class Handler implements Runnable {
- private final static int DEFAULT_SIZE = 8092;
- private final SocketChannel socketChannel;
- private final SelectionKey seletionKey;
- private static final int READING = 0;
- private static final int SENDING = 1;
- private int state = READING;
- ByteBuffer inputBuffer = ByteBuffer.allocate(DEFAULT_SIZE);
- ByteBuffer outputBuffer = ByteBuffer.allocate(DEFAULT_SIZE);
- public Handler(Selector selector, SocketChannel channel) throws IOException {
- this.socketChannel = channel;
- socketChannel.configureBlocking(false);
- this.seletionKey = socketChannel.register(selector, 0);
- seletionKey.attach(this);
- seletionKey.interestOps(SelectionKey.OP_READ);
- selector.wakeup();
- }
- @Override
- public void run() {
- if(state == READING){
- read();
- }else if(state == SENDING){
- write();
- }
- }
- class Sender implements Runnable {
- @Override
- public void run() {
- try {
- socketChannel.write(outputBuffer);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- if(outIsComplete()){
- seletionKey.cancel();
- }
- }
- }
- private void write() {
- try {
- socketChannel.write(outputBuffer);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- while(outIsComplete()){
- seletionKey.cancel();
- }
- }
- private void read() {
- try {
- socketChannel.read(inputBuffer);
- if(inputIsComplete()){
- process();
- seletionKey.attach(new Sender());
- seletionKey.interestOps(SelectionKey.OP_WRITE);
- seletionKey.selector().wakeup();
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- public boolean inputIsComplete(){
- return false;
- }
- public boolean outIsComplete(){
- return false;
- }
- public void process(){
- }
- }
NIO支持的特性:
- Channels,连接到文件、socket等等,支持非阻塞读。
- Buffers,与数组相似的对象,能直接从Channels中读写。
- Selectors,辨识哪一个通道的集合有IO事件。(Tell which of a set of Channels have IO events)
- SelectionKeys,维护IO事件的状态和绑定。
多线程设计
- 添加线程增加可扩展性,主要应用在多核处理器中
- Worker 线程,Reactors要快速出发handlers。handlers的处理降低了Reactor的速度。将非I/O操作分离到其他线程中处理。
- Multiple Reactor Threads,多Reactor线程。Reactor线程可以使IO操作饱和,分布负载到其他的reactors,负载均衡来匹配CPU和IO之间的速度差异。
使用多个Reactors
文章转自:http://ryanflyer.iteye.com/blog/1672876
0 0
- netty学习04
- Netty学习-04-AIO
- Netty学习-05-Netty
- Netty----什么是Netty学习
- netty学习
- Netty学习
- Netty学习
- Netty学习
- Netty学习
- netty 学习
- netty学习
- Netty学习
- Netty学习
- Netty学习 netty nio编程
- 【Netty】netty学习笔记一
- Netty自学-Netty学习(一)
- Netty 学习(5) Netty Example--echo
- Netty 学习(8)Netty Example Telnet
- Java NIO系列教程(八) SocketChannel
- 二分查找树
- HDU 2795单点线段树第二日练手
- 解决多工程maven项目启动出现permgen space问题
- SSH连接时报错警告消息:Reverse Mapping Checking – Possible Break-in Attempt Error with SSH
- netty学习04
- Java Bean以及xsd相互生成
- 平衡二叉树
- Java NIO系列教程(九) ServerSocketChannel
- ubuntu下搭建android开发环境
- hdu5695 Gym Class(拓扑排序+优先)
- IOS开发,常用快捷键汇总
- Lovely Palindromes
- [BZOJ 1028] [纪中3066] 麻将 水暴力