Netty入門到精通一
因為一次工作需要,要從華為的一個區跑到另一個區開會,我終於見到了我心目中的大神(李林鋒:Netty中國推廣者,現華為技術有限公司平臺中介軟體架構與設計部設計師),喜歡技術的我迫不及待的和他交流了起來,大神的技術果然牛逼,小弟膜拜中,大牛給我講解了很多設計思想,在我遇到大部分開發者中,大多交流技術,用了什麼什麼技術,然後覺得很牛逼,經過和大牛交流後,才明白設計思想很重要,很多人注重用神馬神馬框架,神馬神馬技術,卻不知道框架設計思想,為什麼這麼設計,這或許就是設計師和碼農的區別吧(本人也只敢稱自己是碼農( >﹏<。),和大神交流後感覺自己弱爆了),一個好的產品是有設計思想和靈魂的,好吧這裡我們就不扯蛋了。
好吧說說我為什麼寫下這篇文章吧,因工作需要,本人需要用到Netty,正好遇到了些問題,這是我就想起了大神,大神太忙了等了許久才回了我郵件(華為內部郵箱,華為內部不允許上網( >﹏<。)),下班後在網上找了一些資料,發現大多要不不是很全,要不就很籠統,讓人不好理解,看電子書很蛋疼吧,領導還安排有別的任務呢,再說相信對於初學者來說也遇到不少問題吧,然後自己資料整理了一下,寫下此文章,本人會不定期的更新Netty文章,所以要有耐心一點,最好關注一下我的微博,當然心急吃不了熱豆腐,有神馬技術上的問題也可以一起交流,本人CSDN部落格名Jimmy_zjf888,覺得寫的不錯的給個贊,送上鮮花,當然寫的差的別吐槽丟大便就好。
首先我們要知道神馬是Netty,我們為什麼要用Netty,Netty的優勢是神馬?
Netty 是一個基於 JAVA NIO 類庫的非同步通訊框架,它的架構特點是:非同步非阻塞、基於事件驅動、高效能、高可靠性和高可定製性,那麼NIO和傳統IO有神馬區別呢?下面我們來看看程式碼吧,這裡的客戶端和服務端我就用公司前臺和參觀客戶做例子吧.
/**
* 傳統socket服務端
* @author-Jimmy_zjf888-
*
*/
public class OrdinaryServer {
public static void main(String[] args)throws Exception {
//建立socket服務,開啟並監聽8888埠
ServerSocket server=new ServerSocket(8888);
while(true){
//獲取一個套接字(阻塞)
final Socket socket = server.accept();
System.out.println("來個一個新客戶!");
//前臺妹子給客人端茶倒水
handler(socket);
}
}
/**
* 讀取資料
* @param socket
* @throws Exception
*/
public static void handler(Socket socket){
try {
byte[] bytes = new byte[1024];
//獲取socket的一個輸入流
InputStream inputStream = socket.getInputStream();
while(true){
//迴圈讀取讀取資料(阻塞)
int read = inputStream.read(bytes);
if(read != -1){
System.out.println(new String(bytes, 0, read));
}else{
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我們執行一下如上程式碼,開啟debug模式
哎喲一開始就發現final Socket socket = server.accept();程式碼執行到這一句的時候就開始阻塞了,這時我們用控制檯的telnet去模擬吧
,然後回車,發現程式碼往下執行了,哎喲發現int read = inputStream.read(bytes);執行到這一句就阻塞了
總結了一下傳統的IO有2個阻塞點一個系server.accept()的時候阻塞,另外一點系
nputStream.read(bytes)的時候阻塞,如果這麼阻塞下去,如果有別的客人也來咱們公司參觀的話,是不是那個前臺妹子就不能照顧那個客人了?對沒錯的,我們再telnet一下試試
發現有新的客人來的時候我們的前臺,只能照顧不周了,因為她在忙著照顧她第一個客人,那麼我們該怎麼辦呢?是不是得多招幾個前臺妹子啊?聽到這裡有點小激動,又招妹子了,來看看怎麼實現把,首先我們需要一個前臺管理員,當客人來的時候能夠負責分配空閒的前臺去照顧客人對吧,程式碼如下。。。
public static void main(String[] args)throws Exception {
//建立一個執行緒池
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
//建立socket服務,開啟並監聽8888埠
ServerSocket server=new ServerSocket(8888);
while(true){
//獲取一個套接字(阻塞)
final Socket socket = server.accept();
System.out.println("來個一個新客戶!");
//派送空閒的前臺妹子去接待客人
newCachedThreadPool.execute(new Runnable() {
@Override
public void run() {
//前臺妹子給客人端茶倒水
handler(socket);
}
});
}
}
執行程式碼看看有沒有像我們想象中的那樣能夠解決問題,
我們再來一次,看看問題還會不會存在
我們總結一下,單執行緒情況下只能有一個客戶端,多執行緒的情況下可以有多個客戶端,但非常消耗記憶體(要招很多前臺妹子,公司的資源是有限的,不能不停招前臺,雖然對咱們程式猿來說是福利,但對公司來說就是一筆不小的開資,那麼我們應該怎麼辦呢?請看下篇)