服務管理與服務腳本
linux服務
服務啟動過程詳解
在開機啟動過程中,我們計算機的各種服務也會按照配置信息啟動服務,那個我們的服務使如何啟動的呢?我們以 init 3
模式為例,進行說明:
上圖中:rc 3 --> 意味着讀取/etc/rc.d/rc3.d/下的內容,現在我們看看/etc/rc.d/rc3.d/下有什么東西。
在/etc/rc.d/rc3.d/目錄下,我們看到全部都是軟鏈接連接到/init.d/下的腳本。
我們可以通過腳本加狀態的模式啟用或關閉我們的某個服務:
K*: K##*:##運行次序;數字越小,越先運行;數字越小的服務,通常為依賴到別的服務
S*: S##*:##運行次序;數字越小,越先運行;數字越小的服務,通常為被依賴到的服務
但是實際上它並不是按照數字排序的,而是按照字符串的大小排序的。
K開頭的服務代表開機不啟動 S開頭的服務代表開機啟動
所以我們在寫服務腳本的時候,如果是依賴於某些服務的,我們最好能夠將我們的腳本連接名排到我們的服務所依賴的服務軟連接后面。
我們看一下,在啟動計算機的過程中,init加載了一個腳本/etc/rc.d/rc,下面是這個腳本的一部分內容。
# First, run the KILL scripts. for i in/etc/rc$runlevel.d/K*;do # Check if the subsystem is already up. subsys=${i#/etc/rc$runlevel.d/K??} [-f /var/lock/subsys/$subsys -o -f /var/lock/subsys/$subsys.init ]||continue check_runlevel "$i"||continue # Bring the subsystem down. [-n "$UPSTART"]&& initctl emit --quiet stopping JOB=$subsys $i stop [-n "$UPSTART"]&& initctl emit --quiet stopped JOB=$subsys done # Now run the START scripts. for i in/etc/rc$runlevel.d/S*;do # Check if the subsystem is already up. subsys=${i#/etc/rc$runlevel.d/S??} [-f /var/lock/subsys/$subsys ]&&continue [-f /var/lock/subsys/$subsys.init ]&&continue check_runlevel "$i"||continue # If we're in confirmation mode, get user confirmation if["$do_confirm"="yes"];then confirm $subsys rc=$? if["$rc"="1"];then continue elif["$rc"="2"];then do_confirm="no" fi fi update_boot_stage "$subsys" # Bring the subsystem up. [-n "$UPSTART"]&& initctl emit --quiet starting JOB=$subsys if["$subsys"="halt"-o "$subsys"="reboot"];then export LC_ALL=C exec $i start fi $i start [-n "$UPSTART"]&& initctl emit --quiet started JOB=$subsys done
在上面的腳本中我們發現,計算機在啟動服務過程中,會在對應的運行級別下,先關閉一部分服務,關閉玩服務之后才會再對應的運行級別下啟動一些服務。
所以面圖片中帶有K開頭的軟鏈接程序,就相當於執行真正指向的腳本后面跟上stop,帶有S開頭的軟鏈接程序,就相當於執行真正指向的腳本后面跟上start。
我們以autofs為例,作以說明:
[root@CT691 ~]#/etc/rc.d/init.d/autofs start
Starting automount: automount: program is already running.
[ OK ]
上述的效果其實和service autofs
本質上是一樣的:
[root@CT691 ~]#service autofs start
Starting automount: automount: program is already running.
[ OK ]
接下來,我們以一個簡單的服務腳本為例,做一個簡單的說明演示:
腳本:
#!/bin/bash source /etc/rc.d/init.d/functions if[ $1 !="stop"]&&[ $1 !="start"]&&[ $1 !="restart"]&&[ $1 !="status"];then echo "The parameter must be start,stop,restart,status" exit; fi if[ $1 ="start"];then if[-e /var/lock/subsys/$(basename $0)];then action "the `basename $0` has started!" false else touch /var/lock/subsys/$0 action "the ` basename $0` start success" true fi elif[ $1 ="stop"];then if[-e /var/lock/subsys/$(basename $0)];then rm -rf /var/lock/subsys/$(basename $0) action "the `basename $0` has stopped!" true else action "the`basename $0` is not starting" false fi elif[ $1 ="restart"];then if[-e /var/lock/subsys/$(basename $0)];then rm -rf /var/lock/subsys/$(basename $0) action "the `basename $0` has stopped!" true touch /var/lock/subsys/$0 action "the ` basename $0` restart success" true else action "the`basename $0` is not starting" false action "the`basename $0` is not starting" false fi elif[ $1 ="status"];then if[-e /var/lock/subsys/$(basename $0)];then echo -e "the \033[1;32;1m`basename $0`\033[0m is running" else echo -e "the \033[1;31;1m`basename $0`\033[0m has stopped!" fi fi
接下來,我們將這個腳本放到/etc/rc.d/init.d/中去,先試一下看是否有什么問題:
我們使用service試試:一樣可以使用
現在這個腳本並不是開機就能運行的,我們將它做成服務,還需要進行一些改變。在linux上,有一個工具控制着計算機服務的開機是否運行:ntsysv命令
如下圖所示,帶星好的就是開機運行的服務,不帶星號的就是開機不運行的服務
chkconfig命令
這個工具有一個不好的地方就是它只能改本模式下的服務的開機是否啟動,不能改變其他模式下服務的開機啟動,如果我想改5模式的,需要使用ntsysv --level=5
,如果我們想改各個模式下的開機服務,如果使用這個方法一個一個該改,十分的不方便,所以,我們使用chkconfig命令:
我們可以使用這個命令看到各個模式下的服務是否開啟或關閉,我以上圖的第一個服務為例,關閉在3,5模式下的開機服務,看看如何實現:
關閉成功。
更多的時候,我們會使用chkconfig NetworkManager on
或chkconfig NetworkManager off
,這種方式默認啟用或關閉2345模式下的服務。
接下來我們使用chkconfig NetworkManager on
開啟服務,既然我們將服務就開啟了,那么在/etc/rc3.d/下面肯定有一個以S開頭的相關服務這就意味着它開機就能啟動。
接下來,我們做一個小實驗:
- 查看atd服務是否開啟,若開啟,關閉
- 刪除掉/etc/rc3.d/下atd的軟鏈接
- 創建一個數值靠后,並且是S開頭的軟鏈接
- chkconfig查看atd服務狀態
我們看到,當我們創建一個S開頭的軟鏈接之后,它的開機服務狀態就變成了on了。
接下來我們將剛才的testsrv.sh做成我們的服務腳本,要做服務腳本,還需要一點點的改動,我們需要在注釋中加上一行#chkconfig: 35 96 03
35
代表的含義是在3和5模式下開機啟動,96
代表S開頭的編號,03
代表K開頭的編號。
現在還是沒有服務啟動的的,我們需要手動加上去:
現在,在3模式下他已經是可以開機啟動的服務了,我們也可以現在手動改成在3模式下開機不啟動的狀態,我們只需要chkconfig --level 3 testsrv.sh off
:
[root@CT691 init.d]#chkconfig --list testsrv.sh testsrv.sh 0:off 1:off 2:off 3:on 4:off 5:on 6:off [root@CT691 init.d]#chkconfig --level 3 testsrv.sh off [root@CT691 init.d]#ls /etc/rc3.d/K03* /etc/rc3.d/K03testsrv.sh
如果我們不想要這個服務,我們需要將這個服務給刪除,刪除的方法是:chkconfig --del testsrv.sh
,刪除服務后,文件並不會被刪除,但是軟鏈接會被刪除。chkconfig --list
也不能查詢到。
非獨立服務與xinetd進程
很多時候,一些服務我們平時用不到,有時候一年才用一次或者好幾個月用一次,如果讓該服務開機就跑起來就太過於浪費資源。我們需要再使用它的時候自動開啟,這該如何實現呢?
我們上面的一個一個的服務就做獨立服務,而非獨立服務是有特定的服務進行代理監聽端口,等等有訪問時由特定服務通知該服務啟動運行,這個特定的服務就是xinetd,我們也可以稱它是超級守護進程。
Telnet服務就是一個非獨立服務,它的使用需要依賴於xinetd,當我們使用yum安裝該軟件時,它會自動安裝上xinetd,下面是我安裝好的Telnet:
接下來我們啟動該服務,在第一次安裝后,首先啟動xinetd,在啟動telnet:
我們在啟動服務后可以看看是誰在監聽這着23端口:
接下來我們嘗試使用Telnet連接該系統,然后再次查看是誰在監聽端口:
當我們開始使用的時候,他就變成了由原服務來執行,這就是我們要說的非獨立服務。
一個特殊的服務腳本
正常級別下,最后啟動一個服務S99local沒有鏈接至/etc/rc.d/init.d一個服務腳本,而是指向了/etc/rc.d/rc.local腳本
不便或不需寫為服務腳本放置於/etc/rc.d/init.d/目錄,且又想開機時自動運行的命令,可直接放置於/etc/rc.d/rc.local文件中
- /etc/rc.d/rc.local在指定運行級別腳本后運行
- 可以根據情況,進行自定義修改