React+Springboot 的分离项目发布流程(基于Nginx与Tomcat)

一、项目说明

该项目是基于React+SpringBoot的一个分离项目。前端使用UmiJS来构建,使用了Ant Design Pro的组件库。后端是基于SpringBoot框架搭建的Java项目。

二、前端React打包

(一)使用WebStorm打包

  1. 使用 yarn build 命令打包前端项目,然后会在根目录下生成dist文件夹。这就是我们前端的包。如下图所示:
    前端打包示意图

  2. 通过配置config.js去设置hash。详细参考UmiJS官网相关配置
    参考示例
    官网参考

  3. 可以在plugin.config.js覆盖原本的一些打包配置。可以详细参考这个大佬的博文去自定义构建打包配置https://blog.csdn.net/liusaint1992/article/details/83717444
    在这里插入图片描述
    到此为止,前端的打包完成。

三、后端Springboot项目打包

(一)使用IDEA打 .war包

  1. maven的多环境打包构建需要在pom.xml配置一个新的<profile>。配置后,勾选配置,dev举例,根据application-dev.yml配置打包。
  2. 选中test,点击右上方小闪电图标,禁掉test。
  3. 点击clean,删除上一次的target。
  4. 点击package,打包。
    在这里插入图片描述
    在这里插入图片描述

(二)使用命令打多环境配置的包

使用以下命令,根据对应的环境配置文件打包。一步到位

mvnw -Psit clean package  -Dmaven.test.skip=true

在这里插入图片描述
打包成功后,如图,会在target下出来两个发布包。.war包内置了tomcat,可以直接启动。下面的是不带tomcat的,我们需要把这个包放到容器下启动。(本文使用的包为.original
在这里插入图片描述

四、前端包发布Nginx服务器

(一)Linux上安装Nginx

  • 下载解压Nginx
  1. 进入/usr/local文件夹,我们一般把自己安装的应用放在该文件夹中,可以理解为 C:/Progrem Files/。
cd /usr/local
  1. 创建nginx文件夹。
mkdir nginx
  1. 下载nginx安装包,我下载的是1.13.7版本的。
cd nginx
wget http://nginx.org/download/nginx-1.13.7.tar.gz
  1. 下载完成后,解压安装包。
sudo tar -xvf nginx-1.13.7.tar.gz
  • 编译nginx
  1. 进入nginx目录
cd /usr/local/nginx/nginx-1.13.7
  1. 执行命令
./configure
  1. 执行make命令
apt-get install make
make
  1. 执行make install命令
make install
  • 启动测试nginx
  1. 进入nginx启动目录
cd /usr/local/nginx/sbin
  1. 启动nginx
./nginx
  1. 完成后,访问服务器的80端口,查看是否出来Nginx的欢迎界面。

  2. 附注一张安装目录结构示意图
    nginx目录结构示意图

(二)修改nginx.config

根据下图,配置项目端口与ip地址,

server {
        listen       80;
        server_name  localhost 192.168.0.100;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            # 配置前台包文件的路径
            root   html/dist; 
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
            proxy_read_timeout 1200; 
        }
        # 配置反向代理
        location /api/ {
           proxy_redirect off;
           proxy_set_header Host $host:$server_port;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_pass http://192.168.0.100:8080/newcomp/api/;  
           index  index.html index.htm;
           proxy_read_timeout 1200;
           client_max_body_size    100m;

        }
        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }

配置完成后,进入sbin目录下,重启nginx服务。

cd /usr/local/sbin
./nginx -s reload

可以使用以下命令,查询nginx进程,如图示:

ps -ef|grep nginx

在这里插入图片描述

(三)使用工具filezilla上传打包文件

使用文件传输工具,将我们本地打好的前端dist包上传至nginx的html文件夹下,nginx会自动热部署相应的文件。
在这里插入图片描述

五、后端包发布Tomcat服务器

(一)Linux安装JDK1.8

  1. oracle官网下载压缩包https://www.oracle.com/java/technologies/javase-jdk8-downloads.html
  2. 将压缩包放在/usr/local/java下,解压
    在这里插入图片描述
tar -zxvf jdk-8u231-linux-x64.tar.gz
  1. 设置环境变量
vim /etc/profile

在文件末尾加入

 export JAVA_HOME=/usr/local/java/jdk1.8.0_231
 export JRE_HOME=${JAVA_HOME}/jre
 export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
 export PATH=.:${JAVA_HOME}/bin:$PATH

如果显示无法保存修改命令(说明该文件只有读权限,所以要添加写权限,或者用root权限改)

sudo vim /etc/profile 
  1. 使配置生效
source /etc/profile 
  1. 检查是否生效
java -version

在这里插入图片描述

(二)Linux上安装Tomcat

  1. 进入官网,选择你需要的tomcat版本,下载对应的tar.gz版本。
    在这里插入图片描述
  2. 下载完成后,登录你的Linux系统,通过命令行,输入rz,打开文件传输窗口,将你本地的Tomcat安装包上传至你的/usr/local 目录下。也可以通过工具上传,亦可以直接在Linux上使用wget命令下载。
cd /usr/local
ll
rz

打开如下:
在这里插入图片描述

  1. 解压
sudo tar -zxvf apache-tomcat-8.5.47.tar.gz

解压后
在这里插入图片描述
安装完毕。

(三)修改server.xml、startup.sh等配置文件

  • server.xml
    这个配置文件,如果不需要自定义配置的话,可以不修改,只要将发布包放在webapps下,就能解析到8080端口。
    但是我们在服务器上,可能存在多个Tomcat容器,所以,简单介绍下该server.xml的一些自定义配置。
<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!-- Note:  A "Server" is not itself a "Container", so you may not
     define subcomponents such as "Valves" at this level.
     Documentation at /docs/config/server.html
 -->
<!-- 8005 为当执行shutdown.sh关闭tomcat时就是连接8005端口执行“SHUTDOWN”命令,多个tomcat同时启动时,需要自行修改-->
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <!-- A "Service" is a collection of one or more "Connectors" that share
       a single "Container" Note:  A "Service" is not itself a "Container",
       so you may not define subcomponents such as "Valves" at this level.
       Documentation at /docs/config/service.html
   -->
  <Service name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
    -->


    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->
    <!-- 8080 不用说,http监听端口;8443是https的监听端口 -->
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->
    <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443
         This connector uses the NIO implementation. The default
         SSLImplementation will depend on the presence of the APR/native
         library and the useOpenSSL attribute of the
         AprLifecycleListener.
         Either JSSE or OpenSSL style configuration may be used regardless of
         the SSLImplementation selected. JSSE style configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
        <SSLHostConfig>
            <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->
    <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
         This connector uses the APR/native implementation which always uses
         OpenSSL for TLS.
         Either JSSE or OpenSSL style configuration may be used. OpenSSL style
         configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                         certificateFile="conf/localhost-rsa-cert.pem"
                         certificateChainFile="conf/localhost-rsa-chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <!-- 8009--httpd等反向代理tomcat时就可以使用使用ajp协议反向代理到该端口。虽然我们经常都是使用http反向代理到8080端口,但由于ajp建立tcp连接后一般长时间保持,从而减少了http反复进行tcp连接和断开的开销,所以反向代理中ajp是比http高效的。 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />


    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->
    <Engine name="Catalina" defaultHost="localhost">

      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true"
            xmlValidation="false" xmlNamespaceAware="false"
            >
          <!-- 这个可以配置项目启动后访问路径,就不要加项目名称就能访问了-->
         <!-- <Context path="" docBase ="/newcomp/"/> -->
        
        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

      </Host>
    </Engine>
  </Service>
</Server>

  • startup.sh
    要想使用 ./startup 命令启动项目,需要在 /bin 目录下修改该启动文件。在末尾添加如下内容,需要对应之前我们的各种配置路径。
#set java environment
export JAVA_HOME=/usr/java/jdk1.8.0_231
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:%{JAVA_HOME}/lib:%{JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

#tomcat
export TOMCAT_HOME=/usr/local/apache-tomcat-8.5.47

exec "$PRGDIR"/"$EXECUTABLE" start "$@"
  • shutdown.sh
    同理
#set java environment
export JAVA_HOME=/usr/java/jdk1.8.0_231
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:%{JAVA_HOME}/lib:%{JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

#tomcat
export TOMCAT_HOME=/usr/local/apache-tomcat-8.5.47

exec "$PRGDIR"/"$EXECUTABLE" stop "$@"

在使用./shutdown.sh可能会出现,停止服务了,但是查询该tomcat进程还是存在的情况。我们可以使用kill 命令将该tomcat进程手动杀掉。但是总归不方便,我们下面还会继续说明这个问题。

(四)启动Tomcat

进入bin 目录下,使用命令 ./startup.sh 启动Tomcat。
访问http://IP地址:8080 查看Tomcat能否正常显示初始化页面。

(五)发布后台

将我们之前打的original包,上传至tomcat下的webapps目录下,修改名称,去掉后缀。(在测试Tomcat能否正常工作后,将之前webapps下,默认的文件都删除)重新启动Tomcat就可以了。

六、编写shell脚本,简化发布流程

以上讲解了我们打包发布的场景。但是命令太多,操作繁琐。那么我们可以写一个shell脚本,来简化我们的后续发布流程。
我们一般会把我们自定义的脚本,放在/usr/local/sbin目录下,方便我们以及他人统一管理脚本文件。
我们只需要把我们的前后台包,传到指定的位置,修改好对应的名称,然后执行一下我们编写的shell脚本,就可以完成发布了。

大家可以参考:

#! /bin/bash

## author:qiuyu
## 2020-10-26
## dev apache-tomcat-8.5.47测试发布 shell


date
echo 'Redeploy 192.168.0.100:8081'

## 前端文件,热部署
rm -rf /usr/local/nginx/html/dist
cp -r /home/sinosoft/fbb/newcompqiantai/dist /usr/local/nginx/html
echo 'Nginx hot-loading successful'

## 后台
sh /usr/local/apache-tomcat-8.5.47/bin/shutdown.sh
cp /home/sinosoft/fbb/newcomphoutai/newcomp.war /usr/local/apache-tomcat-8.5.47/webapps/
sh /usr/local/apache-tomcat-8.5.47/bin/startup.sh
echo 'Tomcat run successful'
echo 'Please view log ---> tail -f /usr/local/apache-tomcat-8.5.47/logs/catalina.out'

编写好我们的shell脚本后,后缀名称为.sh.通过chmod +x 脚本名称.sh 命令添加脚本的执行权限。对了,大家最好要在linux环境下编写脚本。本人在windows下编写好上传后,执行时出现问题,后来发现是windows系统和linux系统下的空格是不一样的,这就很尴尬。。。

上面存留了一个问题,Tomcat下bin的./shutdown.sh命令出现Tomcat进程杀不掉的情况,通过ps -ef|grep tomcat 查询仍然可以看到进程存在。我们可以通过如下步骤去解决:

  1. vim修改tomcat下bin/catalina.sh文件,添加点东西,主要是在启动时,记录tomcat启动的pid,如下:

#设置记录CATALINA_PID。
#该设置会在启动时候bin下新建一个CATALINA_PID文件
#关闭时候从CATALINA_PID文件找到pid,kill。。。同时删除 CATALINA_PID文件

在 PRGDIR=dirname "$PRG" 后面加上(大概文件第139行左右):

if [ -z "$CATALINA_PID" ]; then
    CATALINA_PID=$PRGDIR/CATALINA_PID
    cat $CATALINA_PID
fi
  1. vim tomcat的shutdown.sh文件,在最后一行加上 -force:
exec "$PRGDIR"/"$EXECUTABLE" stop -force  "$@"

然后再使用shutdown.sh脚本时,就能把tomcat进程也杀掉了。

本文只是个人在学习时总结的一些东西,涉及纰漏,还望指出。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨雨雨就要爆炸了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值