16 KiB
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进程。
# 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编译参数
--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块。
# 全局参数设置
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服务,每个虚拟主机之间是独立的,互不影响。
2. 虚拟主机类型
- 基于域名的虚拟主机
- 基于IP的虚拟主机
- 基于端口的虚拟主机
3. 基于域名的虚拟主机
创建虚拟主机配置文件:
[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/下),并创建对应的网站:
[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
重新加载配置文件:
[root@test ~]# nginx -s reload
客户端配置路由映射(本地域名解析):
[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
测试访问:
[root@test ~]# curl www.wxin.com
web1
[root@test ~]# curl www.wxin1.com
web2
4. 基于IP的虚拟主机
添加IP地址:
[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区分的虚拟机:
[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;
}
}
重新加载配置文件:
[root@test ~]# nginx -s reload
创建网站:同上
测试访问:
[root@test ~]# curl http://192.168.159.130
web1
[root@test ~]# curl http://192.168.159.131
web2
5. 基于端口的虚拟主机
创建虚拟主机配置文件:
[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;
}
}
创建网站:同上
重新加载配置文件:
[root@test ~]# nginx -s reload
测试访问:
[root@test ~]# curl www.wxin.com
web1
[root@test ~]# curl www.wxin.com:8080
web2