nginx/nginx基础.md
2025-03-10 19:29:08 +08:00

408 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<h2><center>Nginx基础</center></h2>
------
## 一:简介
Nginx的官方网站www.nginx.org
### 1. 介绍
nginxengine 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<UP,BROADCAST,RUNNING,MULTICAST> 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<link>
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<UP,BROADCAST,RUNNING,MULTICAST> 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<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
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
```