在传统单体项目中,一个项目的整体都部署在一台服务器之上,组成这个系统的模块可能包括了 Java 应用程序和 Oracle 数据库 ,可能一些项目会加快系统处理请求的性能还会引入缓存模块,在项目不停迭代的过程中可能会出现分布式架构,将数据库和应用程序模块分别部署到不同几台服务器上,这样单台机器的性能就会得到提升。
应用程序也可能会分拆成为多个模块,部署到多台服务器之上,这时面临一个问题就是如何将外部的请求分发到不同模块服务器之上,这时就需要一种反向代理服务器将请求分发到不同应用服务器之上。 Nginx 就是这样一种能够具备反向代理负载均衡功能软件,它不仅可以作为 Web 服务器来使用,还能作为网关二次开发功能,也能作为静态资源的服务器并且提供一些静态文件缓存功能。
负载均衡
至于怎么安装 Nginx 不是本篇文章的重点,安装可以查看官方的文档 官方 Red Hat/CentOS 软件包,能做负载均衡的功能有很多种方式例如云计算厂商的 DNS 负载均衡服务,我经常使用的是 Ngnix 的负载均衡服务可以配置权重,权重越重的服务器处理的请求会相对比较多,默认是轮询的方式处理。
首先先使用 server
关键字定义虚拟服务器,然后指定 listen
关键字需要监听的流量端口。接着使用 location
块匹配客户端请求的 URL,再用 proxy_set_header
关键字指定 Host 的 HTTP 请求头,最后用 proxy_pass
关键字将请求转发到 upstream
组,upstream
块定义了 NGINX 用来均衡流量的服务器,一个简单配置模板如下:
http {
upstream my_upstream {
server tomcat1.example.com;
server tomcat2.example.com;
}
server {
listen 80;
location / {
proxy_set_header Host $host;
proxy_pass http://my_upstream;
}
}
}
NGINX 还可以针对 TCP 应用程序(如 MySQL)和 UDP 应用程序,如 DNS 和 RADIUS 进行负载均衡,对于 TCP 应用程序,配置模板:
stream {
upstream my_upstream {
server server1.example.com:1234;
server server2.example.com:2345;
}
server {
listen 1123 [udp];
proxy_pass my_upstream;
}
}
目前 Nginx 支持几种负载均衡策略,为 HTTP、TCP 和 UDP 提供多种负载均衡方式,所有这些方式都能够选择分配到每个上游服务器的流量的权重:
- Hash: 根据特定的键值分发请求如客户端 IP 地址或请求 URL 上。
- 最少连接: 向活跃连接数最少的服务器转发请求。
- 最少时间: 基于响应时间和活跃连接数进行综合计算,将请求转发到负载最小的服务器。
- IP Hash: 根据客户端 IP 地址的前三个八位字节进行请求分配。
- Round Robin 轮询: 默认使用可按顺序在上游服务器之间分发请求。
- Random with Two Choices: 随机选择两台服务器并将请求转发到活动连接数较少的服务器。
默认 Nginx 常用也就是加权重版本的负载均衡,默认有还有一些权重 Tag 的策略,配置如下:
upstream tomcat_group {
server 192.168.1.16:8080 down;
server 192.168.1.18:8080 weight=2;
server 192.168.1.13:8080;
server 192.168.1.12:8080 backup;
}
- down: 表示当前的 Web Server 暂时不参与负载。
- weight: 默认为1 Weight 越大,负载的权重就越大。
- backup: 其它所有的非 Backup Server Down 或者忙的时候,请求 Backup 机器,所以这台机器压力会最轻。
静态缓存
在计算机中有很多缓存的设计典型就是 CPU 和 硬盘之间的缓存设计,而对应业务开发人员来说大部分使用都是一些缓存中间件来提高系统性能,这里的缓存最大作用将已经计算过的对象数据通过缓存存储起来,下次有类似的需求的时候直接从缓存中返回而不是从数据库中读取,这样设计为通读缓存能降低数据源的计算压力。这里要介绍的是 Nginx 作为静态文件服务器时,可以做的静态文件缓存功能,因为很多静态文件是不变的一次写入很少修改了,所有如果有缓存功能支持,每次处理请求时就从缓存中返回,这种架构如下:
每当浏览器访问 CSS 、HTML 、JS 静态文件时可以开启 Nginx 的缓存功能,使得这些文件能被缓存,开启这个功能只需要在对应的域名下配置文件加入一些配置项:
nginx
user nginx;
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 100000;
events {
worker_connections 2048;
multi_accept on;
}
http {
sendfile on;
access_log off;
error_log /data/log/nginx-1.8/error.log error;
# 缓存数据目录,Ngnix 不会主动创建需要手动创建
proxy_cache_path /data/nginx-1.8/cache levels=1:2 keys_zone=cache_zone:10m inactive=60m;
server {
listen 80;
server_name localhost;
root /usr/local/services/nginx-1.8/html/;
location / {
}
# 缓存配置
location ~.*\.(gif|jpg|png|css|js)(.*) {
# 设置是否开启对后端响应的缓存,如果开启的话,参数值就是zone的名称
proxy_cache cache_zone;
# 响应状态码为200 302时,10分钟有效
proxy_cache_valid 200 302 10m;
# 缓存过期时间
expires 1d;
add_header X-Proxy-Cache $upstream_cache_status;
}
}
}
配置管理
如果使用的 CentOS 系统默认的 YUM 包管理安装的 Nginx 软件,正常启动之后会有一个提示页面,此页面会帮助服务器管理员来管理 Nginx 软件,配置文件路径和静态文件目录都在页面有提示。
如果无法查看到此页面,可能是默认的服务器防火墙软件阻止 Nginx HTTP 访问端口,使用以下命令来放行端口:
sudo firewall-cmd --zone=public --permanent --add-service=http
另外大部分情况 Linux 服务器从配置完成到服务运行都会产生关机状况,如果有特殊情况关机了,就需要手动启动这些 Nginx 服务,这里可以将 Nginx 设置为开机自启服务:
# 设置开机自启
sudo systemctl enable nginx
# 关闭开机自启
sudo systemctl disable nginx