|
Nginx的负载均衡是基于反向代理实现的,因此,本文先讨论什么是反向代理,再在这个的基础上讨论负载均衡以及负载均衡时应该注意哪些策略。 反向代理:如下图所示, - @+ ~- j& O3 q$ u" C
↓-----Nginx将结果返回给浏览器---丨 对Tomcat来说,只知道服务对象是Nginx服务器 浏览器 -发起对该域的访问请求-> Nginx --------------Nginx将请求来转发给Tomcat服务器----> Tomcat... 丨-对Tomcat来说,只对nginx负责,将结果返回给Nginx服务器---↑
& d( M* } u5 b/ T) N从图中,我们可以知道,对于浏览器来说,他会发一个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的这么一个过程便称为反向代理。& |: C/ @ q+ Z. X$ ?8 F) i2 N" u
3 x0 D9 b/ e0 ]) s5 j
那么,Nginx服务器是如何实现这一步的呢,事实上也很简单,只需要在location中做一下简单的配置即可,命令大概如下图所示:(配置完命令记得reload重新加载才能生效)" Q9 \6 x: S6 F ?% N
, d. F5 |) D9 Q& D1 F' ~. v
' E: @( R5 \# `. t4 P5 m# E* F5 f- worker_processes 1;$ n( Q( l* L+ f: i: N$ ^1 x) F
- events{
复制代码 . n/ `$ ` O! ?
/ P. ~, ^+ S. X& _重点在于location处,这样的配置代表的是,所有来自浏览器的请求,在Nginx收到之后,都会代理到http://192.168.1.62:8080所在的地方( j0 |* i7 u: j5 W6 Y. I
) B: t! O1 Y$ B6 T' R! J$ ]比如,我浏览器上发起http://192.168.1.61/a/index.html;Nginx收到之后,将会发出http:// 192.168.1.62:8080/a/index.html这么一个请求到所连接的服务器上,如上图的Tomcat。
% S$ k0 |* O a6 m9 d+ I0 ]2 o
, @) m' \& |- q4 a接下来我们做这样一个假设,假如后端连接着几台。几十台服务器呢,这个时候Nginx也是做同样的代理吗,答案是肯定的。图示如下:那么,在这么多台服务器上,Nginx的转发又是基于怎样的策略呢?这个时候就涉及在负载均衡了,说白了就是,应该怎样的分发,才能做到资源的最大限度的利用?7 ^' Y q$ u1 r8 z
( q/ {$ X- V- ~% |/ v |+ A
0 h, o: P0 A0 R: i
/ F& ?0 u% H g( ]: }5 m
# I- X: t8 ^+ |) Z: i& c负载均衡策略( 我们这里假设三台服务器的IP地址分别为 http:// 192.168.1.62:8080 http:// 192.168.1.63:8080 http:// 192.168.1.64:8080 ) 1. 平均轮询配置如下图:
) z4 ^5 i/ u" t" ?( E9 w
1 q% w/ r! \% ]3 q+ {; v
' W' Q1 {9 ^: w
这里我们把后台所有的服务器放入upstream中,并在代理中进行引用。
# ]; ~% j. I# I8 d 2. 加权轮询,使用weight参数设置,配置如下
( s6 `; E8 I0 E1 a3 z7 j
4 U; t7 o+ `7 I2 N( D$ h! a; b3. ip_hash策略0 v3 ~; @9 J2 N: `5 g
(根据用户的IP地址进行hash运算,只要是同个用户发的请求,就会被永远地转发在某台服务器上,比如张三发的请求第一次时是由Tomcat1返回的,李四的是有Tomcat2返回的,那么,以后张三的所有请求,都有由Tomcat1返回,这就是ip_hash策略),配置如下:
/ ]; {: P. z+ P0 T/ y- | 其他地方保持不变,在upstreaem中如下设置:
% T" Q8 C1 P5 z4 m" T9 t' o& ^, @# e. q
- u5 Y* z1 |7 `+ K
! M% L; R0 I; u ~
6 U( r {) F1 w+ O1 Q8 H" ^* z/ l4. fair策略
* @ s: G' L, t# g(动态weight策略,我们的加权轮询是显式指定weight的,而fair策略是根据服务器的响应能力进行动态指定的,而意义上讲,我觉得是更为智能化的解决方法,不过这里要记住一点,fair策略是一个第三方策略)3 L! w9 Q C/ Z6 c( \( o# t) ?
5. url_hash策略
v) ?. e0 Z4 t" q/ L, B5 J; f& J. o' j, i* p
(类似于ip,只不过绑定的值是url,这个也是第三方策略)
- ~$ u+ p. r# ?, J9 Pfair策略与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重新编译源文件即可" G, S Y: ?3 _, [% X' r
% u! B2 @" ~, l6 g
5 p- _, d/ D) o. X: o* O& h/ B* w! u) V
url_hash策略的用处?; x* F7 d l. E; L% J k+ g
3 F" q1 h/ M! Y2 J
url_hash策略比较适合于大型电子商务网站,对于不同的商品便是不同的url,我们可以据此进行负载均衡。
! c( f* L* ~2 V, g; h7 J1 j8 i8 F& ?- W( @& q
原理就是不同的商品形成不同的静态页面,然后服务器根据不同商品的火爆程度,按照命中率高的放在缓存里,加快访问速度,也就是说实现了一个基于缓存的服务器,相当于把有限的缓存最优化起来;
2 x* N6 {* ~9 w( I b" l/ {& t( W, B
8 g5 y8 O0 S5 f) Q6 x
5 Y- U, T/ P6 i7 P6 d
t4 v& M( h$ r4 `8 v' x其他的配置
' G( G) J: ?! A4 a# {4 @备份与停机状态:5 e5 L$ G2 t7 n2 M; c1 N
server 192.168.1.64 backup;//备份,不参与转发,只有当所有服务器都挂掉时才参与转发;
: Q/ p* k1 b3 C# y5 A# t+ R: k. z0 G
: F) B# A7 H6 Z1 gserver 192.168.1.65 down;//临时停机维护,不参与任何转发,是关闭状态,9 }! S* T ~; b
3 _* Z3 T/ S1 w1 Z
down存在的意义在于,有时我们需要对服务器做临时停机更新维护,假如我们直接关闭服务器的话,那么对于Nginx来说,他还是会把请求发到该服务器上的,因为他并不知道服务器已关,而设置down后,Nginx则不会再发到该服务器上了,避免造成无用的请求浪费。
. l o, X/ c2 S4 A" `
: _* b3 @* ^# d7 \5 P
, n9 n/ N2 ?4 o& q/ r; g6 `# V8 j: M/ _, ^( \' G
max_fails: 达到指定次数后认为服务器挂掉
* P. g6 Q9 \9 a3 U' G8 H7 V5 s2 K' N9 N L
fail_timeout:挂掉多久后再次测试是否已经挂掉6 Q, v" r, k$ ~* [4 H# ^
! J4 T9 N& t! }& S9 y5 E' Q. P8 ?$ `配置命令
, S/ @1 N) h3 S$ Z7 j6 g% j* b& @$ N* T/ F: D6 r3 J
server 192.168.1.66 max_fails=2 fail_timeout=60s;
: e, r$ @/ x4 B' E
- z$ {# N" a6 A0 u) U7 g$ c 后记) T7 G# K0 I+ U9 `- M$ b
我们知道,服务器是会存储用户的session的,那么,如果按照上文所说的,比如fair策略,每次Nginx会根据后端服务器群的能力把请求分发出去,那假如第一次时分在了A,那么我把数据存储到了A服务器上,第二次时,刚好被分配到了B服务器上,那么问题来了,我的session不就不见了?(这就是我们在访问部分网站时有时我们的登录状态会不见)当然了,你可能 会说,ip_hash策略不就可以避免这一点吗?没错,这确实是一个解决方法,那除了ip_hash呢?其他策略下又当如何呢?下篇博客将会讲到负载均衡下如何对session进行处理。
1 a: N' S+ q# C; `
) ^( f G" m7 ~8 w4 t# d, }; M: k9 s9 E r
2 p L4 u9 q. s$ Y
7 [' V* `' _+ M8 G' X" i- a
* `7 G1 T/ A O q. o* A+ B3 O) T
|