spring-boot gradle vue 前後端分離專案在騰訊雲上部署到 tomcat nginx
前言
因為種種原因,把後端部署在 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 直接訪問專案,而不是通過 /專案名 來訪問的話,也可以進行配置。
埠
騰訊雲要開啟埠,首先需要到官網控制檯修改許可權組!!(我直接開啟所有了)
然後設定開啟埠加好了。
處理中遇到一個特別詭異的問題,我在後面搭了 tomcat,nginx 兩個環境,但是不管怎麼搞就只有上午在 tomcat 上弄好的 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 install
編譯後,自動安裝在 /usr/local/nginx
。
也可以先編譯再安裝,速度快點。
make
make install
或
make && make install
缺少依賴的話會報錯,按照錯誤安裝依賴就是了。
安裝依賴
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 命令。
軟連線:In -s /usr/local/nginx/sbin/nginx /etc/bin/nginx
- 啟動
nginx
- 停止
nginx -s stop
- 重啟
nginx -s reload
- 檢視程序
ps -ef | grep nginx
要用,還是得配置防火牆(開放埠)。
配置,修改 /nginx/conf/nginx.comf 檔案(版本: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(代理)。
如下:
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/api,當然可以用 ip 直接當根,不過我沒配置…
也就是說現在的 api 需要用 ip:埠/api/api/xxxx …. 媽耶
所以在 nginx 配置中有這麼一行:
proxy_pass http://localhost:89/api/api;
至於上面的 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 放上去…不知道有沒有啥副作用…
在 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 MyApplication extends SpringBootServletInitializer {
/**
* 實現SpringBootServletInitializer可以讓spring-boot專案在web容器中執行
*/
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
builder.sources(this.getClass());
return super.configure(builder);
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
ps:不這樣貌似也可以,因為我上次….