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

网络品牌营销策略有哪些上海百度seo牛巨微

网络品牌营销策略有哪些,上海百度seo牛巨微,百度竞价推广点击软件,岳阳市委网站文章目录 1. NIO 服务端的常见代码2. 成因3. 危害4. 一种简单的解决方案5. Netty 的解决方案5.1 涉及的变量、常量和方法5.2 判断流程5.3 优点 6. JDK 对 NIO 的优化7. 总结 1. NIO 服务端的常见代码 public static void main(String[] args) throws IOException {ServerSocke…

文章目录

  • 1. NIO 服务端的常见代码
  • 2. 成因
  • 3. 危害
  • 4. 一种简单的解决方案
  • 5. Netty 的解决方案
    • 5.1 涉及的变量、常量和方法
    • 5.2 判断流程
    • 5.3 优点
  • 6. JDK 对 NIO 的优化
  • 7. 总结


1. NIO 服务端的常见代码

public static void main(String[] args) throws IOException {ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(8080));serverSocketChannel.configureBlocking(false);Selector selector = Selector.open();serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {// 如果没有连接的通道,则跳过本轮循环int readyChannels = selector.select();if (readyChannels == 0) {continue;}Set<SelectionKey> selectionKeys = selector.selectedKeys();Iterator<SelectionKey> iterator = selectionKeys.iterator();while (iterator.hasNext()) {SelectionKey selectionKey = iterator.next();if (selectionKey.isAcceptable()) {SocketChannel socketChannel = serverSocketChannel.accept();socketChannel.configureBlocking(false);socketChannel.register(selector, SelectionKey.OP_READ);} else if (selectionKey.isReadable()) {// 处理读取数据的逻辑}iterator.remove();}}
}

说明:select() 是阻塞的,直到有返回值。但当它频繁返回 0 时,会导致 CPU 不断跳过本轮循环,在循环内空转,这就出现了空轮询 bug。

2. 成因

Selector 借助操作系统的多路复用机制(例如 Linux 系统的 epoll)来监控多个通道的 I/O 事件。不过在某些特定情形下,Selector 对象的 select()select(long timeout) 方法可能会提前返回 0。此时没有任何通道准备好进行 I/O 操作,这就引发了空轮询现象。

这种 bug 通常是由 底层操作系统的多路复用机制、Java 虚拟机(JVM)以及网络环境等多方面因素共同导致的。例如,在 Linux 系统中使用 epoll 时,当 epoll_ctl 操作失败或者 epoll_wait 返回错误时,就可能致使 Selector 出现空轮询问题。

3. 危害

空轮询 bug 会 Selector 不断地进行无意义的轮询,从而 使 CPU 使用率急剧上升,系统性能大幅下降。

4. 一种简单的解决方案

public static void main(String[] args) throws IOException {ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(8080));serverSocketChannel.configureBlocking(false);int emptySelections = 0; // 统计空轮询的次数Selector selector = Selector.open();serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {// 如果没有连接的通道,则空轮询的次数加一,并跳过本轮循环int readyChannels = selector.select();if (readyChannels == 0) {emptySelections++;// 如果空轮询的次数大于等于 100 次,则重建 selector,并将 空轮询的次数 置为 0if (emptySelections >= 100) {selector = rebuildSelector(selector);emptySelections = 0;}continue;}Set<SelectionKey> selectionKeys = selector.selectedKeys();Iterator<SelectionKey> iterator = selectionKeys.iterator();while (iterator.hasNext()) {SelectionKey selectionKey = iterator.next();if (selectionKey.isAcceptable()) {SocketChannel socketChannel = serverSocketChannel.accept();socketChannel.configureBlocking(false);socketChannel.register(selector, SelectionKey.OP_READ);} else if (selectionKey.isReadable()) {// 处理读取数据的逻辑}iterator.remove();}}
}private static Selector rebuildSelector(Selector oldSelector) throws IOException {Selector newSelector = Selector.open();// 将旧 selector 的所有 有效 的通道 注册到新 selector 里for (SelectionKey key : oldSelector.keys()) {if (key.isValid() && key.channel().isOpen()) {int interestOps = key.interestOps();key.cancel(); // 从旧 selector 中取消注册key.channel().register(newSelector, interestOps);}}oldSelector.close();return newSelector;
}

说明:本解决方案认为 只要一个 selector 有至少 100 次的空轮询,就对其进行重建,重建时排除无效的通道。

缺点:检测机制不精确。如果空轮询的次数在很长一段时间才累积到 100 次,那么这时候大概率不需要重建 selector。因为在这个场景中,空轮询是一个偶发事件,这样就会由于重建 selector 浪费一定的时间。如果将判断条件改为 在某个时间段内的空轮询次数超过某个值,那就会避免无效的 selector 重建。

5. Netty 的解决方案

5.1 涉及的变量、常量和方法

  • private static final int SELECTOR_AUTO_REBUILD_THRESHOLD 常量:空轮询次数的阈值(默认为 512),如果超过,则重建 selector。
  • int selectCnt 变量:run 方法循环外的局部变量,用于统计空轮询的次数。每次轮询都加一,无论是否是空轮询,如果不是空轮询,则会将其重新置为 0
  • protected void run() 方法:相当于 NIO 代码中的 main 方法,包含一个无限循环,在循环中监听并处理。
  • private int select(long deadlineNanos) 方法:监测已注册的通道中有没有发生事件,如果发生,则返回发生事件的通道数。该方法实际上使用的是 NIO 的 Selectorselect 方法,由于多种因素,该方法可能返回 0
  • private boolean unexpectedSelectorWakeup(int selectCnt) 方法:判断空轮询次数有没有大于等于阈值,如果超过,则触发重建 selector 的机制,并在 run 方法中将空轮询次数置为 0
  • public void rebuildSelector() 方法:触发重建 selector 的流程。
  • private void rebuildSelector0() 方法:重建 selector。

5.2 判断流程

  1. run 方法中,通过 select 方法监测有没有通道发生事件。如果由于某些因素,该方法返回 0,则表示发生了空轮询,之后调用 unexpectedSelectorWakeup 方法,如果该方法返回 true,则将 selectCnt 置为 0
  2. unexpectedSelectorWakeup 方法中判断 selectCnt 是否大于等于 SELECTOR_AUTO_REBUILD_THRESHOLD。如果是,则会调用 rebuildSelector 方法。
  3. rebuildSelector 方法中调用 rebuildSelector0 方法。
  4. rebuildSelector0 方法中,将通道绑定到新的 selector,最后关闭旧的 selector。

5.3 优点

这种方案比简单方案优秀的就是它的监测机制,简单方案监测的是 自服务端启动开始的空轮询次数,这种方案监测的是 连续的空轮询次数因为一旦轮询不是空轮询,selectCnt 就会清零)。

6. JDK 对 NIO 的优化

在 JDK 1.5、JDK 1.6 等早期版本中,Selector 的空轮询 bug 比较突出。Oracle 对 JDK 不断进行优化和修复,JDK 1.8 及后续版本在处理 Selector 相关问题上有了更好的表现。虽然不能绝对保证不会出现空轮询,但出现的概率相比早期版本大大降低。

7. 总结

NIO 的 Selector 借助底层操作系统的多路复用机制来监听多个通道的事件,由于某些因素,可能导致这个方法频繁返回 0,从而服务端不停地在循环中空转,这就是 NIO 的空轮询问题。

解决这个问题的方法就是统计空轮询的次数,当超过一个数值后,就重建 selector。其中的统计空轮询的机制很重要,建议设计为 统计连续空轮询的次数

这个问题在 JDK 的早期版本中比较退出,但随着 JDK 的升级,这个 bug 出现的概率降低了许多。

http://www.dtcms.com/wzjs/490686.html

相关文章:

  • 网站收费怎么做whois查询 站长工具
  • 番禺区网站建设哪里有seo相关ppt
  • 东莞专业微网站建设推广洛阳网站建设优化
  • 产品 网站建设深圳市推广网站的公司
  • 济南网站建设北京做的好的seo公司
  • 青岛中英网站建设网站交易
  • 阜宁县住房城乡建设局网站百度下载安装免费下载
  • 自动做海报的网站seo关键词如何布局
  • 做购物网站是怎么链接银行搜索引擎优化排名案例
  • 可以做样机图的网站百度指数搜索
  • 比分网站制作百度手机助手应用商店
  • 网站的三级页面怎么做个人建网站步骤
  • 深圳网站建设做一个公司网站要多少钱广告网站推荐
  • 上海网站公安局备案太原关键词排名推广
  • 南宁百度网站建设公司哪家好微博营销的特点
  • 乐山市住房和城乡建设局网站百度seo排名主要看啥
  • 标识设计公司网站关键词查询工具免费
  • 商务网站建设公学网络营销去哪个学校
  • 成都网站建设电话最好的网络推广方式
  • 做中英文版的网站需要注意什么怎么提交百度收录
  • wordpress可以做电影站网站制作多少钱
  • java做的网站php公众号运营收费价格表
  • 企业网站建设应该怎么做百度助手app免费下载
  • 酒店行业网站建设方案济南疫情最新消息
  • 滕州网站建设做推广
  • 做字幕网站有哪些最权威的排行榜网站
  • 加强住房公积金网站建设百度关键词seo排名
  • 嘉兴网站建设全包seo免费诊断
  • 网站做优化得话从哪里优化微信营销方法
  • 做网站需要申请专利吗海外推广服务