日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

网络与IO知识扫盲(四):C10K问题、BIO的弊端与NIO的引入

發(fā)布時(shí)間:2024/2/28 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网络与IO知识扫盲(四):C10K问题、BIO的弊端与NIO的引入 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

C10K 問(wèn)題

C10K 問(wèn)題: http://www.kegel.com/c10k.html
我們使用BIO的時(shí)候,來(lái)一個(gè)連接就拋出一個(gè)線程。被拋出的獨(dú)立的線程進(jìn)行阻塞,等待接收已連接的client發(fā)來(lái)的數(shù)據(jù),這樣不會(huì)影響其他client繼續(xù)連接。每個(gè)線程自己忙自己的。
但是隨著連接數(shù)的變大,拋出的線程越多,由于線程之間的切換,系統(tǒng)的性能會(huì)越來(lái)越低。

舉一個(gè)例子

一個(gè)客戶端可以通過(guò)2個(gè)不同的ip,與服務(wù)端創(chuàng)建2*65000個(gè)連接。

C10Kclient.java

package com.bjmashibing.system.io;import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.SocketChannel; import java.util.LinkedList;public class C10Kclient {public static void main(String[] args) {LinkedList<SocketChannel> clients = new LinkedList<>();InetSocketAddress serverAddr = new InetSocketAddress("192.168.150.11", 9090);for (int i = 10000; i < 65000; i++) { // 一個(gè)客戶端可以通過(guò)2個(gè)不同的ip,與服務(wù)端創(chuàng)建2*65000個(gè)連接try {SocketChannel client1 = SocketChannel.open();SocketChannel client2 = SocketChannel.open();/*linux中你看到的連接就是:client...port: 10508client...port: 10508*/client1.bind(new InetSocketAddress("192.168.150.1", i)); // 這臺(tái)機(jī)器上的第一個(gè)ip// 192.168.150.1:10000 192.168.150.11:9090client1.connect(serverAddr);boolean c1 = client1.isOpen();clients.add(client1);client2.bind(new InetSocketAddress("192.168.110.100", i)); // 這臺(tái)機(jī)器上的第二個(gè)ip// 192.168.110.100:10000 192.168.150.11:9090client2.connect(serverAddr);boolean c2 = client2.isOpen();clients.add(client2);} catch (IOException e) {e.printStackTrace();}}System.out.println("clients " + clients.size());try {System.in.read();} catch (IOException e) {e.printStackTrace();}} }

關(guān)于為什么需要在Linux上單獨(dú)配一個(gè)路由條目

在Linux上單獨(dú)配一個(gè)路由條目

因?yàn)槲锢頇C(jī)的192.168.110.100和虛擬機(jī)的192.168.150.0不是直連關(guān)系
192.168.150.2是虛擬機(jī)所在網(wǎng)絡(luò)的網(wǎng)關(guān),用于完成網(wǎng)絡(luò)地址轉(zhuǎn)換。
來(lái)自192.168.110.100的網(wǎng)絡(luò)包在返回給客戶端的時(shí)候,經(jīng)過(guò)NAT地址轉(zhuǎn)換,目標(biāo)ip被改成了192.168.150.2,Windows收到之后不知道這個(gè)ip應(yīng)該發(fā)給誰(shuí)了,導(dǎo)致三次握手的第二次回的包被windows丟棄了,沒(méi)有連接上。

關(guān)于為什么連接的速度并不快?(一秒鐘僅能夠建立4個(gè)連接左右)

為什么BIO慢?
創(chuàng)建一個(gè)連接的過(guò)程如下圖所示。

  • accept系統(tǒng)調(diào)用,是一個(gè)阻塞的循環(huán)過(guò)程,這個(gè)過(guò)程耗費(fèi)時(shí)間。
  • 拋出一個(gè)線程的速度比較慢。

    這就是整個(gè)BIO的弊端。想要調(diào)優(yōu),就要解決阻塞的問(wèn)題,但阻塞是由內(nèi)核提供給我們的API決accept receive定的。

NIO 的引入

NIO的N是啥意思呢?有兩個(gè)角度可以理解

  • Non-Blocking IO (操作系統(tǒng)中)
  • New IO (JDK中)

Linux中的文件描述符是輸入輸出雙向的。
Java中ServerSocketChannel也是淡化了輸入、輸出的概念,把輸入、輸出合在一起了。

一段NIO的代碼
SocketNIO.java

package com.bjmashibing.system.io;import java.net.InetSocketAddress; import java.net.StandardSocketOptions; import java.nio.ByteBuffer; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.LinkedList;public class SocketNIO {public static void main(String[] args) throws Exception {LinkedList<SocketChannel> clients = new LinkedList<>();ServerSocketChannel ss = ServerSocketChannel.open();ss.bind(new InetSocketAddress(9090));ss.configureBlocking(false); //設(shè)置false時(shí),是非阻塞。OS層面的NONBLOCKING,不會(huì)阻塞地去等待連接。// ss.setOption(StandardSocketOptions.TCP_NODELAY, false); // StandardSocketOptions.TCP_NODELAY // StandardSocketOptions.SO_KEEPALIVE // StandardSocketOptions.SO_LINGER // StandardSocketOptions.SO_RCVBUF // StandardSocketOptions.SO_SNDBUF // StandardSocketOptions.SO_REUSEADDRwhile (true) {//接受客戶端的連接,不會(huì)阻塞Thread.sleep(1000);SocketChannel client = ss.accept(); //開(kāi)始接收客戶端。不會(huì)阻塞等待連接,如果得不到連接,則返回 -1,NULL// ss.accept();方法調(diào)用內(nèi)核了,有下面這些情況:// 1,沒(méi)有客戶端連接進(jìn)來(lái),返回值是啥呢?在 BIO 的時(shí)候一直卡著,但是在NIO的時(shí)候不會(huì)卡著,返回的是-1,NULL// 2、有客戶端的連接,ss.accept();返回的是這個(gè)客戶端的fd 5(OS層面),Client對(duì)象(java層面)if (client == null) {System.out.println("null.....");// 可以不處理它,不要把這段當(dāng)做性能消耗去思考。} else {client.configureBlocking(false); //重點(diǎn)// socket有兩個(gè)角度:// 1、服務(wù)端的listen socket<連接請(qǐng)求三次握手后,往我這里扔,我去通過(guò)accept,得到后面的連接的socket>// 2、服務(wù)端接受客戶端連接進(jìn)來(lái)之后,形成的連接socket<連接后的數(shù)據(jù)讀寫(xiě)使用的>int port = client.socket().getPort();System.out.println("client...port: " + port);clients.add(client);}//執(zhí)行讀取行為:遍歷已連接的客戶端去讀寫(xiě)數(shù)據(jù),這個(gè)過(guò)程不會(huì)阻塞ByteBuffer buffer = ByteBuffer.allocateDirect(4096); //直接內(nèi)存分配,可以在堆里分配,也可以在堆外分配for (SocketChannel c : clients) { //串行化!!!! 多線程!!int num = c.read(buffer); // 返回值 >0 -1 0 不會(huì)阻塞if (num > 0) {buffer.flip();byte[] aaa = new byte[buffer.limit()];buffer.get(aaa);String b = new String(aaa);System.out.println(c.socket().getPort() + " : " + b);buffer.clear();}}}} }

運(yùn)行起來(lái)

ss.configureBlocking(true);阻塞狀態(tài)下

ss.configureBlocking(false);非阻塞狀態(tài)下

非阻塞了,這有什么意義?
假設(shè)這時(shí)候有兩個(gè)客戶端連接進(jìn)來(lái)了,其中一個(gè)的示例是下面這個(gè)樣子的:


曾經(jīng)我們是需要拋出一個(gè)線程,把這個(gè)線程扔出去,讓它自己去讀取數(shù)據(jù)。
現(xiàn)在不需要拋線程了,完全在一個(gè)線程中執(zhí)行,只不過(guò)是無(wú)數(shù)個(gè)循環(huán)。而在沒(méi)有連接的時(shí)候,循環(huán)也不會(huì)被阻塞,依然繼續(xù)循環(huán),從而讓循環(huán)后半部分的讀取數(shù)據(jù)的邏輯就有機(jī)會(huì)在當(dāng)前循環(huán)當(dāng)中被執(zhí)行到

再用C10K壓測(cè)一下

用C10K壓測(cè)一下NIO的性能(單客戶端10W連接):大約每秒鐘能建立50個(gè)左右的連接
現(xiàn)在使用NIO的瓶頸是:當(dāng)連接進(jìn)來(lái)很多客戶端時(shí),for (SocketChannel c : clients)遍歷每一個(gè)客戶端去讀取數(shù)據(jù)的過(guò)程耗費(fèi)了性能。


另外,報(bào)錯(cuò)超出文件描述符的數(shù)量,這個(gè)是可以設(shè)置的:ulimit -SHn 500000(軟硬openfile,改成50萬(wàn))

注:為啥ulimit -n 1024,但是連接數(shù)超過(guò)了1024呢?
這個(gè)理論是對(duì)的,只不過(guò)要看用戶。權(quán)限對(duì)root來(lái)說(shuō)等于虛設(shè),很多資源的約束在root用戶也是放開(kāi)的。而且在公司里,生產(chǎn)環(huán)境肯定是非root用戶啟動(dòng)程序。

超強(qiáng)干貨來(lái)襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生

總結(jié)

以上是生活随笔為你收集整理的网络与IO知识扫盲(四):C10K问题、BIO的弊端与NIO的引入的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 在线观看视频99 | 欧美三级在线播放 | 极品尤物在线观看 | 亚洲精品在线免费播放 | 亚洲黄色一区 | 少妇人妻互换不带套 | 91在线播放国产 | 尤物在线视频 | 在线观看亚洲一区二区 | 人体裸体bbbbb欣赏 | www.蜜臀av.com | 国产色影院 | 六月久久| 午夜一级视频 | 国产偷拍一区二区 | 扒下小娇妻的内裤打屁股 | 精品国产999久久久免费 | 全部免费毛片在线播放 | 丰满人妻一区二区三区无码av | 午夜黄色福利 | 国产一区二区视频免费观看 | 久草视频在线免费 | 久久天天躁狠狠躁夜夜躁2014 | wwwxxx在线播放 | 天天操欧美 | 午夜爱爱影院 | 久青草免费视频 | 久久国产影院 | 国产精品二| 日韩av免费 | 97国产一区| 亚洲精品国产乱伦 | 欧美大片www| 国产精品第2页 | av亚洲在线| 成人午夜视频一区二区播放 | 成人一区二区三区仙踪林 | 日韩激情在线观看 | 精品视频在线观看一区二区 | 黄频在线 | 久久香蕉综合 | 久久婷婷国产麻豆91天堂 | 久久久久久久久久综合 | 国产精品高潮呻吟久久久久久 | 8050午夜二级 | 一级特黄视频 | 亚洲男同视频 | 国产视频亚洲 | 在线国产精品一区 | 91中出| 你懂的在线观看网站 | 亚洲一区在线看 | 毛片视频在线免费观看 | 久久噜噜色综合一区二区 | 日韩精品免费视频 | 亚欧美精品 | 国产香蕉在线 | 国产午夜免费视频 | 第一色影院 | 久久中文视频 | 黄色一节片 | 欧美91av | 蜜桃av导航| 91视频在线免费观看 | 亚洲自啪 | 天天干夜夜撸 | 亚洲国产精彩视频 | 雷电将军和丘丘人繁衍后代视频 | 欧美天堂一区 | 欧美性猛交一区二区三区精品 | gv天堂gv无码男同在线观看 | 成人亚洲| 91视频88av| 超碰午夜 | 国模小黎自慰gogo人体 | 真人一毛片 | 北条麻妃99精品青青久久 | 无限国产资源 | 国产精品婷婷午夜在线观看 | 亚洲AV无码AV吞精久久中文版 | 欧美乱论 | 与亲女洗澡时伦了毛片 | 精品视频一二三区 | 久久精品人妻av一区二区三区 | 欧美中文字幕在线观看 | 久久精品成人一区二区三区蜜臀 | 91小宝寻花一区二区三区 | 亚洲欧美日韩精品久久亚洲区 | 久久天| 精品一区二区在线视频 | 岛国精品一区二区三区 | 天天操天天操天天射 | 国模叶桐尿喷337p人体 | 国产成人三级一区二区在线观看一 | jizzjizz在线观看 | 亚洲欧美日韩在线一区二区 | av网子| 69人人| 久久欧美 |