前後端分離那些事

jaycaoln發表於2019-04-04

前後端分離那些事

問題:我們打包的dist資料夾和Index.html後,需要後端怎麼配合,我們才能線上上域名成功訪問?

一、將dist包和後端程式碼丟在一起。如tomcat。

前後端分離那些事

我們將dist包和後端的jar包放在一起,由後端部署到對應的伺服器。

開發環境

前後端分離那些事
在webpack的dev-server中代理髮送介面

 proxyTable: {
  '/api/': {
    target: 'http://10.180.221.199:8090/api',
    changeOrigin: true,
  }
}
複製程式碼
 Network.get('/api/user/login').then((res) => {});
複製程式碼

相當於請求 http://10.180.221.199:8090/api

後端

if (indexof(api) !== -1) {
    to class;
} else {
    return index.html
};
複製程式碼

測試生產環境

我們的前後端程式碼部署在一個伺服器上面,就是直接請求https://test-project.pingan.com這樣的了。

普通的,tomcat將index和dist放在src下面,後端配置路由,進行返回。後端配置路由主要有兩種:

1.api(前後端約定好的字元)作為字首,當判斷到前端的請求是api開頭,則表示用於介面的請求,後端跳轉到對應的class做各種邏輯處理。

2.除了api外,所有的請求,我們在前端router中設定的路由(/、/home、/login等)我們只需要後端返回index.html,index.html會根據需要去引入對應的js css檔案等,之後我們在頁面路由的點選的頁面跳轉,自然走的是前端配置的router。

二、前後端完全分離,我們將dist放在node或者nginx啟動一個伺服器上.

前後端分離那些事
前端和後端擁有兩個不同的伺服器,我們將node程式碼和dist包放在前端部署的伺服器上,由node啟動一個服務,由node給我們傳送介面和返回返回index.html頁面。後端伺服器是用來給我們提供介面訪問的。

前後端分離那些事
類似於上面的,我們可以會在Node上設定一個通用的api字首作為介面,可以在node通過http傳送介面請求,也可以直接用一個代理轉發介面請求。其他非api的我們可以返回Index頁面即可。

NetWork:

import axios from 'axios';
const env = {
  development: 'http://0.0.0.0:37111', // 本地開發環境
  test: '', // 測試環境
  production: '', // 生產環境
};
const instance = axios.create({
  baseURL: env[process.env.NODE_ENV],
  timeout: 10000,
});
...
複製程式碼
 Network.get('/api/user/login').then((res) => {});
複製程式碼

node

...
const renderIndex = (pageName) => {
  return async (ctx) => {
    await ctx.render(`./dist/${pageName}.html`);
  };
};
router
  .get('/', renderIndex('index'))
  .get('/home', renderIndex('index'))
  .get('/login', renderIndex('index')); // 如果不是api就返回index頁面

router.use('/api', checkLogin, apiRouter.routes()); //api就進行介面的請求
...
複製程式碼

比較

兩者的優缺點顯而易見,用tomcat如果有新的dist包,每次都需要後端進行專案的重啟,加大了合作成本。所以前後端完全分離的方式是更理想的,可以做到互不影響,自然效率更高。

  • 前後端完全分離,相互獨立,減少合作成本
  • 可以在Node上,配置錯誤日誌,修改後端介面返回的資料格式,catch error,請求引數校驗等

簡言之,其實node和nginx最簡單的一個目的就是為了將index.html返回。node可以做的事情,nginx也可以做。

nginx進行配置

申請了一個雲伺服器,CentOS7,我們用root使用者進行登入(當然,也可以下載一個secureFX視覺化操作。)

ssh root@12.34.12.43
yum list | grep nginx // 檢視yum源
vim /etc/yum.repos.d/nginx.repo // 修改源配置檔案
複製程式碼

官網上提供了安裝nginx的方法

sudo yum install yum-utils
複製程式碼
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
複製程式碼
sudo yum install nginx
複製程式碼

利用nginx -v測試是否安裝成功。切換到nginx資料夾下面

cd /etc/nginx
cd /usr/share/nginx/html
複製程式碼

有兩個我們必須知道的檔案conf.d(資料夾,裡面配置各種虛擬主機)和nginx.conf(nginx的基本配置 )

nginx.conf 檔案是Nginx總配置檔案,在我們搭建伺服器時經常調整的檔案。

#執行使用者,預設即是nginx,可以不進行設定
user  nginx;
#Nginx程式,一般設定為和CPU核數一樣
worker_processes  1;   
#錯誤日誌存放目錄
error_log  /var/log/nginx/error.log warn;
#程式pid存放位置
pid        /var/run/nginx.pid;
events {
    worker_connections  1024; # 單個後臺程式的最大併發數
}
http {
    include       /etc/nginx/mime.types;   #副檔名與型別對映表
    default_type  application/octet-stream;  #預設檔案型別
    #設定日誌模式
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;   #nginx訪問日誌存放位置
    sendfile        on;   #開啟高效傳輸模式
    #tcp_nopush     on;    #減少網路報文段的數量
    keepalive_timeout  65;  #保持連線的時間,也叫超時時間
    #gzip  on;  #開啟gzip壓縮
    include /etc/nginx/conf.d/*.conf; #包含的子配置項位置和檔案
複製程式碼

進入conf.d目錄,然後使用vim default.conf進行檢視。

server {
    listen       80;   #配置監聽埠
    server_name  localhost;  //配置域名
    #charset koi8-r;     
    #access_log  /var/log/nginx/host.access.log  main;
    location / {
        root   /usr/share/nginx/html;     #服務預設啟動目錄
        index  index.html index.htm;    #預設訪問檔案
    }
    #error_page  404              /404.html;   # 配置404頁面
    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;   #錯誤狀態碼的顯示頁面,配置後需要重啟
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}
    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

複製程式碼

一些實用的命令組合

nginx // 啟動nginx
systemctl start nginx.service
ps aux | grep nginx // 檢視nginx啟動情況
nginx -s stop // 停止nginx
nginx -s quit
killall
systemctl stop nginx.service
nginx -s reload // 重新載入配置檔案
netstat -tlnp // 檢視埠占用情況
複製程式碼

配置errorpage

error_page  404 http://www.baidu.com;
複製程式碼

簡單配置禁止訪問

location / {
    deny   32.21.22.123;
    allow  10.25.32.112;
}
複製程式碼

注意有個坑,現在是所有的都不能訪問

location / {
    deny   all;
    allow  45.76.202.231;
}
複製程式碼

要學會使用正則進行配置,例如以php結尾的就不能訪問了。

location ~\.php$ {
    deny all;
}
複製程式碼

虛擬主機

虛擬主機是一臺物理主機伺服器劃分的多個磁碟空間,可以理解就是一臺獨立的伺服器。

我們配置一個新的port虛擬主機

server{
        listen 8001;
        server_name localhost;
        root /usr/share/nginx/html/html8001;
        index index.html;
}
複製程式碼

這裡的server_name可以配置成ip和域名等。

反向代理

理解一下正向代理,vpn就是一個例子,我們想訪問國外某網站,需要通過代理伺服器去請求。

前後端分離那些事
方向代理

反向代理其實就是真實伺服器不能直接被外部網路訪問到,需要一臺代理伺服器,代理伺服器和真實伺服器是在一個網路中的,

反向代理跟代理正好相反(需要說明的是,現在基本所有的大型網站的頁面都是用了反向代理),客戶端傳送的請求,想要訪問server伺服器上的內容。傳送的內容被髮送到代理伺服器上,這個代理伺服器再把請求傳送到自己設定好的內部伺服器上,而使用者真實想獲得的內容就在這些設定好的伺服器上

前後端分離那些事

反向代理的用途和好處

安全性:正向代理的客戶端能夠在隱藏自身資訊的同時訪問任意網站,這個給網路安全代理了極大的威脅。因此,我們必須把伺服器保護起來,使用反向代理客戶端使用者只能通過外來網來訪問代理伺服器,並且使用者並不知道自己訪問的真實伺服器是那一臺,可以很好的提供安全保護。

功能性:反向代理的主要用途是為多個伺服器提供負債均衡、快取等功能。負載均衡就是一個網站的內容被部署在若干伺服器上,可以把這些機子看成一個叢集,那Nginx可以將接收到的客戶端請求“均勻地”分配到這個叢集中所有的伺服器上,從而實現伺服器壓力的平均分配,也叫負載均衡。

我們需要通過訪問a.com,反向代理到b.com,等同於訪問a.com其實是訪問到了b.com

server{
        listen 8001;
        server_name a.com;
        location / {
               proxy_pass http://b.com;
        }
}
複製程式碼

pc和移動端的適配 $http_user_agent

server{
     listen 80;
     server_name nginx2.jspang.com;
     location / {
      root /usr/share/nginx/pc;
      if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
         root /usr/share/nginx/mobile;
      }
      index index.html;
     }
}
複製程式碼

負載均衡

負載均衡:就是分攤到多個操作單元上執行。如果某個伺服器down了,就會自動從伺服器中移除

upstream test {
  server localhost:8080;
  server localhost:8081;
}
server {
  listen       81;                                                         
  server_name  localhost;                                               
  client_max_body_size 1024M;

  location / {
    proxy_pass http://test;
    proxy_set_header Host $host:$server_port;
  }
}
複製程式碼

權重

適用於伺服器效能不同的伺服器

upstream test {
    server localhost:8080 weight=9;
    server localhost:8081 weight=1;
}
複製程式碼

ip_hash

存在一個問題,比如說我們Login的session,如果訪問了一個機器,但是連線另外一個機器是沒有的,那就要重新登入了,可以用id_hash保持一直連線一個機器

upstream test {
  ip_hash;
  server localhost:8080;
  server localhost:8081;
}
複製程式碼

fair(第三方)

按後端伺服器的響應時間來分配請求,響應時間短的優先分配。

upstream backend { 
  fair; 
  server localhost:8080;
  server localhost:8081;
}
複製程式碼

url_hash(第三方)

按訪問url的hash結果來分配請求,使每個url定向到同一個後端伺服器,後端伺服器為快取時比較有效。 在upstream中加入hash語句,server語句中不能寫入weight等其他的引數,hash_method是使用的hash演算法

upstream backend { 
  hash $request_uri; 
  hash_method crc32; 
  server localhost:8080;
  server localhost:8081;
}
複製程式碼

gzip壓縮

gzip有一個原理,瀏覽器先告訴伺服器是否支援gzip,如果支援,伺服器就是以gzip進行壓縮。一般可以壓縮至原來的30%

http {
   .....
    gzip on;
    gzip_types text/plain application/javascript text/css;
   .....
}
複製程式碼

相關文章