当前位置: 首页 > 科技观察

Nginx从入门到工作,看这篇文章就够了

时间:2023-03-17 13:41:29 科技观察

本文是Nginx的极简教程,旨在帮助新手快速上手Nginx。图片来自PexelsNginx简介什么是Nginx?Nginx(enginex)是一个轻量级的网络服务器、反向代理服务器和电子邮件(IMAP/POP3)代理服务器。什么是反向代理?反向代理(ReverseProxy)方式是指使用代理服务器接受互联网上的连接请求,然后将请求转发给内网的服务器,并将从服务器得到的结果返回给互联网上请求的客户端连接。此时代理服务器对外充当反向代理服务器,如下图:Nginx入门的详细安装方法请参考:https://github.com/dunwu/nginx-tutorial/blob/master/docs/nginx-ops.mdNginx使用比较简单,就几个命令。常用命令如下: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反向代理先实现一个小目标:不管配置复杂,只完成一个HTTP反向代理。nginx.conf配置文件如下:#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文件,记录当前启动的Nginx的进程IDpidD:/Tools/nginx-1.10.1/logs/nginx.pid;#工作模式和连接限制事件{worker_connections1024;#最大并发数connectionsofasinglebackgroundworkerprocessprocess}#设置HTTP服务器,利用其反向代理功能提供负载均衡支持http{#设置mime类型(email支持类型),类型由mime.types文件定义includeD:/Tools/nginx-1.10.1/conf/mime.types;default_typeapplication/octet-stream;#设置日志log_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函数(zerocopymode)输出文件。对于普通应用,#必须设置为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;#}}}注意:conf/nginx.conf是Nginx的默认配置文件。您还可以使用nginx-c指定您的配置文件。好吧,试试看:启动webapp,注意开始绑定的端口要和Nginx中upstream设置的端口保持一致。更改host,在C:\Windows\System32\drivers\etc目录下的host文件中添加一条DNS记录:127.0.0.1www.helloworld.com启动上面的startup.bat命令。在您的浏览器中访问www.helloworld.com,您可以毫无意外地访问它。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;}}负载平衡在前面的例子中,代理只指向一个服务器。但是在网站的实际运行过程中,大部分都是以集群的形式运行的,这时候就需要使用负载均衡来进行流量分配。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,对所有请求进行负载均衡处理(以下示例采用weightedround-robin策略)。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;#Buffer代理缓冲客户端请求的最大字节数}}}负载均衡策略Nginx提供了多种负载均衡策略,让我们一一来看:各种分布式系统中的负载均衡策略基本原理是同样的,如果对原理感兴趣,不妨参考:https://dunwu.github.io/blog/design/theory/load-balance-theory/轮询:upstreambck_testing_01{#所有的默认权重服务器是1server192.168.250。220:8080Server192.168.250.221:8080Server192.168.250.222:8080}加权:upstreambck_testing_011)最少连接:upstreambck_testing_01{least_conn;#withdefaultweightforall(weight=1)server192.168.250.220:8080server192.168.250.221:8080server192.168.250.222:8080}加权最少连接:upstreambck_testing_01:6server.201;{280weight=83server192.168.250.221:8080#defaultweight=1server192.168.250.222:8080#defaultweight=1}IP哈希:upstreambck_testing_01{ip_hash;#withdefaultweightforall(weight=1)server192.168.250.220:8080server192.168.250.221:8080server192.168.250.222:8080}通用哈希:upstreambck_testing_01{hash$request_uri;#withdefaultweight192.016server:8080server.122820.1682server.168.250.222:8080}该网站有多个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;}}}静态站点有时,我们需要配置静态站点(即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,可以避免中文乱码的问题(在windows服务器下设置后,字符还是乱码,暂时没找到解决办法)。一个简化的配置如下: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应用程序相互访问时,必然会存在跨域问题。解决跨域问题一般有两种方式:CORS,在后端服务器设置HTTP响应头,在Access-Control-Allow-Origin中加入你需要允许访问的域名。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-Control,Content-Type';}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以引入跨域配置:#----------------------------------------------------#这个文件是一个项目nginx配置片段#是包含(推荐)直接在nginxconfig中#或者复制到已有的nginx中,自己配置#www.helloworld.com域名需要配置dnshosts#其中api开启了cors,需要在另外一个配置文件中进行匹配这个目录#-------------------------------------------------上游amfront_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;}}这样就搞定了作者:张鹏编辑:陶家龙来源:github.com/dunwu/nginx-教程