一、Linux 背景知識
? ? ? ? Linux 的第一個版本開發者是 Linus,所以部分人會叫“林納斯”。Linux 只是一個開源的操作系統內核,有些公司/開源組織基于 Linux 內核,配套了不同的應用程序,構成不同的操作系統(比如 vivo、),也就是不同“發行版”:RedHat 收費,CentOS 社區免費版但是停止維護了(出了問題小公司不好搞,但是大公司有能力二次開發),Ubuntu 免費并且在持續維護。
? ? ? ? Linux 免費開源、穩定(持續運行不重啟很多年都沒問題)、安全(管理員才能操作內核)、社區支持(有問題去社區問)。
? ? ? ? 我們程序員必學 Linux,只不過不同崗位側重點不同。Linux 雖有圖形界面,但不好用切占資源開銷,所以 Java 開發需要學 Linux 基礎命令。Linux 自身提供了 API 給程序員完成復雜編程,比如文件操作、多線程、socket 編程等。但是 Java 有封裝好的工具,并且跨平臺,所以不需要學 Linux 的系統編程。然后就是在 Linux 上部署項目,讓用戶訪問,企業有自動化工具一鍵部署。安裝程序是運維的事。最后就是讀日志,tail 跟蹤日志,grep 過濾信息。
二、Linux 環境搭建
? ? ? ? 物理機裝 Linux 用起來不方便,虛擬機裝 Linux 有各種環境問題,云服務器開機就用就是費錢,可以申請學生優惠。小的項目 2核2G夠,大的比如微服務項目 2核4G 夠。
? ? ? ? 買好后,要記住:公有?IP、管理員賬戶(默認root)、密碼。
? ? ? ? 下 XShell 終端軟件,遠程連接服務器,對服務器進行操作。
家庭/學校免費 - NetSarang Websitehttps://www.xshell.com/zh/free-for-home-school/
? ? ? ? XShell 遠程連接:
? ? ? ? 復制粘貼設置:工具》選項》終端:
三、Linux 基礎命令
- ~ 表示 home 目錄,root 管理員的 home 目錄是 /root,普通用戶是 /home/用戶名。
1、創建文件夾(mkdir)
語法:touch [選項] [?錄]
? ? ? ? mkdir:創建文件夾
? ? ? ? mkdir -p:先創建所有不存在的父文件夾(parent),再創建文件夾(test)。
2、創建文件(touch)
? ? ? ? touch:什么后綴都行
3、刪除文件夾/文件(rm)
? ? ? ? rm -rf:直接刪除文件夾,及其下所有內容。包括只讀文件也刪除。(-r 指刪除文件夾下,還有文件的情況)
????????不要輕易在根目錄 / 下使用該命令,即刪除所有包括系統文件,使用了系統也會提示不能操作:圖中說明加?--no-preserve-root 選項會忽略警告強制刪除。
? ? ? ? rm -ri:刪除所有文件之前,詢問。
4、列出目錄(ls)
? ? ? ? ls :列出當前目錄下的所有文件夾、文件。
? ? ? ? ls -a:列出所有文件,包括 . 開頭的隱藏文件。
? ? ? ? ls -l:列出所有文件的詳細信息。
? ? ? ? ll :列出所有文件,包括隱藏文件的詳細信息。
? ? ? ? ls -dl:列出當前文件的詳細信息。
5、改變工作目錄(cd)
? ? ? ? cd 絕對路徑:
? ? ? ? cd 相對路徑:. 表示當前目錄,.. 表示上一級目錄。
? ? ? ? cd - : 返回最近訪問的目錄。
6、顯示當前目錄(pwd)
7、快捷鍵
????????tab 自動補全:敲部分文件名,tab 可根據當前目錄下的文件自動補全。
? ? ? ? crl+c:輸入輸錯了,取消命令。
8、復制文件夾/文件(cp)
? ? ? ? cp 源文件 目標路徑
? ? ? ? 可以重命名:
? ? ? ? 若目標路徑里有重復的,-f 是強制覆蓋,-i 是覆蓋前詢問。
9、剪切文件夾/文件(mv)
? ? ? ? mv:
? ? ? ? 可以重命名剪切的源文件:
9、寫文件(vi)
? ? ? ? vi/vim 文件名:用 vim 文本編輯器打開文件。
? ? ? ? i :進入編輯模式。
? ? ? ? Esc:退出編輯模式。
? ? ? ? :q? 未修改,直接退出。
? ? ? ? :wq? 修改,保存退出。
? ? ? ? :wq!? 修改,強制保存退出。(另一個窗口也修改了這個文件并保存了,如果當前窗口不要另一個窗口修改的,就強制保存并退出)
? ? ? ? :q? 修改了,強制不保存退出。
更多參考使用文檔,命令?vimtutor。
10、讀文件
? ? ? ? cat -n 文件名:讀取文件所有內容,并顯示行號。
? ? ? ? more : 顯示部分內容。按?enter 再顯示一行,按 下箭頭 再顯示一頁。 crl+c 結束。
? ? ? ? less :滾動讀取,:q 退出。
? ? ? ? head -10:顯示頭 10 行。
? ? ? ? tail -10:顯示尾 10 行。
11、查找內容(grep)
? ? ? ? 常用于查看日志。
? ? ? ? grep?-w 全字匹配。-r 遞歸查找所有文件。--color 高亮查找。
? ? ? ? 現實場景中,有很多用戶請求,日志滾動得很快,所以需要用 tail -100f 跟蹤最新日志,但是有些日志不是我們想要的,就用 grep 過濾日志。
12、查看進程(ps)
? ? ? ? 顯示所有進程,并查找進程:ps aux 或者 ps -ef | grep "進行名" 或 “進程 id”
13、查看網絡狀態(netstat)
? ? ? ? | 表示把前一個命令得輸出,作為后一個命令得輸入。
? ? ? ? netstat -anp | grep "進程名" 或 “端口號”。
14、上傳/下載文件
? ? ? ? 安裝命令:
apt-get install lrzsz
? ? ? ? 上傳文件:直接拖拽 / rz。
? ? ? ? 下載文件:sz 文件名。
四、搭建 Java 部署環境
1、軟件管理(apt)
? ? ? ? 不同發行版的 Linux 軟件管理命令不一樣,Ubuntu 是 apt。
(1)查找軟件包
? ? ? ? 列出的軟件包數據庫:apt list,不建議直接用,因為會顯示所有的軟件,信息太多會卡住。一般搭配 grep。
(2)管理員身份運行
? ? ? ? 在普通用戶上進行 apt 更新、安裝、卸載操作,需要在前面加上?sudo,表示以管理員身份運行。因為軟件的更新、安裝、卸載是管理員才能執行的操作。
? ? ? ? sudo su,可切換至 root 用戶。
(3)更新軟件包數據庫
? ? ? ? 安裝軟件前,需要更新軟件包數據庫。因為 apt 是按照系統上的軟件包數據庫的信息,從倉庫中下載的。如果沒有更新軟件包數據庫,就可能與倉庫中的軟件包信息不一致,導致下載失敗。
? ? ? ? apt-get update
(4)安裝和卸載
? ? ? ? apt install / remove。remove 會殘留配置文件,purge 會把配置文件也刪了。但是也有可能沒刪干凈,查百度。
2、JDK
? ? ? ? 安裝:
// 更新軟件包
apt-get update// 查找 jdk 軟件包
apt list |grep "jdk"// 安裝 jdk
apt install openjdk-17-jdk// 查看 jdk 版本
java -version
? ? ? ? 卸載:
// 查看已安裝 jdk,忽略大小寫
dpkg --list | grep -i jdk// 刪除 jdk
apt-get purge openjdk*// 卸載 jdk
apt-get purge icedtea-* openjdk-*// 查看是否卸載
dpkg --list | grep -i jdk
3、MySQL
? ? ? ? 安裝:
// 查找
apt list |grep "mysql-server"// 安裝
apt install mysql-server// 查看 mysql 狀態
sudo systemctl status mysql
? ? ? ? 安裝安全設置。使用 mysql 的腳本,解決不安全的默認設置:
sudo mysql_secure_installation
? ? ? ? 設置密碼:
// 啟動 mysql
mysql// 設置密碼
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '密碼'// 登錄 mysql
mysql -uroot -p
輸入密碼// 退出 mysql
quit;
? ? ? ? 卸載 mysql:
// 停止 mysql
sudo systemctl stop mysql// 卸載 mysql
sudo apt-get remove --purge mysql-server mysql-client mysql-common// 刪除配置文件和數據
sudo rm -rf /etc/mysql /var/lib/mysql// 清理殘留
sudo apt-get autoremove
sudo apt-get autoclean// 驗證卸載結果
mysql --version
4、部署 Web 到 Linux
? ? ? ? 環境分為:開發環境 dev(開發時用的服務器),測試環境 test(測試人員測試時用的服務器),預發布環境 stage(用的真實用戶數據,但是是內部人員使用發起的請求),灰度環境 prob(逐步上線,一開始只要少量服務器接收用戶請求),發布環境/線上環境 prod(所有服務器都能接收用戶請求)。
? ? ? ? 按這個過程,程序最終上線,就叫做部署。一般公司使用自動化部署工具(如 Jenkins),避免手動部署出錯。
? ? ? ? 在服務器上創建數據庫:
// 執行 .sql 腳本文件
source 腳本文件
(1)Spring Boot 多平臺文件配置? ? ? ??
????????修改 .yml 配置文件,比如數據庫密碼不一樣。但是多個運行環境(idea 本地、服務器開發/測試……)配置文件改來改去很麻煩,就給不同運行環境有不同的 .yml 文件。
? ? ? ? 主配置文件:放公共的部分。@屬性名@
# 哪個環境激活
spring:profiles:active: @profile.name@# 應用服務 WEB 訪問端口
server:port: 8080
# Mybatis-Plus 配置
mybatis-plus:configuration:
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 配置打印 MyBatis ?志map-underscore-to-camel-case: true # 配置駝峰?動轉換
# Spring Boot 日志配置
logging:logback:rollingPolicy:fileNamePattern: logs/spring_blog-%d{yyyy-MM-dd}-%i.logmax-file-size: 10MBmax-history: 30
? ? ? ? 配置 pom 文件:
<profiles><profile><id>dev</id><properties><profile.name>dev</profile.name></properties></profile><profile><id>prod</id><activation><activeByDefault>true</activeByDefault> // 默認激活</activation><properties><profile.name>prod</profile.name></properties></profile></profiles>
? ? ? ? dev:
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/spring_blog?characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=trueusername: rootpassword: "hdalddnasl"driver-class-name: com.mysql.jdbc.Driver
? ? ? ? prod:
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/spring_blog?characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=trueusername: rootpassword: "Zhamuyan200114@"driver-class-name: com.mysql.jdbc.Driver
(2)打包并上線? ? ? ?
????????如果
????????clean >> 打包:
? ? ? ? 把 target 下的 jar 包上傳到服務器,運行程序:
// 后臺運行,就算把連接服務器的終端關閉了,也能運行
??nohup 執行的命令(java -jar jar包) &// 也可以把輸出的內容重定向到 指定文件
??nohup 執行的命令(java -jar jar包) >文件名 &
? ? ? ? 查看程序是否運行:
? ? ? ? 云服務器開放端口號:若有多個端口號,以逗號分隔。
? ? ? ? 如果需要重啟服務,需要先殺掉之前的服務進程,如 8080:kill -9 進程id
(3)存在的問題
①?spring-boot-starter-parent 自帶自動化的資源過濾,如果 springboot 項目沒有指定 spring-boot-starter-parent 的話,使用 @@ 的時候就會報 ScannerException 異常:
? ? ? ? 解決方案:啟用對?src/main/resources
?目錄下資源文件的過濾處理,允許通過占位符動態替換配置文件中的變量。在 build?下加入,主要只需要過濾配置文件,避免把前端靜態資源也過濾了。
<resources><resource><directory>src/main/resources</directory><filtering>true</filtering><includes><include>**/application*</include></includes></resource><resource><directory>src/main/resources</directory><filtering>false</filtering><excludes><exclude>**/application*</exclude></excludes></resource></resources>
②??jar中沒有主清單屬性錯誤。原因是 jar 包里的?META-INF 文件下的?MANIFEST.MF 中缺少?Main-Class 元素聲明,即啟動類所在包。
解決辦法:
③ 服務器本地 root 用戶運行的 Spring Boot 程序無法連接本地數據庫的 root 用戶。解決辦法:
????????查看本地 root 用戶的認證方式:
SELECT User, Host, plugin FROM mysql.user WHERE User = 'root' AND Host = 'localhost';
? ? ? ?
? ? ? ? auth_socket 認證方式,只能通過本地(只能用 UNIX 的?socket?方式登陸)登錄、操作系統用戶必須與數據庫用戶同名。在服務器上 root 用戶直接通過命令行連接本地 mysql (若不指定 --protocol=tcp,則默認通過本地的 mysqld.sock socket 文件連接)的 root 用戶,無需登陸密碼。而 JDBC 默認通過 TCP/IP 協議通信,所以會出現程序連接本地數據庫失敗。
? ? ? ? 解決辦法1(不建議):直接將本地 root 用戶認證方式改為?mysql_native_password,這樣就是通過密碼連接。不建議的原因是,不能使用本地 root 用戶免密連接的功能;再一個是沒有 只給業務用戶 指定的數據庫操作權限安全。
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '密碼';
? ? ? ? 解決辦法2(推薦):
// 創建專用業務用戶
CREATE USER 'spring-blog'@'localhost' IDENTIFIED BY '你的密碼';// 賦予數據庫操作權限
GRANT ALL PRIVILEGES ON 數據庫名.* TO 'spring-blog'@'localhost';// 刷新
FLUSH PRIVILEGES;
④ -parameters 參數問題。?IDEA 的 Java Compiler設置只影響本地編譯,Maven/Gradle 打包時自行調用 Javac,不會讀取 IDEA 的這些配置。
? ? ? ? 解決辦法:在 maven 插件中配置參數。
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><compilerArgs><arg>-parameters</arg></compilerArgs></configuration>
</plugin>
⑤ 如果還有問題,可以查看日志跟蹤。
tail -100f logs/spring_blog.log | grep 'Exception'
????????因為 Spring Boot 項目已經配置了日志持久化,不想 nohup 將輸入保存到 nohup.out,可以使用以下命令丟棄:
nohup 命令 > /dev/null 2>&1 &// 表示將標準輸出(stdout)重定向到 /dev/null(Linux/Unix 系統中的一個特殊文件,也被稱為“黑洞”或“空設備”。),丟棄所有正常輸出。
> /dev/null// 表示將標準錯誤輸出(stderr)重定向到標準輸出(stdout),也就是所有錯誤信息也一起丟棄。
2>&1// 表示在后臺運行該命令
&