zoukankan      html  css  js  c++  java
  • nginx 场景业务汇总 (中)

    本文链接:http://www.cnblogs.com/zhenghongxin/p/8906225.html,如果可以,请阅读上篇 《nginx场景业务汇总(初)》

    (十三)负载均衡

    • 轮询
    http {
        upstream myapp1 {
            server srv1.example.com;
            server srv2.example.com;
            server srv3.example.com;
        }
     
        server {
            listen 80;
     
            location / {
                proxy_pass http://myapp1;
            }
        }
    }

    公平调度原则轮询,类似于rabbitMq的调度规则。依次将请求分发到srv1,srv3,srv3,。

    • 最少连接
    upstream myapp1 {
            least_conn;  //最少连接
            server srv1.example.com;
            server srv2.example.com;
            server srv3.example.com;
        }

    哪个服务器负载低,就分发到此服务器

    • ip_hash (会话持久性)
    upstream myapp1 {
        ip_hash;    //ip_hash
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }

    这是部分解决session共享问题的方法。让同个ip的访问始终分发于某个服务器上,保持会话的一致性。

    • 加权

    利用权重来促使nginx多分发到某些性能高效的服务器。

    upstream myapp1 {
            server srv1.example.com weight=3; 
            server srv2.example.com;
            server srv3.example.com;
        }

    也就是说,如果有五个请求,有3个请求被分发到srv1,一个请求到srv2,一个请求到srv3

    其他参数

     

     
     

    (十四)HTTPS

     为了网站后台更加安全,之前我们做过让后台需要证书登录,但做的是用openssl生成的免费证书。

    # 创建服务器私钥,命令会让你输入一个口令:
    openssl genrsa -des3 -out server.key 1024
    
    # 创建签名请求的证书(CSR):
    openssl req -new -key server.key -out server.csr
    
    # 加载SSL支持的Nginx并使用上述私钥时除去必须的口令:
    cp server.key server.key.org
    openssl rsa -in server.key.org -out server.key
    
    
    # 标记证书使用上述私钥和CSR:
    openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
    
    注意day时间为一年过期

    nginx配置:

       ssl on;
       ssl_certificate /etc/nginx/ssl_key/example.crt;
       ssl_certificate_key /etc/nginx/ssl_key/example.key;

    (十五)openresty 与 lua (ngx_lua)

    我们可以看网络上对它的描述:OpenResty 是一个强大的 Web 应用服务器,Web 开发人员可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,更主要的是在性能方面,OpenResty可以 快速构造出足以胜任 10K 以上并发连接响应的超高性能 Web 应用系统。所以对于一些高性能的服务来说,可以直接使用 OpenResty 访问 Mysql或Redis等,而不需要通过第三方语言(PHP、Python、Ruby)等来访问数据库再返回,这大大提高了应用的性能。确实,该模块非常强大,在很多业务场景都可以用,因为是nginx本身的模块,比起nginx转发给php处理快多了。该模块可以处理的业务:

    • 秒杀场景 -  openresty 是可以直接连接redis,这会产生更快的速度。判断库存是否存在,在秒杀这种高并发的业务下极为适合
    • web保护层 - 在连接php应用前,做一些可以不用php处理的过滤,校验等
    • 统计 - 不放在php层,而是放在nginx模块完成
    • 图片与音频 - 要具体业务分析,我们的业务图片用到此模
    • 限流
    • 缓存
    • 降级
    • 灰度发布等等很多

    使用ngx_lua,先安装luaJIT:

    # cd /usr/local/src
    # wget http://luajit.org/download/LuaJIT-2.0.2.tar.gz
    # tar -xzvf LuaJIT-2.0.2.tar.gz
    # cd LuaJIT-2.0.2
    # make
     
    出现如下内容表示编译成功
    OK        Successfully built LuaJIT
    make[1]: Leaving directory `/usr/local/src/LuaJIT-2.0.2/src'
    ==== Successfully built LuaJIT 2.0.2 ====
     
    # make install
    出现如下内容,表示安装成功
    ==== Successfully installed LuaJIT 2.0.2 to /usr/local ====

    下载nginx_lua 模块

    # cd /usr/local/src
    # wget https://github.com/chaoslawful/lua-nginx-module/archive/v0.8.6.tar.gz
    # tar -xzvf v0.8.6

    进入nginx源码,进行模块添加编译:

    ./configure --user=www --group=www --prefix=/phpstudy/server/nginx --with-http_ssl_module --with-http_sub_module --with-http_stub_status_module --with-pcre --with-http_secure_link_module 
            --add-module=/data/lua-nginx-module-0.8.6

    接着make (不要使用make install)

    可以使用命令查看之前所添加的模块:

    [root@VM_71_225_centos data]# nginx -V
    nginx version: nginx/1.4.6
    built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC) 
    TLS SNI support enabled
    configure arguments: --user=www --group=www --prefix=/phpstudy/server/nginx --with-http_ssl_module --with-http_sub_module --with-http_stub_status_module --with-pcre 
                --with-http_secure_link_module

                --add-module=/data/lua-nginx-module-0.8.6

     完成之后停止nginx,备份nginx,再把当前生成的nginx覆盖进去,重启nginx

     cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_bk
    nginx -s stop cp objs/nginx /usr/local/nginx/sbin/nginx nginx

     查看当前模块是否已经有lua

     可能遇到的错误:

    # /usr/local/nginx-1.4.2/sbin/nginx -v
    ./objs/nginx: error while loading shared libraries: libluajit-5.1.so.2: cannot open shared object file: No such file or directory
    解决方法:
    # ln -s /usr/local/lib/libluajit-5.1.so.2 /lib64/libluajit-5.1.so.2

    使用:

        location /hello {
            default_type 'text/plain';
            content_by_lua 'ngx.say("hello, lua")';
        }

    openresty 请自行查看其它教程

    (十六)基于上述的灰度发布

    即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。可以保证软件的稳定性。比如我们要上一个新的接口,可以通过在业务Nginx通过Lua写复杂的业务规则实现不同的人看到不同的版本。

    以下是一个简单的示例,根据用户IP来体验不同的版本:

    nginx.conf配置:

        location / {
            default_type "text/html"; 
            content_by_lua_file /opt/app/lua/dep.lua;
            #add_after_body "$http_x_forwarded_for";
        }
    
        location @server{
            proxy_pass http://127.0.0.1:9090;
        }
    
        location @server_test{
            proxy_pass http://127.0.0.1:8080;
        }

    dep.lua:

    clientIP = ngx.req.get_headers()["X-Real-IP"]    //获取用户的真实IP
    if clientIP == nil then
        clientIP = ngx.req.get_headers()["x_forwarded_for"]
    end
    if clientIP == nil then
        clientIP = ngx.var.remote_addr    //尝试用remote_addr来获取用户ip
    end
        local memcached = require "resty.memcached"    //从memcache中获得允许查看新版本的Ip列表
        local memc, err = memcached:new()
        if not memc then
            ngx.say("failed to instantiate memc: ", err)
            return
        end
        local ok, err = memc:connect("127.0.0.1", 11211)
        if not ok then
            ngx.say("failed to connect: ", err)
            return
        end
        local res, flags, err = memc:get(clientIP)
        ngx.say("value key: ",res,clientIP)
        if err then
            ngx.say("failed to get clientIP ", err)
            return
        end
        if  res == "1" then
            ngx.exec("@server_test")    //转发到server_test 服
            return
        end
        ngx.exec("@server")   //否则转发到server正式服

     (十七)gzip压缩 

    用于对输出到客户端的内容进行压缩,以减小传输文件体积,减少对网络带宽的占用。在Web应用中通常启用gzip压缩,用来缩短响应时间,提升用户体验。

    # 对static目录下js、css、jpg、jpeg、png、gif后缀的文件启用gzip压缩功能
    location ~ /static/(.+).(js|css|jpg|jpeg|png|gif) {
        gzip on; # 启用gzip压缩,默认是off,不启用
        # 对js、css、jpg、png、gif格式的文件启用gzip压缩功能
        gzip_types application/javascript text/css image/jpeg image/png image/gif;
        gzip_min_length 1024; # 所压缩文件的最小值,小于这个的不会压缩
        gzip_buffers 4 1k; # 设置压缩响应的缓冲块的大小和个数,默认是内存一个页的大小
        gzip_comp_level 1; # 压缩水平,默认1。取值范围1-9,取值越大压缩比率越大,但越耗cpu时间
    }

     (十八)直连memcache 和redis模块

     配置举例(memcache):

     upstream memserver {  把用到的memcached节点,声明在一个组里
            hash_key $request_uri;  // hash计算时的依据,以uri做依据来hash
            server localhost:11211;
            server localhost:11212;
        }
    location / {
               # root   html;
               set $memcached_key $uri;
               memcached_pass memserver;  // memserver为上面的memcache节点的名称
               error_page 404 /writemem.php;
               index  index.php index.html index.htm;
            }

    那么这里,我们会发现挂上两台memcache,nginx会以轮询的方式去连接两台memcache,如果想要用其他的负载均衡算法,可以安装第三方模式。

      (十九)提高Nginx的CPU亲和力

    worker_processes

    worker_processes指令是用来设计Nginx进程数,官方默认设为1,赋值太多了,将会对系统IO影响效率,降低Nginx服务器性能。但是为了让多核CPU能够更好的处理并行任务,我们可以讲该值设置大一些,最好这个值是机器CPU的个数一致,并不是越大越好。 如针对双核CPU 将他设置为2 ,四核CPU可以设置为4

    worker_cpu_affinity

    用来分配每个进程的CPU的工作内核 ,例如是四核的CPU,可以这么设置:

    worker_processes 4 ; 四个进程
    worker_cpu_affinity 0001 0010 0100 1000; 
    //四组值,0是不使用,1是使用。 这样每一个进程都有一个 cpu内核了。
    {解析 四组二进制值分别对应着四个进程,第一个进程对应的是0001 第二个进程对应的是0010,表示第二个进程计算器内核,第三个进程对应的是0100,表示第三个计算机内核,第四个进程对应1000}

    如果八核,那就是八个数,以此类推,这样设置太麻烦了,所以nginx在1.9版本之后,已经可以设置为auto了,让其自动分配

    (二十)其他场景问题:

    • nginx如何将日志按日期分割?

    利用定时任务+nginx信号管理来实现,定时脚本如下:

    #!/bin/bash
    base_path='/usr/local/nginx/logs'
    log_path=$(date -d yesterday +"%Y%m")
    day=$(date -d yesterday +"%d")
    mkdir -p $base_path/$log_path
    mv $base_path/access.log $base_path/$log_path/access_$day.log  //定时移动日志到其他目录
    #echo $base_path/$log_path/access_$day.log
    kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`  //USR1信息号控制nginx重新生成新的日志文件

    定时任务为

    01 00 * * * /xxx/path/b.sh  每天0时1分
    • alias的用法及与root的区别 ?

     先看root

    location /request_path/image/ {
        root /local_path/image/;
    }

    Nginx把请求映射为/local_path/image/request_path/image/xxx.png 下

    再看alias

    location /request_path/image/ {
        alias /local_path/image/;
    }

    Nginx把请求映射为/local_path/image/xxx.png 

  • 相关阅读:
    陶哲轩实分析 12.5.15 :有限交性质
    opencvresize修改图像尺寸
    opencvflip翻转
    opencvarcLength计算轮廓周长
    opencvLUT查表
    opencvcontourArea计算轮廓面积
    opencvRNG产生随机数
    opencvSVD奇异值分解
    opencvreshape修改行数和通道数
    opencvmean计算均值
  • 原文地址:https://www.cnblogs.com/zhenghongxin/p/8906225.html
Copyright © 2011-2022 走看看