当前位置: 首页 > news >正文

东莞网站建设流程图阿里云网站备案好了 怎么建站

东莞网站建设流程图,阿里云网站备案好了 怎么建站,想要网站推广版,如何用html制作网站随着并发数量的提高#xff0c;传统nio框架采用一个Selector来支撑大量连接事件的管理和触发已经遇到瓶颈#xff0c;因此现在各种nio框架的新版本都采用多个Selector并存的结构#xff0c;由多个Selector均衡地去管理大量连接。这里以Mina和Grizzly的实现为例。 在Mina 2…随着并发数量的提高传统nio框架采用一个Selector来支撑大量连接事件的管理和触发已经遇到瓶颈因此现在各种nio框架的新版本都采用多个Selector并存的结构由多个Selector均衡地去管理大量连接。这里以Mina和Grizzly的实现为例。   在Mina 2.0中Selector的管理是由org.apache.mina.transport.socket.nio.NioProcessor来处理每个NioProcessor对象保存一个Selector负责具体的select、wakeup、channel的注册和取消、读写事件的注册和判断、实际的IO读写操作等等核心代码如下  public NioProcessor(Executor executor) {        super(executor);        try {            // Open a new selector            selector  Selector.open();        } catch (IOException e) {            throw new RuntimeIoException(Failed to open a selector., e);        }    }    protected int select(long timeout) throws Exception {        return selector.select(timeout);    }      protected boolean isInterestedInRead(NioSession session) {        SelectionKey key  session.getSelectionKey();        return key.isValid()  (key.interestOps()  SelectionKey.OP_READ) ! 0;    }    protected boolean isInterestedInWrite(NioSession session) {        SelectionKey key  session.getSelectionKey();        return key.isValid()  (key.interestOps()  SelectionKey.OP_WRITE) ! 0;    }    protected int read(NioSession session, IoBuffer buf) throws Exception {        return session.getChannel().read(buf.buf());    }    protected int write(NioSession session, IoBuffer buf, int length) throws Exception {        if (buf.remaining()  length) {            return session.getChannel().write(buf.buf());        } else {            int oldLimit  buf.limit();            buf.limit(buf.position()  length);            try {                return session.getChannel().write(buf.buf());            } finally {                buf.limit(oldLimit);            }        }    }    这些方法的调用都是通过AbstractPollingIoProcessor来处理这个类里可以看到一个nio框架的核心逻辑注册、select、派发具体因为与本文主题不合不再展开。NioProcessor的初始化是在NioSocketAcceptor的构造方法中调用的 public NioSocketAcceptor() {        super(new DefaultSocketSessionConfig(), NioProcessor.class);        ((DefaultSocketSessionConfig) getSessionConfig()).init(this);    }    直接调用了父类AbstractPollingIoAcceptor的构造函数在其中我们可以看到默认是启动了一个SimpleIoProcessorPool来包装NioProcessor protected AbstractPollingIoAcceptor(IoSessionConfig sessionConfig,            Class? extends IoProcessorT processorClass) {        this(sessionConfig, null, new SimpleIoProcessorPoolT(processorClass),                true);    }    这里其实是一个组合模式,SimpleIoProcessorPool和NioProcessor都实现了Processor接口一个是组合形成的Processor池而另一个是单独的类。调用的SimpleIoProcessorPool的构造函数是这样  private static final int DEFAULT_SIZE  Runtime.getRuntime().availableProcessors()  1;     public SimpleIoProcessorPool(Class? extends IoProcessorT processorType) {        this(processorType, null, DEFAULT_SIZE);    }     可以看到默认的池大小是cpu个数1也就是创建了cpu1个的Selector对象。它的重载构造函数里是创建了一个数组启动一个CachedThreadPool来运行NioProcessor通过反射创建具体的Processor对象这里就不再列出了。    Mina当有一个新连接建立的时候就创建一个NioSocketSession并且传入上面的SimpleIoProcessorPool当连接初始化的时候将Session加入SimpleIoProcessorPool  protected NioSession accept(IoProcessorNioSession processor,            ServerSocketChannel handle) throws Exception {        SelectionKey key  handle.keyFor(selector);                if ((key  null) || (!key.isValid()) || (!key.isAcceptable()) ) {            return null;        }        // accept the connection from the client        SocketChannel ch  handle.accept();                if (ch  null) {            return null;        }        return new NioSocketSession(this, processor, ch);    }                private void processHandles(IteratorH handles) throws Exception {            while (handles.hasNext()) {                H handle  handles.next();                handles.remove();                // Associates a new created connection to a processor,                // and get back a session                T session  accept(processor, handle);                                if (session  null) {                    break;                }                initSession(session, null, null);                // add the session to the SocketIoProcessor                session.getProcessor().add(session);            }        }     加入的操作是递增一个整型变量并且模数组大小后对应的NioProcessor注册到session里     private IoProcessorT nextProcessor() {        checkDisposal();        return pool[Math.abs(processorDistributor.getAndIncrement()) % pool.length];    }    if (p  null) {            p  nextProcessor();            IoProcessorT oldp                 (IoProcessorT) session.setAttributeIfAbsent(PROCESSOR, p);            if (oldp ! null) {                p  oldp;            }    }     这样一来每个连接都关联一个NioProcessor也就是关联一个Selector对象避免了所有连接共用一个Selector负载过高导致server响应变慢的后果。但是注意到NioSocketAcceptor也有一个Selector这个Selector用来干什么的呢那就是集中处理OP_ACCEPT事件的Selector主要用于连接的接入不跟处理读写事件的Selector混在一起因此Mina的默认open的Selector是cpu2个。    看完mina2.0之后我们来看看Grizzly2.0是怎么处理的Grizzly还是比较保守它默认就是启动两个Selector其中一个专门负责accept另一个负责连接的IO读写事件的管理。Grizzly 2.0中Selector的管理是通过SelectorRunner类这个类封装了Selector对象以及核心的分发注册逻辑你可以将他理解成Mina中的NioProcessor核心的代码如下 protected boolean doSelect() {        selectorHandler  transport.getSelectorHandler();        selectionKeyHandler  transport.getSelectionKeyHandler();        strategy  transport.getStrategy();                try {            if (isResume) {                // If resume SelectorRunner - finish postponed keys                isResume  false;                if (keyReadyOps ! 0) {                    if (!iterateKeyEvents()) return false;                }                                if (!iterateKeys()) return false;            }            lastSelectedKeysCount  0;                        selectorHandler.preSelect(this);                        readyKeys  selectorHandler.select(this);            if (stateHolder.getState(false)  State.STOPPING) return false;                        lastSelectedKeysCount  readyKeys.size();                        if (lastSelectedKeysCount ! 0) {                iterator  readyKeys.iterator();                if (!iterateKeys()) return false;            }            selectorHandler.postSelect(this);        } catch (ClosedSelectorException e) {            notifyConnectionException(key,                    Selector was unexpectedly closed, e,                    Severity.TRANSPORT, Level.SEVERE, Level.FINE);        } catch (Exception e) {            notifyConnectionException(key,                    doSelect exception, e,                    Severity.UNKNOWN, Level.SEVERE, Level.FINE);        } catch (Throwable t) {            logger.log(Level.SEVERE,doSelect exception, t);            transport.notifyException(Severity.FATAL, t);        }        return true;    }     基本上是一个reactor实现的样子在AbstractNIOTransport类维护了一个SelectorRunner的数组而Grizzly用于创建tcp server的类TCPNIOTransport正是继承于AbstractNIOTransport类在它的start方法中调用了startSelectorRunners来创建并启动SelectorRunner数组 private static final int DEFAULT_SELECTOR_RUNNERS_COUNT  2; Override  public void start() throws IOException {  if (selectorRunnersCount  0) {                selectorRunnersCount  DEFAULT_SELECTOR_RUNNERS_COUNT;            }  startSelectorRunners();} protected void startSelectorRunners() throws IOException {        selectorRunners  new SelectorRunner[selectorRunnersCount];                synchronized(selectorRunners) {            for (int i  0; i  selectorRunnersCount; i) {                SelectorRunner runner                         new SelectorRunner(this, SelectorFactory.instance().create());                runner.start();                selectorRunners[i]  runner;            }        }    }   可见Grizzly并没有采用一个单独的池对象来管理SelectorRunner而是直接采用数组管理默认数组大小是2。SelectorRunner实现了Runnable接口它的start方法调用了一个线程池来运行自身。刚才我提到了说Grizzly的Accept是单独一个Selector来管理的那么是如何表现的呢答案在RoundRobinConnectionDistributor类这个类是用于派发注册事件到相应的SelectorRunner上它的派发方式是这样 public FutureRegisterChannelResult registerChannelAsync(            SelectableChannel channel, int interestOps, Object attachment,            CompletionHandler completionHandler)             throws IOException {        SelectorRunner runner  getSelectorRunner(interestOps);                return transport.getSelectorHandler().registerChannelAsync(                runner, channel, interestOps, attachment, completionHandler);    }        private SelectorRunner getSelectorRunner(int interestOps) {        SelectorRunner[] runners  getTransportSelectorRunners();        int index;        if (interestOps  SelectionKey.OP_ACCEPT || runners.length  1) {            index  0;        } else {            index  (counter.incrementAndGet() % (runners.length - 1))  1;        }                return runners[index];    }     getSelectorRunner这个方法道出了秘密如果是OP_ACCEPT那么都使用数组中的第一个SelectorRunner如果不是那么就通过取模运算的结果1从后面的SelectorRunner中取一个来注册。    分析完mina2.0和grizzly2.0对Selector的管理后我们可以得到几个启示1、在处理大量连接的情况下多个Selector比单个Selector好2、多个Selector的情况下处理OP_READ和OP_WRITE的Selector要与处理OP_ACCEPT的Selector分离也就是说处理接入应该要一个单独的Selector对象来处理避免IO读写事件影响接入速度。3、Selector的数目问题mina默认是cpu2而grizzly总共就2个我更倾向于mina的策略但是我认为应该对cpu个数做一个判断如果CPU个数超过8个那么更多的Selector线程可能带来比较大的线程切换的开销mina默认的策略并非合适幸好可以设置这个数值。 原文地址http://click.aliyun.com/m/21432/              转载于:https://www.cnblogs.com/iyulang/p/6878559.html
http://wiki.neutronadmin.com/news/118728/

相关文章:

  • 中国建设管理信息网站怎样在设计网站做图赚钱吗
  • 眉山住房和城乡建设局网站电子商务平台中搜索词拆解包括
  • 宽带技术网网站佛山中小企业网站制作
  • 雄县没有做网站的公司网站建设及优化 赣icp
  • 小企业网站建设的连接方式家用电器网站建设
  • 墨刀怎么做网站wordpress修改字体加载
  • 邯郸网站设计应搜韦欣cidun8上词什么叫网站后台
  • 广州企业网站建设哪家服务好万峰科技著.asp.net网站开发四酷全书电子工业出版社
  • 仿爱奇艺网站源码免费做苗木的网站
  • 河南做网站联系电话学历提升报名
  • 柳州网站建设哪里有logo设计的最好的公司
  • 企业宣传册免费模板网站广西注册公司网站
  • 毕设做网站太简单外贸怎么入行
  • 无法连接wordpress站点做洗化的网站
  • 最好设计网站建设wordpress 暗箱
  • 网站的推广和宣传方式国外访问国内网站速度
  • 电子商务网站建设文档wordpress 前台用户
  • 昆明网站建设知名企业建筑企业资质新规定2022
  • 稳定的网站服务器租用珠海网站空间注册
  • 怎么在百度建网站泰安卫生人才网
  • 网站建设推广 公司鹿邑建设局官方网站
  • dedecms本地可以更换网站模板出现网站模板不存在北京高端网站开发公司
  • 如何做网站呢在猪八戒网站如何做兼职
  • 有帮忙做儿童房设计的网站吗学全屋定制设计怎么入手
  • 兰州网站搜索排名wordpress与iis7欢迎
  • 电商网站怎么做搜索面试网站建设问题
  • 河北公司网站制作设计php做网站项目的思路
  • 有哪些做调查问卷赚钱的网站wordpress dns
  • php双语网站网站内部搜索怎么做
  • 深圳住房和建设局网站无法登陆网易那个网站可以做字幕