设为首页 收藏本站
查看: 451|回复: 0

[经验分享] apache MINA 源码级分析-[壹]

[复制链接]

尚未签到

发表于 2017-1-4 07:19:46 | 显示全部楼层 |阅读模式
  如果对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处理与业务处理单线程池问题

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-323434-1-1.html 上篇帖子: tomcat6+apache_2.2.9均衡负载 下篇帖子: apache +tomcat 群集 组播路由丢失.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表