管理员
   
论坛积分
分
威望 点
贡献值 个
金币 枚
|
情景 由于公司内网有多台服务器的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: ?6 g% a- l9 {
& y/ N' G% Y1 Y Q0 E+ S9 Z% l7 f, G- ###更新仓库9 k8 _( j4 X x" i" u
- 5 ]& W' q( s8 p8 |, ~4 A6 p+ U
- apt-get update -y
1 |. n+ _2 A% r, g+ o' k - apt-get install wget -y) W4 B/ g. h0 z6 l/ E
- #下载nginx和相关软件包
复制代码 + q2 [& \/ J' R: a
0 a o W' g Z2 jpcre是为了编译rewrite模块,zlib是为了支持gzip功能。额,这里nginx版本有点旧,因为我还要做升级nginx的实验用。大家可以装新版本。" {8 _& l5 D0 _6 C; C
$ W5 D2 G- z- B' T- cd /usr/local/src. o! B# y9 p5 {0 A
- 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>" ` K6 K; [- L3 `) V( n) ~
- wget <a href="http://zlib.net/zlib-1.2.8.tar.gz">http://zlib.net/zlib-1.2.8.tar.gz</a>
7 a. |+ O ~4 X - wget <a href="http://nginx.org/download/nginx-1.4.2.tar.gz">http://nginx.org/download/nginx-1.4.2.tar.gz</a>+ w% r; B8 H' `# K; J, B$ b/ N; [
- tar xf pcre-8.33.tar.gz# L: Z6 q, y9 M' ?- B
- tar xf zlib-1.2.8.tar.gz+ i; h9 S6 H6 `" S1 M1 W3 n
- #安装编译环境6 j5 _# s/ a( K8 U7 j5 s. g
复制代码 % y0 f1 ?6 Q) t% ?& E5 c: L
/ R) c2 z6 x2 ~$ n% }% n# v# L
apt-get install build-essential libtool -y2 n2 H- Y( P$ W! n6 r$ d0 a4 S
#创建nginx用户6 P2 {* ?, v2 @
2 h& F) \6 r( i) k* A3 c" j所谓的unprivileged user
: ~5 C2 Y5 }1 n$ O/ |6 }; V2 {+ ~- r) e3 U# h
- useradd -s /bin/false -r -M -d /nonexistent www! a, N2 q7 E4 C5 |+ ] U+ p/ s
- #开始编译安装
. j4 j( O; ~* l! ~ - * V8 x. G- O" j4 U, `* X) O% F
- /configure --with-pcre=/usr/local/src/pcre-8.33 --with-zlib=/usr/local/src/zlib-1.2.8 --user=www --group=www \
1 f: S- F; t8 B - --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module
. J0 `. @/ \% F% ~+ Q3 n' P' f2 R - make
6 \9 c& `8 H( k - make install d$ t4 r- `( @% }
- #给文件夹授权
复制代码
r- K+ S! g3 C6 @6 U
1 L7 S/ D. B' f% Qchown -R www:www /usr/local/nginx
) F2 z* m: M6 M* N#修改配置文件
+ S v. L# ^6 cvim nginx.conf9 k# ^' r" e6 |
! l7 y3 \. p) u
user www www;; t6 v: a: J J4 I+ L; V
worker_processes 1;, V9 o% H6 b" q
error_log logs/error.log;
G+ ?' U( L& |/ Xpid logs/nginx.pid;
8 y) Q4 p# J: y0 b$ Vworker_rlimit_nofile 65535;% w1 A& C4 _5 \( `8 k n. f. ~! ?3 b
events {; r6 z9 j3 B; M+ F
use epoll;
1 W9 k% u( S6 Y) d) [1 W& ~) w worker_connections 65535;
+ x4 t8 d* `+ v}
/ p% Y4 c7 Z1 \, h/ G/ vhttp {
2 m. a8 r+ a3 y3 R* H" Z include mime.types;, C2 L0 l$ l4 h/ M3 w
default_type application/octet-stream;
2 ]+ o; G% G4 X- g1 j: e& u: [ include /usr/local/nginx/conf/reverse-proxy.conf;4 E1 g! z1 L1 r3 n: J3 K" U6 {! d# `
sendfile on;
9 i& Y( I, X# a" `; a z! N5 D keepalive_timeout 65;7 L. ^) m# F. \ {9 D+ m% ~
gzip on;
7 ?, H8 i1 E8 ~7 F- X: c) ?1 T: p client_max_body_size 50m; #缓冲区代理缓冲用户端请求的最大字节数,可以理解为保存到本地再传给用户5 w+ J( M. D7 f4 |+ }2 W7 Q
client_body_buffer_size 256k;
* ^ m e* n" C. p: f client_header_timeout 3m;
' E- D" e) Q0 {3 u7 Q( Z/ c! q# h client_body_timeout 3m;+ k* ~* `* D b) U
send_timeout 3m;
8 w0 w7 M5 y. n) g# w* D$ b proxy_connect_timeout 300s; #nginx跟后端服务器连接超时时间(代理连接超时)' d" ^8 i5 W0 R6 C
proxy_read_timeout 300s; #连接成功后,后端服务器响应时间(代理接收超时)
& L h9 ~! x( G6 d1 E) m8 P( [) {- l proxy_send_timeout 300s;, y* J3 E" `: v( ]7 _1 h- F: P
proxy_buffer_size 64k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
- l6 l$ [ X3 `3 n- L proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置2 y0 i/ f. c( }/ r% v! m
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
/ c( F" s+ i7 P# @0 \( D; _ proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传递请求,而不缓冲到磁盘
* u1 h4 |+ z* v$ F+ t: z proxy_ignore_client_abort on; #不允许代理端主动关闭连接
3 ~7 m. c: m+ S! M- R server {9 g! }# q4 Q6 H1 s/ F+ {5 W
listen 80;6 z. }, ` D1 @1 u. Y. Y* B
server_name localhost;- A! \* O8 H! V" r8 b
location / {7 \5 k: Y' M4 I
root html;& g9 E8 v+ x! X5 w& K9 C' C6 Q+ c
index index.html index.htm;- D0 R# U+ q% \ R" F! z# I
}: y! J; h6 B* G) l4 J
error_page 500 502 503 504 /50x.html;
, m, Z: W8 l# H: ~4 P$ Y location = /50x.html {
# _, {1 F1 k- W& F1 u root html;( G) _, O) _' N ^
}2 `/ q2 T( B& }3 Q
}* F: a* v) I, i6 _8 z
}0 D; z3 y9 P- ]1 S% W, M1 a
9 \0 O5 B" I6 L2 ^! Q4 n- k编辑反向代理服务器配置文件:! s" U3 J! b" K& g/ R9 H7 H5 Z& c4 n
: N- R0 E# a3 l7 n+ y5 ^vim /usr/local/nginx/conf/reverse-proxy.conf
4 Q+ T. Z1 d. h& L2 i& c
+ S' P' {6 x E- e4 Y# nserver
# n& r7 d6 F% z2 g$ J& d" g{7 |4 N3 t7 }2 L/ i! g
listen 80;
1 ^0 o A) C9 e. m server_name xxx123.tk;$ N" |$ V, R& B4 u2 m% J
location / { `# W) Q0 [; B: Z* n
proxy_redirect off;
6 ~& G/ `4 S- j proxy_set_header Host $host;
9 d d# b3 n4 Y proxy_set_header X-Real-IP $remote_addr; b! b2 A+ p9 l3 V0 ^. g
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
! D/ I% n q% y2 ~" y; q5 Z( a! _ proxy_pass http://192.168.10.38:3000;3 T2 n* T! k2 n( f1 x4 c
}
! P4 c4 [; e" t" h! L# ]4 | D access_log logs/xxx123.tk_access.log;
- ~: y) M) r3 C9 f1 e' l}/ s" v6 s9 n" ~, {8 a. A
' T5 S# y' M7 n" J" H1 ]+ Jserver
9 \" C! ?' ]' V' H- d{
6 h# Z9 O7 j4 D/ H listen 80;) s. e3 L$ l7 i' x5 x% j8 C
server_name xxx456.tk;
1 y! W/ f, d) E, z location / {
& _( r. N5 p, x' u; }, K8 p+ h# v proxy_redirect off;# I. a, l4 Q6 u+ \ P' z
proxy_set_header Host $host;
- R; m" O- d* I- B9 Z" r proxy_set_header X-Real-IP $remote_addr;
' E. O' e" G9 M! u proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
2 M6 W$ V" J5 M2 ~5 a, D0 E# v proxy_pass http://192.168.10.40:80;
: l/ d! B5 n: ^5 Z% M! q }9 o8 m- ?5 k" |, e1 `7 A
access_log logs/xxx456.tk_access.log;
- [% S- A2 ~& p" ~}
, A; `) x9 G" \; L" `( E+ g7 t
% M+ s2 c. N; Q' A然后重新加载nginx配置文件,使之修改生效,再把xxx123.tk域名指向公司静态IP,这样就成功的做到了在浏览器中输入xxx123.tk的时候访问的内网服务器192.168.10.38的3000端口,输入xxx456.tk访问192.168.10.40的80端口的作用。 如果想对后端机器做负载均衡,像下面这配置就可以把对nagios.xxx123.tk的请求分发给内网的131和132这两台机器做负载均衡了。
1 B, W% z$ k, o$ W+ ^: K. e3 n5 y" D7 N4 y' s1 C
upstream monitor_server {
0 X9 T4 ~# G6 X) A# ~: j server 192.168.0.131:80;
' _. f' p( @2 P7 Y* ?2 o& R server 192.168.0.132:80;! R$ r' p' m- H; g. M0 Y. W
}
( P2 c/ ^& T9 Q# \. ~4 v ! s* g& m+ C% [$ o Z% u
server% i& l, B/ k; Q7 Z) E3 d
{
3 B9 ~2 Y$ `+ ~ listen 80;
# \* z7 d& e' [' [0 [3 M server_name nagios.xxx123.tk;1 J& ~' ^8 @# x9 t4 |* k2 ?7 P
location / {5 G1 l6 a! P1 Z: z% ~2 e/ z
proxy_redirect off;* K; F( h: |, h" _. t
proxy_set_header Host $host;
T. d [7 q W6 z proxy_set_header X-Real-IP $remote_addr;5 i: A. @4 `/ a9 e6 s
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
; s7 O3 ^: u. _" ^+ W proxy_pass http://monitor_server;
( t7 U4 F3 G& k5 w, `8 D) N }9 u! j/ C) l' h# P& }, R
access_log logs/nagios.xxx123.tk_access.log;# L9 [! q9 d$ s2 y" @1 r$ i
}; I* {8 J# q& v( v9 y% ?) \
8 k, `6 E: g0 J. h
额,关于负载均衡和缓存就不多说了,这里只是要起到一个简单的“域名转发”功能。 另外,由于http请求最后都是由反向代理服务器传递给后段的机器,所以后端的机器原来的访问日志记录的访问IP都是反向代理服务器的IP。 要想能记录真实IP,需要修改后端机器的日志格式,这里假设后端也是一台nginx: 在后端配置文件里面加入这一段即可:
* I+ s3 U/ M$ e; a) k' m/ s/ i- q! I' j
log_format access '$HTTP_X_REAL_IP - $remote_user [$time_local] "$request" '
7 D* F/ W: @: v'$status $body_bytes_sent "$http_referer" '
. m8 \7 H+ X# Z: H'"$http_user_agent" $HTTP_X_Forwarded_For';
+ \6 V. Y" u; c+ N; p. V$ j4 @ & p- I( t0 a. g$ O- W2 d
access_log logs/access.log access;
7 V s7 A6 R, c/ W5 k$ J Y& o: f4 f- g6 B r+ y) c
再看看原来日志的格式长什么样:
' h: j' n$ r |8 O) A6 ?& [2 S3 I5 d, ]; ?7 U2 U6 X3 t
1( j8 ]1 w8 }0 ?6 i2 E V& D
2
, i7 }- c. |- q. [# z" i1 Z9 l3& M; X s+ L' A! F+ t
4( h. L$ C" R t' u
5
( A* J A, B2 l m0 d! H#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
% J; o8 O6 B& H, F# '$status $body_bytes_sent "$http_referer" '0 b5 {1 }* H. B: A
# '"$http_user_agent" "$http_x_forwarded_for"';
. C5 f: `0 O7 l : B7 s" ~/ ~& o0 ]9 T
#access_log logs/access.log main;
+ Q/ R: F; D( @. e6 V, j/ ~看出区别了吧 遇到的问题 之前没配置下面这段,访问时候偶尔会出现504 gateway timeout,由于偶尔出现,所以不太好排查
7 C; ~3 l% N+ \1 f3 |* N0 n; L" x+ I$ ~1 Q8 w( w6 J9 w
10 k+ s1 y B9 U w2 p7 C: B
2
. y: Q, R7 b5 N1 f; \3( W4 n& Y: ^( @* _8 s
4& {% Q5 A- P* r# l1 b: o( p
5
; z. q" d W1 A! J6
! {- k: `. J9 Z& ~7, d8 l; A9 x' H& d* Y1 @ h
8
" w- p, p# J2 Yproxy_connect_timeout 300s;6 g2 K: L$ Q) N( k/ X2 @, J
proxy_read_timeout 300s;$ A, \+ P3 G& n, F! s/ j" e4 p
proxy_send_timeout 300s;7 q8 Z ?5 p, z. x, ~& q
proxy_buffer_size 64k;/ N" i6 k" u+ w1 Q0 j% m
proxy_buffers 4 32k;
/ Z7 I$ l9 M+ F! ]; H# y1 Dproxy_busy_buffers_size 64k;& [% L8 S) ?9 z
proxy_temp_file_write_size 64k;" N% ~5 N$ K: n4 t3 K8 |: }1 T
proxy_ignore_client_abort on;
3 i2 U: n1 ^; L% Y! o/ W报错日志:
. G$ I9 ]9 ^: o: ]7 X) I \* V6 P: t/ r, ], v% `2 }
...upstream timed out (110: Connection timed out) while reading response header from upstream, client: ...(后面的省略) 从日志看来是连接超时了,网上一通乱查之后估计可能是后端服务器响应超时了,本着大胆假设,小心求证的原则,既然假设了错误原因就要做实验重现错误:那就调整代理超时参数,反过来把代理超时阀值设小(比如1ms)看会不会次次出现504。后来发现把proxy_read_timeout 这个参数设置成1ms的时候,每次访问都出现504。于是把这个参数调大,加入上面那段配置,解决问题了。$ e" U9 P6 b/ y# O% C5 ?/ u
( n4 H& A9 M: E: r4 i3 V
PS:关于域名转发
, p8 L H' ]* p: S r$ _6 m6 i7 k' ]4 f+ i+ T2 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/ 的内容。
9 m- K" E/ o/ M5 r$ S4 g |
|