文章很長,建議收藏起來,慢慢讀! 備注:持續更新中.....
- 瘋狂創客圈 經典圖書 : 《Netty Zookeeper Redis 高並發實戰》 面試必備 + 大廠必備 + 漲薪必備
- 瘋狂創客圈 經典圖書 : 《SpringCloud、Nginx高並發核心編程》 面試必備 + 大廠必備 + 漲薪必備
- 瘋狂創客圈 價值1000元 百度網盤資源大禮包,免費拿 【博客園總入口 】
價值連城:2021春招月薪過5萬 面試題 總系列
搞定下面這些面試題,2021春招月薪過5萬(猛!) | 阿里、京東、美團、頭條.... 隨意挑、橫着走!!! |
---|---|
Java基礎 | |
1: JVM面試題(史上最強、持續更新、吐血推薦) | https://www.cnblogs.com/crazymakercircle/p/14365820.html |
2:Java基礎面試題(史上最全、持續更新、吐血推薦) | https://www.cnblogs.com/crazymakercircle/p/14366081.html |
3:死鎖面試題(史上最強、持續更新) | [https://www.cnblogs.com/crazymakercircle/p/14323919.html] |
4:設計模式面試題 (史上最全、持續更新、吐血推薦) | https://www.cnblogs.com/crazymakercircle/p/14367101.html |
5:架構設計面試題 (史上最全、持續更新、吐血推薦) | https://www.cnblogs.com/crazymakercircle/p/14367907.html |
還有 10 幾篇 篇價值連城 的面試題 | 具體..... 請參見【 瘋狂創客圈 高並發 總目錄 】 |
萬字長文: 瘋狂創客圈 springCloud 高並發系列
springCloud 高質量 博文 | |
---|---|
nacos 實戰(史上最全) | sentinel (史上最全+入門教程) |
springcloud + webflux 高並發實戰 | Webflux(史上最全) |
SpringCloud gateway (史上最全) | |
還有 10 幾篇 萬字長文 的高質量 博文 | 具體..... 請參見【 瘋狂創客圈 高並發 總目錄 】 |
Linux 自啟動 假死自啟動
在linux的使用過程中,我們經常會碰到需要將某個自定義的應用程序設置為開機自啟動以節省操作時間,這里提供兩個設置開機自啟動的方法。
方法一:在 /etc/rc.local 添加開機自啟動程序
ubuntu在開機過程之后,會執行/etc/rc.local(注意/etc/init.d中也有個rc.local,不要弄混了)文件中的腳本程序,初始情況下,這個文件內容是這樣的:
downey@ubuntu:~$ cat /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
並不包含其它內容,用戶可以在里面添加需要開機執行的腳本命令,這里以diodon粘貼板工具為例,如果我要開機運行diodon進程,在文本中添加:
downey@ubuntu:~$ cat /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
./usr/bin/diodon &
exit 0
看到這里有些盆友就要問了,為什么要在執行命令后面加&?
在shell執行命令后加&是為了讓應用程序在后台運行,rc.local也是一個腳本,主進程在運行這個腳本時必須能夠返回,如果在這個腳本里面執行了一些死循環或者其他無法返回的任務,整個系統就很可能卡死在這里,無法啟動,所以在這里運行的用戶程序必須是能夠返回或者本身就使用一些后台運行的進程。
經過上面的添加,在下次重啟的時候,使用命令:
downey@ubuntu:~$ ps -ef |grep "diodon"
downey 2097 1880 0 22:53 ? 00:00:04 diodon
downey 2937 2842 0 23:27 pts/2 00:00:00 grep --color=auto diodon
就可以看到diodon進程已經在后台運行。
刪除
既然有添加,就必須得有刪除,其實以rc.local的刪除方式很簡單,直接刪除rc.local中用戶添加的部分即可。
需要提醒的是,在操作系統文件時,做備份是非常必要的
方法二:在/etc/init.d/ 目錄下添加腳本
添加用戶進程
第二種方式就是將自己的用戶腳本添加到/etc/init.d並鏈接到自啟動程序當中。
還是以diodon軟件來舉例,我編輯一個運行diodon的腳本:
#!/bin/bash
./usr/bin/diodon
將其命名為diodon.sh,並用指令:
chmod +x diodon.sh
sudo cp diodon.sh /etc/init.d/
將文件放到/etc/init.d目錄中,然后將diodon,sh腳本鏈接到開機運行序列中:
cd /etc/init.d
sudo update-rc.d diodon.sh defaults 96
insserv: warning: script 'diodon' missing LSB tags and overrides
這樣重新啟動時,就可以看到diodon.sh正在運行了。
sudo update-rc.d diodon.sh defaults 96
在這條指令中,update-rc.d是一個系統的鏈接工具。
而defaults 96則是指定了腳本的開機順序,數字為0-99,數字越大執行優先級越低,用戶添加的程序最好選擇低優先級的執行順序,因為很可能我們的用戶程序會依賴一些系統的應用進程,例如如果應用程序要使用到網絡部分,就先得讓網絡后台程序先初始化完畢。
看到這里,細心的朋友已經發現了,在鏈接腳本時有一個警告:
insserv: warning: script 'diodon' missing LSB tags and overrides
作為一個菜鳥而言,是不敢忽視任何警告的,所以只好求助google,解決辦法是在自己的腳本中的#!/bin/bash下添加:
### BEGIN INIT INFO
# Provides: downey
# Required-Start: $local_fs $network
# Required-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: tomcat service
# Description: tomcat service daemon
### END INIT INFO
添加這些的目的是告訴系統一些關於這個啟動腳本的具體信息,其中比較重要的有這幾項:
# Required-Start: 運行這個腳本需要的環境
# Required-Start: 停止這個腳本需要的環境
# Default-Start: 提供運行的運行級別
# Default-Stop: 不運行的運行級別
# Description: 描述
關於linux下的運行級別參考:linux運行級別
刪除用戶進程
既然有添加就必然有刪除,如果需要刪除自定義開機運行腳本,輸入:
sudo update-rc.d -f diodon remove
方法三:systemd的開機自啟動
上面提到的兩種方式適用於經典的system V控制系統啟動和關閉的情況,但是目前(2018年10月)在大多數發行版上都開始使用了systemd的系統軟件控制方式,包括Ubuntu16,centos.systemd系統管理着linux下的進程運行,屬於應用程序,不屬於linux內核的范疇。
在systemd系統上設置開機自啟動的方式也是非常簡單的(盡管systemd這套軟件管理工具並不簡單)。
確定系統是否應用了systemd工具來管理
這里要注意的是,systemd是linux發行版上的預裝工具,用來管理系統軟件的啟動運行和結束,所以通常來說,這套東西是依賴於發行版的,如果系統使用了這一套工具,那么就可以使用它來管理進程,如果不是,即使你安裝了它,它也不會被默認配置為系統管理工具。
查看系統是否使用systemd工具我們可以使用如下的指令:
systemd --version
如果系統返回如下類似的信息,表明該系統是由systemd工具來管理軟件:
systemd 232
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN
systemctl的使用
對軟件的管理主要是同通過systemd工具中的systemctl命令,相比於之前的system V的控制方式,systemd顯得更加簡潔明了,對用戶更加友好,拿httpd來舉例:
開啟httpd服務:
sudo systemctl start httpd
設置httpd服務自啟動:
sudo systemctl enable httpd
至於關閉和取消自啟動,大家心里應該有數了吧。
設置systemctl的服務文件
我們再回到重點,設置開機自啟動。
我們要為目標設置一個配置文件,其實這是可以預想到的,linux作為一個復雜的系統,開機自啟動涉及到的依賴、運行級別、運行環境等等問題肯定需要用戶去指定,在啟動的時候系統才知道怎么正確地去運行軟件。這個配置文件固定以.service作為后綴,比如我們如果要運行/home/downey目錄下的test.sh腳本,我們可以添加一個配置文件test.service:
[Unit]
Description=
Documentation=
After=network.target
Wants=
Requires=
[Service]
ExecStart=/home/downey/test.sh
ExecStop=
ExecReload=/home/downey/test.sh
Type=simple
[Install]
WantedBy=multi-user.target
將文件放在/usr/lib/systemd/system 或者 /etc/systemd/system目錄下,然后可以測試一下:
sudo systemctl start test.service
然后你可以查看你的/home/downey/test.sh腳本是否已經運行,如果已經運行表示配置文件沒有問題。然后可以鍵入:
sudo systemctl enable test.service
設置test腳本開機啟動。如果上一步沒有出問題,這一步基本上也不會有什么問題,系統會打印出如下信息:
Created symlink /etc/systemd/system/multi-user.target.wants/test.service → /usr/lib/systemd/system/test.service.
可以看到,這里在/etc/systemd/system/multi-user.target.wants/目錄下創建了一個/usr/lib/systemd/system/test.service文件的軟鏈接,到這里設置開機自啟動就完成了。
systemctl配置文件的簡單解析
在上面的配置文件中,為了演示起見,我將一些本測試腳本不需要但是比較重要的配置項也寫了出來,其實如果不需要可以刪除,但是[Unit]/[Service]/[Install]這三個標簽需要保留。
我們來一個個簡單介紹一下配置項:
Description:運行軟件描述
Documentation:軟件的文檔
After:因為軟件的啟動通常依賴於其他軟件,這里是指定在哪個服務被啟動之后再啟動,設置優先級
Wants:弱依賴於某個服務,目標服務的運行狀態可以影響到本軟件但不會決定本軟件運行狀態
Requires:強依賴某個服務,目標服務的狀態可以決定本軟件運行。
ExecStart:執行命令
ExecStop:停止執行命令
ExecReload:重啟時的命令
Type:軟件運行方式,默認為simple
WantedBy:這里相當於設置軟件,選擇運行在linux的哪個運行級別,只是在systemd中不在有運行級別概念,但是這里權當這么理解。
如果有多項,用逗號作為分隔。
方法四:定時自重啟
定時監測與假死重啟的方式,使用crontab 定時任務監測進程,並且實時重啟。
准備 自動啟動腳本
舉個例子,
vi /usr/local/presto_monitor.sh
#!/bin/sh
command="/usr/local/Presto/presto-server-0.100/bin/launcher run"
appname=presto-server
logfile=/usr/local/log/presto_monitor.log
#返回 ps -ef 出來的所有字符串中含有 $appname 的進程個數
checkrun=`ps -ef | grep $appname | grep -v "grep" | wc -l`
echo "$appname 運行監測開始….."
#ps -ef | grep launcher | grep -v "grep" | wc -l
#while true
#do
#echo $checkrun
if [ 0 = $checkrun ]; then
#進程不存在
time2=$(date "+%Y-%m-%d %H:%M:%S")
echo "$appname 服務宕機,正在重新啟動"
#echo "$appname 服務宕機,宕機時間為:"$time2>>$appname.log
#./$appname $appname &logfile
nohup $command > $logfile 2>&1 &
#nohup /usr/local/Presto/presto-server-0.100/bin/launcher run > presto_run.log 2>&1 &
sleep 1
pid=$(ps -ef | grep -v 'grep' | egrep $appname| awk '{printf $2 " "}')
echo "$appname ($pid)重新啟動成功!!!"
else
#進程存在
sleep 1
pid=$(ps -ef | grep -v 'grep' | egrep $appname| awk '{printf $2 " "}')
echo "$appname ($pid) 服務運行正常...持續監控中"
fi
time=$(date "+%Y-%m-%d %H:%M:%S")
echo "本輪監測完畢,當前時間為:"$time
#done
#這里有一行
使用nohup命令后台運行命令之后,需要使用exit正常退出當前賬戶,這樣才能保證命令一直在后台運行(es head插件有這個問題)。
command>out.file是將command的輸出重定向到out.file文件,即輸出內容不打印到屏幕上,而是輸出到out.file文件中。如果不想要輸出文件則修改 out.file 為 /dev/null。
2>&1 是將標准出錯重定向到標准輸出,這里的標准輸出已經重定向到了out.file文件,即將標准出錯也輸出到out.file文件中。
最后一個&, 是讓該命令在后台執行。
0-輸入 1-輸出 2-錯誤
crontab 定時任務
crontab:定時任務的守護進程,精確到分,設計秒的我們一般寫腳本 -->相當於鬧鍾
日志文件: ll /var/log/cron*
編輯文件: vim /etc/crontab
進程:ps -ef | grep crond ==> /etc/init.d/crond restart
作用:定時備份,實時備份
Linux下的任務調度分為兩類,系統任務調度和用戶任務調度。
(1) 系統任務調度:系統周期性所要執行的工作,比如寫緩存數據到硬盤、日志清理等。
在/etc/crontab文件,這個就是系統任務調度的配置文件。
(2) 用戶任務調度:用戶定期要執行的工作,比如用戶數據備份、定時郵件提醒等。
用戶可以使用 crontab 工具來定制自己的計划任務。
在crontab 文件都被保存在/var/spool/cron目錄中。其文件名與用戶名一致
1.系統定時任務:例如清理系統日志,清理系統緩存 -->不過多的關注
查詢系統定時處理任務的路徑:
路徑1:
cd /etc/logrotate.d/ -->可以寫定時任務
less syslog
路徑2:
cat /etc/crontab -->不推薦使用,但是可以看格式
路徑3:
ls /etc/ | grep cron*
anacrontab
cron.d -->同路徑2 ,可以寫定時任務
cron.daily
cron.deny -->控制普通用戶使用定時任務crontab
cron.hourly
cron.monthly
crontab
cron.weekly
2.用戶的定時任務 -->關注重點
查看自動執行命令
/etc/crontab -l
如果沒有權限,
sudo groupadd root:crontab
sudo chown root:crontab /var/spool/cron/crontabs/
啟動 crond
service crond start
*/10 * * * *
cron 的主配置文件是 /etc/crontab,它包括下面幾行:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
前四行是用來配置 cron 任務運行環境的變量。 SHELL 變量的值告訴系統要使用哪個 shell 環境(在這個例子里是 bash shell);
PATH 變量定義用來執行命令的路徑。
cron 任務的輸出被郵寄給 MAILTO 變量定義的用戶名。
如果 MAILTO 變量被定義為空白字符串(MAILTO=""),電子郵件就不會被寄出。
HOME 變量可以用來設置在執行命令或腳本時使用的主目錄。
/etc/cron.allow和/etc/cron.deny 文件被用來限制對 cron 的使用。
這兩個使用控制文件的格式都是每行一個用戶。 兩個文件都不允許空格。
如果使用控制文件被修改了,cron 守護進程(crond)不必被重啟。
使用控制文件在每次用戶添加或刪除一項 cron 任務時都會被讀取。
無論使用控制文件中的規定如何,root 都總是可以使用 cron。
如果 cron.allow 文件存在,只有其中列出的用戶才被允許使用 cron,並且 cron.deny 文件會被忽略。
如果 cron.allow 文件不存在,所有在 cron.deny 中列出的用戶都被禁止使用 cron。
crontab 常用命令
安裝crontab:
yum install crontabs
crontab服務操作說明:
/sbin/service crond start //啟動服務
/sbin/service crond stop //關閉服務
/sbin/service crond restart //重啟服務
/sbin/service crond reload //重新載入配置
查看crontab服務狀態:
service crond status
手動啟動crontab服務:
service crond status
查看crontab服務是否已設置為開機啟動,執行命令:
方法一: 界面啟動 ntsysv
方法二: 加入開機自動啟動: chkconfig –level 35 crond on
crontab -l查看定時任務列表
編輯定時任務
crontab –e
==》vim /var/spool/cron/root
每隔2分鍾輸出時間到文件
*/2 * * * * echo date
>> $HOME>test.txt
crontab -r 刪除定時任務
==> 從/var/spool/cron目錄中刪除用戶的crontab文件
==> 如果不指定用戶,則默認刪除當前用戶的crontab文件
crontab –i 在刪除用戶的crontab文件時給確認提示
備份crontab文件
crontab -l > $HOME/mycron
系統級任務調度與用戶級任務調度
root用戶的任務調度操作可以通過“crontab –uroot –e”來設置,也可以將調度任務直接寫入/etc/crontab文件,需要注意的是,如果要定義一個定時重啟系統的任務,就必須將任務放到/etc/crontab文件,即使在root用戶下創建一個定時重啟系統的任務也是無效的。
其他注意事項
當crontab突然失效時,可以嘗試/etc/init.d/crond restart解決問題。或者查看日志看某個job有沒有執行/報錯tail -f /var/log/cron。
千萬別亂運行crontab -r。它從Crontab目錄(/var/spool/cron)中刪除用戶的Crontab文件。刪除了該用戶的所有crontab都沒了。
在crontab中%是有特殊含義的,表示換行的意思。如果要用的話必須進行轉義%,如經常用的date ‘+%Y%m%d’在crontab里是不會執行的,應該換成date ‘+%Y%m%d’
最后.crontab箴言
1.環境變量問題,例如crontab不能識別Java的環境變量
crontab執行shell時,只能識別為數不多的環境變量,普通的環境變量是無法識別的,所以在編寫shell時,最好使用export重新聲明變量,確保腳本執行。
2.命令的執行最好用腳本
3.腳本權限加/bin/sh,規范路徑/server/scripts
4.時間變量用反斜線轉義,最好用腳本
5.定時任務添加注釋
6.>/dev/null 2>&1 ==> &>/dev/null,別隨意打印日志文件
7.定時任務里面的程序腳本盡量用全路徑
8.避免不必要的程序以及命令輸出
9.定時任務之前添加注釋
10.打包到文件目錄的上一級
crontab內容格式
用戶所建立的crontab文件中,每一行都代表一項任務,每行的每個字段代表一項設置,它的格式共分為六個字段,前五段是時間設定段,第六段是要執行的命令段,格式如下:
minute hour day month week command
其中:
1、minute: 表示分鍾,可以是從0到59之間的任何整數;
2、hour:表示小時,可以是從0到23之間的任何整數;
3、day:表示日期,可以是從1到31之間的任何整數;
4、month:表示月份,可以是從1到12之間的任何整數;
5、week:表示星期幾,可以是從0到6之間的任何整數,這里的0代表星期日;
6、command:要執行的命令,可以是系統命令,也可以是自己編寫的腳本文件。
前五個時間設定段,可以含如下特殊字符:
1、星號(*):代表所有可能的值,例如month字段如果是星號,則表示在滿足其它字段的制約條件后每月都執行該命令操作;
2、逗號(,):可以用逗號隔開的值指定一個列表范圍,例如,“1,2,5,7,8,9”;
3、中杠(-):可以用整數之間的中杠表示一個整數范圍,例如“2-6”表示“2,3,4,5,6”;
4、正斜線(/):可以用正斜線指定時間的間隔頻率,例如“0-23/2”表示每兩小時執行一次。同時正斜線可以和星號一起使用,例如*/10,如果用在minute字段,表示每十分鍾執行一次。
crontab 查看日志
一.文件位置
位置一般在/var/spool/cron/下,如果你是root用戶,那下面有個root文件,建議日常備份,避免誤刪除導致crontab 文件丟失;
二.日志文件位置
默認情況下,crontab中執行的日志寫在/var/log下,如:
#ls /var/log/cron*
/var/log/cron /var/log/cron.1 /var/log/cron.2 /var/log/cron.3 /var/log/cron.4
crontab的日志比較簡單,當crond執行任務失敗時會給用戶發一封郵件。恰巧在我們的一台服務器上發現一個任務沒有正常執行,而且crond發郵件也失敗了。通過看mail的日志,看到是磁盤空間不足造成的。
可以將每條 crontab中的任務增加自己的日志,有利於查找執行失敗原因。
0 6 * * * //root/script/ss.sh >> /root/for_crontab/mylog.log 2>&1
把錯誤輸出和標准輸出都輸出到mylog.log中。
回到◀瘋狂創客圈▶
瘋狂創客圈 - Java高並發研習社群,為大家開啟大廠之門