利用systemd部署golang項(xiàng)目的實(shí)現(xiàn)方法
簡介
- CentOS 7 繼承了 RHEL 7 的新的特性,例如強(qiáng)大的 systemd, 而 systemd 的使用也使得以往系統(tǒng)服務(wù)的 /etc/init.d 的啟動(dòng)腳本的方式就此改變, 也大幅提高了系統(tǒng)服務(wù)的運(yùn)行效率。但服務(wù)的配置和以往也發(fā)生了極大的不同,同時(shí)變的簡單而易用了許多。
- CentOS 7 的服務(wù) systemctl 腳本存放在:/usr/lib/systemd/,有系統(tǒng) system 和用戶 user 之分, 即:/usr/lib/systemd/system 和 /usr/lib/systemd/user
配置文件
- 這里我們先要說明一下 unit 的文件位置,一般主要有三個(gè)目錄:
/lib/systemd/system /run/systemd/system /etc/systemd/system
- 這三個(gè)目錄的配置文件優(yōu)先級(jí)依次從低到高,如果同一選項(xiàng)三個(gè)地方都配置了,優(yōu)先級(jí)高的會(huì)覆蓋優(yōu)先級(jí)低的。 系統(tǒng)安裝時(shí),默認(rèn)會(huì)將 unit 文件放在 /lib/systemd/system 目錄。如果我們想要修改系統(tǒng)默認(rèn)的配置,比如 nginx.service,一般有兩種方法:
- 在 /etc/systemd/system 目錄下創(chuàng)建 nginx.service 文件,里面寫上我們自己的配置。
- 在 /etc/systemd/system 下面創(chuàng)建 nginx.service.d 目錄,在這個(gè)目錄里面新建任何以.conf 結(jié)尾的文件,然后寫入我們自己的配置。推薦這種做法。
- /run/systemd/system 這個(gè)目錄一般是進(jìn)程在運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建 unit 文件的目錄,一般很少修改,除非是修改程序運(yùn)行時(shí)的一些參數(shù)時(shí),即 Session 級(jí)別的,才在這里做修改。
服務(wù)配置
- 每一個(gè)服務(wù)以.service 結(jié)尾,一般會(huì)分為 3 部分:[Unit]、[Service] 和 [Install],就以 nginx 為例吧,具體內(nèi)容如下:
[Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/docs/ After=network.target remote-fs.target nss-lookup.target [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s QUIT $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target
配置項(xiàng)說明
- 下面分別解釋下著三部分的含義
[Unit]
- Description : 服務(wù)的簡單描述
- Documentation : 服務(wù)文檔
- After= : 依賴,僅當(dāng)依賴的服務(wù)啟動(dòng)之后再啟動(dòng)自定義的服務(wù)單元
[Service]
- Type : 啟動(dòng)類型 simple、forking、oneshot、notify、dbus
- - Type=simple(默認(rèn)值):systemd 認(rèn)為該服務(wù)將立即啟動(dòng),服務(wù)進(jìn)程不會(huì) fork。如果該服務(wù)要啟動(dòng)其他服務(wù),不要使用此類型啟動(dòng),除非該服務(wù)是 socket 激活型
- - Type=forking:systemd 認(rèn)為當(dāng)該服務(wù)進(jìn)程 fork,且父進(jìn)程退出后服務(wù)啟動(dòng)成功。對(duì)于常規(guī)的守護(hù)進(jìn)程(daemon),除非你確定此啟動(dòng)方式無法滿足需求, 使用此類型啟動(dòng)即可。使用此啟動(dòng)類型應(yīng)同時(shí)指定 PIDFile=,以便 systemd 能夠跟蹤服務(wù)的主進(jìn)程。
- - Type=oneshot:這一選項(xiàng)適用于只執(zhí)行一項(xiàng)任務(wù)、隨后立即退出的服務(wù)。可能需要同時(shí)設(shè)置 RemainAfterExit=yes 使得 systemd 在服務(wù)進(jìn)程退出之后仍然認(rèn)為服務(wù)處于激活狀態(tài)。
- - Type=notify:與 Type=simple 相同,但約定服務(wù)會(huì)在就緒后向 systemd 發(fā)送一個(gè)信號(hào),這一通知的實(shí)現(xiàn)由 libsystemd-daemon.so 提供
- - Type=dbus:若以此方式啟動(dòng),當(dāng)指定的 BusName 出現(xiàn)在 DBus 系統(tǒng)總線上時(shí),systemd 認(rèn)為服務(wù)就緒。
- PIDFile : pid 文件路徑
- Environment : 環(huán)境變量(可以添加多個(gè))eg :Environment=REPO_REF=dev
- ExecStartPre :啟動(dòng)前要做什么,上文中是測試配置文件 -t
- ExecStart:啟動(dòng)
- ExecReload:重載
- ExecStop:停止
- PrivateTmp:True 表示給服務(wù)分配獨(dú)立的臨時(shí)空間
[Install]
- WantedBy:服務(wù)安裝的用戶模式,從字面上看,就是想要使用這個(gè)服務(wù)的有是誰?上文中使用的是:multi-user.target ,就是指想要使用這個(gè)服務(wù)的目錄是多用戶。
操作示例
- 每一個(gè).target 實(shí)際上是鏈接到我們單位文件的集合,當(dāng)我們執(zhí)行
systemctl enable nginx.service
- 就會(huì)在 /etc/systemd/system/multi-user.target.wants/ 目錄下新建一個(gè) /usr/lib/systemd/system/nginx.service 文件的鏈接。
常用的 service 操作
# 自啟動(dòng) systemctl enable nginx.service # 禁止自啟動(dòng) systemctl disable nginx.service # 啟動(dòng)服務(wù) systemctl start nginx.service # 停止服務(wù) systemctl stop nginx.service # 重啟服務(wù) systemctl restart nginx.service # 查看Unit定義文件 systemctl cat nginx.service # 編輯Unit定義文件 systemctl edit nginx.service # 重新加載Unit定義文件 systemctl reload nginx.service # 列出已啟動(dòng)的所有unit,就是已經(jīng)被加載到內(nèi)存中 systemctl list-units # 列出系統(tǒng)已經(jīng)安裝的所有unit,包括那些沒有被加載到內(nèi)存中的unit systemctl list-unit-files # 查看服務(wù)的日志 journalctl -u nginx.service # 還可以配合`-b`一起使用,只查看自本次系統(tǒng)啟動(dòng)以來的日志 # 查看所有target下的unit systemctl list-unit-files --type=target # 查看默認(rèn)target,即默認(rèn)的運(yùn)行級(jí)別。對(duì)應(yīng)于舊的`runlevel`命令 systemctl get-default # 設(shè)置默認(rèn)的target systemctl set-default multi-user.target # 查看某一target下的unit systemctl list-dependencies multi-user.target # 切換target,不屬于新target的unit都會(huì)被停止 systemctl isolate multi-user.target systemctl poweroff # 關(guān)機(jī) systemctl reboot # 重啟 systemctl rescue # 進(jìn)入rescue模式
Systemd + Golang Demo
- 下面例子通過 Systemd 部署一個(gè)最簡單的 Golang Web Server
package main import ( "flag" "fmt" "log" "net/http" ) func main() { var address string flag.StringVar(&address, "address", "5353", "listen address") flag.Parse() http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, This is a test for systemd !\n") }) // 設(shè)置訪問路由 log.Printf("Starting server on %s\n", address) log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", address), nil)) }
- 編譯代碼,并將可執(zhí)行文件同步到遠(yuǎn)程服務(wù)器上
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o systemd-test main.go rsync -zP ./systemd-test root@gp-aliyun:/usr/local/bin/
- 在遠(yuǎn)程服務(wù)器上編寫服務(wù)配置,放在 /etc/systemd/system/ 中
[Unit] Description=Systemd Test After=network.target [Service] User=nobody # Execute `systemctl daemon-reload` after ExecStart= is changed. ExecStart=/usr/local/bin/systemd-test -address "6060" [Install] WantedBy=multi-user.target
- 通過 systemctl 啟動(dòng)服務(wù)
# 每一次修改ExecStart都需執(zhí)行 systemctl daemon-reload # 啟動(dòng) systemctl start systemd-test.service # 查看狀態(tài) systemctl status systemd-test.service
- 狀態(tài)如下
- 可以通過 curl 進(jìn)行測試:
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Win7環(huán)境下搭建Go開發(fā)環(huán)境(基于VSCode編輯器)
這篇文章主要介紹了Win7環(huán)境下搭建Go開發(fā)環(huán)境(基于VSCode編輯器),需要的朋友可以參考下2017-02-02Goland 的安裝及激活教程(window、linux下安裝)
這篇文章主要介紹了Golang Goland 的安裝及激活詳細(xì)教程,包括window下安裝goland和linux下安裝goland,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10關(guān)于Go語言中特有的設(shè)計(jì)模式與實(shí)現(xiàn)方式講解
雖然Go語言沒有像其他語言那樣明確的設(shè)計(jì)模式,但在實(shí)踐中,開發(fā)者們?nèi)匀话l(fā)現(xiàn)了一些在Go語言中特別適用的設(shè)計(jì)模式和實(shí)現(xiàn)方式,本文就來和大家一一進(jìn)行講解2023-05-05go語言發(fā)送smtp郵件的實(shí)現(xiàn)示例
這篇文章主要介紹了go發(fā)送smtp郵件的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09go語言yaml轉(zhuǎn)map、map遍歷的實(shí)現(xiàn)
本文主要介紹了go語言yaml轉(zhuǎn)map、map遍歷的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09Golang使用Docker進(jìn)行集成測試的示例詳解
集成測試需要解決外部依賴問題,如?MySQL、Redis、網(wǎng)絡(luò)等依賴,本文就來聊聊?Go?程序如何使用?Docker?來解決集成測試中外部依賴問題吧2023-07-07golang(gin)的全局統(tǒng)一異常處理方式,并統(tǒng)一返回json
這篇文章主要介紹了golang(gin)的全局統(tǒng)一異常處理方式,并統(tǒng)一返回json,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01Go結(jié)構(gòu)體從基礎(chǔ)到應(yīng)用深度探索
本文深入探討了結(jié)構(gòu)體的定義、類型、字面量表示和使用方法,旨在為讀者呈現(xiàn)Go結(jié)構(gòu)體的全面視角,通過結(jié)構(gòu)體,開發(fā)者可以實(shí)現(xiàn)更加模塊化、高效的代碼設(shè)計(jì),這篇文章旨在為您提供關(guān)于結(jié)構(gòu)體的深入理解,助您更好地利用Go語言的強(qiáng)大功能2023-10-10Go語言實(shí)現(xiàn)運(yùn)算符重載的方法詳解
這篇文章主要為大家詳細(xì)介紹了如何利用Go語言實(shí)現(xiàn)運(yùn)算符重載的方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-09-09