|
Nginx的负载均衡是基于反向代理实现的,因此,本文先讨论什么是反向代理,再在这个的基础上讨论负载均衡以及负载均衡时应该注意哪些策略。 反向代理:如下图所示, 6 Y7 T2 P: w2 ]+ k7 |, H: e- V
↓-----Nginx将结果返回给浏览器---丨 对Tomcat来说,只知道服务对象是Nginx服务器 浏览器 -发起对该域的访问请求-> Nginx --------------Nginx将请求来转发给Tomcat服务器----> Tomcat... 丨-对Tomcat来说,只对nginx负责,将结果返回给Nginx服务器---↑
( T" s+ M+ e. A6 D4 [! z: n' y从图中,我们可以知道,对于浏览器来说,他会发一个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的这么一个过程便称为反向代理。, {/ s S9 z* L1 ] K* N& [/ L
6 c& w! x. V6 h. B2 R& l: C+ v- a那么,Nginx服务器是如何实现这一步的呢,事实上也很简单,只需要在location中做一下简单的配置即可,命令大概如下图所示:(配置完命令记得reload重新加载才能生效)
, g" C9 I6 B& ?6 C2 o3 u1 _# q6 N8 h! ^5 ~. V% m' I
# e J4 H0 b" Q+ M8 j: r
- worker_processes 1;
0 m3 l3 w2 Y$ }) Z% u8 z - events{
复制代码 * r6 o8 C3 U& y/ P2 ^
7 K1 m3 E8 K- g: L1 K4 N, s5 b2 h
重点在于location处,这样的配置代表的是,所有来自浏览器的请求,在Nginx收到之后,都会代理到http://192.168.1.62:8080所在的地方
, H' i; Z% S4 m3 V: ?4 n
* b5 L0 Q( s/ L- Z& B9 Y% R0 [比如,我浏览器上发起http://192.168.1.61/a/index.html;Nginx收到之后,将会发出http:// 192.168.1.62:8080/a/index.html这么一个请求到所连接的服务器上,如上图的Tomcat。( i/ Q* Y6 g1 S; {, S
" L7 ]0 Y* U" f/ o7 P! C
' H2 {! m% } ^! [/ }: |接下来我们做这样一个假设,假如后端连接着几台。几十台服务器呢,这个时候Nginx也是做同样的代理吗,答案是肯定的。图示如下:那么,在这么多台服务器上,Nginx的转发又是基于怎样的策略呢?这个时候就涉及在负载均衡了,说白了就是,应该怎样的分发,才能做到资源的最大限度的利用?0 Z, T% n8 h5 H- C7 l
1 m/ A" T! ^3 p" R1 d. P9 }
9 ]; p0 D% ~. ?4 W, ~+ f9 g
6 G7 ~* f3 Y5 @: Y: E/ M: Q. Y4 S2 T1 K0 w, a: N
负载均衡策略( 我们这里假设三台服务器的IP地址分别为 http:// 192.168.1.62:8080 http:// 192.168.1.63:8080 http:// 192.168.1.64:8080 ) 1. 平均轮询配置如下图:
" c3 s) M: u4 I9 `2 `& K
~; L& E1 E$ G M8 H' U8 D* ~& g
5 y. X5 N( s `3 Z这里我们把后台所有的服务器放入upstream中,并在代理中进行引用。
! L4 i1 `) o3 J- U 2. 加权轮询,使用weight参数设置,配置如下9 {" v: [) Q; y4 N8 S/ P N
5 j9 t# a. F" m+ X v
3. ip_hash策略
, I2 c2 g: v$ u1 g' a) U(根据用户的IP地址进行hash运算,只要是同个用户发的请求,就会被永远地转发在某台服务器上,比如张三发的请求第一次时是由Tomcat1返回的,李四的是有Tomcat2返回的,那么,以后张三的所有请求,都有由Tomcat1返回,这就是ip_hash策略),配置如下:! N/ i# i4 ^* D0 l
其他地方保持不变,在upstreaem中如下设置:7 ^3 @4 }! e2 J0 O
: F4 {3 ^& \9 M H- c) _- K2 m! h/ |$ V* A+ Y4 @, A
1 H, b! {: m) ~
& }) V8 ^8 v, z N. S4. fair策略! E4 i4 z m. }2 b
(动态weight策略,我们的加权轮询是显式指定weight的,而fair策略是根据服务器的响应能力进行动态指定的,而意义上讲,我觉得是更为智能化的解决方法,不过这里要记住一点,fair策略是一个第三方策略)' e; k8 X# P: h4 F' e
5. url_hash策略9 F+ U1 v# T6 y- X
3 S. X+ i7 {0 e% d
(类似于ip,只不过绑定的值是url,这个也是第三方策略)" r& ?+ T( H5 [. P. ^5 D
fair策略与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重新编译源文件即可8 R3 Y9 n3 c/ V
) V' E( I7 x' c4 K: p1 A, M% D7 ^$ o9 o9 N4 I
f- b& L$ b) @% @ R2 nurl_hash策略的用处?
# U3 n* k! i8 E: _' D8 ?2 e
# J+ U2 x% f/ \+ |0 v7 surl_hash策略比较适合于大型电子商务网站,对于不同的商品便是不同的url,我们可以据此进行负载均衡。
/ D) r4 v" n3 E$ [+ V: L8 ^+ X; \2 T) N
原理就是不同的商品形成不同的静态页面,然后服务器根据不同商品的火爆程度,按照命中率高的放在缓存里,加快访问速度,也就是说实现了一个基于缓存的服务器,相当于把有限的缓存最优化起来;4 w7 t; z. Y( Z' D
) Q; _. G! o: i( p: c6 q' K/ U
5 s, r4 R! K( P4 P& w Z0 e. d
1 W" X e J6 k M其他的配置4 d, H3 g& P3 G- r1 s8 B" P& }
备份与停机状态:" d( v* v' f- @% O& B/ y9 [
server 192.168.1.64 backup;//备份,不参与转发,只有当所有服务器都挂掉时才参与转发;) e! ^% f( U8 G1 T5 D- e& P
4 O" U6 @; x, W1 _, p7 z+ I
server 192.168.1.65 down;//临时停机维护,不参与任何转发,是关闭状态,
9 G% g6 ~' _$ S7 n6 J! y. X; W+ b- ^$ G. o$ j
down存在的意义在于,有时我们需要对服务器做临时停机更新维护,假如我们直接关闭服务器的话,那么对于Nginx来说,他还是会把请求发到该服务器上的,因为他并不知道服务器已关,而设置down后,Nginx则不会再发到该服务器上了,避免造成无用的请求浪费。
% |: k+ \+ S4 L9 g
( ?0 ? j& A% |& w1 ?7 X% {! c' m4 \- Z3 Y' U
' Y9 f0 t. Q- z x* K
max_fails: 达到指定次数后认为服务器挂掉
& Z+ O. ~$ U8 i$ H4 S- i1 z+ Y1 D% o! _$ a, v# T, m5 o" |6 b
fail_timeout:挂掉多久后再次测试是否已经挂掉
/ K$ x) I" @& N* ^
5 r, u8 Z# q; U# i; k配置命令
9 t- i( t( u. M0 g& {+ M" T5 o0 p" R
server 192.168.1.66 max_fails=2 fail_timeout=60s;6 v* E* G( `* S1 I3 ]& H0 d; T# b5 }& Q
, ?& Y2 {5 E o3 ^
后记
1 K" T3 d8 r8 F5 v% y( L我们知道,服务器是会存储用户的session的,那么,如果按照上文所说的,比如fair策略,每次Nginx会根据后端服务器群的能力把请求分发出去,那假如第一次时分在了A,那么我把数据存储到了A服务器上,第二次时,刚好被分配到了B服务器上,那么问题来了,我的session不就不见了?(这就是我们在访问部分网站时有时我们的登录状态会不见)当然了,你可能 会说,ip_hash策略不就可以避免这一点吗?没错,这确实是一个解决方法,那除了ip_hash呢?其他策略下又当如何呢?下篇博客将会讲到负载均衡下如何对session进行处理。
2 l7 I b* ]" @( N' h& n2 N! f; G1 C5 s7 l
! D* z2 G6 y J N* g: ?6 p0 v
" N) M) i6 j* k0 x5 t
' r* p$ B7 F% n6 Z" T8 o9 [ J9 b& |
|