文章目录
Nginx 的使用
什么是Nginx
nginx是一个http服务器,是一个使用C语言开发的高性能的Http服务器及反向代理服务器,同时也可以作为IMAP/POP3/SMTP的代理服务器。官方测试Nginx能够支撑5万并发量,并且CPU、内存等资源消耗非常低,运行非常稳定。
Nginx运用场景
- http服务器:Nginx可以独立提供http服务,可以做网页静态服务器。
- 虚拟主机:可以实现在一台服务器虚拟出多个网站,例如个人网站使用的虚拟主机(不同端口、不同域名)。
- 反向代理/负载均衡:当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要使用集群可以使用Nginx做反向代理,并且集群服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台闲置的情况。
- web缓存:类似 SQUID,VARNISH。Nginx可以对不同的文件做不同的缓存处理,配置灵活,并且支持FastCGI_Cache,主要用于对FastCGI的动态程序进行缓存。配合着第三方的ngx_cache_purge,对制定的URL缓存内容可以的进行增删管理。
Nginx特点(为什么使用Nginx)
- 热部署
- 占用资源少:2万并发、10个线程,内存消耗几百M
- 可靠性高
- 利用nginx可以对IP限速,可以限制连接数。
- 配置简单,更灵活。
部署Nginx
1、windows下部署
- 官网下载: Nginx管网。
- 操作
- 解压后就可启动,免安装
(1)WIN + R CMD 打开Nginx目录:
(2)启动: start nginx.exe
(3)停止: nginx.exe -s stop
(4)重启: nginx.exe -s reload
- 验证
打开服务管理器查看Nginx是否启动成功
2、Linux下部署
- 第一种安装组件:
- gcc && g++
yum install gcc-c++- pcre
yum install -y pcre pcre-devel- zlib
yum install -y zlib zlib-devel- openssl
yum install -y openssl openssl-devel
- 第二种官网下载
- 安装
1. 解压nginx文件
tar -zxvf nginx-1.17.5.tar.gz
2. 安装
## 创建一个nginx安装目录
mkdir nginx
cd nginx-1.12.2
## 指定文件安装路径
./configure --prefix=/home/lege/nginx
make
make install
#安装完成后内容会安装到指定的路径 /home/lege/nginx下,否则会在默认目录/usr/local/nginx
- 启动
## 修改配置文件
cd /home/lege/nginx/conf
vim nginx.conf
## 设置端口为8080,也可设置成其他
listen 8080;
## 进入到启动目录
cd /home/lege/nginx/sbin
## 检查配置文件是否有问题
./nginx -t
##没有问题的结果如下所示:
[soa@testsoa04 sbin]$ ./nginx -t
nginx: the configuration file /home/lege/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /home/lege/nginx/conf/nginx.conf test is successful
[soa@testsoa04 sbin]$
## 查询配置参数
./nginx -V
## 对于已安装的nginx需要修改配置参数
./configure --prefix=/home/lege/nginx ...配置参数
make
make install
然后重新启动nginx即可
## 启动
./nginx
## 停止
./nginx -s stop
## 重启
./nginx -s reload
## 输入网址验证是否启动成功
http://ip:port/
配置
打开config文件夹下的: nginx.config
########### 每个指令必须有分号结束。#################
#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
}
}
}
配置注意事项:
1、$remote_addr 与 $http_x_forwarded_for 用以记录客户端的ip地址。
2、$remote_user :用来记录客户端用户名称。
3、$time_local : 用来记录访问时间与时区。
4、$request : 用来记录请求的url与http协议。
5、$status : 用来记录请求状态;成功是200。
6、$body_bytes_s ent :记录发送给客户端文件主体内容大小。
7、$http_referer :用来记录从那个页面链接访问过来的。
8、$http_user_agent :记录客户端浏览器的相关信息。
9、 惊群现象:一个网路连接到来,多个睡眠的进程被同时叫醒,但只有一个进程能获得链接,这样会影响系统性能。
10、每个指令必须有分号结束。
匹配location
location = / {
# 精确匹配 / ,主机名后面不能带任何字符串
[ configuration A ]
}
location / {
# 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
# 但是正则和最长字符串会优先匹配
[ configuration B ]
}
location /documents/ {
# 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
[ configuration C ]
}
location ~ /documents/Abc {
# 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
[ configuration CC ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配所有以 gif,jpg或jpeg 结尾的请求
# 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则
[ configuration E ]
}
location /images/ {
# 字符匹配到 /images/,继续往下,会发现 ^~ 存在
[ configuration F ]
}
location /images/abc {
# 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在
# F与G的放置顺序是没有关系的
[ configuration G ]
}
location ~ /images/abc/ {
# 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用
[ configuration H ]
}
location ~* /js/.*/\.js
location匹配注意事项:
1、以=开头表示精确匹配。
2、^~ 开头表示uri以某个常规字符串开头,不是正则匹配。
3、~ 开头表示区分大小写的正则匹配。
4、~* 开头表示不区分大小写的正则匹配
5、/ 通用匹配, 如果没有其它匹配,任何请求都会匹配到
优先级:
(location =) > (location 完整路径) > (location ^~ 路径) > (location ,* 正则顺序) > (location 部分起始路径) > (/)
nginx监控
开启状态页
#设定查看Nginx状态的地址
location /status {
stub_status on; #表示开启stubStatus的工作状态统计功能。
access_log off; #access_log off; 关闭access_log 日志记录功能。
#auth_basic "status"; #auth_basic 是nginx的一种认证机制。
#auth_basic_user_file conf/htpasswd; #用来指定密码文件的位置。
}
配置登录密码
yum install -y httpd-tools
/usr/local/apache/bin/htpasswd -c /data/nginx/conf/htpasswd biglittleant
New password:
完成后会在/data/nginx/conf/目录下生成htpasswd文件。
访问URL
curl http://127.0.0.1/status
Active connections: 1
server accepts handled requests
16 16 18
Reading: 0 Writing: 1 Waiting: 0
#active connections – 活跃的连接数量
#server accepts handled requests — 总共处理了16个连接 , 成功创建16次握手, 总共处理了18个请求
#Reading — 读取客户端的连接数: Writing 响应数据到客户端的数量; Waiting 开启 keep-alive 的情况下,这个值等于 active – (reading+writing), 意思就是 Nginx 已经处理完正在等候下一次请求指令的驻留连接.
编写zabbix监控脚本
nginx_status_fun(){
NGINX_PORT=$1
NGINX_COMMAND=$2
nginx_active(){
/usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/status/" 2>/dev/null| grep 'Active' | awk '{print $NF}'
}
nginx_reading(){
/usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/status/" 2>/dev/null| grep 'Reading' | awk '{print $2}'
}
nginx_writing(){
/usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/status/" 2>/dev/null| grep 'Writing' | awk '{print $4}'
}
nginx_waiting(){
/usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/status/" 2>/dev/null| grep 'Waiting' | awk '{print $6}'
}
nginx_accepts(){
/usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/status/" 2>/dev/null| awk NR==3 | awk '{print $1}'
}
nginx_handled(){
/usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/status/" 2>/dev/null| awk NR==3 | awk '{print $2}'
}
nginx_requests(){
/usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/status/" 2>/dev/null| awk NR==3 | awk '{print $3}'
}
case $NGINX_COMMAND in
active)
nginx_active;
;;
reading)
nginx_reading;
;;
writing)
nginx_writing;
;;
waiting)
nginx_waiting;
;;
accepts)
nginx_accepts;
;;
handled)
nginx_handled;
;;
requests)
nginx_requests;
esac
}
反向代理
详解:
# 对 “/” 启用反向代理
location / {
proxy_pass http://127.0.0.1:3000; # 设置要代理的 uri,注意最后的 /。可以是 Unix 域套接字路径,也可以是正则表达式。
proxy_redirect off; # 设置后端服务器“Location”响应头和“Refresh”响应头的替换文本
proxy_set_header X-Real-IP $remote_addr; # 获取用户的真实 IP 地址
#后端的Web服务器可以通过 X-Forwarded-For 获取用户真实IP,多个 nginx 反代的情况下,例如 CDN。参见:http://gong1208.iteye.com/blog/1559835 和 http://bbs.linuxtone.org/thread-9050-1-1.html
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#以下是一些反向代理的配置,可选。
proxy_set_header Host $host; # 允许重新定义或者添加发往后端服务器的请求头。
client_max_body_size 10m; #允许客户端请求的最大单文件字节数
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数,
proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的设置
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k;
#设定缓存文件夹大小,大于这个值,将从upstream服务器传
}
举例:
location ^~ /service/ {
proxy_pass http://192.168.60.245:8080/;
proxy_redirect default;
proxy_set_header Host $host
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
简化:
location /proxy/ {
proxy_pass http://backend.com/;
proxy_redirect default;
}
配置rewrite
rewrite功能就是集合正则表达式和标志位实现url重写和重定向。rewrite只能放在server{}、location{}、if(){}块中,并且只能对域名后边的出去传递参数外的字符串起作用。如URL:
http://microloan-sms-platform.yxapp.xyz/proxy/sms/task/querydeleted?page=1&pagesize=10
只对/proxy/sms/task/querydeleted进行重写。
如果相对域名或参数字符串起作用,可以使用全局变量匹配,也可以使用proxy_pass反向代理。
表明看rewrite和location功能有点像,都能实现跳转,主要区别在于rewrite是在同一域名内更改获取资源的路径,而location是对一类路径做控制访问或反向代理,可以proxy_pass到其他机器。很多情况下rewrite也会写在location里,它们的执行顺序是:
- 执行server块的rewrite指令
- 执行location匹配
- 执行选定的location中的rewrite指令
如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件;循环超过10次,则返回500 Internal Server Error错误。
rewrite规则后边,通常会带有flag标志位:
- last : 相当于Apache的[L]标记,表示完成rewrite
- break : 停止执行当前虚拟主机的后续rewrite指令集
- redirect : 返回302临时重定向,地址栏会显示跳转后的地址
- permanent : 返回301永久重定向,地址栏会显示跳转后的地址
last 和 break 区别:
- last一般写在server和if中,而break一般使用在location中
- last不终止重写后的url匹配,即新的url会再从server走一遍匹配流程,而break终止重写后的匹配
- break和last都能组织继续执行后面的rewrite指令
rewrite常用正则:
- . : 匹配除换行符以外的任意字符
- ? : 重复0次或1次
-
- : 重复0次或更多次
- \d :匹配数字
- ^ : 匹配字符串的开始
- $ : 匹配字符串的介绍
- {n} : 重复n次
- {n,} : 重复n次或更多次
- [c] : 匹配单个字符c
- [a-z] : 匹配a-z小写字母的任意一个
可以使用()来进行分组,可以通过$1的形式来引用。
示例:
location /proxy/ {
proxy_pass http://microloan-notification-web.yxapp.in;
rewrite /proxy/(.*)$ /$1 break;
}
配置负载均衡
示例:
upstream test.net{
ip_hash;
server 192.168.11.1:80;
server 192.168.11.11:80 down;
server 192.168.11.123:8009 max_fails=3 fail_timeout=20s;
server 192.168.11.1234:8080;
}
upstream是Nginx的HTTP Upstream模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。
Nginx的负载均衡模块目前支持4种调度算法:
- 轮询(默认)。每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。Weight 指定轮询权值,Weight值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下。
- ip_hash。每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,有效解决了动态网页存在的session共享问题。
- fair。这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair模块。
- url_hash。此方法按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx 的hash软件包。
upstream可以设定每个后端服务器在负载均衡调度中的状态,支持的状态参数:
- down:表示当前的server暂时不参与负载均衡
- backup:预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。
- max_fails:允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
- fail_timeout:在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。
注,当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。
设置页面缓存
页面缓存设置指令:
- proxy_cache_path :指定缓存的路径和一些其他参数,缓存的数据存储在文件中,并且使用代理url的哈希值作为关键字与文件名。
proxy_cache_path /data/nginx/cache/webserver levels=1:2 keys_zone=webserver:20mmax_size=1g;
levels参数指定缓存的子目录数。keys_zone指定活动的key和元数据存储在共享池(webserver为共享池名称,20m位共享池大小),inactive参数指定的时间内缓存的数据没有被请求则被删除,默认inactive为10分钟·max_size指定缓存空间的大小。
- proxy_cache:设置一个缓存区域的名称,一个相同的区域可以在不同的地方使用。
- proxy_cache_valid:为不同的应答设置不同的缓存时间。
设置读写分离
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://192.128.133.202;
if ($request_method = "PUT"){
proxy_pass http://192.128.18.201;
}
}
}
nginx优化
nginx内核优化
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.ip_local_port_range = 4000 65000
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 16384
net.core.netdev_max_backlog = 16384
net.ipv4.tcp_max_orphans = 16384
#以下参数是对iptables防火墙的优化,防火墙不开会提示,可以忽略不理。
net.ipv4.ip_conntrack_max = 25000000
net.ipv4.netfilter.ip_conntrack_max=25000000
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=180
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait=120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait=60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait=120
nginx全局变量
$args:这个变量等于请求行中的参数,同$query_string。
$is_args: 如果已经设置$args,则该变量的值为"?",否则为""。
$content_length: 请求头中的Content-length字段。
$content_type: 请求头中的Content-Type字段。
$document_uri: 与$uri相同。
$document_root: 当前请求在root指令中指定的值。
$host: 请求主机头字段,否则为服务器名称。
$http_user_agent: 客户端agent信息。
$http_cookie: 客户端cookie信息。
$limit_rate: 这个变量可以限制连接速率。
$request_method: 客户端请求的动作,通常为GET或POST。
$remote_addr: 客户端的IP地址。
$remote_port: 客户端的端口。
$remote_user: 已经经过Auth Basic Module验证的用户名。
$request_body_file`: 客户端请求主体的临时文件名。
$request_uri: 请求的URI,带参数
$request_filename: 当前请求的文件路径,由root或alias指令与URI请求生成
$scheme: 所用的协议,比如http或者是https,比如rewrite ^(.+)$ $scheme://example.com$1 redirect;。
$server_protocol: 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr: 服务器地址,在完成一次系统调用后可以确定这个值。
$server_name: 服务器名称。
$server_port: 请求到达服务器的端口号。
$request_uri: 包含请求参数的原始URI,不包含主机名,如:/foo/bar.php?arg=baz,它无法修改。
$uri: 不带请求参数的当前URI,$uri不包含主机名,如/foo/bar.html可能和最初的值有不同,比如经过重定向之类的。它可以通过内部重定向,或者使用index指令进行修改。不包括协议和主机名,例如/foo/bar.html。
例子:
访问链接是:http://localhost:88/test1/test.html
网站路径是:/var/www/html
$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/test.html
$document_uri:/test1/test.html
$document_root:/var/www/html
$request_filename:/var/www/html/test1/test.html