本文作者:黃小斜
市中ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書合作)期待與您的合作!轉(zhuǎn)載請(qǐng)務(wù)必在文章開頭注明出處和作者。
Java作為一門后端語(yǔ)言,對(duì)于網(wǎng)絡(luò)編程的支持是必不可少的,但是,作為一個(gè)經(jīng)常CRUD的Java工程師,很多時(shí)候都不需要接觸到網(wǎng)絡(luò)編程,自然而然地對(duì)這個(gè)東西不那么重視了,畢竟,即使像是JVM虛擬機(jī),Java多線程,在平時(shí)工作的時(shí)候還會(huì)用到一些,但是對(duì)于網(wǎng)絡(luò)編程,除非你做的東西確實(shí)是需要自己寫通訊服務(wù)代碼的,比如網(wǎng)絡(luò)游戲,以及偏向中間件方向的開發(fā), 可能會(huì)接觸到一些網(wǎng)絡(luò)編程的實(shí)踐,要不然在平時(shí)的開發(fā)工作中確實(shí)不多見(jiàn)。
讓我們看下網(wǎng)絡(luò)編程在百度百科上的定義:網(wǎng)絡(luò)編程最主要的工作就是在發(fā)送端把信息通過(guò)規(guī)定好的協(xié)議進(jìn)行組裝包,在接收端按照規(guī)定好的協(xié)議把包進(jìn)行解析,從而提取出對(duì)應(yīng)的信息,達(dá)到通信的目的。
那么,為什么網(wǎng)絡(luò)編程重要呢,簡(jiǎn)單來(lái)說(shuō),計(jì)算機(jī)之間之所以能夠通信,靠的就是網(wǎng)絡(luò)編程,只不過(guò)平時(shí)這些代碼不需要我們自己來(lái)寫罷了,TCP/IP的協(xié)議代碼已經(jīng)封裝在了Linux內(nèi)核中 ,而Tomcat里的代碼則負(fù)責(zé)處理一個(gè)個(gè)網(wǎng)絡(luò)請(qǐng)求,返回請(qǐng)求方需要的數(shù)據(jù)。再比如像netty這樣的網(wǎng)絡(luò)編程框架,也會(huì)把復(fù)雜的NIO處理邏輯封裝成簡(jiǎn)單的API,即使如此,需要使用netty來(lái)做服務(wù)端開發(fā)的工程師仍然不多。
Java網(wǎng)絡(luò)編程對(duì)于Java工程師來(lái)說(shuō)是很重要的能力,這也是我在接觸了一系列相關(guān)面試題,以及Tomcat和netty實(shí)現(xiàn)之后才逐漸意識(shí)到的,想要了解這兩個(gè)東西的實(shí)現(xiàn)原理,就必須要會(huì)網(wǎng)絡(luò)編程的知識(shí),當(dāng)然了,這一切的基礎(chǔ)就是你要首先懂得計(jì)算機(jī)網(wǎng)絡(luò),這部分內(nèi)容也可以參考我關(guān)于計(jì)算機(jī)網(wǎng)絡(luò)的一篇文章。
計(jì)算機(jī)網(wǎng)絡(luò)之于Java網(wǎng)絡(luò)編程,好比數(shù)據(jù)結(jié)構(gòu)之于算法,前者是后者的基礎(chǔ),沒(méi)有前者的支撐,直接學(xué)習(xí)后者,是沒(méi)有意義的。
之前我也寫了一篇關(guān)于計(jì)算機(jī)網(wǎng)絡(luò)該怎么學(xué)的文章,可以先看看。總體來(lái)看,計(jì)算機(jī)網(wǎng)絡(luò)告訴我們的是,兩臺(tái)計(jì)算機(jī)想要進(jìn)行通信,它們需要約定一種傳輸協(xié)議和編碼解碼的標(biāo)準(zhǔn),因此計(jì)算機(jī)網(wǎng)絡(luò)通常分為5層,而其中一些標(biāo)準(zhǔn)就包括TCP和IP,HTTP等等,這些協(xié)議都是為了更好地實(shí)現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)傳輸而產(chǎn)生的。
但是,這些協(xié)議只是協(xié)議而已,要真正在Java代碼里實(shí)現(xiàn)網(wǎng)絡(luò)傳輸,就需要讓代碼實(shí)現(xiàn)協(xié)議,當(dāng)然了,像TCP/IP這樣通用的協(xié)議棧。還輪不到Java應(yīng)用程序自己來(lái)實(shí)現(xiàn),否則也太麻煩了,Linux的內(nèi)核里已經(jīng)對(duì)其進(jìn)行了封裝,并且會(huì)向上提供API,所以Java應(yīng)用程序只需要調(diào)用Linux內(nèi)核提供的即可。
而再往上,也就是HTTP這類應(yīng)用層協(xié)議,Java代碼是可以直接進(jìn)行解析或者組裝的,畢竟HTTP的報(bào)文比較簡(jiǎn)單,我們可以直接通過(guò)Java提供的API進(jìn)行操作,大家也都知道,Java里有一些網(wǎng)絡(luò)編程的包,提供了一些常用于網(wǎng)絡(luò)通訊的類,比如Socket可以用來(lái)建立網(wǎng)絡(luò)連接,IO流則可以用來(lái)處理網(wǎng)絡(luò)傳輸?shù)腎O輸入和輸出。
換言之,網(wǎng)絡(luò)編程的實(shí)質(zhì)就是先進(jìn)行網(wǎng)絡(luò)連接,然后進(jìn)行IO傳輸,而網(wǎng)絡(luò)IO這個(gè)東西里又大有門道,這部分內(nèi)容我們?cè)谙乱还?jié)里繼續(xù)分享。
說(shuō)到這三個(gè)東西,相比學(xué)過(guò)Java的朋友都不會(huì)陌生,畢竟面試題也經(jīng)???,背也都背下來(lái)了。
但是這幾個(gè)東西為什么會(huì)有這樣的區(qū)別呢,不妨一起來(lái)探究一下。
BIO是最原始的Java IO模式,也叫阻塞式IO,多個(gè)BIO處理必須要串行執(zhí)行,因?yàn)镮O此時(shí)被阻塞了。
而NIO則是相對(duì)較新的一種模式,它基于Linux的epoll來(lái)進(jìn)行實(shí)現(xiàn),通過(guò)一個(gè)線程對(duì)多個(gè)連接進(jìn)行處理,當(dāng)發(fā)現(xiàn)有活躍的連接時(shí)進(jìn)行對(duì)應(yīng)的IO處理,本質(zhì)上是IO多路復(fù)用的一種實(shí)現(xiàn)。
而AIO和上面兩者不太一樣,它強(qiáng)調(diào)的不是阻塞非阻塞,而是對(duì)IO的處理是異步化的,通常來(lái)說(shuō)就是建立連接,然后提供一個(gè)處理完IO的回調(diào)接口,然后就可以扔在一邊不管了,等待IO處理結(jié)束后回調(diào)相應(yīng)的接口。值得一提的是,AIO需要底層操作系統(tǒng)的支持。
了解了BIO、NIO和AIO之后,你對(duì)于網(wǎng)絡(luò)編程中的幾個(gè)核心概念你應(yīng)該已經(jīng)有所了解了,接下來(lái)就不得不看看Java網(wǎng)絡(luò)編程中最牛掰的一個(gè)框架:netty了。比起NIO和BIO,了解netty的人應(yīng)該更少了,其實(shí),netty就是基于NIO實(shí)現(xiàn)的異步網(wǎng)絡(luò)編程框架,既有了NIO的高性能IO處理方式,又通過(guò)異步化編程使得netty的編程方式更加簡(jiǎn)單高效。
我當(dāng)時(shí)接觸netty的時(shí)候,還是在學(xué)習(xí)RPC和分布式服務(wù)的時(shí)候,我發(fā)現(xiàn)每當(dāng)有RPC出現(xiàn)的地方,也總有網(wǎng)絡(luò)編程框架的身影,好比netty這樣的通訊框架常常會(huì)被提到,我當(dāng)時(shí)并不太理解通訊框架是干嘛用的,以至于我對(duì)RPC是什么東西都不太理解。
當(dāng)我現(xiàn)在搞懂了RPC之后,再去研究網(wǎng)絡(luò)編程框架就有了新的感覺(jué),其實(shí),不管是RPC還是HTTP,都需要通信框架的支持,只不過(guò)支持HTTP的服務(wù)器已經(jīng)有很多了,比如Tomcat,比如Nginx,這些服務(wù)器完全可以cover掉網(wǎng)絡(luò)框架,后面我們也會(huì)再來(lái)聊一下Tomcat這個(gè)神奇的服務(wù)器。
Tomcat這個(gè)服務(wù)器我們Java工程師一直在用,但是很多朋友對(duì)它其實(shí)知之甚少,只知道它可以運(yùn)行JavaWeb應(yīng)用。
其實(shí)Tomcat這個(gè)服務(wù)器,也是基于NIO實(shí)現(xiàn)的一個(gè)服務(wù)器,不妨把Tomcat分為兩個(gè)部分來(lái)看,一部分是connector,負(fù)責(zé)網(wǎng)絡(luò)連接,接受請(qǐng)求和處理請(qǐng)求,另一部分是container,也就是容器,Tomcat本質(zhì)上是一個(gè)servlet容器,這一部分負(fù)責(zé)的就是編排一系列容器里的處理器、調(diào)用鏈以及層級(jí)結(jié)構(gòu),比如engine的下一層是host,host的下一層是context。
當(dāng)一個(gè)網(wǎng)絡(luò)請(qǐng)求到達(dá)Tomcat時(shí),connector先負(fù)責(zé)處理這個(gè)請(qǐng)求,再扔到container跑一遍拿到結(jié)果,但在生產(chǎn)環(huán)境中,connector一次性要處理的請(qǐng)求就多的去了,因此就必須要支持高并發(fā)以及IO多路復(fù)用,因此Tomcat也采用了NIO的IO處理方式,同時(shí)通過(guò)多線程進(jìn)行請(qǐng)求處理,總體來(lái)說(shuō)已經(jīng)達(dá)到了非常不錯(cuò)的性能了。
一個(gè)小小的Java網(wǎng)絡(luò)編程,居然一下子牽扯出這么多復(fù)雜的知識(shí)點(diǎn)出來(lái),先是計(jì)算機(jī)網(wǎng)絡(luò),再到Java網(wǎng)絡(luò)編程API,再到BIO、NIO和AIO,然后又談到了Tomcat和netty。
其實(shí),網(wǎng)絡(luò)編程的內(nèi)容可能還不止這些,比如NIO的底層實(shí)現(xiàn)是基于Linux的epoll來(lái)完成了,而Linux的網(wǎng)絡(luò)IO模型有select、poll和epoll等方式,要真正搞懂NIO,你還需要搞懂epoll。
其實(shí)一開始我對(duì)于Java網(wǎng)絡(luò)編程也沒(méi)有什么概念,只不過(guò)在看了很多面試題之后,才逐漸發(fā)現(xiàn)問(wèn)題所在,比如BIO和NIO的區(qū)別,背了好幾次面試答案仍然不解其意,要是再問(wèn)到epoll、poll和select的區(qū)別,更是完全不得要領(lǐng),究其原因還是不知道這些東西到底是什么,有什么用,以及它們和一些實(shí)際場(chǎng)景間的關(guān)系。
因此,我覺(jué)得,網(wǎng)絡(luò)編程方向的面試題重在理解概念,對(duì)于計(jì)算機(jī)網(wǎng)絡(luò)、IO模型,以及網(wǎng)絡(luò)編程框架要能夠真正理解了這些東西之后,你才能夠?qū)γ嬖囶}游刃有余,否則,這類面試題再怎么背都不會(huì)有什么效果,正如計(jì)算機(jī)網(wǎng)絡(luò)這種純理論的課程一樣,在不理解的情況下,分析問(wèn)題和回答問(wèn)題肯定是難以達(dá)到面試官要求的。
所以,請(qǐng)按照這樣的一個(gè)順序進(jìn)行復(fù)習(xí)和實(shí)踐,相信這對(duì)于你學(xué)習(xí)網(wǎng)絡(luò)編程會(huì)有所幫助。
1、計(jì)算機(jī)網(wǎng)絡(luò)知識(shí)
2、Java網(wǎng)絡(luò)編程基礎(chǔ)
3、NIO、BIO、AIO
4、Linux的網(wǎng)絡(luò)IO模型:epoll、select和poll
5、netty網(wǎng)絡(luò)編程框架
6、Tomcat服務(wù)器
這方面能推薦的資源就非常多了,我盡量按照先易后難的順序?yàn)榇蠹彝扑]資源
《Java網(wǎng)絡(luò)編程》
《netty權(quán)威指南》
《How Tomcat Work》
《Tomcat架構(gòu)解析》
我整理一些Java網(wǎng)絡(luò)編程復(fù)習(xí)的視頻資源,習(xí)慣看視頻的朋友可以了解一下。
Java技術(shù)倉(cāng)庫(kù)《Java程序員復(fù)習(xí)指南》
https://github.com/h3pl/Java-Tutorial
整合全網(wǎng)優(yōu)質(zhì)Java學(xué)習(xí)內(nèi)容,幫助你從基礎(chǔ)到進(jìn)階系統(tǒng)化復(fù)習(xí)Java。
關(guān)于如何學(xué)習(xí)Java網(wǎng)絡(luò)編程,并且搞定相關(guān)面試題,我們今天就講到這里了,如果還有什么疑問(wèn)也可以到我公眾號(hào)里找我探討,后續(xù)會(huì)有更多的文章推出,包括如何系統(tǒng)性地學(xué)習(xí)JavaWeb,以及如何系統(tǒng)性地學(xué)習(xí)后端技術(shù)。敬請(qǐng)期待。
對(duì)了,你想問(wèn)我文章里提到的資源去哪找?我已經(jīng)給你準(zhǔn)備好了
文中提到的資源都可以免費(fèi)領(lǐng)取,在我的公眾號(hào)【程序員黃小斜】回復(fù)“Java網(wǎng)絡(luò)編程“即可免費(fèi)領(lǐng)取對(duì)應(yīng)的資源。
如果覺(jué)得本文對(duì)你有幫助的話,請(qǐng)你也不要吝嗇你的“好看”哈,轉(zhuǎn)發(fā)朋友圈就是對(duì)我大的支持啦,你們的支持是對(duì)我大的鼓勵(lì)。
對(duì)本系列文章有什么建議和意見(jiàn),也歡迎留言告訴我,期待你的回饋。
微信公眾號(hào):程序員黃小斜
知乎:黃小斜
B站:黃小斜