Nginx 安装以及简单配置

深入理解 Nginx 服务 - 1

一、Nginx 介绍

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k44KDC2G-1585544628184)(assets/nginx.jpg)]

  • Nginx (engine x) 是一个高性能的 HTTP 和 反向代理 服务,也是一个IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。

  • Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

  • 在高连接并发的情况下,Nginx是Apache服务器不错的替代品。

  • 创始人伊戈尔·赛索耶夫

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B77diE0U-1585544628186)(assets/2fdda3cc7cd98d10d7efa38e2b3fb80e7bec9052.jpg)]

二、为什么选择 Nginx

1、特性介绍

  • Nginx 是一个高性能的 Web 和反向代理服务器, 它具有有很多非常优越的特性:

1、作为 Web 服务器

  • 可以作为HTTP 代理服务器和反向代理服务器,支持通过缓存加速访问,可以完成简单的负载均衡和容错,支持包过滤功能,支持SSL等,相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。能够支持高达 50,000 个并发连接数的响应,感谢 Nginx 为我们选择了 epoll and kqueue 作为开发模型.

2、作为负载均衡服务器

  • 可以进行自定义配置,支持虚拟主机,支持URL重定向,支持网络监控,支持流媒体传输等。Nginx 既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP代理服务器 对外进行服务。Nginx 用 C 编写, 不论是系统资源开销还是 CPU 使用效率都比 Perlbal 要好的多。

3、作为邮件代理服务器:

  • Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器),他支持IMAP/POP3 代理服务功能,支持内部SMTP代理服务功能。

4、Nginx 优点

  • Nginx 安装非常的简单,配置文件 非常简洁(还能够支持perl语法),Bugs非常少的服务器: Nginx 启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够在 不间断服务的情况下进行软件版本的升级。

2、Nginx VS Apache

1、内核和功能上的比较

特性 Nginx Apache
请求管理 事件驱动模型使用异步套接字处理,较少了内存和CPU开销 同步套接字、进程和线程每个请求都要使用一个单独的进程或线程,使用同步套接字
设计语言 C C、C++
可移植性 多平台 多平台
诞生时间 2002 1994

2、一般功能比较

功能 Nginx Apache
HTTPS支持 作为模块支持 作为模块支持
虚拟主机 原生支持 原生支持
CGI支持 仅支持FastCGI 支持CGI和FastCGI
系统模块 静态模块系统 动态模块系统
  • 从以上功能上的对比,我们很难发现那些功能 Apache 无法实现。那我们为什么更喜欢用Nginx 呢,Nginx 相对 Apache 有那些有点呢?

3、Nginx 相对 apache 的优点

  • 轻量级,同样起web 服务比Apache 占用更少的内存及资源

  • 静态处理,Nginx 静态处理性能比 Apache 高 3倍以上

  • 抗并发,Nginx 处理请求是异步非阻塞的,而Apache则是阻塞型的。在高并发下Nginx 能保持低资源低消耗高性能。在Apache+PHP(prefork)模式下,如果PHP处理慢或者前端压力很大的情况下,很容易出Apache进程数飙升,从而拒绝服务的现象。

  • 高度模块化的设计,编写模块相对简单

  • 社区活跃,各种高性能模块出品迅速

三、Nginx IO多路复用

1、I/O multiplexing【多并发】

第一种方法就是最传统的多进程并发模型 (每进来一个新的I/O流会分配一个新的进程管理。)

第二种方法就是I/O多路复用 (单个线程,通过记录跟踪每个I/O流(sock)的状态,来同时管理多个I/O流 。)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1kxqRZHR-1585544628187)(assets/1.png)]

I/O multiplexing 这里面的 multiplexing 指的其实是在单个线程通过记录跟踪每一个Sock(I/O流)的状态来同时管理多个I/O流。发明它的原因,是尽量多的提高服务器的吞吐能力。在同一个线程里面, 通过拨开关的方式,来同时传输多个I/O流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0j3hvJEb-1585544628188)(assets/2-1552270732106.png)]

2、nginx 事件驱动

一个请求到来了,nginx接收请求的过程是怎样的?

ngnix会有很多连接进来, epoll会把他们都监视起来,然后像拨开关一样,谁有数据就拨向谁,然后调用相

应的代码处理。

  • select, poll, epoll 都是I/O多路复用的具体的实现,其实是他们出现是有先后顺序的。

I/O多路复用这个概念被提出来以后, 相继出现了多个方案

  • select 是第一个实现 (1983 左右在BSD里面实现的)。

select 被实现以后,很快就暴露出了很多问题。

• select 会修改传入的参数数组,这个对于一个需要调用很多次的函数,是非常不友好的。

• select 如果任何一个sock(I/O stream)出现了数据,select 仅仅会返回,但是并不会告诉你是那个sock上有数

据,于是你只能自己一个一个的找,10几个sock可能还好,要是几万的sock每次都找一遍…

• select 只能监视1024个链接。

• select 不是线程安全的,如果你把一个sock加入到select, 然后突然另外一个线程发现,这个sock不用,要收

回,这个select 不支持的,如果你丧心病狂的竟然关掉这个sock, select的标准行为是不可预测的

  • 于是14年以后(1997年)一帮人又实现了poll, poll 修复了select的很多问题,比如

• poll 去掉了1024个链接的限制,于是要多少链接呢, 主人你开心就好。

• poll 从设计上来说,不再修改传入数组,不过这个要看你的平台了,所以行走江湖,还是小心为妙。

其实拖14年那么久也不是效率问题, 而是那个时代的硬件实在太弱,一台服务器处理1千多个链接简直就是神

一样的存在了,select很长段时间已经满足需求。

但是poll仍然不是线程安全的, 这就意味着,不管服务器有多强悍,你也只能在一个线程里面处理一组I/O流。

你当然可以那多进程来配合了,不过然后你就有了多进程的各种问题。

  • 于是5年以后, 在2002, 大神 Davide Libenzi 实现了epoll.

epoll 可以说是I/O 多路复用最新的一个实现,epoll 修复了poll 和select绝大部分问题, 比如:

• epoll 现在是线程安全的。

• epoll 现在不仅告诉你sock组里面数据,还会告诉你具体哪个sock有数据,你不用自己去找了。

3、异步非阻塞

[[email protected]  ~]# pstree |grep nginx
 |-+= 81666 root nginx: master process nginx
 | |--- 82500 nobody nginx: worker process
 | \--- 82501 nobody nginx: worker process
  • 1个master进程,2个work进程

  • ​ 每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker不会这么一直等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。这就是异步。此时,如果再有request 进来,他就可以很快再按这种方式处理。这就是非阻塞和IO多路复用。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。这就是异步回调。

四、Nginx 的内部技术架构

  • Nginx服务器,以其处理网络请求的高并发、高性能及高效率,获得了行业界的广泛认可,近年已稳居web服务器部署排名第二的位置,并被广泛用于反向代理和负载均衡。

  • Nginx是如何实现这些目标的呢?答案就是其独特的内部技术架构设计。看懂下面这张图,就明白了Nginx的内部技术架构。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JjNWlFPU-1585544628189)(assets/2517ca78056c497db1c3a804118bb891_th.png)]

  • 简要说明几点:

1、nginx启动时,会生成两种类型的进程,一个是主进程(Master),一个(windows版本的目前只有一个)或多个工作进程(Worker)。主进程并不处理网络请求,主要负责调度工作进程,也就是图示的三项:加载配置、启动工作进程及非停升级。所以,nginx启动以后,查看操作系统的进程列表,我们就能看到至少有两个nginx进程。

2、服务器实际处理网络请求及响应的是工作进程(worker),在类unix系统上,nginx可以配置多个worker,而每个worker进程都可以同时处理数以千计的网络请求。

3、模块化设计。nginx的worker,包括核心和功能性模块,核心模块负责维持一个运行循环(run-loop),执行网络请求处理的不同阶段的模块功能,如网络读写、存储读写、内容传输、外出过滤,以及将请求发往上游服务器等。而其代码的模块化设计,也使得我们可以根据需要对功能模块进行适当的选择和修改,编译成具有特定功能的服务器。

4、事件驱动、异步及非阻塞,可以说是nginx得以获得高并发、高性能的关键因素,同时也得益于对Linux、Solaris及类BSD等操作系统内核中事件通知及I/O性能增强功能的采用,如kqueue、epoll及event ports。

5、代理(proxy)设计,可以说是nginx深入骨髓的设计,无论是对于HTTP,还是对于FastCGI、memcache、Redis等的网络请求或响应,本质上都采用了代理机制。所以,nginx天生就是高性能的代理服务器

五、Nginx 安装部署和配置管理

1、nginx 部署-Yum

  • 访问 nginx官方网站:http://www.nginx.org

  • Nginx版本类型

  • Mainline version: 主线版,即开发版

  • Stable version: 最新稳定版,生产环境上建议使用的版本

  • Legacy versions: 遗留的老版本的稳定版

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WY4lHJYr-1585544628190)(assets/捕获.PNG)]

1、官方 Yum 安装指导

  • 在新机器上首次安装nginx之前,需要设置nginx软件包存储库。 之后,您可以从存储库安装和更新nginx。
[[email protected]  ~]# yum -y install yum-utils
  • 要设置yum存储库,
[[email protected]  ~]# vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
  • 默认情况下,使用稳定的nginx软件包的存储库。 如果要使用主线nginx软件包,请运行以下命令:
[[email protected]  ~]# yum-config-manager --enable nginx-mainline
  • 要安装nginx,请运行以下命令:
[[email protected]  ~]# yum -y install nginx

2、Yum 安装 nginx

[[email protected]  ~]# yum -y install nginx
[[email protected]  ~]# systemctl start nginx
[[email protected]  ~]# systemctl enable nginx
  • 注意 : 查看防火墙状态, 需要关闭防火墙
[[email protected]  ~]# getenforce 
Disabled

[[email protected]  ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor pres
et: enabled)   Active: inactive (dead)
 Docs: man:firewalld(1)

3、查看 nginx 安装版本

[[email protected]  ~]# nginx -v
nginx version: nginx/1.14.2

[[email protected]  ~]# nginx -V
nginx version: nginx/1.14.2
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) 
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments:
 --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 --lock-path=/var/run/nginx.lock --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 --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --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'

4、浏览器访问验证

浏览器访问 www.qfedu.com (在访问机器上添加 hosts 解析)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vX7vAm6Z-1585544628191)(assets/nginx-html.png)]

2、Nginx 编译安装与配置使用

1.查看系统版本/安装常用软件(系统最小化安装)

[root@qfedu.com ~]# cat /etc/centos-release
CentOS Linux release 7.6.1810 (Core) 

1、安装编译环境

[[email protected] ~]# yum -y install gcc gcc-c++

2、安装pcre软件包(使nginx支持http rewrite模块)

[[email protected] ~]# yum install -y pcre pcre-devel

3、安装 openssl-devel(使 nginx 支持 ssl)

[[email protected] ~]# yum install -y openssl openssl-devel 

4、安装zlib

[[email protected] ~]# yum install -y zlib zlib-devel gd gd-devel

5、创建用户 nginx

[[email protected] ~]# useradd -s /sbin/nologin nginx 

6、编译安装 nginx

1、下载安装包
[root@qfedu.com ~]# wget http://nginx.org/download/nginx-1.16.0.tar.gz
[root@qfedu.com ~]# tar -zxvf nginx-1.16.0.tar.gz
[root@qfedu.com ~]# cd nginx-1.16.0
2、编译配置
[root@qfedu.com nginx-1.16.0]# ./configure --prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-pcre \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-http_image_filter_module \
--with-http_slice_module \
--with-mail \
--with-threads \
--with-file-aio \
--with-stream \
--with-mail_ssl_module \
--with-stream_ssl_module 
    
[root@qfedu.com nginx-1.16.0]# make && make install
[root@qfedu.com nginx-1.16.0]# cd /usr/local/nginx/sbin
[root@qfedu.com sbin]# ./nginx        		# 启动Nginx
[root@qfedu.com sbin]# ./nginx -t      		# 验证配置文件是正确
[root@qfedu.com sbin]# ./nginx -s reload  	# 重启Nginx
[root@qfedu.com sbin]# ./nginx -s stop   	# 停止Nginx
[root@qfedu.com sbin]# ./nginx -v            # 查看是否安装成功
nginx version: nginx/1.16.0
[root@qfedu.com sbin]# netstat -ntlp | grep nginx # 查看是否启动
tcp   0    0 0.0.0.0:80     0.0.0.0:*     LISTEN    20949/nginx: master
3、配置 Nginx 命令和服务并开机启动
1、创建服务配置文件
[root@qfedu.com sbin]# vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
2、添加执行权限
[root@qfedu.com sbin]# chmod +x /usr/lib/systemd/system/nginx.service
3、启动服务(先停止nginx服务)
[root@qfedu.com sbin]# systemctl daemon-reload
[root@qfedu.com sbin]# systemctl start nginx.service   # 启动
[root@qfedu.com sbin]# systemctl stop nginx.service    # 停止
[root@qfedu.com sbin]# systemctl reload nginx.service  # 修改配置后重新加载生效 
[root@qfedu.com sbin]# systemctl restart nginx.service # 重启
[root@qfedu.com sbin]# systemctl status nginx   # 查看服务是否启动
4、添加开机启动
[root@qfedu.com sbin]# systemctl enable nginx.service
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service
4、防火墙默认开启,加入放行端口80
[root@qfedu.com sbin]# firewall-cmd --zone=public --add-port=80/tcp --permanent
success
[root@qfedu.com sbin]# firewall-cmd --reload
success

7、Nginx 编译参数

# 查看 nginx 安装的模块
[[email protected] ~]# nginx -V

# 模块参数具体功能 
--with-cc-opt='-g -O2 -fPIE -fstack-protector'   # 设置额外的参数将被添加到CFLAGS变量。(FreeBSD或者ubuntu使用)
--param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' 
--with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' 

--prefix=/usr/share/nginx                        # 指向安装目录
--conf-path=/etc/nginx/nginx.conf                # 指定配置文件
--http-log-path=/var/log/nginx/access.log        # 指定访问日志
--error-log-path=/var/log/nginx/error.log        # 指定错误日志
--lock-path=/var/lock/nginx.lock                 # 指定lock文件
--pid-path=/run/nginx.pid                        # 指定pid文件

--http-client-body-temp-path=/var/lib/nginx/body    # 设定http客户端请求临时文件路径
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi     # 设定http fastcgi临时文件路径
--http-proxy-temp-path=/var/lib/nginx/proxy         # 设定http代理临时文件路径
--http-scgi-temp-path=/var/lib/nginx/scgi           # 设定http scgi临时文件路径
--http-uwsgi-temp-path=/var/lib/nginx/uwsgi         # 设定http uwsgi临时文件路径

--with-debug                                        # 启用debug日志
--with-pcre-jit                                     # 编译PCRE包含“just-in-time compilation”
--with-ipv6                                         # 启用ipv6支持
--with-http_ssl_module                              # 启用ssl支持
--with-http_stub_status_module                      # 获取nginx自上次启动以来的状态
--with-http_realip_module                 # 允许从请求标头更改客户端的IP地址值,默认为关
--with-http_auth_request_module           # 实现基于一个子请求的结果的客户端授权。如果该子请求返回的2xx响应代码,所述接入是允许的。如果它返回401或403中,访问被拒绝与相应的错误代码。由子请求返回的任何其他响应代码被认为是一个错误。
--with-http_addition_module               # 作为一个输出过滤器,支持不完全缓冲,分部分响应请求
--with-http_dav_module                    # 增加PUT,DELETE,MKCOL:创建集合,COPY和MOVE方法 默认关闭,需编译开启
--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_spdy_module                   # SPDY可以缩短网页的加载时间
--with-http_sub_module                    # 允许用一些其他文本替换nginx响应中的一些文本
--with-http_xslt_module                   # 过滤转换XML请求
--with-mail                               # 启用POP3/IMAP4/SMTP代理模块支持
--with-mail_ssl_module                    # 启用ngx_mail_ssl_module支持启用外部模块支持

8、Nginx 配置文件

[[email protected] ~]# vim /usr/local/nginx/conf/nginx.conf
# 全局参数设置 
worker_processes  1;          # 设置nginx启动进程的数量,一般设置成与逻辑cpu数量相同 
error_log  logs/error.log;    # 指定错误日志 
worker_rlimit_nofile 102400;  # 设置一个nginx进程能打开的最大文件数 
pid        /var/run/nginx.pid; 
events {                      # 事件配置
    worker_connections  10240; # 设置一个进程的最大并发连接数
    use epoll;                # 事件驱动类型
} 
# http 服务相关设置 
http {  
    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;      # 用于开启文件高效传输模式,一般设置为on,若nginx是用来进行磁盘IO负载应用时,可以设置为off,降低系统负载
    tcp_nopush        on;      # 减少网络报文段数量,当有数据时,先别着急发送, 确保数据包已经装满数据, 避免了网络拥塞
    tcp_nodelay       on;      # 提高I/O性能,确保数据尽快发送, 提高可数据传输效率                           
    gzip              on;      # 是否开启 gzip 压缩 
    keepalive_timeout  65;     # 设置长连接的超时时间,请求完成之后还要保持连接多久,不是请求时间多久,目的是保持长连接,减少创建连接过程给系统带来的性能损                                    耗,类似于线程池,数据库连接池
    types_hash_max_size 2048;  # 影响散列表的冲突率。types_hash_max_size 越大,就会消耗更多的内存,但散列key的冲突率会降低,检索速度就更快。                                            types_hash_max_size越小,消耗的内存就越小,但散列key的冲突率可能上升
    include             /etc/nginx/mime.types;  # 关联mime类型,关联资源的媒体类型(不同的媒体类型的打开方式)
    default_type        application/octet-stream;  # 根据文件的后缀来匹配相应的MIME类型,并写入Response header,导致浏览器播放文件而不是下载
# 虚拟服务器的相关设置 
    server { 
        listen      80;        # 设置监听的端口 
        server_name  localhost;        # 设置绑定的主机名、域名或ip地址 
        charset koi8-r;        # 设置编码字符 
        location / { 
            root  /var/www/nginx;           # 设置服务器默认网站的根目录位置 
            index  index.html index.htm;    # 设置默认打开的文档 
            } 
        error_page  500 502 503 504  /50x.html; # 设置错误信息返回页面 
            location = /50x.html { 
            root  html;        # 这里的绝对位置是/var/www/nginx/html 
        } 
    } 
 }

9、检测 nginx 配置文件是否正确

[[email protected] ~]# usr/local/nginx/sbin/nginx -t

10、启动 nginx 服务

[[email protected] ~]# /usr/local/nginx/sbin/nginx

11、Nginx 命令控制

nginx -c /path/to/nginx.conf  	 # 以特定目录下的配置文件启动nginx:
nginx -s reload            	 	 # 修改配置后重新加载生效
nginx -s reopen   			 	 # 重新打开日志文件
nginx -s stop  				 	 # 快速停止nginx
nginx -s quit  				  	 # 完整有序的停止nginx
nginx -t    					 # 测试当前配置文件是否正确
nginx -t -c /path/to/nginx.conf  # 测试特定的nginx配置文件是否正确

12、脚本实现 nginx 开机自启

1、添加启动脚本
[[email protected] ~]#  vim /etc/init.d/nginx
#!/bin/bash
# 
# nginx - this script starts and stops the nginx daemon 
# 
# chkconfig:  - 85 15  
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \ 
#              proxy and IMAP/POP3 proxy server 
# processname: nginx 
# config:      /usr/local/nginx/conf/nginx.conf 
# config:      /etc/sysconfig/nginx 
# pidfile:    /usr/local/nginx/logs/nginx.pid 
  
# Source function library. 
. /etc/rc.d/init.d/functions
  
# Source networking configuration. 
. /etc/sysconfig/network
  
# Check that networking is up. 
[ "$NETWORKING" = "no" ] && exit 0 
  
nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx) 
  
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
  
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
  
lockfile=/var/lock/subsys/nginx
  
make_dirs() { 
  # make required directories 
  user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -` 
  options=`$nginx -V 2>&1 | grep 'configure arguments:'` 
  for opt in $options; do
      if [ `echo $opt | grep '.*-temp-path'` ]; then
          value=`echo $opt | cut -d "=" -f 2` 
          if [ ! -d "$value" ]; then
              # echo "creating" $value 
              mkdir -p $value && chown -R $user $value 
          fi
      fi
  done
} 
  
start() { 
    [ -x $nginx ] || exit 5 
    [ -f $NGINX_CONF_FILE ] || exit 6 
    make_dirs 
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE 
    retval=$? 
    echo
    [ $retval -eq 0 ] && touch $lockfile 
    return $retval 
} 
  
stop() { 
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT 
    retval=$? 
    echo
    [ $retval -eq 0 ] && rm -f $lockfile 
    return $retval 
} 
  
restart() { 
    configtest || return $? 
    stop 
    sleep 1 
    start 
} 
  
reload() { 
    configtest || return $? 
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP 
    RETVAL=$? 
    echo
} 
  
force_reload() { 
    restart 
} 
  
configtest() { 
  $nginx -t -c $NGINX_CONF_FILE 
} 
  
rh_status() { 
    status $prog 
} 
  
rh_status_q() { 
    rh_status >/dev/null 2>&1 
} 
  
case "$1" in
    start) 
        rh_status_q && exit 0 
        $1 
        ;; 
    stop) 
        rh_status_q || exit 0 
        $1 
        ;; 
    restart|configtest) 
        $1 
        ;; 
    reload) 
        rh_status_q || exit 7 
        $1 
        ;; 
    force-reload) 
        force_reload 
        ;; 
    status) 
        rh_status 
        ;; 
    condrestart|try-restart) 
        rh_status_q || exit 0 
            ;; 
    *) 
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2 
esac
2、添加权限
[[email protected] ~]# chmod +x /etc/init.d/nginx
3、重载系统启动文件
[[email protected] ~]# systemctl daemon-reload
4、设置开机自启
[[email protected] ~]# systemct start nginx

13、nginx 日志文件详解

  • nginx 日志文件分为 log_formataccess_log 两部分

  • log_format 定义记录的格式,其语法格式为

  • log_format 样式名称 样式详情

  • 配置文件中默认有

log_format  main  'remote_addr - remote_user [time_local] "request" '
                  'status body_bytes_sent "$http_referer" '
                  '"http_user_agent" "http_x_forwarded_for"';9 A
点击这里 点击这里
变量 说明
r e m o t e a d d r remote_addr和 http_x_forwarded_for 客户端的ip
$remote_user 客户端的名称
$time_local 访问时的本地时间
$request 请求的URL和http协议
$status 访问的状态码
$body_bytes_sent 发送给客户端的主体内容大小
$http_referer 记录客户端是从哪个页面链接访问过来的,若没有链接,则访问‘-’
$http_user_agent 记录客户端使用的浏览器的相关信息

六、Nginx 虚拟机配置

1、什么是虚拟主机?

​ 虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主机,每个虚拟主机可以独立对外提供www服务,这样就可以实现一台主机对外提供多个web服务,每个虚拟主机之间是独立的,互不影响。

​ 虚拟主机指的是在单一机器上运行多个网站(例如 company1.qfedu.com 和 company2.qfedu.com)。虚拟主机可以是"基于 IP"的,即每个IP一个站点;或者是"基于域名"的,即每个域名一个站点。这些站点运行在同一物理服务器上,对用户不会有任何感知。Nginx也可以配置多种类型的虚拟主机: 基于IP的虚拟主机、基于端口的虚拟主机、基于域名的虚拟主机。下面将分别介绍这些虚拟主机的配置,及优缺点。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q1Zy6TIA-1585544628193)(assets/824142-20170614222954712-1804018134.png)]

1、配置位置

此章节所有内容,既可以在七层代理层配置,又可以在业务逻辑层配置。但七层代理层配置的虚拟主机常配合nginx的ngx_http_proxy_module模块使用。 而业务逻辑层配置的虚拟主机常配合nginx的ngx_http_fastcgi_module模块使用。

2、nginx支持三种类型的虚拟主机配置

1、基于域名的虚拟主机 (server_name来区分虚拟主机——应用:外部网站)
2、基于ip的虚拟主机, (一块主机绑定多个ip地址)
3、基于端口的虚拟主机 (端口来区分虚拟主机——应用:公司内部网站,外部网站的管理后台)

2、 基于域名的虚拟主机

1、配置通过域名区分的虚拟机

# 标准 location
server {
        listen 80;
        server_name www.qfedu01.com;
        root         /usr/local/nginx/html/web1;
        access_log   /var/log/nginx/web1/www.qfedu01.com.log main;
        error_log    /var/log/nginx/web2/www.qfedu01.com.error.log;
        location / {
                index index.html;
        }
}
# 多个 location
server {
        listen 80;
        server_name www.qfedu02.com;
        root         /usr/local/nginx/html/web2;
        access_log   /var/log/nginx/web2/www.qfedu02.com.log main;
        error_log    /var/log/nginx/web2/www.qfedu02.com.error.log;
        location / {
                index index.html;
        }
}



# 模板配置
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;
        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
        location / {
        }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

2、 为 虚拟机创建 index 文件

[[email protected] ~]# cd /usr/local/nginx/html
[[email protected] html]# mkdir -p web{1,2}
[[email protected] html]# cd web1
[[email protected] web1]# vim index.html
[[email protected] web1]# cat index.html 
<html>
<p>
this is my 1000phone01
</p>
</html>

[[email protected] html]# cd web2
[[email protected] web2]# vim index.html
[[email protected] web2]# cat index.html 
<html>
<p>
this is my 1000phone02
</p>
</html>

3、添加权限重载配置文件

[[email protected] ~]# mkdir /var/log/nginx
[[email protected] ~]# chown nginx.nginx /var/log/nginx/
[[email protected] ~]# chown nginx.nginx /usr/local/nginx/html/
# 如果编译安装的执行
[[email protected] ~]# /usr/local/nginx/sbin/nginx -s reload
# 如果 yum 安装的执行
[[email protected] ~]# nginx -s reload

5、 测试访问

[root@localhost ~]# curl http://www.qfedu01.com/
<html>
<p>
this is my 1000phone01
</p>
</html>

4、客户端配置路由映射

在 C:\Windows\System32\drivers\etc\hosts 文件中添加两行

192.168.152.166 www.qfedu01.com www.qfedu02.com

浏览器输入:http://www.qfedu01.com/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JYwWS5ju-1585544628194)(assets/1-1585479310892.png)]

6、补充:如果配置不能正常访问

问题描述: 配置完 nginx 两个虚拟机后,客户端能够访问原始的server ,新增加的 server 虚拟机 不能够访问,报错如下页面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8ywjIkw0-1585544628194)(assets/824142-20170614201534618-1766240416.png)]

解决过程:

1、查看报错日志(找到错误日志)
  [[email protected] ~]# cat logs/error.log 
  2017/06/15 04:00:57 [error] 6702#0: *14 "/root/html/index.html" is forbidden (13: Permission denied), client: 10.219.24.1, server: www.qfedu02.com, request: "GET / HTTP/1.1", host: "www.qfedu02.com"
  [root@logs]# date
  Tue Mar 12 10:05:53 CST 2019
2、检查权限
[[email protected] ~]# ll
  drwxr-xr-x. 2 root root 4096 Jun 15 03:59 html
  [[email protected] html]# ll
  total 8
  -rw-r--r--. 1 root root 537 Jun 15 03:59 50x.html
  -rw-r--r--. 1 root root 616 Jun 15 03:51 index.html
  说明:发现目录权限没有问题
3、检查nginx启动进程
[[email protected] ~]# ps anx|grep nginx
  6546 ? Ss 0:00 nginx: master process ./sbin/nginx
  6702 ? S 0:00 nginx: worker process
  6726 pts/1 S+ 0:00 grep nginx
  说明:发现nginx的work process是 nobody 的
4、修改 nginx.conf 文件
  打开nginx.conf文件所在的目录,查看文件的属性 (root root)
  [[email protected] ~]# ll
  drwxr-xr-x. 2 root root 4096 Jun 15 04:08 conf
  在nginx.conf文件的第一行加上 user root root;
  [[email protected] ~]# cat conf/nginx.conf
  user root root;
5、重新 reload nginx 进程
  [[email protected] ~]#nginx -s reload
  注意:
  nginx -s reload 命令加载修改后的配置文件,命令下达后发生如下事件
  1. Nginx 的 master进程检查配置文件的正确性,若是错误则返回错误信息,nginx继续采用原配置文件进行工作(因为worker未受到影响)
  2. Nginx 启动新的 worker 进程,采用新的配置文件
  3. Nginx 将新的请求分配新的 worker 进程
  4. Nginx 等待以前的 worker 进程的全部请求已经都返回后,关闭相关 worker 进程
  5. 重复上面过程,直到全部旧的worker进程都被关闭掉
6、再次访问,成功!

2、 基于 ip 的虚拟主机

1、一块网卡绑定多个ip

[[email protected] ~]# ifconfig eth0:1 192.168.152.200
[[email protected] ~]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:79:F4:02 
inet addr:192.168.95.134 Bcast:10.255.255.255 Mask:255.0.0.0
...
eth0:1 Link encap:Ethernet HWaddr 00:0C:29:79:F4:02 
inet addr:192.168.95.200 Bcast:10.255.255.255 Mask:255.0.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

2、配置通过ip区分的虚拟机

    server {
        listen 192.168.152.166:80;
        server_name www.qfedu01.com;
        root         /usr/local/nginx/html/web1;
        access_log   /var/log/nginx/web1/www.qfedu01.com.log main;
        error_log    /var/log/nginx/web1/www.qfedu01.com.error.log;
        location / {
                index index.html index.htm;
        }
    }

    server {
        listen 192.168.152.200:80;
        server_name www.qfedu02.com;
        root         /usr/local/nginx/html/web2;
        access_log   /var/log/nginx/web2/www.qfedu02.com.log main;
        error_log    /var/log/nginx/web2/www.qfedu02.com.error.log;
        location / {
                index index.html index.htm;
        }
    }

3、重新 reopen nginx 进程

[[email protected] ~]# nginx -s reopen
或者 
[[email protected] ~]# systemctl restart nginx.service

4、 测试访问

浏览器输入:http://192.168.95.134

浏览器输入:http://192.168.95.200

5、补充:

# 删除绑定的 ip
[[email protected] ~]# ifconfig eth0:1 192.168.95.100 down

3、 基于端口的虚拟主机

1、修改配置文件

    server {
        listen 80;
        server_name www.qfedu01.com;
        root         /usr/local/nginx/html/web1;
        access_log   /var/log/nginx/web1/www.qfedu01.com.log main;
        error_log    /var/log/nginx/web1/www.qfedu01.com.error.log;
        location / {
                index index.html index.htm;
        }
    }

    server {
        listen 8080;
        server_name www.qfedu02.com;
        root         /usr/local/nginx/html/web2;
        access_log   /var/log/nginx/web2/www.qfedu02.com.log main;
        error_log    /var/log/nginx/web2/www.qfedu02.com.error.log;
        location / {
                index index.html index.htm;
        }
    }

2、重新 reload nginx进程

[[email protected] ~]# nginx -s reload
或者 
[[email protected] ~]# systemctl restart nginx.service

3、 测试访问

浏览器输入:http://www.qfedu01.com/

浏览器输入:http://www.qfedu02.com:8080

七、Nginx 虚拟主机 + PHP-FPM

PHP-FPM(FastCGI Process Manager:FastCGI进程管理器)是一个PHPFastCGI管理器。它提供了更好的PHP进程管理方式,可以有效控制内存和进程、可以平滑重载PHP配置。在日常运维中,我们主要将PHP-FPM 的配置文件分为主配置文件和 pool配置文件(每个pool配置文件通常对应一个Nginx虚拟主机)。

1、配置位置

  • 此章节所有内容,只可在业务逻辑层上配置,主要使用 nginx 的 ngx_http_fastcgi_module 模块。七层代理层不配置。
[[email protected] ~]# yum -y install php-fpm

2、PHP-FPM 主配置文件

主配置文件 php-fpm.conf,常用配置如下:

[[email protected] ~]# vim /etc/php-fpm.conf
[global]
pid = /run/php-fpm/php-fpm.pid
error_log = /var/log/php-fpm/error.log
process_control_timeout = 0
;动态方式下开启的php-fpm进程的最大数量
process.max = 2048
;设置 fpm 在后台运行
daemonize = yes
; 设置进程可以打开的文件描述符数量
rlimit_files = 65535
; 设置core dump 的大小
rlimit_core = 67108864
; 设置FPM 的事件处理机制
events.mechanism = epoll
;emergency_restart_interval所设值内出现SIGSEGV或者SIGBUS错误的php-cgi进程数如果超过 emergency_restart_threshold个,php-fpm就会优雅重启
emergency_restart_threshold = 10
emergency_restart_interval = 5

;  加载pool 配置
include = /etc/php-fpm.d/*.conf

3、PHP-FPM pool 配置文件

  • PHP-FPM pool 配置文件,常用配置如下
[[email protected] ~]# vim /etc/php-fpm.d/test.qfedu.com.conf.conf
[test.qfedu.com]
user = nginx
group = nginx
listen = 127.0.0.1:9000
; 允许监听的客户端
listen.allowed_clients = 127.0.0.1
; 设置动态进程池
pm = dynamic
pm.max_children = 512
pm.start_servers = 32
pm.min_spare_servers = 32
pm.max_spare_servers = 64
; 设置每个进程可处理的请求数,当进程达到这个请求数量后会自动释放在重新生成新的进程。避免内存泄漏等情况
pm.max_requests = 1500
; FPM 的监控设置
pm.status_path = /qfedu_monitor_page
; PHP-FPM 的慢请求日志位置。$pool 这里为 test.qfedu.com
slowlog = /var/log/php-fpm/$pool-slow_log
; 设置请求时间达到多少位慢请求
request_slowlog_timeout = 3
; 终止请求超时时间。一个请求若处理大于20s ,则会自动kill 掉。避免进程堆积
request_terminate_timeout = 20
catch_workers_output = no
; 限制 FPM 允许解析的脚本扩展名. 这里不限制,FPM可以解析任何扩展名的文件
security.limit_extensions = ""

4、虚拟主机结合PHP-FPM pool

1、PHP-FPM pool 配置

[[email protected] ~]# vim /etc/php-fpm.d/test.qfedu.com.conf.conf
[test.qfedu.com]
user = nginx
group = nginx
listen = 127.0.0.1:9000
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 512
pm.start_servers = 32
pm.min_spare_servers = 32
pm.max_spare_servers = 64
pm.max_requests = 1500
pm.status_path = /qfedu_monitor_page
slowlog = /var/log/php-fpm/$pool-slow_log
request_slowlog_timeout = 3
request_terminate_timeout = 20
catch_workers_output = no
security.limit_extensions = ""

2、虚拟主机配置

server {
    listen       80;
    server_name  test.qfedu.com;
    root         /usr/local/nginx/html/test.qfedu.com;
    access_log   /var/log/nginx/test.qfedu.com-acess.log;
    error_log    /var/log/nginx/test.qfedu.com-error.log;

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|html)$ {
        expires      1d;
    }

    location / {
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;  # 确保 fastcgi.conf 中存在 SCRIPT_FILENAME 配置
        include fastcgi.conf;     
        fastcgi_pass 127.0.0.1:9000;   # 使用了PHP-FPM 9000 端口的POOL 配置。
    }
}

3、测试

  • 在test.qfedu.com 的虚拟主机root 目录中创建一个today.php 的脚本
[root@qfedu.com ~]# cat /usr/local/nginx/html/test.qfedu.com/today.php
<?php
echo "today is " . date("Y-m-d") . "\n";
?>
[[email protected] ~]# curl http://127.0.0.1/today.php -H "HOST: test.qfedu.com"

4、开启PHP-FPM pool 监控

  • 确保PHP-FPM pool 中开启了监控指令
vpm.status_path = /qfedu_monitor_page
  • 配合Nginx 虚拟主机查看监控数据
server {
    listen       80;
    server_name  test.qfedu.com;
    root         /usr/local/nginx/html/test.qfedu.com;
    access_log   /var/log/nginx/test.qfedu.com-acess.log;
    error_log    /var/log/nginx/test.qfedu.com-error.log;

    if ( $uri ~ "^/qfedu_monitor_page" ){ break; }   # 避免监控的特殊URL被业务上的REWRITE 规则重写

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|html)$ {
        expires      1d;
    }

    location ~ /qfedu_monitor_page {
        include fastcgi.conf;
        fastcgi_pass 127.0.0.1:9000;
    }

    location / {
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;  # 确保 fastcgi.conf 中存在 SCRIPT_FILENAME 配置
        include fastcgi.conf;
        fastcgi_pass 127.0.0.1:9000;			# 使用了PHP-FPM 9000 端口的POOL 配置。
    }
}

5、测试

[[email protected] ~]# curl http://127.0.0.1/qfedu_monitor_page -H "HOST: test.qfedu.com"
pool:                 test.qfedu.com
process manager:      dynamic
start time:           29/Mar/2020:20:17:34 +0800
start since:          853
accepted conn:        4
listen queue:         0
max listen queue:     0
listen queue len:     128
idle processes:       31
active processes:     1
total processes:      32
max active processes: 1
max children reached: 0
slow requests:        0

6、PHP-FPM 配置解释

# PHP-FPM 的 POOL名字
pool:                 test.qfedu.com
# 这个POOL中进程管理方式,这里是动态管理方式。相反还有静态管理方式。
process manager:      dynamic
# POOL从什么时间开始启动
start time:           29/Mar/2020:20:17:34 +0800
# POOL 从启动到现在已经存活了多久
start since:          129
# 当前POOL接受的请求数
accepted conn:        6
# 请求等待队列当前长度,如果这个值不为0,那么说明你的请求处理已经开始有挤压了,应该注意系统状态。
listen queue:         0
# 从启动到现在,请求等待队列历史最大长度
max listen queue:     0
# 请求队列长度大小
listen queue len:     128
# 目前空闲进程数
idle processes:       31
# 目前工作进程数
active processes:     1
# 目前总进程数
total processes:      32
# 从启动到现在,最大的活跃进程数量
max active processes: 1
# 达到进程最大数量限制的次数,如果这个数量不为0,那说明设置的最大进程数量(pm.max_children)太小了,或者进程挤压了。
max children reached: 0
# 慢请求的数量
slow requests:        0
发布了75 篇原创文章 · 获赞 5 · 访问量 2502

猜你喜欢

转载自blog.csdn.net/qq_44273583/article/details/105197070