Nginx 是一个高性能的 HTTP 和反向代理 web 服务器,同时也提供了 IMAP/POP3/SMTP 服务。
其特点是占有内存少,并发能力强(能支持 50000 个并发连接数的响应),国内大多数互联网企业都有使用它。
它也是一个安装非常简单、配置文件非常简洁(还能够支持 perl 语法)、Bug非常少的服务,启动特别容易,并且几乎可以做到 7*24 不间断运行,即使运行数个月也不需要重新启动。
Nginx 的作用主要有三个,一个是反向代理
,一个是负载均衡
,最后一个是动静分离
。
反向代理
反向代理,本质是代理,也可以理解为中介或者中间商,只不过是反向的,表示代理的是服务端。
这和租房的例子有点类似,租客可以理解为客户端,房屋中介可以理解为中间代理,真正的房东可以理解为服务端。
房屋中介手上有很多房源,与多个房东有合作关系,租客无法直接找到房东租房子,只能通过房屋中介去租,那这时房屋中介就成了各个房东的代理人,从租客的角度来看,这就是一个反向代理。
反向代理的特点:客户端无法知道真正为自己提供服务的是哪里的哪一台服务器
正向代理
既然有反向代理,那自然有正向代理。
反向代理,代理的是服务端,而正向代理,正好相反,代理的是客户端。
举个例子,比如在你的个人电脑上,挂上一个 VPN,访问外网访问谷歌,这就是一个正向代理的示例。你的个人电脑,由于某些原因,本身无法访问外网,但通过代理就可以访问到外网的内容。
正向代理的特点:服务端无法知道真正访问自己的是哪里的哪一个客户端
负载均衡:英文名称为 Load Balance,可以理解为一种负载的处理方式,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,避免单一服务器承受压力太大,产生过载情况,同时也是为了优化资源使用,提高响应速度。
Nginx 提供的负载均衡策略分为:内置策略和扩展策略
轮询
轮询策略:按一定的顺序,循环将请求分发给服务器进行处理,如下面的分发,自上往下给每个服务器依次分发请求。
加权轮询
加权轮询:根据每个服务器分配的权重,循环分配请求进行处理,权重越高表示该服务器的处理能力越强,可以承担的请求数量越多。
ip 哈希
ip 哈希策略:对客户端的 ip 进行 hash 操作,然后根据 hash 结果将同一个客户端 ip 的请求分发给同一台服务器进行处理,同时这一个策略可以解决 session 不共享的问题。
url 哈希
url 哈希与 ip 哈希类似,不同点在于 ip 哈希是对客户端 ip 进行哈希操作,而 url 哈希则是对客户端请求的 url 进行哈希操作。这一策略可以配合后端的缓存服务器使用,它能够提高缓存效率,同时解决 session 的问题。
fair
将前端请求分流到负载压力最小的后端节点上。Nginx 通过后端节点对请求的响应时间来判断负载情况,响应时间短的节点负载压力相对小,得出判断结果后,Nginx 就将前端请求分配到负载压力最小的节点上。
在实际的开发中,有些请求是不需要后台处理就能直接展示的,比如一个网站上固定的一些图片、样式、页面恒定的信息等,都是死的,不需要动态展示,那这种就可以考虑单独部署在一个静态资源服务器上,将它们与后端应用的部署分离开,实现动静分离。
动静分离的好处:由于静态资源是死的,不会动态变化,因此可以根据这个特点,对需要用到静态资源的地方做缓存处理,提高响应速度,更快地展示页面信息。
# 先进入到 sbin 目录里面
cd /usr/local/nginx/sbin/
# 启动 nginx 命令
./nginx
# 停止 nginx 命令
./nginx -s stop
# 安全退出 nginx 命令
./nginx -s quit
# 重新加载 nginx 配置文件
./nginx -s reload
# 查看 nginx 进程
ps aux|grep nginx
nginx 的配置文件,我们最常用的、可能也是最需要去改动的就是 nginx.conf 这个文件,它是做路由转发、负载均衡、端口监听等操作的配置所在地。
整个文件的内容,可以分为以下三大板块:
其中,http 块,又可以再分为 http 全局块和 server 块;server 块它也可以再分,分为 server 全局块和 location 块。
一个 http 块中,可以有多个 server 块,而一个 server 块中,也可以有多个 location 块
用个图表示一下结构,大概就类似下面这样的:
下面是一个 nginx.conf 文件的内容,按照上面分块的方式去读它,可以发现整个文件的结构还是比较清晰的。
#user nobody;
#开启进程数 <=CPU数
worker_processes 1;
#错误日志保存位置
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#进程号保存文件
#pid logs/nginx.pid;
#每个进程最大连接数(最大连接=连接数x进程数)每个worker允许同时产生多少个链接,默认1024
events {
worker_connections 1024;
}
http {
#文件扩展名与文件类型映射表
include 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 logs/access.log main;
#打开发送文件
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
#连接超时时间
keepalive_timeout 65;
#打开gzip压缩
#gzip on;
#client_header_buffer_size 4k; 设定请求缓冲,
客户端请求头部的缓冲区大小。
这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,
不过由于一般系统分页都要大于1k,所以这里设置为分页大小。
分页大小可以用命令getconf PAGESIZE 取得。
[root@web001 ~]# getconf PAGESIZE
4096
但也有client_header_buffer_size超过4k的情况,但是client_header_buffer_size该值必须设置为“系统分页大小”的整倍数。
#client_header_buffer_size 4k;
#large_client_header_buffers 4 4k;
#设定负载均衡的服务器列表
#upstream myproject {
#weigth参数表示权值,权值越高被分配到的几率越大
#max_fails 当有#max_fails个请求失败,就表示后端的服务器不可用,默认为1,将其设置为0可以关闭检查
#fail_timeout 在以后的#fail_timeout时间内nginx不会再把请求发往已检查出标记为不可用的服务器
#}
#webapp
#upstream myapp {
# server 192.168.122.133:8080 weight=1 max_fails=2 fail_timeout=30s;
# server 192.168.122.134:8080 weight=1 max_fails=2 fail_timeout=30s;
#}
#配置虚拟主机,基于域名、ip和端口
server {
#监听端口
listen 9000;
#监听域名
server_name localhost;
#charset koi8-r;
#nginx访问日志放在logs/host.access.log下,并且使用main格式(还可以自定义格式)
#access_log logs/host.access.log main;
#返回的相应文件地址
location / {
#负载均衡反向代理
#proxy_pass http://myapp;
#返回根路径地址(相对路径:相对于/usr/local/nginx/)
root html;
#默认访问文件
index index.html index.htm;
}
#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 html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
下面是从其它地方找到的一个 nginx.conf 配置文件示例,记录并学习一下。
个人觉得,这个东西没有一个固定的配置模板,都是根据自己的业务需求去实现配置的,但配置的内容,无非还是端口、负载均衡、路由转发、连接数、超时限制、上传文件大小限制等玩意,刚开始用可能觉得有些麻烦,但当你对 nginx.conf 这个文件操作多了,自然就会觉得没啥了,正所谓熟能生巧。
# 全局块
user www-data;
worker_processes 2; ## 默认1,一般建议设成CPU核数1-2倍
error_log logs/error.log; ## 错误日志路径
pid logs/nginx.pid; ## 进程id
# Events块
events {
# 使用epoll的I/O 模型处理轮询事件。
# 可以不设置,nginx会根据操作系统选择合适的模型
use epoll;
# 工作进程的最大连接数量, 默认1024个
worker_connections 2048;
# http层面的keep-alive超时时间
keepalive_timeout 60;
# 客户端请求头部的缓冲区大小
client_header_buffer_size 2k;
}
# http块
http {
include mime.types; # 导入文件扩展名与文件类型映射表
default_type application/octet-stream; # 默认文件类型
# 日志格式及access日志路径
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
# 允许sendfile方式传输文件,默认为off。
sendfile on;
tcp_nopush on; # sendfile开启时才开启。
# http server块
# 简单反向代理
server {
listen 80;
server_name domain2.com www.domain2.com;
access_log logs/domain2.access.log main;
# 转发动态请求到web应用服务器
location / {
proxy_pass http://127.0.0.1:8000;
deny 192.24.40.8; # 拒绝的ip
allow 192.24.40.6; # 允许的ip
}
# 错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# 负载均衡
upstream backend_server {
server 192.168.0.1:8000 weight=5; # weight越高,权重越大
server 192.168.0.2:8000 weight=1;
server 192.168.0.3:8000;
server 192.168.0.4:8001 backup; # 热备
}
server {
listen 80;
server_name big.server.com;
access_log logs/big.server.access.log main;
charset utf-8;
client_max_body_size 10M; # 限制用户上传文件大小,默认1M
location / {
# 使用proxy_pass转发请求到通过upstream定义的一组应用服务器
proxy_pass http://backend_server;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
}
}
}