面试必备之Nginx入门学习

勤奋不是嘴上说说而已,而是实际的行动,在勤奋的苦度中持之以恒,永不退却。业精于勤,荒于嬉;行成于思,毁于随。在人生的仕途上,我们毫不迟疑地选择勤奋,她是几乎于世界上一切成就的催产婆。只要我们拥着勤奋去思考,拥着勤奋的手去耕耘,用抱勤奋的心去对待工作,浪迹红尘而坚韧不拔,那么,我们的生命就会绽放火花,让人生的时光更加的闪亮而精彩。

导读:本篇文章讲解 面试必备之Nginx入门学习,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

Nginx入门学习

What

Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器,在高连接并发的情况下Nginx是Apache服务器不错的替代品。其特点是占有内存少,并发能力强,事实上Nginx的并发能力确实在同类型的网页服务器中表现较好。
Nginx作为负载均衡服务器,既可以在内部直接支持Rails和PHP程序对外进行服务,也可以支持作为HTTP代理服务器对外进行服务。Nginx用C进行编写,配置文件简洁(支持Perl语法),启动容易,几乎可以做到服务不间断运行和版本升级。

模块化设计

nginx的设计可以说是高度模块化,每个模块就是一个功能模块,只负责自身的功能,模块之间严格遵循高内聚,低耦合的原则。
在这里插入图片描述

  • 核心模块:Nginx 服务器正常运行必不可少的模块,提供错误日志记录、配置文件解析、事件驱动机制、进程管理等核心功能。
  • 标准 HTTP 模块:提供 HTTP 协议解析相关的功能:端口配置、网页编码设置、HTTP 响应头设置等。
  • 可选 HTTP 模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,如:Flash 多媒体传输、解析 Geo IP 请求、SSL 支持等。
  • 邮件服务模块:主要用于支持 Nginx 的邮件服务,包括对 POP3 协议、IMAP 协议和 SMTP 协议的支持。
  • 第三方模块:扩展 Nginx 服务器应用,完成开发者自定义功能,如:Json、Lua支持等。

安装

Windows安装

下载Windows版本的zip包解压,双击nginx.exe即可。在任务管理器的进程窗口可以看到两个nginx进程,分别是master和worker进程。退出Nginx服务的方法:

  • 找到两个进程,右键手动结束任务即可;
  • 命令行方法:./nginx.exe -s stop
  • 脚本化方法stop_nginx.bat:
@echo off
echo stopping nginx service...
net stop nginx
echo Kill nginx process...
taskkill /F /IM nginx.exe>nul

Linux安装

Linux下安装Nginx,至少需要依赖以下几个模块(编译模块时按照这个顺序):

  • openssl-fips; 即ssl功能模块
  • zlib; 即gzip模块
  • pcre. 即rewrite模块

分别搜索得到其下载的地址(包括Nginx),在Linux下执行wget <url>即可,然后tar zxvf *.tar.gz
然后到解压后的目录下执行:

./config    #检查本机的的安装环境
make        #从Makefile中读取指令然后编译
makeinstall #从Makefile中读取指令并安装到指定的位置

验证Nginx是否安装成功:

cd /usr/local/nginx/sbin
./nginx -t  #检验nginx.conf文件的基本有效性
./nginx   #启动Nginx
netstat -ntlp #查看默认的80端口,如果端口占用,则可以修改/etc/nginx.conf文件里面的http.server.listen 82

同时也可以通过打开localhost:82,成功的话可以看到Nginx的欢迎页面。
注意:在pcre官网会看到pcre2这个版本的库文件,不要下载安装这个,否则会安装Nginx失败:

./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source withNginxby using --with-pcre=<path> option.

Mac 安装 nginx

最简单的方法:brew install nginx
The default port has been set in /usr/local/etc/nginx/nginx.conf to 8080 so that nginx can run without sudo。
nginx will load all files in /usr/local/etc/nginx/servers/.
To have launchd start nginx now and restart at login: brew services start nginx
Or, if you don’t want/need a background service you can just run: nginx
停止:nginx -s stop

集群版安装

命令行及工具

nginx原生自带或者支持的命令:

nginx -c /etc/nginx.conf #-c 参数指定自定义配置文件路径
nginx -s stop #快速关闭Nginx,可能不保存相关信息,并迅速终止web服务。(快速退出) 
nginx -s quit #平稳关闭Nginx,保存相关信息,有安排的结束web服务。(平滑退出) 
nginx -s reload                #重新加载配置文件
nginx -s reopen               #重新加载日志文件。

ngxtop

Nginx网站服务器在生产环境中运行时需要进行实时监控;专业的监控软件如Nagios, Zabbix, Munin的网络监控支持Nginx监控,并给出综合性报告或者长期数据统计功能。
ngxtop命令行工具,可以快速简便地监控Nginx服务器的请求,通过分析 Nginx 或者其他日志文件,使用类似 top 命令的界面实时展示出来的。采用python编写,可以通过pip install ngxtop来安装。

ngxtop [options] (print|top|avg|sum) <var>

选项:
-l : 指定日志文件的完整路径 (Nginx 或 Apache2)
-f : 日志格式
–no-follow: 处理当前已经写入的日志文件,而不是实时处理新添加到日志文件的日志
-t : 更新频率
-n : 显示行号
-o : 排序规则(默认是访问计数)
-a …: 添加表达式(一般是聚合表达式如: sum, avg, min, max 等)到输出中。
-v: 输出详细信息
-i : 只处理符合规则的记录
一些内置变量:

  • bodybytessend
  • http_referer
  • http_user_agent
  • remote_addr
  • remote_user
  • request
  • status
  • time_local

实例:

ngxtop #列出10个 Nginx 服务,按请求数量排序
ngxtop -n 20 #显示前20个最频繁的请求
ngxtop info #获取Nginx基本信息
ngxtop top remote_addr #显示请求最多的客户端IP地址
ngxtop -i 'status == 404' print request status #显示状态码是404的请求
ssh user@remote_server tail -f /var/log/apache2/access.log | ngxtop -f common #使用普通格式从远程服务器解析apache日志
ngxtop -l access.log --no-follow -i 'http_user_agent.find('iPhone')'    #搜索客户端为 iPhone 的 log

参考:
ngxtop:在命令行实时监控 Nginx 的神器

实现原理

请求处理方式

高性能得益于多进程和异步机制,异步机制使用的是异步非阻塞方式。
多进程
服务器每当收到一个客户端时,由服务器master主进程生成一个worker子进程,和客户端建立连接进行交互,直到连接断开,该子进程就结束。
优点

  1. 各个进程之间相互独立,不需要加锁,减少使用锁对性能造成影响,降低编程的复杂度,降低开发成本;
  2. 采用独立的进程,可以让进程互相之间不会影响,如果一个进程发生异常退出时,其它进程正常工作,master 进程则很快启动新的 worker 进程,确保服务部中断,将风险降到最低。

缺点

  1. 操作系统生成一个子进程需要进行内存复制等操作,在资源和时间上会产生一定的开销;
  2. 当有大量请求时,会导致系统性能下降。当有大量请求时,会导致系统性能下降。

异步非阻塞
每个工作进程使用异步非阻塞方式,可以处理多个客户端请求。当某个工作进程接收到客户端的请求以后,调用 IO 进行处理,如果不能立即得到结果,就去处理其他的请求(即为非阻塞);而客户端在此期间也无需等待响应,可以去处理其他事情(即为异步);当 IO 返回时,就会通知此工作进程;该进程得到通知,暂时挂起当前处理的事务去响应客户端请求。

事件驱动模型

在 Nginx 的异步非阻塞机制中,工作进程在调用 IO 后,就去处理其他的请求,当 IO 调用返回后,会通知该工作进程。对于这样的系统调用,主要使用 Nginx 服务器的事件驱动模型来实现。
在这里插入图片描述
Nginx 的事件驱动模型由事件收集器、事件发送器和事件处理器三部分基本单元组成。事件收集器负责收集 worker 进程的各种 IO 请求,事件发送器负责将 IO 事件发送到事件处理器,而事件处理器负责各种事件的响应工作。
事件发送器将每个请求放入一个待处理事件的列表,使用非阻塞 I/O 方式调用“事件处理器”来处理该请求。其处理方式称为“多路 IO 复用方法”,常见的包括以下三种:select 模型、poll 模型、epoll 模型。

架构设计

在这里插入图片描述
Nginx 服务器使用 master/worker 多进程模式。多线程启动和执行的流程如下:主程序 Master process 启动后,通过一个 for 循环来接收和处理外部信号;主进程通过 fork() 函数产生子进程,每个子进程执行一个 for 循环来实现 Nginx 服务器对事件的接收和处理。
一般推荐 worker 进程数与 cpu 内核数一致,这样一来不存在大量的子进程生成和管理任务,避免进程之间竞争 CPU 资源和进程切换的开销。而且 Nginx 为了更好的利用多核特性,提供 cpu 亲缘性的绑定选项,可以将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来 cache 的失效。
对于每个请求,有且只有一个工作进程对其处理。每个 worker 进程都是从 master 进程 fork 过来,在 master 进程里面,先建立好需要 listen 的 socket(listenfd)之后,然后再 fork 出多个 worker 进程。所有 worker 进程的 listenfd 会在新连接到来时变得可读,为保证只有一个进程处理该连接,所有 worker 进程在注册 listenfd 读事件前抢 accept_mutex,抢到互斥锁的那个进程注册 listenfd 读事件,在读事件里调用 accept 接受该连接。
当一个 worker 进程在 accept 这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。一个请求,完全由 worker 进程来处理,而且只在一个 worker 进程中处理。

在 Nginx 服务器的运行过程中,主进程和工作进程需要进程交互。交互依赖于 Socket 实现的管道来实现。

  • Master-Worker 交互
    这条管道与普通的管道不同,它是由主进程指向工作进程的单向管道,包含主进程向工作进程发出的指令,工作进程 ID 等;同时主进程与外界通过信号通信;每个子进程具备接收信号,并处理相应的事件的能力。
  • worker-worker 交互
    这种交互是和 Master-Worker 交互是基本一致的,但是会通过主进程。工作进程之间是相互隔离的,所以当工作进程 W1 需要向工作进程 W2 发指令时,首先找到 W2 的进程 ID,然后将正确的指令写入指向 W2 的通道。W2 收到信号采取相应的措施。

Apache & nginx

  • nginx相对于Apache的优点:
    同样是web服务,nginx更轻量级,即比Apache占用更少的内存及资源;对PHP-CGI支持良好、反向代理功能、支持7层负载均衡、前端Cache、维持连接;抗并发,nginx处理请求是异步非阻塞的,而Apache则是阻塞型的;社区活跃,各种第三方高性能模块供选择;
    Apache 相对于nginx 的优点:rewrite模块功能比nginx 的rewrite 强大;动态页面模块多;bug少,稳定;Apache有先天不支持多核心处理负载鸡肋的缺点。
  • Nginx配置文件简洁,,正则配置”简单”且运行效率高;nginx -t 测试一下配置有效性;Apache复杂;Apache 对 PHP 支持比较简单;
  • 最核心的区别在于Apache是同步多进程模型,一个连接对应一个进程;nginx是异步的,多个连接(万级别)可以对应一个进程;
  • 可以充分返回两者的优势,搭配使用,使用nginx做前端以及负载均衡, 后端用Apache配置集群。大型网站建议用nginx自带的集群功能。

负载均衡算法

none/round-robin(轮询)

upstream按照轮询(默认,即没有任何配置信息时)方式进行负载,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。简便、成本低廉。缺点:可靠性低和负载分配不均衡。适用于图片服务器集群和纯静态页面服务器集群。

Least Time(least_time)

请求会分配给响应最快和活跃连接数最少的backend;

weight(权重)

指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。下面的负载均衡实战就是使用权重的方式。

ip_hash(访问ip)

每个请求按访问ip的hash函数结果分配,IPv4会考虑前3个octet,IPv6会考虑所有的地址位,这样每个访客固定访问一个后端服务器,可以解决session sticky问题。配置只需要在upstream中加入ip_hash;即可:

upstream tomcatserver {
    ip_hash;
    server 127.0.0.1:8080;
    server 127.0.0.1:8090;
}

least-connected(最少连接least_conn)

Nginx会把下一个连接分配给具有最小活动连接的服务器,常用于一些请求需要更长的时间才能完成的情况,nginx将尽量不会把过多的请求来使忙碌的应用程序服务器超负荷运行,而是将新的请求分发到不太忙的服务器。把上面的配置信息中的 ip_hash 换成 least_conn 即可。

fair(第三方)

按后端服务器的响应时间来分配请求,响应时间短的优先分配。与weight分配策略类似。需要安装第三方模块。如何得知响应时间长短?

upstream tomcatserver { 
	server 127.0.0.1:8080;
	server 127.0.0.1:8090;
	fair;
}

url_hash(第三方)

和IP哈希类似,只不过针对请求的url进行hash(基于缓存的server,页面静态化)。后端服务器为缓存、文件、静态服务器时比较有效。在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法。缺点是当后端服务器宕机的时候,url_hash不会自动跳转的其他缓存服务器,而是返回给用户一个503错误。

 upstream tomcatserver {
      server 127.0.0.1:8080;
      server 127.0.0.1:8090;
      hash $request_uri;
      hash_method crc32;
}

应用场景

1.反向代理

正向代理 vs 反向代理

正向代理:一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。如VPN;
反向代理:指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。

优势

  • 可以起到保护网站安全的作用,任何来自网络的请求都必须先经过代理服务器。
  • 通过缓存静态资源,加速Web请求。
  • 实现负载均衡。四层负载均衡的LVS,七层负载均衡的Nginx、Haproxy等。

实战

下面的负载均衡实战,nginx就是一个反向代理服务器;

2.负载均衡

负载均衡,可用于优化资源的利用率, 最大化吞吐量,减少延迟并确保容错配置。

下面以一个偏前端 nginx server 搭配两个后端 Tomcat server 来实现一个超级简单的负载均衡;以Windows 系统为例,其他系统类似;主要步骤:

  1. 下载 nginx 和 Tomcat zip 解压缩安装包,Tomcat 复制一份(当然,此处也可以下载两个不同版本的Tomcat 安装包,但是在生产环境不建议这么做,不稳定;另一方面,如果是想要升级后端的Tomcat server 的版本,比如为了使用 HTTP 2 的特性,会想要升级生产环境的 Tomcat server的版本,此时可以通过这种方式来实现所谓的灰度发布,即先使用权重负载均衡算法把前端的流量的20%转移分配到新版本的 Tomcat server,80% 的流量依旧使用旧版本,在线上运行一段时间,发现新版本的没有什么问题,后续可以逐步实现完全的流量切换),修改conf/server.xml 配置文件里面的端口 port 实现单机安装多个 Tomcat server,即我们在学习 hadoop 时所谓的伪分布部署模式。此处修改配置端口信息时,建议把 server.xml 里面的所有的端口信息都修改一下,除非是在很熟悉 Tomcat 这几个端口的作用的情况下。
<Server port="18005" shutdown="SHUTDOWN">
<Connector port="18080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
<Connector port="18009" protocol="AJP/1.3" redirectPort="8443" />
  1. 同时修改 webapps/ROOT/index.jsp 里面的 body 标签的内容,方便我们识别两个 Tomcat server;效果如图;为了偷懒,第一个 Tomcat server 保持其端口信息不变即可:
    在这里插入图片描述
  2. 修改 nginx 的配置文件 nginx.conf:
worker_processes  1;#工作进程的个数,一般与计算机的cpu核数一致
events {
    worker_connections  1024;#单个进程最大连接数(最大连接数=连接数*进程数)
}
http {
    include       mime.types; #文件扩展名与文件类型映射表
    default_type  application/octet-stream;#默认文件类型
    sendfile        on;#开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
     keepalive_timeout  65; #长连接超时时间,单位是秒
     gzip  on;#启用Gizp压缩
     # 服务器的集群
     upstream  nginxloadbalance.com {#集群名字
     	# upstream还可以为每个设备设置状态值:
		# down:表示当前server暂时不参与负载;
		# weight:默认为1.weight越大,负载的权重就越大;
		# max_fails:允许请求失败的次数默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
		# fail_timeout : max_fails次失败后,暂停的时间。
		# backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。
		# 健康检查:max_fails 指令设置在fail_timeout期间与nginx服务器连续的不成功的尝试连接的通信数量。默认情况下,max_fails为1,当设置为0时,该服务器的运行状况检查会被禁用。fail_timeout还定义服务器将被标记为失效的时间。在服务器发生故障后的 fail_timeout间隔之后,nginx将开始以实时客户端的请求优雅地探测服务器。如果探测成功,则将服务器标记为活动的。
        server 127.0.0.1:8080  weight=1; # 待验证:不要写localhost,不然访问速度会很慢
        server 127.0.0.1:18080  weight=2;
     }
     #当前的Nginx的配置
     server {
         listen       81;#监听81端口,可配置
         server_name  localhost; #当前服务的域名
     location / {
             proxy_pass http://nginxloadbalance.com;
             proxy_redirect default;
             # 以下配置可用于模拟一台tomcat宕机时,nginx的自动剔除和切换
             proxy_connect_timeout 1; #连接超时时间
		     proxy_read_timeout 1;
    		 proxy_send_timeout 1;
         }
         error_page   500 502 503 504  /50x.html;
         location = /50x.html {
             root   html;
         }
     }
}

浏览器访问 http://localhost:81/index.jsp,刷新页面,看到出现 Tomcat2 字样的页面(即请求到达后端Tomcat server 2)的概率是 Tomcat server 1 的2倍,这正是负载均衡算法在起作用。
在这里插入图片描述

3. HTTP服务器(包含动静分离)

4.正向代理

5.虚拟主机

改进

虽然 nginx 已经足够强大,性能优越,并且有非常多的扩展模块(可以理解为插件)可以考虑安装使用,但是很多大公司依旧不满意,于是催生出一系列 nginx 的进阶版:

  • nginx plus 商业版
    difference
  • tengine 淘宝改进版
  • OpenResty
  • kong

参考:
Nginx开发从入门到精通

nginx
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()

nginx -c /etc/nginx/conf.d/nacos.conf
nginx: [emerg] “upstream” directive is not allowed here in /etc/nginx/conf.d/nacos.conf:1

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/142396.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!