【51CTO.com原稿】本文首先介绍Nginx的反向代理、负载均衡、动静分离、高可用等原理,然后解读Nginx的配置文件,带你从原理到实战31段均衡器软件教程,彻底了解Nginx!
图片来自 Pexels
Nginx 是一个开源的轻量级 Web 服务器、反向代理服务器、负载均衡器和 HTTP 缓存。 其特点是高并发、高性能、低显存。
Nginx 是专门为性能优化而开发的。 性能是其最重要的考虑因素。 它在实现上非常注重效率,能够承受高负载的考验,最大可以支持5万个并发连接。
Nginx还支持热部署。 它非常容易使用,几乎可以7x24小时不间断运行。 Nginx的网站用户包括:百度、淘宝、京东、腾讯、新浪、网易等。
反向代理
①转发代理
Nginx除了作为反向代理实现负载均衡之外,还可以作为正向代理上网。
②反向代理
客户端不知道代理服务器,客户端不需要做任何配置,用户只需向反向代理服务器请求,反向代理服务器选择目标服务器,获取数据并返回给客户端。
反向代理服务器和目标服务器对外是同一台服务器,只暴露代理服务器的地址,隐藏真实服务器的IP地址。
负载均衡
不要将原始请求集中在一台服务器上,而是减少服务器数量,然后将请求分发到每台服务器上,将负载分配到不同的服务器上,即负载均衡。
静动分离
为了提高网站的解析率,静态页面和动态页面可以由不同的服务器进行解析,以提高解析率,减轻原有单一服务器的压力。
高可用性
为了提高系统的可用性和容错能力,可以减少Nginx服务器的数量。 当主服务器发生故障或宕机时,备份服务器可以立即充当主服务器不间断工作。
Nginx 配置文件
①文件结构
... #全局块
events { #events块
...
}
http #http块
{
... #http全局块
server #server块
{
... #server全局块
location [PATTERN] #location块
{
...
}
location [PATTERN]
{
...
}
}
server
{
...
}
... #http全局块
}
Nginx配置文件由三部分组成:
②配置文件
########### 每个指令必须有分号结束。#################
#user administrator administrators; #配置用户或者组,默认为nobody nobody。
#worker_processes 2; #允许生成的进程数,默认为1
#pid /nginx/pid/nginx.pid; #指定nginx进程运行文件存放地址
error_log log/error.log debug; #制定日志路径,级别。这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg
events {
accept_mutex on; #设置网路连接序列化,防止惊群现象发生,默认为on
multi_accept on; #设置一个进程是否同时接受多个网络连接,默认为off
#use epoll; #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
worker_connections 1024; #最大连接数,默认为512
}
http {
include mime.types; #文件扩展名与文件类型映射表
default_type application/octet-stream; #默认文件类型,默认为text/plain
#access_log off; #取消服务日志
log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
access_log log/access.log myFormat; #combined为日志格式的默认值
sendfile on; #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
sendfile_max_chunk 100k; #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
keepalive_timeout 65; #连接超时时间,默认为75s,可以在http,server,location块。
upstream mysvr {
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup; #热备
}
error_page 404 https://www.baidu.com; #错误页
server {
keepalive_requests 120; #单连接请求上限次数。
listen 4545; #监听端口
server_name 127.0.0.1; #监听地址
location ~*^.+$ { #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
#root path; #根目录
#index vv.txt; #设置默认页
proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表
deny 127.0.0.1; #拒绝的ip
allow 172.18.5.54; #允许的ip
}
}
}
配置示例
接下来通过配置Nginx配置文件,实现正向代理、反向代理、负载均衡、Nginx缓存、动静分离、高可用Nginx的六大功能,并进一步分析Nginx的原理。 当需要使用Nginx配置文件时,参考本文示例即可,建议保存。
①转发代理
正向代理的代理对象是客户端。 正向代理是指代理服务器为客户端访问目标服务器。
实现效果:在浏览器中输入,浏览器跳转到。
具体配置:
server{
resolver 8.8.8.8;
listen 80;
location / {
proxy_pass http://$http_host$request_uri;
}
}
在需要访问内网的客户端上执行以下操作之一:
1. 方法1(推荐)
export http_proxy=http://你的正向代理服务器地址:代理端口
2. 方法2
vim ~/.bashrc
export http_proxy=http://你的正向代理服务器地址:代理端口
②反向代理
反向代理是指中间服务器充当前端服务器响应客户端请求的代理,代理的对象是服务器。
实现效果:在浏览器中输入,从Nginx服务器跳转到Linux系统的Tomcat主页。
具体配置:
server {
listen 80;
server_name 192.168.4.32; #监听地址
location / {
root html; #/html目录
proxy_pass http://127.0.0.1:8080; #请求转向
index index.html index.htm; #设置默认页
}
}
实现效果:根据浏览器输入的不同路径,跳转到不同端口的服务。
具体配置:
server {
listen 9000;
server_name 192.168.4.32; #监听地址
location ~ /example1/ {
proxy_pass http://127.0.0.1:5000;
}
location ~ /example2/ {
proxy_pass http://127.0.0.1:8080;
}
}
定位命令说明:
③负载均衡
实现效果:在浏览器地址栏中输入,平均到5000和8080端口,实现负载均衡效果。
具体配置:
upstream myserver {
server 192.167.4.32:5000;
server 192.168.4.32:8080;
}
server {
listen 80; #监听端口
server_name 192.168.4.32; #监听地址
location / {
root html; #html目录
index index.html index.htm; #设置默认页
proxy_pass http://myserver; #请求转向 myserver 定义的服务器列表
}
}
Nginx分发服务器策略:
协程(默认):按照时间顺序一一分配请求。 如果服务器宕机,可以手动删除。
权重:权重越高,分配的客户端越多,默认为1。
例如:
upstream myserver {
server 192.167.4.32:5000 weight=10;
server 192.168.4.32:8080 weight=5;
}
IP:根据请求IP的Hash值分配,每个访问者定时访问一个前端服务器。
例如:
upstream myserver {
ip_hash;
server 192.167.4.32:5000;
server 192.168.4.32:8080;
}
公平:根据前端服务器的响应时间进行分配,响应时间短的优先分配给请求。
例如:
upstream myserver {
fair;
server 192.168.4.32:5000;
server 192.168.4.32:8080;
}
④ Nginx 缓存
实现效果:3天内,通过浏览器地址栏访问不会从服务器抓取资源,3天后(过期)重新从服务器下载。
具体配置:
# http 区域下添加缓存区配置
proxy_cache_path /tmp/nginx_proxy_cache levels=1 keys_zone=cache_one:512m inactive=60s max_size=1000m;
# server 区域下添加缓存配置
location ~ \.(gif|jpg|png|htm|html|css|js)(.*) {
proxy_pass http://192.168.4.32:5000;#如果没有缓存则转向请求
proxy_redirect off;
proxy_cache cache_one;
proxy_cache_valid 200 1h; #对不同的 HTTP 状态码设置不同的缓存时间
proxy_cache_valid 500 1d;
proxy_cache_valid any 1m;
expires 3d;
}
Expires是给资源设置一个过期时间。 通过设置Expires参数,浏览器可以缓存过期时间之前的内容,减少服务器与服务器之间的请求和流量。
也就是说不需要去服务器验证,可以直接通过浏览器本身确认是否过期,因此不会产生额外的流量。 这种方法非常适合不经常变化的资源。
⑤动静分离
实现效果:通过浏览器地址栏访问静态资源服务器的静态资源内容。
通过浏览器地址栏访问动态资源服务器的动态资源内容。
具体配置:
upstream static {
server 192.167.4.31:80;
}
upstream dynamic {
server 192.167.4.32:8080;
}
server {
listen 80; #监听端口
server_name www.abc.com; 监听地址
# 拦截动态资源
location ~ .*\.(php|jsp)$ {
proxy_pass http://dynamic;
}
# 拦截静态资源
location ~ .*\.(jpg|png|htm|html|css|js)$ {
root /data/; #html目录
proxy_pass http://static;
autoindex on;; #自动打开文件列表
}
}
⑥高可用性
通常,后台目标服务集群是通过Nginx主服务器访问的。 当主服务器挂掉后,手动切换到备份服务器。 此时备份服务器作为主服务器,访问前端目标服务器。
实现效果:规划两台Nginx服务器,通过浏览器地址栏访问虚拟IP地址,停止主服务器的Nginx,再次访问虚拟IP地址仍然有效。
具体配置:
# 安装 keepalived
yum install keepalived -y
# 检查版本
rpm -q -a keepalived
keepalived-1.3.5-16.el7.x86_64
1、在两台Nginx服务器上安装Keepalived:Keepalived相当于一个路由。 它使用脚本来测量当前服务器是否还活着。 如果还活着,则继续访问,否则切换到另一台备份服务器。
2、修改主备服务器的/etc/keepalived/keepalivec.conf配置文件(可直接替换),完成高可用主从配置。
Keepalived将Nginx服务器绑定到一个虚拟IP,Nginx高可用集群将这个虚拟IP暴露给外界。 客户端通过访问这个虚拟IP来访问Nginx服务器。
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from_Alexandre.Cassen@firewall.loc
smtp_server 192.168.4.32
smtp_connect_timeout 30
router_id LVS_DEVEL # 在 /etc/hosts 文件中配置,通过它能访问到我们的主机
}
vrrp_script_chk_http_port {
script "/usr/local/src/nginx_check.sh"
interval 2 # 检测脚本执行的时间间隔
weight 2 # 权重每次加2
}
vrrp_instance VI_1 {
interface ens7f0 # 网卡,需根据情况修改
state MASTER # 备份服务器上将 MASTER 改为 BACKUP
virtual_router_id 51 # 主备机的 virtual_router_id 必须相同
priority 100 # 主备机取不同的优先级,主机值较大,备份机值较小
advert_int 1 # 每隔多长时间(默认1s)发送一次心跳,检测服务器是否还活着
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.100 # VRRP H 虚拟地址,可以绑定多个
}
}
数组说明如下:
router_id:在/etc/hosts文件中配置,通过它我们可以访问我们的主机。
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
127.0.0.1 LVS_DEVEL
间隔:设置脚本执行的间隔时间。
Weight:当脚本执行失败,即Keepalived或者Nginx死机时,权重减少(可以是正数)。
界面:输入ifconfig命令查看当前网卡名称。
ens7f0: flags=4163 mtu 1500
inet 192.168.4.32 netmask 255.255.252.0 broadcast 192.168.7.255
inet6 fe80::e273:9c3c:e675:7c60 prefixlen 64 scopeid 0x20ink>
... ...
3、在/usr/local/src目录下添加检查脚本nginx_check.sh:
#!/bin/bash
A=`ps -C nginx -no-header |wc -l`
if [ $A -eq 0 ];then
/usr/local/nginx/sbin/nginx
sleep 2
if [ ps -C nginx -no-header |wc -l` -eq 0 ];then
killall keepalived
fi
fi
4、启动两台服务器的Nginx和Keepalived:
# 启动 nginx
./nginx
# 启动 keepalived
systemctl start keepalived.service
5. 查看虚拟IP地址IPa。 停止主服务器192.168.4.32Nginx和Keepalived,然后访问虚拟IP查看高可用效果。
原理分析
Nginx启动后,Linux系统中有两个进程,一个是Master,一个是Worker。
Master作为管理员,不参与任何工作,只负责将不同的任务分配给多个Worker(通常有多个Worker)。
ps -ef |grep nginx
root 20473 1 0 2019 ? 00:00:00 nginx: master process /usr/sbin/nginx
nginx 4628 20473 0 Jan06 ? 00:00:00 nginx: worker process
nginx 4629 20473 0 Jan06 ? 00:00:00 nginx: worker process
工人如何工作? 客户端首先通过Master发送请求,管理员收到请求后将请求通知给Worker。
多个Worker采用抢夺任务的机制,拿到任务的Worker会通过Tomcat、反向代理、访问数据库等转发请求(Nginx本身并不直接支持Java)。
一个Master多个Worker有什么好处?
多少工人合适? Nginx和Redis类似,都采用IO复用机制,每个worker都是一个独立的进程,每个进程只有一个主线程。
通过以异步和非阻塞的方式处理请求,每个工作线程都可以最大限度地提高 CPU 的性能。 因此,worker的数量与服务器中CPU的数量相等是最合适的。
思维:
恭喜! 至此,你已经掌握了Nginx的六大功能的配置方法,并跟我一起进一步讲解了Nginx的原理。 关于最近两次笔试可能会问到的思考题31段均衡器软件教程,欢迎大家在评论区积极讨论。