tomoya06 / web-developer-guidance

Actually it's just a notebook for keeping down some working experience.
4 stars 0 forks source link

Nginx - Basic #27

Open tomoya06 opened 3 years ago

tomoya06 commented 3 years ago

Nginx

概述

简介 :Nginx(发音同“engine X”)是异步框架的网页服务器,也可以用作反向代理、负载平衡器和HTTP缓存。

最初Nginx是为了解决早年的C10K问题而生的。C10K,C代表Client客户、10K代表10000,即一台服务器同时保持1万链接。【来源】

常用功能

http代理

作为web服务器最常用的功能之一,尤其是反向代理。有关网络代理的介绍参考另一篇issue

Nginx在做反向代理时,提供性能稳定,并且能够提供配置灵活的转发功能。

配置参考如下:

#配置单个反向代理节点
server { 
    listen       80;
    server_name  big.server.com;
    access_log   logs/big.server.access.log  main;

    location / {
      proxy_pass      http://127.0.0.1:8080;
    }
}

#配置一组反向代理服务节点
upstream big_server_com {
    server 192.168.0.1:8000;
    server 192.168.0.1:8001;
}
server { 
    listen          80;
    server_name     big.server.com;
    access_log      logs/big.server.access.log main;

    location / {
        proxy_pass      http://big_server_com;
    }
}

负载均衡

负载平衡(Load balancing)是一种计算机技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最优化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。

用Nginx做负载均衡,Nginx有绝对的决策权,可以按照规则将请求分配给它知道的节点中的一个,通过这种分配,使得所有节点需要处理的请求量处于相对平均的状态,从而实现负载均衡。

Nginx支持的负载均衡策略分类如下。配置参考掘金博客

最佳实现

upstream server_group {
   ##默认配置即为轮询策略 
   #random; ##随机策略
   server backend1.example.com; 
   server backend2.example.com; 
   server backend3.example.com; 
   server backend4.example.com;
}

性能优先

upstream server_group {
    ##最少连接数
    server backend1.example.com weight=5;
    server backend2.example.com; #默认为不配置权重为1
}
upstream server_group{
   ##fair;
   ##least_conn;
   server backend1.example.com; 
   server backend2.example.com; 
   server backend3.example.com; 
   server backend4.example.com;
}

保持稳定

upstream server_group {
    ##ip_hash;
    ##hash $request_uri consistent;
    server backend1.example.com;
    server backend2.example.com;
}

哈希负载均衡详解

普通hash即通过hash计算得出的hash值和总权重的余数作为挑选server的依据。nginx中使用的一致性hash是一种通用算法。

一致性hash本质上是把服务器的hash值映射到同一个环上(环上的数值范围是0~2^23)。要确定一个请求key将分配给哪台服务器,首先也将key的hash值映射到这个环上,然后找到顺时针方向离该hash最近的服务器即可。

参考维基百科,普通哈希在服务器数量发生变化时,可能会改变所有资源对应的hash值,也就是所有的缓存都失效了,这会使得缓存服务器大量集中地向原始内容服务器更新缓存。一致哈希算法的主要思想是将每个缓存服务器与一个或多个哈希值域区间关联起来,其中区间边界通过计算缓存服务器对应的哈希值来决定;如果服务器数量发生变化,只有相邻区间边界的服务器会受到影响,其他服务器不需要任何改变。

避免雪崩

一对一的一致性哈希可能会出现雪崩现象,即一个节点挂掉后,对相邻节点带来加倍的流量压力。解决方法是引入虚拟节点,即每个实际服务器节点可以映射到多个hash值节点,这样可以让各个服务器都有机会分摊问题节点的流量。

image

HTTP缓存

http缓存分强缓存和协商缓存。强缓存主要是expires和cache-control两个请求头;协商缓存有etag和last-modified等请求头。

location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
    expires 2d; #设置有效时间为2d
    add_header Cache-Control "public, no-transform"; #public资源;no-transform不得对资源进行转换或转变
}

根据测试,协商缓存 last-modified + etag 默认是开启的。

tomoya06 commented 3 years ago

HTTP/2

nginx开启http/2,准备工作可参考掘金博客

Push

http/2一大特点是支持服务器推送。nginx支持配置推送文件包。

server {
    # Ensure that HTTP/2 is enabled for the server        
    listen 443 ssl http2;

    ssl_certificate ssl/certificate.pem;
    ssl_certificate_key ssl/key.pem;

    root /var/www/html;

    # whenever a client requests demo.html, also push
    # /style.css, /image1.jpg and /image2.jpg
    location = /demo.html {
        http2_push /style.css;
        http2_push /image1.jpg;
        http2_push /image2.jpg;
    }
}

更多配置方案参考nginx官方文档

tomoya06 commented 3 years ago

Gzip

Nginx开启Gzip压缩功能, 可以使网站的 css/js/xml/html 文件在传输时进行压缩,提高访问速度,进而优化Nginx性能。

http {
    gzip on;                 #决定是否开启gzip模块,on表示开启,off表示关闭;
    gzip_min_length 1k;      #设置允许压缩的页面最小字节(从header头的Content-Length中获取) ,当返回内容大于此值时才会使用gzip进行压缩,以K为单位,当值为0时,所有页面都进行压缩。建议大于1k
    gzip_buffers 4 16k;      #设置gzip申请内存的大小,其作用是按块大小的倍数申请内存空间,param2:int(k) 后面单位是k。这里设置以16k为单位,按照原始数据大小以16k为单位的4倍申请内存
    gzip_http_version 1.1;   #识别http协议的版本,早起浏览器可能不支持gzip自解压,用户会看到乱码
    gzip_comp_level 2;       #设置gzip压缩等级,等级越底压缩速度越快文件压缩比越小,反之速度越慢文件压缩比越大;等级1-9,最小的压缩最快 但是消耗cpu
    gzip_types text/plain application/x-javascript text/css application/xml;    #设置需要压缩的MIME类型,非设置值不进行压缩,即匹配压缩类型
    gzip_vary on;            #启用应答头"Vary: Accept-Encoding"
}

更多配置直接Google

tomoya06 commented 3 years ago

移动端跳转

问题引用自这里

在nginx配置路由时可以根据$http_user_agent来获取和判断访问者的UA。

server {
    listen       80;
    server_name  www.phpblog.com.cn;
        # 匹配移动端的跳转
    if ($http_user_agent ~* (mobile|nokia|iphone|ipad|android|samsung|htc|blackberry)) {
            rewrite  ^(.*)    http://m.phpblog.com.cn$1 permanent;
        }
        # 不匹配移动端的跳转
    if ($http_user_agent !~* (mobile|nokia|iphone|ipad|android|samsung|htc|blackberry)) {
            rewrite  ^(.*)    http://www.phpblog.com.cn$1 permanent;
        }
    location / {
        root   www;
        index  index.html index.htm;
    }
}