nginx反向代理的实现方法有三种,分别是:ngx_http_proxy_module、ngx_http_upstream_module、ngx_http_fastcgi_module。


ngx_http_proxy_module


ngx_http_proxy_module反向代理的简单实现:

        在两台机器上,分别装上nginx启动好并且都能够正常访问后,将其中一台主机作为方向代理主机,如 192.168.96.130 进行如下配置,在server中的proxy_pass 的后面填上另一台主机的访问地址http://192.168.96.132,这台主机是真正提供服务的主机。

        location / {

            proxy_pass http://192.168.96.132;

        }

        配置好后将192.168.96.130的主机进行重启或重载,然后访问192.168.96.130主机,这样就配置好了简单的反向代理。


实现部分页面代理:

        将部分请求地址进行代理,默认的地址还是通过本地进行访问,如:将 http://192.168.96.130/forum 的地址方向代理到 http://192.168.96.132/bbs/  这个地址上,配置方法如下,将192.168.96.130主机上的nginx进行如下配置:

        location / {

            root /usr/share/nginx/html;

            index index.html index.htm;

        }

        location /forum/ {

            proxy_pass http://192.168.96.132/bbs/;

        }

        在服务主机192.168.96.132 上,在文档目录下添加 bbs目录,并创建index.html 默认文件,配置好后使用nginx -t 检查语法,然后使用 nginx -s reload 进行重载即可。然后访问地址 http://192.168.96.130/forum这个地址就被反向代理到了 http://192.168.96.132/bbs/ 这个地址,而访问默认地址http://192.168.96.130则显示这个主机本地的页面。


将特定格式的请求代理:

        location ~* \.(jpg|png|gif|jpeg)$ {

           proxy_pass http://192.168.96.132;

        }

        配置中location后面的 ~* 这个代表不区分大小写的匹配模式,后面的是正则表达式,当使用模式时被代理的地址不能有路径。也就是说将这些图片结尾的文件请求都代理到proxy_pass 后面的这个请求中去。这个地址http://192.168.96.132  后面不能带有其他的目录,请求过来的地址都会追加到这个设定的地址后面,比如请求http://192.168.96.130/1.jpg,这个地址中的1.jpg会被追加到 http://192.168.96.132后面,变为http://192.168.96.132/1.jpg。请求的地址也可以是动态页面.php或.jsp等。


将客户端的信息发送到real server中:

代理服务器:

        location /forum/ {

            proxy_pass http://192.168.96.132/bbs/;

            proxy_set_header Host $host;

            proxy_set_header real_ip $remote_addr;

        }

read server中:

        将nginx.conf中的log_format记录日志项后面加上一个$http_real_ip 来记录客户端的真正IP地址,自定义header头要加上“http_”,设置好后重新加载配置,再访问几次页面,然后在real server的访问日志/var/log/nginx/access.log中就可以看到自定义的真正的客户端IP地址。

        在后端的real server中接受到的是代理服务器发送过来的请求,所以请求的头信息都是代理服务器的,对于记录这些请求信息记录在日志中没有意义,所以要将真正的请求清新发送到real server中,这样real server记录的日志信息才是有意义的。


nginx缓存:

        开启缓存:在配置文件中的http内添加如下内容:

proxy_cache_path /cache/nginx/ levels=1:1 keys_zone=mycache:32m;

        其中/cache/nginx/目录是缓存文件所在的目录,这个目录属主必须是运行nginx的用户,evels=1:1表示缓存的一级子目录和二级子目录的字符个数。keys_zone=mycache:32m;表示缓存文件的key的名称和所用内存空间的大小,其他值使用默认即可。修改好配置后创建目录,并使用chown -R nginx:nginx /cache/nginx修改目录属主属组。然后在location中定义具体的缓存细节,不需要缓存的就不定义。

        location /forum/ {

            proxy_cache mycache;

            proxy_cache_valid 200 1d;

            proxy_cache_valid 301 302 10m;

            proxy_cache_valid any 1m;

            proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;

            proxy_pass http://192.168.96.132/bbs/;

            proxy_set_header Host $host;

            proxy_set_header real_ip $remote_addr;

        }

        配置好后检查语法错误并重载。再访问定义缓存的页面,然后在/cache/nginx目录中就可以看到生成的缓存文件了 6/3/cb28183652614d3fdade42d5539caa36,此时即使修改源数据访问的数据任然是缓存中的。

其他选项:

        proxy_connect_timeout:由代理服务发送请求到后端服务的超时时长。

        proxy_hide_header:隐藏由proxy响应给客户端时指定的首部。

        详细资料见:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_valid


ngx_http_upstream_module


ngx_http_upstream_module模块的反向代理:

        upstream可以将多个主机组成一个组,然后在配置中定义组的名称。upstrean只能定义在配置段的http中。首先要有三台主机,两台作为real server,一台作为代理服务,都能正常访问后再在代理服务器的配置文件中的http内定义如下内容:

        upstream upservers{

            server 192.168.96.132;

            server 192.168.96.134;

        }

        在location中加上proxy_pass http://upstream/;这一段,注意upstream是上面定义的服务器的组名称,后面不能连接端口之类的符号。

        location /forum/ {

            proxy_pass http://upservers/;

            proxy_set_header Host $host;

            proxy_set_header real_ip $remote_addr;

        }

        location ~* \.(jpg|png|gif|jpeg)$ {

            proxy_pass http://upservers;

            proxy_set_header Host $host;

            proxy_set_header real_ip $remote_addr;

        }

        将两台服务器的页面内容写成不一样的,这样可以看到效果,配置好后检查配置文件并重载,再访问代理服务器的IP地址,这样每次刷新都能看到不同的real server来响应。


为每个server定义权重:

        upstream upservers{

            server 192.168.96.132 weight=2;

            server 192.168.96.134;

        }

        这样权重高的服务就可以接收更多的请求。


将客户端请求固定到某个server上:

        upstream upservers{

            ip_hash;

            server 192.168.96.132 weight=2;

            server 192.168.96.134;

        }

        只要在配置项中加上ip_hash即可。


连接失败断开服务:

        当连接real server失败时会尝试重新连接,当连接达到一定次数时就认定为真正的连接失败,就将这台服务从服务器表中剔除。有两个配置项:

        fail_timeout=time        连接多长时间认定为失败

        max_fils=number         尝试连接多少次认定为失败

        upstream upservers{

            server 192.168.96.132 max_fails=2 fail_timeout=1;

            server 192.168.96.134 max_fails=2 fail_timeout=1;

        }

        配置访问测试正常后,将其中一台real server关闭,这样宕机的服务器就不会被调度到。


将一台主机作为备用:

        upstream upservers{

            server 192.168.96.132;

            server 192.168.96.134 backup;

        }

        当正常访问时只有132这台主机响应服务,但当132这台主机宕机后134这台主机就会响应请求。


基于sticky实现session绑定:

        cookie:将相同的cookie发往相同的real server

        route:将路由信息发给客户端,客户端请求时带着该路由信息

        lean:测试阶段,稳定版不支持


        在upstream中添加sticky即可:sticky cookie。

        upstream backend {

             server backend1.example.com;

            server backend2.example.com;

            sticky cookie srv_id expires=1h domain=.example.com path=/;

        }

还有least_conn等调度方法等。

详细资料参考:http://nginx.org/en/docs/http/ngx_http_upstream_module.html#sticky


自定义响应报文首部:

        自定义响应报文首部可以判别是缓存中返回的数据还是后端的upstream响应的。这个功能是由ngx_http_headers_module模块提供的,可以在代理服务器响应给客户端时的首部添加自定义header,这个自定义header可以设置在http,server,location中,这个header和proxy_set_header不一样,set header是设置给后端real server的请求头,这个是add header是响应给客户端的。设置方法是在上面所说的任意位置添加如下:

        add_header x-via $server_addr;        其中$server_addr是系统变量,是当前代理服务器的IP。

        查看是否命中缓存:

        自定义响应报文头部可以查看很多信息,可以在头部添加是否命中缓存的信息,这样可以查看到当前的请求是从缓存中读取的还是直接响应的,设置方法如下:

        先打开缓存功能,具体设置参考上面的“nginx缓存”,然后添加如下header头:

        add_header X-Cache $upstream_cache_status;        后面的这个变量信息代表是否命中缓存

        配置好后在浏览器端访问代理服务器,然后查看header信息,在header信息中就可以看到刚才设置的两个自定义header头信息,如下:

  1. X-Cache: HIT        MISS表示没有命中,HIT表示命中缓存

  2. X-Via: 192.168.96.130

详细资料见:http://nginx.org/en/docs/http/ngx_http_upstream_module.html


ngx_http_fastcgi_module


ngx_http_fastcgi_module模块反向代理:

        使用的是fastcgi协议,LNMP只能以这种方式运行,php以fpm方式工作,nginx将动态内容发送给php处理完成后返回给nginx,nginx再将结果封装返回给客户端。

        安装php-fpm:

        在yum源里面有php-fpm的rpm包,可以直接安装,使用命令yum list all *fpm*可以看到有php-fpm,直接安装即可yum install php-fpm,安装好后可以直接启动。php-fpm监听在9000端口。

        配置nginx支持php-fpm:

        location ~ \.php$ {

            root     /usr/share/nginx/html;     网页文件位置

            fastcgi_pass  127.0.0.1:9000;        php-fpm的监听地址

            fastcgi_index index.php;               主页文件位置

            fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;        传递的参数

            include       fastcgi_params;          包含的另一个文件

        }

        fastcgi_params这个文件中包含向php-fpm传递的各种参数,包括地、端口、url等等各种信息。修改后就可以检查配置并重载配置文件,如果访问不了可能是fastcgi_params这个文件的顺序有点问题,改成如下顺序就可以了:

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;

fastcgi_param  SERVER_SOFTWARE    nginx;

fastcgi_param  QUERY_STRING       $query_string;

fastcgi_param  REQUEST_METHOD     $request_method;

fastcgi_param  CONTENT_TYPE       $content_type;

fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;

fastcgi_param  REQUEST_URI        $request_uri;

fastcgi_param  DOCUMENT_URI       $document_uri;

fastcgi_param  DOCUMENT_ROOT      $document_root;

fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  REQUEST_SCHEME     $scheme;

fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  REMOTE_ADDR        $remote_addr;

fastcgi_param  REMOTE_PORT        $remote_port;

fastcgi_param  SERVER_ADDR        $server_addr;

fastcgi_param  SERVER_PORT        $server_port;

fastcgi_param  SERVER_NAME        $server_name;

fastcgi_param  REDIRECT_STATUS    200;

        还有一点,默认的主页文件中要添加index.php,这样就可以识别php主页。

        index index.php index.html index.htm;


php-fpm与mysql/mariadb连接工作:

        首先为php-fpm安装mysql模块,yum install php-mysql,安装好后重启php-fpm,然后到phpinfo()页面中查看“Additional .ini files parsed”这一项,看是否会去加载mysql.ini文件,如果可以然后安装mysql数据库,yum install mysql-mariadb。安装好后启动mariadb,看看3306端口是否启动,然后到index.php目录中连接数据库:

        $conn = mysql_connect('127.0.0.1','',''); 

        var_dump($conn);

        测试是否可以连接,这样LNMP就搭建完成了。


fastcgi的缓存:

        同上面的设置基本,只是使用的指令不同,在http配置段中的一些配置:

        fastcgi_cache_path /cache/fastcgi/ levels=1:1 keys_zone=mycache2:32m inactive=3 max_size=1g;

        在location中的一些配置:在fastcgi_cache mycache2;这一段中这个mycache2是上面设置的名称。

        location ~ \.php$ {

            root /usr/share/nginx/html;

            fastcgi_pass  127.0.0.1:9000;

            fastcgi_cache mycache2;

            fastcgi_cache_valid 200 1d;

            fastcgi_cache_valid 301 302 10m;

            fastcgi_cache_valid any 1m;

            fastcgi_cache_key   $uri;

            fastcgi_index index.php;

            fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;

            include       fastcgi_params;

        }