|
Nginx的负载均衡是基于反向代理实现的,因此,本文先讨论什么是反向代理,再在这个的基础上讨论负载均衡以及负载均衡时应该注意哪些策略。 反向代理:如下图所示, 3 M' {: O8 [# x9 g# S
↓-----Nginx将结果返回给浏览器---丨 对Tomcat来说,只知道服务对象是Nginx服务器 浏览器 -发起对该域的访问请求-> Nginx --------------Nginx将请求来转发给Tomcat服务器----> Tomcat... 丨-对Tomcat来说,只对nginx负责,将结果返回给Nginx服务器---↑ * P/ B. k+ A4 P5 Y7 S8 E+ R
从图中,我们可以知道,对于浏览器来说,他会发一个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的这么一个过程便称为反向代理。
/ |! t* Z& ?4 `% L" f) T* k" b9 Q" J; M+ R Z2 k# R0 u
那么,Nginx服务器是如何实现这一步的呢,事实上也很简单,只需要在location中做一下简单的配置即可,命令大概如下图所示:(配置完命令记得reload重新加载才能生效)
* ?$ H8 e8 y" j% G' r* t- o! h. o+ Z/ @1 \
) v4 h: x2 L; a2 x# t. c
- worker_processes 1;: M2 i0 _; e& }
- events{
复制代码 . J! A% i" j+ {3 n2 q2 I7 p6 O
% w* n" [+ Z) o6 }/ e$ F/ e7 y
重点在于location处,这样的配置代表的是,所有来自浏览器的请求,在Nginx收到之后,都会代理到http://192.168.1.62:8080所在的地方
9 d" l3 B c9 L. f0 P
( W2 e3 I9 }: K4 }& {& f1 O比如,我浏览器上发起http://192.168.1.61/a/index.html;Nginx收到之后,将会发出http:// 192.168.1.62:8080/a/index.html这么一个请求到所连接的服务器上,如上图的Tomcat。
- ]" V; R) z; c o. H* E7 F6 f0 @1 O! V
/ c' d9 G8 }% o. o7 t) q& Y
接下来我们做这样一个假设,假如后端连接着几台。几十台服务器呢,这个时候Nginx也是做同样的代理吗,答案是肯定的。图示如下:那么,在这么多台服务器上,Nginx的转发又是基于怎样的策略呢?这个时候就涉及在负载均衡了,说白了就是,应该怎样的分发,才能做到资源的最大限度的利用?/ I: m% ]# |0 M! k2 e
/ N( S h. T! g, R) s u" m, M; } r& D5 n/ E: l- I+ a: Y
. H/ E" O" T; d# P" L3 b( h
4 B& E" [& F# O负载均衡策略( 我们这里假设三台服务器的IP地址分别为 http:// 192.168.1.62:8080 http:// 192.168.1.63:8080 http:// 192.168.1.64:8080 ) 1. 平均轮询配置如下图: - f* x2 I* }1 h* O
6 l$ ] Y4 C/ b$ a
5 [, H8 m# a) f; g; a这里我们把后台所有的服务器放入upstream中,并在代理中进行引用。
- e2 j2 J7 U s3 E 2. 加权轮询,使用weight参数设置,配置如下% F; N! B" e' x& ^
9 @: W4 m/ T0 @' u% V% h4 P9 t
3. ip_hash策略
+ S' L* u: p- }0 O% V2 X(根据用户的IP地址进行hash运算,只要是同个用户发的请求,就会被永远地转发在某台服务器上,比如张三发的请求第一次时是由Tomcat1返回的,李四的是有Tomcat2返回的,那么,以后张三的所有请求,都有由Tomcat1返回,这就是ip_hash策略),配置如下:9 {/ c0 N5 }/ H7 g1 H& h# n
其他地方保持不变,在upstreaem中如下设置:
7 S% q3 |4 k7 L
3 U2 S( e9 i; Y6 d! l$ _$ r# t$ l
5 e# i/ k$ I4 m M j
; X Q- ?, J F5 P4. fair策略/ g+ d$ m6 }0 w# j* Y' }
(动态weight策略,我们的加权轮询是显式指定weight的,而fair策略是根据服务器的响应能力进行动态指定的,而意义上讲,我觉得是更为智能化的解决方法,不过这里要记住一点,fair策略是一个第三方策略)" D+ a3 T) z, ~4 Y
5. url_hash策略/ O y8 V& t- c8 Z
2 \$ u: a, F) B6 W- a, F" M(类似于ip,只不过绑定的值是url,这个也是第三方策略)' h4 l( G3 U1 S Q+ u5 s
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重新编译源文件即可, ], T6 r: {6 K- P6 t' R" n; D
% ]5 N4 ~" u0 G4 i
" h& [7 v" ~' u1 ~
' }9 k* L# J e1 t$ U5 Zurl_hash策略的用处?9 [6 f1 U7 a/ r" I# U* L
" u/ T" t2 y" a- p I' gurl_hash策略比较适合于大型电子商务网站,对于不同的商品便是不同的url,我们可以据此进行负载均衡。0 g8 {. ? B7 S$ h# R$ U0 d
* x5 M2 \) E4 J% I' n h3 E, D$ S! i原理就是不同的商品形成不同的静态页面,然后服务器根据不同商品的火爆程度,按照命中率高的放在缓存里,加快访问速度,也就是说实现了一个基于缓存的服务器,相当于把有限的缓存最优化起来;
; X3 e# P' z0 A# V/ b4 v
. m K2 {7 C+ l% ~+ }; {6 {) |3 N' }) o6 S" ?
" R6 u( P, s; D1 V2 f
其他的配置. A0 x' R4 p; P1 B
备份与停机状态:
9 _4 k/ ~: d% }7 o# a$ p; `( Lserver 192.168.1.64 backup;//备份,不参与转发,只有当所有服务器都挂掉时才参与转发;
# o% o% f8 k: @1 ~' Z, q+ C" M L* E8 E+ w; U& O
server 192.168.1.65 down;//临时停机维护,不参与任何转发,是关闭状态,
% a W0 I9 m+ p# c8 a8 G8 \0 F# s Y$ R! g, n2 A
down存在的意义在于,有时我们需要对服务器做临时停机更新维护,假如我们直接关闭服务器的话,那么对于Nginx来说,他还是会把请求发到该服务器上的,因为他并不知道服务器已关,而设置down后,Nginx则不会再发到该服务器上了,避免造成无用的请求浪费。
4 _4 a( e* Y2 G) \. F: R
" [, p% q6 L2 d2 h; F$ [3 {2 f4 T
' k* G, x" ?+ }1 S7 }) l7 |# s9 g! M8 T, o9 @ w
max_fails: 达到指定次数后认为服务器挂掉
: R0 i, x w# v# o! T: ~. T! F! G4 a6 }+ D; f
fail_timeout:挂掉多久后再次测试是否已经挂掉0 t+ e- g/ E8 E9 C' H5 B
0 n+ d1 I; q& Z b0 X) I M) L
配置命令
) A- c" ~- x3 {6 G3 o, U5 _- r# D6 }( y5 g8 Y8 G* r+ ], c
server 192.168.1.66 max_fails=2 fail_timeout=60s;
5 M* m' l1 b% W8 @1 H) H- a/ ~# |7 j( }' q' L4 [0 k
后记( ^( R8 s6 l' v
我们知道,服务器是会存储用户的session的,那么,如果按照上文所说的,比如fair策略,每次Nginx会根据后端服务器群的能力把请求分发出去,那假如第一次时分在了A,那么我把数据存储到了A服务器上,第二次时,刚好被分配到了B服务器上,那么问题来了,我的session不就不见了?(这就是我们在访问部分网站时有时我们的登录状态会不见)当然了,你可能 会说,ip_hash策略不就可以避免这一点吗?没错,这确实是一个解决方法,那除了ip_hash呢?其他策略下又当如何呢?下篇博客将会讲到负载均衡下如何对session进行处理。9 }; x9 u5 s. s+ f) z
" `8 j- x( z8 O4 @/ \( m3 U( y
3 C* w l7 Y6 Z, c5 x; Q* x* N1 C" Q( b5 e# V7 P
- r1 ]- O$ W* C" D4 o& L
- K' p' r; o9 @! e5 p# k |