在軟體開發中,通常的做法是將一些基礎,簡單的服務組合在一起而形成乙個具有某一功能的特定服務。這種搭積木的結構,或者說自下而上的組合更有利於程式的資源隔離以及維護與拓展。高層的服務依賴底層服務提供業務計算,低層的服務提供諸如資料儲存,網路傳輸等基礎操作。
這些低層的服務就如現實世界中的城市基礎設施,沒有道路車輛就無處行駛,沒有發電廠提供的電力所有的電力裝置就無法工作。所以,在程式世界構建的時候,這些基礎服務必須預先完成載入(初始化)。當低層介面與高層介面變得比較多時,它們的關係錯綜複雜。所以,合理地管理它們變得非常有必要!下面我們將討論幾種常見的模式:
一種非常簡單的方式是:將所有的服務按照依賴層級逐個地載入它們。如下圖, c 分別依賴了 a 與 b 。在程式啟動的時候可以按照 a -> b -> c 的方式依次載入它們。
這種方式能夠有效地解決服務依賴,在服務不是特別複雜,依賴的鏈不是很長的情況下它會是乙個很不錯的選擇。但是這種方式會將整個服務啟動的時候變得很長,因為它們的載入是逐個進行的。因此在大型的服務中這種方式是不被推薦的。
另一種方式是按需載入,在服務被使用(呼叫)時,再去載入它所依賴的服務。如下圖,有 2 個高層服務 c 與 e,它們分別依賴了基礎服務 a,b 與 b,d。
當訪問 c 服務的時候,會按需載入 c b a。c 去嘗試找到並載入 b,b 也會嘗試找到並載入 a。這是乙個有返回的過程,所有使用符號表示。同理,e 服務的載入過程也是按照 e b d。
這種模式最大的優點是能做到按需載入,當高層服務被使用的時候才會去載入依賴的服務。在容器技術中也稱之為依賴注入
。為避免重複載入的過程,實際上我們會把這些服務放在乙個服務容器裡面,服務的載入會有容器處理,我們要做的僅僅是從乙個容器裡面找到它們。例如上圖中 c, e 都依賴了 b。
大多的應用服務都會選擇按需載入的模式,它不僅能避免有序載入的不能同時載入多個服務的問題,按需載入實際上因為不會載入那些無訪問的服務,所以能有效地節省一部分資源。
但這就是終極方案嗎?顯然不是!下面我們來了解第三種模式。
分組載入是將服務按照依賴的層級劃分稱不同的servicegroup
。servicegroup 之間是按照順序載入的,但 servicegroup 內的服務是並行載入的。這種方式能夠快速地將所有的服務一次性載入。與按需載入不同,分組載入可以在應用啟動成功之時就可以立即服務;同時對於按序載入能過做到更加快速地啟動服務。如下圖,servicegroup 1
中的a
,b
, 'c' 是並行載入的,servicegroup 2
在servicegroup 1
載入完成之後才開始載入。
服務 a, b, d 之間沒有依賴,所以它們的載入可以是無序的。當servicegroup 1
載入完成之後,servicegroup 2
在載入之前就已經載入了必要的服務。這時候不會出現servicenotfound
的問題。下面的**使用了 dsl 來描述整個載入的過程:
銷毀的順序必須是載入順序的反序。這樣你才能保證不回出現必要服務的丟失。groupedservicebus servicebus = ...
servicebus.start(servicea, serviceb, serviced)
.then(servicec, servicee)
.awaitstarted();
使用 dsl 的方式設計 api 能過讓它變得更加容易使用跟理解。import com.google.common.util.concurrent.service;
public inte***ce groupedservicebus
public inte***ce kernelservice
可以使用kernelservice
來指定哪些服務是必須正確載入的,當 kernelservice 載入失敗應用並不能提供乙個正確的服務,這時你也許可以將整個程式退出。
上面的public class groupedservicebusimpl implements groupedservicebus ] start failure, system will be exit 1.", service.getclass());
system.exit(1);
} else ] start failure.", service.getclass());}}
};@override
public void awaitstarted() }}
@override
public void awaitstopped()
servicecluster.clear();}}
@override
public groupedservicebus start(final service... services)
@override
public groupedservicebus then(service... services)
private void awaitstartedservicemanager(final servicemanager servicemanager) }}
servicecluster
是乙個servicemanager
的集合,在這裡servicemanager
就是我們上面講到的servicegroup
。在servicegroup
的所有服務都可以並行載入。
這三種模式沒有哪一種是絕對正確跟優秀的。在程式設計中,除了要考慮效能,穩定性等同時還要避免陷入過度設計的陷阱。你的選擇需要適應你的環境!
快速啟動MSSQLSERVER服務
如果你每次都是通過開啟 sqlservermanager 來啟動服務的話就太有耐心了。乙個批處理就能幫你搞定,絕對的事半功倍 echo offecho 1啟動服務 echo 2關閉服務 echo 3重啟服務 set p ans if ans 1 goto start if ans 2 goto st...
如何啟動httpd服務?
windows作業系統中,apache在windows nt下一般以服務方式執行,而在windows 95下則以控制台程式方式執行。詳情請參見在windows下執行apache。unix作業系統中,程式作為乙個守護程序執行,在後台不斷處理請求。本文件描述了如何呼叫httpd。如果配置檔案中liste...
如何啟動rsync服務
關於如何搭建rsync服務端,可以參考 這位寫的很不錯也很詳細。而我在這裡要寫的是如何啟動rsync服務,有時候時間長了就會忘了。沒有辦法呀,寫在部落格裡留下記憶。如果你的 rsync.conf是預設位置即 etc rsync.conf 那麼你直接執行 usr bin rsync daemon 即可...