還不會部署微服務項目?保姆級教程來啦!
大家好,我是魚皮。
項目上線是每位學編程同學必須掌握的基本技能。之前我已經給大家分享過很多種上線單體項目的方法了,今天再出一期微服務項目的部署教程,用一種最簡單的方法,帶大家輕松部署微服務項目。
開始之前,先做個小調研啊,大家更喜歡看 “真實踩坑版” 的教程還是 “壓縮純凈版” 的教程呢?
本期教程我還是保持自己一貫的風格,依然是保姆級教程,包含了一些踩坑過程和解決方案,大家跟著做就完事兒~
更推薦看視頻版:https://www.bilibili.com/video/BV1Cp4y1F7eA/
項目介紹
這次的教程以我帶大家全程直播手把手開發的、基于 Spring Cloud + Docker 代碼沙箱的 在線判題系統 為例,進行演示。
這個項目的核心功能是讓用戶能夠在線選題和做題,然后由系統自動判題:
項目用到的核心依賴包括:MySQL 數據庫、Redis 緩存、RabbitMQ 消息隊列、Nacos 注冊中心
涉及的核心服務包括:用戶服務、題目服務、判題服務(代碼沙箱)、Gateway 網關服務
傳統部署
對于這樣一個項目,如果我們還用傳統單機項目的部署方式,一個個打 jar 包、用 Java 命令來啟動,會有哪些問題呢?
- 要一個個安裝依賴,比如 MySQL 數據庫、Redis、消息隊列、Nacos,非常麻煩!
- 要一個個打 jar 包、一個個手動運行 jar 包,非常麻煩!
- 不方便集中觀察所有服務的運行狀態和資源占用情況
所以,為了解決這些問題,我們會選用一種更高效的微服務部署方式 —— Docker Compose。
Docker Compose 介紹
在介紹 Docker Compose 前,先簡單介紹下 Docker。
Docker 是一種容器技術,允許開發者將應用程序和所有依賴項(如代碼、庫、配置等)制作為 鏡像
。可以把鏡像簡單理解為軟件安裝包,可以在不同的計算機上通過它快速安裝和啟動應用程序(容器),這些程序獨立隔離地運行,不受外部環境的影響。
如果要部署微服務項目,可能要啟動多個 Docker 容器,比如 MySQL 容器、用戶服務容器等。這時就需要 Docker Compose 了。它是一個容器編排助手,用于集中管理多個 Docker 容器的啟動和協同工作。可以在一個配置文件中集中定義所有容器以及它們的關系。然后,可以使用一行命令啟動所有容器,而不需要手動運行多個命令。
需要注意的是,Docker Compose 通常適用于把所有微服務部署在同一臺服務器的場景,在真實的企業級項目中,往往會使用 K8S 等更專業的容器編排和自動化部署工具,更方便地在多個服務器上部署容器。
部署流程
了解了 Docker 和 Docker Compose 的作用后,我們來快速了解下部署流程,分為 2 大階段 —— 本地部署和服務器部署。
一、本地部署
- 梳理服務部署表格
- Maven 子父模塊打包
- Dockerfile 編寫
- 編寫環境依賴配置
- 編寫服務配置
- 調整程序配置
- 測試訪問
二、服務端部署
- 準備服務器
- Docker Compose 安裝
- 同步文件
- 獲取 jar 包
- 服務啟動
- 測試訪問
一、本地部署
第一階段是本地部署,也可以叫做部署準備。
強烈建議大家,比起直接操作線上服務器,最好是先在本地把所有的流程跑通,風險更低、效率更高。
這里我使用的是 Mac 操作系統,已經安裝了 Docker Desktop 軟件,管理 Docker 容器會更方便一些。
對于本地沒有 Docker 環境的同學,這一階段仔細看一遍有個印象就足夠了。可以直接拿我調試好的配置文件在服務器上部署,而不用自己調試。
怎么樣,夠貼心吧!可以叫我 “保姆魚皮”,簡稱 “保姆皮”。
1.1、梳理服務部署表格
在部署微服務項目前,首先要規劃好要部署哪些服務、以及各服務的關鍵信息,比如服務名稱、版本號、占用端口號、關鍵配置等。
對于我的在線判題項目,梳理好的服務表格如下:
服務名稱 | 英文名 | 端口號 | 版本號 | 服務類別 |
數據庫 | mysql | 3306 | v8 | 環境依賴 |
緩存 | redis | 6379 | v6 | 環境依賴 |
消息隊列 | rabbitmq | 5672, 15672 | v3.12.6 | 環境依賴 |
注冊中心 | nacos | 8848 | v2.2.0 | 環境依賴 |
網關服務 | gateway | 8101 | java 8 | 業務服務 |
用戶服務 | yuoj-backend-user-service | 8102 | java 8 | 業務服務 |
題目服務 | yuoj-backend-question-service | 8103 | java 8 | 業務服務 |
判題服務 | yuoj-backend-judge-service | 8104 | java 8 | 業務服務 |
為什么這里我要劃分服務類別為 “環境依賴” 和 “業務服務” 呢?
因為在啟動服務時,必須要先啟動環境依賴,才能啟動業務服務,否則就會報類似 “無法連接數據庫” 之類的錯誤。
1.2、Maven 子父模塊打包
對于微服務項目,我們通常是使用 Maven 的子父模塊功能進行管理的。需要部署項目時,不用針對每個子服務單獨執行 mvn package
命令進行打包,而是可以一鍵打包所有服務。
想要實現這個功能,需要給子父模塊的依賴文件(pom.xml)進行一些配置,主要包括:
1)父模塊配置
在父模塊的 pom.xml 文件中引入 spring-boot-maven-plugin
即可,注意一定不要配置 configuration 和 repackage!
示例代碼如下:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
2)子模塊配置
修改所有需要啟動 Spring Boot 的服務(用戶服務、題目服務、判題服務、網關服務)的子模塊 pom.xml 文件。
主要是增加 executions 配置,使用 spring-boot-maven-plugin 的 repackage 命令來構建子模塊,從而自動在構建時將公共模塊的依賴打入 jar 包。
示例代碼如下:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
1.3、Dockerfile 編寫
Dockerfile 是定義 Docker 容器鏡像構建過程的文件,包括容器鏡像使用的基礎環境、容器內的依賴和文件、容器的配置、啟動命令等。
有了 Dockerfile,我們就能很輕松地制作出自己的容器鏡像。
雖然 Dockerfile 的寫法并不復雜,但我還是建議大家盡量不要自己寫,直接去網上找個差不多的項目,復制粘貼別人的 Dockerfile 就足夠了!
這里魚皮給大家提供 2 種常用的 Spring Boot 項目的 Dockerfile。
1)復制 jar 包版
思路:在本地打好 jar 包后,復制 jar 包到容器中運行
示例代碼如下:
# 基礎鏡像
FROM openjdk:8-jdk-alpine
# 指定工作目錄
WORKDIR /app
# 將 jar 包添加到工作目錄,比如 target/yuoj-backend-user-service-0.0.1-SNAPSHOT.jar
ADD {本地 jar 包路徑} .
# 暴露端口
EXPOSE {服務端口號}
# 啟動命令
ENTRYPOINT ["java","-jar","/app/{jar 包名稱}","--spring.profiles.active=prod"]
2)Maven 打包版
思路:復制本地代碼到容器中,在容器中使用 Maven 打包再運行
示例代碼如下:
# 基礎鏡像
FROM maven:3.8.1-jdk-8-slim as builder
# 指定工作目錄
WORKDIR /app
# 添加源碼文件
COPY pom.xml .
COPY src ./src
# 構建 jar 包,跳過測試
RUN mvn package -DskipTests
# 啟動命令
ENTRYPOINT ["java","-jar","/app/target/{jar 包名稱}","--spring.profiles.active=prod"]
此處由于我們的微服務項目可以一鍵打好所有子服務的 jar 包,就沒必要每個服務單獨在容器中打包了,所以選擇第一種方式的 Dockerfile。
我們需要給每個 Spring Boot 服務(用戶服務、題目服務、判題服務、網關服務)都編寫一個 Dockerfile,放到每個子服務的根目錄下。
以用戶服務為例,示例代碼如下:
# 基礎鏡像
FROM openjdk:8-jdk-alpine
# 指定工作目錄
WORKDIR /app
# 將 jar 包添加到工作目錄,比如 target/yuoj-backend-user-service-0.0.1-SNAPSHOT.jar
ADD target/yuoj-backend-user-service-0.0.1-SNAPSHOT.jar .
# 暴露端口
EXPOSE 8102
# 啟動命令
ENTRYPOINT ["java","-jar","/app/yuoj-backend-user-service-0.0.1-SNAPSHOT.jar","--spring.profiles.active=prod"]
建議先在本地利用 IDEA 開發工具調通鏡像構建流程,確保每個 Dockerfile 都是可以成功制作鏡像的:
查看容器的啟動日志,發現能夠啟動服務、看到 Spring 圖標即可:
1.4、編寫環境依賴配置
接下來,我們就要編寫 Docker Compose 的配置文件了,可以根據配置文件快速啟動多個服務。
之前我們已經梳理了服務部署表格,將服務劃分為了 “環境依賴” 和 “業務服務”。
由于業務服務依賴 MySQL 等環境依賴,所以需要拆分 2 套 Docker Compose 的配置文件,分別為 docker-compose.env.yml
環境配置和 docker-compose.service.yml
業務服務配置,保證先成功啟動依賴,再啟動服務。
學過 Docker Compose 的同學可能聽說過 depends_on 配置,也能決定服務的啟動順序。但是千萬注意,depends_on 并不會等待服務完全就緒,只是確保它們在啟動時的順序,并不穩定。
如何編寫 Docker Compose 文件呢?
和 Dockerfile 一樣,直接去網上找現成的 Docker Compose file,復制粘貼過來略做修改就能使用了~
再配合以下 2 個網站,完全無需記憶 Docker Compose 的寫法!
- Docker Compose file 官方文檔:https://docs.docker.com/compose/compose-file/
- 搜索現成的 Docker 鏡像:https://hub.docker.com/
當然,現在 AI 時代了,還有更簡單的方式!
直接把我們整理好的服務部署需要喂給 GPT,讓 AI 幫我們生成配置即可~
示例 prompt:
現在我需要用 docker compose 來部署 mysql 8(3306 端口)username=root,password=123456
redis 6(無密碼,6379端口)、rabbitmq v.3.12.6( 5672 端口 password: guest,username: guest)、nacos 2.2.0(8848端口);還有 4 個本地的 springboot 服務(名稱分別為:yuoj-backend-user-service 8102端口、yuoj-backend-question-service 8103端口、yuoj-backend-judge-service 8104端口、yuoj-backend-gateway 8101 端口),每個服務本地目錄都有一個 Dockerfile,請幫我自動生成 docker compose 的 yml 配置文件,要求這些服務網絡能夠連通
效果還是非常不錯的,只要你描述地足夠清楚,生成的配置完全可用!
由于這篇文章是教程嘛,我就帶大家通過調試的方式一步步完成 Docker Compose 文件,最后會把完整的 Docker Compose 文件給大家分享出來,大家直接用就行了~
我們要分別在 Docker Compose 中定義 4 大基礎依賴,包括 MySQL、Redis、RabbitMQ 和 Nacos。
1)MySQL
我們不僅要創建一個 MySQL 服務,還要在創建服務后自動創建我們需要的庫表結構。
所以需要先準備數據庫 SQL 腳本文件,里面包含了建庫、建表語句,我們把它放在微服務項目根目錄的 mysql-init
文件夾中:
魚皮帶大家做的每個項目都提供了現成的建表語句,這是一個非常好的開發習慣,便于其他人快速啟動你的項目。
由于要在本地啟動 MySQL,還需要定義一個文件夾 .mysql-data
來存放 MySQL 的持久化數據,防止容器重啟后數據丟失。
做好這兩點后,就可以編寫 docker-compose.env.yml
文件了,先只寫一個 MySQL 服務,示例代碼如下:
關鍵配置的含義我都寫到注釋里了
version: '3'
services:
mysql:
image: mysql:8 # 使用的鏡像
container_name: yuoj-mysql # 啟動的實例名稱
environment:
MYSQL_ROOT_PASSWORD: 123456 # root 用戶密碼
ports:
- "3306:3306" # 端口映射
volumes:
- ./.mysql-data:/var/lib/mysql # 將數據目錄掛載到本地目錄以進行持久化
- ./mysql-init:/docker-entrypoint-initdb.d # 自動執行啟動腳本
restart: always # 崩潰后自動重啟
networks:
- mynetwork # 指定網絡
networks:
mynetwork: # 自定義網絡,實現網絡互通和隔離
寫好配置文件后,可以直接在 IDEA 里執行 Docker Compose 文件,調試 MySQL 的運行:
運行成功后,我們可以在本地成功連接數據庫:
2)Redis
Redis 服務的定義和啟動操作和 MySQL 服務幾乎一致,Redis 的 Docker Compose 配置示例代碼如下:
version: '3'
services:
redis:
image: redis:6
container_name: yuoj-redis
ports:
- "6379:6379"
networks:
- mynetwork
volumes:
- ./.redis-data:/data # 持久化
networks:
mynetwork:
然后在本地執行 Docker Compose 文件,啟動 Redis 服務,并且嘗試進入 Terminal 來調試 Redis:
3)RabbitMQ
同 MySQL 和 Redis,RabbitMQ 的 Docker Compose 配置示例代碼如下:
version: '3'
services:
rabbitmq:
image: rabbitmq:3.12.6-management # 支持管理面板的消息隊列
container_name: yuoj-rabbitmq
environment:
RABBITMQ_DEFAULT_USER: guest
RABBITMQ_DEFAULT_PASS: guest
ports:
- "5672:5672"
- "15672:15672" # RabbitMQ Dashboard 端口
volumes:
- ./.rabbitmq-data:/var/lib/rabbitmq # 持久化
networks:
- mynetwork
networks:
mynetwork:
本地執行 Docker Compose 文件,啟動 RabbitMQ 服務,然后可以訪問 localhost:15672
查看到管理面板,就表示啟動成功了~
賬號密碼都是 guest
4)Nacos
和其他服務一樣,Nacos 也需要編寫 Docker Compose 配置。
但是在選擇 Nacos 鏡像時必須要注意,建議選擇支持 linux/arm64 架構的鏡像版本,比如 v2.2.0-slim
,否則后面可能會無法運行:
Nacos 示例配置文件如下:
version: '3'
services:
nacos:
image: nacos/nacos-server:v2.2.0-slim
container_name: yuoj-nacos
ports:
- "8848:8848"
volumes:
- ./.nacos-data:/home/nacos/data
networks:
- mynetwork
environment:
- MODE=standalone # 單節點模式啟動
- PREFER_HOST_MODE=hostname # 支持 hostname
- TZ=Asia/Shanghai # 控制時區
networks:
mynetwork:
然后在本地執行 Docker Compose 啟動 Nacos,訪問 localhost:8848/nacos
能夠看到管理頁面,就表示運行成功了~
管理頁面的賬號和密碼默認都是 nacos
完整 Docker Compose 文件
分別調試完上述服務后,我們把所有的配置拼在一起,就得到了完整的文件,文件名為 docker-compose.env.yml
。
完整代碼如下:
version: '3'
services:
mysql:
image: mysql:8 # 使用的鏡像
container_name: yuoj-mysql # 啟動的實例名稱
environment:
MYSQL_ROOT_PASSWORD: 123456 # root 用戶密碼
ports:
- "3306:3306" # 端口映射
volumes:
- ./.mysql-data:/var/lib/mysql # 將數據目錄掛載到本地目錄以進行持久化
- ./mysql-init:/docker-entrypoint-initdb.d # 啟動腳本
restart: always # 崩潰后自動重啟
networks:
- mynetwork # 指定網絡
redis:
image: redis:6
container_name: yuoj-redis
ports:
- "6379:6379"
networks:
- mynetwork
volumes:
- ./.redis-data:/data # 持久化
rabbitmq:
image: rabbitmq:3.12.6-management # 支持管理面板的消息隊列
container_name: yuoj-rabbitmq
environment:
RABBITMQ_DEFAULT_USER: guest
RABBITMQ_DEFAULT_PASS: guest
ports:
- "5672:5672"
- "15672:15672" # RabbitMQ Dashboard 端口
volumes:
- ./.rabbitmq-data:/var/lib/rabbitmq # 持久化
networks:
- mynetwork
nacos:
image: nacos/nacos-server:v2.2.0-slim
container_name: yuoj-nacos
ports:
- "8848:8848"
volumes:
- ./.nacos-data:/home/nacos/data
networks:
- mynetwork
environment:
- MODE=standalone # 單節點模式啟動
- PREFER_HOST_MODE=hostname # 支持 hostname
- TZ=Asia/Shanghai # 控制時區
networks:
mynetwork:
1.5、編寫業務服務配置
用同樣的方式,我們可以編寫業務服務的 Docker Compose 文件,文件名稱 docker-compose.service.yml
。
示例代碼如下,其中需要格外關注的配置是 build 和 depends_on:
version: '3'
services:
yuoj-backend-gateway:
container_name: yuoj-backend-gateway
build: # 服務的 Docker 構建文件位置
context: ./yuoj-backend-gateway
dockerfile: Dockerfile
ports:
- "8101:8101"
networks:
- mynetwork
yuoj-backend-user-service:
container_name: yuoj-backend-user-service
build:
context: ./yuoj-backend-user-service
dockerfile: Dockerfile
ports:
- "8102:8102"
networks:
- mynetwork
depends_on: # 本服務依賴的服務,控制啟動先后順序
- yuoj-backend-gateway
yuoj-backend-question-service:
container_name: yuoj-backend-question-service
build:
context: ./yuoj-backend-question-service
dockerfile: Dockerfile
ports:
- "8103:8103"
networks:
- mynetwork
depends_on:
- yuoj-backend-user-service
- yuoj-backend-gateway
yuoj-backend-judge-service:
container_name: yuoj-backend-judge-service
build:
context: ./yuoj-backend-judge-service
dockerfile: Dockerfile
ports:
- "8104:8104"
networks:
- mynetwork
depends_on:
- yuoj-backend-user-service
- yuoj-backend-question-service
- yuoj-backend-gateway
# 網絡,不定義的話就是默認網絡
networks:
mynetwork:
1.6、調整程序配置
編寫好上述配置文件后,本地嘗試運行 Docker Compose 業務服務,結果發現:報錯啦!依賴服務的地址訪問不通!
這是由于之前我們的項目訪問依賴服務時,全部是使用了固定的 IP 地址(比如 localhost),而容器內部的 localhost(或 127.0.0.1)通常指向容器本身,而不是宿主主機。所以為了在容器內訪問其他服務,程序中應該使用服務名稱而不是 localhost。
我們給每個 Spring Boot 服務都增加一套 prod 上線配置,在配置中更改服務調用地址。
用戶服務、題目服務和判題服務的 application-prod.yml
配置修改如下:
# 生產環境配置文件
spring:
# 數據庫配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://mysql:3306/yuoj # localhost 改為 mysql
username: root
password: 123456
# Redis 配置
redis:
database: 1
host: redis # localhost 改為 redis
port: 6379
timeout: 5000
cloud:
nacos:
discovery:
server-addr: nacos:8848 # localhost 改為 nacos
rabbitmq:
host: rabbitmq # localhost 改為 rabbitmq
port: 5672
password: guest
username: guest
Gateway 網關服務的配置修改如下:
spring:
cloud:
nacos:
discovery:
server-addr: nacos:8848 # localhost 改為 nacos
gateway:
routes:
- id: yuoj-backend-user-service
uri: lb://yuoj-backend-user-service
predicates:
- Path=/api/user/**
- id: yuoj-backend-question-service
uri: lb://yuoj-backend-question-service
predicates:
- Path=/api/question/**
- id: yuoj-backend-judge-service
uri: lb://yuoj-backend-judge-service
predicates:
- Path=/api/judge/**
application:
name: yuoj-backend-gateway
main:
web-application-type: reactive
server:
port: 8101
knife4j:
gateway:
enabled: true
strategy: discover
discover:
enabled: true
version: swagger2
然后執行 mvn package
命令重新打包、執行 Docker Compose。
結果發現大多數服務都啟動了,但是判題服務還有報錯。
這是因為程序在創建消息隊列時存在硬編碼的變量,指定了 host 為 "localhost",示例代碼如下:
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
String EXCHANGE_NAME = "code_exchange";
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
舉這個例子是為了告訴大家,在程序中盡量不要寫固定 IP 或域名,全部改為動態讀取配置文件,便于修改。
示例修改后的代碼如下:
/**
* 用于創建測試程序用到的交換機和隊列(只用在程序啟動前執行一次)
*/
@Slf4j
@Component
public class InitRabbitMqBean {
@Value("${spring.rabbitmq.host:localhost}")
private String host;
@PostConstruct
public void init() {
try {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(host);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
String EXCHANGE_NAME = "code_exchange";
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 創建隊列,隨機分配一個隊列名稱
String queueName = "code_queue";
channel.queueDeclare(queueName, true, false, false, null);
channel.queueBind(queueName, EXCHANGE_NAME, "my_routingKey");
log.info("消息隊列啟動成功");
} catch (Exception e) {
log.error("消息隊列啟動失敗");
}
}
}
1.7、測試訪問
修復上述問題后,所有服務都可以通過 Docker Compose 文件啟動了。
然后我們訪問 localhost:8101/doc.html
網關地址,能夠看到 Swagger 聚合接口文檔。
依次調用用戶注冊 => 登錄 => 獲取登錄用戶信息 => 創建題目接口,全部執行成功。
至此,第一階段就完成啦。
二、服務器部署
在第二階段,我們的目標就是在真實的 Linux 服務器上部署微服務項目。有了第一階段的準備,第二階段簡直可以說是易如反掌!
2.1、準備服務器
首先,我們要有一臺 Linux 服務器。
選擇服務器前,我們必須要評估下微服務項目的內存占用,千萬別把服務器的內存買小了!
可以使用 Docker Desktop 直接查看內存占用,虛擬機內存大概占用了 8 個 G、容器實際內存占用了 4 個 G:
那我們搞多少內存的服務器呢?
我猜很多同學會說 8 G,奈何我天生反骨,明知山有虎偏向虎山行(主要是想省 ??),我就搞一臺 2 核 4 G 的服務器吧(發行版是 CentOS 7.9 Linux),咱們來猜一猜它夠不夠部署這套有 4 個業務服務的微服務項目呢?
咱們一起來見證下!
2.2、Docker Compose 安裝
有了服務器后,直接參考 Docker Compose 官方文檔來安裝。這里我們使用 Docker Compose V2 版本,相比 V1 版本統一了命令,使用更方便:
Docker Compose V2 地址:https://docs.docker.com/compose/migrate/
Docker Compose Linux 安裝:https://docs.docker.com/compose/install/linux/#install-using-the-repository
安裝過程很簡單,跟著官方文檔來就行了,主要包括以下幾個步驟:
1)設定安裝來源:
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
2)安裝 Docker 和 Docker Compose:
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
3)啟動 Docker:
sudo systemctl start docker
4)測試 Docker:
systemctl status docker
sudo docker run hello-world
2.3、同步文件
接下來,我們需要把本地折騰好的微服務項目源碼上傳到服務器上,可以選擇用 FTP 或 SSH 連接文件手動上傳文件。
我這里使用 JetBrains 開發工具的遠程部署功能,可以配置文件自動上傳,步驟如下:
1)進入遠程部署配置
2)添加遠程部署配置:
這里建議大家不要暴露自己的服務器 IP 啊,當你看到本文的時候,其實我已經把服務器的 IP 更換掉了哈哈哈哈哈哈哈哈!
3)指定連接的服務器配置:
4)配置本地文件和服務器文件路徑映射:
5)開啟自動上傳:
6)首次需要手動上傳文件。
上傳前記得先刪除無用的文件,然后右鍵項目根目錄,點擊部署上傳代碼:
上傳成功,在服務器對應路徑(/code/yuoj-backend-microservice)下能看到已上傳的文件列表:
2.4、獲取 jar 包
光把代碼上傳到服務器還是不夠的,因為我們構建 Docker 鏡像需要 jar 包。
有 2 種方式得到 jar 包:
- 本地執行
mvn package
打好 jar 包,然后再上傳 - 服務器上裝 Maven,在服務器上打包
但是因為 jar 包比較大,頻繁改動的話同步速度會比較慢,所以更建議第二種方式,步驟如下:
1)安裝 Maven:
sudo yum install maven
2)安裝好后,執行打包:
sudo mvn package
打包成功:
2.5、服務啟動
所有一切準備就緒,接下來就是使用 Docker Compose 命令分別啟動環境依賴和業務服務啦。
1)啟動環境依賴
先使用 docker compose 一行命令啟動環境依賴:
docker compose -f docker-compose.env.yml up
注意:
- 老版本使用 "docker-compose" 替代 "docker compose"
- 如果沒有權限,命令前加上 "sudo"
然后喝杯咖啡,等待啟動即可~
啟動成功后,我們可以通過公網 IP 來嘗試訪問服務。
先進入到云服務商的服務器配置頁,修改服務器的防火墻配置,放通以下端口:
然后像訪問本地服務一樣分別去訪問 MySQL、Redis、RabbitMQ、Nacos 即可,應該都是成功的。
由于進程在前臺啟動會影響我們的操作,所以先按 ctrl + c
退出,加上 -d
參數讓容器在后臺啟動:
sudo docker compose -f docker-compose.env.yml up -d
試著查看下 docker 容器的狀態:
sudo docker stats
能夠查看到所有容器的資源占用情況:
實話說,我開始緊張了,不知道 4 G 的內存夠不夠撐。。。
2)啟動業務服務
確保環境依賴都啟動成功后,接下來啟動業務服務:
docker compose -f docker-compose.service.yml up
項目全部啟動,看得很爽:
正常來說,應該會啟動成功;但如果運氣背,可能會有失敗,比如我這的網關服務就啟動失敗了。
如果某個服務啟動失敗,可以再次單獨只啟動它,比如網關服務:
sudo docker compose -f docker-compose.service.yml up yuoj-backend-gateway
2.6、測試訪問
最后,像驗證本地微服務項目部署一樣,訪問線上網關的接口文檔( http://你的服務器 IP:8101/doc.html ),依次調用用戶注冊 => 登錄 => 獲取登錄用戶信息 => 創建題目,全部成功~
最后使用 docker stats
命令查看 Docker 容器的狀態,發現總共的內存占用大概 3 G,也就是說 4 G 內存的服務器是完全足夠小型微服務項目的部署了~
至此,微服務項目部署教程就結束了。
最后
最后我再問個問題,如果我只有一臺 2 G 內存的服務器,能否成功部署這套有 4 個業務服務的項目呢?如果能的話,又應該怎么部署呢?歡迎大家討論。
下圖是個小提示: