Nginx
Nginx 是高性能的web服务器,拥有处理高并发,正向/反向代理的能力;
Nginx的代理功能与负载均衡功能也是最常被用到的;
docker 安装 NGINX 的文档已经烂大街了,我们直接跳过;
什么是 正向/反向代理?
正向代理
正向代理有以下特点
- 工作过程是客户端通过代理服务器来访问服务器,这个过程中需要在客户端配置代理服务器;
- 正向代理对客户端是透明的,对服务端是非透明的,即服务端是不知道当前请求是来自客户端还是服务端;
简单来说,为客户端提供代理服务的过程,我们就可以称为 “正向代理”
反向代理
反向代理有以下特点
- 工作过程是 客户端访问代理服务器,再有代理服务器将请求代理到内网中的服务器(原始服务端),这个过程对于客户端是无感知的;
- 反向代理在不暴露服务端的场景下,将请求通过代理服务器返回给客户端,从而起到了保护服务端的作用
简单来说,和正向代理相反,为服务端提供代理服务的过程,称之为 “反向代理”
Nginx为什么能处理高并发请求?
1.基于事件驱动的架构
“事件驱动” 即当某个事件发生时,系统会调用相应的事件处理器来处理该事件.好处在于当我们把事件注册进系统后,就不用阻塞等待,使程序能够异步地响应事件的发生
2.epoll机制
nginx使用epoll作为事件通知机制,通过将待处理事件加入到epoll实例中,并使用epoll_wait函数来等待事件的发生,从而实现高效的事件管理
3.采用多进程模式,每个进程都是单线程
多进程主要分为 一个master主进程和多个worker工作进程组成,每个进程采用单线程,之所以采用单线程是为了减少线程之间切换带来的开销
主进程主要作用在于监控工作进程,而实际处理客户端请求的是工作进程
> ps aux|grep nginx
1 root 0:00 nginx: master process nginx -g daemon off;
20 nginx 0:00 nginx: worker process
4.独特的内存管理
Nginx在内存使用上也做了很多优化,例如"内存池技术",不过我们的重点不在于分析其优化手段
常见的Nginx命令有哪些?
以下是我目前所知的nginx相关命令,欢迎各位补充
# 查看nginx版本
> nignx -v
# 查看nginx版本和详细配置
> nginx -V
# 检测配置文件是否有语法错误
> nginx -t
# 检测配置文件是否有语法错误并转储
> nginx -T
# 在检测配置文件期间屏蔽非错误信息
> nginx -q
# 杀死所有nginx进程
> killall nginx
# 强制停止Nginx服务
> nginx -s stop
# 处理完所有请求后再停止服务
> nginx -s quit
# 重启
> nginx -s reopen
# 重新加载Nginx配置文件
> nginx -s reload
# 设置Nginx的工作目录前缀
> nginx -p prefix
# 设置配置文件
> nginx -c filename
# 设置配置文件外的全局指令
> nginx -g directives
Nginx配置文件结构
-
全局块
: 配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。 -
events块
: 配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。 -
http块
: 可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。 -
server块
: 配置虚拟主机的相关参数,一个http中可以有多个server。 -
location块
: 配置请求的路由,以及各种页面的处理情况。
结合以下配置便于理解
########### 每个指令必须有分号结束。#################
#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; #监听地址
#server_name example.com www.example.com; # 也可以监听多个域
location ~*^.+$ { #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
#root path; #根目录
#index vv.txt; #设置默认页
proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表
deny 127.0.0.1; #拒绝的ip
allow 172.18.5.54; #允许的ip
}
}
}
常见的配置实例
- 域名
server {
# 监听 example.com
server_name example.com;
# 监听多个域
server_name example.com www.example.com;
# 监听所有子域
server_name *.example.com;
# 监听所有顶级域
server_name example.*;
# 监听未指定的主机名(监听 IP 地址本身)
server_name "";
}
- 负载均衡
# server 可选参数
# `weight`访问权重数值越高,收到请求越多
# `fail_timeout`指定的时间内必须提供响应
# `max_fails`尝试失败服务器连接的最大次数
# `down`标记一个服务器不再接受任何请求
# `backup`有服务器宕机,标记的机器接收请求
# `热备`
# 当一台服务器挂掉时,会将请求负载到backup指定的服务器
upstream service_group {
server 127.0.0.1:3000;
server 127.0.0.1:4000 backup; #热备
}
# `轮询`
# 循环处理请求
upstream service_group {
server 127.0.0.1:3000;
server 127.0.0.1:4000;
server 127.0.0.1;
}
# `加权轮询`
# weight越大越容易接收请求
upstream service_group {
server localhost:8080 weight=9;
server localhost:8081 weight=1;
}
# `ip_hash`
# 相同的客户端ip请求相同的服务器
upstream service_group {
server 127.0.0.1:3000;
server 127.0.0.1:4000;
ip_hash;
}
# `fair`
# 响应时间短的优先分配
upstream service_group {
fair;
server 127.0.0.1:3000;
server 127.0.0.1:4000;
}
# `url_hash`
# 按访问url的hash结果来分配请求
upstream service_group {
hash $request_uri;
hash_method crc32;
server 127.0.0.1:3000;
server 127.0.0.1:4000;
}
# `keepalive`
# 激活缓存以连接到上游服务器
upstream service_group {
server 127.0.0.1:3000;
server 127.0.0.1:4000;
#http1.1特性
#这设置了与每个Memcached服务器的连接保持活动状态的空闲连接数。
#这意味着Nginx会维护最多32个连接,以便快速重用这些连接而不是每次需要时都新建
keepalive 32;
}
- 升级连接(适用于支持 WebSockets 的应用程序)
upstream node_js {
server 0.0.0.0:3000;
keepalive 5;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://node_js;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
- 子文件夹中的代理
location /folder/ { # / 很重要!
proxy_pass http://127.0.0.1:3000/; # / 很重要!
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; # 获取客户端真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 获取客户端真实IP
}
- 重定向
# 301 重定向
server {
listen 80;
server_name www.example.com;
return 301 http://example.com$request_uri;
}
# 或
location / {
if ($host != 'www.example.com' ) {
# permanent 代表的就是301
rewrite ^/(.*)$ http://example.com/$1 permanent;
}
}
# 302 重定向
server {
listen 80;
server_name www.example.com;
return 302 http://example.com$request_uri;
}
# 或
location / {
if ($host != 'www.veryyoung.me' ) {
# redirect 你猜
rewrite ^/(.*)$ http://example.com/$1 redirect;
}
}
- 隐藏PHP入口文件文件 index.php
location / {
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php/$1 last;
}
}
- 跨域
server {
listen 80;
server_name api.xxx.com;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET,POST,HEAD';
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}
nginx的配置是非常灵活的,由于篇幅原因,写这么多就得了
参考
官方文档(全局变量): https://nginx.org/en/docs/varindex.html
NGINX 备忘清单: https://wangchujiang.com/reference/docs/nginx.html
反向代理与负载均衡详解:https://www.runoob.com/w3cnote/nginx-proxy-balancing.html
文档中如果存在错误或者不明确的地方欢迎指正