前言:
项目想要上线,前提是肯定需要一台服务器
我下面使用的是腾讯服务器和宝塔Linux的管理工具来进行项目的部署上线
项目部署:
我原来那篇文章写了用nginx的原生部署,不过我觉得那种方法已经很不实用了,主要还有一个原因就是我部署不成功,下面介绍用宝塔面板直接部署
这里推荐一个连接虚拟机的工具:xshell
那里的主机填服务器IP
然后后面的账号(root)和密码。
这样就算连接成功了。
宝塔面板部署前端项目:
1:首先先将前端项目打包成dist文件夹:
这就来到了第一坑:
我点了build之后,报错了一堆的错误
分析这个vue-tsc -b && vite build,
前面的vue-tsc -b是 Vue 3 项目中用于 TypeScript 的 CLI 工具,它会检查你项目中的 TypeScript 代码是否存在类型错误。这有助于及早发现和修复潜在的问题。
就会发现什么错误呢。比如你这个变量没有用,它也会给你报错
不过我们知道这些都不影响上线,所以我们直接删除这个命令
直接vite build构建就行
2:在宝塔面板里面下载nginx:
(后面其实还有蛮多东西要下,不过这个部分只部署前端):
3:创建PHP项目:
将自己前端打包的文件(dist)里面的文件直接拉到宝塔面板的文件中:
你添加站点之后:
宝塔会自动生成一个文件夹
直接把文件dist目录拉进去即可。
访问ip:
用户中心的:
伙伴匹配系统的:
宝塔面板部署后端项目:
这里我直接拿伙伴匹配系统举例,伙伴匹配系统里面牵涉到Redis的配置,还有Redisson配置信息的修改,比较复杂
1:在服务器上安装或者部署Mysql和Redis:
Mysql:
1:直接在软件商店里面安装Mysql:
注意:这里其实按照5版本和8版本的都可以,不过在后面的操作命令上有点不同
2:修改端口:
Mysql默认端口3306,Redis默认端口6379,
这边直接一起修改了
在云服务器的上也需要修改
3:修改验证模式:
mysql8:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '{替换成你的root密码,没有大括号}';
mysql5:
GRANT ALL ON *.* TO root@'%' IDENTIFIED BY '{替换成你的root密码,没有大括号}' WITH GRANT OPTION;
并且修改一下数据库root的密码:
关于为什么要修改这个验证模式:
其实就是一种更稳定的办法:
修改验证模式的原因
- 连接问题:如果你的应用程序或库无法与 MySQL 建立连接,可能需要将用户的验证模式修改为更兼容的形式。
- 升级影响:在从旧版本升级到新版本的 MySQL 时,应用程序对连接的影响可能导致需要调整验证模式以确保协作。
- 安全策略:根据业务需求和安全策略,企业可能会选择使用更安全的验证模式。
最后在刷新一下权限:
FLUSH PRIVILEGES;
Redis:
1:下载:
2:修改端口:
3:修改配置:
关闭redis的保护模式:
放开访问:
2:在yml文件中配置对应信息:
3:打jar包放到宝塔面板文件中:
4:创建Java项目:
注意点:
1:如果配置完以上信息之后,没有任何提示,只出现了一个红叉叉
就说明这个时候你指定的端口被占用了
解决办法:
如果是8080端口的话:就去软件商店里面把tomcat关掉
2:防火墙的配置包括宝塔面板里面的和服务器的配置
碰到的第一个bug:
在说碰到的bug之前,
我们要先知道去哪里能看到报错信息
这个配置好之后,你直接点启动,宝塔面板会提示你启动成功,不过你看到那个项目还是红色的未启动状态,这真的很坑
所以这个时候如果我们发现启动不了,然后又不报错,我们可以有以下两个方式来看报错:
1:xshell
2:宝塔面板中的有项目日志(这个真的是后面才发现的)
ok,说明了在哪里能看到报错信息
我们再说一下碰到的bug:
Java .lang. unsupportedclassversionerror: com/usercenter/usercenterproject/UserCenterProjectApplication已被最新版本的Java运行时(类文件版本61.0)编译,此版本的Java运行时仅识别类文件版本高达52.0
Java .lang. unsupportedclassversionerror
Java .lang. unsupportedclassversionerror:已被最新版本的Java运行时(类文件版本61.0)编译,此版本的Java运行时仅识别类文件版本高达52.0
其实说起来就是你的JDK版本和运行环境的版本不一致
解决办法:
在springboot项目中手动降低springboot的版本和java版本
碰到的第二个bug:
做完上述步骤之后,发现项目还是跑不起来
这个bug蛮离谱,我其实不是很懂这个为什么会出这样的bug,不过还是在此记录一下把。
访问了公网ip/api,发现打不开这个网址
然后用netstat -ntlp在xshell里面查看了一下网络信息,发现只有IPv6启动了,IPv4的没启动
问了一下GPT
回答说:应用程序只监听了IPv6地址
解决办法:
在springboot项目依赖中加入
通过将 server.address
设置为 0.0.0.0
, Spring Boot 应用程序将监听所有可用的网络接口,而不仅仅是本地环回接口(localhost)。这意味着您可以通过任何网络接口(包括公共 IP 地址)来访问您的应用程序。
Docker部署前后端:
说Docker之前,我们可以先了解一个概念:镜像
什么是镜像呢?
镜像(Mirroring)是一种文件存储形式,是冗余的一种类型,一个磁盘上的数据在另一个磁盘上存在一个完全相同的副本即为镜像。
我觉得可以理解为一份文件的副本。
Docker是什么:
Docker是一个开源的容器引擎,它有助于更快地交付应用。 Docker可将应用程序和基础设施层隔离,并且能将基础设施当作程序一样进行管理。使用 Docker可更快地打包、测试以及部署应用程序,并可以缩短从编写到部署运行代码的周期。
稍微翻译一下就是docker是一个容器,可以将项目环境和项目代码一起打包成一个镜像,所有人都能下载和访问
以后想再启动项目,直接下载镜像就行
也可以把docker理解为软件安装包
Dockerfile:用于指定构建Docker镜像的方法
一般把这个Dockerfile放在自己项目的根目录下。
Dockerfile的编写方法:
先来看几个Dockerfile的案例把
第一个Dockerfile案例:
FROM maven:3.8.1-jdk-8-slim as builder
# Copy local code to the container image.
WORKDIR /app
COPY pom.xml .
COPY src ./src
# Build a release artifact.
RUN mvn package -DskipTests
# Run the web service on container startup.
CMD ["java","-jar","/app/target/UserCenterProject-0.0.1-SNAPSHOT.jar","--spring.profiles.active=prod"]
- from 依赖的基础镜像
- workdir 工作目录
- copy 从本机复制文件
- run 执行命令
- cmd 指定运行容器时默认执行的命令
跨域问题:
跨域是什么?
跨域(Cross-Origin Resource Sharing,CORS)是一个 Web 浏览器的安全特性,用于控制不同源之间的资源共享。
简单来说就是比如你前端运行在 http://localhost:5173,这个域名上,然后你要想后端发送请求
你后端的域名是 http://localhost:8080,这样也会发生跨域
其实在我们自己电脑上进行前后端联调的时候也会发生跨域的问题
只要协议,端口号或者ip地址有一个不一样都是跨域
我们有了这些概念之后,我们就开始去想如何在服务器上解决跨域问题?
如何解决跨域?
1:最简单粗暴的方法,把域名端口ip地址都改成相同的
这种方式在线上不太能实现,顺口提一下就好了
2:网关支持(NGINX):
这种方法是修改nginx的配置
让nginx帮你做代理:告诉浏览器允许跨域 (cross-orgin-allow)
具体步骤:
location /api {
proxy_pass http://服务器ip/api/;
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' "true";
if ($request_method = "OPTIONS") {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' "true";
add_header 'Access-Control-Max-Age' 86400;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE';
add_header 'Access-Control-Allow-Headers' 'reqid, nid, host, x-real-ip, x-forwarded-ip, event-type, event-id, accept, content-type';
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain, charset=utf-8';
return 204;
}
}
这里有两个点需要说一下
1:就是这个预检请求OPTINOS:
预检请求(Preflight Request)是在跨域 HTTP 请求中,浏览器为了了解服务器支持的请求方法和头信息而发送的一种 OPTIONS 请求。
简单理解为浏览器在发送跨域请求前发一个这个预检请求OPTINOS来保证浏览器安全性
我们直接在配置文件中对这个预检请求OPTINOS进行修改,允许这个请求跨域。
2:第二个就是这个proxy_pass
这个就是将你要发的请求代理到那个域上
这里并不是随便设置的这个/api
这是前端axious拦截器的部分代码:
我们可以看到,有一个baseURL属性:
axios
的 baseURL
属性用于设置所有 axios 请求的基础 URL
换句话说,比如,如果你在 axios 中发起一个请求,像 axios.get('/users')
,那么实际的请求会变成 http://118.89.53.22/api/users
拼上这个/api后,nginx会自动帮你代理到你想要去的域名。
3:修改后端服务,后端允许跨域:
a.后端的control层打上注解:@CrossOrigin
这个注解的意思就是后端允许跨域
b.添加web全局响应拦截器:
(这也是鱼皮老师比较推荐的方法)
这里的属性可以更灵活一点:
@Configuration
public class WebMvcConfg implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
//设置允许跨域的路径
registry.addMapping("/**")
//设置允许跨域请求的域名
//当**Credentials为true时,**Origin不能为星号,需为具体的ip地址【如果接口不带cookie,ip无需设成具体ip】
.allowedOriginPatterns("*")
//是否允许证书 不再默认开启
.allowCredentials(true)
//设置允许的方法
.allowedMethods("*")
//跨域允许时间
.maxAge(3600);
}
}
自此所有解决跨域问题的方法都解决完了
项目前后端应该已经算是正式部署上线了。
自己在处理跨域时候碰到的问题:
其实我照着视频解决这个问题的时候,我自己的思考是比较少的,我其实有点不理解,这个路径到底是要发到哪里去,巴拉巴拉的搞得好乱,我就在星球上看到一个方法,我就复制粘贴,看到一个就尝试一个,这样其实不好。等我今晚回来复盘得时候,我想清楚了。
首先前端得nginx是要配得(虽然修改后端配置,不过我觉得主流应该还是用nginx)
我配置好了nginx之后,我往后端发请求,后端响应了一个 :无效跨域请求 (Invaild cross-orgin request)
然后我这个时候就懵了,我一直还在想,我后端为什么会返回这样一个报错,后面看到星球里面一个修改了我上面说的WebMvcConfg,我一看原来是因为我原来在本地进行前后端联调,然后我就设置了localhost,这样得地址可以跨域,没有设置我服务器得ip,修改之后我得问题就解决了,但我们不是说还有那个@CrossOrigin,那个时候我也不知道我看到了那一句话,我就把这个给注释掉了,现在想来真是有点病急乱投医了。
然后我今晚又重新看了一遍鱼皮老师在用户中心项目中解决跨域问题的视频,发现他光配置了nginx就可以跨域,果不其然我今晚又重新看了一遍自己的项目,我把后端的WebMvcConfg给删了,接着从前端发送请求,请求也请求到了。
这下总算是理解了鱼皮老师说的两种解决方法(我一开始以为前后端都需要去配置)