1. 程式人生 > >分散式系統研發初體驗

分散式系統研發初體驗

原文 我終於深入參與了一個分散式系統了,好多想法不一樣了!

來自 伯樂線上 http://blog.jobbole.com/73590/

前言

過去兩個月深入的參與了一個分散式系統的開發,記得之前有人說過“想成為架構師之前,都是從微觀架構開始的”。儘管我從沒想過將來的某一天要成為一個架構師,或者領域專家,我只是想萌萌噠的編碼,寫著自己喜歡的Code,和一群志同道合的朋友做出大家喜歡的商品和產品。但是工作久了慢慢的搭架子的事情還是會來到你的面前,因為時間總會把一部分人慢慢推向海邊,使得他們成為最早見到陽光的人。

不扯淡了,為什麼要說陽光呢,還是因為過去的兩(三)個月可能過的太充實也太痛苦了,完成之後,曙光來臨的時候整個人是會發光的哦。“深度”參與是因為我終於有機會在搭架子的過程中有了話語權和選擇權,同時也會承擔70%以上的編碼工作。

之前我的自我認知是我可能在軟體方面的積累還可以,比如設計模式,架構分層,程式解耦,API入手等方面,但是總覺得我在硬體網路方面積累的太少,太薄了。

比如:

  • 不同操縱系統之間的特點;
  • 網路埠管理與分發;
  • 哪些網路協議可以幫助我們更好的完成工作,監控虛擬機器的時候是在虛機上加代理好還是用協議去控制;
  • 硬體是否支援分散式,在擴充套件過程中對於.net C#的相容怎麼樣;
  • 什麼時候使用多執行緒,在把執行緒交給程式排程的時候我們怎麼控制和捕捉執行緒的異常;
  • 日誌系統對於整個分散的系統是多麼的重要;
  • 何時使用關係資料庫,什麼時候使用Nosql;
  • 訊息佇列用擅長的MSMQ還是RabbitMQ.
  • 怎樣有效的和其他部門的同事溝通;
  • 用什麼樣的方式去有效排程不同語言開發的系統;
  • 測試用例對於大系統從零散到完整是多麼的重要;
  • 系統標準,程式碼原則對於後期的維護餘擴充套件是多麼的重要;
  • 等;

專案簡介

首先專案詳細內容不便多說,簡答的說,就是為國內某大型廠商建立一套協調其自身搭建的私有云以及其購買的公有云的一套系統。說牛X一點就是:一套混合雲系統。

使用Restful

這是在構建完整個系統最大的收穫,之前使用web api的經驗只是為電商系統的移動終端提供資料互動的介面,但是在這次專案之後發現Rest介面的不僅作為我們系統向外部系統提供互動的方式,同時在一些開源工具其暴露出來的介面也是基於rest的,可見全世界的程式設計師對於json對於rest有多麼的喜愛;

為什麼裝上軟體配置完成之後使用不了

之前的開發經驗由於使用的都是微軟的技術包括組建,工具。但是在專案中使用一些開源工具之後,配置成功之後卻總也跑不起來,同時由於開源工具已將Exception封裝起來,我們很難知道具體是什麼樣的問題,有的時候除錯好久還是跑不起來,很沮喪也很懊惱,結果最後發現是由於公司IT只是將常用的埠開啟,其他的都幹掉了,如果申請開放埠的話還要走流程,於是對於開發人員有時候有一臺外網的開發虛擬機器也是相當的有必要的。

使用RabbitMq

個人是非常的喜歡使用Mq的,之前做電商總喜歡在Application層下面放入一層Service,你可以不用但是總會強迫症似的不去不寫。為什麼不用Msmq呢,原因是有很多了,簡單點就是rabbit要比Msmq的協議更加高階,支援的處理功能也更加豐富,最重要的原因是Rabbit在開源語言使用上是佔領先地位的,而且我們的系統又要嫁接太多的開源語言系統,最後只能適配他們嘍。

之前知道Mq在企業系統間資料互動使用頻繁,不但能有效的劃分層次,解耦依賴,同時資料互動方式上也相當的便捷。總會有訊息沒有被消費者使用,那我們就需要程式非同步的去處理這個訊息隊列了。

Redis

系統中使用了三種資料儲存,MySql,SqlServer,Redis,當然前兩種適用於開源和C#,而Redis的使用則是為了那些總是難以找到有效關係和依賴的資料,比如之前只是知道Reids可以作為資料的儲存,可以分散式,可以主從複製,但是在這次開發之後更真真的發現Reids或者Nosql對於一個數據規則難以掌握,資料量大的系統是多麼的重要,因為有的時候一批的Json串過來之後,難以有效的挖出裡面的關係與邏輯,索性就一次性將他們放入Redis中吧,使用時再反序列吧。同時建立讀寫分離的原則,我們主要將讀放在了Redis裡面,寫到了Mysql,並通過Mysql的觸發器實現伺服器段資料的主從複製同步。

日誌系統

之前我們的單一系統的時候,比如只是簡單的3層架構的話,我們通過Debug可以從頭debug到資料庫,每一步都是掌握在手底下,每一步都盡收眼底。可是對於這一個層次太深,組建呼叫較多,同時又是多執行緒的系統來說,挖到雷的機會,時間,成本都是要考慮的。於是有效的使用日誌元件,有效的在程式碼中埋雷就顯的尤為迫切和必要,能夠更好的幫助我們找到問題所在。

元件式開發

之前的簡單分層系統我們通過Svn或其他的程式碼管理工具,每次提交都可以Merge看的到,但是當系統龐雜同時系統獨立性很強的時候,分組建,分模組開發就顯得很重要。因為不想浪費大家一起Merge的時間,我們習慣性每個人有自己的Branch每週2的時候提交程式碼,大家一起參與,這樣減少了好多因為程式碼管理浪費的時間。

測試用例

之前小的系統使用測試用例基本就是裝B用的,本來小小的系統整套流程腦子一想就可以知道怎麼做啦,為什麼還要浪費時間。可是在這次開發中充分理解了測試用例的重要性。比如我需要你給我提供多臺伺服器的監控資料包括CPU資訊,IO資訊,NEt資訊等等,但是你還沒有想到怎麼樣去抓取虛擬資訊,不能因為你的問題去影響其他人的進度的,最好的方式從使用者角度獲知他希望使用什麼樣的資料,為其建立API,同時為API建立測試用例並保證測試穩定。而後期我有了監控虛機的方式之後我在建立對應的適配方法適配到對應的API上。

所以首先肯定要保證API的穩定,因為他之上的東西已經穩定了嗎,你只好辛苦啦,有效的測試用例可以幫助我們更好的剝離專案邏輯與協調元件系統。

編碼原則

這個主要是每週有時間大家一起參與Code Review,由於開發人員的能力不同資歷不同,所以總會在程式碼的編寫上和建立出現太多的不統一。比如命名啦,變數宣告啦,有的時候會發現剛畢業的小朋友會將好多的私有變數放在類的頂部,同時一個類裡寫太多的方法,而且有的方法好長,還沒有註釋。於是有的時候你想了解一個方法的真正含義,要滑鼠各種滾動,到變數宣告去了解真正用途,好煩的。

有的時候程式碼的職責不明確,總是瀑布的思想方式去寫程式碼,比如我們兩個功能:一個是傳送API請求建立虛擬機器,另一個是在虛擬機器建立成功時候將操作Log寫入db。他們習慣性的將寫DB的邏輯放在了傳送HTTPRequst的方法裡面,這完全是兩個邏輯。另一個問題是由於建立虛擬機器是需要時間的,同時儘管虛擬機器操作成功有可能你寫DB的時候網路原因DB失敗了。我認為這應該是個原子的操作,兩者的狀態必須統一,就像是你在手機充值的時候顯示銀行卡扣金額成功,可是手機充值是出現問題,錢不是白花了嗎。所以在這些有特殊邏輯的地方要建立特殊的統一的機制,不能每個人有各自的實現。

之後就是溝通了

由於專案涉及到多個專案組,我們並不是同一個部門,相互也不熟悉,所以溝通上就會有一些需要注意的。首先要了解“對手”,主要是因為如果對方是個技術高手,你不能像個白痴小孩,要有所準備,最起碼知道他們用什麼開發語言,他們需要關注的業務邏輯,等等,不能讓他們得到你是個菜鳥的結論。

由於口頭的好多東西可能是沒有經過檢驗的東西,所以前幾次達成的協議我們只是做個參考,需要多次溝通之後才能確定結果,比如我們的專案中我們需要和Python組Java組協調訊息介面,訊息格式的時候。你要知道協調RabbitMQ時候我們需要定義下互動的Exchange,queue name 或者RoteKey等等,同時由於訊息格式比較大,需要定義一些關鍵字或者預設欄位的話,需要發郵件進行確認與溝通,避免開發過程中產生誤會影響完成的功能返工。

總之這次搭架子的過程收穫很多,一時半會也不能想的全面,以後慢慢聊,由於是第一次資歷尚淺,好多的技術選型,問題考慮可能不成熟,也希望大家知道更多的能夠糾錯指導。

下面就說一些我們在架構中使用的一些東西:

開發語言:C#,java,Python;

資料儲存:快取,檔案(xml),MSsql,Mysql,Redis;

資料互動:rest,json,RabbitMq;

作業系統:ubuntu,windows;

虛擬機器監控:zabbix;

搜尋:solr;

多執行緒,多層架構,模組式開發,元件式開發;