Nginx修炼之路(一)

Nginx介绍

Nginx,发音 engine [ˈendʒɪn| x  。

俄罗斯的工程师Igor Sysoev在就职于Rambler Media(http://www.rambler.ru/ ) 期间, 使用C语言开发了Nginx。

Nginx使用基于事件驱动的架构能够并发处理百万级别的TCP连接, 高度模块化的设计和自由的许可证使得扩展Nginx功能的第三方模块层出不穷, 并且优秀的设计带来了极佳的稳定性。

因此其作为Web服务器被广泛应用到流量巨大的网站上, 包括腾讯、 新浪、 网易、淘宝等访问量巨大的网站。

为什么选择Nginx?

以下特点让Nginx成为了后起之秀。

  • 更快 —— 一方面,单次请求会得到更快的相应;另一方面,在并发量大时,Nginx可以比其他Web服务器得到更快的响应。
  • 单机支持10万以上的并发 —— 理论上, Nginx支持的并发连接上限取决于内存, 10万远未封顶,此特性让Nginx成为当之无愧的性能之王。
  • 低内存消耗 —— 一般情况下, 10000个非活跃的HTTP Keep-Alive连接在Nginx中仅消耗2.5MB的内存, 这是Nginx支持高并发连接的基础。
  • 高扩展性 —— Nginx的设计极具扩展性, 它完全是由多个不同功能、 不同层次、 不同类型且耦合度极低的模块组成。因此, 当对某一个模块修复Bug或进行升级时, 可以专注于模块自身, 无须在意其他。
  • 高可靠性 —— 官方提供的常用模块都非常稳定, 每个worker进程相对独立, master进程在1个worker进程出错时可以快速“拉起”新的worker子进程提供服务。

与其他Web服务器的对比

  • TomcatJetty面向Java语言, 先天就是重量级的Web服务器, 它们的性能与Nginx没有可比性。
  • IIS只能在Windows操作系统上运行,Windows作为服务器在性能和稳定性上不如类UNIX操作系统,因此需要高性能Web服务器时,IIS一般不会入选。
  • Apache是老牌服务器,超稳定、少BUG、rewrite强大、善于处理动态请求,但由于采用同步多进程,一个连接对应一个进程,这使得它在性能上落后Nginx。

功能

Nginx的三大功能:

  1. 反向代理  —— 区别于正向代理(隐藏真实客户端),可以隐藏真实服务端
  2. 负载均衡  —— 将Nginx接收到的请求按照规则分发(是反向代理的一种体现)
  3. 缓存        —— 在客户端和服务端之间临时存储某些数据,加快后续访问

当然也有其他功能,如限流等。

反向代理

主要用到了 proxy_pass URL ,URL可以是主机名或IP地址加端口的形式,还可以使用upstream块(负载均衡)。

值得注意的是,默认情况下反向代理不会转发请求头中的Host、X-Real-IP等头部信息,这会使得服务端无法获取到客户端真实信息如IP地址,解决办法在下面的Nginx配置文件示例中给出。

http {
    
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    #gzip_http_version 1.0;
    gzip_comp_level 6;
    gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    gzip_vary off;
    gzip_disable "MSIE [1-6]\.";


    include       mime.types;
    default_type  application/octet-stream;

    #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  logs/access.log  main;

    sendfile        on;
    keepalive_timeout  65;

    #gzip  on;

    #  配置反向代理
    server {

    	listen 80;
    	server_name www.vnshu.com;
        location / {
            #  转发到服务端的666端口
            proxy_pass http://127.0.0.1:666;
            proxy_redirect off;
            #  将一些真实头部信息转发给服务端
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Poto $scheme;
        }
    }
}

上述配置文件中,将www.vnshu.com域名的请求转发到后端server的666端口进行处理。

负载均衡

大多数网站刚开始时都是一台服务器就能应付了,但随着用户的增长,访问量越来越大,单台服务器就很难扛住了。这时候就需要部署集群来分担流量压力,当请求到Nginx时,Nginx就会根据一定的规则把请求分配给不同的服务器,从而实现负载均衡。Nginx修炼之路(一)

负载均衡有多种算法,如轮询、IP哈希、权重(加权轮询和加权随机)、随机、最小连接数等。

下面是轮询算法的实现,Nginx将按时间顺序分配请求。

upstream serverList {
    server 1.2.3.4;
    server 1.2.3.5;
    server 1.2.3.6;
}

下面是ip_hash算法的实现,同一个IP固定访问同一个服务器,可以解决session的问题(但某台服务器崩溃就会导致与之相关的客户端登录失效)。

upstream serverList {
    ip_hash;
    server 1.2.3.4;
    server 1.2.3.5;
    server 1.2.3.6;
}

其他就不一一列举了。

下面是同一台主机不同端口的轮询负载均衡主要配置:

upstream pool {
	server localhost:8081;
	server localhost:8082;
}

server {
	listen 9999;
	server_name localhost;
	location / {
	    proxy_pass http://pool;
	}
}

开启两个业务逻辑相同的应用,分别监听8081和8082端口,然后访问localhost:9999的请求就会转发给这两个应用进行处理。

每一种负载均衡算法中,在server 行后面可以携带一些参数,如:

  1. down:  当前服务器不参与负载
  2. weight:  权重,值越大,服务器的负载量越大
  3. max_fails:允许请求失败的次数,默认为1
  4. fail_timeout:  max_fails次失败后暂停的时间
  5. backup: 备份机, 只有其它所有的非backup机器down或者忙时才会请求backup机器

session不一致

负载均衡常常会导致session不一致,从而使得客户端需要频繁重新登录。

session不一致目前的解决方案有以下三种:

  1. 会话保持 
  2. 会话复制
  3. 会话共享

1. 会话保持

通过会话保持,负载均衡进行请求分发的时候保证每个客户端固定地访问到后端的同一台应用服务器。

nginx的ip_hashurl_hash(非官方模块,nginx版本1.7.2之前需要额外安装)都是可行的session解决方案。

  • ip_hash —— 同一客户端IP访问转发到同一后端server
  • url_hash —— 访问同一url转发到同一后端server(适用于缓存,访问指定url的请求都转发到某台缓存服务器,加快速度)

会话保持带来了两个问题

  1. 一定程度上破坏了负载均衡
  2. 某台server宕机导致session丢失,从而被分配到该台server的客户端仍需重新登录

2. 会话复制

将每台server上存储的session都复制到集群中其他server,最终所有集群server中的session信息都是一致的,但规模较大的集群就不推荐使用了。

3. 会话共享

前两种方法都有瑕疵,会话共享将session放在统一的地方,比较推荐使用

session由于需要频繁使用,所以也更推荐存放在存取速度更快的分布式KV数据库中,如Redis。

小结

本文就Nginx的非常常用的两个功能做了一些介绍与示例的给出,学会了这几个功能,简单的开发和部署就不是什么问题了。

nginx的负载均衡并不是真正的负载均衡,因为它并不知道某个用户对后端服务器的压力大小,只是根据请求次数按照相应规则进行分配而已。

参考

Apache和Nginx的区别

Nginx和Tomcat的区别

nginx系列之一:nginx入门

Nginx主要功能及使用

nginx常用功能全揭秘

使用Nginx实现负载均衡

评论或私信站长

1 条评论

  1. #1

    匿名用户 2020-08-03 17:12
    有 . 东西