Nginx概述

Posted 礁之

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx概述相关的知识,希望对你有一定的参考价值。

一、nginx基本简介

(1)Nginx是什么

  • Nginx是一个开源、高性能、可靠的HTTP中间件和代理服务

开源: 即开放源代码,但是不代表完全免费,一些公司会推出二次开发服务,这是收费的,开放的源代码只是底层代码

高性能: 即支持海量并发

(2)常见的HTTP服务

  • HTTPD: Apache
  • IIS: 微软
  • GWS: 谷歌 (k8s就是谷歌研发的,只是谷歌的Brog中的一个功能)
  • openrestry
  • tenginx 淘宝基于nginx自行开发的,是开源的
  • nginx

(3)Nginx应用场景

静态处理对静态页面的处理,httpd(apache)和nginx默认只能处理静态页面
反向代理不直接处理客户端请求,而是转发请求给其他服务器,通常和tomcat组成反向代理
负载均衡通常跟反向代理相结合,负责将客户端的请求转交给其他压力比较小的服务器,会有两台以上的服务器
资源缓存对客户端经常访问的数据进行缓存,加快客户端访问的速度
安全防护nginx本身对自己就有一定的防护措施
访问限制类似于apache的order deny 和allow 即拒绝和允许
访问认证对网站添加指定的用户名和密码

(4)I/O模型

  • Nginx是一个高性能的HTTP和反向代理的web服务器,同时也提供了IMAP/POP3/SMTP服务。nginx为什么能比apache的并发数量高了3W,就是因为apache和nginx使用的I/O模型不同。

单apache理想并发:2W

单nginx理想并发:5W

  • I/O模型是什么:

I/O即input和output(上传和下载),不管是网络数据还是磁盘数据都需要进行I/O

而每次I/O都需要进行两个阶段:

第一步:将数据从磁盘文件先加载至内核空间(缓冲区),等待数据准备完成,时间较长

第二步:将数据从内核缓冲区复制到用户空间进程的内存中,时间较短

Nginx工作流程:

  1. 首先客户端想要访问Nginx服务器的index.html页面
  2. Nginx收到请求后,Nginx进程发送请求给内核去处理
  3. 内核收到请求后去磁盘获取index.html
  4. 获取index,html后发送给内核中的缓冲区开始准备数据
  5. 数据准备好之后再发送给Nginx进程中的缓冲区(内存)
  6. 最后返回客户端Nginx服务器的index.html页面

在这里插入图片描述

-同步异步、阻塞和非阻塞

调用者就是Nginx进程(用户进程),被调用者就是内核,用户进程调用内核拿取数据

1、同步和异步是在用户空间内的操作,关注被调用者消息的通信机制


  • 同步: 调用者向被调用者发送任务请求,被调用者在完成任务请求的时间内,调用者会一直等待被调用者完成任务请求,在被调用者完成任务请求后,调用者才会执行下一个请求并且继续向被调用者发送任务请求。

例如: 老板给员工小王布置一个任务,老板在小王完成这个任务之前,会一直等待小王,在这个过程中老板不会去做其他事情


  • 异步: 调用者向被调用者发送任务请求,被调用者完成任务请求后会通过状态、通知或者回调机制主动通知调用者,这个期间调用者可以继续执行下一个请求

例如: 老板分配给员工小王一个任务,小王在做完这个任务后会向老板汇报,这个过程中老板不会进行等待,而是去做其他事情


  • 同步和异步的区别:

同步:被调用者不会主动向调用者返回任务的状态,在返回状态之前,调用者需要一直等待被调用者完成任务

异步:被调用者会主动向调用者返回任务的状态,在返回状态之前,调用者可以执行下一个请求

2、阻塞和非阻塞是在内核空间内的操作,关注调用者在等待结果返回之前的状态


  • 阻塞: 指I/O操作需要彻底完成之后才会返回到用户空间,在调用结果返回之前,调用者被挂起,不能执行下一个操作

例如: 手洗衣服,没洗完之前手是干不了其他事情的


  • 非阻塞: 指I/O操作被调用之后会立刻返回一个用户状态,无需等待I/O操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起

例如: 使用全自动洗衣机,不需要占用使用者的时间,洗完之后去拿就行,在这个期间使用者可以去干其他的事情


-模型介绍

同步阻塞型
同步非阻塞型最慢
IO多路复用,异步阻塞较慢
信号驱动型,异步半阻塞较快
异步IO模型,异步非阻塞最快
  • 异步半阻塞是apache所使用的模型,异步表示会主动返回成功值时,而半阻塞是因为用户进程建立SIGIO的信号处理程序,复制数据从磁盘到内核空间等待处理完递交给SIGIO告知进程,这个过程是不阻塞的,但是用户进程从内核空间复制到用户空间时,还得等待数据准备完成,这个过程是阻塞的,故称为半阻塞

  • 异步非阻塞就是nginx所使用的模型,nginx性能比apache好,也有数据传输模型不同这个原因

二、Nginx高并发原理

(1)Nginx高并发使用的方式

Nginx高并发使用的是epoll的方式,提供给用户访问,复制数据的一些操作让内核完成,而Nginx进程做的事情少了自然可以接受的请求数量就多了,apache使用的是select的方式

  • 使用select方式的缺点:(apache)

1、能够监视文件描述符的数量存在最大限制

2、线性遍历扫描所有数据,效率低下

  • 使用epoll方式:(Nginx)

1、epoll在linux2.6中增加了内存拷贝mmap机制,加速与内核空间的消息传递,即内存映射

2、每当FD就绪,采用系统的回调函数之间将fd放入,效率更高

3、最大连接无限制

4、轻量级:功能模块少、代码模块化

内存映射: 磁盘中有数据,而每个数据都有对应的inode值。在读取数据的时候会在内存中映射一个相同的inode值、大小也相同的数据,在下次读取数据的时候就不需要遍历inode值,分析路径了,从而提高了效率。

(2)为什么要绑定Nginx进程到不同的CPU上

默认情况下,Nginx的多个进程可能跑在某一个CPU或者CPU的某一个核心上,导致Nginx进程使用硬件的资源不均,因此绑定Nginx进程到不同的CPU上是为了充分利用硬件的多CPU多核资源的目的,这个也叫做CPU亲和(affinity)

[root@rzy ~]# vim /etc/nginx/nginx.conf 
。。。。。。
 3 worker_processes  1;   #1核的CPU,因为使用的是虚拟机只给了一个核心,所以这里默认是1核
 4 
。。。。。。
#例如:(1核是不用写worker_cpu_affinity的)
******(1)有两个核心:
worker_processes 2
worker_cpu_affinity 01 10;

******(2)有四个核心
worker_processes 4
worker_cpu_affinity 0001 0010 0100 1000;

******(3)有八个核心
worker_processes 8
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000
#依次类推
#也可以写:(自动)
worker_processes auto
worker_cpu_affinity auto  

(3)零拷贝sendfile

  • 传统文件传输,在实现上其实是比较复杂的,具体流程细节如下:
  1. 调用read函数,文件数据从硬盘被复制到内核缓冲区
  2. read函数返回,文件数据从内核缓冲区复制到用户缓冲区
  3. write函数调用,将文件数据从用户缓冲区复制到内核与socket相关的缓冲区
  4. 数据从socket缓冲区复制到相关协议引擎

所以说传统文件数据实际上是经过了四次复制操作:
硬 盘 — — 内 核 缓 冲 区 — — 用 户 缓 冲 区 — — s o c k e t 缓 冲 区 ( 内 核 ) — — 协 议 引 擎 硬盘——内核缓冲区——用户缓冲区——socket缓冲区(内核)——协议引擎 socket

  • 传统的文件传输需要经过多次上下文的切换才能完成复制或者读取,而sendfile文件传输是在内核中完成操作的,函数直接在两个文件描述符之间传递数据,从而避免了内核缓冲区数据和用户缓冲区数据之间的拷贝,操作效率比传统的文件传输高了很多,所以这个操作也被称之为零拷贝,下面是具体操作流程:
  1. 系统调用sendfile函数通过DMA把硬盘数据拷贝到kernel buffer(内核缓冲区)
  2. 数据被kernel(内核)直接拷贝到拎一个与socket相关的kernel buffer(内核缓冲区)
  3. DMA把数据从kernel buffer(内核缓冲区)直接拷贝给协议栈

在这个过程中数据没有用户空间和内核空间之间的切换,在内核中直接完成了从一个缓冲区到另一个缓冲区的拷贝

三、安装Nginx

(1)实验环境

系统主机名ipnginx版本
Centos7.4rzy192.168.100.202nginx/1.18.0

(2)安装Nginx

-使用YUM安装

******(1)先做基础配置
[root@Centos7 ~]# hostnamectl set-hostname rzy
[root@Centos7 ~]# su
[root@rzy ~]# systemctl stop firewalld
[root@rzy ~]# setenforce 0
setenforce: SELinux is disabled
[root@rzy ~]# mount /dev/cdrom /mnt/
mount: /dev/sr0 写保护,将以只读方式挂载
mount: /dev/sr0 已经挂载或 /mnt 忙
       /dev/sr0 已经挂载到 /mnt 上

******(2)创建YUM源文件(http://nginx.org/en/linux_packages.html进入Nginx官网复制yum源)
#使用yum安装需要配置网络yum源,使用虚拟机需要使用桥接模式连接公网
[root@rzy ~]# cd /etc/yum.repos.d/
[root@rzy yum.repos.d]# ll
总用量 4
-rw-r--r--. 1 root root 56 1月  12 18:33 centos.repo
[root@rzy yum.repos.d]# vim Nginx.repo  #创建新的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
module_hotfixes=true

[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
module_hotfixes=true
#保存退出
[root@rzy yum.repos.d]# yum -y install yum-utils   
[root@rzy yum.repos.d]# yum -y install nginx 
#等待下载完成
[root@rzy yum.repos.d]# systemctl start nginx
[root@rzy yum.repos.d]# netstat -anpt | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1853/nginx: master  
[root@rzy yum.repos.d]# nginx -v  #查看版本
nginx version: nginx/1.18.0
[root@rzy yum.repos.d]# cd /usr/share/nginx/html/  #nginx网页目录存放位置
[root@rzy html]# ll
总用量 8
-rw-r--r-- 1 root root 494 10月 29 23:25 50x.html
-rw-r--r-- 1 root root 612 10月 29 23:25 index.html
[root@rzy html]# vim index.html 
[root@rzy html]# echo "aaaaaaaaaaaaaaa" > index.html 
[root@rzy html]# systemctl restart nginx

(3)测试是否可以正常访问

在这里插入图片描述

-使用源码包安装

******(1)先做基础配置
[root@Centos7 ~]# hostnamectl set-hostname rzy
[root@Centos7 ~]# su
[root@rzy ~]# systemctl stop firewalld
[root@rzy ~]# setenforce 0
setenforce: SELinux is disabled
[root@rzy ~]# mount /dev/cdrom /mnt/
mount: /dev/sr0 写保护,将以只读方式挂载
mount: /dev/sr0 已经挂载或 /mnt 忙
       /dev/sr0 已经挂载到 /mnt 上

******(2)上传源码包,安装nginx
[root@rzy ~]# yum -y install pcre-devel zlib-devel  #先安装前提包
。。。。。。
完毕!
[root@rzy ~]# ll
总用量 1020
-rw-------. 1 root root    1264 1月  12 18:27 anaconda-ks.cfg
-rw-r--r--  1 root root 1039530 4月  19 18:04 nginx-1.18.0.tar.gz
[root@rzy ~]# tar xf nginx-1.18.0.tar.gz  
[root@rzy ~]# useradd -M -s /sbin/nologin nginx
[root@rzy ~]# cd nginx-1.18.0
[root@rzy nginx-1.18.0]# ./configure \\
> --prefix=/usr/local/nginx \\  #指定nginx的目录
> --user=nginx \\            #指定nginx的用户
> --group=nginx \\           #指定nginx的组
> --with-http_stub_status_module \\   #这个模块是可以查看nginx的状态
> && make && make install 
[root@rzy nginx-1.18.0]# ln -s /usr/local/nginx/sbin/nginx  /usr/local/sbin/ #创建软连接,优化nginx命令执行路径
[root@rzy nginx-1.18.0]# /usr/local/nginx/sbin/nginx   #开启nginx
[root@rzy nginx-1.18.0]# netstat -anpt | grep 80      #查看端口号
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3732/nginx: master  

******(3)编写启动脚本
[root@rzy nginx-1.18.0]# vim /usr/lib/systemd/system/nginx.service 
[Unit]
Description=nginx
After=network.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
PrivateTmp=true

[Install]
WantedBy=multi-user.target
#保存退出
[root@rzy nginx-1.18.0]# systemctl start nginx
[root@rzy nginx-1.18.0]# netstat -anpt | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3779/nginx: master  
[root@rzy nginx-1.18.0]# systemctl stop nginx
[root@rzy nginx-1.18.0]# netstat -anpt | grep 80
[root@rzy nginx-1.18.0]# systemctl start nginx
[root@rzy nginx-1.18.0]# netstat -anpt | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3802/nginx: master  

(4)测试是否可以正常访问
在这里插入图片描述

以上是关于Nginx概述的主要内容,如果未能解决你的问题,请参考以下文章

Nginx 动静分离概述

Nginx 动静分离概述

nginx.conf 忽略了 nginx-ingress 配置映射片段

将 nginx rtmp 片段发送到 WebRTC

1. Nginx基本概述与部署

text 有用的nginx命令和片段