本文链接: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 ; 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=;
server srv2.example.com;
server srv3.example.com;
}

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

其他参数

 
 

(十四)HTTPS

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

# 创建服务器私钥,命令会让你输入一个口令:
openssl genrsa -des3 -out server.key # 创建签名请求的证书(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 -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..tar.gz
# cd LuaJIT-2.0.
# make 出现如下内容表示编译成功
OK Successfully built LuaJIT
make[]: Leaving directory `/usr/local/src/LuaJIT-2.0./src'
==== Successfully built LuaJIT 2.0. ==== # make install
出现如下内容,表示安装成功
==== Successfully installed LuaJIT 2.0. 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.
built by gcc 4.8. (Red Hat 4.8.-) (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.

完成之后停止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./sbin/nginx -v
./objs/nginx: error while loading shared libraries: libluajit-5.1.so.: cannot open shared object file: No such file or directory
解决方法:
# ln -s /usr/local/lib/libluajit-5.1.so. /lib64/libluajit-5.1.so.

使用:

    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", )
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 == "" 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 ; # 所压缩文件的最小值,小于这个的不会压缩
gzip_buffers 1k; # 设置压缩响应的缓冲块的大小和个数,默认是内存一个页的大小
gzip_comp_level ; # 压缩水平,默认1。取值范围1-,取值越大压缩比率越大,但越耗cpu时间
}

 (十八)直连memcache 和redis模块

配置举例(memcache):

 upstream memserver {  把用到的memcached节点,声明在一个组里
hash_key $request_uri; // hash计算时的依据,以uri做依据来hash
server localhost:;
server localhost:;
}
location / {
# root html;
set $memcached_key $uri;
memcached_pass memserver; // memserver为上面的memcache节点的名称
error_page /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  ; 四个进程
worker_cpu_affinity ;
//四组值,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重新生成新的日志文件

定时任务为

  * * * /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

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. Django之常用命令以及问题汇总

    基本命令 1.新建一个django项目 django-admin.py startproject project-name 2.新建一个app python manage.py startapp ap ...

  2. linux下memcache安装

    安装配置 1. 安装libevent # tar zxf libevent-1.4.6-stable.tar.gz # cd libevent-1.4.6-stable # ./configure # ...

  3. SNP/单核苷酸多态性分析

    SNP/单核苷酸多态性分析 SNP(Single Nucleotide Polymorphism),即单核苷酸多态性,是由于单个核苷酸改变而导致的核酸序列多态.一般来说,一个SNP位点只有两种等位基因 ...

  4. python性能测试大致计划

      hi guy: 如果注意到创建时间,那就对了.这份文章,是我学习Python一个月以后动手写的.   写下这份计划以后,只完成了第一步,其中磕磕绊绊编写代码的过程,很大一部分时间是完全用txt写的 ...

  5. 主成分_CPA

    基本原理:方差最大原理 通过正交变换将原相关性变量转化为不相关的变量 第一主成分:线性组合  方差最大 第二主成分:线性组合,COV(F1,F2)=0 步骤: 原始数据标准化:DataAdjust(m ...

  6. 设计模式之java源码-工厂方法模式

    工厂方法模式 8.1 女娲造人的故事 东汉<风俗通>记录了一则神话故事:“开天辟辟,未有人民,女娲搏,黄土作人……”,讲述的内容就是大家非常熟悉的女娲造人的故事.开天辟地之初,大地上并没有 ...

  7. c++11多线程学习笔记之一 thread基础使用

    没啥好讲的  c++11  thread类的基本使用 #include "stdafx.h" #include <iostream> #include <thre ...

  8. 百度词汇检索,计算PMI值

    '''词汇检索百度返回值,并且计算PMI值的类''' from bs4 import BeautifulSoup import requests import re import pandas as ...

  9. 2018.09.14 codeforces364D(随机化算法)

    传送门 根据国家集训队2014论文集中胡泽聪的随机化算法可以通过这道题. 对于每个数,它有12" role="presentation" style="posi ...

  10. Cygwin工具的简单使用

    简介 从使用角度来看:Cygwin就是一个windows软件,该软件就是在windows上仿真linux操作系统.简言之,cygwin是一个在windows平台上运行的 linux模拟环境,使用一个D ...