使用systemd,把服務裝進 Linux 心臟裡~

語言: CN / TW / HK

theme: fancy

圖片

原創:小姐姐味道(微信公眾號ID:xjjdog),歡迎分享,轉載請保留此資訊。

Linux非常的安全、可靠,而且有一股黑黝黝的妹子味道,這說明她也是柔軟的。

把服務跑在Linux上,就像男生把女裝藏在密碼箱裡一樣讓人放心,它的穩定安全可以讓人安穩的睡個懶覺。

SPOF,是著名的單點問題。鑑於xjjdog非常討厭賣弄縮寫名詞的特點,我把它的全稱打在這裡:single point of failure。

一臺Linux是孤單一臺Linux,所以跑在上面的服務,就會有單點問題。解決單點問題通常可以通過叢集,也可以通過奢侈的影子節點來達到這個目的。

但無論怎麼搞,我們都希望跑在Linux上的某個程序,能夠隨著Linux的啟動自動啟動,隨著Linux的關閉自動關閉。我們希望自己的應用程式,就像是Linux的血肉一樣,就像是安裝在Linux的心臟裡。

準備程式

很長一段時間裡,我使用supervisor來做這種事情。但可惜的是,supervisor並不是Linux的預裝軟體,而且它是python寫的,需要裝一大堆依賴包。在網路許可權逐漸收緊的企業環境中,使用supervisor會給自己徒添煩惱。

是的,並不是supervisor不好,只不過它太麻煩。頻繁的網路許可權申請讓人抓狂,甚至喧賓奪主。

退而求其次,那就是systemd。

圖片

為了說明怎麼使用它,我們準備一段小小的Java程式。

``` import com.sun.net.httpserver.HttpContext; import com.sun.net.httpserver.HttpServer;

import java.io.OutputStream; import java.net.InetSocketAddress;

public class Runner {     public static void main(String[] args) throws Exception{         HttpServer server = HttpServer.create(new InetSocketAddress(14000), 0);         HttpContext context = server.createContext("/");         context.setHandler(exchange -> {             try {                 String response = "Ojbk!";                 exchange.sendResponseHeaders(200, response.getBytes().length);                 OutputStream os = exchange.getResponseBody();                 os.write(response.getBytes());                 os.close();             } catch (Exception ex) {                 ex.printStackTrace();             }         });         server.start();     } }

```

這段程式碼將在14000埠開啟一個Http伺服器,每當你訪問它的時候,它都會輸出Ojbk!。

``` curl http://localhost:14000

```

把程式搞成服務

要想讓上面的程式成為系統的一部分,需要將其服務化。

``` [Unit] Description=My First Java Service After=network.target StartLimitIntervalSec=0 [Service] Type=simple Restart=always RestartSec=1 User=root ExecStart=/usr/bin/env java /opt/Runner

[Install] WantedBy=multi-user.target ```

比較重要的就是ExecStart,它配置了你確切要執行的命令,我們這裡當然是一個簡單的class檔案。

給這個檔案起一個名字吧,比如xjjdogfirstjava.service,然後把檔案扔進/etc/systemd/system/目錄裡。

要啟動這個服務的話,直接執行下面的命令就好了。

``` systemctl start xjjdogfirstjava

```

如果你找不到剛剛建立的服務,記得reload一下。

``` systemctl daemon-reload

```

如果你想要它隨著Linux啟動的話,可以執行enable建立一個連結就可以了。

``` systemctl enable xjjdogfirstjava

```

除了這兩者,disable、stop、restart也是標配的指令。

注意到配置檔案裡有這麼2行內容。

``` Restart=always RestartSec=1

```

它表明,每當程式異常終止的時候,都會自動重啟這個程序,重啟的間隔是1秒。

更多一些的配置

我們注意到,上面的配置檔案裡,有After=network.target字樣。它表明當MySQL啟動完畢的時候,才會啟動xjjdogfirstjava服務,也就是強行指定了一個依賴關係。

但很多小夥伴在使用上面配置的時候,經常發現服務自動重啟幾次之後,就再也不會再重啟了。

等等,我們不是使用了Restart=always引數麼?

這是由於systemd預設內建了兩個閾值。

StartLimitBurst=5 StartLimitIntervalSec=10

當你把StartLimitIntervalSec設定成0的時候,目的就總算達到了,我們的程式可以一直一失敗,一直重啟下去。

雖然這樣,保持一個重啟間隔是一個比較好的習慣。因為大多數服務重啟的時候,都會造成伺服器資源的上升,如果你不想讓你的伺服器報警,那就不要這麼壓迫它。

End

這就是systemd,一個Linux內建的程式。有了它,你的應用程式終於能夠和Linux合為一體,天荒地老的伴隨下去了。

作者簡介:小姐姐味道 (xjjdog),一個不允許程式設計師走彎路的公眾號。聚焦基礎架構和Linux。十年架構,日百億流量,與你探討高併發世界,給你不一樣的味道。我的個人微信xjjdog0,歡迎新增好友,進一步交流。

推薦閱讀:

1. 玩轉Linux
2. 什麼味道專輯

3. 藍芽如夢
4. 殺機!
5. 失聯的架構師,只留下一段指令碼
6. 架構師寫的BUG,非比尋常
7. 有些程式設計師,本質是一群羊!

小姐姐味道

不羨鴛鴦不羨仙,一行程式碼調半天

346篇原創內容