部署前后端分离项目
layout: post
title: 部署前后端分离项目
date: 2018-07-25
categories: study
toc: true
tags: [踩坑集,部署,nginx,tomcat,vue,代理,腾讯云,spring boot,软连接]
description:
关键词
spring-boot
gradle
腾讯云
tomcat
nginx
vue
前后端分离
代理
前言
因为种种原因,把后端部署在 tomcat 上,前端项目部署在 nginx 上。
Tomcat
tomcat 的运行没什么说的,将项目打包为 war,放在 webapps 下,启动 tomcat 会自动解压 war 包。
spring-boot 项目打 war 包部署到外部容器见文章末。
比如 etob.war ,放在 webapps 下,运行后 webapps 下会有一个 war 包解包后的 etob/ 文件夹,此时如果没有修改配置文件,我们可以通过 公网ip:8080/etob 访问我们的项目。
默认运行在 8080 端口,可以在 conf/server.xml 里修改端口。
当然,想要通过 ip:8080 直接访问项目,而不是通过 id:port/project_name 来访问的话,也可以进行配置。
流程
一
终端下 ssh 上传本地文件服务器。
scp
本地文件地址
[email protected]:/服务器存放文件的文件夹
部署(一)
直接放 webapp 下,./start.sh
即可。
会自动解压 war 包,不过这样一个 tomcat 只能部署一个项目。
###部署(二)
删除原 webapps/ROOT
目录下的所有文件,修改文件 conf/server.xml
,在Host节点下增加如下Context的内容配置:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
......
<Context path="" docBase="C:/apache-tomcat-6.0.32/myapps/bc.war"></Context>
</Host>
注意:
1)path 的值设置为空;
2)应用不要放到 tomcat 的 webapps 目录下(如上述配置是放到自定义的文件夹 myapps 内的),否则访问时路径会有问题;
3)docBase 指定到绝对路径。
如配置此设置后重启 tomcat,如果 docBase 指向的是 war 文件,则会自动将 war 解压到 webapps/ROOT 目录;如果 docBase 指向的是应用已解压好的目录,如 docBase=”C:/apache-tomcat-6.0.32/myapps/bc” ,则tomcat不会生成 webapps/ROOT 目录(这种情况下,这样就可以不用删除 webapps/ROOT 目录,但 webapps/ROOT 目录内的内容是无法访问的),访问时将直接使用docBase指定的目录。
部署(三)
与方法二类似,但不是修改全局配置文件 conf/server.xml
,而是在 conf/Catalina/localhost
目录下增加新的文件 ROOT.xml
(注意大小写),文件内容如下:
<?xml version='1.0' encoding='utf-8'?>
<Context path="/" docBase="/usr/local/src/java/tomcat/apache-tomcat-8.0.48/test" debug="0" privileged="true" reloadable="true"/>
端口
腾讯云要开启端口,首先需要到官网控制台修改权限组!!(没注意到这个问题折腾了很久)
然后设置开启端口就好了。
处理中遇到一个特别诡异的问题,只有 8080 端口可以在公网访问…
但是其他端口可以在内网访问,比如设置 nginx 在 89 端口,在服务器内用curl localhost:89
,可以收到返回信息。
扫描公网 ip,发现只开放了 8080,22(ssh)端口。
因为安全组再三确认已经搞了,怀疑是防火墙问题,但是自认为已经把防火墙关了,还是不行。
防火墙,安全组…翻来覆去地确认,不知问题在哪。
最后执行 iptables -F
(清空防火墙规则),其他端口就能用了…现在还是不知所以然。
PS: firewalld 服务与 iptables 服务都不是真正的防火墙,它们都只是用来定义防火墙规则功能的防火墙管理工具。将定义好的规则交由内核中的 netfilter 即网络过滤器来读取,从而真正实现防火墙功能,所以其实在配置规则的思路上是完全一致的。
我发现自己上装了 firewalld
,iptables
两个服务,猜测是不是这个原因造成了上面的问题,总之先关闭一个。决定关闭 iptables
。
不要用 remove
命令,用停用。
停用 chkconfig iptables off
开启 chkconfig iptables on
我怀疑是百度 “端口操作” 时,网上的文章没有区分 iptables,firewalld 两种不同环境,直接给出命令,然后我就面向百度编程(copy,paste),把两个服务都搞上了…然后关闭了这个防火墙那边仍开着,所以一直没能成功…
linux 服务器与端口相关的操作,这里列一些命令。
注意!!!!
下面的命令中有 iptables 的,应该就是在 iptables 下才能执行的操作。(大概吧)
不要瞎几把搞。
比如 firewalld 下开放端口,应该执行
firewall-cmd --zone=public --add-port=80/tcp --permanent
(–permanent永久生效,没有此参数重启后失效)
-
(iptables )开启端口(一),以 80 为例
vi /etc/sysconfig/iptables
打开配置文件加入如下语句:-A INPUT -p tcp -m state –state NEW -m tcp –dport 80 -j ACCEPT
重启防火墙,修改完成上面这条命令据说最好写在
-A INPUT -j REJECT --reject-with icmp-host-prohibited
上面。我是这样做的,不晓得是不是必须项。 -
(iptables )开启端口(二)
/sbin/iptables -I INPUT -p tcp –dport 80 -j ACCEPT
写入修改/etc/init.d/iptables save
保存修改service iptables restart
重启防火墙,修改生效 -
(firewalld)这个是 firewalld 的防火墙操作
重启防火墙:
systemctl restart firewalld.service
关闭防火墙:
systemctl stop firewalld.service
-
firewalld 的基本使用
启动: systemctl start firewalld
关闭: systemctl stop firewalld
查看状态: systemctl status firewalld
开机禁用 : systemctl disable firewalld
开机启用 : systemctl enable firewalld
-
列出所有端口
netstat -ntlp
-
查看监听(Listen)的端口
netstat -lntp
-
检查端口被哪个进程占用
netstat -lnp|grep 8080
-
查看程序占用的端口
ps -aux | grep tomcat
nginx
下载最新版本,解压后需要自己编译安装。
打开解压后的文件夹。
./configure
设置以默认配置来安装,
执行 make && make install
,编译并安装。
缺少依赖的话会报错,按照错误安装依赖就是了。一般缺少以下四中依赖,可以直接按步骤 5 一键安装。
安装依赖
yum install gcc
yum install pcre-devel
yum install zlib zlib-devel
yum install openssl openssl-devel
yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel
//一键安装上面四个依赖
安装之后,我把 nginx 加入系统变量,然后就阔以直接用 nginx 了,森林教我直接建立软连接放在 /etc/bin
下,也可以直接用 nginx 命令。
软连接
软连接:ln -s /usr/local/nginx/sbin/nginx /etc/bin/nginx
这个软连接的建立貌似是 centos 的操作,在 ubuntu 上,放在 /usr/local/bin 或者 /usr/bin 下都可以。建议 /usr/local/bin 下
- 启动
nginx
- 停止
nginx -s stop
- 重启
nginx -s reload
- 查看进程
ps -ef | grep nginx
要使用,还是得配置防火墙(开放端口)。
nagix 进行相关配置,修改 /nginx/conf/nginx.conf 文件(版本:nginx-1.15.2,不同版本配置文件路径不同 )。
我这样配置的,先看配置,再解释。
(省略其他)
http{
server {
listen 80;
location / {
root /home/hqweay/etob/dist;
index index.html;
}
location /api {
add_header 'Access-Control-Allow-Origin' '*';
proxy_pass http://localhost:89/api/api;
}
}
注意下面的 location /api 这一项是配置代理的后端接口。
稍微解释一下。
前后端分别开发的时候,前端使用了 vue,用 node.js 模拟了一个服务器环境,前后端不在同一个环境,所以访问后端的 api 就会产生跨域问题。在开发环境解决该问题,可以在 vue 的 config/index.js 中的 dev(开发环境)中配置 ProxyTable(代理)。
如下:
后端接口:http://localhost:8089/api/xxxx
前端环境:http://localhost:80
proxyTable: {
'/api': { //使用"/api"来代替"http://localhost:8089"
target: 'http://localhost:8089', //源地址
changeOrigin: true, //改变源
pathRewrite: {
'^/api': '/api'
//路径重写 因为原来的api路径含有 /api
//http://localhost:8089/api/chatRoom/addMessage
//不重写的话 使用就是 /api/api/chatRoom/addMEssage
//因为 使用"/api"来代替"http://localhost:8089"
//重写 就可以 用 /api/chatRoom/addMEssage
}
}
}
配置后,前端可以直接用 api/xxxxx
作为接口访问。
部署上去后,就不能这样搞了,所以要在 nginx 上配置一下代理。
本来我想都弄在 tomcat 上,不过…诶!
nginx 上的配置也有点奇怪。
因为我把后端部署上去后,根目录是 ip:port/api,当然可以用 ip 直接当根,不过我没配置…
也就是说现在的 api 需要用 ip:端口/api/api/xxxx … 妈耶
所以在 nginx 配置中有这么一行:
proxy_pass http://localhost:89/api/api;
就是用 /api
替换了 http://localhost:89/api/api 。(部署在 tomcat 的后端项目)
至于上面的 add_header 'Access-Control-Allow-Origin' '*';
,是据说 vue 项目必须的,我按照别人说的加了,没有测试过不加会是什么情况。(也许不影响)
其他没什么说的了,再解释下下面这个。
location / {
root /home/hqweay/etob/dist;
index index.html;
}
root 后面是前端代码所在的文件夹(随便放在服务器的哪里都可以,因为是绝对路径嘛…)。index 就是根文件。
springboot + gradle 打 war 包部署到外部容器
有一点没说,因为 spring boot 自带了 tomcat 容器,所以想要部署到外部容器,需要做点改动。
好像不改动也可以,之前我在波波老师的服务器上部署时,就是直接打包 war 放上去…不知道有没有啥副作用…
Ps:这一步是必须的,2018-11-20 遇到了不改动部署,访问 404 的问题。
在 gradle 中默认打包为 jar。
可以把 jar 包放服务器上直接运行,java -jar etob.jar
,不过关闭终端,就断了。
设置打包为 war。
apply plugin: 'war'
把默认的 tomcat 设置为仅仅在生产环境使用。
dependencies {
providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
}
spring-boot 入口实现 SpringBootServletInitializer 接口
导包不提,
@SpringBootApplication
public class ChatroomApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ChatroomApplication.class, args);
}
/**
* 实现SpringBootServletInitializer可以让spring-boot项目在web容器中运行
*/
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(this.getClass());
}
}
ps:不这样貌似也可以,因为我上次…
上一篇: flask工程部署
下一篇: SBT 工程部署记录
推荐阅读
-
详解.net core webapi 前后端开发分离后的配置和部署
-
详解.net core webapi 前后端开发分离后的配置和部署
-
Z从壹开始前后端分离【 .NET Core2.0/3.0 +Vue2.0 】框架之二 || 后端项目搭建
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之七使用JWT生成Token(个人见解)
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之十一Swagger使用一
-
解决vue+springboot前后端分离项目,前端跨域访问sessionID不一致导致的session为null问题
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之十数据库基础方法的封装
-
springBoot 解决前后端分离项目中跨越请求,同源策略
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之九如何进行用户权限控制
-
基于Vue的前后端分离项目实践