当前位置: 首页 > 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://www.yutouwan.com/news/118728/

相关文章:

  • 哔哩哔哩推广网站discuz论坛seo设置
  • 网页设计网站规划房产网站推广
  • 东台做淘宝网站怎么看网站备案
  • 网站注册搜索引擎的目的网络销售技巧和话术
  • 电子政务和网站建设自评seo优化网站建设哪家好
  • 网站做访问追踪省住房和城乡建设厅
  • 网站开发技术总结报告中国建筑最新消息
  • 衡水手机网站建设价格网站的工作简报怎么做
  • 建设网站一定要电脑吗手机上建设网站
  • 自己创造网站平台发布产品的免费平台有哪些
  • 哪个网站网页做的好看做网站构架用什么软件
  • 网站建设都有哪些方面如何选择邯郸网站制作
  • 做网站赚钱 知乎公司网站建设服务费入什么科目
  • 网站建设的基本元素河北云网站建设
  • 车网站建设策划书专业做效果图公司
  • 东莞做网站 汇卓小程序注册好了怎么办开始使用
  • 公司建网站几天可以手机网站怎么做301
  • 住房和城乡建设部网站电话网站的相对路径
  • 网站建设与制作设计公司广州推广比较好的公司
  • 做水果生意去那个网站深圳网站建设服务哪一个便宜
  • 手机网站建站教程阿里云服务器建立网站
  • 建设网站郑州中企动力网站建设 医疗
  • 网站模板如何优化wordpress自助发布插件
  • cms进行网站开发折一把古风扇子
  • 网站建设卖花网站的目的北京电商网站开发公司哪家好
  • 各省施工备案网站网站评论源码
  • 网站 制作登录网站建设中所涉及的所有链接建设
  • o2o商城网站搭建做文献ppt模板下载网站
  • 黄陂建设网站国企网站建设合同
  • 山西自助建站费用低上海建设单位工程备案网站