Nginx基础

------ ## 一:简介 Nginx的官方网站:www.nginx.org ### 1. 介绍 ​ nginx(engine x)是一个高性能的开源的HTTP和反向代理web服务,同时提供IMAP/POP3/SMTP服务。 ​ nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。在BSD-like协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好。 ​ nginx处理高并发能力是十分强大的,能经受高负载,支持高达50,000个并发连接数。 ​ nginx支持热部署,启动简单。 ​ nginx的功能:web服务器、代理服务器、负载均衡器。 ​ nginx有模块化组成,支持异步,非阻塞。 ### 2. 异步,非阻塞 ​ 每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker不会这么一直等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。这就是异步。此时,如果再有request 进来,他就可以很快再按这种方式处理。这就是非阻塞和IO多路复用。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。这就是异步回调。 案例: ​ 客户(发送方)向收款员(接收方)付款(发送请求)后在等待收款员找零的过程中,还可以做其他事情,比如打电话、聊天等;而收款员在等待收款机处理交易(IO操作)的过程中还可以帮助客户将商品打包,当收款机产生结果后,收款员给客户结账(响应请求)。在四种方式中,这种方式是发送方和接收方通信效率最高的一种。 #### 同步异步 ​ 同步与异步的重点在消息统治的方式上,也就是调用结果通知的方式。 ​ 同步:当一个同步调用发出去后,调用者要一直等待调用结果的通知后,才能进行后续的执行。 ​ 异步:当一个异步调用发出去后,调用者不能立即得到调用结果的返回。 ​ 异步调用要想获得结果,一般有两种方式: - 主动轮询异步调用的结果。 - 被调用方通过callback来通知调用方调用结果。 案例: ​ 同步取快递:小明收到快递将送达的短信,在楼下一直等到快递送达。 ​ 异步取快递:小明收到快递将送达的短信,快递到楼下后,小明在下楼去取。 ​ 异步取快递,小明知道快递到达楼下有两种方式: - 不停的电话问快递小哥到了没有,即主动轮询 - 快递小哥到楼下后,打电话通知小明,然后小明下楼取快递,即回调通知。 #### 阻塞非阻塞 ​ 阻塞与非阻塞在于进/线程等待消息时候的行为,也就是在等待消息的时候,当前进/线程是挂起还是非挂起状态。 ​ 阻塞:阻塞调用在发出去后,在消息返回之前,当前进/线程会被挂起,直到有消息返回,当前进/线程才会被激活。 ​ 非阻塞:非阻塞调用在发出去后,不会阻塞当前进/线程,而会立即返回。 案例: ​ 阻塞取快递:小明收到快递即将送达的信息后,什么事都不做,一直专门等快递。 ​ 非阻塞取快递:小明收到快递即将送达的信息后,等快递的时候,还一边敲代码、一边刷微信。 **同步与异步,重点在于消息通知的方式;阻塞与非阻塞,重点在于等消息时候的行为。** 所以,就有了下面4种组合方式: - 同步阻塞:小明收到信息后,啥都不干,等快递; - 同步非阻塞:小明收到信息后,边刷微博,边等着取快递; - 异步阻塞:小明收到信息后,啥都不干,一直等着快递员通知他取快递; - 异步非阻塞:小明收到信息后,边刷着微博,边等快递员通知他取快递。 #### I/O多路复用 ### 3. 内部结构 ​ nginx启功是,会产生两种类型的进程,一个是主程序(Master),一个或多个工作进程(Worker)。主进程并不处理网络请求,主要负责调度工作进程,也就是:加载配置、启动工作进程及非停升级。所以,nginx启动以后,查看操作系统的进程列表,我们就能看到至少有两个nginx进程。 ```bash # ps -aux | grep nginx root 3021 0.0 0.0 49076 1092 ? Ss 09:55 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf nginx 3022 0.0 0.1 51556 2112 ? S 09:55 0:00 nginx: worker process nginx 3023 0.0 0.1 51556 2128 ? S 09:55 0:00 nginx: worker process nginx 3024 0.0 0.1 51556 2356 ? S 09:55 0:00 nginx: worker process nginx 3025 0.0 0.1 51556 2100 ? S 09:55 0:00 nginx: worker process ``` ​ 服务器实际处理网络请求及响应的是工作进程(worker),在类UNIX系统上,nginx可以配置多个worker,而每一个worker进程都可以同时处理数以千计的网络请求。 ​ 模块化设计。nginx的worker,包括核心和功能性模块,核心模块负责维持一个运行循环(run-loop),执行网络请求处理的不同阶段的模块功能,如网络重写、存储读写、内容传输、外出过滤,以及将请求发往上游服务器等。而其代码的模块化设计,也使得我们可以根据需要对功能模块进行适当的选择和修改,编译成具有特定功能的服务器。 ​ 事件驱动、异步及非阻塞,可以说是nginx得以获得高并发、高性能的关键因素,同时也得益于对Linux、Solaris及类BSD等操作系统内核中事件通知及I/O性能增强功能的采用,如kqueue、epoll及event ports。 ​ 代理(proxy)设计,可以说是nginx深入骨髓的设计,无论是对于HTTP,还是对于FastCGI、memcache、Redis等的网络请求或响应,本质上都采用了代理机制。所以,nginx天生就是高性能的代理服务器。 ## 二:文件详解 ### 1. nginx编译参数 ```shell --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 //指定pid文件 --lock-path=/var/run/nginx.lock //指定lock文件 --http-client-body-temp-path=/var/cache/nginx/client_temp //设定http客户端请求临时文件路径 --http-proxy-temp-path=/var/cache/nginx/proxy_temp //设定http代理临时文件路径 --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp //设定http fastcgi临时文件路径 --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp //设定http uwsgi临时文件路径 --http-scgi-temp-path=/var/cache/nginx/scgi_temp //设定http scgi临时文件路径 --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-debug //启用debug日志 --with-pcre-jit //编译PCRE包含“just-in-time compilation” --with-ipv6 //启用ipv6支持 --with-http_addition_module //作为一个输出过滤器,支持不完全缓冲,分部分响应请求 --with-http_auth_request_module //实现基于一个子请求的结果的客户端授权。如果该子请求返回的2xx响应代码,所述接入是允许的。如果它返回401或403中,访问被拒绝与相应的错误代码。由子请求返回的任何其他响应代码被认为是一个错误。 --with-http_dav_module //增加PUT,DELETE,MKCOL:创建集合,COPY和MOVE方法 默认关闭,需编译开启 --with-http_flv_module --with-http_geoip_module //使用预编译的MaxMind数据库解析客户端IP地址,得到变量值 --with-http_gunzip_module //它为不支持“gzip”编码方法的客户端解压具有“Content-Encoding: gzip”头的响应。 --with-http_gzip_static_module //在线实时压缩输出数据流 --with-http_image_filter_module //传输JPEG/GIF/PNG 图片的一个过滤器)(默认为不启用。gd库要用到) --with-http_mp4_module --with-http_random_index_module --with-http_realip_module //允许从请求标头更改客户端的IP地址值,默认为关 --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module //启用ssl支持 --with-http_stub_status_module //获取nginx自上次启动以来的状态 --with-http_spdy_module //SPDY可以缩短网页的加载时间 --with-http_sub_module //允许用一些其他文本替换nginx响应中的一些文本 --with-http_v2_module --with-http_xslt_module //过滤转换XML请求 --with-mail //启用POP3/IMAP4/SMTP代理模块支持 --with-mail_ssl_module //启用ngx_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' ``` ### 2. Nginx配置文件详解 ​ nginx.conf的组成:nginx.conf一共由三部分组成,分别为:全局块、events块、http块。 ​ 在http块中又包含http全局块、多个server块。 ​ 每个server块中又包含server全局块以及多个location块。 ```shell # 全局参数设置 user nginx; worker_processes auto; #设置nginx启动进程的数量,一般设置成与逻辑cpu数量相同 注意: 1.物理cpu数:主板上实际插入的cpu数量,可以数不重复的 physical id 有几个(physical id) 2.cpu核数:单块CPU上面能处理数据的芯片组的数量,如双核、四核等 (cpu cores) 3.逻辑cpu数:一般情况下,逻辑cpu=物理CPU个数×每颗核数 error_log /var/log/nginx/error.log notice; #指定错误日志 pid /var/run/nginx.pid; events { worker_connections 1024; #设置一个进程的最大并发连接数 } http { include /etc/nginx/mime.types; default_type application/octet-stream; #如果MIME文件未定义,浏览器默认下载。 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 /var/log/nginx/access.log main; #设置访问日志的位置和格式 sendfile on; #是否调用sendfile函数输出文件,一般设置为on,若nginx是用来进行磁盘IO负载应用时,可以设置为off,降低系统负载 #tcp_nopush on; # 合并数据包减少网络调用 keepalive_timeout 65; #设置长连接的超时时间 #gzip on; #是否开启gzip压缩,将注释去掉开启 include /etc/nginx/conf.d/*.conf; #加载子配置文件 } ``` ## 三:Nginx虚拟主机 ### 1. 什么是虚拟主机 ​ 虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主机,每个虚拟主机可以独立对外提供www服务,这样就可以实现一台主机对外提供多个web服务,每个虚拟主机之间是独立的,互不影响。 ![](http://182.92.143.66:40072/directlink/img/nginx/image-202502220001.png) ### 2. 虚拟主机类型 - 基于域名的虚拟主机 - 基于IP的虚拟主机 - 基于端口的虚拟主机 ### 3. 基于域名的虚拟主机 创建虚拟主机配置文件: ```bash [root@test ~]# vim /etc/nginx/conf.d/test.conf server { listen 80; server_name www.wxin.com; location / { root /usr/share/nginx/web1; index index.html index.htm; } } server { listen 80; server_name www.wxin1.com; location / { root /usr/share/nginx/web2; index index.html index.htm; } } ``` 创建网站发布目录(在/usr/share/nginx/下),并创建对应的网站: ```bash [root@test ~]# mkdir /usr/share/nginx/web1 [root@test ~]# mkdir /usr/share/nginx/web2 [root@test ~]# echo "web1" > /usr/share/nginx/web1/index.html [root@test ~]# echo "web2" > /usr/share/nginx/web2/index.html ``` 重新加载配置文件: ```bash [root@test ~]# nginx -s reload ``` 客户端配置路由映射(本地域名解析): ```bash [root@test ~]# vim /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.159.130 www.wxin.com 192.168.159.130 www.wxin1.com ``` 测试访问: ```bash [root@test ~]# curl www.wxin.com web1 [root@test ~]# curl www.wxin1.com web2 ``` ### 4. 基于IP的虚拟主机 添加IP地址: ```bash [root@test ~]# ifconfig ens33:1 192.168.159.131/24 [root@test ~]# ifconfig ens33: flags=4163 mtu 1500 inet 192.168.159.130 netmask 255.255.255.0 broadcast 192.168.159.255 inet6 fe80::9e8b:2599:99f6:4087 prefixlen 64 scopeid 0x20 ether 00:0c:29:0a:e2:2b txqueuelen 1000 (Ethernet) RX packets 546698 bytes 785195981 (748.8 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 159219 bytes 9799907 (9.3 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ens33:1: flags=4163 mtu 1500 inet 192.168.159.131 netmask 255.255.255.0 broadcast 192.168.159.255 ether 00:0c:29:0a:e2:2b txqueuelen 1000 (Ethernet) lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1000 (Local Loopback) RX packets 148 bytes 13994 (13.6 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 148 bytes 13994 (13.6 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ``` 配置通过IP区分的虚拟机: ```bash [root@test ~]# vim /etc/nginx/conf.d/test.conf server { listen 192.168.159.130:80; server_name www.wxin.com; location / { root /usr/share/nginx/web1; index index.html index.html; } } server { listen 192.168.159.131:80; server_name www.wxin1.com; location / { root /usr/share/nginx/web2; index index.html index.html; } } ``` 重新加载配置文件: ```bash [root@test ~]# nginx -s reload ``` 创建网站:同上 测试访问: ```bash [root@test ~]# curl http://192.168.159.130 web1 [root@test ~]# curl http://192.168.159.131 web2 ``` ### 5. 基于端口的虚拟主机 创建虚拟主机配置文件: ```bash [root@test ~]# vim /etc/nginx/conf.d/test.conf server { listen 80; server_name www.wxin.com; location / { root /usr/share/nginx/web1; index index.html index.html; } } server { listen 8080; server_name www.wxin.com; location / { root /usr/share/nginx/web2; index index.html index.html; } } ``` 创建网站:同上 重新加载配置文件: ```bash [root@test ~]# nginx -s reload ``` 测试访问: ```bash [root@test ~]# curl www.wxin.com web1 [root@test ~]# curl www.wxin.com:8080 web2 ```