调度算法有一些常用的设置,默认设置相等于rr
加了权重默认就等于wrr
ip_hash(在lvs的时候,有个算法叫源地址哈希,还有目标地址哈希)
最少链接相当于wlc
根据请求报文的某些首部字段来进行调度,当用户发送请求到http的头部请求报文的若干首部,可以根据首部信息来进行调度,key(就是首部字段的名称)
通常是配合后端的缓存cache服务器来实现,为了加速性能,为大量地在互联网应用中才用缓存,在nginx中,对于缓存,性能提升还是很明显的
也可以在后端的rs和nginx服务器之间添加缓存服务器,
客户端去访问1.html,nginx会对1.html做哈希运算得出哈希值来决定调度到后端哪一个varnish缓存服务器上,把后端web服务器的页面信息缓存到服务器上去,利用缓存可以大大提高访问速度,磁盘存储文件的方式是不一样的,把数据也会缓存到内存中,提升性能,
用户访问1.html始终调度到第一台缓存服务器上,2.html调度到第二台,这样命中率就很高,因为访问1.html始终会访问到1缓存服务器,因此在调度的时候,应该把对方发起请求的url来根据他来作为调度的条件判断,
(在判断时,如何去调度:varni服务器可能有权重,希望大部分的缓存是往第一台服务器上调度,有一些服务器的缓存放到第二台来实现,
1权重是1 ,2服务器权重是2,每次调度的时候有一份往1.html,有两份往2.html
实现起来很简单,就是把用户的url做哈希运算,哈希运算之后得出哈希值(用md5就是128位的二进制),然后去除以总权重1+2=3,得出结果只有三种可能性,0,1,2 0往第一台服务器,12,往第二台)
这就是简单的调度算法,根据url进行调度,根据头部的uri(头部信息来进行调度,针对请求报文的哪个字段来进行调度,url)
用它作为请求报文,只要请求报文的url固定的就固定往一台机器上调度
现在在每个主机上面多创建一些页面
在17上也创建
定义的是url调度,所以只要访问一个页面,就会往一个服务器上调度,所有人读调度到17
只要url固定,就会始终往一个机器上调度
但是这种情况有巨大问题,如果有一个varnish出现故障,算出来的总权重结果就完全不一样了,就会产生严重的问题,原来1.html是往1缓存服务器上调度的,结果因为服务器变了,下次就不往1上调度了,下次往别处调度了,而且一变化,影响所有的url调度
之前是三权重,现在加一台服务器,变成总权重是4了,受影响的就变成了所有的机器,这样就有可能所有的请求都无法命中,结果后端服务器压力暴涨,*(原来可能缓存服务器承担了百分之80的压力),
这样就缓存不起作用,叫缓存穿透,直接跳过缓存服务器,把压力放到后端服务器上去了,后端服务器瞬间压力过大,可能就崩溃了
如何解决,有更先进的算法,一致性哈希,算法非常有意思
把用户发过来的请求url也做哈希运算,得出一个值,用这个值来取余的时候使用哈希环来取余(哈希环就是一个转圈的环,上面有一些数字,最后一个数字是2的32次方-1,4个G的空间,40多亿个数字,当用户访问的时候,有可能得出的结果是其中一个,
提供缓存的服务器ip地址也在做运算,比如cache服务器的ip地址(假设192.168.30.200 200是有权重的,假设权重是2 ,我们就随机加一个数字,比如加一个x,得出一个新值
因为是2 的权重,就再加一个随机值,这样就生成了两个新的ip地址
新的ip地址用ip1和ip2来表示
这些ip地址来以后也是用哈希来运算,得出哈希值,也是给2 的32次方取余,得出一个值,也就落在哈希环上了
落在环上的3个不同位置)
圆圈是对用户请求url做的哈希运算
方框是后端缓存服务器的ip地址哈希运算
当用户访问1.html,谁来提供服务,按哈希环上的顺时针来找,谁近谁就提供服务
**但是也有缺陷,(现在只有三个地址,ip1,ip2,ip3,这个三个地址可能太偏了,也可能连着在一起,这时候带来的问题就是第一台服务器承担了大部分的缓存,后面的服务器承担的缓存很少,就叫哈希环的偏移,
要解决很简单,如果ip3是权重是1 ,就乘100,生成100个虚拟ip
ip1 权重是2 ,就*200生成200个虚拟ip,如果不够再加一个0 。就是1000,2000
2000个虚拟ip对于2的32次方取模,就相对比较均匀的放在了一个环上 了,生成了2000个虚拟的值,2000+1000=3000,3000个ip在这个环上偏移也就不会太严重 了,这就是著名的一致性哈希
**
实现起来很简单,加一个consitent
由于我们服务器少,效果上是看不出来差别,是nginx特有的算法,lvs没有
lvs只能根据目标服务器的ip地址,不识别应用层协议,顶多根据传输层的端口号IP地址,应用层的url是判断不了的
为worker进程保持长连接的数量,如果后端的服务器和nginx服务器都是短连接,意味着发送一个请求就断开,断开以后,新的用户发送链接,又会打开新的端口号,还需要经过tcp三次握手,这样就会占用大量的端口号,要断开也不是立即断开,还有timewait,tcp4次挥手,有一个timewait,断开不是马上断开
在这段时间端口是占用的
新的连接要用心的端口号,旧的链接还不释放端口号
这样如果前端服务器量太大,端口号就会被耗尽,导致链接失败,所以可以在后端启用长连接,
只要连接以后,因为长连接是不会断的,在这个里面可以不断地发请求,这个数量需要定义,最大多少连接数
nginx除了http的功能,还可以作为邮件代理,tcp的转发代理(tcp调度器),用到专门的模块叫stream,调用的是tcp,udp协议,不关心客户端引用层协议,只关心传输层协议
假设后端有两个服务器,mysql,nginx服务器想去调度不同的mysql数据库服务器,这个转发是基于tcp3306端口的,需要用到stream模块
必须放在主模块里
我们要修改也只能改主配置文件,还是在17和200上实现,把数据库装上
默认是链接不上去的,必须要创建个账号
在17上安装数据库
这样就可以远程连接这两个数据库了
起来了,但是30.7上的服务器上是没有数据库,这个服务器只负责调度
客户端链接nginx服务器,就被调度到5.1版本的数据库(就是30.200)
再链接一次就被调度到了5.5上了
把一台服务器宕机了,检查是否有健康性检查功能
天生就有健康性检查功能
下面就是源码编译了
把http服务关闭
安装开发包组
实际上别人用的选项多了去了
先创建账号,解包
允许configure
检查是否有目录
缺包
我们想修改,看到的版本
重新解压
现在修改c语言源码
大概40几行,
现在想不隐藏nginx版本,现在想暴露,就可以单独分别设置
现在改好源码之后就可以放心configure
再sbin下的主程序,正常情况应该加PATH变量
就起来了
看报文头部
想要隐藏版本
隐藏版本就是具体版本不让你看,但是给你看自己的名称