SpringBoot整合Nginx的全部流程

对Nginx还不了解的同学可以先看这篇文章​​Nginx 相关介绍(Nginx是什么?能干嘛?)​

今天的目标是将SpringBoot项目由默认部署方式(jar)替换成war形式,部署在同一台电脑上的两个不同端口的tomcat上,利用Nginx做反向代理,将请求自由的映射到不同端口的tomcat中。


第一步:将SpringBoot项目由默认部署方式(jar)替换成war形式

(1)设置打包方式为war

    <groupId>com.sun</groupId>
<artifactId>mydata</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!--因为要放入外部的tomcat中,因此更改默认打包方式(jar)为war包-->
<packaging>war</packaging>
<name>mydata</name>
<description>Demo project for Spring Boot</description>

(2)将SpringBoot内置的Tomcat在发布时剔除,provided表示该包只在编译和测试中使用,在发布时去除。而在发布时,此依赖由servlet容器即Tomcat提供。更详细的解释​​Maven依赖Scope选项详解​

PS:不推荐在spring-boot-starter-web直接将tomcat移除,否则需要添加servlet-api依赖。

       <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>

(3)由于SpringBoot项目没有传统的web.xml文件,因此我们需要在缺少web.xml文件的情况下构建war包,需要添加以下配置。

    <plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<!--如果想在没有web.xml文件的情况下构建WAR,请设置为false。-->
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>

(4)更改项目启动类,将之前的启动类删除,新建启动类,继承SpringBootServletInitializer类,重写configure方法,即将启动类交给Servlet容器进行启动。

package com.sun.mydata;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;


@SpringBootApplication
public class TMydataApplication extends SpringBootServletInitializer {

public static void main(String[] args) {
SpringApplication.run(TMydataApplication.class, args);
}

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(TMydataApplication.class);
}
}

(5)使用maven package打包项目,拿到war包。

至此,war包已经打包好了。可以修改前端界面,形成两个不同的war包。

之后需要将war包分别放入不同的Tomcat的webapp中。


第二步:在一台机器上配置两个Tomcat

(1)下载Tomcat8,否则低版本的Tomcat启动时,报出找不到javax/el/ELManager类等错误。

(2)下载的Tomcat复制一份,修改这两个Tomcat的配置。

         1)避免两个Tomcat启动混乱,需要设置不同CATALINA_HOME

具体方式:修改Tomcat安装目录内的bin/startup.bat,添加以下代码中的中间内容

JAVA_HOME是JDK的安装目录,CATALINA_HOME是对应的Tomcat的安装目录,分别对这两个Tomcat进行修改。

setlocal

SET "JAVA_HOME=C:\Java\jdk1.8.0_201"
SET "CATALINA_HOME=D:\tomcat\tomcat2\apache-tomcat-8.5.41"

rem Guess CATALINA_HOME if not defined

          2)修改Tomcat的端口,防止端口冲突。

仅修改第二个Tomcat安装目录下的conf/server.xml,修改Server port="8006"、Connector port="8081"、redirectPort="8444"、Connector port="8010"、redirectPort="8444"。基本上加1就可以,为了防止潜在的端口冲突,都改了保险点。但Connector port="8081"是必须要改的。

          3)设置不加项目名访问,和SpringBoot的访问路径保持一致。

修改Tomcat安装目录下的conf/server.xml,在Host标签下加入该配置。path表示映射后的访问路径,即不需要项目名,docBase表示物理路径,即解压后的war包所处的绝对路径或相对路径。

     <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">

<Context path="/" docBase="D:\tomcat\tomcat2\apache-tomcat-8.5.41\webapps\mydata-0.0.1-SNAPSHOT" reloadable="false"></Context>

</Host>

此时运行Tomcat安装目录下的bin/startup.bat,可以看到项目正常启动了,但启动的控制台界面可能输出乱码,如下图。

【SpringBoot】SpringBoot整合Nginx的全部流程_spring

最简单的修改方式为:修改conf/logging.properties下47行左右的UTF-8为GBK

java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter
java.util.logging.ConsoleHandler.encoding = GBK

再次启动Tomcat,可以看到现在的控制台没有乱码了。

同理,对第二个Tomcat进行以上的配置。

【SpringBoot】SpringBoot整合Nginx的全部流程_SpringBoot_02

测试一下能够访问主界面

【SpringBoot】SpringBoot整合Nginx的全部流程_Tomcat_03

看出来,部署成功了。


最后一步,配置Nginx,这一步相比与之前的配置,简单多了。

(1)修改Nginx安装目录下的conf/nginx.conf,在以下位置设置服务器集群地址。

即添加upstream [name]{...},这个name随便起,不过接下来会用到,需要保持一致。

weight是请求的分配权重,权重越大,对应的Tomcat上接收的请求就越多。

 #keepalive_timeout  0;
keepalive_timeout 65;

#gzip on;

upstream mydata {
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8081 weight=1;
}

server {
listen 80;
server_name localhost;

(2)添加请求转发规则,依然是在nginx.conf中配置。

即通过proxy_pass 配置请求转发地址,访问nginx代理服务器时跳转到指定的服务器。当我们依然输入http://localhost:80 时,请求会跳转到我们配置的服务器。

其中mydata就为之前的name,当我们访问/时,Nginx自动将请求转发至mydata集群中的任意一个Tomcat中。

#charset koi8-r;

#access_log logs/host.access.log main;

location / {
proxy_pass http://mydata;
proxy_redirect default;
}

#error_page 404 /404.html;

更详细的Nginx的配置与说明,参考​​nginx配置集群,以springboot为例​

最后启动Nginx安装目录下的nginx.exe。

在地址栏中输入localhost,即可看到Nginx已经将请求转发至某一个Tomcat中了,不停刷新的话,会出现不同的界面,即分配到不同的Tomcat中(如果界面一直没有变化,可能是浏览缓存造成的,需要在每次的刷新前清除缓存)

第一次点击:

【SpringBoot】SpringBoot整合Nginx的全部流程_SpringBoot_04

第二次点击:

【SpringBoot】SpringBoot整合Nginx的全部流程_spring_05

可见,Nginx已经起到了作用,对整个Tomcat集群做了负载均衡。

到这里,我们就全部配置好了。

关于一致性Session处理,可以单独部署Redis用作Session控制。

更多的架构,可以参考这篇文章​​高并发的解决方案​