管理员
   
论坛积分
分
威望 点
贡献值 个
金币 枚
|
情景 由于公司内网有多台服务器的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.04( m; H3 k$ l4 G7 G, F
0 a; {/ B& U/ N3 ]- ###更新仓库8 r# @) {9 X: Z9 I) R, v/ x
+ N8 g {5 d6 L; i8 R- apt-get update -y; f" B: u# h p, l; O6 P7 x2 Q
- apt-get install wget -y) @) }/ N7 p9 C+ _* ~
- #下载nginx和相关软件包
复制代码
. h5 g C j Q9 m# t7 v* n, h2 [! [! j& k5 q
pcre是为了编译rewrite模块,zlib是为了支持gzip功能。额,这里nginx版本有点旧,因为我还要做升级nginx的实验用。大家可以装新版本。" L' t4 |4 C2 ?) I2 U9 e- u* d6 J! u6 P
. w& Q4 T2 |9 U
- cd /usr/local/src5 O- i$ h. H! T+ k/ |8 }
- 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>) c, X1 P! W" [) b2 @! o
- wget <a href="http://zlib.net/zlib-1.2.8.tar.gz">http://zlib.net/zlib-1.2.8.tar.gz</a>
, @% B5 i, Q) h3 `4 Y. B6 }/ 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>
' H2 f0 j8 B1 s* j - tar xf pcre-8.33.tar.gz
# g$ ?( }# ]7 i( T- p) s$ ] - tar xf zlib-1.2.8.tar.gz2 g$ O$ G! \4 l4 v
- #安装编译环境
0 n0 t$ Y0 C0 c
复制代码
& J) C; w! H8 e0 M % z' M: W4 b# O+ e' O
apt-get install build-essential libtool -y
/ J6 u6 B/ _: o+ [4 @8 Q0 M! [#创建nginx用户" @( t" W! f+ v* e" S
1 \& ~7 o/ g* V; W所谓的unprivileged user
6 J. d' |' f; ~ O* ?7 E) [& O f) Z- l' d* ` [
- useradd -s /bin/false -r -M -d /nonexistent www" o! i/ \' d' r9 U
- #开始编译安装
- O. ?! k7 R: ^5 S$ f7 T5 s - ! a+ n1 p! l' N+ w7 _
- /configure --with-pcre=/usr/local/src/pcre-8.33 --with-zlib=/usr/local/src/zlib-1.2.8 --user=www --group=www \
8 H6 }( M0 j2 j$ F% a - --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module
4 K1 n/ ]. k4 F" u, U- _* h: A - make
5 _; [ H7 s0 w - make install
! F7 Q5 q/ O/ l% s% f o$ V. w1 b - #给文件夹授权
复制代码
' _! w) z/ C5 W2 l/ d9 N ( F" A3 ~% @' f( \
chown -R www:www /usr/local/nginx
3 C1 D' v7 m0 U#修改配置文件
2 {/ F2 V# {; m7 Jvim nginx.conf v2 {* T3 ^0 ^! p
% ?- s, P- r+ U1 O
user www www;
$ c2 F% D, ^* {( p% U4 J0 kworker_processes 1;' K% y* u$ g7 v" s5 f
error_log logs/error.log;- L. ]9 c) o# j" g
pid logs/nginx.pid;
0 b- J' J2 l# P3 K( lworker_rlimit_nofile 65535;
. T6 y6 }$ c! p7 r% Yevents {
2 V* K# W. Y; l# y- m use epoll;9 {$ N( y3 G Y3 k1 {4 r2 ~
worker_connections 65535;
0 Y9 s4 N5 d+ d2 T}8 M0 M5 H& W" o5 p7 u) _
http {
0 x# @. w$ x- ~9 M n include mime.types;
7 [, o+ o5 E' v" i" F default_type application/octet-stream;$ A) c2 o! O* J: {! Z
include /usr/local/nginx/conf/reverse-proxy.conf;+ O! I" W) O4 x
sendfile on;6 U+ D4 K7 U6 o% H( l( W# M3 H
keepalive_timeout 65;
6 n' j( _5 ^) Z, ? gzip on;4 \) ]: v* o @
client_max_body_size 50m; #缓冲区代理缓冲用户端请求的最大字节数,可以理解为保存到本地再传给用户
, f4 I% u3 ~9 K0 C3 `. ?$ y client_body_buffer_size 256k;
8 m0 a! M5 U9 V9 L9 S client_header_timeout 3m;
5 n b R) Y( A) v5 L1 g7 i client_body_timeout 3m;5 `$ `) E% F0 Q: o' v
send_timeout 3m;
4 P+ _' K; K+ T6 n+ b- G. m3 [ proxy_connect_timeout 300s; #nginx跟后端服务器连接超时时间(代理连接超时)
1 `9 {1 z) v0 M- K) M( e proxy_read_timeout 300s; #连接成功后,后端服务器响应时间(代理接收超时)
6 n3 c5 y+ `* C0 \ proxy_send_timeout 300s;
& g2 C7 m# }( y proxy_buffer_size 64k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小6 p/ I, s, N& y, M
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置9 ~9 L$ T7 x/ |2 `$ K8 W/ O8 O* V4 [
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)2 {- Y" \' ^9 Q
proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传递请求,而不缓冲到磁盘
; H }7 a5 N, K4 W" D* `, I( S proxy_ignore_client_abort on; #不允许代理端主动关闭连接
4 x d) T1 `7 f: y. C server {
- ^. T0 \1 F) ~. D* N r# x% F9 [ listen 80;' p7 s4 d7 {# }: `* w# w0 O$ g
server_name localhost;4 u/ \6 h5 M( k6 b& e" ^
location / {' q( W5 m, R, y, @: t& v
root html;& E" z2 e0 R' M3 }( u) Y. w l
index index.html index.htm;
1 f( ~/ I$ C; K8 ]9 C( C) o }+ M) H0 G2 y# L4 @. p7 K
error_page 500 502 503 504 /50x.html;
* i8 h; w. g, @7 c location = /50x.html {
- B: R! H& J. c: k# a# o root html;9 x- q+ P# L1 _) v6 g( k+ J
}6 T+ _- t# k3 \. o% M2 H9 L
}
6 N4 `2 E+ G8 k" D1 N4 k" f' n}
3 ~7 I V- c' L# i2 y# y
+ |2 P' C* S0 F& z8 h编辑反向代理服务器配置文件:
( g4 h7 }" X9 V) A; |) V/ U
( Q! g) [- \/ Svim /usr/local/nginx/conf/reverse-proxy.conf
& O0 p5 U; `4 ^4 X8 w5 _ P& T* \1 F. q9 |( R& m! O; v
server% V: f/ H7 @* j, c" r- i; I9 i
{
9 }+ H% \: n4 [3 T/ d listen 80;
* I# m9 e+ W) i8 \+ q6 @ server_name xxx123.tk;
. U$ ]8 e! v! m! b/ [ g( L location / {9 { R# `) { @, G/ s0 i- U/ l
proxy_redirect off;8 O' O+ U% o( H* T0 v# e" ?! {
proxy_set_header Host $host;3 S% B5 I6 A! l, G
proxy_set_header X-Real-IP $remote_addr;
) f# b9 J4 |5 K' t, i; z proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
( Q; u8 p; r; W6 {' }5 N; } proxy_pass http://192.168.10.38:3000;
% M1 q& G; ^: K: | W8 W. } }
9 ?' l1 m$ {1 k; l4 X, c access_log logs/xxx123.tk_access.log;8 O4 x% _7 }! k% F1 K
}8 {# s. g4 G7 k8 T7 Y# ^
' P: i& O: Y5 `' Y+ Wserver
0 x. y9 X' x1 l8 B" r6 Y1 q( z{7 S( [, @7 Y1 J+ q8 y4 N/ ?
listen 80;
, d% a( B/ Z# ?, k7 n server_name xxx456.tk;5 S! \. _6 a. k! z
location / {6 F) u, E! m( o9 G- `
proxy_redirect off;: S- Y! h9 z$ ]+ R: L2 Y
proxy_set_header Host $host;) N: d+ T7 {) T+ l! H
proxy_set_header X-Real-IP $remote_addr;: D6 M9 B) k* l: W5 g! E9 {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;. [! i3 \* _6 P L5 S$ t) j
proxy_pass http://192.168.10.40:80;
. t8 S5 S& l. `9 `5 K& m: V }
" Y+ @. m/ `! r6 P# |; a9 I8 v- x9 ^ access_log logs/xxx456.tk_access.log;
' y5 ^8 V6 e* `3 a; o} _; B" V- X/ W4 k+ W& {
2 c9 a' v3 V6 p( C! R% ^然后重新加载nginx配置文件,使之修改生效,再把xxx123.tk域名指向公司静态IP,这样就成功的做到了在浏览器中输入xxx123.tk的时候访问的内网服务器192.168.10.38的3000端口,输入xxx456.tk访问192.168.10.40的80端口的作用。 如果想对后端机器做负载均衡,像下面这配置就可以把对nagios.xxx123.tk的请求分发给内网的131和132这两台机器做负载均衡了。# d V8 | S. \& l: T7 O; F4 R! D
( w9 i3 z+ Y' Eupstream monitor_server {: y9 ^" D' S( l5 U
server 192.168.0.131:80;) @) C- `- M s( f
server 192.168.0.132:80;: [. A+ i1 c7 A
}
" n& s# J4 G$ s9 S- ]# O: [# Q
* [$ C+ h" r; B) X/ N! K1 Cserver
! E$ ~0 w! ^8 s# @! C) c{: b% M* L+ h' r4 p
listen 80;
6 m- ?( W, e' i2 m* q0 P server_name nagios.xxx123.tk;/ [* O4 I \0 ]/ _+ t6 G
location / {" l P( D! `; D+ L5 x
proxy_redirect off;
- V8 O/ R% C6 o7 m proxy_set_header Host $host;4 ?9 M' ^- m- p K. f. b
proxy_set_header X-Real-IP $remote_addr;, x( x6 `. T( C% j
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 8 e" a" o* l- @" C9 K
proxy_pass http://monitor_server;# N0 g2 O* P. T: M$ H2 y5 H
}
9 t8 T1 i; K$ d2 f( b( w$ l* z7 o access_log logs/nagios.xxx123.tk_access.log;4 S; ]8 |8 ~1 L5 N0 S, f1 j
}$ u9 ]' ^3 i) S A
3 r9 z* l7 g/ ]+ y
额,关于负载均衡和缓存就不多说了,这里只是要起到一个简单的“域名转发”功能。 另外,由于http请求最后都是由反向代理服务器传递给后段的机器,所以后端的机器原来的访问日志记录的访问IP都是反向代理服务器的IP。 要想能记录真实IP,需要修改后端机器的日志格式,这里假设后端也是一台nginx: 在后端配置文件里面加入这一段即可:
6 \* w* ]5 ^2 R: x
0 I6 F+ }3 W! C) u/ {& @4 ^log_format access '$HTTP_X_REAL_IP - $remote_user [$time_local] "$request" ', _) z% d( X, u5 d7 L2 ~
'$status $body_bytes_sent "$http_referer" '" k2 m+ T% m5 i9 T# b! A5 q5 L0 |( i
'"$http_user_agent" $HTTP_X_Forwarded_For';
4 v" i1 P. E: S' ?& E
! J7 r6 }. B5 E* A0 B* r3 waccess_log logs/access.log access;% W# r0 k1 ?' H" p3 _
3 \9 a; s8 H( \( G再看看原来日志的格式长什么样:" f5 P1 T; {4 j% `" j
! Q) o* R+ L9 z; K1
2 i6 A4 `0 P0 H; p2
3 q3 j9 x8 ^+ i& O H32 g/ |7 w' N- L$ R% z V7 e
4: e' F6 G7 [8 \7 p/ ?. V! b, [8 ?
50 {1 C& L. a* {
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '. n! [% ~3 A9 P' B5 m3 g
# '$status $body_bytes_sent "$http_referer" '7 h, J0 }- N. X
# '"$http_user_agent" "$http_x_forwarded_for"';& H" ? I% H. ^# b' h- L1 U; S% m
2 s p" w% g# {: \% d1 Z0 u' X
#access_log logs/access.log main;% U! l! I W$ |
看出区别了吧 遇到的问题 之前没配置下面这段,访问时候偶尔会出现504 gateway timeout,由于偶尔出现,所以不太好排查
: T: ^& ]9 [ U- q# \4 R0 g1 x
" H0 q% d4 w/ b6 ~& h: k6 W1' e% n6 p! X- H3 t; f
2- i, K: o4 l! |" P+ Z
3- a! l4 Z3 h, C& B
43 b4 ~& S5 i$ X& I# B$ ~! @
53 c. C: p$ [$ y4 _! @7 R
6
7 \; I+ }$ s! O5 t77 Z U, f/ a# ]
8# R+ D1 j9 b. E
proxy_connect_timeout 300s;
8 r+ Y* R5 ~, M/ o8 wproxy_read_timeout 300s;
- w) ~7 M" h8 C% ? Lproxy_send_timeout 300s;& U: k0 I, C$ L! {9 x ^
proxy_buffer_size 64k;
7 R) e4 x' B2 y1 Fproxy_buffers 4 32k;
9 W" Y. D- W: z0 C" qproxy_busy_buffers_size 64k;
|& s/ B1 c- w% }, D; P( uproxy_temp_file_write_size 64k;1 p" J0 H, @# S7 g3 ?
proxy_ignore_client_abort on;, S9 \7 n5 ~5 i! S7 x( w5 Y- ]
报错日志:, a. l% r) `, ] X/ I
8 b& f4 O. K9 d9 F1 U6 e5 n( N# q L
...upstream timed out (110: Connection timed out) while reading response header from upstream, client: ...(后面的省略) 从日志看来是连接超时了,网上一通乱查之后估计可能是后端服务器响应超时了,本着大胆假设,小心求证的原则,既然假设了错误原因就要做实验重现错误:那就调整代理超时参数,反过来把代理超时阀值设小(比如1ms)看会不会次次出现504。后来发现把proxy_read_timeout 这个参数设置成1ms的时候,每次访问都出现504。于是把这个参数调大,加入上面那段配置,解决问题了。
8 x( g8 b6 @9 j6 ?. B7 Z, \( y8 X; u) g0 n8 q4 k& H
PS:关于域名转发
, W5 z0 W1 |' r# w$ q) ~6 `, A$ Y+ K4 U: ~' I+ H2 v2 S
所谓域名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/ 的内容。7 Z0 J& |7 e* }6 f, E
|
|