当我们想要提高后端服务器的并发性能,可以通过分配更多的资源给 Tomcat 服务器,但是这只能提高一部分的性能。因为每台 Tomcat 的服务器是有最大连接数为 200.所以即可拥有无穷无尽的内存,也会因为单台 Tomcat 的原因而无法发挥这些资源的最大价值。
所以我们就使用多台 Tomcat 来解决这个问题。然后使用 Nginx 负载均衡来将请求转发到后端服务器。
首先你得先有 Nginx 的安装包,这里我就不演示这个下载安装的过程了。你可以在这个页面选择你想要下载的 nginx 版本:nginx: download
然后就是对我们的代码进行打包,我们的项目是 Maven 项目,所以打包起来会很简单,并且是 SpringBoot 项目,所以打包结果就是 jar 包,可以在 Windows 的控制台中使用 java -jar xx.jar
来启动项目即可,因为 SpringBoot 项目在打包时会将 Tomcat 服务器也打包进去。
普通的 Java 项目则是打包成 war 包,然后放在 Tomcat 的 webapps 目录下来部署的。
1. 打包项目
这里示例项目是 SpringBoot 项目,所以部署起来非常的简单。
首先在 Maven 的生命周期中选择 package
,它会生成一个 target 目录,然后你可以直接使用 java -jar xxx.jar
来运行这个 jar 包。
比如这个项目的端口是 9090,由于我们的服务器都是在本地搭建的,所以我们会设置不同的端口,比如端口设置为 9090
,9091
这两个端口。
不过使用 java -jar xxx.jar
你可能会遇到下面的这个问题,因为我们 IDEA 中的 JDK 版本与环境变量中的 JDK 版本可能会不一样,下面的这个就是 IDEA 使用的是 Java 11,然后环境变量中的使用的是 Java 8。总的来说就是环境变量的 JDK 版本太低了,使用 Java 11 为妥。
下面的是报错信息:
org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class [com.example.dao.UserDAO] for bean with name ‘userDAO’ defined in URL [jar:file:/E:/tomcat-cluster/apis-1.0.0.jar!/BOOT-INF/lib/mapper-1.0.0.jar!/com/example/dao/UserDAO.class]: problem with class file or dependent class; nested exception is java.lang.UnsupportedClassVersionError: com/example/dao/UserDAO has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
这个的意思是说当前电脑的 Java 版本太低(52.0 -> Java8,55.0 -> Java11),电脑中的 Java 为版本 8。
如果还有其他的报错就自行解决吧,比如常见的端口被占异常。
2. Nginx 负载均衡
在启动了 Tomcat 服务器之后,我们需要在 Nginx 的配置文件进行配置。
配置如下:
http {upstream tomcat {server localhost:9090;server localhost:9091;}server {listen 8080location / {proxy_pass http://tomcat;}}
}
配置完成之后,然后双击 nginx.exe
就可以了。当然以上是一些基本的配置。
最后我们在本地浏览器访问 localhost:8080
就可以了,nginx 会将请求分配到两个 Tomcat 的其中一个。这个我们不需要关心。
3. Nginx 负载均衡策略
Nginx 常见的负载均衡有四种,当然还有第三方的负载均衡策略,这里我们就只介绍 Nginx 自带的均衡策略。
- 轮询(默认使用)
- weight(权重)
- ip_hash(客户端 IP 哈希)
- least_conn(最少连接)
3.1. 轮询
这是 Nginx 默认的负载均衡策略,通常我们也不会去设置其他的负载均衡策略,因为这些设置主要由业务场景来决定。
轮询就是将客户端的请求依次发送给后端服务器,比如下面的配置就是 9090 和 9091 交替处理请求。
upstream tomcat {server localhost:9090;server localhost:9091;
}
它还有其他的参数,这里也介绍一下:
- max_fails:设置服务器在
fail_timeout
时间内的最大失败次数,如果向该服务器发送的请求在fail_timeout
时间内失败了三次,就将该服务器设置为已宕机,最大宕机时间则需要设置fail_time
参数。 - fail_timeout:失败超时时间,与
fail_fails
一起使用。 - fail_time:服务器最大宕机时长,默认为 10s,
fail_time
之后 nginx 会去确认服务器是否可用。 - backup:该参数代表该服务器为备用机,当主服务器宕机时,备用机就会接收请求。
- down:该参数设置服务器为永久宕机。
比如下面的配置,
upstream tomcat {# fail_timeout 时间内最大失败次数为 3,最大宕机时长为 100sserver localhost:9090 max_fails=3 fail_timeout=20 fail_time=100;server localhost:9091 backup;server localhostL9092 down;
}
3.2. weight(权重)
这种设置方式主要是根据服务器的资源多少来具体地分配请求,需要手动指定。
upstream tomcat {server localhost:9090;# 权重为 2,将会收到更多的请求,按照轮询来讲就是 1:2:1 的分配server localhost:9091 weight=2;server localhostL9092;
}
- 权重默认值为 1,权重数字越大被分配到的请求也会越多。
- 可以结合
轮询
、ip_hash
和least_conn
来使用。
3.3. ip_hash(客户端 IP 哈希)
根据客户端 IP 的哈希值来转发请求。这样可以保证一个客户端只会请求一台服务器,可以保证 session 的一致性。
upstream tomcat {# 加上这一个配置即可,非常简单!ip_hash;server localhost:9090;server localhost:9091;server localhostL9092;
}
3.4. least_conn(最少连接)
当请求处理时间不一导致有些服务器处于繁忙、有些处于空闲时,使用该配置可以更好地解决这个问题。它会根据服务器正在处理请求的数量来分配请求,将请求分配给那些比较空闲的服务器。
upstream tomcat {# 加上这一个配置即可,非常简单!least_conn;server localhost:9090;server localhost:9091;server localhostL9092;
}