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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

servlet解析演进(2-1)

發布時間:2025/3/21 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 servlet解析演进(2-1) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

上文說了簡單的servlet解析過程。實際上,tomcat在解析servlet的 時候是吧連接器定位為滿足以下三個條件:

1、必須事先接口org.apache.catalina.Connector

2. 必須創建請求對象,該請求對象的類必須實現接口org.apache.catalina.Request。?

3. 必須創建響應對象,該響應對象的類必須實現接口org.apache.catalina.Response。

tomcat的連接器有很多種類:Coyote、mode_jk、mod_jk2和mode_webapp等。

來自瀏覽器的請求類型是有區別的http/0.9 http/1.0 http/1.1.

http/1.1又叫做持久連接,上文中一次請求處理完畢就關閉了socket。然而,在現實的頁面請求中需要加載多種資源(js、img css)。如果每次請求都開啟關閉連接那將是非常耗時的事情。http/1.1能夠讓瀏覽器和服務器保持一種持久化的連接,快速的相應請求。這樣,請求的形式就和之前不同,他是一塊編碼的形式,并使用特殊頭部transfer-encoding感知發送過來的數據信息。同時,如果瀏覽器有較大數據請求之前發送頭部信息Expect: 100-continue頭部到服務器,等待服務器的相應。如果服務器響應數據能夠接受大數據請求,才真正的發送數據,避免先發送大數據而遭服務器拒絕而浪費了傳輸數據的帶寬資源。

本文重點說明連接器的演進。


連接器的演進主要包括了以下幾個方面:

1、處理請求不再只是一次處理一次請求,而是生成Processor池,用于處理多個連接請求。同事Processor處理器也不再是每次請求新生成實例處理請求,而是從池子中獲取到一個處理器去完成請求。同時,實現了Processor處理方法異步化,讓連接器線程能夠繼續接受其他的請求。

2、處理器線程和連接器線程通過wait() notifyAll()的方式進行線程間通信。

3、Processor處理器中,增加了標識符,KeepAlive、stopped和http11,為處理器在處理的過程中設定“路口”,及時相應請求的變化。

4、socket緩沖區大小不再是像前文一樣設置為定值,而是通過獲取連接器傳遞過來的參數設置緩沖區大小。

5、處理器的職能更加的豐富。

連接處理 ?parseConnection,針對不同的連接協議做不同的處理。


解析請求 parseRequest


解析頭部 parseHeaders?


6、去掉了靜態處理器,暫時無法接受靜態資源請求。

------------------------

1、連接器啟動:

HttpConnector?connector?=?new?HttpConnector(); SimpleContainer?container?=?new?SimpleContainer(); connector.setContainer(container); try?{ //初始化連接器,打開socket連接 connector.initialize(); //開啟監聽,開啟連接器線程、將處理器線程啟動并入隊列。 connector.start();System.in.read(); } catch?(Exception?e)?{e.printStackTrace(); }

1.1 初始化連接、打開socket連接(使用工廠模式)

public?void?initialize() throws?LifecycleException?{ //初始化標志,不能重復初始化 if?(initialized) throw?new?LifecycleException?( sm.getString("httpConnector.alreadyInitialized")); this.initialized=true;Exception?eRethrow?=?null; //?Establish?a?server?socket?on?the?specified?port try?{ //打開socket連接 serverSocket?=?open();}?catch?(IOException?ioe)?{log("httpConnector,?io?problem:?",?ioe);eRethrow?=?ioe;}?catch?(KeyStoreException?kse)?{log("httpConnector,?keystore?problem:?",?kse);eRethrow?=?kse;}?catch?(NoSuchAlgorithmException?nsae)?{log("httpConnector,?keystore?algorithm?problem:?",?nsae);eRethrow?=?nsae;}?catch?(CertificateException?ce)?{log("httpConnector,?certificate?problem:?",?ce);eRethrow?=?ce;}?catch?(UnrecoverableKeyException?uke)?{log("httpConnector,?unrecoverable?key:?",?uke);eRethrow?=?uke;}?catch?(KeyManagementException?kme)?{log("httpConnector,?key?management?problem:?",?kme);eRethrow?=?kme;} if?(?eRethrow?!=?null?) throw?new?LifecycleException(threadName?+?".open",?eRethrow); } private?ServerSocket?open() throws?IOException,?KeyStoreException,?NoSuchAlgorithmException,CertificateException,?UnrecoverableKeyException,KeyManagementException { //?Acquire?the?server?socket?factory?for?this?Connector//獲得服務器socket工廠實例 ServerSocketFactory?factory?=?getFactory(); //?If?no?address?is?specified,?open?a?connection?on?all?addresses//如果沒有指定地址,在所有地址上打開一個連接 if?(address?==?null)?{log(sm.getString("httpConnector.allAddresses")); try?{ return?(factory.createSocket(port,?acceptCount));}?catch?(BindException?be)?{ throw?new?BindException(be.getMessage()?+?":"?+?port);}}? //在指定地址上打開一個連接 try?{InetAddress?is?=?InetAddress.getByName(address);log(sm.getString("httpConnector.anAddress",?address)); try?{ return?(factory.createSocket(port,?acceptCount,?is));}?catch?(BindException?be)?{ throw?new?BindException(be.getMessage()?+?":"?+?address?+ ":"?+?port);}}?catch?(Exception?e)?{log(sm.getString("httpConnector.noAddress",?address)); try?{ return?(factory.createSocket(port,?acceptCount));}?catch?(BindException?be)?{ throw?new?BindException(be.getMessage()?+?":"?+?port);}} }

1.2、開啟監聽,開啟連接器線程、將處理器線程啟動并入隊列。

//為連接器綁定指定數量的處理器 public?void?start()?throws?LifecycleException?{???? //判斷該線程的connect開啟狀態,避免重復開啟 if?(started) throw?new?LifecycleException(sm.getString("httpConnector.alreadyStarted")); threadName?=?"HttpConnector["?+?port?+?"]"; //打開監聽 lifecycle.fireLifecycleEvent(START_EVENT,?null); started?=?true; //?Start?our?background?thread//開啟一個后臺連接器線程 threadStart(); //創建處理器,并調用recyle方法將其放置到棧隊列中 while?(curProcessors?<?minProcessors)?{ if?((maxProcessors?>?0)?&&?(curProcessors?>=?maxProcessors)) break;HttpProcessor?processor?=?newProcessor();recycle(processor);} }

2、連接器、容器之間的協作關系


2.1 容器派發socket到處理器線程

public?void?run()?{ //?Loop?until?we?receive?a?shutdown?command//開啟循環,知道我們獲得了結束命令 while?(!stopped)?{ //?Accept?the?next?incoming?connection?from?the?server?socket Socket?socket?=?null; try?{//獲得socket請求 socket?=?serverSocket.accept();//??設置超時時間 if?(connectionTimeout?>?0)socket.setSoTimeout(connectionTimeout); //設置tcp?nodelay屬性 socket.setTcpNoDelay(tcpNoDelay);}?catch?(AccessControlException?ace)?{ //拋出連接安全錯誤信息 log("socket?accept?security?exception",?ace); continue;}?catch?(IOException?e)?{ try?{ //?If?reopening?fails,?exit//如果再次開啟失敗,退出 synchronized?(threadSync)?{ if?(started?&&?!stopped)log("accept?error:?",?e); if?(!stopped)?{???????????????? //??關閉異常連接 serverSocket.close();?????????????//???重新開啟異常連接? serverSocket?=?open();}} //??異常處理,包括不限于秘鑰等錯誤請求 }?catch?(Exception?ioe)?{log("socket?reopen,?io?problem:?",?ioe); break;} continue;}???//判斷處理器棧是否有可用處理器,沒有按規則生成,有則獲取棧中處理器 HttpProcessor?processor?=?createProcessor(); //獲取處理器為空,可能情況是請求數量過多,超過了承受的最大處理器個數 if?(processor?==?null)?{ try?{log(sm.getString("httpConnector.noProcessor"));socket.close();}?catch?(IOException?e)?{;} continue;} //派發socket到處理器 processor.assign(socket); //?The?processor?will?recycle?itself?when?it?finishes } //獲取到了結束命令,通知其他線程 synchronized?(threadSync)?{ threadSync.notifyAll();} }

2.2處理器接收到派發socket

synchronized?void?assign(Socket?socket)?{ //?d等待該處理器的其它socket處理執行完畢 while?(available)?{ try?{wait();}?catch?(InterruptedException?e)?{}} //?Store?the?newly?available?Socket?and?notify?our?thread//將新獲取的socket放置到處理器中,并發送線程通知 this.socket?=?socket; available?=?true;notifyAll(); if?((debug?>=?1)?&&?(socket?!=?null))log("?An?incoming?request?is?being?assigned"); }

2.3 ?處理器接收到了socket請求,準備處理

public?void?run()?{ //?Process?requests?until?we?receive?a?shutdown?signal while?(!stopped)?{ //?Wait?for?the?next?socket?to?be?assigned//等待連接器的socket請求 Socket?socket?=?await(); if?(socket?==?null) continue; //?Process?the?request?from?this?socket try?{ //處理socket請求 process(socket);}?catch?(Throwable?t)?{log("process.invoke",?t);} //?Finish?up?this?request//處理完畢,將該processor線程歸還給Stack?processors?用來處理接下來的socket請求 connector.recycle(this);} //?Tell?threadStop()?we?have?shut?ourselves?down?successfully synchronized?(threadSync)?{ //該處理器線程退出,通知其他processor threadSync.notifyAll();} }

未完待續

轉載于:https://my.oschina.net/zjItLife/blog/608576

總結

以上是生活随笔為你收集整理的servlet解析演进(2-1)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 97视频精品| 欧美丰满熟妇xxxxx | 美国一级特黄 | 丁香花国语版普通话 | 欧美jizzhd欧美18 | 美女福利视频网 | 久久神马影院 | 久草福利资源在线观看 | 一区二区三区精品免费视频 | 韩国精品一区二区三区 | 亚洲人人精品 | 成人在线免费播放视频 | 熟睡人妻被讨厌的公侵犯 | 巨胸喷奶水www久久久免费动漫 | 欧美日韩国产在线 | 无码国精品一区二区免费蜜桃 | 亚洲尹人 | 亚洲瘦老头同性xxxxx | 少妇久久久久久久久久 | 亚洲一区二区三区av无码 | 欧美性三级| 久草中文在线视频 | 日韩欧洲亚洲AV无码精品 | 91精品国产乱码久久 | 一区www | 操碰在线视频 | 国产aa大片| 亚洲欧美综合 | 永久免费看片 | 天天摸天天做天天爽 | av免费观看入口 | 自拍亚洲国产 | 国产精品网站在线观看 | 色老头免费视频 | 三级男人添奶爽爽爽视频 | 天天干天天操天天 | 在线观看av网 | 久久久精品人妻无码专区 | 欧色av | 国产中文字字幕乱码无限 | 亚洲精选久久久 | 精品国产乱子伦 | 九月婷婷 | 成年人网站免费看 | 青青草在线播放 | 无码国产精品一区二区高潮 | 欧美一级片网站 | h片在线观看 | 毛片久久久 | 久久国产精品-国产精品 | 欧美日韩免费观看视频 | 日韩精品一区二区三区网站 | 成人小视频免费 | 一级免费黄色 | 一级黄色美女视频 | 狠狠噜噜 | 中文无码日韩欧 | 精品动漫一区二区三区在线观看 | 无码人妻一区二区三区免费n鬼沢 | 亚洲中文字幕久久无码 | 欧美 日韩 国产 一区 | 国产精品久久久久久久久久妞妞 | 91九色国产ts另类人妖 | 884aa四虎影成人精品一区 | 成人欧美一区二区三区黑人一 | 91精品国产综合久久香蕉 | 在线观看视频福利 | 三及毛片 | 香蕉视频在线免费播放 | 亚洲色图二区 | 国产剧情在线 | 性巴克成人免费网站 | 欧美在线观看www | 国产精品无码一区二区三区在线看 | 超碰在线99| 日韩在线观看 | 国产日韩精品视频 | 成人av网址大全 | 污污在线免费观看 | 精品国产乱码久久久久久预案 | 成人91免费视频 | 明日花绮罗高潮无打码 | 国产成人小视频 | 成人片在线播放 | 欧美精品中文 | 国产丰满麻豆 | 欧美三级视频网站 | 成人一级视频在线观看 | 中文字幕av影院 | 色桃视频| 精品人伦一区二区三区蜜桃网站 | 黄色大片免费观看 | 秋霞午夜影院 | 欧美日本韩国在线 | 伊人五月综合 | 日韩一级黄| 国产视频一区二区不卡 | 国产香蕉一区二区三区 | 久久偷看各类女兵18女厕嘘嘘 |