前端運維部署那些事

聊到運維,很長一段時間我以爲跟前端就是毫無關聯的玩意,應該說半毛錢關係都木。但隨着前端工程化的發展,前端基本運維部署相關知識甚至也逐步被重視,若是你公司的運維部門很強大,那麼你也能夠徹底忽略運維相關的。只是樹醬以爲,若是你想更多瞭解前端架構,仍是須要具有必定的運維相關知識儲備。固然,如今雲廠商都想應推出本身的Serverless服務(下一篇會講~),號稱讓前端更專一業務的開發,而不用擔憂底層應用的部署和維護,對開發者而言能夠更多聚焦到業務領域的開發,有興趣的童鞋能夠去玩玩html

1.npm

npm 是 Node.js 官方提供的包管理工具,主要用來管理項目依賴,發佈等等,下面介紹幾個比較常見的部署應用場景,經常使用的npm命令這裏不做介紹了前端

1.1 nrm

nrm(npm registry manager )是npm的鏡像源管理工具,由於npm默認創建的連接訪問的是國外的資源,訪問速度較慢,使用這個就能夠快速地在 npm 源間切java

  • 如何安裝
npm install -g nrm 
複製代碼
  • 查看可選的資源
nrm ls   

*npm ---- https://registry.npmjs.org/

cnpm --- http://r.cnpmjs.org/

taobao - http://registry.npm.taobao.org/

eu ----- http://registry.npmjs.eu/
...
複製代碼
  • 添加私有倉庫連接
nrm add name http://registry.npm.tree.com/  # 私有倉庫連接
nrm use name # 使用本址的鏡像地址 
複製代碼

nrm 更多用於若是公司內網部署了私有倉庫,也就是方便用nrm做來源切換,也有益於依賴的版本管理,若是你想搭建本身的私有倉庫,可使用verdaccio,能夠看這個具體的教程 點我👇node

1.2 發佈npm包

當咱們想發佈一個npm包,須要完成什麼樣的流程呢?webpack

  • 先註冊npm帳號 🔗
  • 配置package.json
{
  "name": "kutil",
  "version": "1.0.0", #版本名稱
  "scripts":[], # 可執行的腳本命令
  "repository": "https://github.com/xxx/xxx.git", #github倉庫地址
  "author": "tree <shuxin_liu@kingdee.com>", #做者
  "description": "工具包「, #包的說明 "keywords": [ "utils", ] } 複製代碼
  • 配置打包機制

若是是工具類打包,推薦使用rollup,webpack比較適合打包一些應用,例如SPA或者同構項目nginx

  • 添加單元測試

優質的開源包,都有單元測試模塊,來保證包的穩定性和代碼質量,常見會有build-passing的標記,有興趣的童鞋能夠閱讀樹醬以前寫的前端單元測試那些事git

  • 開發文檔readme.me

readme方便開發者快速熟悉,包括具體的Api介紹、使用例子、項目介紹等等,還能夠加入包括單元測試覆蓋率、下載量、證書等等github

最後完成上面一系列操做以後,到了最終的發佈環節web

npm login # 登陸你上面註冊的npm帳號

npm publish # 登陸成功後,執行發佈命令

+ kutil@1.0.0 # 發佈成功顯示npm報名及包的版本號
複製代碼

2. jenkins

jenkins做爲一個可擴展的自動化服務器,能夠用做簡單的 CI 服務器,具備自動化構建、測試和部署等功能,簡而言之,jenkins能夠方便咱們平常的前端項目版本更新迭代(開發、測試、生產環境等),也能夠經過它自動化完成一系列的操做包括:編譯打包元測試、代碼掃描等,官方文檔docker

2.1 如何安裝

  • 下載 Jenkins.

  • 打開終端進入到下載目錄.

  • 運行命令 java -jar jenkins.war --httpPort=8080.

  • 打開瀏覽器進入連接 http://localhost:8080.

  • 按照說明完成安裝.

詳細流程圖可參考 Jenkins+github 前端自動化部署

2.2 配合前端項目自動化部署

這裏主要介紹jenkins流水線配置的使用,流水線的代碼定義了整個的構建過程, 他一般包括構建, 測試和交付應用程序的階段,下面是路徑和倉庫的配置

圖片相關配置以下:

  • SCM:選擇git或者svn做爲代碼觸發器
  • 腳本路徑:在項目根目錄建立jenkinsfile來編寫流水線

下面介紹一個簡單版的jenkinsfile的流水線任務寫法,完成整個前端工程化部署涉及的編譯打包、靜態掃描、單元測試等環節

def gitUrl = "http://gitlab.****.com/shc/****.git"//GIT入口(隨不一樣工程改變)
def gitCred = "***-***-4f00-a926-1848b670d97b"    //GIT 身份憑據
if ("DEV" == buildType) {
    buildScript = "build_development"
    try {
        node('k8s') {
            stage('下拉源碼') {
                   checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${gitCred}", url: "${gitUrl}"]]])
                 #可由片斷生成器生成,選擇示例步驟 「checkout:Check out from version control」,生成流水線腳本獲取
            }
            checkStatus('下拉源碼')
            stage('代碼構建編譯') {
                sh "yarn run ${buildScript}"
            }
            checkStatus('代碼構建編譯')
            stage('代碼靜態掃描') {
                sh 'yarn run lint'
            }
            checkStatus('代碼靜態掃描')
            stage('單元測試') {
                 sh 'yarn run unit'
            }
            checkStatus('單元測試')
        }
    } catch(Exception e) {
       
    }
} 
複製代碼

完成後,便可構建項目,分階段完成,首先是下拉源碼、代碼構建編譯、代碼掃描等等,全部環節成功纔算自動化部署成功,以下所示

3.Docker

Docker是一個虛擬環境容器,能夠將開發環境、代碼、配置文件等一併打包到這個容器中,最後發佈應用

3.1 如何使用

經過將部署的操做集中成一個部署腳本完成傳統的部署流程,經過在服務器上運行docker容器來運行前端應用

如何安裝

yum install docker-ce
複製代碼

項目目錄,部署項目須要準備Dockerfile和nginx.conf(若是nginx不做定製化,能夠直接用官方鏡像)

3.2 Dockerfile 配置

dockerfile是一個配置文件,用來讓docker build命令清楚運行那些操做,建立dockerfile並編寫相關配置

FROM node:latest as builder 
WORKDIR /app
COPY package.json 
RUN npm install   
COPY . .
RUN npm run build


FROM nginx:latest
COPY nginx.conf /etc/nginx
COPY --from=builder /app/dist  /usr/share/nginx/html

//ps: 每個指令的前綴都必須是大寫的。

複製代碼
  • ADD和COPY: 將文件或目錄複製到Dockerfile構建的鏡像中
  • EXPOSE: 指定運行該鏡像的容器使用的端口,能夠是多個。
  • RUN : 指令告訴docker 在鏡像內執行命令
  • FROM :經過FROM指定的鏡像名稱,這個鏡像稱之爲基礎鏡像,必須位於第一條非註釋指令
  • WORKDIR: 在容器內部設置工做目錄

Nginx.conf 配置以下

events {
    worker_connections  1024;
}
http{
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }   
    }
}
複製代碼

建立文件並編寫後,用docker建立鏡像

3.3 如何建立鏡像

使用當前目錄的 Dockerfile 建立鏡像,標籤爲 frontend

docker build -t frontend .
複製代碼
  • -t :指定要建立的目標鏡像
  • . :Dockerfile 文件所在目錄,能夠指定Dockerfile 的絕對路徑

鏡像成功生成

3.4 查看鏡像

docker image ls | grep frontend
複製代碼

出現結果則應用鏡像 frontend 成功建立,而後咱們基於該鏡像啓動一個Docker容器

4.5 如何啓動

使用docker鏡像frontend:latest以指定80端口映射模式啓動容器,並將容器命名爲frontend

docker run --name frontend -p 80:80 frontend:latest
複製代碼
  • -p: 指定端口映射,格式爲:主機(宿主)端口:容器端口 將宿主的80端口映射到容器的80端口
  • -name: 爲容器指定一個名稱;

完成 docker 部署

docker也能夠集成到上一節講的jenkins自動化部署流水線中去

stage('部署到開發聯調環境') {
                echo "auto deploy to test environment"
                sh "docker build -t frontend ."
                sh "docker run --name frontend -p 80:80 frontend:latest"
  }
複製代碼

4.PM2

PM2是node進程管理工具,能夠利用它來簡化不少node應用管中繁瑣任務,是Nodejs應用程序守護進程必不可少的選擇,方便管理基於nodejs平臺下可以有獨立運行訪問的web服務,如nextjs、express、koa等前端應用

4.1 常見的應用場景

  • 部署node koa2 或 express 項目應用
  • 部署 前端SSR(後端渲染)應用,如nuxt.js(Vue)和 next.js(React)等構建服務端渲染應用框架

4.2 如何使用

  • 安裝 :npm install -g pm2
  • 啓動node項目 : pm2 start app.js 或者 pm2 start bin/www
  • 中止pm2服務:pm2 stop bin/www
  • 中止全部pm2服務: stop all
  • 重啓pm2服務: pm2 restart bin/www
  • pm2全部進程信息:pm2 list

啓動後以下所示

4.3 高階應用

在項目根目錄中添加一個processes.json

{
 #apps是一個數組,每個數組成員就是對應一個pm2中運行的應用
  "apps": [{
    "name": "app",  #名稱
    "script": "./", #程序入口
    "cwd": "./",           #應用程序所在的目錄
    "error_file": "./logs/err.log",#錯誤輸出日誌
    "log_date_format": "YYYY-MM-DD HH:mm Z" #日期格式
  }]
}
複製代碼

結合packjson腳本命令,能夠用processes來管理多應用

"script":{
    "pm2":"pm2 start processes.json"
}
複製代碼

更多命令和配置信息查看 pm2文檔

5.Nginx

Nginx它既能夠做爲 Web 服務器,也能夠做爲負載均衡服務器,具有高性能、高併發鏈接等

5.1 前端Nginx那些事

詳細信息請看以前梳理的前端Nginx那些事

5.2 補充

  • 灰度發佈

灰度發佈便是讓一部分人繼續用舊版本的產品A,而後一部分用戶開始用新版本特徵的產品B,若是用戶對B沒有什麼問題反饋,則逐步擴大範圍。一方面能夠保證總體系統的穩定,並且在初始灰度的時候就能夠發現、調整問題,以保證其影響度

傳統的灰度是經過Nginx分發流量到服務器,這裏介紹一下簡單的灰度規則配置,經過在nginx裏面配置路由規則就好,若是是規則複雜的話,能夠結合nginx+lua 作一些些灰度的業務邏輯

1.根據Cookie實現灰度發佈

經過獲取cookie設置的版本號來區分

upstream test1 {
    server 192.168.0.1:8080 max_fails=1 fail_timeout=60;
}

upstream default {
    server 192.168.0.0:8080 max_fails=1 fail_timeout=60;
}

server {
  listen 80;
  server_name  www.****.com;
  set $group "default";
    if ($http_cookie ~* "version=V1"){
        set $group test1;
    }

  location / {                       
    proxy_pass http://$group;
    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    index  index.html index.htm;
  }
 }
複製代碼
  1. 根據IP實現灰度發佈

經過內外網IP來區分

upstream test1 {
    server 192.168.0.1:8080 max_fails=1 fail_timeout=60;
}

upstream default {
    server 192.168.0.0:8080 max_fails=1 fail_timeout=60;
}

server {
  listen 80;
  server_name  www.xxx.com;
  set $group default;
  if ($remote_addr ~ "10.0.0.110") {
      set $group test1;
  }

location / {                       
    proxy_pass http://$group;
    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    index  index.html index.htm;
  }
}
複製代碼

相關文章
相關標籤/搜索