管理员
   
论坛积分
分
威望 点
贡献值 个
金币 枚
|
情景 由于公司内网有多台服务器的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.049 U; Z# u8 p1 i: F1 r0 `) j$ v( j
3 \* y0 P" a* L- ###更新仓库6 ^# K/ _; T6 m3 } A/ v
+ q8 `: y; B& F1 c+ a2 ~- apt-get update -y- J; v5 ^( g6 p; a6 k0 t
- apt-get install wget -y/ {. |; D7 R. {* ~+ k& y
- #下载nginx和相关软件包
复制代码 4 A" ^0 [7 ~0 t1 `$ [
1 Z/ p3 W% T1 K& b" A& H
pcre是为了编译rewrite模块,zlib是为了支持gzip功能。额,这里nginx版本有点旧,因为我还要做升级nginx的实验用。大家可以装新版本。
# K6 m6 J6 t* p# U( N3 f* p" m9 l4 `. d, @
- cd /usr/local/src
: S9 D9 w. ~ ?8 L3 O - 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># p2 ~# n, k" }2 P
- wget <a href="http://zlib.net/zlib-1.2.8.tar.gz">http://zlib.net/zlib-1.2.8.tar.gz</a>/ K; ~& m6 I+ t. v x9 q4 e
- wget <a href="http://nginx.org/download/nginx-1.4.2.tar.gz">http://nginx.org/download/nginx-1.4.2.tar.gz</a>
/ A0 Q5 M, K0 C1 G( I, S, K. P - tar xf pcre-8.33.tar.gz
, f4 z9 A6 ?) I - tar xf zlib-1.2.8.tar.gz
( k% h v h1 }- u$ L Z1 b8 C# R - #安装编译环境
$ M3 W* K$ S# q
复制代码 5 q- v( }1 I, g9 @- D! |/ X1 R
) T) e- Z$ _# i& T
apt-get install build-essential libtool -y
2 b# y h. B/ }& y r3 r& V1 e, J k#创建nginx用户- a- q# m% |: n
( f' `$ |7 ^" |9 E$ ?所谓的unprivileged user
' [- i4 A" `; ~ o6 k4 |+ \7 b2 H& s+ C
- useradd -s /bin/false -r -M -d /nonexistent www
0 H* W- R- F* d - #开始编译安装5 h' F; Q9 e5 ^2 p1 V+ n
/ u) b1 ~% ?! E. h4 S2 c5 e- /configure --with-pcre=/usr/local/src/pcre-8.33 --with-zlib=/usr/local/src/zlib-1.2.8 --user=www --group=www \& r" E |. P# n+ T
- --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module
7 H: |8 E( n* s) \( G# J' S% Y - make, o" |/ x6 r2 I2 H' ^
- make install, {+ b/ o5 D7 Q# u5 R+ z7 T
- #给文件夹授权
复制代码 a/ E& D2 V# D
1 f! I5 t' W k1 [+ M }4 Q6 Schown -R www:www /usr/local/nginx- y1 f" w! O1 D
#修改配置文件
$ B# o+ B* T( Y" Y$ M- bvim nginx.conf
$ j& m1 U8 y- o# v" Y4 t
% j, Y9 N% Y% {6 m) u* X7 S8 wuser www www;
3 q j6 J& o" T* tworker_processes 1;
2 f g7 q$ J: R& berror_log logs/error.log;2 _1 |: l! R% ^% z4 N
pid logs/nginx.pid;
( N$ |* P" z1 ?# z, f' Uworker_rlimit_nofile 65535;
* k* o/ \4 T# B; ?! s: q! z, Y/ P5 D7 w, vevents {* r3 ]1 N" b# B ]; H S
use epoll;
# N1 l$ M" U0 d0 I7 i/ } worker_connections 65535;( d/ o6 s( Q3 u) y
}
5 D( o/ g" j0 s4 Zhttp {2 `: O+ v9 I# w/ ]% t
include mime.types;
3 n; E Q6 B- c* S. a default_type application/octet-stream;
, Y$ A; ]$ u; r# L0 u! r$ P' U include /usr/local/nginx/conf/reverse-proxy.conf;
. Q; X2 ^' N, m; k1 j sendfile on;
S; l* n& n+ N keepalive_timeout 65;
! f* G' l, `4 f9 E" n& t( L2 o gzip on;
; G1 ~' H; T) y+ c9 p4 [ client_max_body_size 50m; #缓冲区代理缓冲用户端请求的最大字节数,可以理解为保存到本地再传给用户
; w7 t% |4 V! A: j( F( [ client_body_buffer_size 256k;
3 }- R2 t3 ]' N# b2 Z; O3 D3 Y client_header_timeout 3m;$ x' I. \( `- o6 b
client_body_timeout 3m;: @+ T7 M) R& J- j7 Z2 I. P9 l
send_timeout 3m;! P. N) _) q! x% r C
proxy_connect_timeout 300s; #nginx跟后端服务器连接超时时间(代理连接超时)
7 D/ ^' i5 r% Q' x# g& Z proxy_read_timeout 300s; #连接成功后,后端服务器响应时间(代理接收超时)$ Y: b" s8 Q4 _
proxy_send_timeout 300s;
. q& Q* ^7 ?1 j) \' | i3 h8 F proxy_buffer_size 64k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小; L* w2 g7 ^3 k3 g; N% S! G* n8 h
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
1 |( x ?3 Z8 n0 H2 S# x7 \7 U proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)4 s* S* _8 \2 m# t+ C8 d
proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传递请求,而不缓冲到磁盘
; q, Z" A9 F; i2 E+ E" r4 W z proxy_ignore_client_abort on; #不允许代理端主动关闭连接 F1 @/ [7 [; w! W) [% y% _
server {
# ?5 w6 v6 H0 \6 ^9 n5 U/ W+ d listen 80;
# H' s+ T! s! F9 o- \5 T" ]2 _ server_name localhost;
: D6 }0 r0 ~1 |' j$ t0 W location / {
% _4 }. W5 z) H* W3 ^ root html;
# X0 K2 d! h/ y+ v index index.html index.htm;* u# J7 Q# T/ _ K' c) Y
}& R$ p4 {1 u4 t, ^5 D
error_page 500 502 503 504 /50x.html;
) i* {& C7 t# g3 ~- c* q location = /50x.html {
8 \- T, \6 w4 v; x root html;: T$ `9 T4 t3 i: W
}/ q* T6 ]. _8 B9 a# w% ]- K* O9 N
}
) i# h: |. k3 X$ P. i) n} E5 I G2 }" t1 N- u! ~" p
3 {% L4 J; e8 {. R
编辑反向代理服务器配置文件:: d9 ^6 o0 | w9 b
7 n' h a7 ]1 w! ivim /usr/local/nginx/conf/reverse-proxy.conf
; w$ p m, r. d
% C! _ m- w( L* n; C1 yserver8 a+ C" {2 J( J4 @
{4 f" Z* N: C, X/ u
listen 80;5 S$ G4 p6 L: Y- p" E
server_name xxx123.tk;; Y: A4 d) T! R! J0 v6 ]4 v
location / { M+ H$ ?1 ^! G& m
proxy_redirect off;7 r, R, a% |, h) C
proxy_set_header Host $host;
9 N% Q3 i% r- a; g7 i6 T& T proxy_set_header X-Real-IP $remote_addr;
7 i+ G5 g4 {" { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
* I- i( A M9 A) H proxy_pass http://192.168.10.38:3000;
6 Z2 |+ t/ o E }
: K9 `1 X$ n) h% ^$ d! l- A access_log logs/xxx123.tk_access.log;1 K" Z: `4 P) V h! f2 [
}. @0 h4 b7 h- G9 b
. z: W) Z$ j8 vserver
' M$ X |$ b$ I, X6 X- u: \# \; X8 U{
# K; m( q/ ~/ z$ T: z! ? listen 80;
% }; ?, j& y" Z9 _( s server_name xxx456.tk;! p/ L' s7 J3 Z4 p* Y2 `; a/ k% P
location / {
8 f7 v" Z+ F" W2 I9 g) Z proxy_redirect off;2 H9 a! q) h7 \
proxy_set_header Host $host;: t S$ |+ I& ^: \& q
proxy_set_header X-Real-IP $remote_addr;3 ^* E! e3 F" c$ j( V' g9 D
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
8 P7 D: l+ e* J& F( u" i7 h8 c proxy_pass http://192.168.10.40:80;/ Z7 e8 ?) d- P/ V
} Y5 p* T9 Z1 X+ R5 b
access_log logs/xxx456.tk_access.log;: N7 {2 `5 E7 J: j: v5 S6 ]
}
^0 {5 l T9 H/ I" y- O/ ]6 I
1 D4 i! ^6 n1 z' N: n然后重新加载nginx配置文件,使之修改生效,再把xxx123.tk域名指向公司静态IP,这样就成功的做到了在浏览器中输入xxx123.tk的时候访问的内网服务器192.168.10.38的3000端口,输入xxx456.tk访问192.168.10.40的80端口的作用。 如果想对后端机器做负载均衡,像下面这配置就可以把对nagios.xxx123.tk的请求分发给内网的131和132这两台机器做负载均衡了。* H5 w/ B0 D# j5 @3 R
, _+ C6 l7 T |- R8 C( u0 }
upstream monitor_server {# v' d! U& \5 _; m, _
server 192.168.0.131:80;1 o1 v6 g7 r& r4 B& W3 A7 T. j1 Q
server 192.168.0.132:80;
/ I7 O/ H; a. H+ R}
% A4 a" v7 l& B 3 y9 O# }4 ^( J/ ?
server
, b* ]2 E. D# z" g{9 q5 `! V3 q3 g6 z' [3 k
listen 80;6 U! }/ _8 T6 E+ L; p9 Q4 w
server_name nagios.xxx123.tk;% M9 D; }8 b6 ~
location / {
1 ^ `2 I$ j3 a& @6 Q* U: N3 M proxy_redirect off;. F& W* l* G$ [+ ^$ L: S
proxy_set_header Host $host;
: E3 C* w9 C- [3 c! @2 Y1 _- G proxy_set_header X-Real-IP $remote_addr;
& \3 T7 R3 Q8 f2 X- Y- B proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# P+ \6 y7 j. r% `( h proxy_pass http://monitor_server;' g* ^& y6 V" J. C
}
5 o9 A8 J2 R0 A0 {$ i access_log logs/nagios.xxx123.tk_access.log;
; l2 d9 d* ~, `}
% v7 o9 {7 A! } {9 v4 I) S
& r# _, t* m2 s2 u$ b& `1 d1 B, c) J额,关于负载均衡和缓存就不多说了,这里只是要起到一个简单的“域名转发”功能。 另外,由于http请求最后都是由反向代理服务器传递给后段的机器,所以后端的机器原来的访问日志记录的访问IP都是反向代理服务器的IP。 要想能记录真实IP,需要修改后端机器的日志格式,这里假设后端也是一台nginx: 在后端配置文件里面加入这一段即可:
& g1 x3 B: s6 t9 `6 u7 }4 J* }+ G; \% @
log_format access '$HTTP_X_REAL_IP - $remote_user [$time_local] "$request" '! ^2 J1 u. |9 c4 [( b, V
'$status $body_bytes_sent "$http_referer" '
. ~! t: ~) [( X5 y8 N" s; Z'"$http_user_agent" $HTTP_X_Forwarded_For';4 b' {# i, _/ k$ O0 L. Z
1 i# B( P, @. }
access_log logs/access.log access;$ ^& L0 r w1 A5 b9 k6 u+ q9 w( a
* g. J; B* C: i5 d# S* ~5 |; }. B r再看看原来日志的格式长什么样:
( K) V6 b6 C6 u! y8 |4 `8 f; A% ]* G
1
9 c$ P* Y9 \% l+ E0 I, e# X2; P6 n% \+ P T7 o
3& [: j [ L5 f
4% s: u' H+ K7 N" i( R4 E! ]% e0 {/ j
5
% K$ p8 s2 v6 O4 J#log_format main '$remote_addr - $remote_user [$time_local] "$request" '9 {5 a, ?0 h7 I- J% U5 G
# '$status $body_bytes_sent "$http_referer" '/ U# m7 {' }" _
# '"$http_user_agent" "$http_x_forwarded_for"';3 t2 U2 A) k& M
# I$ Q1 ~# `( ~! r, K#access_log logs/access.log main;( F. P6 B8 O0 F j" p" ?
看出区别了吧 遇到的问题 之前没配置下面这段,访问时候偶尔会出现504 gateway timeout,由于偶尔出现,所以不太好排查
1 p( J0 n2 F2 v g H1 |
% i( v' {- h& n" b( K1: d) c5 n1 r) T. N/ P" W1 V A
2+ K, I6 K4 e/ H2 u& `' O2 t- o) U
3
9 P- R9 s0 d1 ~" d: }: g41 o U, K3 d# h. }
5
0 N( W* s# V) r: T5 K8 r6% q- m0 E7 \, E# L
7% @' e+ F4 y5 |( Q0 i/ k# i8 p
8' v9 E+ Q0 ]4 B& ~
proxy_connect_timeout 300s;
) s: q0 k3 t7 G8 \* q2 @8 o! aproxy_read_timeout 300s;( t$ J- A+ `% Q" g" ^3 t
proxy_send_timeout 300s;) E) m: Z8 q' p% g
proxy_buffer_size 64k;
" a, F% L1 R# J) e9 f8 uproxy_buffers 4 32k;
7 |2 Q5 n9 q0 k( \- L% J* Lproxy_busy_buffers_size 64k;7 s2 j' M! E; V0 f) o
proxy_temp_file_write_size 64k;
6 T5 ]7 B( l$ S- iproxy_ignore_client_abort on;: b6 P& U; \* ~" t! Q9 B
报错日志:) H9 n- R* c; z7 w" j% Z
7 [) _0 T0 m3 h; d2 a
...upstream timed out (110: Connection timed out) while reading response header from upstream, client: ...(后面的省略) 从日志看来是连接超时了,网上一通乱查之后估计可能是后端服务器响应超时了,本着大胆假设,小心求证的原则,既然假设了错误原因就要做实验重现错误:那就调整代理超时参数,反过来把代理超时阀值设小(比如1ms)看会不会次次出现504。后来发现把proxy_read_timeout 这个参数设置成1ms的时候,每次访问都出现504。于是把这个参数调大,加入上面那段配置,解决问题了。
% |' K' s% f( Q# n; ]; g! @) X3 F: X0 e, o' K9 B
PS:关于域名转发
: h- A3 L8 I9 u
( ~7 C7 o, f! c5 a, ?所谓域名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/ 的内容。1 K! E! \4 d; A$ v$ f( m4 F
|
|