React/Vue 實現的前端應用, java/Go/Python 實現的後端應用,前後端分離的應用部署的最佳實踐

gongchengship發表於2024-10-20

前後端分離的應用(React 前端 + Java 後端)在部署過程中,需要考慮效能、擴充套件性、安全性、以及維護方便性等多個方面。下面我將詳細介紹前後端分離應用的最佳實踐,從架構設計構建和打包部署策略CI/CD 整合安全性措施等幾個角度來描述。

微服務架構圖示例


壹.總體概述

一、架構設計

1. 前後端的獨立部署

  • 前端:React 應用是一個單頁應用(SPA,Single Page Application),可以透過 Webpack 等工具進行打包,最後生成靜態資原始檔(如 .html.css.js)。前端可以直接部署在靜態資源伺服器上(如 Nginx、Apache),或者託管在 CDN 上。
  • 後端:Java 後端通常是透過 Spring Boot、Spring Cloud 或其他框架構建的 RESTful API 或 GraphQL API 服務。Java 應用可以打包成獨立的 JAR 檔案或者部署到應用伺服器上(如 Tomcat、Jetty),也可以透過 Docker 容器化部署。

這種架構使得前後端可以獨立擴充套件獨立部署,前端可以放在 CDN 上以提升載入速度,後端可以單獨橫向擴充套件以提高 API 處理能力。

2. API Gateway(可選)

  • 在一些更復雜的應用中,特別是在微服務架構下,可能會用到 API Gateway 作為後端服務的統一入口。API Gateway 可以處理請求的路由、負載均衡、認證、限流等操作,提升系統的安全性和效能。
  • 例如,使用 Nginx 作為反向代理伺服器,將前端的請求轉發到對應的後端 API 伺服器。或者在微服務場景下,使用 Zuul、Kong 或者 Spring Cloud Gateway 等閘道器解決方案。

二、前端構建與打包

1. 構建工具:React 應用可以使用 Webpack 或者 Create React App 進行構建。在生產環境中,可以透過 Webpack 的最佳化配置來壓縮檔案和減少資源大小。

  • 打包配置

    • 使用 TerserPlugin 來最小化 JavaScript 檔案。
    • 使用 MiniCssExtractPlugin 將 CSS 提取成獨立檔案並壓縮。
    • 利用 Content Hashing 來實現快取最佳化。
  • 構建命令:執行 npm run buildyarn build 來生成生產環境下的靜態檔案(通常放在 /build 目錄中)。

2. 前端資源的託管:打包後的靜態資源可以部署在以下位置:

  • CDN(內容分發網路):將前端的靜態資源上傳到 CDN 服務提供商(如 AWS CloudFront、阿里雲 CDN、Cloudflare 等),使得使用者可以從離他們最近的伺服器下載前端資源,加快頁面的載入速度。
  • 靜態資源伺服器:可以使用 Nginx、Apache 作為靜態資源伺服器。Nginx 不僅能託管前端檔案,還能充當反向代理轉發請求到後端 API 服務。

3. 路由處理:如果使用 React Router 管理前端路由,在使用靜態伺服器(如 Nginx)時需要處理前端路由。因為所有的前端路由都應該返回同一個 index.html 檔案:

  • Nginx 的配置中需要新增類似:
    location / {
        try_files $uri /index.html;
    }
    

三、後端部署

1. 獨立部署 Java 應用

  • 傳統部署方式:透過將 Java 應用(如 Spring Boot 專案)打包成可執行的 JAR 檔案(使用 mvn packagegradle build),然後直接執行 java -jar app.jar
  • 容器化部署:使用 Docker 將 Java 應用容器化,可以使用官方的 OpenJDK 映象作為基礎映象,並在其上構建應用。
    • Dockerfile 示例:
      FROM openjdk:11-jre-slim
      COPY target/app.jar /app/app.jar
      ENTRYPOINT ["java", "-jar", "/app/app.jar"]
      

部署後可以使用 Kubernetes 等容器編排工具來管理容器的擴充套件、滾動更新等。

2. 連線資料庫和快取

  • 後端通常需要連線資料庫(如 MySQL、PostgreSQL 等),或者分散式快取(如 Redis、Memcached)。
  • 使用資料庫連線池(如 HikariCP)來最佳化資料庫連線的效能。
  • 可以透過配置環境變數或者配置檔案管理資料庫連線資訊。

3. 負載均衡

  • 可以使用 Nginx 或者 HAProxy 進行負載均衡,將請求分發到多個後端例項,提升可擴充套件性和容錯能力。
  • 在容器化部署時,可以利用 Kubernetes 的 Service 和 Ingress 進行負載均衡。

四、CI/CD 整合

1. CI/CD 管道:透過 Jenkins、GitLab CI、GitHub Actions 等工具實現自動化構建、測試、部署。

  • 前端:當程式碼推送到版本控制系統時,CI 系統可以自動執行 npm run build 來構建前端程式碼,生成的靜態檔案會被自動上傳到 CDN 或靜態資源伺服器。
  • 後端:後端 Java 應用可以在 CI/CD 管道中自動構建(使用 Maven/Gradle),並打包成 Docker 映象。然後將映象推送到 Docker Registry(如 DockerHub 或私有倉庫),最後使用 Kubernetes 或其他工具進行自動化部署。

2. 藍綠部署/滾動更新:在後端部署時,可以使用藍綠部署(Blue-Green Deployment)或滾動更新(Rolling Update)策略,保證應用在不中斷服務的情況下進行更新。

  • 藍綠部署:建立兩個環境(blue 和 green),新的程式碼部署到空閒的環境中,測試透過後,切換流量到新環境。
  • 滾動更新:逐步替換掉老的服務例項,避免服務中斷。

五、安全性

1. 跨域問題(CORS)

  • 由於前後端分離,前端發起的請求會受到瀏覽器的跨域訪問限制。需要在後端 Java 應用中正確配置 CORS(Cross-Origin Resource Sharing)策略。
  • 在 Spring Boot 中可以透過 @CrossOrigin 註解或者全域性配置來解決跨域問題。

示例:

@RestController
@CrossOrigin(origins = "https://your-frontend-domain.com")
public class ApiController {
    // API endpoints
}

2. HTTPS 和證書管理

  • 確保前後端通訊使用 HTTPS,避免資料在傳輸過程中被竊取。
  • 可以使用 Let’s Encrypt 等免費工具獲取 SSL 證書,並配置 Nginx 或 Apache 實現 HTTPS。

3. JWT 和 OAuth2

  • 如果需要使用者認證和授權,推薦使用 JWT(JSON Web Token)和 OAuth2 協議來保護 API。前端會在使用者登入後獲取到 JWT,後續的 API 請求會在請求頭中附加該 JWT 進行身份認證。
  • 後端可以透過 Spring Security 配合 OAuth2 或 JWT 進行認證和授權。

六、日誌和監控

1. 日誌管理

  • 前端和後端應用應分別進行日誌管理。前端可以使用 JavaScript 日誌庫記錄客戶端的行為日誌併傳送到後端儲存。
  • 後端可以透過 Logback 或 Log4j 記錄 API 請求日誌、錯誤日誌等,並透過 ELK(Elasticsearch + Logstash + Kibana)等工具對日誌進行集中管理和分析。

2. 監控和報警

  • 使用 Prometheus 和 Grafana 監控後端 Java 服務的健康狀況、響應時間、錯誤率等關鍵指標。
  • 前端可以使用 Google Analytics 或類似的監控工具跟蹤使用者行為、頁面載入時間等資訊。

七、總結

前後端分離應用的部署涉及到前端靜態資源的構建、託管,後端服務的部署和擴充套件,安全性策略的配置,以及日誌監控等方面。以下是關鍵點:

  1. 前端:打包靜態資源並託管到 CDN 或 Nginx 上。
  2. 後端:Java 應用可以容器化部署,使用負載均衡和 API Gateway 最佳化請求管理。
  3. CI/CD 整合:使用自動化構建、測試和部署管道,實現快速迭代和無縫部署。
  4. 安全性:確保使用 HTTPS,加上正確的 CORS 和認證機制。
  5. 監控:監控系統執行狀況,分析日誌,及時報警。

透過遵循這些最佳實踐,可以實現高效、安全且可擴充套件的前後端分離應用的部署。


分割線

貳.示例實戰

以React + Java 為例更加詳細地描述這樣的前後端分離的應用程式如何部署

在 React + Java 組合的前後端分離架構中,前端使用 React 構建,而後端使用 Java(如 Spring Boot)處理業務邏輯和提供 API 介面。前端和後端分別獨立開發和部署,前端與後端透過 HTTP API 通訊。為了詳細說明 React + Java 前後端分離應用的部署流程,接下來會從以下幾個方面來解釋:

  1. 應用結構概述
  2. 後端 Spring Boot 應用的部署
  3. 前端 React 應用的部署
  4. 前後端整合與通訊配置
  5. 生產環境部署細節
  6. 安全性與效能最佳化
  7. 示例:基於 Nginx 的前後端部署配置

一、應用結構概述

React(前端)

  • 使用 React 框架構建單頁應用(SPA),利用 React Router 實現路由和頁面導航。
  • 靜態資源包括 HTML、CSS、JavaScript、影像等,這些資源會被打包並上傳到靜態伺服器或 CDN 上。
  • 與後端透過 RESTful API 或 GraphQL 進行資料互動。使用 Axios、Fetch 等庫傳送 HTTP 請求。

Java(後端)

  • 使用 Spring Boot 框架開發後端服務,提供業務邏輯處理、資料庫操作以及 API 服務。
  • API 介面為前端提供資料訪問介面,通常是 REST API。
  • 負責驗證、授權、安全等功能,並處理來自前端的 API 請求,連線資料庫進行增刪改查操作。

通訊方式:前端的 React 應用傳送 HTTP 請求到後端的 Java API,後端透過 JSON 等格式返回資料給前端。


二、後端 Spring Boot 應用的部署

  1. 打包後端應用

    • 使用 Maven 或 Gradle 構建工具打包 Spring Boot 應用。可以透過以下命令進行打包:
      • Mavenmvn clean package
      • Gradlegradle build
    • 打包完成後會生成一個可執行的 JAR 檔案,例如 app.jar
  2. 部署到伺服器

    • 選擇一個適當的伺服器(如 AWS EC2、DigitalOcean、Google Cloud Compute Engine 等),可以使用 Linux(如 Ubuntu)來進行部署。
    • 上傳打包好的 app.jar 檔案到伺服器,確保已經安裝 Java 執行時環境(如 OpenJDK 或 Zulu JDK)。
  3. 啟動 Spring Boot 應用

    • 在伺服器上透過以下命令啟動應用:
      java -jar app.jar
      
    • 也可以配置 systemd 或者 init.d 服務,以確保 Spring Boot 應用能夠在伺服器重啟時自動啟動。
  4. 配置反向代理(可選)

    • 如果需要透過 Nginx 或 Apache 作為反向代理,可以配置代理伺服器,將外部請求轉發到 Spring Boot 應用。Nginx 示例配置如下:
      server {
          listen 80;
          server_name your-domain.com;
          
          location /api/ {
              proxy_pass http://localhost:8080/;  # Spring Boot 執行在本地 8080 埠
              proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
          }
      }
      
  5. 資料庫配置

    • 確保應用連線的資料庫(如 MySQL、PostgreSQL 等)也已經部署在伺服器或雲資料庫上,並且在 application.propertiesapplication.yml 中正確配置了資料庫連線。

三、前端 React 應用的部署

  1. 打包 React 應用

    • 使用 npmyarn 打包 React 應用:
      npm run build  # or yarn build
      
    • 這會在 build/ 目錄中生成一套靜態資源(HTML、CSS、JavaScript、影像等)。
  2. 上傳到靜態資源伺服器

    • 將打包後的靜態資源上傳到一個伺服器或 CDN,常見的部署選項包括:
      • 傳統伺服器(如 Nginx、Apache):將 build/ 目錄的檔案上傳到伺服器的靜態資源目錄。
      • CDN(如 AWS S3、CloudFront):將靜態資源託管到 CDN 提供的物件儲存服務中。
  3. Nginx 部署示例

    • 將打包後的 React 靜態資源上傳到伺服器的 /var/www/react-app 目錄。
    • 配置 Nginx,將前端的請求指向該目錄:
      server {
          listen 80;
          server_name your-domain.com;
          
          location / {
              root /var/www/react-app;  # React 打包後的檔案目錄
              index index.html;
              try_files $uri /index.html;  # React SPA 路由
          }
      }
      
  4. 透過域名訪問前端應用

    • 確保已經將域名解析指向伺服器的 IP 地址,這樣使用者可以透過 http://your-domain.com 訪問 React 應用。

四、前後端整合與通訊配置

  1. API URL 配置

    • 在前端 React 應用中,透過環境變數或配置檔案指定後端 API 的基礎 URL。例如,在 src/config.js 中配置:
      const API_BASE_URL = process.env.REACT_APP_API_BASE_URL || "http://your-domain.com/api";
      export default API_BASE_URL;
      
    • 在前端呼叫 API 時,可以使用 API_BASE_URL 動態構建請求 URL。
  2. 跨域(CORS)配置

    • 當前端和後端部署在不同的域名或埠下時,瀏覽器會阻止跨域請求。需要在 Spring Boot 中啟用 CORS 配置:
      @Configuration
      public class WebConfig implements WebMvcConfigurer {
          @Override
          public void addCorsMappings(CorsRegistry registry) {
              registry.addMapping("/api/**")
                      .allowedOrigins("http://your-frontend-domain.com")
                      .allowedMethods("GET", "POST", "PUT", "DELETE");
          }
      }
      
  3. 安全認證(可選)

    • 如果需要對 API 請求進行認證,可以使用 JWT(JSON Web Token)在前後端之間傳遞使用者認證資訊。
    • 在後端生成 JWT 並透過 HTTP 響應頭或 Cookie 返回給前端,前端將 JWT 儲存在 localStoragesessionStorage 中,每次請求時透過 HTTP 請求頭髮送 JWT。

五、生產環境部署細節

  1. SSL 配置(HTTPS 支援)

    • 為了安全性,前端和後端的通訊應該透過 HTTPS 進行。可以在 Nginx 上配置 SSL 證書(例如透過 Let's Encrypt 免費獲取證書)。
    • Nginx 配置示例:
      server {
          listen 443 ssl;
          server_name your-domain.com;
          
          ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
          ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
          
          location / {
              root /var/www/react-app;
              index index.html;
              try_files $uri /index.html;
          }
          
          location /api/ {
              proxy_pass http://localhost:8080/;
              proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
          }
      }
      
  2. 負載均衡和高可用性

    • 對於高流量應用,可以使用負載均衡器(如 AWS ELB 或 Nginx 負載均衡)分發流量到多個後端例項,確保高可用性和故障轉移能力。
  3. 日誌和監控

    • 部署後需要對前端和後端應用進行監控。可以在後端使用 Spring Boot Actuator 提供的健康檢查和監控功能,前端可以使用 Google Analytics 等工具監控使用者行為和效能。

六、安全性與效能最佳化

  1. 安全性

    • 對於前端,啟用內容安全策略(CSP),防止跨站指令碼攻擊(XSS)。
    • 對於後端,確保資料庫安全,啟用 HTTPS 加密通訊,並新增認證和授權機制(如 OAuth2、JWT)。
  2. 效能最佳化

    • 前端:啟用程式碼拆分和懶載入,最佳化圖片、壓縮 CSS 和 JavaScript 檔案,並透過 CDN 加速資源載入。
    • 後端:快取常用資料,使用 Redis 等工具減少資料庫查詢頻次,最佳化資料庫索引和查詢。

七、示例:基於 Ngin

x 的前後端部署配置

下面是完整的 Nginx 配置檔案示例,將 React 前端和 Spring Boot 後端部署在同一伺服器上:

server {
    listen 80;
    server_name your-domain.com;
    
    location / {
        root /var/www/react-app;
        index index.html;
        try_files $uri /index.html;  # React 路由
    }
    
    location /api/ {
        proxy_pass http://localhost:8080/;  # 轉發 API 請求到 Spring Boot 應用
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

透過這種配置,/ 路徑下的請求會交給 React 前端,/api/ 路徑下的請求會轉發到 Spring Boot 後端。


在 React + Java 的前後端分離架構下,前端和後端可以獨立開發和部署,前端負責介面和互動邏輯,後端負責業務邏輯和資料處理。透過打包前後端應用、使用 Nginx 進行靜態資源託管和 API 轉發、配置 SSL 和跨域訪問,能夠實現安全、靈活和高效的部署。

相關文章