跳至主要內容

Da-API平台-项目部署

holic-x...大约 30 分钟项目Da-API平台

项目部署

前后端分离部署:原生部署、宝塔方式部署、Docker部署、工作流部署

  • 前端:npm run build项目打包

  • 后端:

    backend 项目:web 项目,部署 spring boot 的 jar 包(对外的)

    gateway 网关项目:web 项目,部署 spring boot 的 jar 包(对外的)

    interface 模拟接口项目:web 项目,部署 spring boot 的 jar 包(不建议对外暴露的)

    关键:网络必须要连通

​ 理解不同部署方式的场景和优点,理解配置才能更好地去使用

1.多环境部署

【1】多环境部署概念

本地开发:localhost(127.0.0.1)

多环境:指同一套项目代码在不同的阶段需要根据实际情况来调整配置并且部署到不同的机器上。

为什么需要?针对不同环境做不同的事情

【1】每个环境互不影响

【2】区分不同的阶段:开发 / 测试 / 生产

【3】对项目进行优化:

​ 本地日志级别

​ 精简依赖,节省项目体积

​ 项目的环境 / 参数可以调整,比如 JVM 参数

多环境分类:

【1】本地环境(自己的电脑)localhost

【2】开发环境(远程开发)大家连同一台机器,为了大家开发方便

【3】测试环境(测试)开发 / 测试 / 产品,单元测试 / 性能测试 / 功能测试 / 系统集成测试,独立的数据库、独立的服务器

【4】预发布环境(体验服):和正式环境一致,正式数据库,更严谨,查出更多问题

【5】正式环境(线上,公开对外访问的项目):尽量不要改动,保证上线前的代码是 “完美” 运行

【6】沙箱环境(实验环境):为了做实验

【2】前端多环境&项目打包

(1)项目打包

请求地址

  • 本地开发环境:localhost:8000
  • 线上环境:IP(可绑定域名)
startFront(env) {
    if(env === 'prod') {
        // 不输出注释 
        // 项目优化
        // 修改请求地址
    } else {
        // 保持本地开发逻辑
    }
}

用了 umi 框架,build 时会自动传入 NODE_ENV == production 参数,start NODE_ENV 参数为 development

启动方式

开发环境:npm run start(本地启动,监听端口、自动更新)

线上环境:npm run build(项目构建打包),可以使用 serve 工具启动(npm i -g serve)

项目的配置

​ 不同的项目(框架)都有不同的配置文件,umi 的配置文件是 config,可以在配置文件后添加对应的环境名称后缀来区分开发环境和生产环境。参考文档:https://umijs.org/zh-CN/docs/deployment

开发环境:config.dev.ts

生产环境:config.prod.ts

公共配置:config.ts 不带后缀

前端项目打包:

// 1.在requestConfig.ts配置baseURL
baseURL:'http://[IP]:8101', // 项目部署环境后端接口交互地址


// 2.在config.ts中配置 访问后台接口地址和静态化
 exportStatic: {},  // 静态化: 生成的目录在每个模块文件夹中都会有个index.html(可以看官方文档确认),给每个路由都配了一个index.html

image-20240316192903501

​ 可以参考官方文档提供的部署策略,可以从中配置对网站进行优化。

数据传输:利用sftp将文件内容传输到service下

image-20240316213555219

如果使用sftp连接腾讯云,提示找不到匹配的outgoing encryption算法,需要相应调整协议算法规则(文件->属性->配置协议算法属性),然后再重新连接尝试

image-20240316213356669

(2)常见问题

​ 通过指令npm run build打包,发现自己创建的一些包没有被正确打包,重新导入依赖尝试

【3】后端多环境&项目打包

​ 通过maven的package指令打包项目(jar打出来看看有没问题),项目打包生成的jar在target文件夹下,进入到指定目录,执行指令运行生成的jar

​ 如果打包过程中发现单元测试不通过则可通过maven选项卡的一个小闪电按钮禁用跳过test模块,直接打包

image-20240316201640903

​ Springboot项目可以通过application.yml添加不同的后缀以区分配置文件,可以在启动项目的时候传入环境变量

java -jar .\xxx-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod

image-20240316201819451

image-20240316201957644

api-platform-backend项目打包:修改appliction-prod.yml文件,修改配置

主要修改内容:依赖的环境地址:数据库地址、项目端口号、缓存地址、消息队列地址等、服务器配置

核心部署流程说明:

【1】项目打包

​ 即springboot项目打包:api-platform-backend、api-platform-interface、api-platform-gateway,分别为其指定一个上线配置application-prod.yml,修改其中的一些核心配置:例如数据库连接配置、nacos配置、url转发配置等,将所有基于本地localhost的配置调整为后续的上线IP地址或者指定域名

​ 随后执行mvn package打包(跳过测试用例

【2】将打包好的jar上传到发布目录中

​ 如果通过jar方式启动,则将打包好的jar都上传到/www/wwwroot中即可,后续可通过宝塔操作创建JAVA项目启动项目(此处需注意启动的时候必须指定激活的配置文件为prod)

​ 此处需注意的是有两种上传jar的方式,一种是通过宝塔的文件传输功能将本地打包好的jar上传上去;另一种方式是通过github或者gitee等代码管理平台,将本地打包好的jar上传到该平台,然后再由服务器通过git clone的方式获取到对应的jar。两种方式都能够实现jar上传,具体结合实际场景选择合适的操作方式即可

【3】部署

​ 部署可分为多种部署方式,如果通过宝塔方式部署,则直接创建JAVA项目配置启动指令即可(核心在于指定启动的jar、启动规则、基于什么配置文件)

【4】数据库配置&项目打包

​ 注意本地和线上保持一致,Navicat版本连接远程mysql数据库如果版本不兼容会被拒绝访问,因此要确认本地mysql版本和线上mysql版本要一致。如果通过宝塔安装数据库则可在软件商店对应查看相应的数据库版本,如果要做版本切换则必须注意对原有存量数据库信息进行备份(还有一种可能是协议问题,可以在连接URL后面添加参数?useSSL=false尝试连接)

image-20240316195829534

​ 通过idea的database选项卡可以将数据表的DDL语句输出,保存对应信息即可

image-20240316195717686

Mysql安装配置问题

image-20240316211408755

​ 配置完成通过Navicat访问发现提示,MySQLService拒绝该IP的访问,需要设置相应数据库的权限,将访问权限设置为所有人访问或者指定IP访问,填充属性:用户名、密码、公网IP

image-20240316211510519

2.原生部署

【1】nginx安装配置&部署静态页面

【1】方式1:用系统自带的软件包管理器安装(例如centos的yum)

【2】方式2:用nginx官网open in new window提供的方式安装

# 获取nginx安装包
wget http://nginx.org/download/nginx-1.21.6.tar.gz
# 解压、重命名
tar -zxvf nginx-1.21.6.tar.gz -C /root/service/
mv nginx-1.17.5 nginx
# 安装
make
make install

# 执行指令检查依赖
cn nginx
./configure

# 安装依赖
yum install pcre pcre-devel -y
yum install openssl openssl‐devel -y
yum install zlib zlib‐devel -y

# 安装
make
make install

image-20240316204739749

# 进入nginx安装目录,/usr/local下生成nginx目录
cd /usr/local/nginx

# 在sbin目录下控制nignx服务(启动、停止、重写加载)
./nginx # 启动
./nginx ‐s stop # 停止
./nginx ‐s reload # 重写加载

# 启动成功后查看是否有nginx的线程是否存在
ps ‐ef | grep nginx

上传静态资源文件到指定目录,配置conf/nginx.conf文件

server {
    listen        80;
    server_name localhost   ;
    location / {
    	root /home/test;
    	index index.html index.htm;
    }
}
# 将静态资源文件上传至/home/test目录,例如此处将index.html文件上传到/home/test目录

# 启动nginx服务,通过ip:80访问首页(参考启动指令,启动nginx时指定配置文件)
/usr/local/nginx/sbin/nginx -c /usr/local/software/nginx/conf/nginx.conf

【2】前端项目部署配置

nginx对应配置:conf/nginx.conf
server {
    listen        80;
    server_name localhost   ;
    location / {
    	root /root/service/api-platform-frontend;
    	index index.html index.htm;
    }
}

# 上传dist文件夹的所有内容到/root/service/api-platform-frontend

# 在sbin目录下控制nignx服务(启动、停止、重写加载)
./nginx # 启动
./nginx ‐s stop # 停止
./nginx ‐s reload # 重写加载(修改类nginx.conf配置之后则需要注意reload)

# 启动成功后查看是否有nginx的线程是否存在
ps ‐ef | grep nginx

nginx启动访问公网IP(默认端口为80):(查看nginx进程,如果跳转页面无法正常访问则检查原有宝塔中引入nginx是否冲突,提示站点没有匹配信息,先卸载掉宝塔中的nginx,确保自己安装的可以正常访问)

image-20240316214359477

​ 继续访问IP发现访问403错误,检查nginx启动进程(发现nginx启动进程为nobody,因此要修改启动配置将原有默认user nobody改为user root

image-20240316221522739

​ 修改完上述配置后再次尝试访问(初次访问加载可能有点慢 耐心等待)

image-20240316221152508

【3】后端项目部署配置

线上环境配置

此处将所有软件安装包放在/root/software下进行管理

【1】JDK环境安装:参考文章Linux下安装Java环境open in new window

yum install java-1.8.0-openjdk.x86_64

# 安装完成查看java版本
java -version

image-20240316221911919

【2】Maven环境安装:参考文章open in new window

(1)下载maven依赖open in new window,将下载好的maven依赖上传到linux服务器,项目中使用的maven版本是3.5.2open in new window,对应maven-3.5.2下载open in new window

image-20240316222713677

wget https://archive.apache.org/dist/maven/maven-3/3.5.2/binaries/apache-maven-3.5.2-bin.tar.gz

(2)解压、配置

# 解压、重命名
tar -zxvf apache-maven-3.5.2-bin.tar.gz -C /root/software
mv apache-maven-3.5.2 maven-3.5.2

# 配置maven环境变量,补充maven配置,随后保存
vim /etc/profile

export MAVEN_HOME=/root/software/maven-3.5.2
export PATH=${PATH}:${MAVEN_HOME}/bin

# 刷新配置让配置生效
source /etc/profile

# 检查maven配置是否生效
mvn -version

image-20240316224324324

后端项目部署

【1】方式1可以将后端项目推送到github仓库,随后git clone项目,然后执行mvn指令编译安装

# 安裝git
yum install -y git

# 将后端项目推送到远程,通过git clone方式获取到项目
git clone xxxx

# 在后端项目目录中执行指令打包跳过测试
mvn package -DskipTests
(因为此处maven没有配置从哪里加载依赖,依次首次加载可能有点慢)

【2】直接本地打包prod版本,随后上传到服务器中执行(将jar上传到/root/service)

# 执行指令启动项目
java -jar api-platform-backend-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod

// 如果出现错误Unable to access jarfile .api-platform-backend-0.0.1-SNAPSHOT.jar,要修改这个文件的权限
chmod a+x api-platform-backend-0.0.1-SNAPSHOT.jar

image-20240316225629385

​ 指令执行完成,后端项目正常启动,但是可能存在一点小问题(因为此处Nacos注册中心还没有启动)

​ 上面的指令执行项目启动,但是会发现目前这个shell窗口不能做任何事情,因此需要调整指令

# 让项目在后台运行
nohup java -jar api-platform-backend-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod &

image-20240316230411835

​ 参考文章:Linux之让程序在后台运行open in new window

3.宝塔面板部署

上述内容是基于CentOS原生部署方式,如果要调整为宝塔部署要注意配置冲突问题,最好就是重装系统,确保一个干净的上线部署环境

image-20240317094009861

image-20240317094547127

创建完成可访问宝塔面板:

image-20240317094612581

image-20240317094644476

​ 系统重装后如果要在本地的xhsell连接,可能会提示找不到匹配的key exchange算法,这个时候需要修改相关配置(原因在于本地使用的XShell4版本太低,而要连接的服务器版本升级,两者匹配的算法校验不同),可以升级xshell、xftp版本再次尝试连接,或者选择要连接的SSH算法规则

image-20240317095210422

【1】宝塔配置

(1)根据提示,先获取到宝塔面板用户的用户名、密码。登录宝塔实例,执行指令sudo /etc/init.d/bt default获取用户信息

image-20240317095653937

(2)外网IP访问:http://[43.138.185.20]:8888/tencentcloud/,输入获取到的用户名密码登录到宝塔面板

image-20240317095804913

(3)关联腾讯云API秘钥,参考官网提示指引open in new window

​ (需注意202311新规定,原可直接查看secretId、secretKey,现只有在新建的时候才能看到SecretKey,因此在初始化创建的时候就要保存下来)

​ 如果创建忘记保存则可以先禁用秘钥后删除重新创建即可,供宝塔面板关联绑定使用

​ 新版本宝塔新增了很多功能,可以帮助快速上线

image-20240317101728741

部署上线环境配置

尽量确保与本地编译执行的软件版本配置保持一致,避免版本兼容问题触发其他隐形问题

​ 可以在软件商店中搜索要安装的软件,选择急速安装,默认使用宝塔安装配置的方式

(1)nginx安装(1.21)

image-20240317101130635

​ 安装完成,可在软件商店中对其版本进行管理

image-20240317102234272

(2)MySQL安装(5.7)

image-20240317101915283

​ 安装完成,生成数据库用户和关联数据库即可(并在后台项目中绑定配置),注意数据库访问用户名、密码和访问权限。

​ 本地通过Navicat连接远程数据库将本地现有的数据库进行迁移

(3)JAVA JDK环境等配置

【2】前端部署

​ 在软件商店中安装nginx后,点击网站->添加站点

  • 域名:服务器IP

    默认配置,不用改操作,点击提交,创建一个静态PHP站点

​ 进入到站点目录,随后将api-platform-frontend项目生成的dist文件夹中的所有内容,直接放到对应站点目录即可

image-20240317102544508

image-20240317102822791

​ 站点创建成功默认生成一些文件,此时确认nginx启动随后访问外网IP(默认端口80)随后可以得到下述页面,说明nginx配置完成

image-20240317102839591

​ 确认主页可以访问,则将前端打包的dist文件夹中的所有内容替换到/www/wwwroot/xxx目录

image-20240317103205350

​ 随后再次访问公网IP,即可访问前端页面

image-20240317103335784

​ **对比原生方式部署,思考宝塔是如何实现nginx配置,在哪里可以跟踪?如果存在多个项目部署,则配置不同端口即可。可以配置相应的文件。**这些内容都可以在nginx管理进行查看,其实相当于宝塔将原生部署的一些操作进行可视化处理,提供方便快捷的方式给用户使用

image-20240317103535228

【3】后端部署

(1)部署流程

​ 网站添加Java项目(升级宝塔版本,发现其提供了很多项目部署的可视化操作面板)

image-20240317103729718

​ 还可对项目环境进行配置,例如JDK环境(项目使用的是1.8.0_351),则选择指定或者相近版本安装即可

image-20240317104042029

参考教程:新版宝塔Java项目部署教程open in new window

例如此处将本地编译生成的jar上传并放置在/www/wwwroot下(即/www/wwwrootapi-platform-backend-0.0.1-SNAPSHOT.jar),项目jar选中之后会自动填充配置信息

image-20240317104818329

​ 参考原生项目部署方式,指令需明确指定配置文件

# 执行指令启动项目(原生部署方式)
java -jar api-platform-backend-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod


# 宝塔启动配置(与原生部署的指令相同,只不过此处多加了几个启动参数)
/www/server/java/jdk1.8.0_371/bin/java  -jar -Xmx1024M -Xms256M  /www/wwwroot/api-platform-backend-0.0.1-SNAPSHOT.jar --server.port=8101 --spring.profiles.active=prod

image-20240317105629174

image-20240317105852479

​ 该开始启动的时候CPU占用会比较多,当CPU恢复正常,项目启动完成(如果启动失败则手动复制指令在shell中执行确认指令是否正常)

防火墙配置:放开指定端口限制

​ 但是启动成功发现不能访问,例如8080端口(实际查看自身项目配置端口),查看端口情况发现8080是IPV6,无法访问。

springboot启动项目访问端口8080 IPV6,配置server.address=0.0.0.0

解决方案:宝塔:防火墙需要放行对应端口(访问的是IPV6但是IPV4)

image-20240316233557165

image-20240317110852240

​ 检查项目启动日志,此处由于Nacos还没有启动,导致springboot项目启动失败(如果单纯要启动一个jar可以打包一个可以访问的版本尝试访问即可)

(2)api-platform-interface部署(8080)

​ 打包api-platform-interface,上传到/www/wwwroot下随后创建java项目启动测试,此处interface使用的是8080端口

​ 此处需注意检查pom.xml配置,如果其需要通过jar方式启动,则此处的配置要参考api-platform-backend进行配置

image-20240317112644846

基于上述pom.xml配置,无法通过jar方式启动项目(检查项目报错信息),此处只需要改动一处,将<skip>属性注释掉即可(即将配置类也打包上去),随后重新打包上传再次尝试

image-20240317112811665

# 可以先在本地检查jar运行情况,后续再上传部署
java -jar .\xxx-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod

# 启动指令
/www/server/java/jdk1.8.0_371/bin/java  -jar -Xmx1024M -Xms256M  /www/wwwroot/xxx-0.0.1-SNAPSHOT.jar --server.port=8080 --spring.profiles.active=prod

image-20240317113659366

确认api-platform-interface启动成功后访问:http://[IP]:8080/api/name/getNameByGet?name=hello

访问http://[IP]:8080/api/:跳转到正确页面即可

image-20240317131020402

(3)Nacos部署(8848)

​ 应用商店中安装Nacos,安装完成点击设置可以查看nacos注册中心主页地址,(默认启动端口号是8848),访问注册中心主页,默认用户名密码nacos。

image-20240317131208796

​ 可以看到这个nacos和自身本地启动的差不多,此时则可进一步调整后台引用到nacos的配置(服务提供方:api-platform-backend、服务调用方/消费者:api-platform-gateway)

image-20240317131453750

(4)api-platform-backend部署(8101)

# 宝塔启动配置(与原生部署的指令相同,只不过此处多加了几个启动参数)
/www/server/java/jdk1.8.0_371/bin/java  -jar -Xmx1024M -Xms256M  /www/wwwroot/api-platform-backend-0.0.1-SNAPSHOT.jar --server.port=8101 --spring.profiles.active=prod

(5)api-platform-gateway部署(8090)

# 宝塔启动配置(与原生部署的指令相同,只不过此处多加了几个启动参数)
/www/server/java/jdk1.8.0_371/bin/java  -jar -Xmx1024M -Xms256M  /www/wwwroot/api-platform-gateway-0.0.1-SNAPSHOT.jar --server.port=8090 --spring.profiles.active=prod

image-20240317132901542

(6)确认项目启动状态(backend、nacos、gateway、interface)

​ api-platform-interface:访问接口测试即可(项目默认提供了一个index.html,检查访问IP:8080/api是否正常即可)

​ nacos:检查上线环境中nacos的服务注册情况

​ api-platform-backend、api-platform-gateway:检查项目启动日志,看dubbo日志是否正常

image-20240317133457551

​ 完成上述操作之后,则可联调前后端调用接口,确认前后端是否正常交互响应,如果异常则一一根据日志排查出错信息

(7)常见问题

springboot项目启动后发现可以通过127.0.0.1、localhost访问,但是无法通过外网IP访问

​ springboot项目启动后发现可以通过127.0.0.1、localhost访问,但是无法通过外网IP访问,原因应该是springboot自带的tomcat导致,可以修改配置文件的application.ymlserver.address=0.0.0.0解决。(127.0.0.1可能会使用ipv6,修改为0.0.0.0可改为Ipv4,这点可以在本地调试验证,以api-platform-interface为例)

# 查看端口监听状态
netstat -ntlp 

分别用多种方式访问:

http://localhost:8080/api/name/getNameByGet?name=x

http://127.0.0.1:8080/api/name/getNameByGet?name=x

http://192.168.xx.xx:8080/api/name/getNameByGet?name=x(外网地址:通过ipconfig查阅)

image-20240317121754952

# 如果application配置,则可以在项目启动指令中指定server.address=0.0.0.0
/www/server/java/jdk1.8.0_371/bin/java  -jar -Xmx1024M -Xms256M  /www/wwwroot/xxx-0.0.1-SNAPSHOT.jar --server.port=8080 --address=0.0.0.0 --spring.profiles.active=prod
# application.yml配置
# 应用服务 WEB 访问端口
server:
  port: 8080
  servlet:
    context-path: /api
  address: 0.0.0.0

noob:
  client:
    access-key: noob
    secret-key: abcdefg

访问无法被处理

可能是端口被防火墙拦截,此处需要注意两个点:轻量应用服务器的防火墙配置、宝塔防火墙配置,二者缺一不可

轻量应用服务器防火墙配置:进入到指定服务器,在防火墙选项卡中进行配置

image-20240317130213075

此处注意防火墙模板概念,防火墙模板是针对所有的轻量应用服务器配置一个防火墙模板,它要应用到对应的实例才能生效。而此处要配置的是指定服务器的防火墙配置,因此要进入到指定实例进行配置方能生效,例如此处根据上图所示放开3306-20000端口供系统项目部署使用

image-20240317130429779

宝塔实例防火墙配置

​ 配置完上述服务器防火墙配置,还需要对宝塔实例的防火墙配置进行管理,放开指定的端口

image-20240317130700796

​ 配置完成此时再尝试访问,就不会出现访问无法被处理问题,而是直接访问到对应项目接口等

4.Docker部署(宝塔面板部署可直接跳到5校验)

​ 使用宝塔安装Docker,在linux命令行中执行docker -v指令验证docker是否安装成功

​ 将应用制作成镜像:给前端和后端项目编辑一个Dockerfile

​ Dockerfile:用于指定构建Docker镜像的方法,一般情况下可以参考同类项目的一些配置配置文件(例如github、gitee)

​ 宝塔提供了Docker管理器可以方便地对镜像进行管理

后端部署

image-20240316234955499

​ 通过git clone方式将项目克隆到指定目录,随后根据Dockerfile构建镜像

​ Dockerfile -t (打标签:给同一个项目的多个不同发布版本构建不同的镜像打标签)

​ 执行没有权限则加sudo

# 根据Dcokerfile构建镜像(在Dockerfile所在目录中执行指令)
docker build -t api-platform-backend:V.0.0.1 .

前端部署

​ 创建一个docker用于存放Dockerfile所需要的内容,构建Dockfile、nginx配置

​ 参考原生部署思路,通过配置nginx实现转发。此处Dockerfile构建的核心是用自己本地的nginx配置去顶掉(覆盖)Dockerfile镜像中本身的nginx配置

FROM nginx

WORKDIR /usr/share/nginx/html/
USER root

# 将本地配置的nginx覆盖Docker默认的配置
COPY ./docker/nginx.conf /etc/nginx/conf.d/default.conf

# 将前端生成的代码包放到默认的nginx发布代码包目录
COPY ./dist  /usr/share/nginx/html/

# 显示告诉开发者这个项目占用80端口(只是一个注释,无实际作用)
EXPOSE 80

# 启动nginx
CMD ["nginx", "-g", "daemon off;"]

nginx.conf

server {
    listen 80;

    # gzip config
    gzip on;
    gzip_min_length 1k;
    gzip_comp_level 9;
    gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;
    gzip_vary on;
    gzip_disable "MSIE [1-6]\.";

    root /usr/share/nginx/html;
    include /etc/nginx/mime.types;

    location / {
        try_files $uri /index.html;
    }

}

​ 推送代码,然后根据Dockerfile构建镜像

# 根据Dcokerfile构建镜像(在Dockerfile所在目录中执行指令)
docker build -t api-platform-frontend:V.0.0.1 .
# 查看当前构建的所有镜像
sudo docker images

扩展:关注镜像优化的两个指标:镜像大小、镜像构建时间,可以通过多阶段构建的方式来减少镜像尺寸、减少构建时间

5.前后端对接

【1】跨域问题

​ 跨域问题:浏览器为了用户的安全,仅允许向 同域名、同端口 的服务器发送请求。为了检测跨域问题,浏览器会在发送请求之前发送一个预检请求,如果预检不通过则不会往下走

image-20240317111307379

如何解决跨域

【1】把域名、端口改成相同的,让服务器告诉浏览器:允许跨域(返回 cross-origin-allow 响应头)

【2】网关支持(Nginx)

【3】修改后端服务:配置 @CrossOrigin 注解,添加 web 全局请求拦截器(Springboot设置cros跨域的4种方式open in new window

image-20240317140845814

【2】前端线上部署动态路由跳转失效问题

问题分析:前端通过动态路由实现接口信息查看,但是在这个过程中却发现访问404错误。一步步排查思路,思考会不会是dist文件夹内少打包了东西或者是上传过程中出现问题?

解决过程:排查代码路由设定,发现这个接口信息查看页面是配置了动态路由,也就是说其不同于其他页面配置,通过npm run build指令打包不会生成其index.html静态页面,它的构建是基于事件触发的时候给它指定的参数然后再进行渲染。因此排除是项目打包配置的问题。

image-20240317151918714

​ 继续思考,如果不是打包问题,那可能就是线上线下环境路由配置问题,因此通过搜索关键字,确认react项目本地测试和线上部署动态路由失效的场景,进而进一步排查问题(参考解决方案文章open in new window),可以参考React Router的文档跟踪信息(参考文章:react 打包后,项目部署完毕到服务器上,刷新页面报错(404)open in new window

image-20240317150406458

​ 解决react使用BrowserRouter部署后刷新页面报404

image-20240317145745252

browserHistory:Browser history 是使用 React Router 的应用推荐的 history。它使用浏览器中的 Historyopen in new window API 用于处理 URL,创建一个像example.com/some/path这样真实的 URL 。

hashHistory :Hash history 使用 URL 中的 hash(#)部分去创建形如 example.com/#/some/path 的路由。

createMemoryHistory :Memory history 不会在地址栏被操作或读取。这就解释了是如何实现服务器渲染的。同时它也非常适合测试和其他的渲染环境(像 React Native )。和另外两种history的一点不同是你必须创建它,这种方式便于测试。

​ 处理:对应nginx相应配置try_files属性,配合browserHistory使用。在创建的站点中修改nginx配置(注意不要修改nginx的主配置,应该要对应到自己的站点),配置完成重载配置或者重启nginx再次访问尝试确认

image-20240317151905994

server {
    listen 80;
    server_name your-domain.com;
 
    location / {
        # 用于配合 browserHistory使用
        try_files $uri $uri/index.html /index.html;
  }
}

6.测试

​ 当所有的内容都配置好之后,依次检查项目是否正常启动成功,前后端对接访问测试是否和本地测试一样。确认无误即上线部署成功,随后可进入下一步域名配置、完善系统功能即可

image-20240317152239960

7.域名配置

当一个用户输入网址时候,整个流程做了哪些事情

​ 前端访问流程:用户输入网址 =》域名解析服务器(将网址解析为IP地址/交给其他的域名解析服务)=》nginx接收请求,找到对应文件并返回给前端 =》 前端加载文件到浏览器中(js、css)=》 渲染页面

​ 后端访问流程:用户输入网址 =》域名解析服务器(将网址解析为IP地址/交给其他的域名解析服务)=》(中间也可以加nginx反向代理转发)对应服务器 =》 访问对应端口请求接口数据 =》 响应交互

【1】前端子域名配置、解析

申请域名、配置域名解析

​ 参考腾讯云官方提供,DNS域名解析。添加一条A记录,将子域名转发到指定的ip:

image-20240317155254263

nginx配置

​ 将原有nginx配置绑定新添加的域名,让nginx能过识别这个域名

image-20240317155445838

​ 配置完成,直接通过子域名访问,即可直接访问到页面主页(子域名配置绑定成功可以将原有IP配置删除,避免从公网IP直接访问)

【2】后端子域名配置、解析(如果配置了域名相应要调整相应的请求地址IP为对应域名,测试一下即可)

​ 参考上述操作给后端接入一个子域名:例如api-backend.xxx.com。

​ 以api-platform-interface为例:访问【IP】:8080/api,配置后端子域名,则可通过子域名方式访问:api-backend.xxx.com:8080/api(此处访问要设定端口,因为默认是80端口访问)

image-20240317160947557

​ 如果开发者不希望暴露后端项目端口,则可通过配置nginx反向代理(当其访问到nginx根目录的是否,自动把请求转发到目标url(则可直接通过api-backend.xxx.com/api))

image-20240317161404960

【3】常见问题

​ 问题描述:基于上述配置,通过IP可以直接连通前后端。但是如果给前端指定了域名访问前端,虽然可以正常交互数据,但是会发现cookie并没有被正确地设置进去,导致一直重复强制登陆。例如此处登录后请求失败(此时前端为域名访问,请求后端为IP请求),前后端交互虽然是正常,但是前端校验却显示用户没有登录。且如果给前后端指定了不同的域名还是会导致cookie缓存作用域失效

image-20240317162922308

​ 此处需要理解 cookie 作用域和 session 机制。cookie 必须种在和后端请求域名、以及前端域名保持一致的域名(或者子域名)下,才会在发送请求时自动带上 cookie、并且不会出现 cookie 跨站问题。

image-20240317181724922

具体的解决方案:

1)建议前端和后端接口域名保持一致,用 Nginx 进行端口转发

2)修改 application.yml 中 cookie.domain 配置,指定种的 cookie 域名为前端域名、后端请求的公共子域名(例如此处的api.holic-x.com)

调整具体内容:

【1】前端:配置绑定域名为api.holic-x.com,修改后端请求接口:原baseURL:http://外网IP:8101,改为通过同一个子域名访问不同端口:http://api.holic-x.com:8101

【2】后端项目:配置cookie的domain作用域(设置为api.holic-x.com)

image-20240317173918638

​ 访问流程:前端访问流程:用户输入网址 =》域名解析服务器 =》nginx接收请求,找到对应文件并返回给前端 =》前端随后请求后台数据 =》域名解析服务器(将网址解析为IP地址,此处部署为同一个应用服务器因此前端解析api.holic-x.com为对应的IP地址访问到后端)=》找到对应端口的对应服务器 =》 访问对应端口请求接口数据 =》 响应交互

​ 前提是确保IP都能正常访问的基础上再一步步完善域名配置:例如此处是一步步去发现问题解决问题

​ 【1】前端IP访问 =》请求IP响应后端(后端做跨域处理,得以正常交互)

​ 【2】随后在调整前端为域名访问=》请求IP响应后端(后端做了跨域请求处理,虽然能够正常交互但是Cookies的domain却失效了)

​ 【3】调整前后端为同一域名访问,即前端为域名访问=》请求域名响应后端(此处只需要将IP改为与前端一致的子域名,由域名解析方做解析转发),域名解析方接收到请求后解析域名会将请求后端的内容映射到对应IP地址(而这个IP地址本身就是可以访问到后台的)(域名解析方还可以将api.xxx.com映射到另一个域名处理)

image-20240317180455766

PS:nginx处理跨域的另一种方式,如何理解这个转发配置:proxy_pass 代理指定地址,随后转发到当前服务器下的/api


server {
    listen 8080;
    # server_name your-domain.com;
    location / {
        # 用于配合 browserHistory使用
        try_files $uri $uri/index.html /index.html;
    }
		
		# 允许后端项目跨域
    location /api {
            rewrite ^/api/(.*) /$1 break;
        # 后台服务地址
        proxy_pass http://43.138.185.20/api;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_set_header   Host              $http_host;
        proxy_set_header   X-Real-IP         $remote_addr;
    }
}

8.上线部署总结

【1】项目打包

​ 后端:项目本地打包测试,确认无误后上传jar

​ 前端:打包dist文件

【2】宝塔方式部署

​ 按照相关依赖环境,配置nginx、mysql数据库、nacos等必要部署环境

​ 部署前端:nginx部署配置,确认页面能否正常访问

​ 部署后端:创建java项目,设定启动配置,先启动nacos服务器,随后依次启动api-platform-backend、api-platform-gateway、api-platform-interface

【3】前后端联调

​ 解决跨域问题,先确保可以通过IP直接访问,确认每个功能都可以正常联通

​ nginx配置,解决react上线部署动态路由失效问题

​ 随后调整IP访问,更改为域名访问(主要是api-platform-frontend、api-platform-backend直接的跨域访问、不同域名下cookies失效问题解决)

【4】扩展部署方式

​ 还可通过Dockerfile、云服务平台等方式实现快速部署

9.项目运维

【1】如何快速上线?

api接口调用平台上线地址open in new window

​ 基于上述配置,在不改动配置基础上,只需要相应替换前后端编译生成的版本即可

​ 前端:将编译生成的dist文件夹所有内容推到/www/wwwroot/xxxx(其中xxxx为站点所在位置)文件夹下

​ 后端:依次分别打包api-platform-backend、api-platform-gateway、api-platform-interface三个jar,先后重启即可(必须确保nacos注册中心正常启动)

​ 数据库:可通过本地Navicat访问远程服务器数据库进行同步更新

​ 注意点:尤其要注意不同版本的更新迭代,避免错乱,可以考虑借助Dockerfile的方式构建镜像,保留每个版本迭代的记录

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3