日韩性视频-久久久蜜桃-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ò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美日韩经典 | 影音先锋三级 | 好吊色视频一区二区 | 懂色av一区二区三区在线播放 | 夜夜综合网 | 国产精品久久国产精麻豆96堂 | 欧美国产日韩一区二区 | 激情综合色 | 欧美三级韩国三级日本三斤 | 成人音影| 欧美黑人一级 | 激情女主播 | 激情另类小说 | 九色蝌蚪9l视频蝌蚪9l视频 | 免费99视频 | 人妻无码一区二区三区免费 | 国产一区二区自拍视频 | 国产日韩亚洲欧美 | 免费av在线播放网址 | 爱久久 | 亚洲精品国产精品乱码不卡√香蕉 | 亚洲性xxxx | 国产精品刘玥久久一区 | av天天堂| 国产成人在线观看网站 | 亚洲成人伊人 | 人妻一区二区三区在线 | 国产aⅴ一区二区三区 | 色一情一伦一子一伦一区 | 夜夜爽妓女8888视频免费观看 | 深夜福利久久 | 办公室大战高跟丝袜秘书经理ol | 色妇网| 欧美精品在线第一页 | 色播放 | 国产传媒第一页 | 日韩av免费播放 | 国产成人亚洲综合 | 亚洲欧洲在线视频 | 成年人午夜视频 | 高清不卡毛片 | 日韩三级中文字幕 | 黄网在线免费 | 成人在线视频网址 | 午夜寂寞视频 | 麻豆一区在线 | 免费观看毛片视频 | 国产精品白丝喷水在线观看 | 欧美变态另类刺激 | 青草视频在线看 | 好吊日精品视频 | 欧美日韩精品一区二区 | 日韩一区二区三区在线观看 | 青青青青在线 | 国产v亚洲 | 日本中文字幕成人 | 久久久久久久色 | 在线免费看毛片 | 加勒比久久综合 | 欧美一区永久视频免费观看 | 456亚洲影视 | 亚洲色图 在线视频 | 免费在线播放视频 | 欧美一级视频在线观看 | 岛国精品一区二区三区 | 色日韩| 欧美高清大白屁股ass18 | 三级久久 | 日日操夜夜爽 | 亚洲精品国产精品乱码不99按摩 | 精品视频久久久久久 | 久久久美女视频 | 97碰碰视频 | 国产免费黄色 | 精品一区二区在线看 | 97色在线观看 | 亚洲精品国产日韩 | 国产又粗又猛又黄又爽的视频 | 啪啪.com| 黄色av一区二区三区 | 香蕉久久精品日日躁夜夜躁 | 日本成人片在线 | 视频在线一区 | 午夜色网 | 欧美性黄色 | 亚洲成a人 | a√天堂资源在线 | 成人福利在线视频 | 午夜精品久久久久久久久久久久久蜜桃 | 高清久久 | 少妇欧美激情一区二区三区 | 免费看的一级片 | 狠狠爱夜夜操 | 香蕉网址 | 性自由色xxxx免费视频 | 久久aⅴ乱码一区二区三区 亚洲成人18 | 精品人妻一区二区三区蜜桃视频 | 丁香六月啪啪 | 毛片大片 |