61阅读

nginx配置-Linux VPS上配置Nginx反向代理的方法

发布时间:2018-05-13 所属栏目:nginx 配置

一 : Linux VPS上配置Nginx反向代理的方法

反向代理是什么?

反向代理指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部(或其他)网络上的服务器,并将从服务器上得到的结果返回给Internet上请求连接的客户端。

实现方法:

比如我想在VPS上建一个t.61k.com的域名用来反向代理访问twitter,首先在域名注册商那里的域名管理上为域名t.vpser.net添加A记录到VPS的IP上,再在VPS上修改Nginx的配置文件,添加如下:


server
{
listen 80;
server_name t.61k.com;
location / {
proxy_pass http://twitter.com/;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}


添加好后,先执行:/usr/local/nginx/sbin/nginx -t 检查配置是否正常,如果显示:the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok configuration file /usr/local/nginx/conf/nginx.conf test is successful 则正常,否则按错误提示修改配置。

再执行 kill -HUP `cat /usr/local/nginx/logs/nginx.pid` 使配置生效,域名解析生效后就可以通过t.vpser.net 访问twitter了。

二 : nginx配置技巧汇总

本文记录了一些nginx作为反向代理和文件服务器的配置技巧和解决方案,原文会持续更新

Nginx作为文件服务

避免浏览器自动播放文件

有时对于图片、视频,浏览器会视能力,自动为用户显示或播放。[www.61k.com]这主要是由于Web服务器在返回文件本身数据的同时,返回了一些特殊的MIME类型,比如:image/jpeg(JPEG图像),application/pdf(PDF文档),video/mpeg(MPEG动画)。这些MIMIE类型实际上是告诉浏览器,文件数据到底是什么,这样浏览器就能更好的为用户展示数据。现在像图片、pdf、甚至是视频基本都是可以直接在浏览器中展示和播放的。但是有时,我们需要浏览器为用户下载文件而不是直接播放,而Nginx在默认配置下,会根据文件的后缀来匹配相应的MIME类型,并写入Response header,导致浏览器播放文件而不是下载,这时需要通过配置让Nginx返回的MIME类型为下面这个类型:

application/octet-stream

这个类型会让浏览器认为响应是普通的文件流,并提示用户下载文件。可以通过在Nginx的配置文件中做如下配置达到这样的目的:

location /download/ { types { } default_type application/octet-stream;}

这样当Url路径中包含/download/时,MIME类型会被重置为application/octet-stream。另外,nginx自带的MIME类型映射表保存在conf/mime.types中。

文件上传大小限制放开

有的时候后端的Web-Server提供文件上传的服务,但是如果前端使用Nginx做反向代理时,会出现文件无法上传的问题,这可能是由于Ngxin默认对客户端请求的body的限制。因为,默认情况下Nginx对客户端请求的大小限制是1m,而上传的文件往往超过1m。可以通过修改如下配置项,来放宽这个限制:

client_max_body_size 10m;

将这个值设置为0,可以取消这个限制。这个配置项可以用在http,server,location配置节中。详见client_max_body_size

下载文件重命名

通常情况下,为了保证用户上传的文件在服务器的文件系统中不至于重名,一般会将文件名修改成guid后保存,并在数据库中保持guid与文件名的映射。此时,如果使用Nginx来提供对这些用户文件的下载功能的话,文件下载到用户浏览器,会以文件的guid名作为文件名,这显然是用户不想看到的。可以考虑用这个方案。
假设我们有一个文件的原始文件名为test.txt,对应的guid文件名是21EC2020-3AEA-1069-A2DD-08002B30309D.txt,文件的虚拟路径是/download/

使用服务器端编程语言,在输出的html中使用如下链接提供文件的下载:

<a href="/download/21EC2020-3AEA-1069-A2DD-08002B30309D.txt?n=test.txt" target='_blank'>下载test.txt</a>

可以看到,将原始文件名以QueryString的方式带在请求中,这样可以在Nginx端,利用$arg_name变量来取到这个QueryString的值,从而重写response header:

add_header Content-Disposition "attachment; filename=$arg_n";

这会在response header中加入如下键值:

Content-Disposition: "attachment; filename=test.txt";

经测试,无论是IE还是Chrome都可以支持这个header。

关于Content-Disposition,详见这里

关于Nginx的标准http模块的嵌入变量,详见这里

Nginx作为反向代理

一个IP多个域名

如果只有一个公网IP,但是网站功能需要划分为多个不同的子网站或者子域名,可以用Nginx来搭建反向代理来“复用”IP资源。假设有如下几个域名都是abc.com这个主域的:

www.abc.comimage.abc.comvideo.abc.com

1. 首先在DNS出注册这3个域名同时指向同一个IP,Nginx作为前端的web服务器,让所有访问这个IP地址80端口的请求全部指向Nginx
2. 然后,配置Nginx,根据域名将请求转发转发给内网的上游服务器,例如下面的配置:

server {listen 80;server_name www.abc.com;location / {proxy_pass http://192.168.1.100;} }server {listen 80;server_name image.abc.com;location / {alias /var/www/image;} }server {listen 80;server_name video.abc.com;location / {proxy_pass http://192.168.1.100:8081/video;} }

在上述配置中,将三个域名分发给了不同的模块处理:

  1. www.abc.com分发给上游的http://192.168.1.100服务器处理
  2. image.abc.com则直接映射到了Nginx本机的一个目录
  3. video.abc.com分发给上游的http://192.168.1.100:8081/video服务器处理(video是上游web-server的某虚拟目录)

上游服务器超时

Nginx作为反向代理的时候,如果上游服务器处理时间过长的话,有时会返回504网关超时,从nginx的错误日志看出如果是upstream timed out,就表示是上游服务器处理时间过长,Nginx认为服务超时。Nginx在请求上游服务器时默认的超时时间为1分钟,可以通过调整proxy_read_timeout属性增加这个超时时间

proxy_read_timeout 180s;

三 : Nginx的accept_mutex配置分析

通常多数人不会注意Nginx的accept_mutex配置,不过实际上它对系统的吞吐量有一定的影响,今天生物钟紊乱睡不着觉,索性闲扯一下Nginx的accept_mutex配置。

让我们看看accept_mutex的意义:当一个新连接到达时,如果激活了accept_mutex,那么多个Worker将以串行方式来处理,其中有一个Worker会被唤醒,其他的Worker继续保持休眠状态;如果没有激活accept_mutex,那么所有的Worker都会被唤醒,不过只有一个Worker能获取新连接,其它的Worker会重新进入休眠状态,这就是「惊群问题」。

Nginx缺省激活了accept_mutex,也就是说不会有惊群问题,但真的有那么严重么?实际上Nginx作者Igor Sysoev曾经给过相关的解释:

OS may wake all processes waiting on accept() and select(), this is called thundering herd problem. This is a problem if you have a lot of workers as in Apache (hundreds and more), but this insensible if you have just several workers as nginx usually has. Therefore turning accept_mutex off is as scheduling incoming connection by OS via select/kqueue/epoll/etc (but not accept()).

简单点说:Apache动辄就会启动成百上千的进程,如果发生惊群问题的话,影响相对较大;但是对Nginx而言,一般来说,worker_processes会设置成CPU个数,所以最多也就几十个,即便发生惊群问题的话,影响相对也较小。

假设你养了一百只小鸡,现在你有一粒粮食,那么有两种喂食方法:

  • 你把这粒粮食直接扔到小鸡中间,一百只小鸡一起上来抢,最终只有一只小鸡能得手,其它九十九只小鸡只能铩羽而归。这就相当于关闭了accept_mutex。
  • 你主动抓一只小鸡过来,把这粒粮食塞到它嘴里,其它九十九只小鸡对此浑然不知,该睡觉睡觉。这就相当于激活了accept_mutex。

可以看到此场景下,激活accept_mutex相对更好一些,让我们修改一下问题的场景,我不再只有一粒粮食,而是一盆粮食,怎么办?

此时如果仍然采用主动抓小鸡过来塞粮食的做法就太低效了,一盆粮食不知何年何月才能喂完,大家可以设想一下几十只小鸡排队等着喂食时那种翘首以盼的情景。此时更好的方法是把这盆粮食直接撒到小鸡中间,让它们自己去抢,虽然这可能会造成一定程度的混乱,但是整体的效率无疑大大增强了。

Nginx缺省激活了accept_mutex,是一种保守的选择。如果关闭了它,可能会引起一定程度的惊群问题,表现为上下文切换增多(sar -w)或者负载上升,但是如果你的网站访问量比较大,为了系统的吞吐量,我还是建议大家关闭它。

四 : 一个nginx转发多个域名配置

#user nobody;

worker_processes 1;

#error_log logs/error.log;

#error_log logs/error.log notice;

#error_log logs/error.log info;

#pid logs/nginx.pid;

events {

worker_connections 1024;

}

http {

includemime.types;

default_type application/octet-stream;

#log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"';

#access_log logs/access.log main;

sendfile on;

#tcp_nopush on;

#keepalive_timeout 0;

keepalive_timeout 65;

gzip on;

#web_server是一个服务,指向119的80端口

upstreamweb_server {

#ip_hash;

server 192.168.101.119:80 max_fails=2 fail_timeout=30s;

#server x.x.x.x:8080 max_fails=2 fail_timeout=30s;

}

server {

listen 80;

server_namea1.test.com;#不同的域名配置

index index.html index.htm;

root /home/www/ROOT;

域名转发 一个nginx转发多个域名配置

location / {

proxy_next_upstream http_502 http_504 error timeout invalid_header;

proxy_pass http://web_server;#这里要配置成upstream的“web_server” proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

break;

}

}

#web_server1是另一个服务,指向123的80端口

upstream web_server1 {

#ip_hash;

server 192.168.101.123:80 max_fails=2 fail_timeout=30s;

#server x.x.x.x:8080 max_fails=2 fail_timeout=30s;

}

server {

listen 80;

server_namea2.teset.com;#不同的域名配置

index index.html index.htm;

root /home/www/ROOT;

location / {

proxy_next_upstream http_502 http_504 error timeout invalid_header;

proxy_pass http://web_server1;#这里要配置成upstream的“web_server1” proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

break;

}

}

}

注意:每多配置一个服务,需要添加对应的upstream和server。[www.61k.com]

五 : Nginx多Server反向代理配置

Nginx强大的正则表达式支持,可以使server_name的配置变得很灵活,如果你要做多用户博客,那么每个用户拥有自己的二级域名也就很容易实现了。

下面我就来说说server_name的使用吧:

server_name的匹配顺序

Nginx中的server_name指令主要用于配置基于名称虚拟主机,server_name指令在接到请求后的匹配顺序分别为:

1、准确的server_name匹配,例如:

  1. server{
  2. listen80;
  3. server_namessdr.infowww.ssdr.info;
  4. ...
  5. }

2、以*通配符开始的字符串:

  1. server{
  2. listen80;
  3. server_name*.ssdr.info;
  4. ...
  5. }

3、以*通配符结束的字符串:

  1. server{
  2. listen80;
  3. server_namewww.*;
  4. ...
  5. }

4、匹配正则表达式:

  1. server{
  2. listen80;
  3. server_name~^(?.+)\.howtocn\.org$;
  4. ...
  5. }

Nginx将按照1,2,3,4的顺序对server name进行匹配,只有有一项匹配以后就会停止搜索,所以我们在使用这个指令的时候一定要分清楚它的匹配顺序(类似于location指令)。

server_name指令一项很实用的功能便是可以在使用正则表达式的捕获功能,这样可以尽量精简配置文件,毕竟太长的配置文件日常维护也很不方便。下面是2个具体的应用:

在一个server块中配置多个站点:

  1. server
  2. {
  3. listen80;
  4. server_name~^(www\.)?(.+)$;
  5. indexindex.phpindex.html;
  6. root/data/wwwsite/$2;
  7. }

站点的主目录应该类似于这样的结构:

  1. /data/wwwsite/ssdr.info
  2. /data/wwwsite/linuxtone.org
  3. /data/wwwsite/baidu.com
  4. /data/wwwsite/google.com

这样就可以只使用一个server块来完成多个站点的配置。

在一个server块中为一个站点配置多个二级域名 。

实际网站目录结构中我们通常会为站点的二级域名独立创建一个目录,同样我们可以使用正则的捕获来实现在一个server块中配置多个二级域名:

  1. server
  2. {
  3. listen80;
  4. server_name~^(.+)?\.howtocn\.org$;
  5. indexindex.html;
  6. if($host=ssdr.info){
  7. rewrite^http://www.ssdr.infopermanent;
  8. }
  9. root/data/wwwsite/ssdr.info/$1/;
  10. }

站点的目录结构应该如下:

  1. /data/wwwsite/ssdr.info/www/
  2. /data/wwwsite/ssdr.info/nginx/

这样访问www.ssdr.info时root目录为/data/wwwsite/ssdr.info/www/,nginx.ssdr.info时为/data/wwwsite/ssdr.info/nginx/,以此类推。

后面if语句的作用是将ssdr.info的方位重定向到www.ssdr.info,这样既解决了网站的主目录访问,又可以增加seo中对www.ssdr.info的域名权重。

多个正则表达式

如果你在server_name中用了正则,而下面的location字段又使用了正则匹配,这样将无法使用$1,$2这样的引用,解决方法是通过set指令将其赋值给一个命名的变量:

  1. server
  2. {
  3. listen80;
  4. server_name~^(.+)?\.howtocn\.org$;
  5. set$www_root$1;
  6. root/data/wwwsite/ssdr.info/$www_root/;
  7. location~.*\.php?${
  8. fastcgi_pass127.0.0.1:9000;
  9. fastcgi_indexindex.php;
  10. fastcgi_paramSCRIPT_FILENAME/data/wwwsite/ssdr.info/$fastcgi_script_name;
  11. includefastcgi_params;
  12. }
  13. }

Nginx不同域名反向代理到另一台服务器 proxy_pass和$host

想让一个VPS专门做另一个VPS的前端,后端VPS每添加一个域名,前端VPS就要同时添加一个域名来反向代理,作为前端的VPS如果一个一个的添加后端VPS的域名,那么这个事情特别麻烦,能不能让其自动反向代理后端VPS呢,用到proxy_pass和$host就可以轻松实现。

以下例子为了省事,以lnmp为安装环境进行设置

修改前端VPS的nginx.conf文件,修改成以下内容:

  1. server{
  2. listen80;
  3. server_name$host;
  4. location/{
  5. proxy_passhttp://www.31.gd/;
  6. proxy_set_headerHost$host;
  7. proxy_redirectoff;
  8. proxy_set_headerX-Real-IP$remote_addr;
  9. proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;
  10. proxy_connect_timeout60;
  11. proxy_read_timeout600;
  12. proxy_send_timeout600;
  13. }

下面的一并修改吧。

  1. location/.(php|php5)?$
  2. {
  3. fastcgi_passunix:/tmp/php-cgi.sock;
  4. fastcgi_indexindex.php;
  5. includefcgi.conf;
  6. }
  7. location/status{
  8. stub_statuson;
  9. access_logoff;
  10. }
  11. location/.(gif|jpg|jpeg|png|bmp|swf)$
  12. {
  13. expires30d;
  14. }
  15. location/.(js|css)?$
  16. {
  17. expires12h;
  18. }

这样就可以实现了前端VPS可以反向代理任意域名到后端VPS,只要将域名解析到前端VPS,后端VPS进行域名绑定,那么就可以直接访问到了

一台nginx带多个域名多个tomcat情况的配置

多个域名,其中2个域名需支持泛域名解析:

1、www.abc.com

2、www.bcd.com

3、*.efg.com

4、*.hij.com

其中1,2,3为一台tomcat,4为独立tomcat。前端一台nginx,通过配置多个虚拟主机来实现该部署。

进入/etc/nginx/conf.d目录,所有虚拟主机的配置文件都在该目录下存放,配置。

配置支持泛域名

  1. #
  2. #AvirtualhostusingmixofIP-,name-,andport-basedconfiguration
  3. #
  4. server{
  5. listen81;
  6. server_name*.efg.com;
  7. location/{
  8. proxy_passhttp://localhost:8080;
  9. proxy_set_headerHost$host;
  10. proxy_set_headerX-Real-IP$remote_addr;
  11. proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;
  12. }
  13. }
  14. #
  15. #AvirtualhostusingmixofIP-,name-,andport-basedconfiguration
  16. #
  17. server{
  18. listen81;
  19. server_name*.hij.com;
  20. location/{
  21. proxy_passhttp://localhost:8081;
  22. proxy_set_headerHost$host;
  23. proxy_set_headerX-Real-IP$remote_addr;
  24. proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;
  25. }
  26. }

泛域名解析关键为红色部分,如果没有红色部分,后端8080及8081口对应的tomcat虚拟主机将无法获得域名信息,导致后端tomcat无法获取到对应的域名信息。

后端TOMCAT支持泛域名解析时,需要设置 host name 为 localhost 以支持泛域名指向。

Nginx 多域名配置

nginx绑定多个域名可又把多个域名规则写一个配置文件里,也可又分别建立多个域名配置文件,我一般为了管理方便,每个域名建一个文件,有些同类域名也可又写在一个总的配置文件里。

一、每个域名一个文件的写法

首先打开 nginx域名配置文件存放目录:/usr/local/nginx/conf/servers ,如要绑定域名www.web126.com 则在此目录建一个文件:www.web126.com.conf 然后在此文件中写规则,如:

  1. server
  2. {
  3. listen80;
  4. server_namewww.web126.com;#绑定域名
  5. indexindex.htmindex.htmlindex.php;#默认文件
  6. root/home/www/web126.com;#网站根目录
  7. includelocation.conf;#调用其他规则,也可去除
  8. }

然后重起nginx服务器,域名就绑定成功了。

Nginx服务器重起命令:/etc/init.d/nginx restart。

二、一个文件多个域名的写法

一个文件添加多个域名的规则也是一样,只要把上面单个域名重复写下来就ok了,如:

  1. server
  2. {
  3. listen80;
  4. server_namewww.web126.com;#绑定域名
  5. indexindex.htmindex.htmlindex.php;#默认文件
  6. root/home/www/web126.com;#网站根目录
  7. includelocation.conf;#调用其他规则,也可去除
  8. }
  9. server
  10. {
  11. listen80;
  12. server_namemsn.web126.com;#绑定域名
  13. indexindex.htmindex.htmlindex.php;#默认文件
  14. root/home/www/msn.web126.com;#网站根目录
  15. includelocation.conf;#调用其他规则,也可去除
  16. }

三、不带www的域名加301跳转

如果不带www的域名要加301跳转,那也是和绑定域名一样,先绑定不带www的域名,只是不用写网站目录,而是进行301跳转,如:

  1. server
  2. {
  3. listen80;
  4. server_nameweb126.com;
  5. rewrite^/(.*)http://www.web126.com/$1permanent;
  6. }

四、添加404网页

添加404网页,都可又直接在里面添加,如:

  1. server
  2. {
  3. listen80;
  4. server_namewww.web126.com;#绑定域名
  5. indexindex.htmindex.htmlindex.php;#默认文件
  6. root/home/www/web126.com;#网站根目录
  7. includelocation.conf;#调用其他规则,也可去除
  8. error_page404/404.html;
  9. }

最后还有一个方法需要注意,可能有需要禁止IP直接访问80端口或者禁止非本站的域名绑定我们的IP,这样的话应该

如下处理,放到最前一个server上面即可:

  1. server{
  2. listen80default;
  3. server_name_;
  4. return403;
  5. }

学会上面四种规则方法,基本就可以自己独立解决nginx 多域名配置问题了。

本文标题:nginx配置-Linux VPS上配置Nginx反向代理的方法
本文地址: http://www.61k.com/1200083.html

61阅读| 精彩专题| 最新文章| 热门文章| 苏ICP备13036349号-1