管理员
论坛积分
分
威望 点
贡献值 个
金币 枚
|
情景 由于公司内网有多台服务器的http服务要映射到公司外网静态IP,如果用路由的端口映射来做,就只能一台内网服务器的80端口映射到外网80端口,其他服务器的80端口只能映射到外网的非80端口。非80端口的映射在访问的时候要域名加上端口,比较麻烦。并且公司入口路由最多只能做20个端口映射。肯定以后不够用。 然后k兄就提议可以在内网搭建个nginx反向代理服务器,将nginx反向代理服务器的80映射到外网IP的80,这样指向到公司外网IP的域名的HTTP请求就会发送到nginx反向代理服务器,利用nginx反向代理将不同域名的请求转发给内网不同机器的端口,就起到了“根据域名自动转发到相应服务器的特定端口”的效果,而路由器的端口映射做到的只是“根据不同端口自动转发到相应服务器的特定端口”,真是喜大普奔啊。 涉及的知识:nginx编译安装,nginx反向代理基本配置,路由端口映射知识,还有网络域名等常识。 本次实验目标是做到:在浏览器中输入xxx123.tk能访问到内网机器192.168.10.38的3000端口,输入xxx456.tk能访问到内网机器192.168.10.40的80端口。 配置步骤 服务器ubuntu 12.044 }4 |+ @$ ^. @" i9 M, j
# K/ n1 J4 d i. W
- ###更新仓库
- Z/ d; x0 i' ?% t+ X, K9 S
: _. c. B8 Q/ d D" S- apt-get update -y& v1 v: A, `/ q" T
- apt-get install wget -y0 f9 j2 ^& Y d7 d4 j$ ~( d
- #下载nginx和相关软件包
复制代码
# P5 j) X' ^, e9 g/ U m9 s7 n8 I6 ~/ [- N
pcre是为了编译rewrite模块,zlib是为了支持gzip功能。额,这里nginx版本有点旧,因为我还要做升级nginx的实验用。大家可以装新版本。
% ^2 T4 _2 B" s2 t
9 Z9 e, H$ b, G7 w+ ?- cd /usr/local/src x; ]( a/ H" p5 m
- wget <a href="ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.33.tar.gz">ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.33.tar.gz</a>
% k- `0 w9 I* h# U - wget <a href="http://zlib.net/zlib-1.2.8.tar.gz">http://zlib.net/zlib-1.2.8.tar.gz</a>. s, n, Q7 Z! p1 w
- wget <a href="http://nginx.org/download/nginx-1.4.2.tar.gz">http://nginx.org/download/nginx-1.4.2.tar.gz</a>4 ?& e- m$ p$ D" G
- tar xf pcre-8.33.tar.gz
% D4 |* O' t# q" R1 b* o/ m - tar xf zlib-1.2.8.tar.gz( A+ G9 Y9 \, N1 g1 g) h' e
- #安装编译环境& x% `% y* M! `1 m
复制代码
; N2 w5 f7 A3 L9 Z/ I; d, T% ?" ~
! B! N$ P+ e6 p apt-get install build-essential libtool -y
/ I1 M7 x" [2 U, _* b2 y9 \#创建nginx用户' r# p& q5 c- t) m# D0 V
5 I: t! q, q# |3 N
所谓的unprivileged user
1 E; t" `5 }9 D' f9 ^- ^# ]$ t/ H
- useradd -s /bin/false -r -M -d /nonexistent www: E! t. _$ h& a0 U, H
- #开始编译安装, N7 _( J( P: k5 R, c
- ' ~) j' N- z( F. d
- /configure --with-pcre=/usr/local/src/pcre-8.33 --with-zlib=/usr/local/src/zlib-1.2.8 --user=www --group=www \
0 L# O N* E' A - --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module
! O) N, B9 |" q- E/ [* ]+ f0 S9 P+ N - make
$ g. M1 v: `, D/ [ - make install
Z, M/ j9 B: i3 e( ` - #给文件夹授权
复制代码 * b! P* y- u' ~ I9 s e' m5 h
4 H7 ]0 R! t+ ?% Fchown -R www:www /usr/local/nginx
% M" A7 S" Y, h* V) ]! {#修改配置文件
5 D$ {9 j4 t. H; q9 g7 ?vim nginx.conf% ^% d3 M3 V2 b0 ?# G# o% K6 [
! S Z0 b9 Q. ?* i+ O) |0 f @
user www www;, Q1 r* [& g) E5 x+ b4 z
worker_processes 1;
7 h; |: B' h# S: k J+ qerror_log logs/error.log;
$ u- y8 E' H+ n8 Fpid logs/nginx.pid;
& U2 n* \% ?0 B$ ^6 e( ]. Jworker_rlimit_nofile 65535;
+ x8 U" B; _! s( w3 J0 {6 z0 Jevents {
0 e2 T- s# f9 ?, t use epoll;
# m. g1 w, a1 P5 T. L- j worker_connections 65535;$ X1 A% O3 B/ M# i" J( E4 I
}6 b6 F* |% V/ M' z5 L- l
http {. D5 E% M1 u7 m# a) I7 J6 a
include mime.types;
0 O4 g0 m$ m- R. C default_type application/octet-stream;
: m, e9 a* q7 \3 n# m include /usr/local/nginx/conf/reverse-proxy.conf;: Y n$ K4 t4 M" q8 I, g2 C" J3 U
sendfile on;0 i% i, _3 k# A, i8 F; V1 y
keepalive_timeout 65;$ {' p4 B7 t( ?) e4 {8 Z
gzip on;/ s, q. u9 u O
client_max_body_size 50m; #缓冲区代理缓冲用户端请求的最大字节数,可以理解为保存到本地再传给用户
$ r) p2 t# S: S, c$ x client_body_buffer_size 256k;
3 Z3 F' ?( S H4 [" j3 E client_header_timeout 3m;4 t8 S/ G, L; m8 ^
client_body_timeout 3m;
6 Q$ q, s6 ?2 k+ p send_timeout 3m; k' d1 y# v8 b
proxy_connect_timeout 300s; #nginx跟后端服务器连接超时时间(代理连接超时)
- m7 R9 O( ?% W7 \7 B4 z proxy_read_timeout 300s; #连接成功后,后端服务器响应时间(代理接收超时)
# M$ L7 H. A5 P. e# A( d+ E: V proxy_send_timeout 300s;
$ E! l2 ?0 \% t* {: z3 ^9 J9 ~ q" {- U proxy_buffer_size 64k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小- t6 T0 Q7 y! V" y5 Q R: ~" ~
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
" L& q5 ]+ [) x3 S8 C* \ proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)/ n# b6 ^( G+ p* y. B
proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传递请求,而不缓冲到磁盘
: _8 C! W4 ^) Z$ p5 n+ B8 `% U5 b4 | proxy_ignore_client_abort on; #不允许代理端主动关闭连接
% [+ l9 E. t7 ]! Q1 y8 h server {8 @% z; u# U7 _- W. |, H; U
listen 80;
6 Z0 [( v9 e9 ^5 N! K& g0 f server_name localhost;& `$ g) Y% e# X4 O2 W+ p
location / {
; T9 J0 _" V% E: D( E) J root html;! K% ^8 r) V: e$ q: X& S
index index.html index.htm;/ W- x8 v9 N' ^' S! v
}
, Z& Q+ w! A: K* l9 I3 X$ L; r error_page 500 502 503 504 /50x.html;
6 K5 r7 c* ~% X+ M% a6 ? location = /50x.html {- k0 g, E' h8 H" v& f
root html;
4 K: p8 C6 i. p) Z: F }
9 m1 S! n% N8 v4 a; T6 x }
/ F# ^$ ~' X/ h/ a+ W: x}% h5 ?9 t, j, W+ V
4 c* c& e, f, l$ F编辑反向代理服务器配置文件:5 ]! @' ?4 s2 S! S/ M4 P% B
. Y- `. ~) ^* f
vim /usr/local/nginx/conf/reverse-proxy.conf
; p+ x7 O9 U* z% F1 @! U; g. d5 ]) F9 Q5 b# x
server( h1 u2 _$ h2 i9 N1 k
{
! o7 B+ |+ [* A; a. C listen 80;5 T# ^; N# d0 K' R8 W
server_name xxx123.tk;
* J2 t# F5 y1 o$ O7 Q- y location / {7 t( ~. H6 \/ @: u U; g
proxy_redirect off;$ p4 h5 Z' a9 c
proxy_set_header Host $host;
/ e- F1 ?. |: W6 | proxy_set_header X-Real-IP $remote_addr;" V( q. c( d9 @; ?" K$ T( e
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;$ _& F- U* U4 V! |
proxy_pass http://192.168.10.38:3000;
8 h7 c5 m! n) C4 v6 B4 V# Q }" y& O: Z* ?# L; O0 b% S% M! x A# k
access_log logs/xxx123.tk_access.log;
( W$ Y" X9 Y$ |& W# e}
+ e, Z+ _: b) j2 ? + z! D: ]6 K+ X; t+ [% \8 I
server2 A: `/ A3 o) C6 P' p* { z0 e
{
- C0 x. v5 Z) ?4 z7 S4 j listen 80;' b5 |& k5 o5 M5 z3 r \1 a
server_name xxx456.tk;
( z. z, M: n3 q& }! N2 G1 S& _ location / {
0 r O/ ~ Z1 P8 f; x: p( _ proxy_redirect off;* c- P) E& _2 Y4 L0 X( @
proxy_set_header Host $host;# n, `$ f- a5 N& R+ }
proxy_set_header X-Real-IP $remote_addr;
3 `( O. y/ j0 Q0 B# Y3 @2 l proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;2 K2 s* ^9 a* a$ ^* T3 y
proxy_pass http://192.168.10.40:80;
" ?) z* Y7 s6 A4 f: Y' n }8 g8 } C" N2 Q% e1 l1 Q
access_log logs/xxx456.tk_access.log;) Y2 b+ W& C& i; s" ^2 |
}
$ s6 t1 t+ }9 e( Q: c6 J+ J9 h0 u' M9 m1 Z
然后重新加载nginx配置文件,使之修改生效,再把xxx123.tk域名指向公司静态IP,这样就成功的做到了在浏览器中输入xxx123.tk的时候访问的内网服务器192.168.10.38的3000端口,输入xxx456.tk访问192.168.10.40的80端口的作用。 如果想对后端机器做负载均衡,像下面这配置就可以把对nagios.xxx123.tk的请求分发给内网的131和132这两台机器做负载均衡了。1 @3 v! f7 J; D7 n8 t0 j
: l/ G" N/ I. g/ @' wupstream monitor_server {
1 l$ c/ f" s( u* U server 192.168.0.131:80;- p$ p6 H, @4 }6 Q8 T
server 192.168.0.132:80;6 D& W M. `. {& K8 p
}
: z! n) s# W0 v6 e( I
C0 S: A! Y( s8 r4 P! Cserver6 Q4 N* ], [3 i$ P
{
8 R; O1 v/ C+ [ listen 80;1 t- @$ b" j6 g5 l2 F, S
server_name nagios.xxx123.tk;
J% ]5 j- _1 \# x location / {, }7 Y9 e- S+ F$ Z7 G& C
proxy_redirect off;
! e. D4 H+ `3 ]' ~ proxy_set_header Host $host;3 G8 [0 S) Q- W& @$ N
proxy_set_header X-Real-IP $remote_addr;
# p- Y+ G! y8 t" W proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 5 F, g' V) @/ J, V
proxy_pass http://monitor_server;
3 H+ K4 @' v1 X( i }2 \4 ?6 b9 [2 O$ Y
access_log logs/nagios.xxx123.tk_access.log;- h3 j+ z _/ }: p
}. \& ]( T: F( v8 B
! ]4 V1 ^; w( }' q7 P$ l) |额,关于负载均衡和缓存就不多说了,这里只是要起到一个简单的“域名转发”功能。 另外,由于http请求最后都是由反向代理服务器传递给后段的机器,所以后端的机器原来的访问日志记录的访问IP都是反向代理服务器的IP。 要想能记录真实IP,需要修改后端机器的日志格式,这里假设后端也是一台nginx: 在后端配置文件里面加入这一段即可:2 _$ x w* [- o; S
' z# z3 H* z+ M5 c( ?log_format access '$HTTP_X_REAL_IP - $remote_user [$time_local] "$request" '
8 k* I( l6 e1 u$ D ]) ['$status $body_bytes_sent "$http_referer" '
" p* a; s2 v& m( d1 m'"$http_user_agent" $HTTP_X_Forwarded_For';4 E, J. f/ Z+ q ^
7 X) \3 \3 s' H3 R1 q+ a- b5 Baccess_log logs/access.log access;
1 k! [( e! b+ M0 L, o# W: F, w
: E! w f8 o- C [再看看原来日志的格式长什么样: ~8 `5 X. d( ?
3 Z6 l% k5 J. U. L1
( H) u( d( c/ n4 Y5 g1 W2' \4 u) O# D4 D4 ~5 M
3. t" x+ g9 ?0 m
4
. g1 m5 O0 g, V M! {, r5 V5) r/ R3 y( ^% U1 l G- {/ e
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '! ]4 ^2 }) V" l- i
# '$status $body_bytes_sent "$http_referer" '* I, v; y3 P$ A
# '"$http_user_agent" "$http_x_forwarded_for"';2 M# f4 }# G+ i9 K
6 `' Z, O) V5 V$ L; |- z7 v#access_log logs/access.log main;
$ [9 ]$ u- m' D9 @% H- ?看出区别了吧 遇到的问题 之前没配置下面这段,访问时候偶尔会出现504 gateway timeout,由于偶尔出现,所以不太好排查5 M" f3 E& c5 f3 ?# b8 }
1 C1 s4 C8 V _$ S! i- f1+ ?) H5 Y# ~0 A# u1 X
2: y& T; B" l" d
3$ A3 t! {2 Z, [2 C- F8 B3 j
4, e g! k3 ^# O" t. F
5% B( } G4 q i
64 d+ J4 S6 ] S) v
79 m4 w8 h7 k3 w8 C5 E
8. S6 o% Z$ \! |. n$ P% X1 r
proxy_connect_timeout 300s;4 @' i* a+ [, }- ]5 j- @, ~! T( q
proxy_read_timeout 300s;: U1 M. t3 J6 O& I; x. v7 O3 Y' c
proxy_send_timeout 300s;
+ C2 \* s+ n" W' h' Oproxy_buffer_size 64k;2 e1 {+ ^5 E E6 N2 b, C V+ u6 y2 R
proxy_buffers 4 32k;
) C& A4 I" N3 J: b) {7 U6 }# |. x, Bproxy_busy_buffers_size 64k;3 f/ L+ }7 b4 F, G5 G& W- L5 o
proxy_temp_file_write_size 64k;3 F. @. R! G' V6 M$ \: I* m% U
proxy_ignore_client_abort on;% C( o6 |8 [! u* K( H" d( O( `0 z
报错日志:
5 _2 S, g" L) {5 ~* E7 M& Y- O J9 ?( A' c q& H
...upstream timed out (110: Connection timed out) while reading response header from upstream, client: ...(后面的省略) 从日志看来是连接超时了,网上一通乱查之后估计可能是后端服务器响应超时了,本着大胆假设,小心求证的原则,既然假设了错误原因就要做实验重现错误:那就调整代理超时参数,反过来把代理超时阀值设小(比如1ms)看会不会次次出现504。后来发现把proxy_read_timeout 这个参数设置成1ms的时候,每次访问都出现504。于是把这个参数调大,加入上面那段配置,解决问题了。
; g* ^6 \5 E2 g2 u8 r* m \/ g( @5 d. A. D& r8 t5 `1 P! h: I- M$ s
PS:关于域名转发
& E6 D* n- h. ], r# p& ], x! Y K3 Y
所谓域名URL转发,是通过服务器的特殊设置,将访问您当前域名的用户引导到您指定的另一个网络地址。 地址转向(也可称“URL转发”)即将一个域名指向到另外一个已存在的站点,英文称为“ URL FORWARDING ”。域名指向可能这个站点原有的域名或网址是比较复杂难记的。 已经注册成功的域名,若初设或取消 URL 转发设置,一般均在 24-48 小时之内生效。对于原有已经设置成功的 URL 转发域名,如果修改 URL 转发的目标地址,则只需 1-2 个小时即可生效。 不隐藏路径 URL 转发:例如: http://b.com/ 指向 http://a.com/xxx/ (任意目录);当在浏览器地址栏中敲入 http://b.com/ 后回车, IE 浏览器的地址栏里显示的地址会由原来您敲入的 http://b.com/ 自动变为显示真正的目标地址 http://a.com/xxx/ ; 隐藏路径的 URL 转发:例如:先同上, IE 浏览器的地址栏里显示的地址保持不变,仍是 http://b.com/ ,但实际访问到的是 http://a.com/xxx/ 的内容。0 ^, U5 ?4 G- W- [
|
|