在設計的前夕,設計人員喜歡把領導對將來業務的指望帶入到設計目標當中,好比當前業務也不過是接入幾千輛車,將來業務增加也不過幾萬臺,但領導不少激情,強勢要求二期平臺的接入能力要達到20萬臺,這個要求帶入到架構設計當中,不少人當即崩潰了,在設計的時候,意淫出不少奇妙的東西,很複雜的數據庫結構或者庫表,在設計的初期就早早的確立一些框架如MQ,Memcached,Ehcache等等,在後來的實際運行過程當中,因爲不熟悉,起到反面的做用,性能差,bug多。web
要知道設計和實現,是不一樣的人或團隊在作,若是設計的思路不能貫徹下去,走樣是必然的。sql
這在設計界有個定律,就是設計的越複雜,實現的時候,越難實現,開發週期越長,代碼越複雜,bug越多,功能越不穩定,性能越差,砸鍋的機率越大。數據庫
還有一個定律是:大部分設計者只具有了把事情搞複雜的能力,不具有把複雜的事情搞簡化的能力,因此領導的指望有多大,設計就有多複雜。設計模式
其實架構設計中有兩個可擴展性要求:服務器
一個是性能的可擴展,隨着接入車輛壓力的增大,不須要改動代碼,只須要增長硬件配置,如增長服務器,增長軟件運行的進程實例來達到要求;架構
一個是功能上的可擴展,在一個運營平臺上,同時爲多個不一樣的物流企業提供運營服務,各個企業必然有本身個性化的需求,想要吸引客戶,銷售上就得儘可能答應客戶的各類要求,技術上就要想辦法實現客戶的要求,可是其餘企業客戶八竿子用不着。隨便一個功能的增長,都要考慮對平臺的衝擊,多版本的維護,平臺穩定性等等。不少運營平臺都經歷過功能弱智簡單、功能豐富最後到臃腫再到最後推倒重來這樣的過程,而推倒重來的代價是,羅馬不是一晚上建成的,架構是美好的,不表明功能的完善和穩定,新版本的不穩定,功能的不完善,給運營又會形成極大的衝擊,客戶、客服、售後、市場銷售等連帶着怨聲載道,痛不欲生,紛紛追思舊版本如何如何的美好。因此推倒重來的代價是壯士斷腕,代價很大,不斷也不行,斷了就要經歷短時間的波動。框架
這兩點明確後,咱們知道本身的設計目標:異步
1) 性能可擴展方面分佈式
首先要面向服務進行設計,對子系統當中的調用接口進行定義,在子系統中加以實現,造成服務。這些服務能夠本地部署,能夠分佈式部署,服務的部署對於調用者來講是透明的,不影響的。作到了這一點,咱們才能夠在壓力來臨的時候,經過改變和增長服務器的配置,透明靈活的分佈式部署方式,來緩解壓力的上升。模塊化
面向服務的開發中,對於遠程方法調用的協議,Java的有RMI,DotNet的有WCF,都是很是好的能夠基於TCP二進制交換數據的協議,遠勝於webservice,但在設計的時候,能夠徹底不用考慮這些,在實現的時候,因爲如今的Spring框架很強大,僅僅經過幾行XML配置,就能夠將一個接口透出變成一個RMI服務或者WCF服務。
對於壓力的處理,愚蠢的設計是在一個功能裏反覆優化,好的設計每每是分而治之,經過不一樣的服務,來分擔壓力,如協議解析、入庫、消息通知、應答等分解成不一樣的服務,解析後調用入庫服務,解析程序只是簡單調用入庫服務的接口而後當即返回,而在入庫服務內部,則會經過異步處理保證服務調用後可以當即返回,而不是阻礙整個處理流程。
2)功能可擴展方面
這個實際上是最難的,由於它的要求是比較抽象,就是軟件要求可以修改完善添加現有的功能知足軟件將來的成長,直白點將就是軟件可以改動已知足用戶新增的需求。一些人可能會問,只要有代碼,能夠隨便改。若是是這樣,爲何咱們的客戶提出需求後,咱們老是拒絕。這是由於隨着功能的增多,代碼的增多,可維護性變差,修改某個功能的代碼,或者添加某項功能,會耗費大量的人力和時間,拔出蘿蔔帶出泥,打掃衛生把瓷器打碎,一句話,很難改。
不少弱智的設計,由於害怕將來的擴展,因此對實體類和庫表都保留了N多的擴展字段,由於不知道將來要作什麼用,而後起個無心義的名字,如data1,data2,data3,data4,還有f1,f2,f3這樣的字段,應對將來用戶擴展要求。這算是擴展設計嗎,很難想象,不只起不到做用,反而製造大量的垃圾,代碼的可讀性變的很是差。這種設計能夠休矣。把可擴展設計理解成冗餘設計,預留冗餘這種手段稱不上設計,將來也確定用不着。
什麼算是好的可擴展性,只能說,設計好的,代碼容易改動,容易添加功能,設計的很差的,一個小小的功能,能改出一頭汗,測試的時候,要回歸測試一大片。
可擴展性的設計原則只有兩個字。
軟件功能可擴展性設計最理想的是基於插件化或者模塊化的設計,經過動態加載、事件註冊、功能回調等機制,來達到要求,固然插件化的設計的弊端就是複雜,以複雜爲代價,甚至要犧牲部分性能,來達到軟件的可擴展性。
插件設計這個在部標GPS服務器的設計中用的比較多,對於不一樣的終端的協議,能夠基於插件化的設計,不一樣的協議,按照插件標準進行編寫,造成一個龐大的協議庫,在系統運行的時候,能夠靜態配置,也能夠動態加載,根據不一樣的車輛,不一樣的客戶,不一樣的設備,不一樣的版本,來加載不一樣的協議插件進行解析。
善於運用設計模式,也會提升可擴展性,如熟練運用模板模式,善於將數據和表現、格式分離。好比Ibatis框架,經過sql模板,將原有臃腫無聊的sql代碼剝離出來。大大提升了代碼的可讀性和可擴展性。