文章目录

  • 前言
  • 一、单机垂直扩容
  • 二、水平扩展:集群化
    • ip_hash
      • ip_hash介绍
      • ip_hash实现
      • ip_hash配置
      • ip_hash的使用场景
      • ip_hash的优缺点
    • hash $request_uri
      • hash $request_uri介绍
      • hash $request_uri配置
      • hash $request_uri使用场景
    • 使用sticky模块
      • sticky介绍
      • sticky配置
      • 注意项

前言

为了提高吞吐量,可以对nginx进行扩容处理。
其中,nginx两种扩容方式:(1)单机垂直扩容;(2)水平扩展
接下来对这两种方式进行讲解学习。


一、单机垂直扩容

增加硬件资源,提高性能,物理手段
主要方式有:
云服务资源增加
整机:IBM、浪潮、DELL、HP等
CPU/主板:更新到主流
网卡:10G/40G网卡
磁盘:SAS(SCSI) HDD(机械)、HHD(混合)、SATA SSD、PCI-e SSD、 MVMe SSD
SSD
多副本机制
系统盘/热点数据/数据库存储
HDD
冷数据存储

接下来水平化扩展方式,才是我们真正要学习的

二、水平扩展:集群化

本次学习主要讲述:ip_hashhash $request_uri;使用sticky模块

ip_hash

ip_hash介绍

ip_hash技术能够将某个ip 的请求定向到同一台后端web机器中,这样一来这个ip 下的客户端和某个后端 web机器就能建立起稳固的session.(保持会话)
ip_hash机制能够让某一客户机在相当长的一段时间内只访问固定的后端的某台真实的web服务器,这样会话就会得以保持,在网站页面进行login的时候就不会在后面的web服务器之间跳来跳去了,也不会出现登录一次的网站又提醒重新登录的情况.
了解了ip_hash,我们知道nginx是靠c语言来实现的,那么ip_hash是怎么实现的呢?只有从根上出发才能更好的了解ip_hash 。

ip_hash实现

在ngx_http_upstream_ip_hash_module.c的源文件中,我们可以看到nginx的ip_hash算法的实现。
实现代码如下:

for ( ;; ) {for (i = 0; i < 3; i++) {  hash = (hash * 113 + iphp->addr[i]) % 6271; //iphp->addr[i]为ip的点分十进制法的第i段}p = hash % iphp->rrp.peers->number;n = p / (8 * sizeof(uintptr_t));m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));if (!(iphp->rrp.tried[n] & m)) {ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,"get ip hash peer, hash: %ui %04XA", p, m);peer = &iphp->rrp.peers->peer[p];/* ngx_lock_mutex(iphp->rrp.peers->mutex); */if (!peer->down) {if (peer->max_fails == 0 || peer->fails < peer->max_fails) {break;}if (now - peer->accessed > peer->fail_timeout) {peer->fails = 0;break;}}iphp->rrp.tried[n] |= m;/* ngx_unlock_mutex(iphp->rrp.peers->mutex); */pc->tries--;}if (++iphp->tries >= 20) {return iphp->get_rr_peer(pc, &iphp->rrp);}}

其中,重点就是哈希值的计算,代码如下:

for(i = 0; i < 3; i++) {hash = (hash * 113+ iphp->addr[i]) % 6271;
}

可以查询addrlen的值是3,从代码中可以看出,hash值是根据ip段的前三个来计算的,例如192.168.1.12,192.168.1.13,192.168.1.14 经过nginx的hash值计算是根据ip段的192 168 1来计算的。所以如果在本地的虚拟机中来使用这种负载均衡的方式,那么192.168.1.12,192.168.1.13,192.168.1.14 这三个ip访问的其实是一台tomcat。

了解了ip_hash实现,那么在实际开发中ip_hash是怎么配置的呢啊

ip_hash配置

配置也比较简单,只是在nginx的反向代理中,添加ip_hash关键字即可。
如下所示:

upstream httpds {# ip_haship_hash;server 192.168.44.102 ;server 192.168.44.103 ;
}
server {listen       80;server_name  localhost;location / {proxy_pass http://httpds;# root   html;}location ~*/(css|img|js) {root   /usr/local/nginx/html;}

了解了ip_hash的实现原理,以及配置。那么不仅疑惑,ip_hash怎么场景才使用比较好呢,它有什么优缺点啊

ip_hash的使用场景

适用业务场景:适用于需要账号登录的系统,会话连接保持的业务。

ip_hash的优缺点

优点:
(1)Nginx中的ip_hash技术能够将某个ip 的请求定向到同一台后端web机器中,在这个ip 下的客户端和某个后端 web机器就能建立起稳固的session.
(2)p_hash机制能够让某一客户机在相当长的一段时间内只访问固定的后端的某台真实的web服务器,会话就会得以保持,在网站页面进行login的时候就不会在后面的web服务器之间跳来跳去了,也不会出现登录一次的网站又提醒重新登录的情况.

缺点:
(1)nginx不是最前端的服务器
ip_hash要求nginx一定是最前端的服务器,否则nginx得不到正确ip, 就不能根据ip作hash.
如: 使用的是squid(代理服务器)为最前端.那么nginx取ip时只能得到squid的服务器ip地址,用这个地址来作分流肯定是错乱的
(2)nginx的后端还有其它负载均衡
假如nginx后端还有其它负载均衡,将请求又通过另外的方式分流了,那么某个客户端的请求肯定不能定位到同一台session应用服务器上,这么算起来,nginx后端只能直接指向应用服务器,或者再搭一人squid,然后指向应用服务器. 最好 的办法是用location作一次分流,将需要session的部分请求通过ip_hash分流,剩下的走其它后端去.

需要注意的是, 如果在集群中的某台服务器出现故障,我们想要从nginx的集群配置中移除掉,我们不可以直接的将那一行删掉,比如server 192.168.121.167:8080 ;删掉,如果直接删掉会导致nginx的hash算法重新计算,那么用户的回话或者说缓存都会失效掉,所以这里如果不用这台服务器,直接比较为down即可,也就是 server 192.168.121.167:8080 down;这么做就可以了。

针对宕机这种情况,我们可以使用一致性hash算法。
这样的hash算法在某台服务器发生故障的情况下可以保障大部分的用户体验不出现问题,之前的ip_hash是因为少了节点,note_count数量减少所以导致每次请求都需要重新计算分配到哪个节点,但是一致性hash算法不会,它仅会影响到少部分靠近更新节点的位置,比如节点3由于故障移除掉了,那么它上游的两个用户请求会到节点4,而其他的用户都不会改变

hash $request_uri

hash $request_uri介绍

hash request_uri是针对客户端访问的uri来做的绑定。客户端访问同一个uri的时候,会被分配到同一个服务器上去。这样提高了缓存的命中率。并且这个request_uri就是完整url中刨去最前面host剩下的部分,比如http://www.baidu.com/pan/beta/test1?fid=3这个url,去掉www.baidu.com剩下的就是了,日志里会看到打印出来的request_uri其实是/pan/beta/test1?fid=3。如果只访问www.baidu.com,$request_uri里也会有个/的。

都是通过hash算法来实现的,基本实现都是一样的,每个uri进行hash计算得到一个数值,这个数值除以整个节点数量取余数。(取模算法)
如果一个节点挂了,那么整个全局都会乱掉。因为整个的节点数变了,因为除数变了。

hash $request_uri配置
upstream httpds {hash $request_uri;server 192.168.44.102 ;server 192.168.44.103 ;
}
server {listen       80;server_name  localhost;location / {proxy_pass http://httpds;# root   html;}location ~*/(css|img|js) {root   /usr/local/nginx/html;}
hash $request_uri使用场景

适用于后端服务器为缓存服务器时比较有效。
(1)在不支持cookie的情况下
(2)资源不平均分区

使用sticky模块

sticky介绍

Sticky基于cookie的一种nginx的负载均衡解决方案,通过分发和识别cookie,来使同一个客户端的请求落在同一台服务器上,默认标识名为route
1.客户端首次发起访问请求,nginx接收后,发现请求头没有cookie,则以轮询方式将请求分发给后端服务器。
2.后端服务器处理完请求,将响应数据返回给nginx。
3.此时nginx生成带route的cookie,返回给客户端。route的值与后端服务器对应,可能是明文,也可能是md5、sha1等Hash值
4.客户端接收请求,并保存带route的cookie。
5.当客户端下一次发送请求时,会带上route,nginx根据接收到的cookie中的route值,转发给对应的后端服务器。

sticky配置
upstream {sticky;server 127.0.0.1:9000;server 127.0.0.1:9001;server 127.0.0.1:9002;
}
注意项

总之需要注意:Sticky基于cookie的一种nginx的负载均衡解决方案
1.同一客户端的请求,有可能落在不同的后端服务器上
如果客户端启动时同时发起多个请求。由于这些请求都没带cookie,所以服务器会随机选择后端服务器,返回不同的cookie。当这些请求中的最后一个请求返回时,客户端的cookie才会稳定下来,值以最后返回的cookie为准。
2.cookie不一定生效
由于cookie最初由服务器端下发,如果客户端禁用cookie,则cookie不会生效。
3.客户端可能不带cookie
Android客户端发送请求时,一般不会带上所有的cookie,需要明确指定哪些cookie会带上。如果希望用sticky做负载均衡,请对Android开发说加上cookie。
4.cookie名称不要和业务使用的cookie重名。Sticky默认的cookie名称是route,可以改成任何值。
5.客户端发的第一个请求是不带cookie的。服务器下发的cookie,在客户端下一次请求时才能生效。

6.Nginx sticky模块不能与ip_hash同时使用

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,
分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:服务器课程

nginx扩容(重点集群化处理)相关推荐

  1. etcd mysql集群_Etcd单节点扩容为三节点集群

    Etcd单节点扩容为三节点集群 参考文档 http://www.cnblogs.com/breg/p/5728237.html 开始环境是单节点,存储数据一段时间后发现需要集群高可用环境,幸亏etcd ...

  2. 【云原生】第十篇--Docker主机集群化方案 Docker Swarm

    Docker主机集群化方案 Docker Swarm 一.docker swarm介绍 二.docker swarm概念与架构 2.1 架构 2.2 概念 三.docker swarm集群部署 3.1 ...

  3. docker.10-Docker主机集群化方案 Docker Swarm

    Docker主机集群化方案 Docker Swarm 一.docker swarm介绍 Docker Swarm是Docker官方提供的一款集群管理工具,其主要作用是把若干台Docker主机抽象为一个 ...

  4. 【nginx 扩容及常用模块扩展】

    Nginx高级 第一部分:扩容 通过扩容提升整体吞吐量 1.单机垂直扩容:硬件资源增加 云服务资源增加 整机:IBM.浪潮.DELL.HP等 CPU/主板:更新到主流 网卡:10G/40G网卡 磁盘: ...

  5. Rancher集群化docker管理平台部署、特性及破坏性测试。

    http://8941355.blog.51cto.com/8931355/1712683 rancher是一个docker集群化管理平台,相对于mesos和k8s架构,rancher的部署管理非常简 ...

  6. .netcore 如何获取系统中所有session_集群化部署,Spring Security 要如何处理 session 共享?

    前面和大家聊了 Spring Security 如何像 QQ 一样,自动踢掉已登录用户(Spring Boot + Vue 前后端分离项目,如何踢掉已登录用户?),但是前面我们是基于单体应用的,如果我 ...

  7. keycloak集群化的思考

    文章目录 简介 keycloak中的集群 load balancing负载均衡 暴露客户端IP地址 sticky sessions 和 非sticky sessions shared database ...

  8. Windows7 + Nginx + Memcached + Tomcat 集群 session 共享

    一,环境说明 操作系统是Windows7家庭版(有点不专业哦,呵呵!),JDK是1.6的版本, Tomcat是apache-tomcat-6.0.35-windows-x86,下载链接:http:// ...

  9. 架构系列二:使用Nginx+tomcat实现集群部署

    架构系列二:使用Nginx+tomcat实现集群部署 一.环境介绍  VM1:Ubuntu-S100 IP:192.168.130.128 部署Tomcat应用及Nginx  VM2:Ubuntu-S ...

最新文章

  1. Android:ViewPager为页卡内视图组件添加事件
  2. LDD3源码分析之ioctl操作 .
  3. vue踩坑- 报错npm ERR! cb() never called!
  4. Winform中实现设置ZedGraph的GraphPane的大小匹配ZedGraphControl
  5. Kaggle知识点:对比学习基础
  6. js如何实现扫描身份证识别_如何识别身份证上信息?快速录入看这招
  7. 修改属性页CPropertyPage标题
  8. php怎么传json数据_php和js如何通过json互相传递数据相关问题探讨
  9. excel 图片转url_最全总结 | 聊聊 Python 办公自动化之 Excel(下)
  10. java 的类和接口的变量调用
  11. [MongoDB]安装MongoDB遇到问题
  12. js弹出对话框(半透明背景,兼容各浏览器)
  13. Bootstrap入门学习(三)——简单项目
  14. SQL不同服务器数据库之间的数据操作整理(完整版)
  15. Opencv环境配置
  16. java蓝牙开发_Android蓝牙开发全面总结
  17. snap7 python连接_python snap7 windows-找不到snap7库
  18. java gbk转机内码_GBK/GB2312编码问题分析以及java获取汉字国标码
  19. 得力计算机1526弹音乐,得力1526计算器乐谱 | 手游网游页游攻略大全
  20. c语言 组合问题,排列组合问题 C语言

热门文章

  1. qt实现锁屏功能,即点击锁屏按钮后再点击界面则无效
  2. linux6.3 插u盘,[转载]使用CentOS 6.3制作linux U盘启动盘
  3. 【整理】【精华】【实用】常用代码片段
  4. 「计算机科学速成课」笔记
  5. 微信小程序——操作数组
  6. 2021CTF工业信息安全技能大赛-PLC故障分析
  7. EXCEL VBA字符串替换
  8. Web网站克隆侦察工具HTTrack
  9. 透明代理/正向代理/反向代理
  10. dell服务器安装操作系统时提示找不到光驱怎么办?