本篇隨筆記錄了在學習完SGBlog這個專案之後將這個專案作為我第一個完成的專案部署到雲伺服器的過程.
雖說之前有了解並且看過相關的影片教學,但是第一次實踐還是出現了很多問題
選擇伺服器
伺服器我在這裡選擇的是阿里雲的雲伺服器ECS,為什麼要選擇阿里雲呢? 因為我的OSS也是阿里雲的,所以想著要用就用同一家的吧
因為我有學生認證,所以阿里雲有3個月的試用雲伺服器,這裡我就選用了2核2G的最便宜一檔的伺服器 (因為不是什麼很大的專案而且估計也沒什麼人看)
在選擇完伺服器的配置之後來到了選擇系統這一步,在選擇系統的時候其實我一開始是選擇的windows,心想著windows的圖形化介面用起來很舒服,而且我也熟悉這個系統,隨後安裝了Windows系統來作為我的雲伺服器系統.
伺服器啟動之後想著如何連線到雲伺服器呢?其實之前學習Docker的時候我用的是騰訊的雲伺服器,那時候使用的Linux系統,所以我使用的是WindTerm來建立SSH會話,但是我看阿里雲竟然有自己的一個客戶端,如圖
這個客戶端能快速遠端訪問桌面,很滿意
在使用windows的途中我想起來當初Docker也是執行在Linux上,雖說Windows都能辦到這些(因為我就是這個環境解決了這些問題),但是我不想在雲伺服器上浪費太多時間,之後便切換到了Linux裡的CentOS系統.
專案打包
先說前端專案吧,很簡單,客戶端使用build構建dist,管理端使用build:prod構建dist,因為兩者雖是Vue,但是開發的框架不太一樣 (不想細說了,放過我吧)
之後就是SpringBoot工程的打包,其實第一次打包的時候就是簡單的使用Maven工具裡的Install打包的,jar包執行的時候顯示了報錯 xxxxx-0.0.1-SNAPSHOT.jar中沒有主清單屬性,原因是不能找到程式的主類,需要修改父pom檔案和子模組minghai-blog的pom檔案和子模組minghai-admin的pom檔案
<!-- 此外掛必須放在父 POM 中 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<executions>
<!--
執行本外掛的方法為,在主目錄下執行如下命令:
mvn package assembly:single
對於 IntelliJ IDEA,生成的 JAR 包位於每個模組下的資料夾 target
-->
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<!-- 此處 IntelliJ IDEA 可能會報紅,這是正常現象 -->
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<!-- 配置程式執行入口所在的類 -->
<mainClass>com.minghai.BlogAdminApplication</mainClass>
</manifest>
<manifest>
<!-- 配置程式執行入口所在的類 -->
<mainClass>com.minghai.MHBlogApplication</mainClass>
</manifest>
</archive>
<!-- 設定 JAR 包輸出目錄 -->
<outputDirectory>${project.build.directory}/#maven-assembly-plugin</outputDirectory>
<!-- 設定打包後的 JAR 包的目錄結構為預設 -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
子模組的pom檔案
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
兩個專案打包之後將使用者端管理端的jar包複製到一個檔案裡jar放兩個不同的位置
這裡要先測試以下我們的jar包能否正常執行
在jar包的目錄輸入java -jar <包名>.jar
出現以下的畫面就是SpringBoot的jar包啟動成功了.
前端則是用Nginx來部署專案,這裡將兩個dist放入前端的html資料夾進行測試,並且修改config檔案,這裡就不細展開講(因為windows的nginx部署跟linux的有一點點不一樣(至少我是這麼覺得的))
docker映象的製作
開始痛苦了
這裡我在我的Windows系統上安裝了Docker Desktop,期間經歷了Docker Engine Stopped等各種麻煩(最後妥協了將Docker Desktop安裝在了C盤,主要是不想麻煩了),為什麼要在Windows上安裝Docker? 因為在這上面製作映象,超!級!方!便!
接下來就將需要製作成一個映象的檔案放在同一目錄下以下是Dockerfile的內容(其實可以不放,但是還是放上來看看)
- 管理端的映象檔案
- 使用者端的映象檔案
- Nginx前端檔案的映象檔案
可以看到這裡是暴露了三個埠,8093的是使用者端的,81的則是管理端的,80是Nginx預設自帶的頁面(其實可以不用帶這個,主要是我想留著測試)
製作映象時出現的坑
- 在做到一半的時候我突然想起來我這裡後端專案用的都是開發的時候的環境,也就是我並沒有將資料庫地址什麼的寫成我伺服器的地址,也就是說我伺服器裡的Mysql容器和Redis容器暴露出的埠我這個後端專案並不會連線所以啟動的時候Mybatis和Redis都會報錯(資料來源出問題了)
- 因為SpringBoot的application是可以外部配置的,在同一目錄下的application檔案能修改內部的,所以我這裡就建立了一個application.yml檔案來修改資料來源的一些引數
(具體就不給看了吧,畢竟是伺服器的地址和埠,還有資料庫的賬號密碼) - 其實有想過掛載捲到容器上的application上的,但是想想太麻煩了,而且這個也不是什麼需要持久化的東西,所以就直接在映象裡打包了.
- Nginx的default.conf和nginx.conf是合併的配置檔案(目前是這麼理解的)而我直接在Windows上測試完成直接將Nginx.config裡的內容copy到了default.conf裡的,所以導致docker後來部署的時候老是報錯這一行程式碼不能出現在這裡之類的錯誤.
在雲伺服器的Linux CentOS系統上使用Docker進行專案的快速部署
一點都不快速,純命令列的系統快折磨死我了
(其實是第一次部署什麼都不熟悉老是出錯誤而已)
- 透過阿里雲的這個SSH連線進入到CentOS系統裡(其實還有windTerm,但我覺得阿里雲這個更好用),查閱Docker的文件使用指令安裝完Docker之後檢查Docker安裝情況沒問題之後開始拉取製作好的映象進行部署
- 這裡因為Docker被牆了(2024/10/24)所以在沒有科學的情況下無法正常拉取到映象,這時後我們就需要給Docker新增映象
- 這裡我就不上伺服器來截圖了,就拿我的虛擬機器CentOS系統來說明,我們進入/etc/docker這個目錄,在裡面找到daemon.json這個檔案,我們開啟這個檔案並將我們找到的映象加入到這裡面
sudo nano /etc/docker/daemon.json
{
"registry-mirrors": [
"https://1thrb1uh.mirror.aliyuncs.com",
"https://dockerpull.com",
"https://docker.udayun.com",
"https://dockerproxy.cn",
"https://docker.rainbond.cc",
"https://docker.211678.top"
]
}
- 需要注意的一點是內容必須是Json格式,出一點錯啟動Docker的時候都會報錯
- 但是這個方法我自己使用下來有個問題,那就是隻能pull,其他的操作都不行(search,login,(push沒試過))
- 解決方法:Linux上的科學
- 其實在這個階段卡最久的就是我的容器各種啟動失敗報錯,其中最多的就是配置檔案(包括不限於上文提到的nginx配置檔案跟windows系統的區別以及後端檔案資料庫引數修改的問題)的問題,透過百度一個個問題之後也是能解決.
- 這個階段主要是複習了很多Docker的知識和Linux系統的知識
- 還有一點就是在這裡我的Mysql是使用掛載捲來實現資料持久化的儲存在了/mydata/mysql目錄裡
- 這裡要記住一個很重要的引數就是 -v <你的目錄>:<容器中的目錄>將容器中的目錄繫結到掛載卷裡,這樣子就算容器刪除了下次新增容器的時候也是能讀取到這個資料的
- redis裡記得將daemonize設定成no,不然會閃退
(我也沒去研究為什麼)
專案的正式上線
- 在上線之後我進入前端,發現能訪問了,非常好!
- 但是在點開一篇文章之後我傻眼了,彈出了後端介面404,我去檢視了我的容器執行狀況,
docker ps
- 發現容器都在正常的執行,我檢視了使用者端後臺的日誌
docker logs <容器名字>
- 發現我這個程式沒!有!收!到!任!何!請!求!
- 開啟F12一看,好傢伙,請求地址localhost:7777,這是還沒把前端檔案裡的baseUrl改過來,於是去前端裡更改了baseUrl之後重新打包上傳部署
- 之後就沒問題了,可以正常使用功能,專案也算是上線了(有Bug但是不是很嚴重所以就不想著去解決了,主要是這個系統是我的第一個從後端開發正式部署上線的專案)
這個專案之後的感想
- 其實這個專案整體難度並沒有這個大,對我來說最難的是實現登入驗證的SpringBootSecurity和Jwt的使用(因為在專案前幾天的時候我還在想前後端專案分離了之後我還怎麼儲存登入狀態,之前的Servlet和Jsp又或者是SpringMvc使用模板引擎都是使用Session來儲存登入狀態),SpringSecurity還提供了許可權控制,更是方便.
- 果然學會一樣東西最好的方式就是動手實踐,因為當初這個docker的使用我看影片過了一遍感覺似懂非懂,很多都是模模糊糊的過去了,所以這次部署專案的時候就是對docker有個大概印象但是還是要去查閱大量的文件教程來使用
- 在這個專案中加深了對MVC軟體設計模式的理解,複習了SpringMVC,Spring,Mybatis(MybatisPlus)的使用(其實說白了就是加深鞏固了SSM整合開發框架)
- 這個專案還帶我接觸了OSS物件儲存和雲伺服器的實戰部署,使用了linux來部署專案(之前沒怎麼接觸過,最早解除是在學嵌入式C++開發的時候)
- 感謝三更老師的課程!