前後端分離架構下,前端調用後端的方式有以下兩種:
Ip+端口
通過ip+端口的方式需要暴露後端服務,因爲請求都是從瀏覽器發出的,需要讓任意一個從瀏覽器發出的請求都可以訪問。
採用ip+端口方式的弊端:
- 需要將後端服務的ip加入dns,以免換了ip之後服務不可用
- 如果不分配域名的話,需要向外暴露ip,安全風險較高
- 可能被惡意訪問造成服務崩潰,當然如果是內網的服務,一般隔了好幾層防火牆,這個有點杞人憂天,網絡安全先不考慮了,這個不太擅長。
反向代理
- 雲平臺中微服務的特點:
- 後端作爲雲平臺的微服務,不需要面向用戶暴露微服務,只需要在集羣內部暴露,因此後端微服務只要集羣內可達即可。
- 微服務的IP隨時可能發生變化,而運維人員不知道。以k8s爲例,微服務都部署在pod中,如果一個pod掛了,就會立刻重啓另一個,這時ip可能發生改變,如果前端在調用後端的時候採用ip+端口的方式,就會404
基於上述考慮,反向代理是一個比較好的方式,下面詳細描述如何實現,其實主要是要搞清楚端口,請各位看官看到端口的時候注意對應。
- 前端請求只寫相對路徑,因爲最後都會被nginx轉發到後端服務器,爲了將頁面顯示和調用後端分開,調用後端的統一以apis開始,這樣nginx纔會將以/apis開頭的請求轉發到後端。
export function asyncGetAllDeps() {
return function(dispatch){//dispatch
// API
return fetch(commonUrl + '/apis/getAllDeps',{
method: 'get',
headers: {
'Access-Control-Allow-Origin': 'assessment.frontend'
}
}).then(function(res){
return res.json();
}).then(function(data){
if(data !== undefined || data !== []){
data.forEach((item)=> {
item.key = item.DEPID;
});
dispatch(setallDepList(data));
}
}).catch((error) => {
console.log(error);
});
};
}
- 上述前端代碼應該部署到nginx中,需要拉取nginx鏡像,dockerfile如下
這裏需要注意聲明瞭容器應該打開的端口是80
FROM nginx:1.17.10
COPY build/ /usr/share/nginx/html/
EXPOSE 80
- 部署前端的yaml文件,這裏容器的端口需要指定爲80,與上述在dockerfile寫的端口號應該是一致的。
spec:
containers:
- image: 前端打包成的鏡像的地址
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: 80
timeoutSeconds: 1
name: frontend
ports:
- containerPort: 80
protocol: TCP
- 配置nginx的反向代理
主要實現反向代理的配置代碼如下所示:
location ^~/apis { # 自定義nginx接口前綴
rewrite ^/apis/(.*)$ /$1 break; # 監聽所有/apis前綴,是則轉發後臺api接口地址
include uwsgi_params;
proxy_pass http://backend:8080; # 後臺api接口地址 這個修改
}
location指令匹配以/apis開頭的請求,如果匹配成功的話,使用rewrite指令重寫路徑,去掉前綴/apis,這樣就不需要後端修改接口地址。前端在請求的時候,加上前綴/apis,nginx在匹配到是需要轉發到後端的請求之後,再去掉前綴/apis。完美。
使用proxy_pass實現反向代理,將請求轉發到http://backend:8080。這裏!!!注意了!!!backend是後端的服務名(k8s是用服務名:端口訪問的,其他不清楚),8080是後端服務暴露的端口。
這裏!!!因爲在部署的時候,拉取鏡像的時候對外暴露的端口都是80,因此http的server監聽的端口應該是80!!
server {
listen 80;
}
完整版的nginx配置如下,請叫我雷鋒。
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 80;# default_server;
server_name assessment.frontend.com;
root /usr/share/nginx/html;
location ^~/apis { # 自定義nginx接口前綴
rewrite ^/apis/(.*)$ /$1 break; # 監聽所有/apis前綴,是則轉發後臺api接口地址
include uwsgi_params;
proxy_pass http://backend:8080; # 後臺api接口地址 這個修改
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
- 部署後端微服務
這裏需要將8080端口對外暴露,因爲我們在nginx中配置的可是訪問8080呀!!
spec:
containers:
- image: 後端微服務的鏡像地址
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: 8080
timeoutSeconds: 1
name: backend
ports:
- containerPort: 8080
protocol: TCP
至此,雲平臺中微服務的前後端調用已經完成了,是不是非常優秀,請各位看官做我的粉絲。