nginx基础

本文主要整理一下nginx的基本原理以及3种功能

概览

Nginx是一款轻量级的Web服务器,由俄罗斯程序员伊戈尔·赛索耶夫(下图)于2004年首次开发,2011成立同名公司提供支持。常用作反向代理、负载均衡、HTTP缓存

伊戈尔·赛索耶夫

Nginx 的编写有一个明确目标就是超越 Apache Web服务器的性能。Nginx 提供开箱即用的静态文件,使用的内存比 Apache 少得多,每秒可以处理大约四倍于 Apache 的请求。

Nginx在官方测试的结果中,能够支持五万个并行连接,而在实际的运作中,可以支持二万至四万个并行连接。

wiki

基本原理

master-woker模式

nginx也是master-woker结构,整个结构图如下:

nginx工作模式

Master进程的作用是:

  • 读取并验证配置文件nginx.conf;
  • 接收来自外界的信号,向各worker进程发送信号;
  • 管理worker进程;

惊群现象

主进程(master 进程)首先通过 socket() 来创建一个 sock 文件描述符用来监听,然后fork生成子进程(workers 进程),子进程将继承父进程的 sockfd(socket 文件描述符),之后子进程 accept() 后将创建已连接描述符(connected descriptor),然后通过已连接描述符来与客户端通信。

那么,由于所有子进程都继承了父进程的 sockfd,那么当连接进来时,所有子进程都将收到通知并“争着”与它建立连接,这就叫“惊群现象”。大量的进程被激活又挂起,只有一个进程可以accept() 到这个连接,这当然会消耗系统资源。

争抢机制

参考

工作机制

Nginx 提供了一个 accept_mutex 这个东西,这是一个加在accept上的一把互斥锁。即每个 worker 进程在执行 accept 之前都需要先获取锁,获取不到就放弃执行 accept()。有了这把锁之后,同一时刻,就只会有一个进程去 accpet(),这样就不会有惊群问题了。accept_mutex 是一个可控选项,我们可以显示地关掉,默认是打开的。

woker进程的处理

当一个 worker 进程在 accept() 这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,一个完整的请求。一个请求,完全由 worker 进程来处理,而且只能在一个 worker 进程中处理。

在linux上woker进程采用的 IO多路复用epoll。

通过epoll_create()注册好事件之后,只要有 该fd 上事件发生,epoll_wait() 就能检测到并返回给用户,用户就能”非阻塞“地进行 I/O 了。

epoll() 中内核则维护一个链表,epoll_wait 直接检查链表是不是空就知道是否有文件描述符准备好了。epoll 与 select 相比最大的优点是不会随着 wait的sockfd 数目增长而降低效率,使用 select() 时,内核采用轮训的方法来查看是否有fd 准备好,其中的保存 sockfd 的是类似数组的数据结构 fd_set,key 为 fd,value 为 0 或者 1。

能达到这种效果,是因为在内核实现中 epoll 是根据每个 sockfd 上面的与设备驱动程序建立起来的回调函数实现的。那么,某个 sockfd 上的事件发生时,与它对应的回调函数就会被调用,来把这个 sockfd 加入链表,其他处于“空闲的”状态的则不会。

反向代理

反向代理是针对正向代理而言的,正向代理指得是对客户端的代理,反向代理指得是对服务器的代理,其差别如下。

正向代理 反向代理

这个最常用,这里简单引用配置文件,如下:

反向代理配置

负载均衡

增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡。

负载均衡

负载均衡通过upstream来实现,其配置如下:

负载均衡配置

负载均衡在配置时,可以用不同的策略,包括:

  1. 轮询(默认)

    按照请求次序分别逐一分配到不同普通服务器,如果后端服务器挂了,能自动删除

  2. 权重

    需要设置weight,默认为1,权重越高,被分配的客户数就越多

    upstream server_pool {
    	server 192.168.5.21 weight=10;
    	server 192.168.5.22 weight=10;
    }
    
  3. ip_hash

    按照请求的ip按照哈希算法分配到固定的服务器,每个访问者只会访问到固定的服务器,可以解决session问题

    upstream server_pool {
    	ip_hash;
    	server 192.168.5.21;
    	server 192.168.5.22;
    }
    
  4. fair(第三方)

    按照后端服务器的响应时间来分配请求,响应时间短的优先分配

    upstream server_pool {
    	fair;
    	server 192.168.5.21;
    	server 192.168.5.22;
    }
    

HTTP缓存

如果我们使用Nginx作为静态资源服务器,那么可以使用expires进行缓存控制。

HTTP有多方面的缓存技术,浏览器缓存、服务器缓存,代理缓存,这里主要介绍代理缓存。

基本机制

其过程如下:

Http缓存

第一步:客户端第一次向Nginx请求数据A;

第二步:当Nginx发现缓存中没有数据A时,会向服务端请求数据A;

第三步:服务端接收到Nginx发来的请求,则返回数据A到Nginx,并且缓存在Nginx;

第四步:Nginx返回数据A给客户端应用;

第五步:客户端第二次向Nginx请求数据A;

第六步:当Nginx发现缓存中存在数据A时,则不会请求服务端;

第七步:Nginx把缓存中的数据A返回给客户端应用。

缓存规则

网页缓存是由HTTP消息头中的"Cache-control"来控制的,常见的取值有private、no-cache、max-age、must-revalidate等,默认为private。默认情况下,NGINX尊重Cache-Control源服务器的标头。它不缓存响应Cache-Control设置为Private,No-Cache或No-Store或Set-Cookie在响应头。NGINX只缓存GET和HEAD客户端请求。

如下配置可覆盖这些默认值:

  • proxy_buffering默认为on,若proxy_buffering设置为off,则NGINX不会缓存响应。
  • proxy_ignore_headers可以配置忽略Cache-Control:
1 location /images/ {
  2     proxy_cache my_cache;
  3     proxy_ignore_headers Cache-Control;
  4     proxy_cache_valid any 30m;
  5     # ...
  6 }

proxy_cache zone | off,默认为off,开启的话,参数(my_cache)是zone的名字。

对静态资源的缓存

通过expiers来配置对静态资源的缓存,默认为off,Expires是服务端返回的到期时间。如果下一次请求如果小于服务端返回的过期时间,则直接使用缓存数据。

server {
    listen       80;
    server_name  xxx.xxx.com;
    root         /app/xxx/html/;
    location ~ .*\.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$
    {
        expires      7d;
    }

    location ~ .*\.(?:js|css)$
    {
        expires      7d;
    }

    location ~ .*\.(?:htm|html)$    #不缓存html
    {
        add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
    }
}

小知识

第一个:发送请求,占用了worker的几个链接数?

答案:2个或4个

2个:请求静态资源,客户端和worker建立输入输出两个连接;4个:http反向代理请求动态数据,比如请求tomcat接口,客户端和worker建立输入输出两个连接,tomcat和worker建立输入输出两个连接。

第二个:nginx有一个master.4个worker,每个worker支持的最大连接数是1024,支持的最大并发数是多少?

静态资源请求:worker*connection ** workerprocess/2

http反向代理:worker*connection ** workerprocess/4

主要参考

nginx工作原理

nginx学习

Nginx 缓存配置

# nginx 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×