Nginx实现前后端分离(springboot+vue)+双机互备

背景介绍

项目采用springboot+vue开发,之 前项目布署时,都是采用pom中配置,把vue打包的dist文件copy到springboot项目中resource/static下做的,这样每次发版本只需要启动jar,前后端放一起实现的。但缺点是:每次发版本时Maven打包比较慢,因为还需要copy前端代码到后台,有时需要打两次包。另外,线上单节点,每次发版本升级时,只能停机发版本,用户体验也不好。所以这次想着加个nginx,前后端分离布置 ,也好加两上节点,用nginx做反向代理。

nginx布署安装

这部分相比较简单,之前文件章也有描述,Linux的安装过程请参看之前博客内容:https://blog.csdn.net/xuxiannian/article/details/95967766
windows安使用,只需去Nginx官网下载包,解压即可使用。

Nginx代理结构

项目登陆认证是集成公司4A,和相关同学确认,4A可以返回多个回跳地址,至于多结点session一致性的问题,想了一下,简单做吧,不需要session共享去维护,所以采用ip_hash策略即可,即每个IP的请求都打在一台服务器上。给大家提个醒,如果想做负载均横,内网访问的话需要看一下,记着之前在哪看到过,Nginx是拿IP前三段做的Hash,如果是内网前三段相同,则起不到负载均衡作用,所有请求都会打到同一台服务器上;我这边主要诉求是保持服务高可用,所以请求负载均衡考虑在其次。如果有高诉求负载均衡的,配置权重,考虑session一致,用户session信息可存到redis或存到DB中去维护,请自行百度吧。
需求明确了,总结下:Nginx主要就是前后端分离,两个后端服务节点保证一个简单高可用,即一个前端两后端,同一IP请求落在一个服务器点上

Nginx实现前后端分离(springboot+vue)+双机互备_第1张图片

nginx反向代理

反向代理的理解:和正向代理相比去理解,买保险找代理人,我们是客户,代理人是代理客户去找相应的产品;而反向代理的含义是代理人代理产品找客户;nginx的反向代理是指,对于用户来说,我不关心我要去哪台服务器发请求,不需要知道目的地在哪,我只要把请求发给有反向代理之称的Nginx即可,他来帮我实现请求落在哪台服务器上。
简单总结即:正向代理代理的是客户端,反向代理代理的是服务器

实操

nginx官网配置

VUE打包发版的配置

.evn.production配置路由访问的BaseUrl:VUE_APP_URL ,实际我们在正常访问时是没有/api的,这个是为了配置Nginx中的对应,虚配了一个URI,在Nginx的配置文件中可以把它rewrite掉。域名/IP端口对应Nginx的server中的端口和域名,接着看吧。。。

// 生产环境标记 package.json用
VUE_APP_MODE = 'production'
NODE_ENV = 'production '
// 配置代理;对应Nginx中的server的域名/IP配置
VUE_APP_URL = 'http://192.168.1.1:8000/api'

npm run build后,前端代码打包到dist文件中
Nginx实现前后端分离(springboot+vue)+双机互备_第2张图片

dist拷贝至Nginx中

直接把dist扔到Nginx的html中即可
Nginx实现前后端分离(springboot+vue)+双机互备_第3张图片

Nginx配置

worker_processes  1; #工作进程:数目。根据硬件调整,通常等于CPU数量或者2倍于CPU

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;    # 错误日志:存放路径。

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    #gzip  on;
     upstream positioning{
     ip_hash;
     server 192.168.1.1:8080;
     server 192.168.1.2:8080; 
     
  
    }
    server {
        listen       8000;  #vue端口号是多少就配置多少
        server_name  192.168.1.1; #vue端口号是多少就配置多少
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        
       #这是配置前端项目地址
        location / {
            root   html/dist; #配置首页地址,root为根目录,指向VUE静态文件的dist目录
            index  index.html index.htm;
            try_files $uri $uri/ @router;
            }
            
        #这里是配置负载均衡
        location ^~/api {
            rewrite ^/api/(.*) /$1 break;   #注意:这里需要重写/api为空因为这个/api是我们在前端项目写的标识,手动添加上去的
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $remote_addr;
            # 前端调用接口时有/api的url都会转发到后端(positioning为上面upstream关键字后面的名字)
            proxy_pass http://positioning;  #配置反向代理,跳到后台地址upstream positioning
            proxy_connect_timeout 600;
            proxy_read_timeout 600;
            proxy_send_timeout 600;
            proxy_buffer_size 64k;
            proxy_buffers   4 32k;
            proxy_busy_buffers_size 64k;
            proxy_temp_file_write_size 64k;
        }

    }

}

以上配置主要注意点:
upstream

upstream positioning:这个是用来配置服务器节点的,positioning名字是自定义的,只要保障在后面 proxy_pass中配置一致即可。
upstream支持4种分配方式:

 - 轮询(default):每个请求按时间顺序逐一分配到不同服务器上,如果后端down机自动剔除
 - weight:可配置权重,代理轮询几率,eg:例如:
upstream bakend {
server 192.168.1.1 weight=10;
server 192.168.1.2 weight=10;
}
 - ip_hash:每个请求按IP的Hash结果分配,保证每个访客可以访问到固定一个客户端,可以解决session一致性的问题,本例中就是采用此种策略
 - url_hash:按访问的Url的hash结果来分配,使每个URL定向到后端的同一个服务器上,使用场景可自行脑补:比如说接口服务器的访问,或者缓存服务器。此种Hash策略的就不能加weigh。hash_method是指使用的hash算法
upstream backend {
server 192.168.1.1:8080;
server 192.168.1.2 :8080;
hash $request_uri;
hash_method crc32;
}
 - fair:按后端服务器的响应时间来分配,响应时间短的优先分配 

sever
以下内容有参考https://www.cnblogs.com/jpfss/p/10232980.html

配置Nginx服务器节点信息
 (1) listen端口是指当客户访问请求带着的端口,即Nginx的监听端口
(2)server_name 配置访问哉域名
(3)  location :语法规则location [=|~|~*|^~] /uri/ { … }
请求中URI规则解析,可以有多个,可以指定前端访问页面的地址;可以指定相应的URI跳到后台哪段相应的服务结点上;本例中通过 location ^~/api 指定请求转发到后端,api在VUE中配置相应,通过rewrite重写把api清空(rewrite ^/api/(.*) /$1 break;)即实际用户请求并不需要加api,这个只是为了在nginx做后端相应跳转的标识。其规则详解如下:
参数 说明
= 表示精确匹配
^~ 表示uri以某个常规字符串开头,普通字符匹配
~ 表示区分大小写的正则匹配
~* 表示不区分大小写的正则匹配
!~ 区分大小写不匹配
!~* 不区分大小写不匹配
/ 通用匹配,任何请求都会匹配到
@ 配置文件中的内部定向
location后没有参数直接跟着URI,表示前缀匹配,代表跟请求中的URI从头开始匹配
location的匹配顺序:= > ^~ > ~ = ~* >最长前缀匹配 > /
eg: 以下是示例,帮助大家理解下server的location

server {  
listen       80;  
server_name  localhost;  

location / {  
    root   e:wwwroot;  
    index  index.html;  
}  

# 所有静态请求都由nginx处理,存放目录为html  
location ~ .(gif|jpg|jpeg|png|bmp|swf|css|js)$ {  
    root    e:wwwroot;  
}  

# 所有动态请求都转发给tomcat处理  
location ~ .(jsp|do)$ {  
    proxy_pass  http://test;  
}  

error_page   500 502 503 504  /50x.html;  
location = /50x.html {  
    root   e:wwwroot;  
}  
}  
(4) ReWrite 语法 
last – 基本上都用这个Flag。
break – 中止Rewirte,不在继续匹配
redirect – 返回临时重定向的HTTP状态302
permanent – 返回永久重定向的HTTP状态301

Nginx常用命令

  1. 启动:nginx.exe 或 start nginx.exe;Windows下推荐用后者,因为命令窗口执行1后无法执行其他操作了 | linux: nginx
  2. 停止:nginx.exe -s stop | linux: nginx -s stop
  3. 重载:nginx.exe -s reload |linux: nginx -s reload
  4. 验证:nginx -t

总结

Nginx 的使用主要在配置上,其中做负载均衡用的结点是:upstream。location中的配置也是关键;本例中重点总结一下:
前后端分离:
(1)vue打包时的URL指定Nginx的监听IP与端口;
(2)虚出一段URI,本例中的/api,在没架Nginx时,是没有这个/api的,配置它的主要目的就是为了在Nginx的配置文件中虚出一个location匹配路径与此对应,然后通过proxy_pass可以定向到后台服务的请求路径中
(3)配置rewrite,把这个虚出来的/api 进行地址重写,去掉它即可正常定向
负载均衡:
(1)配置upstream,后面的名字自定义
(2)location结点中配置proxy_pass ,域名中的URI与上面1中自定义的名字对应即可

在这里插入图片描述

补充内容

上线前期,做了调整,目前是未做前后端分离,Nginx做代理两个服务节点。由于我们登陆认证是走的公司统一的4A (认证Authentication、授权Authorization、账号Account、审计Audit统一安全管理平台解决方案)认证:在应用中可以配置4A认证地址所有请求进来都会被拦截,看是否登陆过,如果没有登录,就会跳转到4A进行统一登陆认证(OAuth2.0协议),认证通过后,在4A端可以配置回跳地址,回跳到应用中来。配置流程改为下图所示:

并且遇到了一个问题,4A跳转回来后再次请求时,端口丢了。网上查了下,大家建议改成如下配置

# the 90 port
server {
listen 90;
server_name zxy1994.cn;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host:$server_port; #这里是重点,这样配置才不会丢失端口
location / {
proxy_pass http://127.0.0.1:9001;
}
location = /50x.html {
root html;
}
}

proxy_set_header Host h o s t : host: host:server_port; 这一行是关键。

Nginx日志切割

网上找了相关资料,有两种方法做Nginx日志切割:
(1)一种可以改配置文件,另一种自己写切割脚本切割,
(2)然后配置Linux的crontab,通过定时任务调用方式来做切割。
本文推荐第一种方式,因为后一种方式会对进程重新加载或kill进程,总之就是会新启用一个进程,影响服务使用。

配置文件方式

log_format access-upstream '$time_iso8601|$request|$remote_addr|$upstream_response_time|$http_user_agent|$http_x_forwarded_for';
    map $time_iso8601 $logdate {
    '~^(?\d{4}-\d{2}-\d{2})' $ymd;
    default                       'date-not-found';
}
access_log logs/access-$logdate.log ;

Nginx实现前后端分离(springboot+vue)+双机互备_第4张图片

配置完成后,可以对配置文件进行校验并重新启动即可了

#验证文件配置
nginx -t
#重新加载配置
nginx -s reload

重新加载后生效了
在这里插入图片描述

脚本定时执行方式

编写脚本如下

(1)脚本内容如下所示

#!/bin/bash
date=$(date +%F -d -1day)
cd  /usr/local/nginx/logs
if [ ! -d bak ] ; then
        mkdir -p bak
fi
mv access.log bak/access_$date.log 
mv error.log bak/error_$date.log        
# /usr/bin/nginx -s reload       
kill -s SIGUSR1 $(cat /usr/local/nginx/logs/nginx.pid)
tar -jcvf bak/$date.tar.gz bak/access_$date.log bak/error_$date.log
find /usr/local/nginx/logs/bak -mtime +30 -name "*.gz" -exec rm -rf {} \;
find /usr/local/nginx/logs/bak -mtime +1 -name "*.log" -exec rm -rf {} \;

(2)授权脚本文件

chmod +x nginx_log.sh

配置crontab

也可参考之前配置Mongo日志清理的链接 Mongo日志清理

#打开定时任务
(1)crontab -e 
#进入编辑模式
(2)i 
#填加定时任务调用脚本(根据自己路径配置),每天1点执行
(3)0 1 * * * /bin/sh /opt/shell/nginx_log.sh #添加任务
#保存退出
(4):wq! 

你可能感兴趣的:(技术相关,nginx,spring,boot,vue.js)