|
Nginx的负载均衡是基于反向代理实现的,因此,本文先讨论什么是反向代理,再在这个的基础上讨论负载均衡以及负载均衡时应该注意哪些策略。 反向代理:如下图所示, ~' Q) ~5 Y4 e. F. S. \2 \- j4 ]
↓-----Nginx将结果返回给浏览器---丨 对Tomcat来说,只知道服务对象是Nginx服务器 浏览器 -发起对该域的访问请求-> Nginx --------------Nginx将请求来转发给Tomcat服务器----> Tomcat... 丨-对Tomcat来说,只对nginx负责,将结果返回给Nginx服务器---↑ & A# g* D6 d6 `8 p. |: b8 Z
从图中,我们可以知道,对于浏览器来说,他会发一个http://www.a.com/uri请求到Nginx服务器,对于他来说,他认为数据就是从http://www.a.com/uri域中返回的,事实上,当http://www.a.com/uri到达Nginx服务器后,Nginx服务器会将其转发给http://www.b.com/uri,从http://www.b.com/uri域中取得数据并将其返回给浏览器,这个步骤浏览器是不知道的,也就是说,浏览器并不知道http://www.b.com/uri该域的存在,同理,http://www.b.com/uri所在的域(图中的Tomcat)也并不知道浏览器的存在,他也只对Nginx负责。Nginx的这么一个过程便称为反向代理。/ G* v6 t* o. B$ G, ? m3 s& E
! i/ [0 B1 D" j2 y4 |( o$ P那么,Nginx服务器是如何实现这一步的呢,事实上也很简单,只需要在location中做一下简单的配置即可,命令大概如下图所示:(配置完命令记得reload重新加载才能生效)7 g0 P9 i Y+ ~6 L
! ~0 {& M& m( g; {/ U+ c( F0 _$ M: S' \2 b, E$ |9 z/ D
- worker_processes 1;
& ^$ l6 }/ p$ H# d1 I0 V - events{
复制代码 + F5 ~1 {9 X, A. c
& R' @4 q+ s/ Q( ]
重点在于location处,这样的配置代表的是,所有来自浏览器的请求,在Nginx收到之后,都会代理到http://192.168.1.62:8080所在的地方, G) y! O: j9 s' d: J! }; u( ]
9 [3 z9 H+ e$ s
比如,我浏览器上发起http://192.168.1.61/a/index.html;Nginx收到之后,将会发出http:// 192.168.1.62:8080/a/index.html这么一个请求到所连接的服务器上,如上图的Tomcat。3 V' k' E: [% g2 O; J
) ~9 I8 F5 b: M3 l+ @3 f) X1 h
' X: x' P/ ^; s8 P7 _% A接下来我们做这样一个假设,假如后端连接着几台。几十台服务器呢,这个时候Nginx也是做同样的代理吗,答案是肯定的。图示如下:那么,在这么多台服务器上,Nginx的转发又是基于怎样的策略呢?这个时候就涉及在负载均衡了,说白了就是,应该怎样的分发,才能做到资源的最大限度的利用?
' X* n9 x) D2 M, {4 F/ R
5 }* e, N0 g- j; P; q: Z, n: I- u+ M1 Y2 d: e
; u2 e' l1 N+ m1 c+ ]! D! G
. n) E7 [+ r" I- }5 V
负载均衡策略( 我们这里假设三台服务器的IP地址分别为 http:// 192.168.1.62:8080 http:// 192.168.1.63:8080 http:// 192.168.1.64:8080 ) 1. 平均轮询配置如下图: . W" `9 p& w/ R$ ?4 y1 X
4 D6 o: G r( z- ^4 z8 \3 N- z5 A# ]5 N% v i
这里我们把后台所有的服务器放入upstream中,并在代理中进行引用。: {' T3 S4 C' k; p( h; j% W9 Z
2. 加权轮询,使用weight参数设置,配置如下
0 ?( G4 Q/ w2 x
! H0 F5 D" {3 z$ e3. ip_hash策略
0 U* m8 O' q9 ], I! ?- z/ K(根据用户的IP地址进行hash运算,只要是同个用户发的请求,就会被永远地转发在某台服务器上,比如张三发的请求第一次时是由Tomcat1返回的,李四的是有Tomcat2返回的,那么,以后张三的所有请求,都有由Tomcat1返回,这就是ip_hash策略),配置如下:& k N5 j8 }, T# n& u+ Q
其他地方保持不变,在upstreaem中如下设置:
! P4 m- j) I9 y
- T4 A c, j ~ t% U+ C' m4 |0 h3 i$ i( E- E
; Z( Z: Z4 |8 B6 Y/ S
$ Q M( P& S, d6 ^0 H4. fair策略
& I( @" |1 c" N# }, o(动态weight策略,我们的加权轮询是显式指定weight的,而fair策略是根据服务器的响应能力进行动态指定的,而意义上讲,我觉得是更为智能化的解决方法,不过这里要记住一点,fair策略是一个第三方策略)
& g6 w7 V* T, v. ?' y! g) Y5. url_hash策略9 ~/ q4 M ` M2 F
* C! @3 `* I1 q9 a9 z2 G(类似于ip,只不过绑定的值是url,这个也是第三方策略)
& V9 n* y0 v& Y/ m0 L( dfair策略与url_hash策略的配置与ip_hash策略的类似,直接把upstream tomcats 中的ip_hash替换为fair和url_hash即可,不过这里需要注意的是fair和url_hash都是第三方扩展,因此需要先安装第三方扩展模块,直接百度搜索nginx-upstream-fair-master.zip与upstream-url-hash -master.zip;解压安装使用make&&make install重新编译源文件即可
& p$ V& N( t7 X: {1 O
' ^, x7 O A/ D
5 h+ r+ l i5 U8 t* i: K* i, Q2 z+ I( U
8 r* ~4 G6 y- M" B4 M; Burl_hash策略的用处?! `$ c+ {) H! D) ~4 `4 O8 b
3 t+ y. M1 V- }
url_hash策略比较适合于大型电子商务网站,对于不同的商品便是不同的url,我们可以据此进行负载均衡。* ?1 X ]. F5 s, _* \
" a) l( Z3 z6 c原理就是不同的商品形成不同的静态页面,然后服务器根据不同商品的火爆程度,按照命中率高的放在缓存里,加快访问速度,也就是说实现了一个基于缓存的服务器,相当于把有限的缓存最优化起来;
7 o9 D0 {% ~" @( |9 l
6 a' k2 i, |* Q
" g% H* y2 A* x9 L$ R
) M5 ]* a v$ X1 v6 J其他的配置% `* [+ h) d2 C( @' d' `
备份与停机状态:3 N( q3 I6 z7 g9 A8 J" s2 S
server 192.168.1.64 backup;//备份,不参与转发,只有当所有服务器都挂掉时才参与转发;
2 m% f) S; C( r# r
( G$ ]1 I8 k7 K! Jserver 192.168.1.65 down;//临时停机维护,不参与任何转发,是关闭状态, o. D8 y" k- @
3 E) P% q2 q) m/ t& l" H4 ~( Tdown存在的意义在于,有时我们需要对服务器做临时停机更新维护,假如我们直接关闭服务器的话,那么对于Nginx来说,他还是会把请求发到该服务器上的,因为他并不知道服务器已关,而设置down后,Nginx则不会再发到该服务器上了,避免造成无用的请求浪费。* D& c; d- v3 |/ q3 M, U. G: X
6 l+ Z! ?% o2 v5 F1 h5 D- v! v d- H
: l8 |, j/ C0 C0 h
max_fails: 达到指定次数后认为服务器挂掉, `" L' k3 f' k1 G; w
$ J+ G0 J* C' d4 D S$ u
fail_timeout:挂掉多久后再次测试是否已经挂掉
. w$ Z/ F1 b) W3 {) ]5 e
5 I `' E' R; i$ B2 x8 z配置命令2 B2 z( ]5 \: ]& O) _/ A
D: R# A9 b# o5 vserver 192.168.1.66 max_fails=2 fail_timeout=60s;& Q. o0 }; E& c5 z- _
0 V6 T6 N7 G0 L 后记
$ n D' I3 l& @3 s4 i" c1 ]! o我们知道,服务器是会存储用户的session的,那么,如果按照上文所说的,比如fair策略,每次Nginx会根据后端服务器群的能力把请求分发出去,那假如第一次时分在了A,那么我把数据存储到了A服务器上,第二次时,刚好被分配到了B服务器上,那么问题来了,我的session不就不见了?(这就是我们在访问部分网站时有时我们的登录状态会不见)当然了,你可能 会说,ip_hash策略不就可以避免这一点吗?没错,这确实是一个解决方法,那除了ip_hash呢?其他策略下又当如何呢?下篇博客将会讲到负载均衡下如何对session进行处理。( W2 w$ t: D# l3 [, n
* c( {/ T4 C9 l+ I! @' q C' o! R
3 h0 T# e, E: [. e+ _4 H3 u, \
( ~+ `. C4 A8 b* j2 z/ j* N n) _5 E
- |1 {+ R9 c4 }* D- ~ |