Nginx+Tomcat实现Web服务器的负载均衡

预备

先说一下什么是负载均衡?

负载均衡(Load Balance)其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
负载均衡构建在原有网络结构之上,它提供了一种透明且廉价有效的方法扩展服务器和网络设备的带宽、加强网络数据处理能力、增加吞吐量、提高网络的可用性和灵活性。1

从其定义上看,要搭建负载均衡,是要组网的,只‘一台电脑’(操作单元)是不行滴。

什么是Nginx?

Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。2

说到Nginx,再提一下另一款更加常见的Web服务器–Apache3,两者对比看一下

-NginxApache
1轻量级,采用 C 进行编写,同样的 web 服务,会占用更少的内存及资源apache 的 rewrite 比 nginx 强大,在 rewrite 频繁的情况下,用 apache
2抗并发,nginx 以 epoll and kqueue 作为开发模型,处理请求是异步非阻塞的,负载能力比 apache 高很多,而 apache 则是阻塞型的。在高并发下 nginx 能保持低资源低消耗高性能 ,而 apache 在 PHP 处理慢或者前端压力很大的情况下,很容易出现进程数飙升,从而拒绝服务的现象。apache 发展到现在,模块超多,基本想到的都可以找到
3nginx 处理静态文件好,静态处理性能比 apache 高三倍以上apache 更为成熟,少 bug ,nginx 的 bug 相对较多
4nginx 的设计高度模块化,编写模块相对简单apache 超稳定
5nginx 配置简洁,正则配置让很多事情变得简单,而且改完配置能使用 -t 测试配置有没有问题,apache 配置复杂 ,重启的时候发现配置出错了,会很崩溃apache 对 PHP 支持比较简单,nginx 需要配合其他后端用
6nginx 作为负载均衡服务器,支持 7 层负载均衡apache 在处理动态请求有优势,nginx 在这方面是鸡肋,一般动态请求要 apache 去做,nginx 适合静态和反向。
7nginx 本身就是一个反向代理服务器,而且可以作为非常优秀的邮件代理服务器apache 仍然是目前的主流,拥有丰富的特性,成熟的技术和开发社区
8启动特别容易, 并且几乎可以做到 7*24 不间断运行,即使运行数个月也不需要重新启动,还能够不间断服务的情况下进行软件版本的升级-
9社区活跃,各种高性能模块出品迅速-

两者最核心的区别在于 apache 是同步多进程模型,一个连接对应一个进程,而 nginx 是异步的,多个连接(万级别)可以对应一个进程。一般来说,Nginx 适合处理静态请求和反向代理,Apache 适合处理动态请求。

正向代理和逆向代理

正向代理,意思是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。4
逆向代理,通常被称做反向代理(Reverse Proxy),服务器根据客户端的请求,从其关联的一组或多组后端服务器(如Web服务器)上获取资源,然后再将这些资源返回给客户端,客户端只会得知反向代理的IP地址,而不知道在代理服务器后面的服务器簇的存在。5

这两者的意思差别还是很明显的,正向代理是,我要去访问一个服务器,可能是由某些原因吧,我虽然知道有这么个服务器存在但是我无法直接去访问,所以我只能去请求另外一个服务器(代理),帮我去访问我要访问的服务器获取内容并返回给我,我作为一个客户端,我是知道我要访问的真正的服务器的。而逆向代理是,我(客户端)要请求远程服务器内容,这个远程服务器虽然也能给你想要的数据,但是呢,这个服务器实际上他也没有真正的内容给你,他也是从别的地方(其他的服务器)去拿数据给你,这个过程对客户端来说,是不透明的,客户端不知道你是自己就能直接提供数据还是你是去别的地方拿的数据给我。
举个通俗的例子就是,正向代理,是你要访问谷歌网站,在国内,不好意思你被‘墙’了,访问不到,但是,如果你有台在新加坡的阿里云服务器或者你有台在香港的华为云服务器的话,你搭个代理你就可以成功越墙了!而逆向代理,就是下面我们要做的。

用Nginx搭建负载均衡服务器

正常情况你需要准备如下配置:

服务器名称系统软件网络
Nginxcentos7Nginx192.168.0.5
Tomcat Acentos7tomcat、jdk10.50.200.66:8091
Tomcat Bcentos7tomcat、jdk10.50.200.66:8092

我这里没这么多资源,就用docker在一台服务器上模拟这3台虚拟机,实现一个简单的反向代理和负载均衡服务。
在这里插入图片描述

首先拉取nginx和tomcat的镜像

# docker pull nginx
# docker pull tomcat:8.5
[root@master ~]# docker images
REPOSITORY   TAG         IMAGE ID         CREATED        SIZE
tomcat       8.5         96c4e536d0eb     11 days ago    506MB
nginx        latest      5a3221f0137b     2 weeks ago    126MB

这里nginx用最新的,tomcat用8.5版本的,全部拉取官方的

启动Nginx

docker run -d -p 11180:80 nginx
[root@master nginx]# docker ps
CONTAINER ID  IMAGE  COMMAND                  CREATED          STATUS         PORTS                   NAMES
ffaf961f636d  nginx  "nginx -g 'daemon of…"   10 seconds ago   Up 8 seconds   0.0.0.0:11180->80/tcp   nginx

这里nginx的默认端口是80,我这里服务器80被使用了,所有映射到了11180端口

ok,这样nginx就部署好了,可以访问看看 : ip:11180
nginx
感慨一下docker的伟大!

启动tomcat

# docker run -d -p 8091:8080 tomcat:8.5
# docker run -d -p 8092:8080 tomcat:8.5

因为是在一台服务器上,所以tomcat用docker模拟两台,也是用端口来区分的,分别用 8091和8092,如下:
TomcatA
TomcatB

[root@master nginx]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS          PORTS                     NAMES
64b298e41e38   tomcat:8.5    "catalina.sh run"        4 seconds ago    Up 3 seconds    0.0.0.0:8092->8080/tcp    tomcatB
20573cd3ae78   tomcat:8.5    "catalina.sh run"        35 seconds ago   Up 33 seconds   0.0.0.0:8091->8080/tcp    tomcatA
e70a5b3eb4f5   nginx         "nginx -g 'daemon of…"   15 minutes ago   Up 14 minutes   0.0.0.0:11180->80/tcp     nginx

准备你的应用

将自己的一个应用分别放到两台tomcat服务器应用下。然后刷新地址,如下
在这里插入图片描述
在这里插入图片描述
注意两台tomcat上的应用完全一样的。

配置Nginx逆向代理这两台tomcat

用默认的nginx配置启动的话,会发现无法修改nginx的配置文件,因为进入容器里面无法使用vi或vim命令,实际上可以把nginx的配置文件映射的本地路径下在修改,具体操作可看我以前博客,或自己百度。
这里我只给配置:

# nginx配置
user  nginx;
# 工作进程个数,一般跟服务器cpu核数相等,或者核数的两倍;
# 但是我这里只配置两个,因为我这服务器还有其他应用就不配那么多了
worker_processes  2;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

# 单个进程最大连接数
events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    gzip  on;

    # #服务器集群
    upstream mycluster{
        # 集群有几台服务器即可配置几台,weight表示权重,权重越大被访问到的几率越大
        # 这里添加的是上面启动好的两台Tomcat服务器
        server 10.50.200.66:8091 weight=1;
        server 10.50.200.66:8092 weight=1;
    }

    include /etc/nginx/conf.d/*.conf;
}
server {
    listen       80;
    server_name  localhost;

    location / {
        # 将访问请求转向至服务器集群,mycluster和http中upstream mycluster 对应
        proxy_pass http://mycluster;
    }

    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   /usr/share/nginx/html;
    }
}

现在访问一下nginx页面,就可以了
在这里插入图片描述
另外为了测试是否配置的两台tomcat轮流调用,可以改改自己的应用,比如说标题,多刷新几次就能发现配置是生效的,这里我就不截图了!

补充,关于Nginx一些配置的说明

nginx的版本不一样,一些配置文件也不太一样,但无非也是一些文件名或者文件配置路径不同,上面的配置是nginx版本

root@132b54e8bf0f:/# nginx -v
nginx version: nginx/1.17.3

它的配置文件分成了两部分,分别位于

/etc/nginx/nginx.conf
/etc/nginx/conf.d/default.conf

我们需要使用的主要配置属性如下:

  • main:用于进行nginx全局信息的配置
  • events:用于nginx工作模式的配置
  • http:用于进行http协议信息的一些配置
  • server:用于进行服务器访问信息的配置
  • location:用于进行访问路由的配置
  • upstream:用于进行负载均衡的配置

这里着重介绍upstream负载均衡都有那些配置

方式举例说明
轮询upstream mycluster {
server 192.168.1.10;
server 192.168.1.11;
}
这是默认方式,当weight不指定时,各服务器weight相同,
每个请求按时间顺序逐一分配到不同的后端服务器,
如果后端服务器down掉,能自动剔除。
weightupstream mycluster {
server 192.168.1.10 weight=1;
server 192.168.1.11 weight=2;
}
轮询,weight和访问比率成正比,用于后端服务器性能不均的情况。
如果后端服务器down掉,能自动剔除。比如以下配置,
则1.11服务器的访问量为1.10服务器的两倍。
ip_hashupstream mycluster {
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,
可以解决session不能跨服务器的问题。
如果后端服务器down掉,要手工down掉。
fairupstream mycluster {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
fair;
}
按后端服务器的响应时间来分配请求,
响应时间短的优先分配。(第三方插件)
url_hashupstream mycluster {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
hash $request_uri;
hash_method crc32;
}
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,
后端服务器为缓存服务器时比较有效。
在upstream中加入hash语句,hash_method是使用的hash算法。
(第三方插件)

上表总共介绍了5中负载均衡的配置,默认情况下是按照服务器轮询,可以添加权重轮询,权重越大轮询次数就越多,适合服务器性能不同的场景,性能好就设置权重大一点儿;使用ip_hash有一个好处就是你的web应用不用专门解决session一致性问题了,能解决负载均衡,但是跟系统高可用就不行了,一旦某台服务器宕机了,那么对应的登录用户都访问不到了;后两种配置都需要借助第三方插件实现,fair的公平性更好,设置权重只是针对服务器性能设置的,但是有个现实问题是假设A用户在北京,服务器在广州和上海,广州的服务器比上海好很多,但是网络环境上海要比广州好很多,那么采用fair要比采用weight更加靠谱些;最后url_hash优势已经说了就是访问缓存服务器非常好!

再说一下,负载均衡配置的其他属性:

  • down 在负载服务器后面跟 down参数,说明,此时这台服务器不参与负载
  • weight 权重,默认是1,值越大表示权重越大,那么这台服务区被负载的也越大
  • backup 备用服务器,其它所有的非backup机器down或者忙的时候,请求backup机器。这台机器压力会最轻。
  • max_fails 允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误
  • fail_timeout max_fails次失败后,暂停的时间,默认为10s。
    举个例子:
upstream mycluster {
	# ip_hash;
	server 192.168.0.5:8080;
	server 192.168.0.6:8080 weight=10 down;
	server 192.168.0.7:8080 weight=10;
	server 192.168.0.8:8080 weight=10 backup;
	server 192.168.0.9:8080 weight=10 max_fails=3 fail_timeout=60s;
} 

上面配置了5台服务器,其中192.168.0.6是不参与负载的;192.168.0.8是作为备用服务器,通常情况也不会使用;192.168.0.7192.168.0.9这两台服务器权重是10,是192.168.0.5的10倍,同时服务器192.168.0.9的最大失败次数是3,超时时间1分钟;其他服务器都是最多尝试1次,超时10秒;
另外注意:当upstream配置中ip_hash不能同时和weight/backup参数一起使用!

好了,以上就是Nginx反向代理和负载均衡配置。很简单吧!



  1. 百度百科-负载均衡 ↩︎

  2. 百度百科-Nginx ↩︎

  3. 百度百科-Apache HTTP Server(简称Apache) ↩︎

  4. 百度百科-正向代理 ↩︎

  5. 百度百科-反向代理 ↩︎

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 鲸 设计师:meimeiellie 返回首页