本文链接: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. 使用jdbc编程实现对数据库的操作以及jdbc问题总结

    1.创建数据库名为mybatis. 2. 在数据库中建立两张表,user与orders表: (1)user表: (2)orders表: 3.创建工程 * 开发环境: * eclipse mars *  ...

  2. css3阴影效果

    http://blog.csdn.net/freshlover/article/details/7610269

  3. Android 获取ROOT权限原理解析

    一. 概述 本文介绍了android中获取root权限的方法以及原理,让大家对android玩家中常说的“越狱”有一个更深层次的认识. 二. Root的介绍 1.       Root 的目的 可以让 ...

  4. No handlers could be found for logger “apscheduler.executors.default”?

    Call logging.basicConfig() before instantiating the scheduler. That lets you see what the real probl ...

  5. Spring boot 默认静态资源路径与手动配置访问路径的方法

    这篇文章主要介绍了Spring boot 默认静态资源路径与手动配置访问路径的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下   在application.propertis中配置 ##端口号 ...

  6. CSS 关键的基础知识

    今晚看了 百度传课 一门关于CSS的课程, 感觉不错, 随手记了点儿笔记, 供以后查阅. =================================================== pos ...

  7. SQLInjection 靶场配置

    对于渗透,太小型的网站没有太大价值,而大型网站(比如各种电商平台)对于代码审计往往非常严格,新手基本找不到漏洞,而一些比较容易搞掉的站点(政府.gov.各种教育网站.edu或者很多商业中型站点)渗透又 ...

  8. 2018.09.26 bzoj5221: [Lydsy2017省队十连测]偏题(数学推导+矩阵快速幂)

    传送门 由于没有考虑n<=1的情况T了很久啊. 这题很有意思啊. 考试的时候根本不会,骗了30分走人. 实际上变一个形就可以了. 推导过程有点繁杂. 直接粘题解上的请谅解. 不得不说这个推导很妙 ...

  9. vi 基本使用命令

    说明:以下的例子中 xxx 表示在命令模式下输入 xxx 并回车以下的例子中 :xxx 表示在扩展模式下输入 xxx 并回车小括号中的命令表示相关命令在编辑模式或可视模式下输入的命令会另外注明 1 查 ...

  10. SimpleAdapter 网络视图:带预览的图片浏览器

    MainActivity.java public class MainActivity extends Activity { GridView grid; ImageView imageView; i ...