管理员
论坛积分
分
威望 点
贡献值 个
金币 枚
|
情景 由于公司内网有多台服务器的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
0 l4 T: E6 ^; ?# _0 G. U- d- |0 d9 g2 M5 H3 S( c5 E
- ###更新仓库
# [7 c0 [* G5 ?
3 U. Z( K2 s( L. V. L h g- apt-get update -y
' @$ ]0 \+ X- f7 ] y% Z, n! |* s - apt-get install wget -y0 G/ d2 L# U2 z. s$ x7 \8 j) L
- #下载nginx和相关软件包
复制代码
/ z8 P0 ]2 U1 ^( y& P
. v8 K2 {( v% P) y. Dpcre是为了编译rewrite模块,zlib是为了支持gzip功能。额,这里nginx版本有点旧,因为我还要做升级nginx的实验用。大家可以装新版本。
- Y8 H% F8 F; _4 o N& w- w* L3 {
- cd /usr/local/src1 T" w/ Q$ Z+ I1 O7 f* K
- 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>/ Z3 q! {* D/ `
- wget <a href="http://zlib.net/zlib-1.2.8.tar.gz">http://zlib.net/zlib-1.2.8.tar.gz</a>
! V! u: ]$ B) w5 q. j% H - wget <a href="http://nginx.org/download/nginx-1.4.2.tar.gz">http://nginx.org/download/nginx-1.4.2.tar.gz</a>+ j/ F8 _6 W5 B) a# Z. ~8 q
- tar xf pcre-8.33.tar.gz: X, ?1 h! j) h- U( W2 M
- tar xf zlib-1.2.8.tar.gz
3 v6 h/ E: |; W# T7 S7 Z% a6 H- f. y! c - #安装编译环境
9 p4 {1 w# J# B5 m" F
复制代码 " ~" U R* j! r# Y# {9 }' O
, b+ m1 z9 M0 z( _' z' w apt-get install build-essential libtool -y W& M. c4 L1 }4 S9 x, q
#创建nginx用户
3 ]1 c7 z" K3 l& S+ k! ]$ n- j& q8 L! J4 s$ A- O: J
所谓的unprivileged user1 T" R1 e: f- I i
. y; T, a: o- @% @% E$ c$ l
- useradd -s /bin/false -r -M -d /nonexistent www3 K7 D% c, f7 b- K+ ~5 n# B8 \
- #开始编译安装, c/ Q6 W# @- F$ {
I+ ?: |& j( c. L' |3 T' _5 U- /configure --with-pcre=/usr/local/src/pcre-8.33 --with-zlib=/usr/local/src/zlib-1.2.8 --user=www --group=www \
: B# V6 ]; s L' F - --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module( T. v+ d" M8 I0 f; [/ ~6 v( ^: r
- make4 H4 d* I. ^& Z) B
- make install8 v* }1 e9 n1 R- a
- #给文件夹授权
复制代码
5 _! ^1 \) n3 Q. W# o+ ?, @% g9 s7 U, T / Q0 w3 f8 a; t2 k9 ]( C) \" I
chown -R www:www /usr/local/nginx; R9 W3 \5 T" T( V) _
#修改配置文件
* n- i8 n/ B. w* |% pvim nginx.conf7 P- N* m- s1 S* [& ^( i
+ U' }3 ^" i1 s: i7 [/ u: Nuser www www;
. R4 b* T* S- ~6 r, c8 p. d+ @worker_processes 1;, S- V* T( f5 ~# F
error_log logs/error.log;/ w J# d6 w" E5 @6 N- c% [
pid logs/nginx.pid;) l) g; q& ^; X0 J: \
worker_rlimit_nofile 65535;
, |6 z* t. `# B8 J- s o4 g/ Gevents {, D2 `' u2 `* U+ N8 C/ J
use epoll;8 y5 E7 j& p# M0 F4 O$ M0 z
worker_connections 65535;
; z' n8 d, t. L3 Z1 I$ \( m}
1 v2 k# m( X0 H, p2 ihttp {% a8 t/ M! \* @3 |2 ]1 @
include mime.types;
# b8 Q. f7 V# Q8 ~+ h& g* e default_type application/octet-stream;
8 p6 n( j. b8 D7 _: n include /usr/local/nginx/conf/reverse-proxy.conf;! t) L9 L0 F$ I- d2 T
sendfile on;
3 L" b R1 o* T9 N* M keepalive_timeout 65;
$ }5 @! J1 i% x' D3 `9 B gzip on;
$ G4 q# g9 U2 U: o2 z$ C1 x _ client_max_body_size 50m; #缓冲区代理缓冲用户端请求的最大字节数,可以理解为保存到本地再传给用户2 }. g7 E$ i6 H J3 z/ t$ ?" r
client_body_buffer_size 256k;5 T- ~: k0 d: s: P2 W2 o
client_header_timeout 3m;
: p1 l6 f' J0 F* q% N& w E client_body_timeout 3m;
6 W$ K# k H- G! K9 b! z! o, [ send_timeout 3m;7 I9 S; R, d1 x. R
proxy_connect_timeout 300s; #nginx跟后端服务器连接超时时间(代理连接超时)$ ]+ A6 w5 P2 H ^) |# k+ [
proxy_read_timeout 300s; #连接成功后,后端服务器响应时间(代理接收超时)
8 ^6 \7 W* H. O6 M: f9 M) Y& d @6 H proxy_send_timeout 300s;
$ v7 U3 K3 m* j; b proxy_buffer_size 64k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
5 E8 k3 }& ]6 Q$ Z1 ^ proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
' B( H/ B, @9 T/ w- ^) I) R+ ? proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
. f9 G6 B5 E. q( a% X# L5 L: q proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传递请求,而不缓冲到磁盘! B( K5 W# A- u. T
proxy_ignore_client_abort on; #不允许代理端主动关闭连接 d8 M) ]! f% q# g: e; ?
server {6 q. f6 i. [' R/ o3 w/ B# W; O7 Z
listen 80;. b7 d5 F" A' ]2 O6 U) T
server_name localhost;
7 Z8 _$ g* \/ \ P9 |& Q location / {
2 M; H1 j. W7 E root html;2 v# A$ s8 I, n4 Z% s$ o, Y
index index.html index.htm;
9 {5 i Q2 O% { }
i: w8 q# x9 P# A2 n3 G error_page 500 502 503 504 /50x.html;
% e$ l" W6 Y4 F1 l' I0 _ location = /50x.html {
( K/ y* O# C2 z( ]/ @8 p; w root html;
2 r; _' n" `, z0 l) A- H) `, l. K }
8 {) k; E" w# N. M }$ } n, F. h9 ]: x9 l% T5 [" y9 U
}/ `0 f! \7 w( o) Z5 d9 S# q
7 L3 u0 d; n% {. k- v/ _
编辑反向代理服务器配置文件:
! V3 b8 B: i. B U2 @3 f2 Z
x$ z4 N7 a3 \# q4 g, Wvim /usr/local/nginx/conf/reverse-proxy.conf, i1 x2 O% ]5 {+ O3 y+ o
: A7 U% v( L% g% t4 V+ }
server
+ O$ P* y+ k$ _8 t: j{1 k" t4 p+ |; f
listen 80;
: t% ~9 [. _2 d server_name xxx123.tk;
4 f% O; [; O; p2 P. ` location / {7 G2 D0 w- M7 a* g8 {- I0 x% l
proxy_redirect off;/ ?$ p: w, T' W" y2 P
proxy_set_header Host $host;
& r# m" A# ?" B3 [5 O4 Z! I4 j proxy_set_header X-Real-IP $remote_addr;
: d I! `# ?/ ]0 R% @) ` proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
$ E9 i3 Q6 g- P" }* m& Z) M. [ proxy_pass http://192.168.10.38:3000;
( v/ e' R, q9 ^: m" ^5 w }
7 \5 Q' B0 p% q7 Q% ~5 N+ S0 W access_log logs/xxx123.tk_access.log;
. i# D' F7 M$ P A}
+ g* a9 c/ T" k6 q" C6 R
0 L7 E ~# h2 l U! M& \4 Wserver. D" f9 |: y9 j3 ?
{
: j6 H* L3 N7 P/ b listen 80;
/ p8 H( l) @. I; q& f/ g server_name xxx456.tk;
f' ]/ w- s1 r3 ~1 X+ K0 q0 l% M location / {
/ @* P4 k: }- w/ `" E proxy_redirect off;
4 \2 o4 {+ k- S2 B$ P proxy_set_header Host $host;
; x+ ]& \3 S- R) { @7 c7 | proxy_set_header X-Real-IP $remote_addr;
/ x7 W/ `3 e6 {6 J6 _1 ^! c proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
0 {; D& G% |# b proxy_pass http://192.168.10.40:80; O1 i% ]0 H# e! M/ _/ `
}
+ i/ z& m8 E: h2 B4 b access_log logs/xxx456.tk_access.log;
2 p5 {+ N8 J& a+ R}. G* N7 _) ~- y
3 f$ M8 ^3 m$ m$ z8 d# D然后重新加载nginx配置文件,使之修改生效,再把xxx123.tk域名指向公司静态IP,这样就成功的做到了在浏览器中输入xxx123.tk的时候访问的内网服务器192.168.10.38的3000端口,输入xxx456.tk访问192.168.10.40的80端口的作用。 如果想对后端机器做负载均衡,像下面这配置就可以把对nagios.xxx123.tk的请求分发给内网的131和132这两台机器做负载均衡了。
6 |# e2 b6 G% M2 P* G9 \" ^
- e; s- t6 F5 Hupstream monitor_server {: _9 n+ s% ]2 D7 M# W; q" x
server 192.168.0.131:80;
; d8 ` D& V4 m' ? server 192.168.0.132:80;
3 \* q7 N9 C6 P9 J}
- w" V/ ?3 I- q% o% \6 I6 Z$ [# Y
3 k/ j% ~3 m4 O& O' Q* \5 b" r4 ~server
* B! U; [& X8 a: j( W: w{9 g7 V+ y# u9 r) U
listen 80;/ s. |3 e5 K$ y# s+ a6 N6 K& B
server_name nagios.xxx123.tk;
1 ^# e* J* i! g; A1 B4 ` location / {9 G5 T+ O! r4 o3 C ^: w
proxy_redirect off;8 C$ S0 k, o5 s
proxy_set_header Host $host;
5 ?. d5 {* A# s. _# I% M proxy_set_header X-Real-IP $remote_addr;
1 n5 o5 R( D1 s) i% Y9 `0 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
* W {5 c9 t: P$ p! H proxy_pass http://monitor_server;
/ D* T0 y4 P( H7 T/ n }. F" L' J$ |% ]0 F9 ?: e: K
access_log logs/nagios.xxx123.tk_access.log;
( m; E+ [+ i- `$ C}4 G: B4 t3 U: c5 |) R. Z
0 {; r7 m" P: C% ~0 I额,关于负载均衡和缓存就不多说了,这里只是要起到一个简单的“域名转发”功能。 另外,由于http请求最后都是由反向代理服务器传递给后段的机器,所以后端的机器原来的访问日志记录的访问IP都是反向代理服务器的IP。 要想能记录真实IP,需要修改后端机器的日志格式,这里假设后端也是一台nginx: 在后端配置文件里面加入这一段即可:1 g8 G4 @( \6 O8 k, m: E0 Q5 [
! ]9 k9 Q. b+ J& |
log_format access '$HTTP_X_REAL_IP - $remote_user [$time_local] "$request" '3 g. ~7 C5 Y' z; }* o; D2 U ^
'$status $body_bytes_sent "$http_referer" '
- C: K8 A$ f( G! R4 J( Q'"$http_user_agent" $HTTP_X_Forwarded_For';1 V! l; I6 H& a# I7 ^' V
$ t4 r( X3 V2 x1 ?access_log logs/access.log access;$ o. \) F& d, j: d' q7 Z: U$ B
# \! ?4 [7 T6 W y- i) B( b5 _; U& T
再看看原来日志的格式长什么样:
. \4 \$ i. R% A9 T3 [* a) d* T4 M' O- k8 G# |
1
D6 `9 x* n, |# r& c25 T3 @8 g! ^( I) l9 M, l- u- X5 u
3* V: o. j$ q; M* j: i" ]
4
3 H8 ?3 k8 z# R" T5
- i) F! }0 w8 {2 m1 X: s#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
( T2 T) d& _# d' e% J7 P! R4 f# '$status $body_bytes_sent "$http_referer" ') [: f% s8 G4 ?
# '"$http_user_agent" "$http_x_forwarded_for"';3 o5 e. l9 J$ x! A* H
1 w; x4 L$ R2 r3 O' z4 Y#access_log logs/access.log main;
( Y4 v! C' p6 f, I$ n看出区别了吧 遇到的问题 之前没配置下面这段,访问时候偶尔会出现504 gateway timeout,由于偶尔出现,所以不太好排查
# [ O2 i1 k# `3 y
/ U8 `0 H# s, w- v( e! n7 L1 P' ^# g3 b, h( p; l! q4 O
22 Y( A, Y, E7 X' }/ k% F; p! Q' s
3
8 k) v2 ]) b7 J8 V' Y45 t; n5 c+ b8 _: s7 c6 b3 k
59 ~) @( t2 G, x5 n f {0 v: H- G
65 [# [& b4 g. U/ U# k
7: s0 d* U: x' U! b w
8
3 J+ a0 ^* q/ A3 |proxy_connect_timeout 300s;( g3 w9 y& \9 ]
proxy_read_timeout 300s;
" @, g! ?8 H, t& x/ V' sproxy_send_timeout 300s;
0 ~0 u: y- `4 jproxy_buffer_size 64k;
$ [- c7 l- j' Z, @7 \6 Gproxy_buffers 4 32k;
3 f2 s6 ?* G& O4 s8 Tproxy_busy_buffers_size 64k;7 D) |4 b+ ~7 b) k* a9 k! z
proxy_temp_file_write_size 64k;
, i$ C K7 O) C' u! dproxy_ignore_client_abort on;: Q* Y$ n+ w/ E. H' j9 |! g3 ]
报错日志:' @$ m% p2 m; O W/ x
! R: u7 e; R: ], |+ u5 ]...upstream timed out (110: Connection timed out) while reading response header from upstream, client: ...(后面的省略) 从日志看来是连接超时了,网上一通乱查之后估计可能是后端服务器响应超时了,本着大胆假设,小心求证的原则,既然假设了错误原因就要做实验重现错误:那就调整代理超时参数,反过来把代理超时阀值设小(比如1ms)看会不会次次出现504。后来发现把proxy_read_timeout 这个参数设置成1ms的时候,每次访问都出现504。于是把这个参数调大,加入上面那段配置,解决问题了。
- l/ Q1 ^0 z- k* p9 K* {, m9 X9 Y
PS:关于域名转发( k$ g" K8 I' N" G3 t) c
- _0 h; q' J3 q9 _3 k8 J
所谓域名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/ 的内容。
8 c2 I6 K5 R, ?* {3 a/ d7 J |
|