概述什么是Nginx?Nginx(enginex)是一个轻量级的网络服务器、反向代理服务器和电子邮件(IMAP/POP3)代理服务器。什么是反向代理?反向代理(ReverseProxy)模式是指代理服务器接受互联网上的连接请求,然后将请求转发给内网服务器,并将服务器得到的结果返回给互联网上请求连接的客户端,在此时,代理服务器对外充当反向代理服务器。nginx的使用比较简单,几条命令就可以了。常用命令如下:nginx-sstop快速关闭Nginx,可能不保存相关信息,快速终止web服务。nginx-squit顺利关闭Nginx,保存相关信息,有序结束web服务。nginx-sreload重载是因为它改变了Nginx相关配置,需要重新加载配置。nginx-sreopen重新打开日志文件。nginx-cfilename指定一个Nginx的配置文件来替换默认的。nginx-t不运行,只测试配置文件。nginx会检查配置文件的语法是否正确,并尝试打开配置文件中引用的文件。nginx-v显示nginx的版本。nginx-V显示nginx版本、编译器版本和配置参数。如果不想每次都敲命令,可以在nginx安装目录下添加一个启动批处理文件startup.bat,双击运行。内容如下:@echooffrem如果启动过nginx,启动前记录pid文件,会kill指定进程nginx.exe-sstoprem测试配置文件nginx.exe-t-cconf/nginx的语法正确性。confrem显示版本信息nginx.exe-vrem根据指定的配置启动nginxnginx.exe-cconf/nginx.conf如果是在linux下运行,写一个shell脚本,大同小异。Nginx配置实践我一直认为各种开发工具的配置应该结合实战来描述,这样会更容易让人理解。先实现一个小目标:不管配置复杂,只完成一个http反向代理。nginx.conf配置文件如下:注意:conf/nginx.conf是nginx的默认配置文件。也可以使用nginx-c指定你的配置文件#Runuser#usersomebody;#启动进程,一般设置为等于cpu个数worker_processes1;#全局错误日志error_logD:/Tools/nginx-1.10.1/logs/error.log;error_logD:/Tools/nginx-1.10.1/logs/notice.lognotice;error_logD:/Tools/nginx-1.10.1/logs/info.loginfo;#PID文件,记录本进程的进程IDpidD当前启动的nginx:/Tools/nginx-1.10.1/logs/nginx.pid;#工作模式和连接限制事件{worker_connections1024;#单个后台workerprocess进程的最大并发连接数}#设置http服务器并使用它的反向代理功能提供负载均衡支持http{#设置mime类型(邮件支持类型),类型由mime.types文件定义includeD:/Tools/nginx-1.10.1/conf/mime.types;default_typeapplication/八位字节流;#settingloglog_formatmain'[$remote_addr]-[$remote_user][$time_local]"$request"''$status$body_bytes_sent"$http_referer"''"$http_user_agent""$http_x_forwarded_for"';access_logD:/Tools/nginx-1.10.1/logs/access.logmain;rewrite_logon;#sendfile指令指定nginx是否调用sendfile函数(zerocopy方式)输出文件。对于普通应用,#必须设置为on。如果用于下载等应用,磁盘IO重负载应用,可以设置为off,以平衡磁盘和网络I/O处理速度,减少系统正常运行时间。sendfileon;#tcp_nopushon;#Connectiontimeoutkeepalive_timeout120;tcp_nodelayon;#gzip压缩开关#gzipon;#设置实际服务器列表upstreamzp_server1{server127.0.0.1:8089;}#HTTP服务器server{#监听80端口,80端口是众所周知的端口号,用于HTTP协议listen80;#定义使用www.xx.com访问server_namewww.helloworld.com;#Homeindexindex.html#指向webapp目录rootD:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp;#编码格式charsetutf-8;#代理配置参数proxy_connect_timeout180;proxy_send_timeout180;proxy_read_timeout180;proxy_set_headerHost$host;proxy_set_headerX-Forwarder-For$remote_addr;#反向代理的路径(与upstream绑定),设置映射路径location后location/{proxy_passhttp://zp_server1;}#静态文件,nginx自己处理location~^/(images|javascript|js|css|flash|media|static)/{rootD:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp\views;#过期30天,静态文件更新不多,过期时间可以设置大一些,如果经常更新,可以设置小一点expires30d;}#设置查看Nginx状态的地址location/NginxStatus{stub_statuson;access_logon;auth_basic"NginxStatus";auth_basic_user_fileconf/htpasswd;}#禁止访问.htxxx文件location~/\.ht{denyall;}#错误处理页面(可选配置)#error_page404/404.html;#error_page500502503504/50x.html;#location=/50x.html{#roothtml;#}}}好了,试试看:启动webapp,注意启动绑定了end设置好了,我们试试:启动webapp,注意启动绑定的端口和nginx中upstream设置的端口一致。更改host:在C:\Windows\System32\drivers\etc目录下的host文件中添加一条DNS记录127.0.0.1www.helloworld.com即可启动上一篇中的startup.bat命令访问www.helloworld。com在浏览器中,毫不奇怪,它已经可以访问了。负载平衡配置在前面的例子中,代理只指向一台服务器。但是,在网站的实际运行中,大部分服务器都有多个服务器运行同一个APP。这时候就需要使用负载均衡来分配流量。Nginx也可以实现简单的负载均衡功能。假设这样一个应用场景:将应用部署在Linux环境的三台服务器上,地址为192.168.1.11:80、192.168.1.12:80、192.168.1.13:80。网站域名为www.helloworld.com,公网IP为192.168.1.11。在公网IP所在的服务器上部署nginx,对所有请求进行负载均衡。nginx.conf的配置如下:http{#设置mime类型,由mime.type文件定义include/etc/nginx/mime.types;default_typeapplication/octet-stream;#设置日志格式access_log/var/log/nginx/access.log;#设置负载均衡服务器列表upstreamload_balance_server{#weight参数表示权重值,权重值越高被分配的概率越大server192.168.1.11:80weight=5;server192.168.1.12:80weight=1;server192.168.1.13:80weight=6;}#HTTP服务器server{#监听80端口listen80;#定义www.xx.com访问server_namewww.helloworld.com;#负载均衡allrequestRequestlocation/{root/root;#定义服务器默认网站根目录位置indexindex.htmlindex.htm;#定义首页索引文件名proxy_passhttp://load_balance_server;#请求重定向到服务器列表由load_balance_server定义#以下是一些反向代理配置(可选配置)#proxy_redirectoff;proxy_set_headerHost$host;proxy_set_headerX-Real-IP$remote_addr;#后端Web服务器可以通过X-Forwarded-For获取用户真实IP代理连接超时)proxy_send_timeout90;#后端服务器数据返回时间(代理发送超时)proxy_read_timeout90;#连接成功后,后端服务器响应时间(代理接收超时)proxy_buffer_size4k;#设置代理服务器(nginx)保存用户头信息的缓冲区大小proxy_buffers432k;#proxy_buffers缓冲,一般网页为3如果低于2k,就这样设置proxy_busy_buffers_size64k;#高负载下的缓冲区大小(proxy_buffers*2)proxy_temp_file_write_size64k;#设置缓存文件夹的大小,如果大于这个值,会从上游服务器传过来client_max_body_size10m;#客户端允许的最大单文件字节数client_body_buffer_size128k;#缓冲代理缓冲客户端请求的最大字节数}}}网站有多个webapp配置。当一个网站的功能越来越多时,往往需要将一些功能相对独立的模块分离出来。为了维护这样,通常会有多个webapps。例如:如果www.helloworld.com站点有几个webapps,finance(金融),product(产品),admin(用户中心)。访问这些应用程序的方式是根据上下文区分的:www.helloworld.com/finance/www.helloworld.com/product/www.helloworld.com/admin/我们知道http的默认端口号是80,如果是肯定不可能在一台服务器上同时启动这三个webapp应用,都使用80端口。所以这三个应用需要分别绑定不同的端口号。那么,问题来了。用户在实际访问www.helloworld.com站点时,会访问不同的webapp,并不会访问对应的端口号。因此,同样,您需要使用反向代理来进行处理。配置并不难,我们来看看如何配置:http{#这里省略了一些基本的配置:8083;}server{#这里省略一些基础配置#默认指向productserverlocation/{proxy_passhttp://product_server;}location/product/{proxy_passhttp://product_server;}location/admin/{proxy_passhttp://admin_server;}location/finance/{proxy_passhttp://finance_server;}}}https反向代理配置一些对安全性要求高的站点可能会使用HTTPS(一种使用ssl通信标准的安全HTTP协议)。科普的HTTP协议和SSL标准就不在这里了。但是使用nginx配置https需要知道几点:HTTPS的固定端口号是443,和HTTP的80端口不同,SSL标准需要引入安全证书,所以需要指定证书及其在nginx.conf中的相应键。其他的和http反向代理基本一样,只是在Server部分的配置上有些区别。#HTTPserverserver{#监听443端口。443是知名端口号,主要用于HTTPS协议listen443ssl;#定义使用www.xx.com访问server_namewww.helloworld.com;#ssl证书文件位置(常见证书文件格式:crt/pem)ssl_certificatecert.pem;#ssl证书密钥位置ssl_certificate_keycert.key;#ssl配置参数(可选配置)ssl_session_cacheshared:SSL:1m;ssl_session_timeout5m;#数字签名,这里使用MD5ssl_ciphersHIGH:!aNULL:!MD5;ssl_prefer_server_cipherson;location/{root/root;index.htmlindex.htm;}}静态站点配置有时,我们需要配置静态站点(即html文件和一堆静态资源)。例如:如果所有的静态资源都放在/app/dist目录下,我们只需要在nginx.conf中指定首页和本站的host即可。配置如下:worker_processes1;events{worker_connections1024;}http{includemime.types;default_typeapplication/octet-stream;sendfileon;keepalive_timeout65;gzipon;gzip_typestext/plainapplication/x-javascripttext/cssapplication/xmltext/javascriptapplication/javascriptimage/jpeimgimage/gifgzip_varyon;server{listen80;server_namestatic.zp.cn;location/{root/app/dist;indexindex.html;#Forwardanyrequesttoindex.html}}}然后,在此处添加HOST:127.0.0.1static.zp.cn当您在本地浏览器访问static.zp.cn时,您可以访问静态站点。搭建文件服务器有时候,团队需要对一些数据或资料进行归档,那么文件服务器是必不可少的。使用Nginx可以非常快速方便??的搭建一个简单的文件服务。Nginx中的配置要点:开启autoindex显示目录,默认不开启。打开autoindex_exact_size以显示文件大小。开启autoindex_localtime显示文件的修改时间。root用于设置文件服务打开的根路径。charset设置为charsetutf-8,gbk;,可以避免中文乱码的问题(在windowsserver下设置后,字符还是乱码,暂时没找到解决方法)。一个简化的配置如下:autoindexon;#显示目录autoindex_exact_sizeon;#显示文件大小autoindex_localtimeon;#显示文件时间服务器{charsetutf-8,gbk;#在windowsserver下设置后还是乱码,暂时没有解决办法暂时listen9050default_server;listen[::]:9050default_server;server_name_;root/share/fs;}跨域解决方案在web域的开发中,经常会采用前后端分离的模式。这种模式下,前后端是独立的web应用,例如:后端是Java程序,前端是React或Vue应用。独立的Web应用程序相互访问时,必然会存在跨域问题。解决跨域问题一般有两种方式:1、CORS在后端服务器设置HTTP响应头,在Access-Control-Allow-Origin中添加你需要运行和访问的域名。2、jsonp使用后端根据请求构造json数据并返回,前端使用jsonp跨域。本文不讨论这两种方法。需要注意的是,nginx也提供了基于第一种思路的跨域解决方案。示例:www.helloworld.com网站由一个前端应用程序和一个后端应用程序组成。前端端口号为9000,后端端口号为8080,如果前后端使用http交互,会因为跨域问题导致请求被拒绝。看看nginx是怎么解决的:首先在enable-cors.conf文件中设置cors:#alloworiginlistset$ACAO'*';#setsingleoriginif($http_origin~*(www.helloworld.com)$){set$ACAO$http_origin;}if($cors="trueget"){add_header'Access-Control-Allow-Origin'"$http_origin";add_header'Access-Control-Allow-Credentials''true';add_header'Access-Control-Allow-Methods''GET,POST,OPTIONS';add_header'Access-Control-Allow-Headers''DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-控制,内容类型';}if($request_method='OPTIONS'){set$cors"${cors}options";}if($request_method='GET'){set$cors"${cors}get";}if($request_method='POST'){set$cors"${cors}post";}接下来,在您的服务器中包含enable-cors.conf以引入跨域配置:#--------------------------------------------------#Thisfileisa项目nginx配置片段#可以直接包含在nginxconfig中(推荐)#或者复制到已有的nginx中,自己配置#www.helloworld.com的domainname需要配置dnshosts#其中,api开启cors,需要配合本目录下的另一个配置文件#----------------------------------------------------upstreamfront_server{serverwww.helloworld.com:9000;}upstreamapi_server{serverwww.helloworld.com:8080;}server{listen80;server_namewww.helloworld.com;location~^/api/{includeenable-cors.conf;proxy_passhttp://api_server;rewrite"^/api/(.*)$"/$1break;}location~^/{proxy_passhttp://front_server;}}到这里,就完成了https://github.com/dunwu/nginx-tutorial
