发布时间:2025-12-10 23:07:34 浏览次数:2
基础篇
一、环境
服务器版本:CentOS 7.2
为了保证学习阶段不遇到奇怪的事情,请保证以下四点(大神选择性无视)
1. 确认系统网络
2. 确认yum可用
3. 确认关闭iptables
4. 确认停用selinux
#查看iptables状态systemctlstatusfirewalld.service#关闭防火墙(临时关闭)systemctlstopfirewalld.service#查看SELinux状态getenforce#临时关闭SELinuxsetenforce0
安装一些系统基本工具,正常情况系统都会自带(没有在装哦)
yum-yinstallgccgcc-c++autoconfpcrepcre-develmakeautomakeyum-yinstallwgethttpd-toolsvim
Nginx是一个开源且高性能、可靠的HTTP中间件、代理服务
其他的HTTP服务:
1. HTTPD-Apache基金会
2. IIS-微软
3. GWS-Google(不对外开放)
近几年,Nginx的市场占有率越来越高,一度飙升,为什么呢?接下来我们就知道了!
1. IO多路复用epoll(IO复用)
如何理解呢?举个例子吧!
有A、B、C三个老师,他们都遇到一个难题,要帮助一个班级的学生解决课堂作业。
老师A采用从第一排开始一个学生一个学生轮流解答的方式去回答问题,老师A浪费了很多时间,并且有的学生作业还没有完成呢,老师就来了,反反复复效率极慢。
老师B是一个忍者,他发现老师A的方法行不通,于是他使用了影分身术,分身出好几个自己同一时间去帮好几个同学回答问题,最后还没回答完,老师B消耗光了能量累倒了。
老师C比较精明,他告诉学生,谁完成了作业举手,有举手的同学他才去指导问题,他让学生主动发声,分开了“并发”。
这个老师C就是Nginx。
2. 轻量级
功能模块少 - Nginx仅保留了HTTP需要的模块,其他都用插件的方式,后天添加
代码模块化 - 更适合二次开发,如阿里巴巴Tengine
3. CPU亲和
把CPU核心和Nginx工作进程绑定,把每个worker进程固定在一个CPU上执行,减少切换CPU的cache miss,从而提高性能。
本人使用了鸟哥的lnmp集成包 https://lnmp.org,简单方便-推荐!
#执行这句语句,根据指引,将安装nginxphpmysql可进入lnmp官网查看更详细的过程#默认安装目录/usr/localwget-chttp://soft.vpser.net/lnmp/lnmp1.4.tar.gz&&tarzxflnmp1.4.tar.gz&&cdlnmp1.4&&./install.shlnmp#默认安装目录/usr/local
#打开主配置文件,若你是用lnmp环境安装vim/usr/local/nginx/conf/nginx.conf----------------------------------------user#设置nginx服务的系统使用用户worker_processes#工作进程数一般情况与CPU核数保持一致error_log#nginx的错误日志pid#nginx启动时的pidevents{worker_connections#每个进程允许最大连接数use#nginx使用的内核模型}我们使用 nginx 的 http 服务,在配置文件 nginx.conf 中的 http 区域内,配置无数个 server ,每一个 server 对应这一个虚拟主机或者域名
http{......#后面再详细介绍http配置项目server{listen80#监听端口;server_namelocalhost#地址location/{#访问首页路径root/xxx/xxx/index.html#默认目录indexindex.htmlindex.htm#默认文件}error_page500504/50x.html#当出现以上状态码时从新定义到50x.htmllocation=/50x.html{#当访问50x.html时root/xxx/xxx/html#50x.html页面所在位置}}server{......}}一个 server 可以出现多个 location ,我们对不同的访问路径进行不同情况的配置
我们再来看看 http 的配置详情
http{sendfileon#高效传输文件的模式一定要开启keepalive_timeout65#客户端服务端请求超时时间log_formatmainXXX#定义日志格式代号为mainaccess_log/usr/local/access.logmain#日志保存地址格式代码main}查看 nginx 已开启和编联进去的模块,模块太多了,就不在这长篇大论,有需要自行百度吧~
#大写V查看所有模块,小写v查看版本nginx-V#查看此配置文件是否存在语法错误nginx-tc/usr/local/nginx/conf/nginx.conf
1.静态资源类型
非服务器动态运行生成的文件,换句话说,就是可以直接在服务器上找到对应文件的请求
浏览器端渲染:HTML,CSS,JS
图片:JPEG,GIF,PNG
视频:FLV,MPEG
文件:TXT,任意下载文件
2.静态资源服务场景-CDN
什么是CDN?例如一个北京用户要请求一个文件,而文件放在的新疆的资源存储中心,如果直接请求新疆距离太远,延迟久。使用nginx静态资源回源,分发给北京的资源存储中心,让用户请求的动态定位到北京的资源存储中心请求,实现传输延迟的最小化
2.nginx静态资源配置
配置域:http、server、location#文件高速读取http{sendfileon;}#在sendfile开启的情况下,开启tcp_nopush提高网络包传输效率#tcp_nopush将文件一次性一起传输给客户端,就好像你有十个包裹,快递员一次送一个,来回十趟,开启后,快递员讲等待你十个包裹都派件,一趟一起送给你http{sendfileon;tcp_nopushon;}#tcp_nodelay开启实时传输,传输方式与tcp_nopush相反,追求实时性,但是它只有在长连接下才生效http{sendfileon;tcp_nopushon;tcp_nodelayon;}#将访问的文件压缩传输(减少文件资源大小,提高传输速度)#当访问内容以gif或jpg结尾的资源时location~.*\.(gif|jpg)${gzipon;#开启gzip_http_version1.1;#服务器传输版本gzip_comp_level2;#压缩比,越高压缩越多,压缩越高可能会消耗服务器性能gzip_typestext/plainapplication/javascriptapplication/x-javascripttext/javascripttext/cssapplication/xmlapplication/xml+rssimage/jpegimage/gifimage/png;#压缩文件类型root/opt/app/code;#对应目录(去该目录下寻找对应文件)}#直接访问已压缩文件#当访问路径以download开头时,如www.baidu.com/download/test.img#去/opt/app/code目录下寻找test.img.gz文件,返回到前端时已是可以浏览的img文件location~load^/download{gzip_staticon#开启;tcp_nopushon;root/opt/app/code;}HTTP协议定义的缓存机制(如:Expires; Cache-control等 )
减少服务端的消耗,降低延迟
1.浏览器无缓存
浏览器请求 -> 无缓存 -> 请求WEB服务器 -> 请求相应 -> 呈现
在呈现阶段会根据缓存的设置在浏览器中生成缓存
2.浏览器有缓存
浏览器请求 -> 有缓存 -> 校验本地缓存时间是否过期 -> 没有过期 -> 呈现
若过期从新请求WEB服务器
3.语法配置
location~.*\.(html|htm)${expires12h;#缓存12小时}服务器响应静态文件时,请求头信息会带上 etag 和 last_modified_since 2个标签值,浏览器下次去请求时,头信息发送这两个标签,服务器检测文件有没有发生变化,如无,直接头信息返 etag 和last_modified_since,状态码为304,浏览器知道内容无改变,于是直接调用本地缓存,这个过程也请求了服务,但是传着的内容极少
开发nginx跨站访问设置
location~.*\.(html|htm)${add_headerAccess-Control-Allow-Origin*;add_headerAccess-Control-Allow-MethodsGET,POST,PUT,delete,OPTIONS;#Access-Control-Allow-Credentialstrue#允许cookie跨域}在响应中指定 Access-Control-Allow-Credentials 为 true 时,Access-Control-Allow-Origin 不能指定为 *,需要指定到具体域名
相关跨域内容可参考Laravel 跨域功能中间件使用代码实现跨域,原理与nginx跨域配置相同
防止服务器内的静态资源被其他网站所套用
此处介绍的 nginx 防盗链为基础方式,其它更加深入的方式将在之后的文章介绍
首先,需要理解一个nginx变量
$http_referer#表示当前请求上一次页面访问的地址,换句话说,访问www.baidu.com主页,这是第一次访问,所以$http_referer为空,但是访问此页面的时候还需要获取一张首页图片,再请求这张图片的时候$http_referer就为www.baidu.com
然后配置
location~.*\.(jpg|gif)${#valid_referers表示我们允许哪些$http_referer来访问#none表示没有带$http_referer,如第一次访问时$http_referer为空#blocked表示$http_referer不是标准的地址,非正常域名等#只允许此ipvalid_referersnoneblocked127.xxx.xxx.xxif($invalid_referer){#不满足情况下变量值为1return403;}}Nginx可以实现多种代理方式
HTTP
ICMPPOPIMAP
HTTPS
RTMP
1. 代理区别
区别在于代理的对象不一样
正向代理代理的对象是客户端
反向代理代理的对象是服务端
2. 反向代理
语法:proxy_passURL默认:——位置:loaction#代理端口#场景:服务器80端口开放,8080端口对外关闭,客户端需要访问到8080#在nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url加/,表示绝对根路径;如果没有/,表示相对路径,把匹配的路径部分也给代理走server{listen80;location/{proxy_passhttp://127.0.0.1:8080/;proxy_redirectdefault;proxy_set_headerHost$http_host;proxy_set_headerX-Real-IP$remote_addr;#获取客户端真实IPproxy_connect_timeout30;#超时时间proxy_send_timeout60;proxy_read_timeout60;proxy_buffer_size32k;proxy_bufferingon;#开启缓冲区,减少磁盘ioproxy_buffers4128k;proxy_busy_buffers_size256k;proxy_max_temp_file_size256k;#当超过内存允许储蓄大小,存到文件}}负载均衡的实现方法就是我们上章介绍的反向代理。将客户的请求通过 nginx 分发(反向代理)到一组多台不同的服务器上
这一组服务器我们称为服务池(upstream server),池内的每一个服务器称为一个单元,服务池内将对每一个单元进行请求轮训,实现负载均衡
#配置语法:upstreamname...默认:——位置:httpupstream#自定义组名{serverx1.baidu.com;#可以是域名serverx2.baidu.com;#serverx3.baidu.com#down不参与负载均衡#weight=5;权重,越高分配越多#backup;预留的备份服务器#max_fails允许失败的次数#fail_timeout超过失败次数后,服务暂停时间#max_coons限制最大的接受的连接数#根据服务器性能不同,配置适合的参数#server106.xx.xx.xxx;可以是ip#server106.xx.xx.xxx:8080;可以带端口号#serverunix:/tmp/xxx;支出socket方式}假设我们有三台服务器,并且假设它们的IP地址,前端负载均衡服务器A(127.0.0.1),后台服务器B(127.0.0.2),后台服务器C(127.0.0.3)
新建文件proxy.conf,内容如下,上一章介绍的反向代理配置
proxy_redirectdefault;proxy_set_headerHost$http_host;proxy_set_headerX-Real-IP$remote_addr;proxy_connect_timeout30;proxy_send_timeout60;proxy_read_timeout60;proxy_buffer_size32k;proxy_bufferingon;proxy_buffers4128k;proxy_busy_buffers_size256k;proxy_max_temp_file_size256k;#服务器A的配置http{...upstreamxxx{server127.0.0.2;server127.0.0.3;}server{liseten80;server_namelocalhost;location/{proxy_passhttp://xxx#upstream对应自定义名称includeproxy.conf;}}}#服务器B、服务器C的配置server{liseten80;server_namelocalhost;location/{indexindex.html}}调度算法
轮训:按时间顺序逐一分配到不同的后端服务器
加权轮训:weight值越大,分配到的几率越高
ip_hash:每个请求按访问IP的hash结果分配,这样来自同一个IP固定访问一个后端服务器
least_conn:最少链接数,哪个机器连接数少就分发给谁
url_hash:按照访问的URL的hash结果来分配请求,每一个URL定向到同一个后端服务器
hash关键数值:hash自定义key
ip_hash配置
upstreamxxx{ip_hash;server127.0.0.2;server127.0.0.3;}ip_hash存在缺陷,当前端服务器再多一层时,将获取不到用户的正确IP,获取的将是前一个前端服务器的IP,因此 nginx1.7.2版本推出了 url_hash
url_hash配置
upstreamxxx{hash$request_uri;server127.0.0.2;server127.0.0.3;}1. 缓存类型
服务端缓存:缓存存储在后端服务器,如redis,memcache
代理缓存:缓存存储在代理服务器或者中间件上,它的内容是从后端服务器获取的,但是保存在自己本地
客户端缓存:缓存在浏览器内的
2. nginx 代理缓存
客户端请求nginx,nginx查看本地是否有缓存数据,若有直接返回给客户端,若没有再去后端服务器请求
http{proxy_cache_path/var/www/cache#缓存地址levels=1:2#目录分级keys_zone=test_cache:10m#开启的keys空间名字:空间大小(1m可以存放8000个key)max_size=10g#目录最大大小(超过时,不常用的将被删除)inactive=60m#60分钟内没有被访问的缓存将清理use_temp_path=pff;#是否开启存放临时文件目录,关闭默认存储在缓存地址server{...location/{proxy_cachetest_cache;#开启缓存对应的名称,在keys_zone命名好proxy_cache_valid20030412h;#状态码为200304的缓存12小时proxy_cache_validany10m;#其他状态缓存10小时proxy_cache_key$host$uri$is_args$args;#设置key值add_headerNginx-Cache"$upstream_cache_status";}}}当有个特定请求我们不需要缓存的时候,在上面配置的内容中加入以下配置
server{...if($request_uri~^/(login|register)){#当请求地址有login或register时set$nocache=1;#设置一个自定义变量为true}location/{proxy_no_cache$nocache$arg_nocache$arg_comment;proxy_no_cache$http_pragma$http_authoriztion;}}3. 分片请求
早期版本 nginx 对大文件的分片请求不支持缓存,1.9版本后slice模块实现了这个功能
前端发起请求,nginx去获取这个请求文件的大小,若超过我们的定义slice的大小,会进行切片,分割成多个小的请求去请求后端,到前端就成为一个一个独立的缓存文件
tips:欢迎关注微信公众号:Java后端,获取每日技术博文推送。
优势:每个子请求收到的数据都会形成独立文件,一个请求中断了,其他请求不受影响,原本情况请求中断,再次请求文件将从头开始,而开启分片请求,就接下去获取未请求的小文件
劣势:当文件很大或者slice很小时,可能会导致文件描述符耗尽等情况
语法:slicesize;#当大文件请求时,设置size为每个小文件的大小默认:slice0;位置:http/server/location
#当出现虚拟主机域名相同的情况,重启nginx时,会出现警告⚠️处理,但是并不不会阻止nginx继续使用server{listen80;server_namewww.baidu.com...}server{listen80;server_namewww.baidu.com...}...优先选择最新读取到的配置文件,当多个文件是通过include时,文件排序越靠前,越早被读取=#进行普通字符精确匹配,完全匹配^~#进行普通字符匹配,当前表示前缀匹配~\~*#表示执行一个正则匹配()#当程序使用精确匹配时,一但匹配成功,将停止其他匹配#当正则匹配成功时,会继续接下来的匹配,寻找是否还有更精准的匹配
按顺序检查文件是否存在
location/{try_files$uri$uri//index.php;}#先查找$uri下是否有文件存在,若存在直接返回给用户#若$url下没有文件存在,再次访问$uri/的路径是否有文件存在#还是没有文件存在,交给index.php处理例:location/{root/test/index.htmltry_files$uri@test}location@test{proxy_passhttp://127.0.0.1:9090;}#访问/时,查看/test/index.html文件是否存在#若不存在,让9090端口的程序去处理这个请求location/request_path/image/{root/local_path/image/;}#当我们访问https://cache.yisu.com/upload/information/20210524/347/786645.png时#将访问https://cache.yisu.com/upload/information/20210524/347/786646.png下的文件location/request_path/image/{alias/local_path/image/;}#当我们访问https://cache.yisu.com/upload/information/20210524/347/786645.png时#将访问https://cache.yisu.com/upload/information/20210524/347/786647.png下的文件当一个请求通过多个代理服务器时,用户的IP将会被代理服务器IP覆盖
#在第一个代理服务器中设置setx_real_ip=$remote_addr#最后一个代理服务器中获取$x_real_ip=IP1
413RequestEntityTooLarge#上传文件过大,设置client_max_body_size503badgateway#后端服务无响应504GatewayTime-out#后端服务执行超时
感谢各位的阅读,以上就是“Nginx的概念和用法”的内容了,经过本文的学习后,相信大家对Nginx的概念和用法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是本站,小编将为大家推送更多相关知识点的文章,欢迎关注!