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

(十三)负载均衡

  • 轮询
  1. http {
  2. upstream myapp1 {
  3. server srv1.example.com;
  4. server srv2.example.com;
  5. server srv3.example.com;
  6. }
  7.  
  8. server {
  9. listen ;
  10.  
  11. location / {
  12. proxy_pass http://myapp1;
  13. }
  14. }
  15. }

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

  • 最少连接
  1. upstream myapp1 {
  2. least_conn; //最少连接
  3. server srv1.example.com;
  4. server srv2.example.com;
  5. server srv3.example.com;
  6. }

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

  • ip_hash (会话持久性)
  1. upstream myapp1 {
  2. ip_hash; //ip_hash
  3. server srv1.example.com;
  4. server srv2.example.com;
  5. server srv3.example.com;
  6. }

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

  • 加权

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

  1. upstream myapp1 {
  2. server srv1.example.com weight=;
  3. server srv2.example.com;
  4. server srv3.example.com;
  5. }

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

其他参数

 
 

(十四)HTTPS

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

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

nginx配置:

  1. ssl on;
  2. ssl_certificate /etc/nginx/ssl_key/example.crt;
  3. 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:

  1. # cd /usr/local/src
  2. # wget http://luajit.org/download/LuaJIT-2.0.2.tar.gz
  3. # tar -xzvf LuaJIT-2.0..tar.gz
  4. # cd LuaJIT-2.0.
  5. # make
  6.  
  7. 出现如下内容表示编译成功
  8. OK Successfully built LuaJIT
  9. make[]: Leaving directory `/usr/local/src/LuaJIT-2.0./src'
  10. ==== Successfully built LuaJIT 2.0. ====
  11.  
  12. # make install
  13. 出现如下内容,表示安装成功
  14. ==== Successfully installed LuaJIT 2.0. to /usr/local ====

下载nginx_lua 模块

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

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

  1. ./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
  2.  
  3. 接着make (不要使用make install

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

  1. [root@VM_71_225_centos data]# nginx -V
  2. nginx version: nginx/1.4.
  3. built by gcc 4.8. (Red Hat 4.8.-) (GCC)
  4. TLS SNI support enabled
  5. 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.

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

  1. cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_bk
    nginx -s stop
  2. cp objs/nginx /usr/local/nginx/sbin/nginx
  3. nginx

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

可能遇到的错误:

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

使用:

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

openresty 请自行查看其它教程

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

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

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

nginx.conf配置:

  1. location / {
  2. default_type "text/html";
  3. content_by_lua_file /opt/app/lua/dep.lua;
  4. #add_after_body "$http_x_forwarded_for";
  5. }
  6.  
  7. location @server{
  8. proxy_pass http://127.0.0.1:9090;
  9. }
  10.  
  11. location @server_test{
  12. proxy_pass http://127.0.0.1:8080;
  13. }

dep.lua:

  1. clientIP = ngx.req.get_headers()["X-Real-IP"] //获取用户的真实IP
  2. if clientIP == nil then
  3. clientIP = ngx.req.get_headers()["x_forwarded_for"]
  4. end
  5. if clientIP == nil then
  6. clientIP = ngx.var.remote_addr //尝试用remote_addr来获取用户ip
  7. end
  8. local memcached = require "resty.memcached" //从memcache中获得允许查看新版本的Ip列表
  9. local memc, err = memcached:new()
  10. if not memc then
  11. ngx.say("failed to instantiate memc: ", err)
  12. return
  13. end
  14. local ok, err = memc:connect("127.0.0.1", )
  15. if not ok then
  16. ngx.say("failed to connect: ", err)
  17. return
  18. end
  19. local res, flags, err = memc:get(clientIP)
  20. ngx.say("value key: ",res,clientIP)
  21. if err then
  22. ngx.say("failed to get clientIP ", err)
  23. return
  24. end
  25. if res == "" then
  26. ngx.exec("@server_test") //转发到server_test 服
  27. return
  28. end
  29. ngx.exec("@server") //否则转发到server正式服

 (十七)gzip压缩 

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

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

 (十八)直连memcache 和redis模块

配置举例(memcache):

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

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

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

worker_processes

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

worker_cpu_affinity

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

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

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

(二十)其他场景问题:

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

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

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

定时任务为

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

先看root

  1. location /request_path/image/ {
  2. root /local_path/image/;
  3. }

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

再看alias

  1. location /request_path/image/ {
  2. alias /local_path/image/;
  3. }

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

nginx 场景业务汇总 (中)的更多相关文章

  1. nginx 场景业务汇总 (初)

    本文链接:http://www.cnblogs.com/zhenghongxin/p/8891385.html 在下面的测试中,建议每次修改nginx配置文件后,都用此命令检查一下语法是否正确: [r ...

  2. 从App业务逻辑中提炼API接口

    2.1 从App业务逻辑中提炼API接口 业务逻辑思维导图 功能-业务逻辑思维导图 基本功能模块关系 功能模块接口UML(设计出API) 在设计稿标注API 编写API文档 2.2 设计API的要点 ...

  3. {Python之线程} 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Threading模块 九 锁 十 信号量 十一 事件Event 十二 条件Condition(了解) 十三 定时器

    Python之线程 线程 本节目录 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Thr ...

  4. 聊聊业务系统中投递消息到mq的几种方式

    背景 电商中有这样的一个场景: 下单成功之后送积分的操作,我们使用mq来实现 下单成功之后,投递一条消息到mq,积分系统消费消息,给用户增加积分 我们主要讨论一下,下单及投递消息到mq的操作,如何实现 ...

  5. 架构设计 | 分布式业务系统中,全局ID生成策略

    本文源码:GitHub·点这里 || GitEE·点这里 一.全局ID简介 在实际的开发中,几乎所有的业务场景产生的数据,都需要一个唯一ID作为核心标识,用来流程化管理.比如常见的: 订单:order ...

  6. 17SpringMvc_在业务控制方法中写入包装User的模型来收集参数——解决问题

    在解决问题之前,我要说明一下jsp页面上填入信息,一个用户的信息比如用户的名字,用户的电话,用户的手机等等,在这个jsp页面上填好信息后,转到有个action处理这个信息.原理是什么? 在jsp页面上 ...

  7. 15SpringMvc_在业务控制方法中写入模型变量收集参数,且使用@InitBind来解决字符串转日期类型

    之前第12篇文章中提到过在业务控制方法中写入普通变量收集参数的方式,也提到了这种凡方式的弊端(参数很多怎么办),所以这篇文章讲的是在业务控制方法中写入模型变量来收集参数.本文的案例实现的功能是,在注册 ...

  8. JVM 性能调优实战之:使用阿里开源工具 TProfiler 在海量业务代码中精确定位性能代码

    本文是<JVM 性能调优实战之:一次系统性能瓶颈的寻找过程> 的后续篇,该篇介绍了如何使用 JDK 自身提供的工具进行 JVM 调优将 TPS 由 2.5 提升到 20 (提升了 7 倍) ...

  9. 在后台业务管理系统中使用Autofac实现微信接口的处理

    在后台业务管理系统中使用Autofac实现微信接口的处理,我们只需要把相关使用到的DLL放到BIN目录里面即可,通过IOC控制反转方式实现对接口的调用.在实现在业务系统里面,我们本身程序可能已经依赖了 ...

随机推荐

  1. Android可以子线程更新UI?

    初了解Android的时候,就知道Android是不能在子线程更新UI的,不然程序会直接抛出异常,告诉你,别给我在自线程搞事情! 但是,这个是针对普通的view做的限制,而TextureView,Su ...

  2. 从输入url到显示网页发生了什么

    原文链接:https://juejin.im/post/5bf23afa6fb9a049be5d1494 在浏览器中输入url到显示网页主要包含两个部分: 网络通信和页面渲染 互联网内各网络设备间的通 ...

  3. 779A Pupils Redistribution

    /* A. Pupils Redistribution time limit per test 1 second memory limit per test 256 megabytes input s ...

  4. p3412 [POI2005]SKO-Knights

    传送门 分析 图1 我们假设我们现在有两个向量(2,3)和(4,2),将他们所能到达的点在几何画板上画出来,再将这些点用红线连起来,在将横坐标相同的点用蓝线连起来便能得到图1,就此我们可以发现可以用绿 ...

  5. poj3017 Cut the Sequence 单调队列 + 堆 dp

    描述 把一个正数列 $A$分成若干段, 每段之和 不超过 $M$, 并且使得每段数列的最大值的和最小, 求出这个最小值. 题目链接 题解 首先我们可以列出一个$O(n^2)$ 的转移方程 : $F_i ...

  6. 自然语言处理--中文文本向量化counterVectorizer()

    1.载入文档 #!/usr/bin/python # -*- coding: utf-8 -*- import pandas as pd import re import jieba from skl ...

  7. 2018.09.24 bzoj1867: [Noi1999]钉子和小球(概率dp)

    传送门 概率dp经典题. 如果当前位置(i,j)(i,j)(i,j)有钉子,那么掉到(i+1,j),(i+1,j+1)(i+1,j),(i+1,j+1)(i+1,j),(i+1,j+1)的概率都是1/ ...

  8. Java转换Json日期/Date(1487053489965+0800)/格式以及js时间格式 Tue Feb 14 2017 14:06:32 GMT+0800

    /Date(1487053489965+0800)/用Java怎么转换成yyyy-MM-dd的格式 Tue Feb 14 2017 14:06:32 GMT+0800用Java怎么转换成yyyy-MM ...

  9. 【Unity】1.2 HelloWorld--测试桌面和Android游戏能否正常运行

    分类:Unity.C#.VS2015 创建日期:2016-03-23 一.简介 这一节先搞一个最简单的Unity游戏,目的是为了验证Unity的桌面游戏开发环境和Android游戏开发环境是否有问题. ...

  10. 自学如何去学习jQuery

    学习JQ第一个demo: 制作一个轮播图,制作方法我前面写了一篇博客,传送门-->http://www.cnblogs.com/yewenxiang/p/6100206.html 需要的JQ知识 ...