從 web 開發的視角說一下在使用 Linux 時遇到的問題,主要是針對操作本身,因為指令在網上都可以查到,不會深入原理,但儘量實用。
最初我使用 Linux 是因為我需要的應用在教學裡只提供了 Linux 版本,於是我就按步驟把它部署起來,就這樣順其自然地用了下去,期間也解決了一些問題,在這個過程中,我逐漸產生了一些疑問:為什麼使用 Linux 作為伺服器端,而不是我們日常使用更加熟悉的 Windows 系統,二者在伺服器端有什麼區別?
在這點上,毋庸置疑是 Windows 更勝一籌,圖形化介面操作友好,Windows Server 版相對於面向大眾的版本在操作上也沒有特別大的差別,大部分人應該還是對於微軟這種一以貫之的風格更加習慣。
Linux 也有帶圖形介面的發行版,但作為伺服器使用時這樣反而喪失了一部分優勢,圖形殼程式會佔用伺服器寶貴的硬體資源,通常不做考慮。
客觀來說,Linux 開源免費,而 Windows Server 則需要付費授權。實際上多數情況我們購買雲伺服器的時候,這部分成本已經平攤了。
騰訊雲選擇 Windows Server 時的提示:
Linux 是開源的,它的程式碼由全世界最優秀的程式設計師維護更新,如果有漏洞被發現也會被迅速修復。而 Windows 方面,由於我使用 Windows Server 的經驗並沒有多少,不做過多評價,但對於面向普通使用者的版本,大家都有發言權,儘管微軟的程式設計師非常優秀,但是 Windows 仍然會頻繁地向你推播漏洞修復修補程式,並且偶爾藍屏、宕機
Linux 對於使用者是完全開放的,因為它假定使用者知道自己在做什麼,你可以作業系統中所有的檔案,但 Linux 不會對你的操作負責,這就如同我們在安卓手機中獲取 root 許可權一樣,你獲取了底層檔案的操作許可權,可以按你自己的想法去修改系統,但這樣手機的服務商就不再提供保修服務,因為你做出了超出他們預期的行為。
在 Windows 這邊,不知道是不是大家都經歷過被提示沒有操作許可權的情況,或者想設定許可權卻被告知沒有許可權的情況,我還遇到過微軟自家的軟體沒有許可權讀取檔案而無法識別已安裝的應用程式的問題,這都是因為 Windows 較為複雜的許可權系統。
為什麼將許可權系統放在穩定性這一節,因為在使用者可以自由修改許可權的情況下,系統的穩定性當然會受影響,在 Linux 操作中,我們可以很輕鬆的給檔案設定 777 許可權(最高的許可權,在後面會說到),或者開放防火牆所有埠,而這無疑增加了系統執行的風險,所以在設計這部分的操作時,應該更加謹慎,先看看有沒有其他的方法再進行操作。
嚴格來說,Linux 是核心而不是作業系統,藉助於不同的發行版提供的作業系統相關元件才變成了作業系統,平常我們會簡稱為 Linux 系統,而實際上由於開源的特性,不同的分支會存在不小的差距。這部分涉及很多我不懂的專業知識,而且可以在網上查到很多說明比較,所以不在這裡贅述,我想要說明的是在查詢指令和資料時要注意先決條件,區分不同系統的操作。
這裡借用一下菜鳥教學的圖:
由於雲服務商的問題,國內使用 CentOS 較多,總體是個很好上手的版本,這個版本是基於免費的 RHEL 的原始碼重新編譯成的,這兩種都屬於 Red Hat 公司。而其他的比如 Debian、Ubuntu 都是同樣使用很廣泛的系統,每一種發行版都有它所屬於的社群在使用,並且還有大量自行編譯的客製化化版本。
但要注意的是 CentOS 8 已於 2021 年 12 月 31 日停止維護,Cent OS 7 將於 2024 年 6 月 30 日停止維護,這可能會成為一個隱患,在選擇發行版時需要將其納入考量。
騰訊雲中選擇系統時的映象介紹:
Debian 是一款穩定、便捷、快速的 Linux 發行版,它擁有比大多數 Linux 發行版更為強大的軟體包管理工具,是目前用於建站的首選伺服器作業系統之一。
Ubuntu 是最熱門的 Linux 發行版之一,是一款開放原始碼的免費軟體,基於 Debian Linux 作業系統,其易用性和穩定性均非常出色,並且擁有非常強大成熟的社群資源。
CentOS 是一款流行的開源 Linux 發行版,是 RHEL(Red Hat Enterprise Linux)原始碼經過再編譯而成。(注意:CentOS 社群將於 2024 年 6 月 30 日停止維護 CentOS 7,推薦您選用相容 CentOS 8 的 OpenCloudOS 8 映象替代。)
說了那麼多,不如實際進入系統操作一下,使用雲伺服器時,雖然 web 端都會提供控制檯,但是操作和功能都不能完全滿足我們日常開發的需要,只要能支援 SSH 協定(預設埠 22)的軟體都可以用於遠端連線 Linux,也支援 Telnet 協定,但是由於 Telnet 協定本身並不安全,所以很多發行版都關閉了這一連線方式。
軟體方面有很多選擇,最簡單直接的是 PuTTY,也可以使用 SecureCRT,我自己用得比較多的是 XShell,可以在官網申請免費的家庭/學校版本,完全可以滿足日常的開發使用需求。
上傳軟體使用的是配套 XFTP,其他還可以選擇 WinSCP 等。
預設檔案目錄如下:
有箭頭指向的資料夾代表是軟連線,可以理解為 Windows 的快捷方式,在 ftp 中可以看到圖示左下角有個快捷方式的標誌。
可以將一些常用的資料夾或檔案連結到外層的目錄方便日常使用。
通常我會在根目錄再建立一個「app」資料夾,用來存放我們的 web 應用。
如果一個目錄或檔名是以一個點開始,就表示這個目錄或檔案是一個隱藏目錄或檔案。即以預設方式査找(
ls
)時,不顯示該目錄或檔案。可以使用ls -a
檢視。
在 Windows 中我們要安裝一個新軟體通常又兩種情況,一種是開啟 exe 檔案或其他什麼格式的安裝程式,然後它會把檔案安裝到我們指定的目錄下,同時也會在在登入檔中新增資訊或在系統磁碟中建立一些組態檔之類的,具體有很多情況,另一種是解壓一個壓縮包,開啟即用,通常是一些相對簡易的工具類軟體。
在 Linux 中也是類似的,一方面你可以通過包管理工具來安裝檔案,它會自動將檔案放置到固定的目錄或者你指定的目錄下,另一方面,你也可以下載壓縮包,解壓後再按照軟體的具體用法去使用。
不過即使是安裝包,在 Linux 中也是有區別的,在查資料的時候我們會看到 rpm、yum、apt 等各種各樣格式的檔案,它們都可以安裝軟體,但是卻有著區別。
對比項 | rpm | yum | dpkg | apt |
---|---|---|---|---|
系列 | RedHat 系 | RedHat 系 | Debian 系 | Debian 系 |
區別 | 包安裝工具 | 依賴管理工具 | 包安裝工具 | 依賴管理工具 |
其中,包安裝工具就是簡單的安裝工具,如果某個軟體需要一個依賴庫,你要先手動安裝好才能繼續,類似在 Windows 系統中執行一些軟體需要先安裝.Net Framework XX 這種依賴庫,而依賴管理工具與前端的 npm 類似,會自動幫你安裝所依賴的庫,就是所謂的一鍵安裝升級解除安裝工具。
從上面的表格中可以看出 RedHat 系和 Debian 系的安裝工具有所區別,這也就是為什麼我前面要強調先區分發行版系統再執行命令,在 Debian 中執行 yum 是不可行的,雖然我們可以把 yum 安裝到 Debian 中,但這顯然違反了設計的初衷,因為 Debian 已經有 apt 了,另外需要注意的是,即使是同樣功能的依賴庫,軟體包的名字可能也是不一樣的,可能是因為由不同的人開發了相同功能的軟體,例如編譯 Nginx 所需要的 5 個依賴:
RPM 包預設安裝路徑:
安裝路徑 | 含 義 |
---|---|
/etc/ | 組態檔安裝目錄 |
/usr/bin/ | 可執行的命令安裝目錄 |
/usr/lib/ | 程式所使用的函數庫儲存位置 |
/usr/share/doc/ | 基本的軟體使用手冊儲存位置 |
/usr/share/man/ | 幫助檔案儲存位置 |
另外需要注意的是,指令檔案通常不會作用到全域性,需要我們自己去修改環境變數。如果有在 Windows 中安裝過 Java 可能會有印象,我們安裝完成後並不能在 cmd 中直接使用 Java 指令,而是要到對應的目錄中才可以執行,但是通過設定環境變數,將指令檔案對映到全域性,就可以在任意資料夾目錄使用 Java 指令,Linux 也是一樣的,上文目錄結構那張圖中有個名為「sbin」的檔案,其中儲存的就是指令。有些人提供的安裝指令碼會幫你新增好全域性指令,具體操作需要自己斟酌。
一些常用軟體的安裝流程我之前寫過,可以參考下面兩篇:
在 Linux 上從零開始部署前後端分離的 Vue+Spring boot 專案
守護行程這部分因為方法很多,而且都很容易查到,我沒有寫具體步驟,但是對於 web 開發來說很重要,一定要提一下。
當我第一次開發好應用,上傳伺服器,(中間略去一大堆步驟),啟動使用也 OK 以後,以為一切萬事大吉就把遠端工具關掉了,然後發現應用就不能存取了,瞭解了之後才知道我只是建立了一個前臺的任務,就像 Windows 系統中你當前開啟的視窗,你關閉視窗程式自然不再執行,然而還是有很多程式不依賴於視窗執行,這些後臺任務默默地在執行著工作,就像我們的網站 24 小時線上一樣,所以我們也要通過守護行程這一形式把我們的應用也變成後臺任務,方法有很多,可以參考下面這篇:
許可權問題我們都會說很重要,但是在網上查資料的時候發現很多人改許可權一點都不手軟,這裡以 Nginx 建立自定義紀錄檔為例,Nginx 預設設定第一行如下:
#user nobody;
意思是 Nginx 是通過 nobody 這個使用者來啟動的,所以 Nginx 的最大許可權就是 nobody 的許可權,雖然這裡註釋掉了,但是預設值就是 nobody,這個可以在系統中查到。
Nginx 的預設紀錄檔檔案為/usr/local/nginx/logs/access.log
,通過下圖可以看到它的許可權 rwxrwxrwx,可以簡單來說就是完全許可權,任何人都可以讀、寫或刪除,如果我們想讓 Nginx 在 /usr/local/nginx/logs
這個目錄中寫自定義紀錄檔會得到沒有許可權的錯誤,因為 nobody 這個使用者沒有對這個目錄的讀寫許可權。
我查到一種很常見的解決方法:如果 nobody 沒有讀寫許可權,那麼哪個使用者有讀寫許可權呢?root 肯定有,所以就把 Nginx 的使用者改成了 root,這種思路看起來合理,但是這種許可權操作卻並不必要,回過頭來思考一下,如果沒有目錄的讀寫許可權,給目錄設定相應使用者的讀寫許可權就可以了。
現在我們回到許可權的設定上,rwx 其實很容易就能猜到分別代表讀(用 r 表示)、寫(用 w 表示)和執行(用 x 表示,針對可執行檔案或目錄),為什麼有三個,看下圖:
至於為什麼最開始提到 777 許可權,並且很多文章會讓你執行 chmod 777
,這裡面:
通過 4、2、1 的組合,我們可以得到以下幾種許可權
所以 777 就表示不應該被濫用的最高許可權。
還有很多零散的點需要注意一下不單獨分章節了。
這點很容易被忽視,但是遇到這個問題後很讓人頭疼,我們習慣使用的 Windows 系統檔名是大小寫不敏感的,也就是說一個名字叫 a.txt
的檔案,和一個名字叫 A.txt
是同名的,然而在 Linux 中是對大小寫敏感的,這一點需要留意。
我們的 web 應用經常要暴露一些埠給外部存取,除了要在系統內部的防火牆中開放所需要的埠,還要在雲伺服器平臺上開放相應的埠。另外,不要圖省事把防火牆整個關掉。
\n
, 行尾以 \n
來標識\r
和一個換行符(LF) \n
和,行尾以 \r\n
來標識所以兩邊檔案互相轉移時可能會有多餘字元。
在很多文章中,會有以sudo
開頭的命令,它的作用是臨時提升命令的許可權,讓它獲得最高許可權,也許能提高一些命令的成功率,但如果你已經是 root 使用者了,加上sudo
也沒用。
如果想在 Linux 中直接編輯文字會比想象中複雜,但是多操作幾遍就能理解,條件允許的情況下我會在 ftp 中編輯檔案。
編輯指令可以參考這篇