文章目錄
1. linux中的service是什麼?
service其實事守護進程(daemon process),有如下2個特點:
- 開機自啓動
- 運行在後臺
1.1 linux中的進程
進程終止的原因:
- 正常返回
- 收到信號,異常退出
常見信號:
查看命令: kill -l
SIGTERM: 15, 允許進程執行完畢後退出,可被進程忽略,kill命令發出的默認信號
SIGINT: 2, ctrl+c會發出該信號,效果類似SIGTERM
SIGKILL: 9, 進程立刻退出,不能被忽略
進程對信號的處理方式:
1) 進程退出
2) 忽略信號,繼續執行
3) 調用信號處理函數
1.2 進程異常退出如何排查程序錯誤?
1) 查看日誌,調試時輸出日誌非常重要,方便排查錯誤
2) gdb調試coredump文件
3) 思考程序運行時的環境,運行方式的可能影響,改變運行方式看能否復現錯誤
4) 看源碼
coredump文件如何產生和調試?
linux默認不允許coredump,可能需要使用root權限更改下core文件的大小限制
a) ulimit -c 查看core文件容量限制,若爲0,改爲 unlimited: ulimit -c unlimited
b) 指定core文件的輸出路徑和文件名的格式:
echo “path/file” > /proc/sys/kernel/core_pattern
file可使用core-%e-%u-%g-%h-%p-%s-%t
%e: 程序文件名
%u: 用戶名
%g: 用戶組
%h: 主機名
%p: 進程ID
%s: 導致本次core dump的信號
%t: core dump的時間(離1970.01.01:00:00:00的秒數)
c) gdb -g 二進制文件 core文件,注意二進制文件編譯時一定要加上-g調試模式
什麼情況下會產生core文件?
1) 內存訪問越界(數組,如字符串數組)
2) 多線程程序使用了線程不安全的函數
3) 多線程程序共享數據未加鎖,訪問衝突
4) 非法指針(如對空指針操作,指針未初始化訪問了非法地址)
5) 堆棧溢出
1.3 代碼中的退出
- 進程
exit(num)是進程直接向產生他的角色(如一般父進程或init進程)發信號,退出程序;
return是語言層面的退出,實際上會調用exit,不管return什麼在操作系統看起來都是
正常退出 - 線程
一個線程調用exit或return都會影響另一個線程,導致全部退出
pthread_exit僅僅使得當前線程退出
1.4 nohup 和 後臺任務(jobs)是咋回事?
示例命令: nohup ./foo > log.txt 2>&1 &
拆解:
1) nohup: 表示忽略SIGHUP信號,繼續當前進程
SIGHUP信號什麼時候發出?
當前進程所在的控制終端死亡時(如ssh遠程登錄後退出登錄)
使用 nohup 的效果:
a) 若不使用輸出重定向則把日誌輸出到nohup.out文件中
b) 退出登錄,與遠程shell斷開連接,進程仍繼續執行直到結束
-
2>&1: 表示把標準錯誤重定向到標準輸出,&表示對標準輸出的引用,整體效果是
把標準輸出和標準錯誤重定向到log.txt中 -
&: 表示把當前進程放到後臺執行,如果沒有重定向則log仍然會輸出到屏幕
±---- 4 行: 如果不想輸出到屏幕也不想輸出到文件則重定向到 /dev/null
1.5 進程運行後如何監控?
top, ps, systemd的log或程序自己輸出的log
1.6 linux如何自定義守護進程?
舊方式: service命令
新方式: systemd的命令
1.6.1 linux的開機啓動過程
使用init進程的service命令:
bios自檢 -> 操作系統接管 -> 讀取/boot目錄下的內核文件 ->
運行init進程 -> 讀取/etc/inittab獲取運行級別 -> 運行啓動守護進程的
腳本 -> 用戶登錄 -> login shell
init進程後,用戶登錄前的兩步是啓動守護進程的流程
運行級別:
分爲0-6,每次系統啓動只能選定一種運行級別,不同的運行級別可設置不同的守護
進程集合,可以設置默認的運行級別
運行級別3: 完全的多用戶狀態(有NFS),登錄後進入控制檯命令行模式
運行級別5: X11控制檯,登錄後進入圖形GUI模式
設置操作系統默認的運行級別: 更改 /etc/inittab文件
設置守護進程可被執行的運行級別: 在/etc/init.d中建立配置文件
註冊守護進程到對應級別的守護進程集合中: insserv工具
用戶登錄可選3種方式,與運行級別相關:
1) 圖形界面
2) 命令行登錄,tty1-tty6都可用,ctrl+alt+f1(…, f6)切換,ctrl+alt+f7退出
3) ssh登錄
service啓動方式的缺點:
1) 串行啓動,耗時長
2) 啓動腳本複雜,腳本需要處理啓動遇到的各種情況(如啓動失敗,重啓方式,服務的
依賴等)
1.6.2 新一代的systemd
- 並行啓動
- 考慮了啓動時的各種情況,簡單配置即可
詳細使用教程:
- 將準備以守護進程運行的可執行文件放在/usr/local/sbin目錄下
- 進入/lib/systemd/system編寫 **.service配置文件
- sudo systemctl enable ** 設置開機啓動
如果想立即運行,則將3)替換爲
a) 重新加載修改後的配置文件
sudo systemctl daemon-reload
b) 啓動服務
sudo systemctl start ** 或者
sudo systemctl restart **
爲什麼放在/usr/sbin目錄下:
1) /bin, /usr/bin, /sbin, /usr/sbin均在PATH環境變量中,意味着開機時系統
能搜索到
2) /bin 放置系統的必備執行文件,如cat, cp, ls, mount等
/usr/bin 放置應用程序的必備執行文件,如g++, diff, gzip
/sbin放置系統管理的必備程序,如fdisk
/usr/sbin放置網絡管理的必備程序,如httpd, samba, tcpdump
/是系統核心的程序
/usr是系統級別次核心的程序,類似C:/Windows
/usr/local是用戶編譯的程序, 類似C:/Program Files/
/opt是用戶編譯的不那麼重要的程序,類似 D:/Software 當不需要時,直接rm -rf
都沒問題,當磁盤容量不夠時,也可將/opt掛載到其他磁盤使用
參見阮一峯的博客:
http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html
http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html
配置文件位置:
配置文件: /lib/systemd/system
指向配置文件的符號鏈接: /etc/systemd/system
配置文件編寫:
[Unit]
[Service] 設置待執行程序的路徑,進程啓動,殺死,重啓的方式等
[Install] 設置類似service機制提供的運行級別
常見命令:
systemctl status **.service
(Loaded): 是否開機啓動以及配置文件的位置
(Active): 是否正在運行
sudo systemctl start **.service
sudo systemctl stop **.service
sudo systemctl restart **.service
sudo systemctl kill **.service
sudo systemctl reload **.service
sudo systemctl daemon-reload
systemctl list-dependencies
systemctl list-unit-files --type=service
(enabled): 已經設置開機啓動
(disabled): 未設置開機啓動
(static): 配置文件無[Install]部分,只能作爲其他配置文件的依賴
(masked): 被禁止建立啓動連接
systemctl cat **.service
systemctl list-dependencies **.target // 查看一個target包含的所有unit
systemctl get-default // 查看啓動時的默認target
sudo systemctl enable ** // 設置開機啓動(自動創建到配置文件的符號鏈接)
sudo journalctl -u **.service // 查看某個service的日誌(只要打印輸出就是日誌)
1.6 linux發行版
ubuntu, debain同源,使用apt管理程序包
redhat, centos同源,使用yum管理程序包