如何快速啟動服務

2021-09-19 12:38:10 字數 2909 閱讀 9160

在軟體開發中,通常的做法是將一些基礎,簡單的服務組合在一起而形成乙個具有某一功能的特定服務。這種搭積木的結構,或者說自下而上的組合更有利於程式的資源隔離以及維護與拓展。高層的服務依賴底層服務提供業務計算,低層的服務提供諸如資料儲存,網路傳輸等基礎操作。

這些低層的服務就如現實世界中的城市基礎設施,沒有道路車輛就無處行駛,沒有發電廠提供的電力所有的電力裝置就無法工作。所以,在程式世界構建的時候,這些基礎服務必須預先完成載入(初始化)。當低層介面與高層介面變得比較多時,它們的關係錯綜複雜。所以,合理地管理它們變得非常有必要!下面我們將討論幾種常見的模式:

一種非常簡單的方式是:將所有的服務按照依賴層級逐個地載入它們。如下圖, 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 2servicegroup 1載入完成之後才開始載入。

服務 a, b, d 之間沒有依賴,所以它們的載入可以是無序的。當servicegroup 1載入完成之後,servicegroup 2在載入之前就已經載入了必要的服務。這時候不會出現servicenotfound的問題。下面的**使用了 dsl 來描述整個載入的過程:

groupedservicebus servicebus = ...

servicebus.start(servicea, serviceb, serviced)

.then(servicec, servicee)

.awaitstarted();

銷毀的順序必須是載入順序的反序。這樣你才能保證不回出現必要服務的丟失。

import com.google.common.util.concurrent.service;

public inte***ce groupedservicebus

使用 dsl 的方式設計 api 能過讓它變得更加容易使用跟理解。

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 即可...