首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
184 阅读
2
php接口优化 使用curl_multi_init批量请求
144 阅读
3
《从菜鸟到大师之路 ElasticSearch 篇》
107 阅读
4
2024年备考系统架构设计师
104 阅读
5
PHP 文件I/O
92 阅读
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
登录
Search
标签搜索
php函数
php语法
性能优化
安全
错误和异常处理
问题
vue
Composer
Session
缓存
框架
Swoole
api
并发
异步
正则表达式
php-fpm
mysql 索引
开发规范
协程
dafenqi
累计撰写
786
篇文章
累计收到
32
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
560
篇与
的结果
2023-08-28
PHP实现异步调用方法研究
PHP实现异步调用方法研究浏览器和服务器之间是通过 HTTP 协议进行连接通讯的。这是一种基于请求和响应模型的协议。浏览器通过 URL 向服务器发起请求,Web 服务器接收到请求,执行一段程序,然后做出响应,发送相应的html代码给客户端。这就有了一个问题,Web 服务器执行一段程序,可能几毫秒就完成,也可能几分钟都完不成。如果程序执行缓慢,用户可能没有耐心等下去,就关闭浏览器了。而有的时候,我们更本不关心这些耗时的脚本的返回结果,但却还要等他执行完返回,才能继续下一步。那么有没有什么办法,只是简单的触发调用这些耗时的脚本然后就继续下一步,让这些耗时的脚本在服务端慢慢执行?经过试验,总结出来几种方法,和大家share:1. 最简单的办法就是在返回给客户端的HTML代码中,嵌入AJAX调用,或者,嵌入一个img标签,src指向要执行的耗时脚本。这种方法最简单,也最快。服务器端不用做任何的调用。但是缺点是,一般来说Ajax都应该在onLoad以后触发,也就是说,用户点开页面后,就关闭,那就不会触发我们的后台脚本了。而使用img标签的话,这种方式不能称为严格意义上的异步执行。用户浏览器会长时间等待php脚本的执行完成,也就是用户浏览器的状态栏一直显示还在load。当然,还可以使用其他的类似原理的方法,比如 script 标签等等。2. popen()resource popen ( string command, string mode );//打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。所以可以通过调用它,但忽略它的输出。pclose(popen("/home/xinchen/backend.php &", 'r'));这个方法避免了第一个方法的缺点,并且也很快。但是问题是,这种方法不能通过HTTP协议请求另外的一个WebService,只能执行本地的脚本文件。并且只能单向打开,无法穿大量参数给被调用脚本。并且如果,访问量很高的时候,会产生大量的进程。如果使用到了外部资源,还要自己考虑竞争。3. 使用CURL这个方法,设置CUROPT_TIMEOUT为1(最小为1,郁闷)。也就是说,客户端至少必须等待1秒钟。$ch = curl_init(); $curl_opt = array(CURLOPT_URL, 'http://www.example.com/backend.php', CURLOPT_RETURNTRANSFER, 1, CURLOPT_TIMEOUT, 1,); curl_setopt_array($ch, $curl_opt); curl_exec($ch); curl_close($ch);4. 使用fsockopen这个方法应该是最完美的,但是缺点是,你需要自己拼出HTTP的header部分。$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30); if (!$fp) { echo "$errstr ($errno)<br />\n"; } else { $out = "GET /backend.php / HTTP/1.1\r\n"; $out .= "Host: www.example.com\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); /*忽略执行结果 while (!feof($fp)) { echo fgets($fp, 128); }*/ fclose($fp); }所以,总体来看,最好用,最简单的还是第一种方法。最完美的应该是最后一种,但是比较复杂
2023年08月28日
14 阅读
0 评论
0 点赞
2023-08-28
LaravelS v3.5.0 开发手册
LaravelS v3.5.0 开发手册
2023年08月28日
9 阅读
0 评论
0 点赞
2023-08-28
PHP异步编程: 手把手教你实现co与Koa
PHP异步编程: 手把手教你实现co与Koa
2023年08月28日
20 阅读
0 评论
0 点赞
2023-08-18
nginx php-fpm安装配置
nginx php-fpm安装配置nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端。nginx一般是把请求发fastcgi管理进程处理,fascgi管理进程选择cgi子进程处理结果并返回被nginx本文以php-fpm为例介绍如何使nginx支持PHP一、编译安装php-fpm什么是PHP-FPMPHP-FPM是一个PHP FastCGI管理器 ,是只用于PHP的,可以在 http://php-fpm.org/download下载得到.PHP-FPM其实是PHP源代码的一个补丁,旨在将FastCGI进程管理整合进PHP包中。必须将它patch到你的PHP源代码中,在编译安装PHP后才可以使用。新版PHP已经集成php-fpm了,不再是第三方的包了 ,推荐使用。PHP-FPM提供了更好的PHP进程管理方式,可以有效控制内存和进程、可以平滑重载PHP配置,比spawn-fcgi具有更多优点,所以被PHP官方收录了。在./configure的时候带 –enable-fpm参数即可开启PHP-FPM,其它参数都是配置php的,具体选项含义可以查看这里。安装前准备centos下执行yum -y install gcc automake autoconf libtool make yum -y install gcc gcc-c++ glibc yum -y install libmcrypt-devel mhash-devel libxslt-devel libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel新版php-fpm安装(推荐安装方式)wget http://cn2.php.net/distributions/php-5.4.7.tar.gz tar zvxf php-5.4.7.tar.gz cd php-5.4.7 ./configure --prefix=/usr/local/php --enable-fpm --with-mcrypt --enable-mbstring --disable-pdo --with-curl --disable-debug --disable-rpath --enable-inline-optimization --with-bz2 --with-zlib --enable-sockets --enable-sysvsem --enable-sysvshm --enable-pcntl --enable-mbregex --with-mhash --enable-zip --with-pcre-regex --with-mysql --with-mysqli --with-gd --with-jpeg-dir make all install旧版手动打补丁php-fpm安装(旧版程序已经没有了,大家新版的吧,这里做个展示)wget http://cn2.php.net/get/php-5.2.17.tar.gz wget http://php-fpm.org/downloads/php-5.2.17-fpm-0.5.14.diff.gz tar zvxf php-5.2.17.tar.gz gzip -cd php-5.2.17-fpm-0.5.14.diff.gz | patch -d php-5.2.17 -p1 cd php-5.2.17 ./configure --prefix=/usr/local/php -with-config-file-path=/usr/local/php/etc -with-mysql=/usr/local/mysql -with-mysqli=/usr/local/mysql/bin/mysql_config -with-openssl -enable-fpm -enable-mbstring -with-freetype-dir -with-jpeg-dir -with-png-dir -with-zlib-dir -with-libxml-dir=/usr -enable-xml -with-mhash -with-mcrypt -enable-pcntl -enable-sockets -with-bz2 -with-curl -with-curlwrappers -enable-mbregex -with-gd -enable-gd-native-ttf -enable-zip -enable-soap -with-iconv -enable-bcmath -enable-shmop -enable-sysvsem -enable-inline-optimization -with-ldap -with-ldap-sasl -enable-pdo -with-pdo-mysql make all install以上两种方式都可以安装php-fpm,安装后内容放在 /usr/local/php 目录下以上就完成了php-fpm的安装。对php-fpm运行用户进行设置下面是对php-fpm运行用户进行设置cd /usr/local/php cp etc/php-fpm.conf.default etc/php-fpm.conf vi etc/php-fpm.conf修改user = www-data group = www-data如果www-data用户不存在,那么先添加www-data用户groupadd www-data useradd -g www-data www-data二、编译安装nginx然后按照https://www.cnblogs.com/chaofanq/p/15022916.html 安装nginx三、修改nginx配置文件以支持php-fpmnginx安装完成后,修改nginx配置文件为,nginx.conf其中server段增加如下配置 ,root html; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;否则会出现No input file specified.错误# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # location ~ .php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }四、创建测试php文件创建php文件在/usr/local/nginx/html下创建index.php文件,输入如下内容<?php echo phpinfo(); ?>五、启动服务启动php-fpm和nginx/usr/local/php/sbin/php-fpm #手动打补丁的启动方式/usr/local/php/sbin/php-fpm start sudo /usr/local/nginx/nginxphp-fpm关闭重启见文章结尾六、浏览器访问访问http://你的服务器ip/index.php ,皆可以见到php信息了。七、安装php-fpm时可能遇到的错误1. php configure时出错configure: error: XML configuration could not be found apt-get install libxml2 libxml2-dev (ubuntu下) yum -y install libxml2 libxml2-devel(centos下)2. Please reinstall the BZip2 distributionwget http://www.bzip.org/1.0.5/bzip2-1.0.5.tar.gz tar -zxvf bzip2-1.0.5.tar.gz cd bzip2-1.0.5 make make install3. php的配置文件中有一行--with-mysql=/usr。安装的时候提示:configure: error: Cannot find MySQL header files under yes. Note that the MySQL client library is not bundled anymore.这是由于安装mysql时没有安装mysql头文件,或者是路径指定不正确,php找不到mysql的头文件引起的错误提示。解决方法。(1.) 查看你的系统有没有安装mysql headerfind / -name mysql.h如果有。请指定--with-mysql=/跟你的正常路径。 如果没有。请看下一步。(2.)redhat安装rpm -ivh MySQL-devel-4.1.12-1.i386.rpm(3.)ubuntu安装apt-get install libmysqlclient15-dev(4.)最后一步php的配置选项添加--with-mysql=/usr即可!4.No input file specified.location ~ .php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }5. 如果php configure时缺库,可以先安装库(ubuntu下)sudo apt-get install make bison flex gcc patch autoconf subversion locate sudo apt-get install libxml2-dev libbz2-dev libpcre3-dev libssl-dev zlib1g-dev libmcrypt-dev libmhash-dev libmhash2 libcurl4-openssl-dev libpq-dev libpq5 libsyck0-dev6. mcrypt.h not found. Please reinstall libmcryptapt-get install libmcrypt-dev或者cd /usr/local/src wget http://softlayer.dl.sourceforge.net/sourceforge/mcrypt/libmcrypt-2.5.8.tar.gz tar -zxvf libmcrypt-2.5.8.tar.gz cd /usr/local/src/libmcrypt-2.5.8 ./configure --prefix=/usr/local make make install7. php-fpm 5.4.7 如何关闭 重启?php 5.4.7 下的php-fpm 不再支持 php-fpm 以前具有的 /usr/local/php/sbin/php-fpm (start|stop|reload)等命令, 需要使用信号控制: master进程可以理解以下信号INT, TERM 立刻终止QUIT 平滑终止USR1 重新打开日志文件USR2 平滑重载所有worker进程并重新载入配置和二进制模块示例:php-fpm 关闭:kill -INT cat /usr/local/php/var/run/php-fpm.pidphp-fpm 重启:kill -USR2 cat /usr/local/php/var/run/php-fpm.pid查看php-fpm进程数:ps aux | grep -c php-fpm8.命令行下执行php,提示找不到命令-bash: /usr/bin/php: No such file or directoryvi /etc/profile 在文件底部增加一行配置export PATH=/usr/local/php/bin:$PATH保存退出source /etc/profile9.Package requirements (sqlite3 >= 3.7.7) were not met: No package 'sqlite3' found要从源代码进行编译,需要将依赖项作为可链接库(有时还包括新程序用于构建的标头)提供。-devel软件包会安装这些库,因此要从具有SQLite支持的源代码构建PHP,您需要安装sqlite-devel。yum install sqlite-devel10.Package requirements (oniguruma) were not met:No package 'oniguruma' foundoniguruma是一个处理正则表达式的库,在编译安装php时,如果使用–enable-mbstring 参数, 开启mbstring扩展,则会出现这个错误。原因:mbstring的正则功能需要oniguruma的支持,系统中却没有oniguruma库。[root@2207013 data]# wget https://github.com/kkos/oniguruma/releases/download/v6.9.7/onig-6.9.7.tar.gz [root@2207013 data]# tar -zxvf onig-6.9.7.tar.gz [root@2207013 data]# cd onig-6.9.7 [root@2207013 onig-6.9.7]# ./configure [root@2207013 onig-6.9.7]# make && make install # 注意它安装到哪个目录,这里安装到了/usr/local/lib下 [root@2207013 onig-6.9.7]# export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH [root@2207013 onig-6.9.7]# pkg-config --modversion oniguruma # 此时可查看安装的oniguruma版本 [root@2207013 onig-6.9.7]# pkg-config --variable pcfiledir oniguruma # 查看安装的oniguruma位置
2023年08月18日
15 阅读
0 评论
0 点赞
2023-08-18
nginx 手册
Nginx高性能web服务器Nginx高性能web服务器详细讲解介绍入门Nginx概述Nginx服务器是一款免费开源的高性能、轻量级HTTP服务器及反向代理服务器产品,能够提供IMAP/POP3代理服务 等功能。是 lgor Sysoev 为俄罗斯访问量居首的 Rambler.ru 站点(www.rambler.ru)设计开发的。Nginx功能丰富, 可作为HTTP服务器,也可作为反向代理服务器,邮件服务器 。能够快速响应静态页面的请求,支持 FastCGI、SSL、Virtual Host、URL Rewrite、Gzi p等大量使用功能,并且支持很多第三方的模块扩展主要功能反向代理负载均衡HTTP服务器(包含动静分离)正向代理可以参考的书目https://www.w3cschool.cn/nginx/http://tengine.taobao.org/https://nginx.cn/特性简单描述Nginx使用基于事件驱动架构,使得其可以支持数以百万级别的TCP连接高度的模块化和自由软件许可证是的第三方模块层出不穷Nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;Nginx特点1、轻量级,采用C进行编写,同样的web服务,会占用更少的内存及资源。2、抗并发,nginx以epollandkqueue作为开发模型,处理请求是异步非阻塞的,负载能力比apache高很多,而apache则是阻塞型的。在高并发下nginx能保持低资源低消耗高性能,而apache在PHP处理慢或者前端压力很大的情况下,很容易出现进程数飙升,从而拒绝服务的现象。3、nginx在开启时,会生成一个master进程,然后,master进程会fork多个worker子进程,最后每个用户的请求由worker的子线程处理。4、可以配置nginx的upstream实现nginx的反向代理。5、nginx作为负载均衡服务器,支持7层负载均衡。6、nginx处理静态文件好,静态处理性能比apache高三倍以上。7、支持高并发连接,每秒最多的并发连接请求理论可以达到50000个。8、nginx配置简洁,正则配置让很多事情变得简单,而且改完配置能使用-t测试配置有没有问题,apache配置复杂,重启的时候发现配置出错了,会很崩溃。9、用线程处理用户请求,而线程是共享内存的,只需要开启少量进程,多个线程就可以共享进程的内存,占用内存小。10、一个进程死掉时,会影响到多个用户的使用,稳定性差。11、nginx的设计高度模块化,编写模块相对简单。12、nginx本身就是一个反向代理服务器,而且可以作为非常优秀的邮件代理服务器。13、启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动,还能够不间断服务的情况下进行软件版本的升级。14、社区活跃,各种高性能模块出品迅速。Apache特点1、select同步阻塞。2、一个连接对应一个进程。3、用进程处理用户请求,用MPM(多处理模块)来绑定到网络端口上,接受请求,调度子进程处理请求。4、当用户请求过多时,开启的进程较多,占用内存大,每秒最多的并发连接请求最多不超过3000个。5、一个进程死掉时,不会影响其他的用户6、apache的rewrite比nginx强大,在rewrite频繁的情况下,用apache。7、apache发展到现在,模块超多,基本想到的都可以找到。8、apache更为成熟,少bug,nginx的bug相对较多。9、apache超稳定。10、apache对PHP支持比较简单,nginx需要配合其他后端用。11、apache在处理动态请求有优势,一般动态请求要apache去做,nginx适合静态和反向。12、apache仍然是目前的主流,拥有丰富的特性,成熟的技术和开发社区。核心区别两者最核心的区别在于apache是同步多进程模型,一个连接对应一个进程,而nginx是异步的,多个连接(万级别)可以对应一个进程。一般来说,需要性能的web服务,用nginx。如果不需要性能只求稳定,更考虑apache,apache的各种功能模块实现比nginx好,例如ssl的模块就比nginx好,可配置项多。epoll(freebsd上是kqueue)网络IO模型是nginx处理性能高的根本理由,但并不是所有的情况下都是epoll大获全胜的,如果本身提供静态服务的就只有寥寥几个文件,apache的select模型或许比epoll更高性能。当然,这只是根据网络IO模型的原理作的一个假设,真正的应用还是需要实测。更为通用的方案是,前端nginx抗并发,后端apache集群,配合起来会更好。安装启动Centos系统安装Centos系统安装Ubuntu系统安装1.首先查看linux系统cat /proc/version Linux version 4.9.59-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611) ) #1047 SMP Sun Oct 29 12:19:23 GMT 2017 # 这表示Ubantu系统2.安装nginxsudo apt-get install nginx过程会让选一个Y同意占用内存。3.如果出现无法定位nginx包,进行如下操作:sudo apt-get update4.更新完成之后,安装nginxsudo apt-get install nginx5.Ubuntu安装之后的文件结构大致为:1)所有的配置文件都在/etc/nginx下,并且每个虚拟主机已经安排在了/etc/nginx/sites-available下2)程序文件在/usr/sbin/nginx3)日志放在了/var/log/nginx中4)并已经在/etc/init.d/下创建了启动脚本nginx5)默认的虚拟主机的目录设置在了/var/www/nginx-default (有的版本默认的虚拟主机的目录设置在了/var/www, 请参考/etc/nginx/sites-available里的配置)macbook安装首先确保有brew软件。安装brew search nginx brew install nginx做个软连接ln -s /usr/local/sbin/nginx /usr/bin/nginx常用指令nginx -V 查看版本,以及配置文件地址nginx -v 查看版本nginx -c filename 指定配置文件nginx -h 帮助nginx -s reload|reopen|stop|quit // 重新加载配置|重启|停止|退出 nginx")重新加载配置|重启|停止|退出 nginxnginx -t //查看配置是否有语法错误nginx -c /usr/local/etc/nginx/nginx.conf //启动是加载指定nginx.conf文件基础必会常用功能反向代理反向代理应该是Nginx做的最多的一件事了 ,什么是反向代理呢,以下是百度百科的说法:反向代理(Reverse Proxy)方式是 指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。 简单来说就是 真实的服务器不能直接被外部网络访问,所以需要一台代理服务器,而代理服务器能被外部网络访问的同时又跟真实服务器在同一个网络环境,当然也可能是同一台服务器,端口不同而已。 下面贴上一段简单的实现反向代理的代码server { listen 80; server_name localhost; client_max_body_size 1024M; location / { proxy_pass http://localhost:8080; proxy_set_header Host $host:$server_port; } }保存配置文件后启动Nginx,这样当我们 访问localhost的时候,就相当于访问localhost:8080了负载均衡负载均衡也是Nginx常用的一个功能,负载均衡其意思就是 分摊到多个操作单元上进行执行 ,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。简单而言就是 当有2台或以上服务器时,根据规则随机的将请求分发到指定的服务器上处理,负载均衡配置一般都需要同时配置反向代理,通过反向代理跳转到负载均衡 。而Nginx目前支持 自带3种负载均衡策略 ,还有 2种常用的第三方策略 。1、RR(默认)每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。 简单配置 upstream test { server localhost:8080; server localhost:8081; } server { listen 81; server_name localhost; client_max_body_size 1024M; location / { proxy_pass http://test; proxy_set_header Host $host:$server_port; } }负载均衡的核心代码为 upstream test { server localhost:8080; server localhost:8081; }这里我配置了2台服务器,当然实际上是一台,只是端口不一样而已,而8081的服务器是不存在的,也就是说访问不到,但是我们访问http://localhost的时候,也不会有问题,会默认跳转到http://localhost:8080具体是因为Nginx会自动判断服务器的状态, 如果服务器处于不能访问(服务器挂了),就不会跳转到这台服务器,所以也避免了一台服务器挂了影响使用的情况,由于Nginx默认是RR策略,所以我们不需要其他更多的设置。2、权重指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 例如 upstream test { server localhost:8080 weight=9; server localhost:8081 weight=1; }那么10次一般只会有1次会访问到8081,而有9次会访问到80803、ip_hash上面的2种方式都有一个问题,那就是下一个请求来的时候请求可能分发到另外一个服务器,当我们的程序不是无状态的时候(采用了session保存数据),这时候就有一个很大的很问题了,比如把登录信息保存到了session中,那么跳转到另外一台服务器的时候就需要重新登录了,所以很多时候我们需要一个客户只访问一个服务器,那么就需要用iphash了, iphash的每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。 upstream test { ip_hash; server localhost:8080; server localhost:8081; }4、fair(第三方)按后端服务器的响应时间来分配请求,响应时间短的优先分配。 upstream backend { fair; server localhost:8080; server localhost:8081; }5、url_hash(第三方)按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。 在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法 upstream backend { hash $request_uri; server localhost:8080; server localhost:8081; }以上5种负载均衡各自适用不同情况下使用,所以可以根据实际情况选择使用哪种策略模式,不过 fair和url_hash需要安装第三方模块才能使用 ,由于本文主要介绍Nginx能做的事情,所以Nginx安装第三方模块不会再本文介绍拓展yum安装nginx没有某一模块,该如何添加第三方模块? Nginx几款负载均衡第三方插件的安装与使用正向代理正向代理,意思是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。 客户端才能使用正向代理 。当你需要把你的服务器作为代理服务器的时候,可以用Nginx来实现正向代理,但是目前Nginx有一个问题,那么就是不支持HTTPS,虽然我百度到过配置HTTPS的正向代理,但是到最后发现还是代理不了,当然可能是我配置的不对,所以也希望有知道正确方法的同志们留言说明一下。 resolver 114.114.114.114 8.8.8.8; server { resolver_timeout 5s; listen 81; access_log e:wwwrootproxy.access.log; error_log e:wwwrootproxy.error.log; location / { proxy_pass http://$host$request_uri; } }resolver是配置正向代理的DNS服务器,listen 是正向代理的端口,配置好了就可以在ie上面或者其他代理插件上面使用服务器ip+端口号进行代理了。拓展Nginx-正向代理实现 Nginx本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用Nginx来做服务器,同时现在也很流行动静分离,就可以通过Nginx来实现,首先看看Nginx做静态资源服务器 server { listen 80; server_name localhost; client_max_body_size 1024M; location / { root e:wwwroot; index index.html; } }这样如果访问http://localhost就会默认访问到E盘wwwroot目录下面的index.html,如果一个网站只是静态页面的话,那么就可以通过这种方式来实现部署。HTTP服务器(动静分离)Nginx本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用Nginx来做服务器,同时现在也很流行动静分离,就可以通过Nginx来实现,首先看看Nginx做静态资源服务器 server { listen 80; server_name localhost; client_max_body_size 1024M; location / { root e:wwwroot; index index.html; } }这样如果访问http://localhost就会默认访问到E盘wwwroot目录下面的index.html,如果一个网站只是静态页面的话,那么就可以通过这种方式来实现部署。技能点汇总显示乱码server { listen 80; server_name example.com; root /var/www/example; location / { charset utf-8; #一般是在个别的location中加入此项,具体情况具体对待 rewrite .* /index.html break; } }打开目录浏览功能Nginx默认是 不允许列出整个目录 的。如需此功能, 打开nginx.conf文件,在location server 或 http段中加入autoindex on; 另外两个参数最好也加上去:autoindex\_exact\_size off; 默认为on,显示出文件的确切大小,单位是bytes。改为off后,显示出文件的大概大小,单位是kB或者MB或者GBautoindex\_localtime on; 默认为off,显示的文件时间为GMT时间。改为on后,显示的文件时间为文件的服务器时间错误码原因和解决方案400 bad request错误的原因和解决办法 配置nginx.conf相关设置如下.client_header_buffer_size 16k; large_client_header_buffers 4 64k;根据具体情况调整,一般适当调整值就可以。Nginx 502 Bad Gateway错误proxy_next_upstream error timeout invalid_header http_500 http_503;或者尝试设置:large_client_header_buffers 4 32k;Nginx出现的413 Request Entity Too Large错误这个错误一般在上传文件的时候会出现,编辑Nginx主配置文件Nginx.conf,找到http{}段,添加client_max_body_size 10m; //设置多大根据自己的需求作调整.如果运行php的话这个大小client_max_body_size要和php.ini中的如下值的最大值一致或者稍大,这样就不会因为提交数据大小不一致出现的错误。post_max_size = 10M upload_max_filesize = 2M解决504 Gateway Time-out(nginx)遇到这个问题是在升级discuz论坛的时候遇到的一般看来, 这种情况可能是由于nginx默认的fastcgi进程响应的缓冲区太小造成的, 这将导致fastcgi进程被挂起, 如果你的fastcgi服务对这个挂起处理的不好, 那么最后就极有可能导致504 Gateway Time-out 现在的网站, 尤其某些论坛有大量的回复和很多内容的, 一个页面甚至有几百K。默认的fastcgi进程响应的缓冲区是8K, 我们可以设置大点在nginx.conf里, 加入:fastcgi_buffers 8 128k这表示设置fastcgi缓冲区为8×128k当然如果您在进行某一项即时的操作, 可能需要nginx的 超时参数调大点 ,例如设置成60秒:send_timeout 60;只是调整了这两个参数, 结果就是没有再显示那个超时, 可以说效果不错, 但是也可能是由于其他的原因, 目前关于nginx的资料不是很多, 很多事情都需要长期的经验累计才有结果.location用法location = / { # 精确匹配 / ,主机名后面不能带任何字符串 [ configuration A ] } location / { # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求 # 但是正则和最长字符串会优先匹配 [ configuration B ] } location /documents/ { # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索 # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条 [ configuration C ] } location ~ /documents/Abc { # 匹配任何以 /documents/Abc 开头的地址,匹配符合以后,还要继续往下搜索 # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条 [ configuration CC ] } location ^~ /images/ { # 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。 [ configuration D ] } location ~* \.(gif|jpg|jpeg)$ { # 匹配所有以 gif,jpg或jpeg 结尾的请求 # 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则 [ configuration E ] } location /images/ { # 字符匹配到 /images/,继续往下,会发现 ^~ 存在 [ configuration F ] } location /images/abc { # 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在 # F与G的放置顺序是没有关系的 [ configuration G ] } location ~ /images/abc/ { # 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用 [ configuration H ] } location ~* /js/.*/\.js已=开头表示精确匹配如 A 中只匹配根目录结尾的请求,后面不能带任何字符串。^~开头表示uri以某个常规字符串开头,不是正则匹配~ 开头表示区分大小写的正则匹配;~* 开头表示不区分大小写的正则匹配/ 通用匹配, 如果没有其它匹配,任何请求都会匹配到优先级(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)上面的匹配结果按照上面的location写法,以下的匹配示例成立:* / -> config A 精确完全匹配,即使/index.html也匹配不了 * /downloads/download.html -> config B 匹配B以后,往下没有任何匹配,采用B * /images/1.gif -> configuration D 匹配到F,往下匹配到D,停止往下 * /images/abc/def -> config D 最长匹配到G,往下匹配D,停止往下 你可以看到 任何以/images/开头的都会匹配到D并停止,FG写在这里是没有任何意义的,H是永远轮不到的,这里只是为了说明匹配顺序 * /documents/document.html -> config C 匹配到C,往下没有任何匹配,采用C * /documents/1.jpg -> configuration E 匹配到C,往下正则匹配到E * /documents/Abc.jpg -> config CC 最长匹配到C,往下正则顺序匹配到CC,不会往下到E实际使用中三个匹配规则定义所以实际使用中,个人觉得至少有三个匹配规则定义,如下:#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。 #这里是直接转发给后端应用服务器了,也可以是一个静态首页 # 第一个必选规则 location = / { proxy_pass http://tomcat:8080/index } # 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项 # 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用 location ^~ /static/ { root /webroot/static/; } location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ { root /webroot/res/; } #第三个规则就是通用规则,用来转发动态请求到后端应用服务器 #非静态文件请求就默认是动态请求,自己根据实际把握 #毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了 location / { proxy_pass http://tomcat:8080/ }参考http://tengine.taobao.org/book/chapter_02.htmlhttp://nginx.org/en/docs/http/ngx_http_rewrite_module.html常用正则. : 匹配除换行符以外的任意字符? : 重复0次或1次: 重复1次或更多次: 重复0次或更多次\d :匹配数字^ : 匹配字符串的开始$ : 匹配字符串的结束{n} : 重复n次{n,} : 重复n次或更多次[c] : 匹配单个字符c[a-z] : 匹配a-z小写字母的任意一个rewriteRewrite规则 rewrite功能就是, 使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。 rewrite只能放在 server{},location{},if{} 中,并且 只能对域名后边的除去传递的参数外的字符串起作用 ,例如http://seanlook.com/a/we/index.php?id=1&u=str只对/a/we/index.php重写。语法rewrite regex replacement [flag];如果相对域名或参数字符串起作用,可以使用全局变量匹配,也可以使用proxy_pass反向代理。 表明看rewrite和location功能有点像, 都能实现跳转,主要区别在于rewrite是在同一域名内更改获取资源的路径,而location是对一类路径做控制访问或反向代理,可以proxy_pass到其他机器。 很多情况下rewrite也会写在location里,它们的执行顺序是:执行server块的rewrite指令执行location匹配执行选定的location中的rewrite指令如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件; 循环超过10次,则返回500 Internal Server Error错误 。write实例http { # 定义image日志格式 log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status; # 开启重写日志 rewrite_log on; server { root /home/www; location / { # 重写规则信息 error_log logs/rewrite.log notice; # 注意这里要用‘’单引号引起来,避免{} rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4; # 注意不能在上面这条规则后面加上“last”参数,否则下面的set指令不会执行 set $image_file $3; set $image_type $4; } location /data { # 指定针对图片的日志格式,来分析图片类型和大小 access_log logs/images.log mian; root /data/images; # 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,如果还不在就跳转到最后一个url里 try_files /$arg_file /image404.html; } location = /image404.html { # 图片不存在返回特定的信息 return 404 "image not found\n"; } }全局变量可以用作if判断的全局变量下面是可以用作if判断的全局变量$args: #这个变量等于请求行中的参数,同$query_string$content_length: 请求头中的Content-length字段。$content_type: 请求头中的Content-Type字段。$document_root: 当前请求在root指令中指定的值。$host: 请求主机头字段,否则为服务器名称。$http_user_agent: 客户端agent信息$http_cookie: 客户端cookie信息$limit_rate: 这个变量可以限制连接速率。$request_method: 客户端请求的动作,通常为GET或POST。$remote_addr: 客户端的IP地址。$remote_port: 客户端的端口。$remote_user: 已经经过Auth Basic Module验证的用户名。$request_filename: 当前请求的文件路径,由root或alias指令与URI请求生成。$scheme: HTTP方法(如http,https)。$server_protocol: 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。$server_addr: 服务器地址,在完成一次系统调用后可以确定这个值。$server_name: 服务器名称。$server_port: 请求到达服务器的端口号。$request_uri: 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。$uri: 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。$document_uri: 与$uri相同。例:http://localhost:88/test1/test2/test.php$host:localhost $server_port:88 $request_uri:http://localhost:88/test1/test2/test.php $document_uri:/test1/test2/test.php $document_root:/var/www/html $request_filename:/var/www/html/test1/test2/test.php if语句块if判断指令语法为 if(condition){...} ,对给定的条件condition进行判断。如果为真,大括号内的rewrite指令将被执行,if条件(conditon)可以是如下任何内容:当表达式只是一个变量时,如果值为空或任何以0开头的字符串都会当做false直接比较变量和内容时,使用=或!=~正则表达式匹配,~*不区分大小写的匹配,!~区分大小写的不匹配-f和!-f用来判断是否存在文件-d和!-d用来判断是否存在目录-e和!-e用来判断是否存在文件或目录-x和!-x用来判断文件是否可执行例如:if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1 break; } //如果UA包含"MSIE",rewrite请求到/msid/目录下 if ($http_cookie ~* "id=([^;]+)(?:;|$)") { set $id $1; } //如果cookie匹配正则,设置变量$id等于正则引用部分 if ($request_method = POST) { return 405; } //如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302 if ($slow) { limit_rate 10k; } //限速,$slow可以通过 set 指令设置 if (!-f $request_filename){ break; proxy_pass http://127.0.0.1; } //如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查 if ($args ~ post=140){ rewrite ^ http://example.com/ permanent; } //如果query string中包含"post=140",永久重定向到example.com location ~* \.(gif|jpg|png|swf|flv)$ { valid_referers none blocked www.jefflei.com www.leizhenfang.com; if ($invalid_referer) { return 404; } //防盗链 }https**定义一个新的server,配置如下,必须的配置有listen ,server_name, ssl ,ssl_certificate, ssl_certificate_key,一般配置的时候我都是直接复制,然后改主机名,证书私钥文件,日志路径,root的根目录这几项。如果想让访问80的转到443,可用rewrite语句**listen 443; server_name agent.t.jlhcar.com; ssl on; ssl_certificate, "/usr/local/certificate/xxxx.pem";\\证书 ssl_certificate_key "/usr/local/certificate/xxxx.key";\\私钥 ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_prefer_server_ciphers on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2;\\协议 ... //日志以及root根目录的其他配置server { listen 80; server_name www.example.com rewrite ^/(.*)$ https://www.example.com/$1; }php后端处理(fast-cgi)location ~ \.php($|/) { fastcgi_pass unix:/dev/shm/php-fpm.unix; //最重要的一项,根据实际情况来配置(根据php的配置文件listen的配置来配置) fastcgi_index index.php; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi.conf; }flag标志位last: 相当于Apache的[L]标记,表示完成rewritebreak: 停止执行当前虚拟主机的后续rewrite指令集redirect: 返回302临时重定向,地址栏会显示跳转后的地址permanent: 返回301永久重定向,地址栏会显示跳转后的地址因为301和302不能简单的只返回状态码,还必须有重定向的URL,这就是return指令无法返回301,302的原因了。这里 last 和 break 区别有点难以理解:last一般写在server和if中,而break一般使用在location中last不终止重写后的url匹配,即新的url会再从server走一遍匹配流程,而break终止重写后的匹配break和last都能组织继续执行后面的rewrite指令过期功能(浏览器缓存 性能优化)expires(配置在nginx.conf中的server模块中)为用户访问网站的内容设定一个过期时间,当用户第一次访问到这些内容时,会把这些内容存储在用户浏览器本地,这样用户第二次及之后继续访问该网站,浏览器就会检查已经缓存在用户浏览器本地的内容,就不会去浏览器下载了,直到缓存的内容过期或者被清除为止。根据扩展名进行判断location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { root /var/www/static; expires 365d; 当用户访问网站URL结尾的文件扩展名为上述指定类型的图片时,设置缓存365天。 } location ~ .*\.(js|css)?$ { root /var/www/static; expires 30d; #当用户访问网站URL结尾的文件扩展名为js、css类型的元素时,设置缓存30天。 } ……根据URI中的路径(目录)进行判断,添加expires功能范例location ~ ^/ (images|javascript|js|css|flash|media|static)/ { expires 360d; }单个文件添加expires功能范例location ~(robots.txt){ expires 7d; #给robots.txt机器人文件设置过去时间,在设置的期间内不记录404错误日志。 break;}Nginx expires功能缺点及解决方法当网站被缓存的界面或数据更新了,此时用户端看到还是旧的已经缓存的内容,这样就会影响到用户体验,解决方法如下:对于 经常需要变动的图片等文件 ,可以 缩短对象缓存时间。当网站改版或更新时,可以在服务器将缓存的对象改名(代码程序)对于网站的图片、附件,一般不会被用户直接修改,用户层面上的修改图片,实际上个是重新传到服务器,虽然内容一样,但是会产生一个新的图片名称。网站改版升级会修改js、css等样式文件,若改版时对这些样式文件中的元素改了名,会使得前端的CDN及用户端需要重新缓存内容。gzip压缩配置nginx gzip压缩实现性能优化图片、视频(流媒体)等文件尽量不要压缩 ,因为这些文件大多都是经过压缩的,如果再压缩很可能不会减小或减小很少,或者有可能增大,而在压缩时还会消耗大量的CPU、内存资源gzip on; #表示开启压缩功能 gzip_min_length 1k; #表示允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取。默认值是0,表示不管页面多大都进行压缩,建议设置成大于1K。如果小于1K可能会越压越大 gzip_buffers 432k; #压缩缓存区大小 gzip_http_version 1.1; #压缩版本 gzip_comp_level 9; #压缩比率 gzip_types text/css text/xml application/javascript; #指定压缩的类型 gzip_vary on; #vary header支持会话保持时间用户和服务器建立连接后客户端分配keep-alive链接超时时间,服务器将在这个超时时间过后关闭链接,我们将它设置低些可以让ngnix持续工作的时间更长,1.8.1默认为65秒,一般不超过120秒。 keepalive_timeout 65 60; #后面的60为发送给客户端应答报文头部中显示的超时时间设置为60s:如不设置客户端将不显示超时时间。 Keep-Alive:timeout=60 #浏览器收到的服务器返回的报文 如果设置为0表示关闭会话保持功能,将如下显示: Connection:close #浏览器收到的服务器返回的报文配置nginx worker进程最大打开文件数worker_rlimit_nofile 65535;sendfile配置允许sendfile方式传输文件:是由后端程序负责把源文件打包加密生成目标文件,然后程序读取目标文件返回给浏览器;这种做法有个致命的缺陷就是占用大量后端程序资源,如果遇到一些访客下载速度巨慢,就会造成大量资源被长期占用得不到释放(如后端程序占用的CPU/内存/进程等),很快后端程序就会因为没有资源可用而无法正常提供服务。通常表现就是 nginx报502错误,而sendfile打开后配合location可以实现有nginx检测文件使用存在,如果存在就有nginx直接提供静态文件的浏览服务,因此可以提升服务器性能. sendfile on; # 可以配置在http、server或者location模块,配置如下: sendfile_max_chunk 512k; #Nginxg工作进程每次调用sendfile()传输的数据最大不能超出这个值,默认值为0表示无限制,可以设置在http/server/location模块中。单个工作进程的最大连接数配置单个工作进程的最大连接数:通过worker_connections number;进行设置,numebr为整数,number的值不能大于操作系统能打开的最大的文件句柄数,使用ulimit -n可以查看当前操作系统支持的最大文件句柄数,默认为为1024.events { worker_connections 102400; #设置单个工作进程最大连接数102400 }选择事件驱动模型Nginx支持众多的事件驱动,比如 select、poll、epoll ,只能设置在 events模块 中设置:events { accept_mutex on; multi_accept on; use epoll; #使用epoll事件驱动,因为epoll的性能相比其他事件驱动要好很多 }隐藏ngxin版本号隐藏ngxin版本号:当前使用的nginx可能会有未知的漏洞,如果被黑客使用将会造成无法估量的损失,但是我们可以将nginx的版本隐藏,如下:server_tokens off; #在http 模块当中配置网络连接的优化只能在events模块设置,用于防止在同一一个时刻只有一个请求的情况下,出现多个睡眠进程会被唤醒但只能有一个进程可获得请求的尴尬,如果不优化,在多进程的nginx会影响以部分性能。events { accept_mutex on; #优化同一时刻只有一个请求而避免多个睡眠进程被唤醒的设置,on为防止被同时唤醒,默认为off,因此nginx刚安装完以后要进行适当的优化。 }缓存原理及机制什么是Nginx缓存?Nginx基于 Proxy Store 实现,使用Nginx的 http_proxy模块 可以 实现类似于squid的缓存功能 。当启用缓存时, Nginx会将相应数据保存在磁盘缓存中,只要缓存数据尚未过期,就会使用缓存数据来响应客户端的请求 。如何启用缓存?proxy_cache_pathNginx 启用缓存需要在最顶层的http节点下配置proxy_cache_path命令 。我们先看看proxy_cache_path命令的语法结构:proxy_cache_path /data/cache keys_zone=niyueling:10m;可以看到 proxy_cache_path命 令一共 包含两个参数,第一个参数指定缓存保存的本地路径,第二个参数定义缓存数据的共享内存区域的名称和内存区大小 。Nginx启动后, 缓存加载程序只进行加载一次,加载时会将缓存的元数据加载到共享内存区域 ,但是如果一次加载整个缓存全部内容可能会使Nginx刚启动的前几分钟性能消耗严重,大幅度降低Nginx的性能。所以可以在proxy_cache_path命令中 配置缓存迭代加载 。缓存迭代加载一共可以 设置三个参数:loader_threshold - 迭代的持续时间,以毫秒为单位(默认为200)loader_files - 在一次迭代期间加载的最大项目数(默认为100)loader_sleeps - 迭代之间的延迟(以毫秒为单位)(默认为50)我们可以看下一个小例子:proxy_cache_path /data/cache keys_zone=niyueling:10m loader_threshold=300 loader_files=200;proxy_cache在这个例子中缓存迭代加载可以持续300毫秒或者直到加载满200个项目。在http节点下设置完proxy_cache_path命令,下一步在虚拟服务器配置中配置proxy_cache命令,我们可以看看proxy_cache命令的语法结构:proxy_cache niyueproxy_cache_methodsling;可以看到proxy_cache命令很简单,就是指定了我们刚才配置的内存区。但是这里有一点需要额外注意的是:我们刚才通过 配置proxy_cache_path命令的keys_zone参数配置内存区大小为10m,这并不会限制缓存数据的大小 ,实际上缓存数据是存储在文件系统中的特定文件的元数据副本。 如果想要限制缓存数据的上限,则需要在proxy_cache_path命令中添加max_size参数设置缓存数据上限。 说完了proxy_cache命令。我们接着看看下一个命令:proxy_cache_methods,我们看下该命令语法结构:proxy_cache_methods[GET HEAD POST];proxy_cache_valid在虚拟服务器下配置 proxy_cache_methods 命令可以 指定该虚拟服务器下什么类型的HTTP方法可以被缓存。默认情况下GET请求及HEAD请求会被缓存,而POST请求不会被缓存。 接下来看看另外一个常见的命令: proxy_cache_valid ,先贴下该命令语法结构:proxy_cache_valid reply_code [reply_code...] time;这个命令很有意思,在虚拟服务器下设置该命令,它可以针对不同状态码的响应数据设置不同的缓存时间,我们可以看个简单的小例子:proxy_cache_valid 200 10m ; proxy_cache_valid 404 1m ; proxy_cache_valid 302 5m ;我们通过上面的命令就可以 设置200状态码的缓存时间为10分钟,302重定向的缓存时间为5分钟,404的缓存时间为1分钟 。如果想为 所有状态码定义相同缓存时间,就可以使用any作为第一个参数:proxy_cache_valid any 5m;proxy_cache_bypass接下来看看下一个命令:proxy_cache_bypass。一样先看下语法结构:proxy_cache_bypass cookie_nocachearg_nocache$arg_comment;这个命令可以配置不会向客户端响应缓存,而是直接将请求转发给后端服务进行请求数据。 可以通过上述命令配置需要绕过缓存的请求URL ,也就是说URL中包含该配置的值,则这次请求会直接跳过缓存直接请求后端服务去获取数据。proxy_cache_min_uses接下来还有最后一个比较常用的命令:proxy_cache_min_uses。先贴下语法结构:proxy_cache_min_uses 2;这个命令可以 设置当某请求最少响应几次后会被缓存 。若我设置为2则表示每个请求 最少被请求2次后会加入到缓存中 。Nginx清除缓存如果缓存过期则需要从缓存中删除过期的缓存文件,防止新旧缓存出现交错出错,当Nginx接收到自定义HTTP头或者PURGE请求时,缓存将会被清除。配置缓存清除我们在HTTP节点下创建一个新变量$purge_method来标识使用PURGE方法的请求并删除匹配的URL。http { map request_methodpurge_method { PURGE 1; default 0; } }进入虚拟服务器配置, 在location中配置高速缓存,并且指定缓存清除请求命令proxy_cache_purge。server { listen 80; server_name www.niyueling.cn; location / { proxy_cache niyueling; proxy_cache_purge $purge_method; } }发送清除命令配置proxy_cache_purge指令后需要发送PURGE请求来清除缓存。例如我们使用PURGE方式请求url:PURGE www.niyueling.cn/getArticle则getArticle对应的缓存中的数据将被删除。但是,这些高速缓存数据不会从缓存中完全删除,它们将保留在磁盘上,直到它们被删除为非活动状态,或由缓存清除进程处理。限制IP访问清除命令清除缓存这种命令一般需要权限才可进行操作,所以我们一般需要配置允许发送缓存清除请求的IP地址:geo purge_allowed { default 0; 49.235.28.88 1; 192.168.1.100/24 1; } maprequest_method purge_method { PURGEpurge_allowed; default 0; }当Nginx接收到清除缓存请求时,Nginx检查客户端IP地址,若IP地址已经获得清除缓存权限,则purge_method设置为purge_allowed,值为1表示允许清除缓存,值为0表示表示IP地址未获得权限。从缓存中完全删除文件刚才说过了高速缓存数据不会从缓存中完全删除,它们将保留在磁盘上,直到它们被删除为非活动状态,或由缓存清除进程处理。要完全删除与getArticle相匹配的缓存数据,需要在proxy_cache_path添加参数purger,该参数表示永久的遍历所有缓存条目,并删除与通配符相匹配的条目。proxy_cache_path /data/cache keys_zone=niyueling:10m purger=on;字节缓存当我们请求一个大文件时,因为请求比较耗时,当有下一个请求来临时将不得不等待整个大文件被下载并放入高速缓存。 Nginx用缓存片模块填充高速缓存 。可以将大文件分为较小的切片,每个范围请求选择将覆盖所请求范围的特定切片,并且如果此范围切片仍未缓存,就将其放入缓存中。 启用字节范围缓存需要注意两个条件是否满足 :确保Nginx是使用模块编译的。使用slice指令指定切片的大小。可以使用slice命令指定切片大小:location / { slice 1m; }使用slice指令指定切片大小时应注意切片大小应适当调整,使切片快速下载。因为切片大小指定太小可能会导致内存使用量过多和大量打开的文件描述符,切片大小指定太大的值可能会导致请求延迟。接着将$slice_range变量加入到缓存键中:proxy_cache_key uriis_argsargsslice_range;使用206状态代码缓存响应,缓存有效期30m:proxy_cache_valid 206 30m;然后设置Range头传递$slice_range变量来将传递范围请求:proxy_set_header Range $slice_range;字节缓存小案例:location / { slice 1m; proxy_cache niyueling; proxy_cache_key uriis_argsargsslice_range; proxy_set_header Range $slice_range; proxy_cache_valid 206 30m; }缓存清除小案例http { proxy_cache_path /data/cache keys_zone=niyueling:10m purger=on; map request_methodpurge_method { PURGE 1; default 0; } server { listen 80; server_name www.niyueling.cn; location / { proxy_cache niyueling; proxy_cache_purge $purge_method; } } geo $purge_allowed { default 0; 49.235.28.88 1; 192.168.1.100/24 1; } map request_methodpurge_method { PURGE $purge_allowed; default 0; } }限流在当今流量徒增的互联网时代,很多业务场景都会涉及到高并发。这个时候 接口进行限流是非常有必要的,而限流是Nginx最有用的特性之一,而且也是最容易被错误配置的特性之一。 本篇文章主要讲讲Nginx如何对接口进行限流。为什么需要限流?开源人员可以通过限流限制访问速度来防止外部暴力扫描,或者减少密码被暴力破解的可能性。也可以解决流量突发问题(如线上活动导致访问量突增)。用一句话来概括就是说限流是用于保护服务器不会因为承受不住同一时刻的大量并发请求而宕机。Nginx限流主要分为两种方式:限制访问频率限制并发连接数接下来我们分别来看看Nginx的两种限流方式:限制访问频率限制访问频率其实需要分成两种情况:正常情况下进行访问频率限制以及流量突发情况下进行访问频率限制。我们分别看看这两种情况下Nginx是如何进行处理的:正常流量限制访问频率Nginx中使用ngx_http_limit_req_module模块来限制的访问频率 ,限制的原理实质是 基于漏桶算法原理来实现的 。在nginx.conf配置文件中 可以使用limit_req_zone命令及limit_req命令限制单个IP的请求处理频率。 我们可以先来看看这两个命令的语法结构:limit_req_zone key zone rate对于上面语法结构的参数简单做下解释:key: 定义需要限流的对象。zone: 定义共享内存区来存储访问信息。rate: 用于设置最大访问速率。接下来我们看个简单的例子: http { limit\_req\_zone $binary\_remote\_addr zone=myLimit:10m rate=3r/s; } server { location / { limit\_req zone=myLimit; rewrite / [http://www.niyueling.cn](https://links.jianshu.com/go?to=http%3A%2F%2Fwww.niyueling.cn) permanent; } }对配置简单做下解释:上面binary_remote_addr就是key,表示基于客户端ip(remote_addr)进行限流,binary_表示压缩内存占用量。定义了一个大小为10M,名称为myLimit的内存区,用于存储IP地址访问信息。rate设置IP访问频率, rate=5r/s表示每秒只能处理每个IP地址的5个请求。Nginx限流是按照毫秒级为单位的,也就是说1秒处理5个请求会变成每200ms只处理一个请求。如果200ms内已经处理完1个请求,但是还是有有新的请求到达,这时候Nginx就会拒绝处理该请求。突发流量限制访问频率上面的配置一定程度可以限制访问频率,但是也存在着一个问题:如果突发流量超出请求被拒绝处理,无法处理活动时候的突发流量,这时候应该如何进一步处理呢?Nginx提供burst参数结合nodelay参数可以解决流量突发的问题,可以设置能处理的超过设置的请求数外能额外处理的请求数。我们可以将之前的例子 添加burst参数以及nodelay参数: http { limit\_req\_zone $binary\_remote\_addr zone=myLimit:10m rate=3r/s; } server { location / { limit\_req zone=myLimit burst=5 nodelay; rewrite / [http://www.niyueling.cn](https://links.jianshu.com/go?to=http%3A%2F%2Fwww.niyueling.cn) permanent; } }可以看到我在原有的 location中的limit_req指令中添加了burst=5 nodelay ,如果没有添加nodelay参数,则可以理解为预先在内存中占用了5个请求的位置,如果有5个突发请求就会按照200ms去依次处理请求,也就是1s内把5个请求全部处理完毕。如果1s内有新的请求到达也不会立即进行处理,因为紧急程度更低。这样实际上就会将额外的5个突发请求以200ms/个去依次处理,保证了处理速率的稳定,所以在处理突发流量的时候也一样可以正常处理。如果添加了nodelay参数则表示要立即处理这5个突发请求。限制并发连接数Nginx中的ngx_http_limit_conn_module模块提供了限制并发连接数的功能,可以使用limit_conn_zone指令以及limit_conn执行进行配置。 接下来我们可以通过一个简单的例子来看下: http { limit\_conn\_zone ![binary_remote_addr zone=myip:10m; limit_conn_zone](https://math.jianshu.com/math?formula=binary_remote_addr%20zone%3Dmyip%3A10m%3B%20limit_conn_zone)server\_name zone=myServerName:10m; } server { location / { limit\_conn myip 10; limit\_conn myServerName 100; rewrite / [http://www.niyueling.cn](https://links.jianshu.com/go?to=http%3A%2F%2Fwww.niyueling.cn) permanent; } }上面配置了单个IP同时并发连接数最多只能10个连接,并且设置了整个虚拟服务器同时最大并发数最多只能100个链接。 当然,只有当请求的header被服务器处理后,虚拟服务器的连接数才会计数。刚才有提到过Nginx是基于漏桶算法原理实现的,实际上限流一般都是基于漏桶算法和令牌桶算法实现的。接下来我们来看看两个算法的介绍:漏桶算法漏桶算法是网络世界中流量整形或速率限制时经常使用的一种算法,它的主要目的是控制数据注入到网络的速率,平滑网络上的突发流量。漏桶算法提供了一种机制,通过它,突发流量可以被整形以便为网络提供一个稳定的流量。也就是我们刚才所讲的情况。漏桶算法提供的机制实际上就是刚才的案例: 突发流量会进入到一个漏桶,漏桶会按照我们定义的速率依次处理请求,如果水流过大也就是突发流量过大就会直接溢出,则多余的请求会被拒绝。所以漏桶算法能控制数据的传输速率。令牌桶算法令牌桶算法是网络流量整形和速率限制中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。Google开源项目Guava中的RateLimiter使用的就是令牌桶控制算法。 令牌桶算法的机制如下:存在一个大小固定的令牌桶,会以恒定的速率源源不断产生令牌。如果令牌消耗速率小于生产令牌的速度,令牌就会一直产生直至装满整个令牌桶。漏桶算法与令牌桶算法的区别两种算法都能够限制数据传输速率,但令牌桶还允许某种程度的突发传输。因为令牌桶算法只要令牌桶中存在令牌,那么就可以突发的传输对应的数据到目的地,所以更适合流量突发的情形下进行使用。日志配君众所周知,线上如果出现事故我们通常都是查看日志去进行问题定位并且进行修复。使用好Nginx日志有利于我们线上进行修复异常问题。 在Nginx中日志主要分为两种:access_log(访问日志)和error_log(错误日志) 。通过 查看access_log我们可以查看用户ip,浏览器信息及请求时间等信息,通过查看error_log我们可以查看线上出错的具体信息,可以帮助我们定位异常的原因。 本篇文章主要带领大家详细了解Nginx如何配置日志。本文将会涉及到的日志配置指令:access_loglog_formatopen_log_file_cachelog_not_foundlog_subrequestrewrite_logerror_logaccess_log指令首先,我们可以先看看access_log指令。access_log命令 可以配置访问日志 。我们可以先看下access_log指令的语法结构:access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]]; # 设置访问日志access_log off; # 关闭访问日志我们先来看看语法结构中的参数的含义:path: 指定日志的存放位置format: 指定日志的格式,非必填,默认为预定义的combinedbuffer:指定日志写入时的缓存大小,非必填,默认64kgzip: 日志写入前先进行压缩flush: 设置缓存的有效期if: 设置条件判断,当天剑成立时才会写入日志off: 值为off表示不开启日志,值为on表示开启日志access_log指令可以使用于http根节点,虚拟服务器server节点,上下文配置location以及limit_except中。无法在其他作用域使用access_log指令,否则Nginx会报错。我们可以看一个简单的配置access_log的小例子:access_log /root/.pm2/logs/niyueling.log buffer=32k gzip flush=5m这个配置指定日志存储路径为/root/.pm2/logs/niyueling.log,日志使用默认格式combined。日志缓存大小为32k,日志写入前会进行gzip压缩,缓存有效期为5分钟。log_format指令刚才有讲过如果未指定日志格式,Nginx会 使用combined日志格式为默认格式。 combined日志格式默认使用格式为:log_format combined 'remote_addr -remote_user [![time_local] ' '"](https://math.jianshu.com/math?formula=time_local] ' '")request" statusbody_bytes_sent ' '"http_referer" "http_user_agent"';但是如果不想使用combined日志格式,就可以使用log_format指令来自定义格式内容。log_format指令需要在http节点下进行配置。我们先来看下log_format指令的语法结构:log_format name [escape=default|json] string;我们先来看看log_format的参数对应的用法:name: 指定日志格式名称,因为在access_log指令中需要指定日志格式escape: 设置字符编码方式,可以选择default或者jsonstring: 要写入日志的内容,可以有多个参数,可以使用Nginx变量。下面贴一下log_format指令中常用的一些变量:file 我们可以接着看个自定义日志格式的小案例:http { log_format main 'remote_addr -remote_user [![time_local] "](https://math.jianshu.com/math?formula=time_local] ")request" ' '"status"body_bytes_sent "http_referer" ' '"http_user_agent" "http_x_forwarded_for" ' '"gzip_ratio" request_timebytes_sent $request_length'; server { server_name www.niyueling.cn; access_log /root/.pm2/logs/niyueling.log main; } }open_log_file_cache指令对于网站的访问记录,通常操作都是首先打开日志文件,然后写入日志记录,最后关闭文件。 默认情况下日志文件不进行缓存的,我们可以通过open_log_file_cache指令设置日志文件缓存。 open_log_file_cache指令可以配置在http根节点,虚拟服务器server节点以及上下文location中。我们先看下open_log_file_cache指令的语法结构:open_log_file_cache max=X [inactive=time] [min_uses=N] [valid=time];open_log_file_cache off;首先先贴下参数对应的含义:max: 设置缓存中的最大文件描述符inactive: 设置存活时间min_uses: 在存活时间内,日志文件最少被使用几次后将日志文件描述符写入缓存。valid: 设置检查频率off: 禁用日志缓存可以看一个简单配置日志缓存的小例子:open_log_file_cache max=100 inactive=30s valid=5m min_uses=3;log_not_found指令这个命令 用于指定是否在error_log错误日志中记录不存在的错误,如文件不存在等。 默认值为是。我们可以先看下语法结构:log_not_found on | off;log_not_found指令可以配置在http根节点,虚拟服务器server节点以及上下文location中。设置为on表示记录不存在的错误,设置为off表示不记录不存在的错误。log_subrequest指令log_subrequest指令用于指定在access_log访问日志中是否记录子请求的访问记录。默认情况为不记录,贴下语法结构:log_subrequest on | off;log_subrequest指令可以配置在http根节点,虚拟服务器server节点以及上下文location中。设置为on表示记录子请求访问记录,设置为off表示不记录子请求访问记录。rewrite_log指令rewrite_log指令 由ngx_http_rewrite_module模块提供服务,用来记录日志重写。 可以在error_log错误日志中记录notice级别的重写日志。 默认是不启用状态 ,贴下语法结构:rewrite_log on | off;rewrite_log指令可以配置在http根节点,虚拟服务器server节点以及上下文location以及if条件判断中。设置为on表示在错误日志中记录notice级别的重写日志,设置为off表示在错误日志中不记录notice级别的重写日志。error_log指令error_log指令顾名思义,就是 用来指定错误日志的,一般来说线上出现bug都是通过error_log日志来定位问题所在而加以解决的 。error_log指令可以记录服务器和请求处理过程中的错误信息。我们先看下error_log指令的语法结构:error_log file [level];参数含义其实很容易可以理解:file: error_log 存放路径level: 日志级别,只有日志级别高于指定级别才会记录到error_log中error_log指令可以配置在http节点,main节点,虚拟服务器server节点以及上下文location中。日志切割Nginx记录日志默认情况下是访问日志全部写入access_log中,错误日志全部写入error_log中。这样会导致日志文件原来越大,不利于查看日志分析问题异常,所以我们可以将日志以日期为单位进行切割。首先需要写一个脚本实现Nginx按天切割:日志保存位置base_path='/root/.pm2/logs/niyueling.log'获取当前年信息和月信息log_path=$(date -d yesterday +"%Y%m")获取昨天的日信息day=$(date -d yesterday +"%d")按年月创建文件夹mkdir -p base_path/log_path备份昨天的日志到当月的文件夹mv base_path/access.logbase_path/log_path/access_day.log输出备份日志文件名echo base_path/log_path/access_$day.log通过Nginx信号量控制重读日志kill -USR1 cat /opt/nginx/logs/nginx.pid然后给脚本添加可执行权限,最后添加Linux定时任务:crontab -e每天凌晨两点半进行日志分割30 02 0 * /root/.pm2/logs/splitLog.sh重启Linux定时任务crond restart通过上面的讲解差不多可以知道Nginx对于日志是如何进行配置的,实际上就是通过log_format配置日志格式,如果log_format中使用了Nginx变量,则可以通过open_log_file_cache指令来设置缓存提高性能。然后通过access_log进行设置访问日志,通过error_log指令设置错误日志。最后实现定时任务定时切割每天的日志,有利于我们后期维护。灰度发布根据ip实现灰度发布在百度查自己公司的公网IP原理同时把两个不同版本的代码拉成两个项目,根据ip来判断用户可以去哪个项目,灰度发布的项目目录指向高版本的项目,其他ip的所有用户仍然访问相对的低版本的项目。nginx配置server { listen 80; server_name mb.com; gzip on; charset utf-8; set $mulu /var/www/mb/dist ; if ($remote_addr = 1.2.3.4) { set $mulu /var/www/mr/build; } location / { root $mulu; index index.html; location / { try_files $uri $uri/ /index.html; } } }配置一键生成前因关于Nginx部署、配置的文章网上已经发布过很多,包括我自己也私藏了不少还发布过两篇:后端必备 Nginx 配置 前端必备 Nginx 配置 整理出来为的就是需要的时候,复制、粘贴就能使用。然而千奇百怪的实际开发中,你肯定需要增删Nginx配置。你就得上网搜一下,复制粘贴出bug了又得调一下...搞定还得保存下来以备后患。多了不好找还得整理...就搞得很麻烦后果今天我给大家推荐一款"Nginx配置利器",配配变量就能一键生成常用配置。和繁琐低效配置说再见👋网站链接:nginxconfig 在线配置网站nginxconfig github项目nginxconfig 目前支持:Angular、React、Vue、Node.jsPHP、Pythonwordpress、Magento、Drupal缓存、Https、日志等各种配置...使用实现用户访问*.myweb.com域名自动跳转到myweb.com配置,并且开启http强制跳转到https的配置。配置完之后,下方还有安装步骤指导你配置生效。交互体验相当好生成配置/etc/nginx/sites-available/myweb.com.conf如下:server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name myweb.com; root /var/www/myweb.com/public; # SSL ssl_certificate /etc/letsencrypt/live/myweb.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/myweb.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/myweb.com/chain.pem; # security include nginxconfig.io/security.conf; # index.html fallback location / { try_files $uri $uri/ /index.html; } # additional config include nginxconfig.io/general.conf; } # subdomains redirect server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name *.myweb.com; # SSL ssl_certificate /etc/letsencrypt/live/myweb.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/myweb.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/myweb.com/chain.pem; return 301 https://myweb.com$request_uri; } # HTTP redirect server { listen 80; listen [::]:80; server_name .myweb.com; include nginxconfig.io/letsencrypt.conf; location / { return 301 https://myweb.com$request_uri; } }网站下方还罗列了推荐的nginx配置、安全配置...以作参考/etc/nginx/nginx.conf# Generated by nginxconfig.io # https://nginxconfig.io/?0.domain=myweb.com&0.php=false&0.index=index.html&0.fallback_html user www-data; pid /run/nginx.pid; worker_processes auto; worker_rlimit_nofile 65535; events { multi_accept on; worker_connections 65535; } http { charset utf-8; sendfile on; tcp_nopush on; tcp_nodelay on; server_tokens off; log_not_found off; types_hash_max_size 2048; client_max_body_size 16M; # MIME include mime.types; default_type application/octet-stream; # logging access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log warn; # SSL ssl_session_timeout 1d; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; # Diffie-Hellman parameter for DHE ciphersuites ssl_dhparam /etc/nginx/dhparam.pem; # Mozilla Intermediate configuration ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; # OCSP Stapling ssl_stapling on; ssl_stapling_verify on; resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s; resolver_timeout 2s; # load configs include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }/etc/nginx/nginxconfig.io/security.conf# security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; # . files location ~ /\.(?!well-known) { deny all; }拓展以上就满足日常开发需求啦。如果你压抑不住,想要展示你的高端操作。你可以加入到项目本身开发中;nginxconfig项目本身是 MIT 开源协议,你也可以在此基础上迭代出自己的版本其他配置/案例全面认识Nginx常用配置小试牛刀!Nginx 搭建静态资源服务器Nginx 五大常见应用场景Web服务器王者之争:Apache vs NginxNginx 又一牛X的功能!流量拷贝构建高效安全的Nginx Web服务器为什么站点访问慢?请收好这份 Web 服务器性能提升的总结
2023年08月18日
16 阅读
0 评论
0 点赞
1
...
42
43
44
...
112