apache MINA 源码级分析-[壹]

如果对MINA不了解请看

http://rrsy23.iteye.com/blog/422589

http://www.ibm.com/developerworks/cn/opensource/os-cn-apmina/

 

我们首先看一个MINA最简单的服务器代码 如下

package org.apache.mina.example.echoserver;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.example.echoserver.ssl.BogusSslContextFactory;
import org.apache.mina.filter.ssl.SslFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class Main {
    public static void main(String[] args) throws Exception {
        SocketAcceptor acceptor = new NioSocketAcceptor();
        acceptor.setReuseAddress(true);
        DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();

        chain.addLast("logger", new LoggingFilter());
        //这里是演示所以是单线程,实际是new ProtocolCodecFilter(new ImageCodecFactory(false))
        // chain.addLast("threadPool", new ExecutorFilter(Executors.newSingleThreadExecutor()));
        // Bind
        acceptor.setHandler(new EchoProtocolHandler());
        acceptor.bind(new InetSocketAddress(8080));
        System.out.println("Listening on port " + 8080);


    }

 

我们执行这段代码,然后用telnet连接看看 情况如何?

 

org.apache.mina.example.echoserver.Main
size is 3
[15:26:38] INFO [org.apache.mina.transport.socket.nio.NioSocketAcceptor] - init prepare Selector.open() Thread info--> main

Listening on port 8080

[15:26:41] INFO [org.apache.mina.transport.socket.nio.NioSocketAcceptor] - accept an client connection thread info-->NioSocketAcceptor-1
[15:26:41] INFO [org.apache.mina.filter.logging.LoggingFilter] - OPENEDThread info--> NioProcessor-1 nextFilter is class org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1
[15:26:41] INFO [org.apache.mina.example.echoserver.EchoProtocolHandler] - OPENED Thread info--> NioProcessor-1
[15:26:43] INFO [org.apache.mina.transport.socket.nio.NioSocketAcceptor] - accept an client connection thread info-->NioSocketAcceptor-1
[15:26:43] INFO [org.apache.mina.filter.logging.LoggingFilter] - OPENEDThread info--> NioProcessor-2 nextFilter is class org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1
[15:26:43] INFO [org.apache.mina.example.echoserver.EchoProtocolHandler] - OPENED Thread info--> NioProcessor-2
[15:26:45] INFO [org.apache.mina.transport.socket.nio.NioSocketAcceptor] - accept an client connection thread info-->NioSocketAcceptor-1
[15:26:45] INFO [org.apache.mina.filter.logging.LoggingFilter] - OPENEDThread info--> NioProcessor-3 nextFilter is class org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1
[15:26:45] INFO [org.apache.mina.example.echoserver.EchoProtocolHandler] - OPENED Thread info--> NioProcessor-3
[15:26:50] INFO [org.apache.mina.transport.socket.nio.NioSocketAcceptor] - accept an client connection thread info-->NioSocketAcceptor-1
[15:27:01] INFO [org.apache.mina.example.echoserver.EchoProtocolHandler] - --sleeping wake up 20 seconds---
[15:27:01] INFO [org.apache.mina.filter.logging.LoggingFilter] - OPENEDThread info--> NioProcessor-1 nextFilter is class org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1
[15:27:01] INFO [org.apache.mina.example.echoserver.EchoProtocolHandler] - OPENED Thread info--> NioProcessor-1
[15:27:03] INFO [org.apache.mina.example.echoserver.EchoProtocolHandler] - --sleeping wake up 20 seconds---
[15:27:05] INFO [org.apache.mina.example.echoserver.EchoProtocolHandler] - --sleeping wake up 20 seconds---

 

以上是执行的日志信息[本人在源代码增加了日志,mina的日志真是差啊]

 

下面我们分析哈日志看看问题:

 首先我们看到2中类型的线程池

   一:NioSocketAcceptor

   二:NioProcessor

每次客户端连接 服务器都是NioSocketAcceptor接受请求转给NioProcessor

 第一次连接NioProcessor-1 执行LoggingFilter在执行EchoProtocolHandler[这里线程我让他sleep 20秒]

 第二次连接NioProcessor-2 执行LoggingFilter在执行EchoProtocolHandler[这里线程我让他sleep 20秒]

 第三次连接NioProcessor-3 执行LoggingFilter在执行EchoProtocolHandler[这里线程我让他sleep 20秒]

 第四次连接NioSocketAcceptor accept以后转交给NioProcessor但是NioProcessor线程池线程用完,只能阻塞[线程池大小是3,为什么是3,下面看代码] 第一个线程执行完毕 来处理第四个请求

 

这样我们明白 我们的 业务处理实现IOHandler的类和IoProcessor用一个线程,这样一旦我们的处理类阻塞则服务器就停滞了;

 

这样:就是我第一步内容说的 相当于只有2个车间,我们需要把 2车间拆分为 2个车间异步[流水]作业

 

具体拆分 上面看代码,打开 注释就ok了

 

我们简单看看源代码: 

 

我们首先

SocketAcceptor acceptor = new NioSocketAcceptor();

 

那么到底做了什么我们看看NioSocketAcceptor构造器吧

 

public NioSocketAcceptor() {
        super(new DefaultSocketSessionConfig(), NioProcessor.class);
        ((DefaultSocketSessionConfig) getSessionConfig()).init(this);
    }

 

我们在看看super(new DefaultSocketSessionConfig(), NioProcessor.class);
这个代码

 

 protected AbstractPollingIoAcceptor(IoSessionConfig sessionConfig,
            Class<? extends IoProcessor<T>> processorClass) {
        this(sessionConfig, null, new SimpleIoProcessorPool<T>(processorClass),
                true);
    }

 

看看上面蓝色色代码,构造IoProcessorPool线程池了 那大小是几

看看构造器

 public SimpleIoProcessorPool(Class<? extends IoProcessor<T>> processorType) {
        this(processorType, null, DEFAULT_SIZE);
         System.out.println("size is "+DEFAULT_SIZE);
    }

private static final int DEFAULT_SIZE = Runtime.getRuntime().availableProcessors() + 1;

 

明白了,就是cpu数+1 本机器是一个cpu双核的 所以是3

 

但是不要忘记 3要做的事情很多 项目希望把 业务处理的事情不让这个3做

 

http://rrsy23.iteye.com/blog/422703 解决 io处理与业务处理单线程池问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值