thrift長連接
Ⅰ 如何自己開發一套伺服器管理系統
轉載 表面上看,是一套基於B/S方式實現的分布式管理系統,但其實背後的架構是基於C/S完成的。你以為他是一隻鞋嗎?其實他是一個吹風機。作為界面化的系統,瀏覽器框架是不可或缺的,但更加重要的東西在Socket上面。
一、需要解決中央控制端到各節點伺服器之間的通信。
這個其實牽扯到一個通信協議的問題,各語言都有自己的socket,thread的庫,直接調用即可。但是這個通信協議就需要自己來完成了。既不能太簡單,太簡單了,明碼傳輸,如果別人獲知了這個介面,就很容易執行一些令人討厭的操作。也不能太復雜,太復雜了等於是給自己找麻煩,所以簡單的數據包編解碼的工作或者用token驗證的方式是需要的。通信協議起碼要兩種,一種是傳輸命令執行的協議,一種是傳輸文件的協議。
二、跨語言的socket通信
為什麼要跨語言,主控端和代理端通信,用什麼語言開發其實無所謂。但是為了給自己省事,盡可能使用伺服器上已經有了的默認語言,Ambari前期採用php+puppet的方式管理集群,這不是不可以,puppet自己解決了socket通信協議和文件傳輸的問題,可你需要為了puppet在每台伺服器上都安裝ruby。我是個有點伺服器和代碼潔癖的人。光是為了一個puppet就裝個ruby,我覺得心裡特對不起伺服器的資源。所以我自己寫了一個python的代理端。python是不管哪個linux系統在安裝的時候就都會有了。然後主控端的通信,可以用python實現,也可以用php實現,但是考慮到對於更多的使用者來說,改php可能要比改tornado簡單許多,所以就沒用python開發。hadoop分支版本眾多,發布出去,用戶要自己修改成安裝適合自己的hadoop發行版,就勢必要改源碼,會php的明顯比會python的多。php裡面的model封裝了所有的操作,而python只是個操作代理人的角色而已。
所以也延伸出一個問題,什麼語言用來做這種分布式管理系統的代理端比較合適,我自己覺得,也就是python比較合適了,操作系統自帶,原生的package功能基本夠用。用java和php也可以寫agent,但是你勢必在各節點預先就鋪設好jre或者php運行環境。這就跟為什麼用python和java寫mapred的人最多是一樣的。沒人攔著你用nodejs寫mapred,也可以寫,就是你得在每個節點都裝v8的解釋引擎,不嫌麻煩完全可以這樣干。原理參看map/rece論文,不解釋。perl也是操作系統原生帶的,但是perl的可維護性太差了,還是算了吧。
所以這就牽扯到一個跨語言的socket問題,理論上來說,這不存在什麼問題。但這是理論上的,實際開發過程中確實存在問題,比如socket長連接,通信數據包在底層的封裝方式不同。我沒有使用xml-rpc的原因之一就是我聽說php的xmlrpc跟其他語言的xmlrpc有不同的地方,需要修改才能用,我就沒有用這種辦法。最早是自己定義的操作協議,這時就遇到了這些問題,所以後來直接採用了thrift方式。就基本不存在跨語言的socket通信問題了。
三、代理端執行結果的獲取
無論命令還是文件是否在代理端執行成功,都需要獲取到執行結果返回給中央端。所以這里也涉及一個讀取節點上的stdout和stderr的問題。這個總體來說不是很難,都有現成的包。當然這個時候你需要的是阻塞執行,而不能搞非同步回調。
還有個問題是,我要盡可能使用python默認就帶的包,而盡量不讓伺服器去訪問internet下載第三方的包。
還有代理端最重要的一點,就是python的版本兼容性。centos5用python 2.4,centos6用python 2.6,ubuntu基本默認都是2.7。所以一定要最大限度的保證語言的跨版本兼容性,要是每個操作系統和每一個版本我都寫一個代理,我一個人就累死了。
四、瀏覽器端的model,view,controller
這裡面你要封裝好所有的通信協議,以及需要在節點上面執行的腳本。發送文件的操作和資料庫操作也要在model裡面完成。
如果對tcl/tk很熟,也可以寫基於操作系統界面方式的管理,不用瀏覽器就是了。
view對我來說是最痛苦的事,都是現學的jQuery怎麼用,前端的工作太可怕了。關於這方面,沒有太多可描述的,html和js帶給我的只有痛苦的回憶,萬惡的undefined。
五、跨操作系統的安裝文件封裝。
要適應不同的操作系統也是個很麻煩的事情,需要用agent提前獲知操作系統的發行分支,版本號。然後去找到對應的安裝文件去執行。你不能保證一個分布式系統的集群中所有的節點都可以訪問internet,更多的情況是這些節點都存在在一個安全的內網中。只有個別幾個節點是可以訪問外網的。所以,我勢必要把所有的安裝文件以及他們的依賴盡可能集中起來。我不確定安裝操作系統的lzo,yum或者apt-get會去下什麼鬼東西,甚至無論是yum還是apt-get,裡面都沒有hadoop-lzo的庫文件。所以,最好的辦法是自己編譯打包rpm和deb包。直接安裝就好了,別去找repo下載什麼。
這就是第五步工作,把需要的依賴的東西自己編譯打包成rpm和deb。
deb包很好解決,但是rpm就沒那麼好辦了,需要學習rpm的編譯文件如何編寫,這塊是挺麻煩的,但是這玩意用好了還是挺不錯的。現在我自製的安裝包裡面就已經包含了自己編譯的lzo和snappy兩種壓縮庫,以及hadoop-gpl-packaging的rpm和deb。下一個發布的easyhadoop將直接支持centos5,6,suse,以及ubuntu/debian的系統上安裝hadoop。已經自帶了lzo和snappy以及lzop和snzip。
六、把這些所有東西,整合到一個系統裡面。
關聯這些所有事情間的聯系,整合到一個瀏覽器界面裡面去。寫一個分布式的管理腳本不難,寫一個界面也不難,但是也許是我的水平不行,這兩件事結合起來讓他們協同工作還是有點難度的。對我來說,寫界面的工作可能更難一點。
Cloudera可能是十來個人在寫Manager的東西,ambari也是放到github和apache svn上面,apache基金會的各種committer在寫。easyhadoop沒他們功能那麼強大,一年來只有我一個人設計架構,功能,各種語言的編碼,測試,發布。For the love of god, What have I done(英文部分請站在山頂仰天長嘯)? T_T。從前台到後台,到hadoop和生態系統以及他們的依賴軟體的單獨patch、編譯打包。(系統yum或者apt-get的包不如自己打的好使。)
從時間上來看,全球第一款開源的hadoop部署管理系統應該還是屬於ambari,2011年8月開始寫的,2012年9月底進入apache的incubator。我是大概2012年8月開始寫的easyhadoop,全球第一沒趕上,估計國內第一個開源的hadoop管理系統還是可以排上的。
Ⅱ 2017年,Web 後端出現了哪些新的思想和技術
1. 網路交互的多樣性
1.1 Http1.1協議日漸式微,Http2和websocket,以及更多的自定義協議將會成為主流。
Web後端將不僅僅是一個web後端,而變成一個大後端,或者叫 中端+後端(這個概念阿里巴巴很早就有了)。隨著移動互聯網的發展,以及物聯網的興起(在這里我把mobike的單車看作是物聯網的一個終端),用戶的接入方式由單純的瀏覽器,向著多種接入設備進行演進。 在這個概念之下,用戶的定義會更廣泛,站在後端的角度看來,連接上伺服器的不再是一個個的用戶,而是一個個的終端,並存在多個終端同享一個用戶的情況(多端登錄)。 因此在這個趨勢之下,整個後端的接入層(比如nginx之於web)將會走向更廣闊的天地,對於任意一個設備來說,他將同時利用多種協議和多種方式連接到不同的接入點來達成自身的功能。
1.2 網路協議與網路信息交互的樣式多樣性
從最早的webService,到後來的json-rpc,和thrift再到如今的 protobuf(grpc)等等,我們開始為不同的數據交互設計了不同的序列化協議和調用協議,然而受到環境(移動終端的弱網路狀態),性能(網關服務,與網路調用)的影響,我們開始使用大量容錯性更強,數據量更小的數據傳輸方式,來滿足我們的需求。
在早先的web中,http+from表單的提交成為我們的標配,然而在今天,TCP都不一定成為必選項,UDP和UDP的改進協議都在被不同的公司進行嘗試,甚至於KCP都有可能成為大家考慮的方案之一。
2.數據多樣性開始成為設計的焦點。
2.1 在早先的web後端中,表設計和功能開發構成了日常工作的絕大部分,所有的後端人員都在試圖讓一切的用戶操作落入CRUD的抽象范疇里(比如 Restful),然而CRUD怎麼會滿足我們的抽象需求呢。
自從memcached和redis在被大量引入後端開發之後,我們可以看到,後端人員在對數據的理解上有了大量的改變,我們不再單單把數據視為RDBMS裡面的一行,而是圍繞著業務本身對數據進行了分類。最明顯的是,狀態數據的引入,在開發中,我們將用戶的部分信息,視為一個用戶的狀態,在狀態數據的基礎上,讓用戶的行為變成狀態遷移的觸發,在表現上看我們讓用戶的信息存儲到redis和memcached 里就是最RDMBS不能有效滿足我們的抽象需求的一次改進。
2.2 從狂熱的Nosql到Nosql和RDBMS的共存,代表了後端開發人員對數據這一個方式的新理解,而傳統的行存儲到列存儲,到監控常用的基於時間序列的資料庫都開始進入了我們的視野。
幾年來,大量的開發者,開始將用戶產生的數據進行了更詳細的歸類,不再是rdbms一刀切的方式, 我們會詳細地劃分出用戶的狀態數據落入到Nosql,將用戶的操作數據落入到RDBMS(表述不一定全,但在類似於訂單支付之類的具有冪等性要求的操作中要求事務的完備等),將用戶的行為統計落入時間序列資料庫, 將用戶的大量相關資源(如頭像圖片)將會落入到我們的對象存儲中。在後端開發的手冊里,數據格式的多樣性成為了必須考慮的問題。
3.圍繞著數據的收集,存儲,計算,索引查詢,分析 成為後端的常態
3.1 後端角色的含義,在人手不足的公司里,很難存在一個專注於後端業務開發的開發人員了,在大數據的浪潮下,後端開發人員開始兼職起了數據系統的開發工程師。 隨著互聯網大量技術的演進和發展,任何一個職業都很難找到一個明確的界限,因此圍繞著數據的收集,存儲,計算,分析,和索引查詢都會成為後端開發人員的必備技能。
3.2 數據收集
(1) 隨著分布式,集群化,多IDC的發展,不同於運維的系統性能收集,後端開發開始著重於收集與應用運營過程相關的各類指標和數據,
除了日常的業務開發,同時還會伴隨著應用調用過程的耗時,目標服務可用性等數據的收集,常見的如java的 metrics,zipkin等開源第三方的工具開始被廣泛借鑒和引用。
(2) 用戶行為和終端信息的上報收集,隨著大數據的開展,以及精細化運營的要求,後端逐漸開始接觸到用戶相關信息和終端運行狀態的信息上報,
收集上來的數據不僅用於用戶的畫像分析,同時也為客服的用戶追蹤,用戶的操作行為做出決策,通常表現在當用戶投訴某一筆業務的失敗時,便於開發人員的快速定位和排錯。
3.3 數據存儲
接著上面的數據收集,數據的傳輸和存儲成為了繞不開的功能,kafka的大規模運用,HDFS,HBase等工具也開始成為了後端開發日常的一部分。
3.4 數據計算
然而存儲的原始數據是沒有價值的,後端又開始了他們的數據清洗和數據處理的道路,storm,spark成為了後端的新秀,與用戶運營統計分析(俗稱跑策略跑演算法)不同,當前語境下的後端數據計算,更多是一個短耗時,小規模的計算,典型的則比如風控系統,和預警系統,針對用戶的行為和流量的多少,對惡意用戶進行甄別和快速干預。
3.5 數據索引查詢
(1) 隨著業務的擴充,任意一個app幾乎都內置了相應的搜索引擎,Lucene,solr也成為了後端程序員必備的技能之一,不管是精確搜索,還是模糊匹配,後端身上背負的業務也越來越多。
(2) 准實時數據的搜索也將成為常態,在近幾年的發展中,如何快速地在一個巨量的數據中,完成RDBMS中的 join,distinct統計等成為後端工程師不得不面對的問題
3.6 數據分析查詢
AI和深度學習已經拉開了序幕,圍繞著數據本身的挖掘,學習,也開始成為了產品側的需求,但理想歸理想,現實歸現實,後端的同學們在這個方向上仍然還是摸索狀態,但長遠來說跑不了了。
4.架構設計的更進一步
2017年裡,SOA的名詞正在淡出視野,微服務成了替代SOA的高頻詞,Serverless也開始走向了廣大後端的知識技能圖譜,不管是追新也好,滿足需求也罷,我也向諸位舉例一些常見的單詞,然而掛一漏萬請諸位擔待
4.1 CQRS(命令查詢職責分離模式)
將傳統CRUD的寫操作,進行非同步化,後端配合讀寫資料庫的分離。以及消息隊列的引入,將寫操作相關的一些耗時操作(驗證,走流程)等進行非同步化,常見的如電商中的訂單。
4.2 actor
Erlang的actor的興起,不管是golang Goroutine,還是scala/java的akka,都在深刻地影響著後端系統的架構設計。
4.3 CRDT和最終一致性
分布式系統的興起,也帶來了可用性和一致性的矛盾問題,協同兩個進程間的數據成為了每一個後端繞不過去的坎,為了達成最終一致性,各類方案如雨後春筍般冒出。
4.4 reactive
當android上的流行庫Rxjava,從前端走向後台的時候,也意味著後端也開始進入了響應式編程的時代,java的 vert.x就是其中的例子,那種request-response一招破萬法的時光不再有了。
5. 運維和devops對後端的要求
5.1 安全,穩定,高效,經濟
(1) 隨著業務走向穩定,以及互聯網的發展,網路服務的安全性開始成為了後端的核心之一,由於法律的不健全,對違法分子的追責難度大,違法成本低,網路安全攻擊將會在將來的一段時間內成為常態,這就對後端的程序特別是對外的介面設計提出了更高的要求。
(2) 多機房,異地容災,數據備份。健壯的後端一直是後端應用的要求之一。新的時間里,後端的可用性,穩定性依然是每一個後端都要面對的問題。
(3) 以前一個用戶只有一個電腦,瀏覽網站的時候,只在獲取數據的時候與站點有交互。現在隨著電子設備,智能設備的增多,一個用戶能夠接入網路的設備也在增多,同時長連接和並發數也會增多,因此高性能的接入網關開始成為了後端人員關注的焦點,比如圍繞著intel的dpdk各類應用也是紛至沓來。
(4) 經濟,利用雲服務的即買即用,用完即退的特點,使得在開展運營活動的時候,後端不用向運維徵求和購買大量的機器。 然而為了在運營活動的短時沖擊和突增流量的情況下後端應用能夠平穩地運行,對後端人員的部署和調度能力提出了更高的要求。
5.2 更規范的軟體開發流程
git+jenkins+ansible的開源組合,開始無法滿足開發和運維的需求,項目管理的集成,測試人員的介入,都要求後端的軟體工程工具從各自為陣的開源工具,走向一個大一統的系統,需要我們將 需求,BUG管理,迭代版本,開發,測試,灰度,藍綠部署流程都進行集成。
5.3 雲服務,容器化之爭
公有雲,私有雲,混合雲,以及容器等相關的雲計算技術,也在推動者後端的技術改革,後端面對的不再僅僅是一個物理機器,或者虛擬機,而是一個更復雜更多樣性的環境,對後端業務之外的技術和調度要求將越來越高。
相對於前端,後端實在是一個特別籠統的說法,正如上面提出的觀點,很多的技術其實並不屬於後端工程師,他們有的時候叫 運營開發工程師,有的叫大數據工程師,但為了相對於前端的劃分,因此我把他們的工作內容都劃到了後端裡面去,畢竟相對於技術研究,他們面對的都是一些技術應用的場合,很多的開源軟體只要達到了理解原理如何使用的水平就已經足夠應付日常工作了。
Ⅲ java Nio讀寫為什麼是雙向
作者:美團技術團隊
鏈接:https://zhuanlan.hu.com/p/23488863
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請註明出處。
NIO(Non-blocking I/O,在Java領域,也稱為New I/O),是一種同步非阻塞的I/O模型,也是I/O多路復用的基礎,已經被越來越多地應用到大型應用伺服器,成為解決高並發與大量連接、I/O處理問題的有效方式。
那麼NIO的本質是什麼樣的呢?它是怎樣與事件模型結合來解放線程、提高系統吞吐的呢?
本文會從傳統的阻塞I/O和線程池模型面臨的問題講起,然後對比幾種常見I/O模型,一步步分析NIO怎麼利用事件模型處理I/O,解決線程池瓶頸處理海量連接,包括利用面向事件的方式編寫服務端/客戶端程序。最後延展到一些高級主題,如Reactor與Proactor模型的對比、Selector的喚醒、Buffer的選擇等。
註:本文的代碼都是偽代碼,主要是為了示意,不可用於生產環境。
傳統BIO模型分析
讓我們先回憶一下傳統的伺服器端同步阻塞I/O處理(也就是BIO,Blocking I/O)的經典編程模型:
{
ExecutorService executor = Excutors.newFixedThreadPollExecutor(100);//線程池
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(8088);
while(!Thread.currentThread.isInturrupted()){//主線程死循環等待新連接到來
Socket socket = serverSocket.accept();
executor.submit(new ConnectIOnHandler(socket));//為新的連接創建新的線程
}
class ConnectIOnHandler extends Thread{
private Socket socket;
public ConnectIOnHandler(Socket socket){
this.socket = socket;
}
public void run(){
while(!Thread.currentThread.isInturrupted()&&!socket.isClosed()){死循環處理讀寫事件
String someThing = socket.read()....//讀取數據
if(someThing!=null){
......//處理數據
socket.write()....//寫數據
}
}
}
}
這是一個經典的每連接每線程的模型,之所以使用多線程,主要原因在於socket.accept()、socket.read()、socket.write()三個主要函數都是同步阻塞的,當一個連接在處理I/O的時候,系統是阻塞的,如果是單線程的話必然就掛死在那裡;但CPU是被釋放出來的,開啟多線程,就可以讓CPU去處理更多的事情。其實這也是所有使用多線程的本質:
利用多核。
當I/O阻塞系統,但CPU空閑的時候,可以利用多線程使用CPU資源。
線程的創建和銷毀成本很高,在Linux這樣的操作系統中,線程本質上就是一個進程。創建和銷毀都是重量級的系統函數。
線程本身佔用較大內存,像Java的線程棧,一般至少分配512K~1M的空間,如果系統中的線程數過千,恐怕整個JVM的內存都會被吃掉一半。
線程的切換成本是很高的。操作系統發生線程切換的時候,需要保留線程的上下文,然後執行系統調用。如果線程數過高,可能執行線程切換的時間甚至會大於線程執行的時間,這時候帶來的表現往往是系統load偏高、CPU sy使用率特別高(超過20%以上),導致系統幾乎陷入不可用的狀態。
容易造成鋸齒狀的系統負載。因為系統負載是用活動線程數或CPU核心數,一旦線程數量高但外部網路環境不是很穩定,就很容易造成大量請求的結果同時返回,激活大量阻塞線程從而使系統負載壓力過大。
現在的多線程一般都使用線程池,可以讓線程的創建和回收成本相對較低。在活動連接數不是特別高(小於單機1000)的情況下,這種模型是比較不錯的,可以讓每一個連接專注於自己的I/O並且編程模型簡單,也不用過多考慮系統的過載、限流等問題。線程池本身就是一個天然的漏斗,可以緩沖一些系統處理不了的連接或請求。
不過,這個模型最本質的問題在於,嚴重依賴於線程。但線程是很"貴"的資源,主要表現在:
所以,當面對十萬甚至百萬級連接的時候,傳統的BIO模型是無能為力的。隨著移動端應用的興起和各種網路游戲的盛行,百萬級長連接日趨普遍,此時,必然需要一種更高效的I/O處理模型。
NIO是怎麼工作的
很多剛接觸NIO的人,第一眼看到的就是Java相對晦澀的API,比如:Channel,Selector,Socket什麼的;然後就是一坨上百行的代碼來演示NIO的服務端Demo……瞬間頭大有沒有?
我們不管這些,拋開現象看本質,先分析下NIO是怎麼工作的。
常見I/O模型對比
所有的系統I/O都分為兩個階段:等待就緒和操作。舉例來說,讀函數,分為等待系統可讀和真正的讀;同理,寫函數分為等待網卡可以寫和真正的寫。
需要說明的是等待就緒的阻塞是不使用CPU的,是在「空等」;而真正的讀寫操作的阻塞是使用CPU的,真正在"幹活",而且這個過程非常快,屬於memory ,帶寬通常在1GB/s級別以上,可以理解為基本不耗時。
下圖是幾種常見I/O模型的對比:
以上都是小編收集了大神的靈葯,喜歡的拿走吧!喜歡小編就輕輕關注一下吧!
Ⅳ tcp通道關閉時,發生了什麼 time_wait close_wait
當第一次遇到這種問題的時候,你可能會有如下的問題:
其實,你真正想問的是:
TCP通道是一個連接,連接的兩端都可以向通道里寫數據或者從通道里讀數據,連接的兩端都可以發起關閉操作。整個TCP通道的關閉流程如下:
A(socketfd:10) <——–TCP Connction ———-B(socketfd:20)
關閉A,則A向B發送FIN;
如果程序顯式的關閉了B,那麼B會向A發送一個FIN,然後B就處於LAST_ACK狀態了;
A在接受到B的FIN後,發出最後一個ACK,此時A就處於知名的TIME_WAIT狀態了。TIME_WAIT時間一般會比較長。
盡量避免TIME_WAIT過多的一端主動關閉socket
使用SocketPool,避免頻繁創建/關閉socket
提到Thrift ThreadPoolServer有時候會出現較多的close wait狀態,有朋友問我這是不是thrift的bug?寫過Server比較多的同志們應該能意識到這個問題的原因,不值得說,可是我今天實在是太郁悶無聊了,我就寫寫我的想法吧。
我覺得這當然不能算是Thrift的Bug,如果出現了這樣的問題,其實是因為錯誤的選擇了Server的類型,錯誤的實現了Client,過於保守的Server Max Connection配置等等原因。
對於ThreadPoolServer而言,每一個客戶端連接,Server端都需要提供一個固定的線程來維護,在空閑時,線程堵塞在read()操作,等待客戶端數據的到來。Thrift ThreadPoolServer中使用的默認線程池是定長線程池,意味著Server端能提供的線程池數是有限的。當線程用完時,新的連接將不能得到Server殷勤的服務,它不會在乎你的生死,你必須等待。
Server會接受這個連接,連接成功建立;
Server沒有合適的線程來處理這個連接,於是將這個連接放到暫存列表;
如果這個時候有線程空閑了,則一切順利,這個線程將接管這個連接;
但遺憾的是,我們沒有空閑線程,所以這個連接一直處於空閑狀態,直到客戶端程序timeout(如果設置了timeout的話);
連接timeout,意味著暫存列表裡的連接已經失效了,此時對應的socket處於CLOSE_WAIT中(出現了本文開頭的情況),遺憾的是,我們依然沒有空閑的線程來處理這個連接,所以它一直處於CLOSE_WAIT中。
終於,某一個時刻,有一個客戶端關閉了連接,我們有了空閑線程,它去查看暫存列表。發現有一個socket fd,嘗試去接管它,對這個fd執行read(),然後得到一個Connection Reset error,終於,我們可以優雅的關閉它了(CLOSE_WAIT結束)。
以上就是全部的故事。
Ⅳ 如何在Centos上搭建PHP+JAVA的伺服器
一、需要解決中央控制端到各節點伺服器之間的通信。
這個其實牽扯到一個通信協議的問題,各語言都有自己的socket,thread的庫,直接調用即可。但是這個通信協議就需要自己來完成了。既不能太簡單,太簡單了,明碼傳輸,如果別人獲知了這個介面,就很容易執行一些令人討厭的操作。也不能太復雜,太復雜了等於是給自己找麻煩,所以簡單的數據包編解碼的工作或者用token驗證的方式是需要的。通信協議起碼要兩種,一種是傳輸命令執行的協議,一種是傳輸文件的協議。
二、跨語言的socket通信
為什麼要跨語言,主控端和代理端通信,用什麼語言開發其實無所謂。但是為了給自己省事,盡可能使用伺服器上已經有了的默認語言,Ambari前期採用php+puppet的方式管理集群,這不是不可以,puppet自己解決了socket通信協議和文件傳輸的問題,可你需要為了puppet在每台伺服器上都安裝ruby。我是個有點伺服器和代碼潔癖的人。光是為了一個puppet就裝個ruby,我覺得心裡特對不起伺服器的資源。所以我自己寫了一個python的代理端。python是不管哪個linux系統在安裝的時候就都會有了。然後主控端的通信,可以用python實現,也可以用php實現,但是考慮到對於更多的使用者來說,改php可能要比改tornado簡單許多,所以就沒用python開發。hadoop分支版本眾多,發布出去,用戶要自己修改成安裝適合自己的hadoop發行版,就勢必要改源碼,會php的明顯比會python的多。php裡面的model封裝了所有的操作,而python只是個操作代理人的角色而已。
所以也延伸出一個問題,什麼語言用來做這種分布式管理系統的代理端比較合適,我自己覺得,也就是python比較合適了,操作系統自帶,原生的package功能基本夠用。用java和php也可以寫agent,但是你勢必在各節點預先就鋪設好jre或者php運行環境。這就跟為什麼用python和java寫mapred的人最多是一樣的。沒人攔著你用nodejs寫mapred,也可以寫,就是你得在每個節點都裝v8的解釋引擎,不嫌麻煩完全可以這樣干。原理參看map/rece論文,不解釋。perl也是操作系統原生帶的,但是perl的可維護性太差了,還是算了吧。
所以這就牽扯到一個跨語言的socket問題,理論上來說,這不存在什麼問題。但這是理論上的,實際開發過程中確實存在問題,比如socket長連接,通信數據包在底層的封裝方式不同。我沒有使用xml-rpc的原因之一就是我聽說php的xmlrpc跟其他語言的xmlrpc有不同的地方,需要修改才能用,我就沒有用這種辦法。最早是自己定義的操作協議,這時就遇到了這些問題,所以後來直接採用了thrift方式。就基本不存在跨語言的socket通信問題了。
三、代理端執行結果的獲取
無論命令還是文件是否在代理端執行成功,都需要獲取到執行結果返回給中央端。所以這里也涉及一個讀取節點上的stdout和stderr的問題。這個總體來說不是很難,都有現成的包。當然這個時候你需要的是阻塞執行,而不能搞非同步回調。
還有個問題是,我要盡可能使用python默認就帶的包,而盡量不讓伺服器去訪問internet下載第三方的包。
還有代理端最重要的一點,就是python的版本兼容性。centos5用python 2.4,centos6用python 2.6,ubuntu基本默認都是2.7。所以一定要最大限度的保證語言的跨版本兼容性。
Ⅵ 後端Node.js 與 Java 進行通信,請問有什麼好的實現思路嗎
1、一般來說復,像這種跨語言制的通信都是採用socket,因為對於網路傳輸,位元組流是統一的,但是需要自己有豐富的開發經驗去封裝這個通信層;
2、目前有很多流行的第三方中間消息件,即通信隊列,例如activeMQ,kafka,RabbitMQ等,支持集群和分布式部署,支持訂閱模式,也是很好的選擇,可以節省開發時間,保證高質量可用。