@xushengkai
2022-12-07T01:01:39.000000Z
字数 14070
阅读 234
nginx
[TOC]

Nginx(engine x)是一个高性能的HTTP(解决C10k的问题)和反向代理服务器,也是一个IMAP/POP3/SMTP服务器(收发邮件)。可以做到动静分离,非常强大
c10k:connection连接 10k=10000 也就是万级并发
反向代理服务器:nginx可以做负载均衡和缓存服务器
高并发
IO多路复用
epoll
异步
非阻塞
理论方法
第一种方法:最传统的多进程并发模型,每新进来一个新的I/O流会分配一个新的进程管理
第二种方法:I/O多路复用,单个线程通过记录跟踪每个I/O流的sock状态,来同时管理多个I/O流
发明它的原因,是尽量多的提高服务器的吞吐能力,在同一个线程里面,通过拨开关的方式,来同时传输多个I/O流
技术类型
selecct 仅作了解
poll 仅作了解
epoll
特点
异步,非阻塞
每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker不会这么一直等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。这就是异步。此时,如果再有request 进来,他就可以很快再按这种方式处理。这就是非阻塞和IO多路复用。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。这就是异步回调。
CPU时钟/中断设计
ADSL(非对称数字环路)业务是宽带接入技术中的一种
HTTP--Hyper Text Transfer Protocol,超文本传输协议, 是一种建立在TCP上的无状态连接,整个基本的工作流程是客户端发送一个HTTP请求,说明客户端想要访问的资源和请求的动作,服务端收到请求之后,服务端开始处理请求,并根据请求做出相应的动作访问服务器资源,最后通过发送HTTP响应把结果返回给客户端。其中一个请求的开始到一个响应的结束称为事务,当一个事物结束后还会在服务端添加一条日志条目。
官方网站
https://developer.mozilla.org/zhCN/docs/Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web
简介
统一资源标识符(Uniform Resource Identifier,或URI)HTTP 请求的内容通称为"资源"。”资源“这一概念非常宽泛,它可以是你能够想到的格式。每个资源都由一个 (URI)来进行标识。
URL即统一资源定位符,它是 URI 的一种。一份文档,一张图片,
或所有其他。URI包含URL,URN
URL用于定位
全称叫做:统一资源定位符(URL,英语Uniform Resource Locator的缩写)也被称为网页地址
示例
https://developer.mozilla.orghttps://developer.mozilla.org/en-US/docs/Learn/https://developer.mozilla.org/en-US/search?q=URL在浏览器的地址栏中输入上述任一地址,浏览器就会加载相应的网页(资源)。URL 由多个必须或可选的组件构成。下面给出了一个复杂的 URL:http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument
- 协议
![]()
"http://”告诉浏览器使用何种协议。对于大部分web资源,通常使用HTTP协议或其他安全版本,HTTPS协议。
另外,浏览器也知道如何处理其他协议。例如“ftp”指浏览器处理文件传输。
常见的方案有:主机
![]()
www.example.com既是一个域名,也代表着管理该域名的机构。它指示了需要向网络上哪一台主机发起请求。也可以直接向主机的ip地址发起请求,较不常见。端口
![]()
:80 是端口。它表示用于访问Web服务器上资源的技术“门”。如果访问的该 Web 服务器使用HTTP协议的标准
端口(HTTP为80,HTTPS为443)授予对其资源的访问权限,则通常省略此部分。否则端口就是 URI 必须的部分。路径
![]()
/path/to/myfile.html 是 Web 服务器上资源的路径。在 Web 的早期,类似这样的路径表示Web服务器上的物理文件位置。现在,它主要是由没有任何物理实体的 Web 服务器抽象处理而成的。查询
![]()
?key1=value1&key2=value2 是提供给 Web 服务器的额外参数。这些参数是用 & 符号分隔的键/值对列表。Web 服务器可以在将资源返回给用户之前使用这些参数来执行额外的操作。每个 Web 服务器都有自己的参数规则,想知道特定 Web 服务器如何处理参数的唯一可靠方法是询问该 Web 服务器所有者。片段
![]()
SomewhereInTheDocument 是资源本身的某一部分的一个锚点。锚点代表资源内的一种“书签”,它给予浏览器显示位于该“加书签”点的内容的指示。 例如,在HTML文档上,浏览器将滚动到定义锚点的那个点上;在视频或音频文档上,浏览器将转到锚点代表的那个时间。值得注意的是 # 号后面的部分,也称为片段标识符,永远不会与请求一起发送到服务器。
1.概述
我们获得的图像,影音,广告都是由web服务器 get而来。
概览
协议
客户端(浏览器)
文档组建
视频,文字,图片
2.requests
客户端和服务端通过交换各自的消息来进行交互。通常由像浏览器这样的客户端发出的消息叫做requests,那么被服务端回应的消息就叫做 responses。
3.组件系统
HTTP是一个client-server协议:请求通过一个实体被发出,实体也就是用户代理。大多数情况下,这
个用户代理都是指浏览器,当然它也可能是任何东西,比如一个爬取网页来生成和维护搜索引擎索引的机器。
每一个发送到服务器的请求,都会被服务器处理并且返回一个消息,也就是response。在client与server之
间,还有许许多多的被称为proxies的实体,他们的作用与表现各不相同,比如有些是网关,还有些是caches等。
目的
wget下载一个源码包,分析HTTP头部的信息
通过wget -d选项,学习HTTP头部字段信息。
了解http通信原理,为后期优化打下基础。
1.执行下载
wget -d http://nginx.org/download/nginx-1.12.1.tar.gz#-d:调试信息
2.分析debug信息
DEBUG output created by Wget 1.14 on linux-gnu.URI encoding = “UTF-8”Converted file name 'nginx-1.12.1.tar.gz' (UTF-8) -> 'nginx-1.12.1.tar.Converted file name 'nginx-1.12.1.tar.gz' (UTF-8) -> 'nginx-1.12.1.tar.--2022-12-05 15:59:45-- http://nginx.org/download/nginx-1.12.1.tar.gz正在解析主机 nginx.org (nginx.org)... 3.125.197.172, 52.58.199.22, 2a05Caching nginx.org => 3.125.197.172 52.58.199.22 2a05:d014:edb:5702::6 2正在连接 nginx.org (nginx.org)|3.125.197.172|:80... 已连接。Created socket 3.Releasing 0x0000000000a57a80 (new refcount 1).---request begin--- #请求开始GET /download/nginx-1.12.1.tar.gz HTTP/1.1User-Agent: Wget/1.14 (linux-gnu)Accept: */*Host: nginx.orgConnection: Keep-Alive---request end--- #请求结束已发出 HTTP 请求,正在等待回应...---response begin--- #响应开始HTTP/1.1 200 OKServer: nginx/1.21.5Date: Mon, 05 Dec 2022 07:59:45 GMTContent-Type: application/octet-streamContent-Length: 981093 #总长度Last-Modified: Tue, 11 Jul 2017 15:45:25 GMT #最后一次修改时间Connection: keep-alive #开启了长连接Keep-Alive: timeout=15 #长连接时候15sETag: "5964f295-ef865"Accept-Ranges: bytes---response end--- #响应结束200 OKRegistered socket 3 for persistent reuse.长度:981093 (958K) [application/octet-stream]正在保存至: “nginx-1.12.1.tar.gz”100%[==================================================================2022-12-05 16:00:04 (52.2 KB/s) - 已保存 “nginx-1.12.1.tar.gz” [9810
3.相关资料
HTTP/1.1 HTTP协议版本1.1;
200 OK 响应的状态码是200,即正常返回数据,不同场景会有其它如2xx、3xx、4xx、5xx;
Server 服务器软件是Nginx,版本是1.13.3;
Date 从服务器获取该资源时间,时间差8小时,时区不同;
Content-Type 响应的数据类型,这里的资源是文件,则是application/octet-stream了,其它还有图片,
视频、json、html、xml、css等;
Content-Length response body的长度,也就是源码包的字节大小;
Last-Modified 即下载的文件在服务器端最后修改的时间;
Connection keep-alive Nginx开启了TCP长连接;
ETag ETag HTTP响应头是资源的特定版本的标识符。这可以让缓存更高效,并节省带宽,
因为如果内容没有改变,Web服务器不需要发送完整的响应;
Accept-Ranges 响应头 Accept-Range 标识自身支持范围请求,字段值用于定义范围请求的单位。
206 Partial Content
Accept-Ranges 告诉我们服务器是否支持指定范围请求及哪种类型的分段请求,这里是byte
Content-Range 告诉我们在整个返回体中本部分的字节位置,我们请求的是图片的前100字节
Mainline version: 主线版,即开发版
Stable version: 最新稳定版,生产环境上建议使用的版本
Legacy versions: 遗留的老版本的稳定版
1.准备一台全新的虚机,配置好阿里的yum仓库,查看系统内核版本,关闭防火墙,selinux
[root@192 ~]# uname -r3.10.0-862.el7.x86_64[root@192 ~]# cat /etc/redhat-releaseCentOS Linux release 7.5.1804 (Core)
2.根据官网的提示安装
[root@192 ~]# sudo yum install yum-utils要设置 yum 存储库,请创建具有以下内容命名的文件:/etc/yum.repos.d/nginx.repo[root@192 ~]# vim /etc/yum.repos.d/nginx.repo[nginx-stable]name=nginx stable repobaseurl=http://nginx.org/packages/centos/$releasever/$basearch/gpgcheck=1enabled=1gpgkey=https://nginx.org/keys/nginx_signing.keymodule_hotfixes=true[nginx-mainline]name=nginx mainline repobaseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/gpgcheck=1enabled=0gpgkey=https://nginx.org/keys/nginx_signing.keymodule_hotfixes=true[root@192 ~]# yum makecache[root@192 ~]# yum -y install nginx
3.启动测试
[root@192 ~]# systemctl start nginx[root@192 ~]# systemctl enable nginx[root@192 ~]# nginx -vnginx version: nginx/1.22.1打开浏览器输入服务器ip就可以访问nginx页面
需要记住的
/etc/logrotate.d/nginx 日志轮转文件/etc/nginx/nginx.conf nginx主配置文件/etc/nginx/conf.d nginx的子配置文件/etc/nginx/conf.d/default.conf nginx默认网站配置文件/etc/nginx/mime.types 文件关联程序,网站文件类型和相关处理程序/etc/nginx/modules 模块目录,第三方模块/usr/lib/systemd/system/nginx.service nginx服务脚本/usr/sbin/nginx nginx主程序/var/cache/nginx 各种缓存/var/log/nginx 日志主目录
了解即可
/etc/nginx/fastcgi_params/etc/nginx/scgi_params/etc/nginx/uwsgi_params 动态网站模块文件-python,php所需的相关变量/usr/lib/systemd/system/nginx-debug.service nginx调试程序启动脚本/usr/share/doc/nginx-1.22.1/usr/share/doc/nginx-1.22.1/COPYRIGHT/usr/share/man/man8/nginx.8.gz/usr/share/nginx/usr/share/nginx/html/usr/share/nginx/html/50x.html/usr/share/nginx/html/index.html nginx帮助手册就是这几个文件提供的
[root@192 ~]# nginx -Vnginx version: nginx/1.22.1built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)built with OpenSSL 1.0.2k-fips 26 Jan 2017TLS SNI support enabledconfigure arguments: 配置参数./configure --help查询帮助--prefix=/etc/nginx 安装路径--sbin-path=/usr/sbin/nginx 程序文件--modules-path=/usr/lib64/nginx/modules 模块文件--conf-path=/etc/nginx/nginx.conf 主配置文件--error-log-path=/var/log/nginx/error.log 错误日志--http-log-path=/var/log/nginx/access.log 访问日志--pid-path=/var/run/nginx.pid 程序ID--lock-path=/var/run/nginx.lock 启动锁文件,防止重复启动nginx--http-client-body-temp-path=/var/cache/nginx/client_temp 缓存--http-proxy-temp-path=/var/cache/nginx/proxy_temp 代理缓存--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp php缓存--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp python缓存--user=nginx 用户--group=nginx 组--with-compat 启动动态模块兼容性--with-file-aio 使用nginx的aio特性会大大提高性能,比如图片网站的特点是大量的读IO操作,nginx aio不用等待每次的IO结果,有助于并发处理大量IO和提高nginx 处理效率aio的优点就是能够同时提交多个IO请求给内核,然后直接由内核的IO调度算法去处理这些的请求(directio),这样的话内核就有可能执行一些合并,节约了读取文件的处理时间,就是异步非阻塞--with-threads 多线程模块--with-http_addition_module 追加模块,响应之前或者之后追加文本内容,比如想站在站点底部追加一个js广告或者新增的css样式--with-http_auth_request_module 认证模块--with-http_dav_module 增加上传,创建集合,默认情况下为关闭--with-http_flv_module 添加mp4,flv视频支持模块--with-http_gunzip_module--with-http_gzip_static_module 压缩模块--with-http_mp4_module 多媒体模块--with-http_random_index_module 随机主页模块--with-http_realip_module 获取真实IP模块--with-http_secure_link_module 安全下载模块--with-http_slice_module nginx中文文档--with-http_ssl_module 安全模块--with-http_stub_status_module 访问状态模块--with-http_sub_module nginx替换网站响应内容--with-http_v2_module web2.0模块--with-mail--with-mail_ssl_module 邮件客户端--with-stream--with-stream_realip_module--with-stream_ssl_module--with-stream_ssl_preread_module 负载均衡模块--with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong--param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC'--with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'CPU优化参数
CoreModule核心模块:全局/核心模块,配置影响nginx全局的指令,一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker,process等
EventsModule 事件驱动模块(工作模式等):配置影响nginx服务器或与用户的网络连接,有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网络连接,开启多个网络连接序列化等
HttpCoreModule http内核模块(文档程序类型配置文件等): http块可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
server块:配置虚拟主机的相关参数,一盒htpp中可以有多个server
location块:配置请求的路由,以及各种页面的处理情况
[root@192 ~]# vim /etc/nginx/nginx.conf1 #核心模块2 user nginx;#nginx程序装上以后会系统自动创建一个nginx用户3 worker_processes 2;#开启进程的数量,服务器有几个cpu就对应几个进程,可以设置为auto4 error_log /var/log/nginx/error.log;#错误日志的存储位置5 pid /run/nginx.pid;#进程的号码文件,方便系统调用6789#事件驱动模块10 events {11 worker_connections 10240;12 }13 #最大可以为10240个用户服务#http模块14 http {15 include /etc/nginx/mime.types;16 default_type application/octet-stream;17 #默认以字节流处理方式18 log_format main '$remote_addr - $remote_user [$time_local] "$reques t" '19 '$status $body_bytes_sent "$http_referer" '20 '"$http_user_agent" "$http_x_forwarded_for"';#18-20行日志的格式2122 access_log /var/log/nginx/access.log main;23 #访问日志24 sendfile on;25 #tcp_nopush on;2627 keepalive_timeout 65;2829 #gzip on;3031 include /etc/nginx/conf.d/*.conf;32 } #子配置文件
[root@192 ~]# vim /etc/nginx/conf.d/default.conf1 server {2 listen 80;#监听的端口,改端口就在这里改3 server_name localhost;4 #服务器购买的域名,将localhost替换成域名5 #access_log /var/log/nginx/host.access.log main;6 #日志的位置7 location / {8 root /usr/share/nginx/html;9 index index.html index.htm;10 } #网站某一个网页的位置,index默认主页文件名11#11行以后内容下个篇章看,做动态网站和代理用的。······
1.创建一个新的虚拟主机配置文件
[root@192 ~]# vim /etc/nginx/conf.d/xsk.confserver {listen 80;server_name xsk.com;location / {root /xsk;index index.html;}}准备网站[root@192 ~]# mkdir /xsk[root@192 ~]# echo "徐圣凯真棒" >/xsk/index.html
2.重启服务
[root@192 ~]# systemctl restart nginx
3.设置域名解析
[root@192 ~]# vim /etc/hosts127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4::1 localhost localhost.localdomain localhost6 localhost6.localdomain6192.168.200.149 xsk.com
4.访问
利用elinks纯字符浏览器访问[root@192 ~]# elinks http://xsk.com看到页面显示徐圣凯真棒,实验成功
1.模块
日志模块的名称
ngx_http_log_module
2.相关指令
log_format
access-log
error_log
open_log_file_cache
简介:Nginx有非常灵活的日志记录模式,每个级别的配置可以有各自独立的访问日志,日志格式通过log_format命令定义
语法:log_format name [escape=default | json] string
name表示格式的名称,string表示定义的格式
定义设置的位置
在nginx的主配置文件中log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';
日志格式允许包含的变量,跟日志记录相对应
$remote_addr: 远程地址,记录客户端的ip地址,如果有客户端访问就会在日志中被记录下来- $remote_user:远程用户,记录客户端用户名称,如果有客户端访问就会在日志中被记录下来[$time_local]:本地时间,服务器的时间$request:请求内容,记录请求的URL和HTTP协议$status:状态,记录请求的状态,最常见的找不到页面显示404$body_bytes_sent:发给客户端的字节数,不包括响应头的大小$http_referer:记录从哪个页面访问过来的(超链接)$http_user_agent:记录客户端浏览器的相关信息$http_x_forwarded_for:代理IP
1.access_log
[root@xsk ~]# tail -1 /var/log/nginx/access.log-20221201192.168.200.149 - - [30/Nov/2022:21:40:46 +0800] "GET / HTTP/1.1" 200 16 "-" "ELinks/0.12pre6 (textmode; Linux; 77x27-2)" "-"日志记录解释:客户端的IP -分隔符 -用户名,匿名的 [访问时间] "获取网站的位置/ http/1.1 http的版本" 200状态码 16文件的字节数 "浏览器的相关信息"
2.error_log
[root@xsk ~]# tail /var/log/nginx/error.log2022/12/01 11:21:59 [error] 1065#1065: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.200.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.200.149", referrer: "http://192.168.200.149/"
3.案例:自定义404错误页面
修改主配置文件[root@xsk ~]# vim /etc/nginx/conf.d/xsk.confserver {listen 80;server_name xsk.com;location / {root /xsk;index index.html;}#添加下面几行error_page 404 /404.html;location = /404.html {root /xsk;}}[root@xsk ~]# systemctl restart nginx
3.2创建错误访问页面
[root@xsk xsk]# vim /xsk/404.html<img src="404.jpg" />浏览器访问不存在的页面查看显示结果
1.简介
大量的访问到来时,对于每一条日志记录,都是先打开文件,再写入日志,然后关闭,占用了系统的IO,与业务无关,可以使用open_log_file_cache来设置
2.语法:
open_log_file_cache max=1000 inactive=20s min_uses=3 valid=1
max=1000指的是日志文件的FD,最大的缓存数量为1000,如果超过了怎么办?往下看
min_uses=3 20s内小于3次访问的FD,就给你清掉,结合inactive20秒时间
valid=1m 检查周期为1分钟总结:缓存最多到了1000个,到了极限每分钟开始清除掉,20秒内小于3次文件FD,默认是关闭的,在生产和环境中也建议不开,因为打开会占用内存资源
3.示例
[root@xsk xsk]# vim /etc/nginx/conf.d/xsk.confserver {open_log_file_cache max=1000 inactive=20s min_uses=3 valid=1m;listen 80;server_name xsk.com;location / {root /xsk;index index.html;}error_page 404 /404.html;location = /404.html {root /xsk;}}
安装Nginx,会默认启动日志轮转
[root@xsk xsk]# vim /etc/logrotate.d/nginx/var/log/nginx/*.log { #日志的位置,对所有日志进行轮转daily #按天轮转missingok #丢失不提示rotate 52 #保留52天compress #压缩delaycompress #延迟压缩notifempty #空文件不进行轮转create 640 nginx adm #日志被切割后的权限sharedscripts #切割完成后重启nginxpostrotateif [ -f /var/run/nginx.pid ]; thenkill -USR1 `cat /var/run/nginx.pid`fiendscript}
常用字段
$remote_addr $1$time_local $4$request $7$status $9$body_bytes_set $10
案例样本
1.统计一天的PV量
grep '日期' 日志文件 | wc -l
2.统计一天访问最多的10个IP
grep '日期' 日志文件 | awk '{ips[$1]++}END{for(i in ips){print i,ips[i]}}' | sort -k2 -rn
3.统计一天访问大于100次的IP
grep '日期' 日志文件| awk '{ips[$1]++}END{for (i in ips){if(ips[i]>100) {print i,ips[i]}}}'
4.统计一天访问最多的10个页面($repuest)
grep '日期' 日志文件 | awk '{url[$7]++}END{for(i in url){print url[i],i}}' | sort -k1 -rn | head -10
5.统计一天每个URL访问内容总大小($body_bytes_sent)
次数:grep '日期' 日志文件 | awk '{urls[$7]++;size[$7]+=$10}END{for(i in urls){print urls[i],size[i],i}}' | sort -k1 -rn | head -10大小:grep '日期' 日志文件 | awk '{urls[$7]++;size[$7]+=$10}END{for(i in urls){print urls[i],size[i],i}}' | sort -k2 -rn | head -10
6.统计一天每个IP访问状态码数量($status)
grep '日期' 日志文件 | awk '{ip_code[$1" "$9]++}END{for(i in ip_code){print i,ip_code[i]}}' | sort -k3 -rn | head -10
7.统计一天每个IP访问状态码为404及出现次数($status)
第一种:grep '日期' 日志文件 | awk '{if($9="404"){ip_code[$1" "$9]++}}END{for(i in ip_code){print i,ip_code[i]}}'
8.统计前一分钟的PV量
[root@xsk ~]# shijian=`date -d '-1 minute' +%Y:%H:%M` ; awk -v xsk=$shijian '$0 ~ shijian{i++} END{print i}' /var/log/nginx/access.log195参数解释:shell中的变量在awk程序中无法使用,因为在执行awk时,是一个新的进程去处理的,因此就需要-v来向awk传参,