使用systemd,把服務裝進 Linux 心臟裡~
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,歡迎新增好友,進一步交流。
推薦閱讀:
3. 藍芽如夢
4. 殺機!
5. 失聯的架構師,只留下一段指令碼
6. 架構師寫的BUG,非比尋常
7. 有些程式設計師,本質是一群羊!
小姐姐味道
不羨鴛鴦不羨仙,一行程式碼調半天
346篇原創內容
- 架構師:比起 404,我們更怕 200!
- 完全使用Linux替換Windows之後,我覺得自己非常愚蠢
- sudo,代表了Linux的絕對霸權!
- 讀懂HikariCP一百行程式碼,多執行緒就是個孫子!
- 看到就是賺到!當 LinkedList 不是列表時,速度快的兔子都追不上!
- 讀懂HikariCP一百行程式碼,多執行緒就是個孫子!
- 老闆覺得冷,服務如何縮容?
- 這些傻白甜的Linux命令,不會有人教你!
- 這些傻白甜的Linux命令,不會有人教你!
- 使用systemd,把服務裝進 Linux 心臟裡~
- 不是所有有才華的人,都想當領導!
- 這些老系統程式碼,怎麼寫的這麼爛?
- 這些老系統程式碼,是豬寫的麼?
- 注意:雪花演算法並不是ID的唯一選擇!
- 注意:雪花演算法並不是ID的唯一選擇!
- 超極速優化:網路開發中的請求合併!
- 超極速優化:網路開發中的請求合併!
- 痛快!SpringBoot終於禁掉了迴圈依賴!
- 白瞎了你的 MackBook,這倆工具趕緊安排!
- 7 段小程式碼,玩轉Java程式常見的崩潰場景!