一.启动 cd usr/local/nginx/sbin ./nginx 二.重启 更改配置重启nginx killall -s HUP nginx cd /usr/local/nginx/sbin ./nginx -s reload nginx -t -c /usr/local/nginx/conf/nginx.conf cd /usr/local/nginx/sbin ./nginx -t 三.关闭 查询nginx主进程号 ps -ef | grep nginx 从容停止 kill -QUIT 主进程号 快速停止 kill -TERM 主进程号 强制停止 kill -9 nginx 若nginx.conf配置了pid文件路径,如果没有,则在logs目录下 kill -信号类型 '/usr/local/nginx/logs/nginx.pid' 1.管理 介绍 轻量级web服务器。高性能。反向代理。 也是一个:IMAP/POP3/SMTP代理服务器。 安装,启动 官网源码包 wget http://nginx.org/download/nginx-1.15.5.tar.gz -P /usr/src 配置:configure --prefix= 路径 1.检查环境是否满足安装条件。依赖解决 2.指定安装 配置文件 命令文件 各种文件放哪里, 开启模块功能,内置模块,三方模块。 3.指定软件安装在哪里。 编译 && 安装 启动:/usr/local/nginx/sbin/nginx -g /usr/local/nginx/conf/nginx.conf 检查配置文件是否有问题。 默认网站:一台服务器发布一个网站叫做默认网站。 2.目录访问控制 简单的权限配置 #访问控制:只允许本机访问a目录 其他机器拒绝访问 location /a { allow 127.0.0.1; allow 192.16.16.110; 这是两种写法 deny all; #return 502 拒绝后返回的数据; return http://www.jd.com; #可以是跳转别的网站 return 502; #也可以是返回错误网页 } 认证配置 1.openssl 2.htpasswd yum install -y httpd-tools 在http工具包内。 vim /etc/nginx/htpasswd 如果没有就创建在此目录下。 htpasswd -m /etc/nginx/htpasswd sky 创建sky用户。 之后输入密码 配置: location /b { auth_basic "登录验证"; auth_basic_user_file /etc/nginx/htpasswd; #认证文件。 } 3.日志管理:ELK日志分析系统 区别:也可以定义成json格式 日志级别: debug > info > notice > warn > error > crit > alert > emerg nginx访问日志主要有两个参数控制 1.log_format #用来定义记录日志格式(可以定义多种日志格式,取不同的名字即可) log_format log_name string 2.access_log #用来指定日志文件的路径及使用的何种日志格式记录日志 access_log logs/access_log main; 位置。 日志变量说明: $remote_addr, $http_x_forwarded_for 记录客户端IP地址 $remote_user 记录客户端用户名称 $request 记录请求的URL和HTTP协议(GET,POST,DEL,等) $status 记录请求状态 $body_bytes_sent 发送给客户端的字节数,不包括响应头的大小; 该变量与Apache模块mod_log_config里的“%B”参数兼容。 $bytes_sent 发送给客户端的总字节数。 $connection 连接的序列号。 $connection_requests 当前通过一个连接获得的请求数量。 $msec 日志写入时间。单位为秒,精度是毫秒。 $pipe 如果请求是通过HTTP流水线(pipelined)发送,pipe值为“p”,否则为“.”。 $http_referer 记录从哪个页面链接访问过来的 $http_user_agent 记录客户端浏览器相关信息 $request_length 请求的长度(包括请求行,请求头和请求正文)。 $request_time 请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。 $time_iso8601 ISO8601标准格式下的本地时间。 $time_local 通用日志格式下的本地时间。 日志参数配置。可以百度。 https://www.cnblogs.com/biglittleant/p/8979856.html 案例 4.防盗链:防爬虫,防止别人盗用连接 在浏览器中查看请求头中的refer location /c { 针对文件夹的写法。 #location ~* .(png|gif|bmp)$ { 针对某个文件的写法 ivalid_referers none blockd *.ayitula.com; if ($invalid_referer) { return 403; } } 5.虚拟主机:一台服务器发布多个网站,叫做虚拟主机。 基于IP的虚拟主机 每一个网站都需要一个ip,缺点:需要多个ip如果是公网ip每个ip都需要付费 server { listen 192.16.16.110:80; location / { root html/web1; index index.html index.htm index.php; } } server { listen 192.16.16.111:80; location / { root html/web2; index index.html index.htm; } } 基于端口的虚拟主机 只需要一个ip。 缺点,端口是无法告诉公网用户。无法适用于公网客户。适合内部用户 server { listen 80; server_name www.abc.com; location / { root html/web1; index index.html index.htm index.php; } } server { listen 8080; server_name www.abc.com; location / { root html/web2; index index.html index.htm; } } 基于域名的虚拟主机 修改 /etc/hosts添加域名和地址。适合所有环境,一个IP地址,能配置多个域名。 server { listen 80; server_name www.abc.com; location / { root html/web1; index index.html index.htm index.php; } } server { listen 80; server_name www.cbd.com; location / { root html/web2; index index.html index.htm; } } 6.反向代理 代理的是服务器。 代理服务器,客户机在发送请求时,不会直接发送给目的主机,而是先发送给代理服务器,代理服务器接受客户机请求之后,在向主机发出,并接收目的主机返回的数据,存放在代理服 务器的硬盘中,在发给客户机。 反向代理原理 1),客户端通过浏览器 发起请求 代理服务器 2)代理服务器 接受请求 3)代理服务器 发起请求 业务服务器 4)业务服务器 接受请求 5)业务服务器 处理请求 6)业务服务器 响应请求 代理服务器 7)代理服务器 响应请求 客户端 8)客户端通过浏览器渲染请求并展示给用户。 堡垒机场景 保证数据的安全。 业务服务器只开放对堡垒机的ip地址和80端口的问题。 内网服务器发布场景 ip地址不足,只有一个的时候。代理多个业务服务器。 缓存场景 缓存静态内容。用户访问速度上比较快。并且减小业务服务器的压力。80%的静态数据。20%的动态数据。 实现配置: 在server段里面的location加上proxy_pass http://ip:端口; server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { proxy_pass http://192.16.16.110:80; proxy_set_header 设置有后端的服务器获取用户的主机名或真是ip地址,以及代理者的真实IP地址。 proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 90; #后端服务器链接的超时时间 proxy_send_timeout 90; #后端服务器数据回传时间。规定时间内必须传完所有的数据。 proxy_read_timeout 90; #链接成功后,等待后端服务器响应时间,其实已经进入后端排队 proxy_buffer_size 4k; #缓冲区大小 proxy_buffers 4 32k; # proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } 7.限速 应用场景 DDOS防御 下载场景保护IO。长时间下载会导致硬盘损坏。 两种模块 limit_req_zone 用来限制单位时间内的请求数,即速率限制。 limit_conn_zone 用来限制同一时间连接数,即并发限制。 limit_zone: 是针对每个IP定义一个存储session状态的容器.这个示例中定义了一个10m的容器,按照32bytes/session, 可以处理320000个session。 配置方式: #基于IP对下载速率做限制 限制每秒处理1次请求,对突发超过10个以后的请求放入缓存区。 limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s; #基于IP做连接限制 限制同一IP并发为3 下载速度为300k limit_conn_zone $binary_remote_addr zone=addr:10m; server { listen 80; server_name www.cbd.com; location / { root html/web2; index index.html index.htm; } location /abc{ limit_req zone=one burst=10 nodelay; #突发超过10个以后的请求放入缓存区。 limit_conn addr 3; 限制每个IP只能发起3个并发连接。 limit_rate 300k; 对每个连接限速300k. 注意,这里是对连接限速,而不是对IP限速。如果一个IP允许两个并发连接,那么这个IP就是限速limit_rate×2。 } } 补充路径详解: 格式:location ??? { } 路径优先级 (与代码所在前后顺序无关,只与规则有关) 1. = /error.html 2. ^~ /images/ 3. ~* .(gif|jpg|jpeg|png|bmp|swf)$ 4. /static/ 5. / 解释: 1.表示完整匹配,用=和完全的路径匹配,比如 =/error.html 就匹配 error.html =/ 匹配根路径 2.表示开头等于,优先级第二,越长就越能匹配,比如^~ /abc/cd ^~/abc 第一个会优先匹配/abc/cd/xxx 3.表示不区分大小的正则,并且正则中含义是.jpg等结尾的,优先级第三,同样正则越长越高。 4.表示开头等于/static/的,但是优先级比第二种低,是一种其他配置找不到再找它,越长就越能匹配。 5.因为4说了是越长越能匹配,当能匹配/static/就不会匹配/,而/是所有其他的一个默认匹配。 特别补充比如:location ~* .(gif|jpg|jpeg|png|bmp|swf)$ { //注意正则与其他符号要空格,其他一些配置也是如是。 8.URL重写 介绍 域名修改后,访问老地址,直接跳转到新域名。 rewirte模块:ngx_http_rewrite_module 工能实现是依赖与PCRE(Perl兼容的正则表达式)的支持,所以在编译安装Nginx之前,需要安装PCRE库。 应用场景 域名变更。 用户跳转(从某个连接跳到另一个连接) 伪静态场景(便于CDN缓存动态页面数据) 语法 set 设置变量 if 负责语句中的判断 return 返回返回值或URL break 终止后续的rewrite规则 rewrite 重定向URL set 指令 自定义变量 set $variable value; variable指定变量名称,value变量值。 Context: 指定作用域 server,location,if if判断指令: 语法为if(condition){…} #对给定的条件condition进行判断。 如果为真,大括号内的rewrite指令将被执行,if条件(conditon)可以是如下任何内容: a:当表达式只是一个变量时,如果值为空或任何以0开头的字符串都会当做false,其他情况为true。 b: 直接比较变量和内容时,使用 = 或!= c: 正则表达式匹配,*不区分大小写的匹配,!和!*反之。 注意:使用正则表达式字符串一般不需要加引号,但是如果含有右花括号“}”或者分号“;”字符时,必须要给整个正则表达式加引号 其他指令: -f和!-f用来判断请求文件是否存在 -d和!-d用来判断请求目录是否存在 -e和!-e用来判断是请求的文件或者目录否存在 -x和!-x用来判断请求的文件是否可执行 例子:if (-f $request_filename){ … #判断请求的文件是否存在,存在就执行这里面的代码块 } if判断:nginx内置变量 $host不带端口,$http_host带端口 $arg_name 请求中的的参数名,即“?”后面的arg_name=arg_value形式的arg_name $args 请求中的参数值 $binary_remote_addr 客户端地址的二进制形式, 固定长度为4个字节 $body_bytes_sent 传输给客户端的字节数,响应头不计算在内;这个变量和Apache的mod_log_config模块中的“%B”参数保持兼容 $bytes_sent 传输给客户端的字节数 (1.3.8, 1.2.5) $connection TCP连接的序列号 (1.3.8, 1.2.5) $connection_requests TCP连接当前的请求数量 (1.3.8, 1.2.5) $content_length “Content-Length” 请求头字段 $content_type “Content-Type” 请求头字段 $cookie_name cookie名称 $document_root 当前请求的文档根目录或别名 $document_uri 同 $uri $host 优先级如下:HTTP请求行的主机名>”HOST”请求头字段>符合请求的服务器名 $hostname 主机名 $http_name 匹配任意请求头字段; 变量名中的后半部分“name”可以替换成任意请求头字段,如在配置文件中需要获取http请求头:“Accept-Language”,那么将“-”替换为下 划线,大写字母替换为小写,形如:$http_accept_language即可。 $https 如果开启了SSL安全模式,值为“on”,否则为空字符串。 $is_args 如果请求中有参数,值为“?”,否则为空字符串。 $limit_rate 用于设置响应的速度限制,详见 limit_rate。 $msec 当前的Unix时间戳 (1.3.9, 1.2.6) $nginx_version nginx版本 $pid 工作进程的PID $pipe 如果请求来自管道通信,值为“p”,否则为“.” (1.3.12, 1.2.7) $proxy_protocol_addr 获取代理访问服务器的客户端地址,如果是直接访问,该值为空字符串。(1.5.12) $query_string 同 $args $realpath_root 当前请求的文档根目录或别名的真实路径,会将所有符号连接转换为真实路径。 $remote_addr 客户端地址 $remote_port 客户端端口 $remote_user 用于HTTP基础认证服务的用户名 $request 代表客户端的请求地址 $request_body 客户端的请求主体 此变量可在location中使用,将请求主体通过proxy_pass, fastcgi_pass, uwsgi_pass, 和 scgi_pass传递给下一级的代理服务器。 $request_body_file将客户端请求主体保存在临时文件中。文件处理结束后,此文件需删除。如果需要之一开启此功能,需要设置client_body_in_file_only。如果将次文件传 递给后端的代理服务器,需要禁用request body,即设置proxy_pass_request_body off,fastcgi_pass_request_body off, uwsgi_pass_request_bodyoff, or scgi_pass_request_body off 。 $request_completion 如果请求成功,值为”OK”,如果请求未完成或者请求不是一个范围请求的最后一部分,则为空。 $request_filename 当前连接请求的文件路径,由root或alias指令与URI请求生成。 $request_length 请求的长度 (包括请求的地址, http请求头和请求主体) (1.3.12, 1.2.7) $request_method HTTP请求方法,通常为“GET”或“POST” $request_time 处理客户端请求使用的时间 (1.3.9, 1.2.6); 从读取客户端的第一个字节开始计时。 $request_uri 这个变量等于包含一些客户端请求参数的原始URI,它无法修改,请查看$uri更改或重写URI,不包含主机名,例如:”/cnphp/test.php?arg=freemouse”。 $scheme 请求使用的Web协议, “http” 或 “https” $sent_http_name 可以设置任意http响应头字段; 变量名中的后半部分“name”可以替换成任意响应头字段,如需要设置响应头Content-length,那么将“-”替换为下划 线,大写字母替换为小写,形如:$sent_http_content_length 4096即可。 $server_addr 服务器端地址,需要注意的是:为了避免访问linux系统内核,应将ip地址提前设置在配置文件中。 $server_name 服务器名,www.cnphp.info $server_port 服务器端口 $server_protocol 服务器的HTTP版本, 通常为 “HTTP/1.0” 或 “HTTP/1.1” $status HTTP响应代码 (1.3.2, 1.2.2) $tcpinfo_rtt, $tcpinfo_rttvar, $tcpinfo_snd_cwnd, $tcpinfo_rcv_space 客户端TCP连接的具体信息 $time_iso8601 服务器时间的ISO 8610格式 (1.3.12, 1.2.7) $time_local 服务器时间(LOG Format 格式) (1.3.12, 1.2.7) $uri 请求中的当前URI(不带请求参数,参数位于$args),可以不同于浏览器传递的$request_uri的值,它可以通过内部重定向,或者使用index指令进行修改,$uri不包含 主机名,如”/foo/bar.html”。 匹配符号 模糊匹配:~匹配 !~不匹配 ~×不区分大小写的匹配 精确匹配: =匹配 !=不匹配 常用正则 . : 匹配除换行符以外的任意字符 ? : 重复0次或1次 + : 重复1次或更多次 * : 重复0次或更多次 d :匹配数字 ^ : 匹配字符串的开始 $ : 匹配字符串的介绍 {n} : 重复n次 {n,} : 重复n次或更多次 [c] : 匹配单个字符c [a-z] : 匹配a-z小写字母的任意一个 小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是转义特殊字符。 return指令: 可以返回403, 可以返回url, 可以返回数据。 break 终止。 rewrite语法: rewrite <regex> <replacement> [flag] 关键字 正则 替代内容 flag标记 flag标志位: last: 相当于Apache的[L]标记,表示完成rewrite break: 停止执行当前虚拟主机的后续rewrite指令集 redirect: 返回302临时重定向,地址栏会显示跳转后的地址 permanent: 返回301永久重定向,地址栏会显示跳转后的地址 永久重定向: rewrite ^(.*)$ http://www.jd.com permanent; last使用 工作原理:url重写后,马上发起一个新的请求,再次进入server块,重试location匹配。超过10此匹配不到报500错误,地址栏url不变。 if判断如果是chrome浏览器访问。 就返回新的url http://ip/chrome/$url . 然后拿新的url再去location访问数据。需要创建chorme的目录 location /b { root html; if ($http_user_agent ~* 'chrome'){ rewrite ^(.*)$ /chrome/$1 last; } #http://192.16.16.42/chrome/$uri 重写后的url location /chrome { root html; index index.html; } } 9.优化 优化思路: 充分利用最大服务器性能。并发数。 工作进程优化:大并发优化 优化: cpu的并发数要去测试。先给定一个并发数,看cpu压力。如果压力大,就把并发数调小,反之调大。 netstat -antpl | grep nginx 查看nginx连接数。 top -a 查看cpu使用率 netstat -antpl | grep nginx|grep ESTABLISHED|wc -l 统计连接数。 长连接 优化握手次。 数据压缩 给用户的时候压缩数据:节约带宽。节约时间。 参数 参数说明 说明 说明 客户端缓存 expires 过期时间 1小时。 10.负载均衡 三要素 IP地址 分发器 web服务器 nginx分发器构建web集群:分发器;接受请求和响应请求。 1.ngx_http_upstream_module 基于应用层分发模块。 2.ngx_stream_core_module 基于传输层分发模块 集群原理 虚拟主机+反向代理+upstream分发模块组成。 虚拟主机:接收和响应请求。 反向代理:带用户去数据服务器拿数据。 upstream:告诉nginx去哪个数据服务器拿数据。 分发器配置 nginx分发算法 分发算法:如何将用户请求按照一定的规律分发给业务服务器。 轮询(默认) 基于权重轮询 简介 配置:weight=1 给42服务器分发一个。 给43分发两个。 基于ip_hash: 解决session问题 ip_hash 基于源ip分发 植入ip库,判断ip是哪里的。给分发到哪里的服务器。 基于host主机头,域名分发。 基于开发语言分发 不同语言业务间的分发。 基于浏览器分发 应用于pc和手机端,区分。 第三方 服务器状态 构建高可用Nginx集群:keepalived keepalived简介:高可用就是可用性高。那台机器宕机都切换能正常运行。 运行协议:vrrp 主分发器的kp会向网络中发组播,宣告自己还活着, 组播地址224.0.0.18 下载网址:www.keepalived.org/download.html 安装: systemctl keepalived start 启动 主 1.配置文件中定义脚本 vrrp_script check_nginx { #脚本路径 script "/etc/keepalived/nginx_pid.sh" #探针 每两秒运行一次脚本 interval 2 #失败次数 fall 1 } 2.定义脚本内容 #!/bin/bash nginx_kp_chek () { nginxpid=`ps -C nginx --no-header |wc -l` if [ $nginxpid -eq 0 ];then /usr/local/nginx/sbin/nginx sleep 1 nginxpid=`ps -C nginx --no-header |wc -l` if [ $nginxpid -eq 0 ];then systemctl stop keepalived fi fi } 脚本内容: 脚本文件改权限为 chmod 755 nginx_pid.sh 调用脚本 使用vrrp协议 备 cp主的文件和脚本。 修改 state backup , mcast_src_ip 备的ip 优先级改为比主的低。 RS故障检测机制 upstream web { server 192.168.10.42 max_fail=2 fail_timeout=3; server 192.168.10.43 max_fail=2 fail_timeout=3; #容错机制,3秒内启动两次。启动不起来就是nginx宕机。 } 11.正则表达 . 代表且只能代表任意一个字符(不包括空行) * 重复前面任意0个或多个字符 .* 匹配所有字符。(包括空行) sed -ri 's#(.*)#1#g' bqh.txt 把前面正则匹配的括号内的结果,在后面用1取出来操作。 ^ 表示以什么开头,^bqh 以bqh开头 $ 是以什么结尾 ^$ 表示空行。 例. 就只代表点本身,转义符号,让有着特殊身份移动的字符,脱掉马甲,还原原型$ ^.* 以任意多个字符开头。 .*$ 以任意多个字符结尾。 (.*) 从第一字符匹配,到空格停止, [abc] 匹配字符集合内的任意一个字符【a-zA-Z】 [^abc] 匹配不包括^后的任意字符的内容;中括号里的^为取反,注意和以...开头区别。 a{n,m} 重复n到m次,前一个重复的字符。如果有用egrep/sed -r 可以去掉斜线。 {n,} 重复至少n次,前一个重复的字符。如果有用egrep/sed -r 可以去掉斜线。 {n} 重复n次,前一个重复的字符。如果有用egrep/sed -r 可以去掉斜线。 ①^word 搜索以word开头的;vi ^ 一行的开够 ②word$ 搜索以word结尾的;vi $ 一行的开头 ③^$ 表示空行。 扩展的正则表达式:ERP(egrep或grep -E) + 重复一个或一个以上前面的字符 ? 复0个或一个0前面的字符 | 用或的方式查找多个符合的字符串 () 找出“用户组”字符串