当前位置: 首页 > news >正文

公司网站域名及空间wordpress小技巧

公司网站域名及空间,wordpress小技巧,如何建设国外网站,惠州做网站乐云seoNginx基本概念 return和rewrite对比 Nginx配置说明 worker_processes #官方说明#xff1a;一个CPU配置多于一个worker数#xff0c;对Nginx而言没有任何益处。所以worker数量尽量不要超过CPU内核数量。一般worker数量设置为CPU内核数量。#标准配置 worker_processes auto…Nginx基本概念 return和rewrite对比 Nginx配置说明 worker_processes #官方说明一个CPU配置多于一个worker数对Nginx而言没有任何益处。所以worker数量尽量不要超过CPU内核数量。一般worker数量设置为CPU内核数量。#标准配置 worker_processes auto;worker_connections #针对每一个worker进程的连接数。已验证在只有一个工作进程时该连接数的设置除半就是Nginx的并发连接数。当多个worker进程时并发连接数就会翻倍。#官方说明每一个worker进程能并发处理和发起的最大连接数包含所有连接数。真实的并发连接数不能超过最大文件打开数worker_rlimit_nofile但是配置时超不超过无所谓也就是说并发数也受worker_rlimit_nofile数量所限制。#worker_connections的限制不能超过最大文件打开数在linux终端中输入ulimit -a进行查看。#标准配置 worker_connections 65535;worker_rlimit_nofile #针对每一个worker进程的连接数#官方说明为nginx工作进程改变打开最多文件描述符数目的限制。用来在不重启主进程的情况下增加限制。#标准配置 worker_rlimit_nofile 204800; #需要配置成CPU数和worker_connections乘积还要多Nginx网络模型 老Nginx模型 ​ 主进程 多个 worker 子进程这也是最常用的一种模型。这种方法的一个通用工作模式就是 主进程执行 bind() listen() 后创建多个子进程 ​ 然后在每个子进程中都通过 accept() 或 epoll_wait() 来处理相同的套接字。 ​ 比如最常用的反向代理服务器 Nginx 就是这么工作的。它也是由主进程和多个 worker 进程组成。主进程主要用来初始化套接字并管理子进程的生命周期而 worker 进程则负责实际的请求处理。我画了一张图来表示这个关系。 ​ 这里要注意accept() 和 epoll_wait() 调用还存在一个惊群的问题。换句话说当网络 I/O 事件发生时多个进程被同时唤醒但实际上只有一个进程来响应这个事件其他被唤醒的进程都会重新休眠。 其中accept() 的惊群问题已经在 Linux 2.6 中解决了 而 epoll 的问题到了 Linux 4.5 才通过 EPOLLEXCLUSIVE 解决。 ​ 为了避免惊群问题 Nginx 在每个 worker 进程中都增加一个了全局锁accept_mutex。这些 worker 进程需要首先竞争到锁只有竞争到锁的进程才会加入到 epoll 中这样就确保只有一个 worker 子进程被唤醒。 新Nginx模型 ​ 监听到相同端口的多进程模型 在这种方式下所有的进程都监听相同的接口并且开启 SO_REUSEPORT 选项由内核负责将请求负载均衡到这些监听进程中去。这一过程如下图所示。 安装Nginx 编译安装Nginx 下载依赖包 [rootkuang-73 ~]# yum -y install zlib zlib-devel pcre pcre-devel openssl openssl-devel automake autoconf gcc gcc-c 编译安装 [rootkuang-73 ~]# ./configure –prefix/usr/local/nginx –usernginx –groupnginx –without-http_uwsgi_module –without-http_scgi_module –without-http_browser_module –with-pcre –with-http_addition_module –with-http_ssl_module –with-http_realip_module –with-http_sub_module –with-http_flv_module –with-http_mp4_module –with-http_gzip_static_module –with-http_gunzip_module –with-http_secure_link_module –with-http_stub_status_module –add-module…/nginx-rtmp-module-master #没有需要附加的模块就将该行删除 [rootkuang-73 ~]# make -j 4 make install 模块说明 ①实际使用模块 http_gzip_static_module 压缩功能 http_stub_status_module 内置的状态页 http_addition_module 过滤器的支持 http_dav_module 网页输入命令的支持put等操作 ngx_http_autoindex_module.o 目录浏览的模块默认安装 ngx_http_auth_basic_module.o 基础认证默认安装 mp4或者flv实现了在线MP4播放已验证成功 ②编译携带参数 –with-http_addition_module #启用支持作为一个输出过滤器支持不完全缓冲分部分相应请求 –with-http_sub_module #启用支持允许一些其他文本替换Nginx相应中的一些文本 –with-http_flv_module #启用支持提供支持flv视频文件支持 –with-http_mp4_module #启用支持提供支持mp4视频文件支持提供伪流媒体服务端支持 拓展nginx启动错误 ①启动nginx报错 [rootkuang-73 ~]# /usr/local/nginx/sbin/nginx nginx: [emerg] getpwnam(“nginx”) failed ②那是因为编译安装指定了用户nginx所以要新增该用户 [rootkuang-73 ~]# useradd -s /sbin/nologin -M nginx Nginx生产环境编译参数 ①Nginx生产环境编译参数 –prefix/data/nginx --usernginx --groupnginx --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_flv_module --with-http_ssl_module --with-http_mp4_module --with-pcre/data/tmp/pcre-8.42 --with-openssl/data/tmp/openssl-1.0.2o --with-zlib/data/tmp/zlib-1.2.11 --with-http_v2_module --with-http_image_filter_module --with-stream ②编译参数说明 #注意生产环境下的一些模块是通过编译安装添加的 with-stream用来实现TCP代理而不是仅仅代理80或443端口对应的模块为ngx_stream_core_module默认是不安装需要编译时增加–with-stream ③stream模块相比http模块的功能 只有http模块时虽然在http代码块下的server代码块中可以写任意端口除了80或443但是Nginx代理你去访问的时候只会使用Http协议所以使用http模块不可能实现其他服务的代理比如MySQL的代理 当有stream模块时则可以通过stream模块实现TCP任意端口的代理比如实现MySQL的代理。 编译安装LNMP 安装LNMP架构需要的依赖包 [rootkuang-75 ~]# yum -y install make gcc gcc-c flex bison file libtool libtool-libs autoconf kernel-devel libjpeg libjpeg-devel libpng libpng-devel gd freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glib2 glib2-devel bzip2 bzip2-devel libevent ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5-devel libidn libidn-devel openssl openssl-devel gettext gettext-devel ncurses-devel gmp-devel unzip libcap lsof 部署Nginx 1、安装Nginx ①安装Nginx依赖包 [rootkuang-75 ~]# yum -y install gcc gcc-c autoconf automake zlib zlib-devel openssl openssl-devel pcre* ②创建Nginx运行账户 [rootkuang-75 ~]# useradd -M -s /sbin/nologin nginx ③下载Nginx和pcre http://nginx.org/download/nginx-1.14.1.tar.gz ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.41.tar.gz ④解压Nginx和pcre到指定目录 [rootkuang-75 ~]# tar xf pcre-8.41.tar.gz -C /usr/local/src/ [rootkuang-75 ~]# tar xf nginx-1.14.2.tar.gz -C /usr/local/src/ ⑤编译安装Nginx [rootkuang-75 ~]# cd /usr/local/src/nginx-1.14.2/ [rootkuang-75 nginx-1.14.2]# ./configure --prefix/usr/local/nginx --with-http_dav_module --with-http_stub_status_module --with-http_addition_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module --with-pcre/usr/local/src/pcre-8.41 --usernginx --groupnginx [rootkuang-75 nginx-1.14.2]# make -j 4 make install ⑥创建Nginx启动快捷键 [rootkuang-75 ~]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ 2、启用PHP支持 ①备份配置文件 [rootkuang-75 ~]# cp /usr/local/nginx/conf/nginx.conf{,.bak} ②编辑配置文件支持PHP [rootkuang-75 ~]# vim /usr/local/nginx/conf/nginx.conf 步骤1、修改用户nobody为nginx 步骤2、取消注释启用PHP段的location 步骤3、将/scripts替换成/usr/local/nginx/html ③创建PHP页面 [rootkuang-75 ~]# echo “?php phpinfo(); ?” /usr/local/nginx/html/index.php ④启动Nginx [rootkuang-75 ~]# nginx 部署MySQL5.6版本 #注要源码编译安装MySQL需要大于13G的磁盘空间 1、创建MySQL安装环境 ①添加一块20G磁盘 ②把系统自带的boost库卸载源码编译安装高版本 [rootkuang-75 ~]# yum -y remove boost-* #MySQL5.6不依赖于该boost库这步可省 ③卸载系统自带的mysql [rootkuang-75 ~]# yum -y remove mysql mariadb-* ④安装依赖包 [rootkuang-75 ~]# yum install -y cmake make gcc gcc-c bison ncurses ncurses-devel #cmake版本要2.8以上 ⑤添加用户和组 [rootkuang-75 ~]# groupadd mysql [rootkuang-75 ~]# useradd -M -s /sbin/nologin -r -g mysql mysql 2、下载和解压MySQL源码包 ①mysql程序包下载地址 http://www.mysql.com/Downloads/MySQL-5.6/mysql-5.6.35.tar.gz #MySQL5.6版本不需要boost库 ②解压源码包 [rootkuang-75 ~]# tar xf mysql-5.6.35.tar.gz -C /usr/local/src/ 3、规划安装目录 ①安装目录: /var/lib/mysql [rootkuang-75 ~]# mkdir -p /var/lib/mysql ②将新添磁盘挂载到mysql目录 [rootkuang-75 ~]# mount /dev/sdb1 /var/lib/mysql/ ③创建数据目录: /var/lib/mysql/data [rootkuang-75 ~]# mkdir -p /var/lib/mysql/data #第一步不能创建data目录因为会被挂载覆盖 ④修改权限 [rootkuang-75 ~]# chown -R mysql:mysql /var/lib/mysql 4、编译安装MySQL ①mysql-5.6.35的构建命令和参数 [rootkuang-75 mysql-5.6.35]# cmake -DCMAKE_INSTALL_PREFIX/var/lib/mysql -DMYSQL_DATADIR/var/lib/mysql/data -DSYSCONFDIR/etc -DWITH_MYISAM_STORAGE_ENGINE1 -DWITH_INNOBASE_STORAGE_ENGINE1 -DWITH_MEMORY_STORAGE_ENGINE1 -DWITH_READLINE1 -DMYSQL_UNIX_ADDR/var/lib/mysql/mysql.sock -DMYSQL_TCP_PORT3306 -DENABLED_LOCAL_INFILE1 -DWITH_PARTITION_STORAGE_ENGINE1 -DEXTRA_CHARSETSall -DDEFAULT_CHARSETutf8 -DDEFAULT_COLLATIONutf8_general_ci ②编译和安装 [rootkuang-75 mysql-5.6.35]# make -j 4 #编译过程很可能由于磁盘、内存和CPU不足出问题 [rootkuang-75 mysql-5.6.35]# make install ③修改MySQL文件的属主 [rootkuang-75 ~]# chown -R mysql:mysql /var/lib/mysql/ 5、MySQL初始化配置 ①编辑配置文件 [rootkuang-75 mysql]# cp support-files/my-default.cnf /etc/my.cnf [rootkuang-75 ~]# vim /etc/my.cnf #前四项配置必须有后面可省略 [mysqld] basedir/var/lib/mysql datadir/var/lib/mysql/data port3306 socket/var/lib/mysql/mysql.sock #socket位置需按照编译安装时指定的socket位置 character-set-serverutf8 log-error/var/log/mysqld.log pid-file/tmp/mysqld.pid [mysql] socket/var/lib/mysql/mysql.sock [client] socket/var/lib/mysql/mysql.sock ②编辑启动脚本 [rootkuang-75 mysql]# cp support-files/mysql.server /etc/init.d/mysqld [rootkuang-75 ~]# chmod x /etc/init.d/mysqld [rootkuang-75 ~]# vim /etc/init.d/mysqld basedir/var/lib/mysql datadir/var/lib/mysql/data ③添加其他MySQL自带命令的快捷启动 [rootkuang-75 ~]# ln -s /var/lib/mysql/bin/* /usr/sbin/ #或者添加环境变量方式 ④初始化数据库 [rootkuang-75 scripts]# ./mysql_install_db --basedir/var/lib/mysql --datadir/var/lib/mysql/data --usermysql ⑤启动mysql [rootkuang-75 ~]# /etc/init.d/mysqld start #启动后会自动生成socket文件 ⑥安全初始化 [rootkuang-75 ~]# /var/lib/mysql/bin/mysql_secure_installation ⑦修改初始密码如果未进行安全初始化 [rootkuang-75 ~]# mysql mysql set password for rootlocalhost password(‘123456’); mysql flush privileges; 部署PHP5.6 1、创建PHP安装环境 ①依赖包下载地址可省略通过yum安装 http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz http://iweb.dl.sourceforge.net/project/mcrypt/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz http://iweb.dl.sourceforge.net/project/mcrypt/MCrypt/2.6.8/mcrypt-2.6.8.tar.gz ②下载依赖包 [rootkuang-75 ~]# yum -y install php-mcrypt libmcrypt libmcrypt-devel php-pear libxml2 libxml2-devel curl curl-devel libjpeg libjpeg-devel libpng libpng-devel freetype-devel 2、编译安装PHP ①下载并上传PHP http://jp2.php.net/distributions/php-7.1.24.tar.gz #替换版本号即可替换所下载的软件包 ②解压到指定目录 [rootkuang-75 ~]# tar xf php-5.6.36.tar.gz -C /usr/local/src/ [rootkuang-75 ~]# cd /usr/local/src/php-5.6.36/ ③编译安装PHP [rootkuang-75 php-5.6.36]# ./configure --prefix/usr/local/php --with-config-file-path/usr/local/php/ --enable-fpm --with-mysqlimysqlnd --with-pdo-mysqlmysqlnd --with-iconv-dir --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir/usr --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-mbstring --with-mcrypt --enable-ftp --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --without-pear --with-gettext --disable-fileinfo --enable-maintainer-zts [rootkuang-75 php-5.6.36]# make -j 4 make install 3、PHP初始化配置 ①编辑配置文件 [rootkuang-75 php-5.6.36]# cp php.ini-production /usr/local/php/php.ini #PHP主配置文件 [rootkuang-75 php-5.6.36]# cd /usr/local/php/etc/ [rootkuang-75 etc]# mv php-fpm.conf.default php-fpm.conf #php-fpm配置文件 ②修改运行用户 [rootkuang-75 etc]# vim php-fpm.conf user nginx group nginx ③编辑启动脚本 [rootkuang-75 ~]# cp /usr/local/src/php-5.6.36/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm [rootkuang-75 ~]# chmod x /etc/init.d/php-fpm [rootkuang-75 ~]# chkconfig php-fpm on #设置为开机启动 ④启动php-fpm [rootkuang-75 ~]# /etc/init.d/php-fpm start [rootkuang-75 ~]# netstat -antup | grep 9000 #到此结束Nginx已经可将PHP脚本提交上来处理 4、给user授权可修改配置和重启nginx权限 chown -R root:users /data/home/user00/nginx/sbin/nginx chmod s /data/home/user00/nginx/sbin/nginx 依赖使用源码包 1、上传和解压源码包 [rootkuang-75 soft]# ls #有两个pcre版本 nginx-1.15.6 pcre2-10.32 pcre-8.39 zlib-1.2.11 2、yum安装依赖包 [rootkuang-75 ~]# yum -y install gcc gcc-c openssl openssl-devel #openssl编译必装依赖gcc-c也是依赖的编译软件 3、指定依赖包位置build ①使用最新版的pcre来构建 [rootkuang-75 nginx-1.15.6]# ./configure --prefix/usr/local/nginx --with-http_ssl_module --with-pcre…/pcre2-10.32 --with-zlib…/zlib-1.2.11 #没报错其中省略了其他模块选项并且ssl可省略 [rootkuang-75 nginx-1.15.6]# make -j 4 #报如下错误 make[2]: 进入目录“/root/soft/pcre2-10.32” make[2]: *** 没有规则可以创建目标“libpcre.la”。 停止。 ②使用老版版的pcre来编译 [rootkuang-75 nginx-1.15.6]# ./configure --prefix/usr/local/nginx --with-http_ssl_module --with-pcre…/pcre-8.39 --with-zlib…/zlib-1.2.11 [rootkuang-75 nginx-1.15.6]# make -j 4 #顺利构建和编译 [rootkuang-75 nginx-1.15.6]# make install #安装后Nginx可用 Nginx重新编译 ①重新build源码 [rootkuang-73 ~]# ./configure --prefix/usr/local/nginx --usernobody --groupnobody --with-pcre --with-http_ssl_module #继承原来所有的配置另外添加额外想添加的模块 ②重新编译源码 [rootkuang-73 ~]# make -j 4 #不能make install否则就覆盖安装了 ③生成新可执行二进制文件 [rootkuang-73 ~]# ls nginx-1.15.6/objs/nginx #新版本程序 ④用新程序将旧程序覆盖 [rootkuang-73 ~]# cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak #备份旧程序 [rootkuang-73 ~]# cp ./objs/nginx /usr/local/nginx/sbin/nginx #替换旧程序 ⑤检查新科执行二进制文件 [rootkuang-73 ~]# /usr/local/nginx/sbin/nginx -V #检查新添加的模块 [rootkuang-73 ~]# /usr/local/nginx/sbin/nginx -t #检查新程序的语法 隐藏版本号 ①修改版本号 [rootkuang-73 ~]# vim nginx-1.14.2/src/core/nginx.h #define NGINX_VERSION “6.6.6” #define NGINX_VER “kuang.cn/” NGINX_VERSION #define NGINX_VAR “kuang.cn” ②避免头部信息暴露版本 [rootkuang-73 ~]# vim nginx-1.14.2/src/http/ngx_http_header_filter_module.c static u_char ngx_http_server_string[] “Server: KUANG” CRLF; ③修改http错误码的返回时携带的版本号 [rootkuang-73 nginx-1.15.6]# vim src/http/ngx_http_special_response.c static u_char ngx_http_error_full_tail[] “ IIS ” CRLF ③http上下文中 server_tokens off; 调度算法 Nginx负载均衡算法 ①轮询RR默认 每个请求按时间顺序逐一分配到不同的后端服务如果后端某台服务器死机自动剔除故障系统使用户访问不受影响。 ②加权轮询WRR weight的值越大分配到的访问概率越高主要用于后端每台服务器性能不均衡的情况下。或者仅仅为在主从的情况下设置不同的权值达到合理有效的地利用主机资源。 ③加权最小连接数WLC阿里云 Nginx上实现加权最小连接还没有试验过 ④ip_hash 每个请求按访问IP的哈希结果分配使来自同一个IP的访客固定访问一台后端服务器并且可以有效解决动态网页存在的session共享问题。 #注意Nginx自带的这类方式对于小公司并且也没有实现Cookie会话保持的可以使用此方式除此之外不推荐这类负载均衡方式。就连阿里云的SLB中都没有这类负载均衡的选项而是基于cookie的会话保持。 ⑤url_hash第三方 按访问的URL的哈希结果来分配请求使每个URL定向到一台后端服务器可以进一步提高后端缓存服务器的效率。Nginx本身不支持url_hash如果需要这种调度算法则必须安装Nginx的hash软件包。比喻按公司业务分类某一个业务找指定的部门 ⑥session stiky第三方或收费 会话保持基于cookie推荐使用的方式 ⑦fair第三方 比 weight、ip_hash更加智能的负载均衡算法fair算法可以根据页面大小和加载时间长短智能地进行负载均衡也就是根据后端服务器的响应时间来分配请求响应时间短的优先分配。Nginx本身不支持fair如果需要这种调度算法则必须安装upstream_fair模块。 Nginx负载均衡调度状态 ①down表示当前的server暂时不参与负载均衡 ②backup预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候才会请求backup机器因此这台机器的访问压力最低 ③max_fails允许请求失败的次数默认为1当超过最大次数时返回proxy_next_upstream模块定义的错误。 ④fail_timeout请求失败超时时间在经历了max_fails次失败后暂停服务的时间。max_fails和fail_timeout可以一起使用。 替换可执行二进制文件 ①重新build源码 [rootkuang-73 ~]# ./configure --prefix/usr/local/nginx --usernobody --groupnobody --with-pcre --with-http_ssl_module #继承原来所有的配置另外添加额外想添加的模块 ②重新编译源码 [rootkuang-73 ~]# make -j 4 #不能make install否则就覆盖安装了 ③生成新可执行二进制文件 [rootkuang-73 ~]# ls nginx-1.15.6/objs/nginx #新版本程序 ④用新程序将旧程序覆盖 [rootkuang-73 ~]# cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak #备份旧程序 [rootkuang-73 ~]# cp ./objs/nginx /usr/local/nginx/sbin/nginx #替换旧程序 ⑤检查新科执行二进制文件 [rootkuang-73 ~]# /usr/local/nginx/sbin/nginx -V #检查新添加的模块 [rootkuang-73 ~]# /usr/local/nginx/sbin/nginx -t #检查新程序的语法 添加systemctl开机启动脚本 1、配置systemctl的Unit控制脚本 [rootkuang-75 ~]# vim /usr/lib/systemd/system/nginx.service #同/lib/systemd/system/目录 [Unit] Descriptionnginx - high performance web server Documentationhttp://nginx.org/en/docs/ Afternetwork.target remote-fs.target nss-lookup.target [Service] Typeforking PIDFile/usr/local/nginx/logs/nginx.pid ExecStartPre/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf ExecStart/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf ExecReload/bin/kill -s HUP $MAINPID ExecStop/bin/kill -s QUIT $MAINPID PrivateTmptrue [Install] WantedBymulti-user.target 2、使用systemctl命令控制Nginx ①Nginx的一般控制 [rootkuang-75 ~]# systemctl status nginx [rootkuang-75 ~]# systemctl start nginx [rootkuang-75 ~]# systemctl stop nginx [rootkuang-75 ~]# systemctl reload nginx #修改配置后加载成功 ②添加到开机启动 [rootkuang-75 ~]# systemctl enable nginx.service #脚本中定义了WantedBy所以创建如下开机启动规则 Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service. 删除Nginx ①make命令删除 [rootkuang-73 nginx-1.15.6]# make uninstall #部分软件支持该命令而且有时删除不干净 ②直接删除安装目录 #安装时指定了安装目录 [rootkuang-73 ~]# rm -rf /usr/local/nginx #卸载或者备份时直接对目录进行操作 ③查看makefile文件里有没提供卸载命令 [rootkuang-73 nginx-1.15.6]# vim Makefile ④whereis找出所有目录 [rootkuang-73 nginx-1.15.6]# whereis nginx | xargs rm -rf #注该命令只找Nginx软件运行时用到的几个目录 ⑤使用find找出所有包含nginx的文件和目录 [rootkuang-73 ~]# find / -name nginx | xargs rm -rf 基础使用 server_name匹配 server_name匹配规则 ①匹配IP地址和listen指令指定的IP和端口 ②将Host头字段作为字符串匹配server_name指令 ③将Host头字段与server_name指令值字符串的开始部分做匹配选出最长泛匹配 ④将Host头字段与server_name指令值字符串的结尾部分做匹配选出最长泛匹配 ⑤将Host头字段与server_name指令值进行正则表达式匹配选择第一个匹配到的 ⑥如果所有Host头匹配失败那么将会转向listen指令标记的default server ⑦如果所有Host头匹配失败并且没有default_server那么将会转向满足第一步的第一个server的listen指令。 server_name格式 ①精确匹配 server_name www.xuegod.cn ②泛解析 server_name .xuegod.cn; #替代部分子域名 server_name www.xuegod.; #替代部分顶级域 ③正则表达式匹配 #注意正则匹配时~和要匹配的字符不要带空格和location匹配有点区别 server_name ~^www.example.comKaTeX parse error: Undefined control sequence: \d at position 22: …ver_name ~^www(\̲d̲)\ .example\.(… ; server_name ~^.*.xuegod.cnKaTeX parse error: Expected EOF, got # at position 6: ; #̲以任何字符开头并xuegod.…; return 301 https:// h o s t host hostrequest_uri; #注意使用正则匹配servername时这里强制跳转就要用host而不用server_name 丢弃无host字段的请求 server { listen 80; server_name “”; return 444; } location匹配 CLB的location匹配规则 ①如果命中精确匹配则优先精确匹配并终止匹配 ②如果命中多个前缀匹配则记住最长的前缀匹配并继续匹配 ③如果最长的前缀匹配是优先前缀匹配则命中此最长的优先前缀匹配并终止匹配 ④如果最长的前缀匹配是非优先前缀匹配并且命中多个正则匹配使用第一个命中的正则匹配并终止匹配。否则匹配最长的前缀匹配终止匹配。 URL尾部的/需不需要 关于URL尾部的/有三点也需要说明一下。第一点与location配置有关其他两点无关。 location中的字符有没有/都没有影响。也就是说/user/和/user是一样的。如果URL结构是https://domain.com/的形式尾部有没有/都不会造成重定向。因为浏览器在发起请求的时候默认加上了/。虽然很多浏览器在地址栏里也不会显示/。这一点可以访问baidu验证一下。如果URL的结构是https://domain.com/some-dir/。尾部如果缺少/将导致重定向。因为根据约定URL尾部的/表示目录没有/表示文件。所以访问/some-dir/时服务器会自动去该目录下找对应的默认文件。如果访问/some-dir的话服务器会先去找some-dir文件找不到的话会将some-dir当成目录重定向到/some-dir/去该目录下找默认文件。可以去测试一下你的网站是不是这样的。 #注意通过URL访问的Nginx的目录为rootlocation location的作用 给自己树立一个目录结构并对每一个目录设置对应的权限和定位等配置。 通过URL访问的Nginx的目录为rootlocation。 location匹配规则详解 ①精确匹配 方法1、等号为精确匹配 location / #匹配到了马上停止匹配如果一个网站访问这个比较多可以提高访问速度 方法2、另一种精确匹配完整的URI location /data/image.html #隐式的精确匹配 ②模糊匹配 location /synchrony #模糊匹配URI里已/synchrony开头的已验证 例1、http://localhost/synchrony/app/index.html 例2、http://localhost/synchrony-pass/index.html location ^~ / #指的非正则匹配意思当被选为最长普通匹配时就不要匹配正则了我当老大了就没正则什么事了 ③正则匹配 区分大小写 location ~ ④正则匹配但是不区分大小写 location ~* .TXT$ ⑤命名location location fallback #不是用来处理普通的HTTP请求的专门用来内部重定向的仅对内部访问重定向 #在server上下文中配置 error_page 404 fallback; location fallback { proxy_pass http://www.nginx.org; } #当访问不存在的http://192.168.7.3/en/ 时将会重定向到http://www.nginx.org/en/ location嵌套 ​ location /htdocs { ​ alias /usr/share/phpldapadmin/htdocs; ​ index index.php; ​ location ~ .php$ { ​ alias /usr/share/phpldapadmin; ​ fastcgi_pass 127.0.0.1:9000; ​ fastcgi_index index.php; ​ fastcgi_param SCRIPT_FILENAME d o c u m e n t r o o t document_root documentr​ootfastcgi_script_name; ​ include fastcgi_params; ​ } ​ } Nginx分离location localtion优先级案例 Web服务共享目录 共享非根目录 ①创建共享目录 [rootkuang-73 ~]# cd /usr/local/nginx/html/ [rootkuang-73 html]# mkdir -p good/soso/sdf/ ②配置共享目录 location /soso {root html/good; #每个location有自己的根目录如未申明就用上级代码块中的根目录这里写绝对路径也可以/usr/local/nginx/html/good;autoindex on;}③测试共享目录 http://192.168.7.3/soso/ ④分析实现过程 步骤1、URI被location /soso所匹配到所以要对此提供服务 步骤2、去它定义的根html/good这是个相对路径相对/usr/local/nginx找soso 步骤3、如果soso是个文件则直接输出文件内容如果soso是个目录则输出目录ftp站点效果 通过软链方式共享目录 ①配置Nginx服务器支持自动索引 [rootkuang-73 nginx]# vim conf/nginx.conf #在http上下文中配置如下 location / { root html; index index.html index.htm; autoindex on; #开启自动索引即可 } ②创建URI的软链接 [rootkuang-73 ~]# ln -s /mnt/ /usr/local/nginx/html/centos ③测试访问 http://192.168.7.3/centos/ 通过alias方式共享目录 ①配置虚拟目录指向光盘挂载点 [rootkuang-73 nginx]# vim conf/nginx.conf #在http上下文中配置如下 location /my { alias /mnt; autoindex on; } ②访问测试 http://192.168.7.3/my 使用Django实现上传文件 1、下载upload模块并编译安装Nginx ①nginx-upload-module模块下载地址 https://github.com/fdintino/nginx-upload-module ②编译安装Nginx [rootkuang-73 nginx-1.15.6]# ./configure --usernginx --groupnginx --prefix/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --add-module/root/nginx-upload-module-2.3.0/ [rootkuang-73 nginx-1.15.6]# make -j 4 make install2、Nginx配置调用Django ①Nginx配置脚本 server {listen *:80 default_server;server_name 192.168.1.251;client_max_body_size 20m;client_body_buffer_size 512k;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header REMOTE_ADD $remote_addr;location /upload {upload_pass python;upload_store /tmp/nginx_upload;upload_store_access user:rw group:rw all:rw;set $upload_field_name file;upload_set_form_field ${upload_field_name}_name $upload_file_name;upload_set_form_field ${upload_field_name}_content_type $upload_content_type;upload_set_form_field ${upload_field_name}_path $upload_tmp_path;upload_aggregate_form_field ${upload_field_name}_md5 $upload_file_md5;upload_aggregate_form_field ${upload_field_name}_size $upload_file_size;upload_pass_form_field ^.*$;upload_limit_rate 0;upload_cleanup 400 404 499 500-505;upload_pass_args on; }location python {proxy_pass http://localhost:9999;} }②创建Django项目 未完待续 使用stream模块实现四层代理 1、使用stream模块实现四层代理 ①stream模块实现ssh代理方法 #stream模块用法跟http模块类似编译安装时添加参数–with-stream [rootkuang73 ~]# vim /usr/local/nginx/conf/nginx.conf #添加如下配置 stream { upstream ssh {server 192.168.7.6:22;}server {listen 22;proxy_pass ssh;proxy_connect_timeout 1h;proxy_timeout 1h;} }注意stream没有http模块的很多功能比如基本的location和root都没有 ②将作反向代理服务器的SSH服务关闭 [rootkuang73 ~]# systemctl stop sshd.service ③重新加载Nginx配置文件 [rootkuang73 ~]# /usr/local/nginx/sbin/nginx -s reload [rootkuang73 ~]# netstat -antup | grep 22 #此时为Nginx监听22端口 tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3239/nginx: master ④验证Nginx代理SSH服务成功跳转到kuang-76 kuangkuang-ubuntu:~$ ssh root192.168.7.3 root192.168.7.3’s password: Last login: Sat Jul 13 12:44:04 2019 from 192.168.7.2 [rootkuang-76 ~]# 获取客户端请求的真实IP 获取客户端请求的真实IP地址 location / {proxy_pass https://192.168.10.3:443/;proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme; }rewrite和return跳转 rewrite基本操作 1、rewrite常见用法 ①方便统一管理一个目录对应一个子域名将连接跳转到其他服务器上 案例1、将www.myweb.com/connect 跳转到connect.myweb.com rewrite ^/connect$ http://connect.myweb.com permanent; rewrite ^/connect/(.)$ http://connect.myweb.com/ 1 p e r m a n e n t ; ②网站转移后重定向到新的服务器 r e w r i t e / ( . ∗ ) 1 permanent; ②网站转移后重定向到新的服务器 rewrite ^/(.*) 1permanent;②网站转移后重定向到新的服务器rewrite/(.∗) http://www.baidu.com/ 1 p e r m a n e n t ; r e w r i t e / ( . ∗ ) 1 permanent; rewrite ^/(.*) 1permanent;rewrite/(.∗) https://$hostKaTeX parse error: Expected EOF, got # at position 82: …w.myweb.com #̲用户输入URL时忘记带www了…host ! ‘www.myweb.com’ ) { rewrite ^/(.)$ http://www.myweb.com/KaTeX parse error: Expected EOF, got } at position 19: …ermanent; }̲ ④实现伪静态隐蔽真实目录结…request_uri ~ “/?gid6”){return http://www.myweb.com/123.html;} ⑤静态页面跳转到动态页面 案例1、www.myweb.com/admin/ 下跳转为www.myweb.com/admin/index.php?s if (!-e KaTeX parse error: Expected }, got EOF at end of input: …te ^/admin/(.*) /admin/index.php?s/KaTeX parse error: Expected EOF, got } at position 13: 1 last; }̲ 案例2、rewrite ^/… /resizer/$1.$4?width$2heightKaTeX parse error: Undefined control sequence: \- at position 161: …s/activies/2014\̲-̲([0-9])\-([0-9… http://www.myweb.com/news/activies/ 3 p e r m a n e n t ; ⑦多条件重定向 r e w r i t e 案例 1 、需要打开带有 p l a y 的链接就跳转到 p l a y 不过 / a d m i n / p l a y 这个不能跳转 i f ( 3 permanent; ⑦多条件重定向rewrite 案例1、需要打开带有play的链接就跳转到play不过/admin/play这个不能跳转 if ( 3permanent;⑦多条件重定向rewrite案例1、需要打开带有play的链接就跳转到play不过/admin/play这个不能跳转if(request_filename ~ (.)/play){ set KaTeX parse error: Expected EOF, got } at position 12: payvar 1;}̲ if (request_filename ~ (.)/admin){ set KaTeX parse error: Expected EOF, got } at position 12: payvar 0;}̲ if (payvar ~ ‘1’){ rewrite ^/ http://play.myweb.com/ break; } 2、rewrite其他应用 ①使用全站加密http自动跳转https 方法1、在页面里加js脚本 方法2、后端程序里写重定向 方法3、Web服务器实现重定向跳转 在http的server上下文里添加rewrite ^(.*) https://$host$1 permanent; 3、rewrite重写规则 ①条件语句if中使用正则表达式匹配 ~ 为区分大小写匹配 ~* 为不区分大小写匹配 !和!*分别为区分大小写不匹配及不区分大小写不匹配 ②文件及目录匹配 -f和!-f用来判断是否存在文件 -d和!-d用来判断是否存在目录 -e和!-e用来判断是否存在文件或目录 -x和!-x用来判断文件是否可执行 4、rewrite的flag标记 ①last 相当于apache里面的[L]标记表示rewrite。 步骤1、结束当前的请求处理用替换后的URI重新匹配location 步骤2、可理解为重写rewrite后发起了一个新请求进入server模块匹配location 步骤3、如果重新匹配循环的次数超过10次nginx会返回500错误 步骤4、返回302 http状态码 步骤5、浏览器地址栏显示重地向后的url ②break本条规则匹配完成后终止匹配不再匹配后面的规则。 步骤1、结束当前的请求处理使用当前资源不在执行location里余下的语句 步骤2、返回302 http状态码 步骤3、浏览器地址栏显示重地向后的url ③redirect 返回302临时重定向浏览器地址会显示跳转后的URL地址。 步骤1、临时跳转返回302 http状态码 步骤2、浏览器地址栏显示重地向后的url ④permanent 返回301永久重定向浏览器地址会显示跳转后的URL地址。 步骤1、永久跳转返回301 http状态码 步骤2、浏览器地址栏显示重定向后的url ⑤last和break区别 使用last和break实现URI重写浏览器地址栏不变 使用alias指令必须用last标记 使用proxy_pass指令时需要使用break标记 Last标记在本条rewrite规则执行完毕后会对其所在server{…}标签重新发起请求 break标记则在本条规则匹配完成后终止匹配。 5、Apache和Nginx规则的对应关系 Apache的RewriteCond对应Nginx的if Apache的RewriteRule对应Nginx的rewrite Apache的[R]对应Nginx的redirect Apache的[P]对应Nginx的last Apache的[R,L]对应Nginx的redirect Apache的[P,L]对应Nginx的last Apache的[PT,L]对应Nginx的last 6、Nginx全局变量 arg_PARAMETER #这个变量包含GET请求中如果有变量PARAMETER时的值。 args #这个变量等于请求行中(GET请求)的参数如foo123barblahblah; binary_remote_addr #二进制的客户地址。 body_bytes_sen t #响应时送出的body字节数数量。即使连接中断这个数据也是精确的。 content_length #请求头中的Content-length字段。 content_type #请求头中的Content-Type字段。 cookie_COOKIE #cookie COOKIE变量的值 document_root #当前请求在root指令中指定的值。 document_uri #与uri相同。 host #请求主机头字段否则为服务器名称。 hostname #Set to themachine’s hostname as returned by gethostname http_HEADER is_args #如果有args参数这个变量等于”?”否则等于”空值。 http_user_agent #客户端agent信息 http_cookie #客户端cookie信息 limit_rate #这个变量可以限制连接速率。 query_string #与args相同。 request_body_file #客户端请求主体信息的临时文件名。 request_method #客户端请求的动作通常为GET或POST。 remote_addr #客户端的IP地址。 remote_port #客户端的端口。 remote_user #已经经过Auth Basic Module验证的用户名。 request_completion #如果请求结束设置为OK. 当请求未结束或如果该请求不是请求链串的最后一个时为空(Empty)。 request_method #GET或POST request_filename #当前请求的文件路径由root或alias指令与URI请求生成。 request_uri #包含请求参数的原始URI不包含主机名如”/foo/bar.php?argbaz”。不能修改。 scheme #HTTP方法如httphttps。 server_protocol #请求使用的协议通常是HTTP/1.0或HTTP/1.1。 server_addr #服务器地址在完成一次系统调用后可以确定这个值。 server_name #服务器名称。 server_port #请求到达服务器的端口号。 rewrite实现com跳转到cn 在vhost配置文件添加如下跳转配置 server {listen 80;server_name fenxiao-test.edsmall.com;return 301 https://$server_name$request_uri;#return301高效一些}server {listen 443;server_name fenxiao-test.edsmall.com;location / {#rewrite ^(.*)\.edsmall\.com/(.*)$ $1\.edstao\.com/$2 permanent;rewrite ^/(.*)$ http://fenxiao-test.edstao.com/$1 permanent;} }rewrite配置手机和电脑访问不同页面 [rootkuang-73 nginx]# vim conf/nginx.conf #上下文为location set $mobile_rewrite do_not_perform;## chi http_useragent for mobile /smart phones ##if ($http_user_agent ~* (android|bb\d|meego).mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian |treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino) {set $mobile_rewrite perform;} if ($http_user_agent ~* ^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|c dm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\- c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21| ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|u c)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700| yas\-|your|zeto|zte\-)) {set $mobile_rewrite perform;} if ($mobile_rewrite perform) {return 301 $scheme://tao.edsmall.cn;} return的使用 1、return使用说明 该指令一般用于对请求的客户端直接返回响应状态码。在该作用域内return后面的所有nginx配置都是无效的。 可以使用在server、location以及if配置中。 除了支持跟状态码还可以跟字符串或者url链接。 2、直接返回状态码 server{listen 80;server_name www.aming.com;return 403;rewrite /(.*) /abc/$1; #该行配置不会被执行。 }3、返回字符串 ①要想返回字符串必须要加上状态码否则会报错 server{listen 80;server_name www.aming.com;return 200 hello; }②还可以支持json数据 location ^~ /aming {default_type application/json ;return 200 {name:aming,id:100}; }③也支持写一个变量 location /test {return 200 $host $request_uri; }4、返回URL server{listen 80;server_name www.aming.com;return 301 http://www.aminglinux.com/123.html;rewrite /(.*) /abc/$1; #该行配置不会被执行。 }#注意return后面的url必须是以http://或者https://开头的。 proxy实现错误码跳转页面 普通404页面跳转 ①定义404跳转页面 [rootAWKD-LinuxTest2-10 ~]# vim /etc/nginx/nginx.conf #这里只显示精简代码内容 server {listen 80 default_server;root /usr/share/nginx/html;location / {#error_page 404 /404.html; #错误页面跳转也可以在location中因为是在此截获的404错误码}error_page 404 /404.html; #指定错误码404跳转后的错误页面location /404.html {}②创建404测试页面 [rootAWKD-LinuxTest2-10 ~]# echo “deny” /usr/share/nginx/html/404.html #假装友好错误界面内容是deny ③测试跳转 http://47.97.2.118/good #浏览器中输入一个服务器中没有的资源实现如下404错误跳转 Nginx作反向代理时的错误页面跳转 ①定义404跳转页面 [rootAWKD-ZABBIX-172 nginx]# vim conf/vhost/71-pre.edsmall.com.conf server {listen 443;... ...root /data/nginx/html;location / {proxy_pass http://71-pre;... ...proxy_intercept_errors on; #重点Nginx作反向代理时默认情况下Nginx不支持自定义404错误页面只有这个指令被设置为onNginx才支持将404错误重定向#error_page 404 /404.html; #错误页面跳转也可以在location中因为是在此截获的404错误码}error_page 404 /404.html; #当上游服务器响应头回来后可以根据响应状态码的值进行拦截错误处理与error_page 指令相互结合。用在访问上游服务器出现错误的情况下。location /404.html {root /data/nginx/html;}②创建404测试页面 [rootAWKD-ZABBIX-172 nginx]# echo “deny” /data/nginx/html/404.html #假装友好错误界面内容是deny ③测试跳转 https://71-pre.edsmall.com/soso #浏览器中输入一个服务器中没有的资源实现如下404错误跳转 连接超时 ①上下文为http keepalive_timeout 65; #该项依赖系统没有设置立即回收资源效果是65秒内客户端一直向服务端发送keepalive服务端也回应keepalive的ack包确认保持联系。一到65秒服务端就发送FIN信号。 client_header_timeout 60; #指定等待客户端发送请求头的超时时间 client_body_timeout 60; #设置请求体读取超时时间②连接超时作用 在企业网站中为避免同一个客户长时间占用连接造成服务器资源浪费可以设置相应的连接超时参数实现控制连接访问时间 ③系统设置的tcp_keepalive_timeout时间 [rootkuang-75 ~]# cat /proc/sys/net/ipv4/tcp_keepalive_time #默认为一个小时 7200 配置Nginx支持PHP ①安装使用php的包 [rootkuang-73 ~]# yum -y install php php-fpm [rootkuang-73 ~]# systemctl start php-fpm [rootkuang-73 ~]# ss -lntup #端口9000起来了 ②在server代码模块当中增加如下locatin上下文模块 location ~ \.php$ {root /usr/share/nginx/html;fastcgi_split_path_info ^(.\.php)(/.)$; #这条可以注释掉不懂意思fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;include fastcgi_params;}③添加简单PHP页面 [rootkuang-73 ~]# echo “?php phpinfo(); ?” /usr/local/nginx/html/index.php echo “?php phpinfo(); ?” index.php ④测试PHP页面访问 http://192.168.7.3/index.php fastcgi配置和使用 fastcgi配置和使用 fastcgi也是一个反代和proxy语法类似 ①安装使用php的包 [rootkuang-73 ~]# yum -y install php php-fpm [rootkuang-73 ~]# systemctl start php-fpm [rootkuang-73 ~]# ss -lntup #端口9000起来了 ②上下文http中配置fastcgi fastcgi_connect_timeout 300; #连接到后端fastcgi的超时时间fastcgi_send_timeout 300;fastcgi_read_timeout 300; #应答的超时时间fastcgi_buffer_size 64k; #默认等于内存页面大小fastcgi_buffers 4 64k;fastcgi_busy_buffers_size 128k;fastcgi_temp_file_write_size 128k;fastcgi_cache_path /tmp/nginx_temp levels2:2 keys_zonengx_fcgi_cache:512m inactive1d max_size20g; ③在server上下文中使用fastcgilocation ~ \.php$ {root html;fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;include fastcgi_params; #导入变量名文件fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name;fastcgi_cache ngx_fcgi_cache;fastcgi_cache_valid 200 302 1h;fastcgi_cache_valid 301 1d;fastcgi_cache_valid any 1m;fastcgi_cache_min_uses 1;fastcgi_cache_use_stale error timeout invalid_header http_500;fastcgi_cache_key http://$host$request_uri;}④配置使用php [rootkuang-73 ~]# /usr/local/nginx/sbin/nginx -s reload #重载配置文件 [rootkuang-73 ~]# echo “?php phpinfo(); ?” /usr/local/nginx/html/index.php #此时已可以访问http://192.168.7.3/index.php ⑤使用fastcgi缓存功能 [rootkuang-73 ~]# systemctl stop php-fpm #此时关闭php-fpm服务换一个浏览器依然可以访问http://192.168.7.3/index.php #原因是fastcgi生成了缓存 [rootkuang-73 ~]# ls /tmp/nginx_temp/ #nginx缓存目录 #将以上缓存目录删除之后则不再能访问http://192.168.7.3/index.php 查看缓存机制运行状态 ①专门生成一个进程处理cache [rootkuang-73 ~]# ps -ef | grep nginx nginx 123058 123053 0 15:57 ? 00:00:00 nginx: cache manager process ②目录的名称是基于请求URL通过哈希算法获取到的 /usr/local/nginx/cache/d/91/972fbe600d30f1cc92495981969ff91d 参数说明 ①buffer相关参数 fastcgi_buffering 默认开启缓冲为了Nginx能尽最快速度的接收FastCGI服务器的响应将响应内容放入内存的buffer中。但是如果buffer放不下某一整个响应其中一部分会被放入临时文件。 fastcgi_buffer_size 指Nginx一次性能从FastCGI服务器接收的最大的响应数据 fastcgi_busy_buffers_size 指在Nginx还没有读完一个响应时指定这部分大小buffer可以用来忙于响应客户端 fastcgi_temp_file_write_size 指一次性能写多大的数据到临时文件被fastcgi_buffer_size和fastcgi_buffers两个共同限制比如buffer_size为64k数量buffers为4那么最大为256k fastcgi_max_temp_file_size 指最大缓存文件大小②设置内存cache和磁盘cache #设置web缓存区的名字为cache_one 内存缓存空间大小为200M 自动清除超过1天没被访问的缓存数据磁盘缓存空间大小为30GB fastcgi_cache_path /data/fastcgi_cache_path levels2:2 keys_zonecache_one:200m inactive1d max_size30g; fastcgi_cache_path 跟Redis类似Key-Value都能放得下则都放在内存实在放不下就会将Value放在磁盘文件 keys_zone 用来存Key(热点内容放在内存) inactive 失效时间1天相当于Redis的LRU max_size 最大磁盘占用缓存空间③引用内存cache并配置相应参数 fastcgi_cache ngx_fcgi_cache 引用名为ngx_fcgi_cache命名空间作为cache的内存 fastcgi_cache_valid 200 302 1h 状态码为200和302的响应在磁盘中保存1小时 fastcgi_cache_min_uses 1 第几次访问时就将响应缓存起来这里指缓存到磁盘 fastcgi_cache_use_stale error timeout invalid_header http_500 如果客户访问的某个页面出现error之后的这些错误那么Nginx服务器将使用本地的缓存来响应客户 fastcgi_cache_key 指定Key的对象是什么引入fastcgi_param参数 需要在conf目录中包含env_release文件。 server {listen 8080 ;server_name _;access_log logs/message-notifier.access.log main;error_log logs/message-notifier.error.log error;root /data/home/user00/nginx/html/message-notifier/;location ~ \.php$ {fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;fastcgi_param ITOP_INCLUDE_PATH $document_root/../../include;include fastcgi_params;include env_release;} }Nginx添加Perl支持 Perl的使用场景如果对于一个绝大部分内容是静态的网站只有极少数的地方需要动态显示碰巧你又了解一点perl知识那么nginx perl的结合就能很好解决问题。 ①安装Nginx添加Perl支持 [rootkuang-75 nginx-1.14.2]# yum -y install perl-devel perl-ExtUtils-Embed #安装依赖包 [rootkuang-75 nginx-1.14.2]# ./configure --with-http_perl_module [rootkuang-75 nginx-1.14.2]# make -j 4 make install ②配置把perl脚本写在外部文件中 #位于http配置中 perl_modules perl/lib; perl_require test.pm; #位于server配置中 location /user/ { perl pkg_name::process; } #配置解释 上述配置是把所有来自http://servername/user/下的请求交由test.pm脚本中定义的process方法来处理。 ③进入根目录添加Perl库目录 [rootkuang-75 nginx]# mkdir -p perl/lib cd perl/lib [rootkuang-75 lib]# vim test.pm package pkg_name; use Time::Local; use nginx; sub process { my $r shift; $r-send_http_header(‘text/html; charsetutf-8’); my arr split(‘/’, $r-uri); my u s e r n a m e a r r [ 2 ] ; i f ( ! username arr[2]; if (! usernamearr[2];if(!username || ($username eq “”)) { $username “Anonymous”; } $r-print(Hello, You name is : ’ . $username . ‘’); $r-rflush(); return; } 1; ③访问测试 http://192.168.7.5/user/kuang Hello, You name is : kuang Nginx使用lua Nginx安装lua支持 #注需要LuaJIT-2.0.4.tar.gzngx_devel_kitlua-nginx-module 1.下载安装LuaJIT-2.0.4.tar.gz [rootkuang-74 ~]# wget -c http://luajit.org/download/LuaJIT-2.0.4.tar.gz [rootkuang-74 ~]# tar xzvf LuaJIT-2.0.4.tar.gz [rootkuang-74 ~]# cd LuaJIT-2.0.4 [rootkuang-74 ~]# make install PREFIX/usr/local/luajit [rootkuang-74 ~]# export LUAJIT_LIB/usr/local/luajit/lib #增加环境变量 [rootkuang-74 ~]# export LUAJIT_INC/usr/local/luajit/include/luajit-2.0 2.下载解压ngx_devel_kit [rootkuang-74 ~]# cd /usr/local [rootkuang-74 ~]# wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz [rootkuang-74 ~]# tar -xzvf v0.3.0.tar.gz 3.下载解压lua-nginx-module [rootkuang-74 ~]# cd /usr/local [rootkuang-74 ~]# wget https://github.com/openresty/lua-nginx-module/archive/v0.10.8.tar.gz [rootkuang-74 ~]# tar -xzvf v0.10.8.tar.gz 4.下载安装nginx-1.10.3.tar.gz注意新版本Nginx安装不成功可能需要新版lua模块 [rootkuang-74 ~]# cd /usr/local [rootkuang-74 ~]# wget http://nginx.org/download/nginx-1.10.3.tar.gz [rootkuang-74 ~]# tar -xzvf nginx-1.10.3.tar.gz [rootkuang-74 ~]# cd nginx-1.10.3 [rootkuang-74 nginx-1.10.3]# ./configure --add-module…/ngx_devel_kit-0.3.0 --add-module…/lua-nginx-module-0.10.8 [rootkuang-74 nginx-1.10.3]# make -j 4 make install 5、配置使用lua ①Nginx主配置文件中使用lua [rootkuang-74 ~]# vim /usr/local/nginx/conf/nginx.conf location /hello { #使用lua方式一直接在Nginx主配置中使用 default_type ‘text/plain’; content_by_lua ‘ngx.say(“hello, lua”)’; } location /lua { #使用lua方式二在文本中调用 default_type ‘text/html’; content_by_lua_file conf/lua/test.lua; #相对于Nginx安装目录 } [rootkuang-75 ~]# mkdir /usr/local/nginx/conf/lua [rootkuang-74 ~]# vim /usr/local/nginx/conf/lua/test.lua ngx.say(“hello world”); ②创建库的链接 [rootkuang-74 ~]# ln -s /usr/local/luajit/lib/libluajit-5.1.so.2 /lib64/libluajit-5.1.so.2 6、测试访问 ①访问http://127.0.0.1/hello 显示hello, lua ②访问http://127.0.0.1/lua 显示hello world Nginx结合lua动态选择upstream ①配置Nginx http {lua_shared_dict _ups_zone 64m;...upstream qq_backend{server 192.168.7.6;server 192.168.7.7;}server {listen 80;server_name www.kuang.com;access_log off;location /ups_update {content_by_lua local ups ngx.req.get_uri_args()[ups]if ups nil thenngx.say(usage: /ups_update?upsx.x.x.x)returnendlocal host ngx.var.http_hostlocal ups_from ngx.shared._ups_zone:get(host);ngx.log(ngx.WARN, host, update upstream from , ups_from, to , ups)ngx.shared._ups_zone:set(host, ups);ngx.say(host, update upstream from , ups_from, to , ups);}location / {set_by_lua $cur_ups local ups ngx.shared._ups_zone:get(ngx.var.http_host)if ups ~ nil thenngx.log(ngx.ERR, get [, ups, ] from ngx.shared._ups_zone)return upsend--ngx.log(ngx.INFO, use default upstream);return qq_backend;proxy_next_upstream off;proxy_set_header Host $host;proxy_http_version 1.1;proxy_set_header Connection ;proxy_pass $scheme://$cur_ups;}} }②配置upstream服务器 [rootkuang-76 ~]# systemctl start ngtinx [rootkuang-76 ~]# echo kuang-76 /usr/share/nginx/html/index.html [rootkuang-77 ~]# systemctl start nginx.service [rootkuang-77 ~]# echo kuang-77 /usr/share/nginx/html/index.html 3、测试效果 ①先看默认访问效果 默认负载均衡为轮训 ②绑定后端服务器 [rootkuang-75 ~]# curl -x 127.0.0.1:80 www.kuang.com/ups_update?ups192.168.7.6 再次访问该客户端的请求永远都被转发到绑定的后端服务器上 ③修改后端绑定的服务器 [rootkuang-75 ~]# curl -x 127.0.0.1:80 www.kuang.com/ups_update?ups192.168.7.7 选项x代表使用指定的代理和端口也可以在hosts当中映射好www.kuang.com 在浏览器中测试效果一致 Nginx结合lua动态代理端口 1、动态代理端口 ①需求 需求大致如下:通过url传参的方式,让Nginx代理到不同的服务器 浏览器输入:http://127.0.0.1/remote?port8081被代理到:http://192.168.108.2:8081 ②Nginx配置 server {location /remote {set_form_input $remotePort ;access_by_lua local arg ngx.req.get_post_args()ngx.var.remotePort arg[port];proxy_pass http:192.168.108.2://$remotePort;} }Nginx支持Confluence的Websocket连接 1、Websocket相关模块 ①Nginx支持Websocket所需模块 map指令使用ngx_http_map_module模块提供的默认情况下Nginx有加载这个模块除非人为的 --without-http_map_module。 ②ngx_http_map_module模块作用 ngx_http_map_module模块可以创建变量这些变量的值与另外的变量值相关联。允许分类或者同时映射多个值到多个不同值并储存到一个变量中map指令用来创建变量但是仅在变量被接受的时候执行视图映射操作对于处理没有引用变量的请求时这个模块并没有性能上的缺失。 2、Nginx主配置修改 根据客户端请求中 h t t p u p g r a d e 的值来构造改变 http_upgrade 的值来构造改变 httpu​pgrade的值来构造改变connection_upgrade的值 [rootAWKD-ZABBIX-172 ~]# vim /data/nginx/conf/nginx.conf #http代码模块中添加如下配置信息 http {... ...map $http_upgrade $connection_upgrade {default upgrade; close;} } #如果$http_upgrade 不为 (空)则$connection_upgrade为upgrade #如果$http_upgrade 为 (空)则$connection_upgrade为close3、特定二级域名的Server-Location配置部分 ①新增Websocket反代配置 [rootAWKD-ZABBIX-172 ~]# vim /data/nginx/conf/vhost/confluence.edsmall.com.conf upstream confluence {server 172.16.239.243:8090 max_fails10 fail_timeout5;} upstream synchrony {server 172.16.239.243:8091 max_fails10 fail_timeout5;}location / {proxy_pass http://confluence;proxy_http_version 1.1;proxy_set_header Host $host;#prwxy_set_header X-Real-IP $remote_addr;proxy_set_header x-forwarded-for $remote_addr;#proxy_set_header X-Forwarded-For $http_x_forwarded_for;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection upgrade;proxy_connect_timeout 600;proxy_read_timeout 600;proxy_send_timeout 600;proxy_intercept_errors on;}location /synchrony {proxy_set_header Host $host;#prwxy_set_header X-Real-IP $remote_addr;proxy_set_header x-forwarded-for $remote_addr;#proxy_set_header X-Forwarded-For $http_x_forwarded_for;proxy_connect_timeout 600;proxy_read_timeout 600;proxy_send_timeout 600;proxy_intercept_errors on;#Websocket configurationproxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection upgrade;proxy_pass http://synchrony;}②Websocket反代配置说明 proxt_http_version 1.1; #表示反向代理发送的HTTP协议的版本是1.1HTTP1.1支持长连接 proxy_set_header Upgrade $http_upgrade; #表示设置Upgrade不变 proxy_set_header Connection $connection_upgrade; #这里提供另外一种写法但是实际生产中还是按照上面配置的来 proxy_pass http://synchrony; #反向代理的URI4、重新加载Nginx配置 [rootAWKD-ZABBIX-172 ~]# /data/nginx/sbin/nginx -s reload 5、官网参考文档 http://nginx.org/en/docs/http/websocket.html Nginx并发测试 Nginx并发预估 ①预估算法 {内存G*1024-System}/请求大小单位M ②参数含义 ?G表示内存大小 1024表示内存容量标准进制 system表示系统和服务占用的额外内存和需要预留的内存 请求大小表示静态一般为KB或动态一般为MB的请求大小 ③压测经验 16核32G服务器可以抗住4万多用于负载均衡的并发最多可以抗住5-6万跑满文件描述符。 #注意以上并发预估地方仅做参考真实情况Nginx压测到达瓶颈2700并发时CPU已经耗尽内存却还有很多剩余。 ④其他查看并发的方法 [rootkuang ~]# netstat -n | awk ‘/^tcp/ {S[$NF]} END {for(a in S) print a, S[a]}’ #注意以上方法是查看每种连接的总数比如ESTABLISHED中包含了反向代理Nginx与前端和后端的连接总数 Nginx压力测试 ①配置Nginx最大并发数 以下配置Nginx只有一个worker且每个worker进程最大连接数100作为反向代理的话则最大并发数为50 ②使用ab长连接对Nginx进行压测 [rootkuang-77 ~]# ab -c 50 -t 60 -k http://192.168.7.5/index.html #并发50持续60秒 ③查看Nginx并发数 [rootkuang-75 ~]# netstat -antup | grep 192.168.7.5:80 | grep ES | wc -l [rootkuang-75 ~]# curl http://192.168.7.5/status #还可以通过Nginx状态模块查看 其中curl本身这一次连接也计算入Active connections中所以这里为51 #注意ab压测设置并发参数要是超过了50则在压测一开始就会报错被对方的apr_socket_recv接收数据的进程给中断了。说明数据堆积在apr_socket_recv没有被取走导致溢出异常。有两种可能①apr_socket_recv速度太慢没有及时将数据传递②下家接收数据速度太慢导致堆积。 查找限制Nginx并发的问题 ①查看Nginx的error日志 #发现报错全是一下日志说worker_connections连接不够了 2019/08/18 19:18:39 [alert] 1433#0: *60191 100 worker_connections are not enough while connecting to upstream, client: 192.168.7.7, server: _, request: “GET / HTTP/1.1”, upstream: “http://192.168.7.6:80/”, host: “192.168.7.5” 使用wrk稳定的对Nginx进行压测 ①配置Nginx最大并发数 以下配置计算得出Nginx当前的最大并发数为150 ②使用wrk对Nginx进行压力测试 [rootkuang-77 ~]# wrk -c300 -t4 -d100s http://192.168.7.5 #注意以上压测数据比较准确无论wrk的并发设置为多大在Nginx这边看到的并发都稳定的保持在最大的并发150以下。 持续对Nginx提高压测力度 ①配置Nginx最大并发数 如下图计算Nginx最大并发数理论上应该是4000但是能否达到呢 ②使用wrk对Nginx进行1500并发的压测 [rootkuang-77 ~]# wrk -c1500 -t4 -d100s http://192.168.7.5 ③查看Nginx实际并发数 如下图可知并发数始终在1024之下显而易见是因为最大的文件数限制了连接数 ④增加用户最大能打开的数量 [rootkuang-75 ~]# ulimit -n 65535 #Nginx反向代理服务器上需要增加 [rootkuang-77 ~]# ulimit -n 65535 #客户端也需要增加 [rootkuang-77 ~]# wrk -c1500 -t4 -d100s http://192.168.7.5 此时在对Nginx做压力测试已经可以达到wrk设置的并发数了 ⑤增加压测并发数为1万 [rootkuang-77 ~]# wrk -c10000 -t4 -d100s http://192.168.7.5 如下图可知Nginx的实际并发数维持在2700左右就连curl想要去访问连接数也很难建立起和服务器的连接后续排查是哪里的瓶颈限制 #注意目前已发现当压测并发为1千和1万时本地主机的CPU使用率都是100%只是1千的能够扛得起来1万的却只能抗起2700左右的并发 #注意以下使用ab对Nginx进行压测数据有误所以以下Nginx压测结果不做参考也许是ab运行的机制影响了Nginx压测数据可能是因为ab写数据太勤奋了。 四万并发记录 优化Nginx-绑定内核 ①配置Nginx双内核 ②使用ab对双核Nginx进行压测 如图Nginx为双核时按理说应该能抗起100的并发可是连90的并发都没有扛起来最后70的并发才扛起来后面再用80的并发就抗不起来了。说明Nginx还有很大的优化空间。并且后面会发现内核越多反而性能并没有按趋势上升而是亏了很多性能。 ③将Nginx进程绑定内核 Nginx进程绑定内核好了一点80的并发能够扛得起来但是90的并发还是抗不起来。 优化Nginx-关闭日志 ①将Nginx的access日志关闭 因为压测时会记录大量的日志所以将日志记录关闭能提高部分性能但是生产环境不能关闭日志 ②再次对Nginx进行压测 此时Nginx性能又提高了一部分 进程控制 Nginx进程控制 Nginx重新加载配置文件 #要让 nginx 重新加载配置文件需要给 nginx 主进程发送一个 HUP 信号。nginx 主进程收到信号之后首先检查配置的语法然后尝试应用新配置比如打开日志文件或者建立新的监听套接字。如果应用新配置失败nginx 对改动进行回滚并继续以旧的配置进行工作。如果成功nginx 启动新的 worker 进程并发送关闭消息给旧的 worker 进程要求它们优雅地关闭。旧的 worker 进程关闭监听套接字并继续完成当前的用户请求等用户的请求完成后就会关闭。 [rootlocalhost ~]# kill -s HUP 22650 #向nginx主进程发送一个HUP信号 [rootlocalhost ~]# ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep ‘(nginx|PID)’ PID PPID USER %CPU VSZ WCHAN COMMAND 22650 1 root 0.0 125632 sigsus nginx: master process /usr/sbin/nginx 22981 22650 nginx 0.0 138264 ep_pol nginx: worker process 22982 22650 nginx 0.0 138264 ep_pol nginx: worker process 22983 22650 nginx 0.0 138264 ep_pol nginx: worker process 22985 22650 nginx 0.0 138264 ep_pol nginx: worker process #除了主进程外其所有4个工作进程的PID全变了 手动切割日志 ①日志需要被重命名 [rootlocalhost nginx]# mv access.log access.log.back #重命名后不影响Nginx正常运行并且新的访问日志会继续往back文件中写通过tailf验证因为内核是根据文件描述符来找文件的-已测 ②发送USR1 信号给Nginx 主进程 方法1、[rootlocalhost nginx]# nginx -s reopen #主进程会让所有工作进程关闭old文件打开new文件-已测成功 方法2、[rootlocalhost nginx]# kill -s USR1 4108 #与nginx -s reopen 效果相同-已测 ③此时已经生成了新的access.log日志文件 [rootkuang-73 logs]# ll -rw-r–r-- 1 nginx root 0 4月 2 22:01 access.log #用户为nginx于是工作进程可写 -rw-r–r-- 1 root root 1064 4月 2 22:00 access.log.back 动态升级可执行文件 ①用新版本Nginx可执行程序覆盖旧版本可执行程序 [rootkuang-76 ~]# cp objs/nginx /usr/local/nginx/sbin/nginx #执行这条命令可能会报以下异常提示文件被占用 xueliangdev:~/download/nginx-1.11.1$ sudo cp objs/nginx /usr/local/nginx/sbin/nginx cp: cannot create regular file ‘/usr/local/nginx/sbin/nginx’: Text file busy xueliangdev:~/download/nginx-1.11.1$ ①可以使用以下命令进行强制覆盖 [rootkuang-76 ~]# cp -rfp objs/nginx /usr/local/nginx/sbin/nginx ②动态升级可执行文件 [rootkuang-76 ~]# kill -s USR2 4108 #对nginx主进程发送信号 ③所有新老主进程和worker进程共存 [rootkuang-76 ~]# ps -ef | grep nginx root 4108 1 0 2月26 ? 00:00:00 nginx: master process /usr/sbin/nginx nginx 86100 4108 0 17:33 ? 00:00:00 nginx: worker process nginx 86101 4108 0 17:33 ? 00:00:00 nginx: worker process nginx 86102 4108 0 17:33 ? 00:00:00 nginx: worker process nginx 86103 4108 0 17:33 ? 00:00:00 nginx: worker process root 87120 4108 1 17:47 ? 00:00:00 nginx: master process /usr/sbin/nginx nginx 87126 87120 0 17:47 ? 00:00:00 nginx: worker process nginx 87127 87120 0 17:47 ? 00:00:00 nginx: worker process nginx 87128 87120 0 17:47 ? 00:00:00 nginx: worker process nginx 87129 87120 0 17:47 ? 00:00:00 nginx: worker process ④将old master下的worker 进程优雅关闭 [rootkuang-76 ~]# kill -s WINCH 4108 ⑤old master只有自己而没有工作进程了 [rootkuang-76 ~]# ps -ef | grep nginx root 4108 1 0 2月26 ? 00:00:00 nginx: master process /usr/sbin/nginx root 87120 4108 0 17:47 ? 00:00:00 nginx: master process /usr/sbin/nginx nginx 87126 87120 0 17:47 ? 00:00:00 nginx: worker process nginx 87127 87120 0 17:47 ? 00:00:00 nginx: worker process nginx 87128 87120 0 17:47 ? 00:00:00 nginx: worker process nginx 87129 87120 0 17:47 ? 00:00:00 nginx: worker process ⑥升级后的进程运行有问题 [rootkuang-73 ~]# kill -s HUP 76152 #将old master开启它的所有worker进程并开始工作 [rootkuang-73 ~]# kill -s QUIT 77434 #将有问题的new master从容关闭 ⑦升级后的进程运行稳定 [rootkuang-73 ~]# kill -s QUIT 76152 #完成工作交接就可以将old master关闭 ⑧平滑升级使用说明 可以在升级前将配置提前修改好平滑升级后会使用新的配置文件因为平滑升级后原来的主进程也是会重新替换的 查看Nginx所有进程的优雅格式 [rootlocalhost ~]# ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep ‘(nginx|PID)’ PID PPID USER %CPU VSZ WCHAN COMMAND 22650 1 root 0.0 124964 sigsus nginx: master process /usr/sbin/nginx 22651 22650 nginx 0.0 137668 ep_pol nginx: worker process 22652 22650 nginx 0.0 137668 ep_pol nginx: worker process 22653 22650 nginx 0.0 137668 ep_pol nginx: worker process 22654 22650 nginx 0.0 137668 ep_pol nginx: worker process Nginx支持的六类信号 ①主进程可以处理以下的信号 TERM,INI 快速关闭 QUIT 从容关闭 HUP 重载配置用新的配置开始新的工作进程从容关闭旧的工作进程 USR1 重新打开日志文件 USR2 平滑升级可执行程序 WINCH 从容关闭工作进程 ②工作进程也支持一些信号尽管你不必自己操作 TERM,INI 快速关闭 QUIT 从容关闭 USR1 重新打开日志文件 ③查看所有信号 [rootkuang-73 ~]# kill -l #Nginx只是支持其中的几个信号 杀死Nginx进程的方法 方法1、[rootkuang-73 ~]# pkill -9 nginx #强制关闭Nginx所有进程 方法2、[rootkuang-73 ~]# kill -TERM 75562 #强制关闭Nginx所有进程 方法3、[rootkuang-73 ~]# kill -15 75562 #和上条命令是同一条 方法4、[rootkuang-73 ~]# kill -QUIT 75562 #从容关闭Nginx主进程和子进程 方法5、[rootkuang-73 ~]# kill -QUIT cat /usr/local/nginx/nginx.pid Nginx监控 监控Nginx后端服务器 重新编译安装Nginx ①下载nginx-module-vts模块 [rootkuang-76 ~]# cd /usr/local/src/ [rootkuang-76 src]# git clone git://github.com/vozlt/nginx-module-vts.git②构建Nginx [rootkuang-76 src]# cd nginx-1.14.2/ [rootkuang-76 nginx-1.14.2]# ./configure --prefix/usr/local/nginx --usernginx --groupnginx --without-http_uwsgi_module --without-http_scgi_module --without-http_browser_module --with-pcre --with-http_addition_module --with-http_ssl_module --with-http_realip_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_gunzip_module --with-http_secure_link_module --with-http_stub_status_module --add-module/usr/local/src/nginx-module-vts③编译Nginx [rootkuang-76 nginx-1.14.2]# make -j 4 ④替换Nginx二进制执行程序 [rootkuang-76 nginx-1.14.2]# cp objs/nginx /usr/local/nginx/sbin/nginx 配置Nginx主配置 [rootkuang-76 ~]# vim /usr/local/nginx/conf/nginx.conf http {vhost_traffic_status_zone;vhost_traffic_status_filter_by_host on;server {listen 80;server_name localhost;location / {root html;index index.html index.htm;}location /status {vhost_traffic_status_display;vhost_traffic_status_display_format html;} include vhost/*.conf; }配置两个Vhost虚拟机配置 [rootkuang-76 ~]# vim /usr/local/nginx/conf/vhost/kuang.edsmall.com.conf upstream proxy {server 192.168.7.7:80 max_fails10 fail_timeout5; } server {listen 80;server_name kuang.edsmall.com;location / {proxy_pass http://proxy;proxy_set_header Host $host;proxy_set_header x-forwarded-for $remote_addr;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection upgrade;proxy_connect_timeout 600;proxy_read_timeout 600;proxy_send_timeout 600;proxy_intercept_errors on;} # location /status { # vhost_traffic_status_display; # vhost_traffic_status_display_format html; # } }[rootkuang-76 ~]# vim /usr/local/nginx/conf/vhost/zhilu.edsmall.com.conf upstream zhilu {server 192.168.7.7:81 max_fails10 fail_timeout5; } server {listen 80;server_name zhilu.edsmall.com;location / {proxy_pass http://zhilu;proxy_set_header Host $host;proxy_set_header x-forwarded-for $remote_addr;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection upgrade;proxy_connect_timeout 600;proxy_read_timeout 600;proxy_send_timeout 600;proxy_intercept_errors on;} # location /status { # vhost_traffic_status_display; # vhost_traffic_status_display_format html; # } }建议配置 ①打开vhost过滤 vhost_traffic_status_filter_by_host on; #开启此功能在Nginx配置有多个server_name的情况下会根据不同的server_name进行流量的统计否则默认会把流量全部计算到第一个server_name上。②在不想统计流量的server区域禁用vhost_traffic_status server { ... vhost_traffic_status off; ... }访问Nginx后端服务器监控页面 ①通过Web访问Nginx后端服务器监控 ②验证Nginx的json格式 [rootkuang-76 ~]# curl http://localhost/status/format/json 安装nginx-vts-exporter #下载最新版nginx-vts-exporter [rootkuang-76 ~]# cd /usr/local/src/ [rootkuang-76 src]# wget -c https://github.com/hnlq715/nginx-vts-exporter/releases/download/v0.10.3/nginx-vts-exporter-0.10.3.linux-amd64.tar.gz [rootkuang-76 src]# tar xf nginx-vts-exporter-0.10.3.linux-amd64.tar.gz #启动nginx-vts-exporter [rootkuang-76 src]# cd nginx-vts-exporter-0.10.3.linux-amd64 [rootkuang-76 nginx-vts-exporter-0.10.3.linux-amd64]# nohup ./nginx-vts-exporter -nginx.scrape_timeout 10 -nginx.scrape_uri http://127.0.0.1/status/format/json #配置nginx-vts-exporter服务 [Unit] Descriptionnginx-vts-exporter Afternetwork.target [Service] Typesimple ExecStart/usr/local/nginx-vts-exporter/nginx-vts-exporter -nginx.scrape_urihttp://127.0.0.1/vts_status/format/json Restarton-failure [Install] WantedBymulti-user.target#启动服务nginx-vts-exporter 默认监听端口为 9913 [rootkuang-76 ~]# systemctl enable nginx-vts-exporter [rootkuang-76 ~]# systemctl start nginx-vts-exporter [rootkuang-76 ~]# systemctl status nginx-vts-exporterPrometheus中添加Nginx监控 ①添加Nginx监控配置文件 [rootkuang-75 ~]# vim /usr/local/Prometheus/prometheus.yml - job_name: Yunwei-Environmentstatic_configs:- targets: [192.168.7.6:9913]labels:instance: 192.168.7.6②热重启Prometheus [rootkuang-77 ~]# curl -XPOST http://localhost:9090/-/reload 配置Nginx监控Dashboard ①下载Nginx监控Dashboard https://grafana.com/dashboards/2949 ②导入Nginx监控的Json文件 ③查看Nginx监控信息 使用nginx-vts监控后端upstream ①查看nginx-module-vts模块获取的信息 http://172.16.68.172:8888/status ②查看nginx-vts-exporter获取的信息 http://172.16.68.172:9913/metrics nginx_upstream_responseMsec 在Prometheus上监控此upstream后端响应时间应该可以做后端端口检测 监控Nginx状态和连接 查看Nginx状态 ①Nginx状态查看模块 http_stub_status_module ②Nginx使用状态模块 location /status {stub_status;}③测试模块运行 http://192.168.7.3/status ④查看结果说明 Active connections #当前Nginx正处理的活动连接数已有的连接 server accepts handled requests #总共处理了5452191个连接成功创建5452191次握手总共处理了10970248个请求 Reading #Nginx正在读取客户端的Header信息数 Writing #Nginx正在返回客户端的Header信息数 Waiting #开启keep-alive的情况下这个值等于active-(readingwriting)意思就是Nginx已经处理完正在等候下一次请求指令的驻留连接 ⑤AWKD现网配置 location /nginx_status {stub_status on;access_log off;allow 127.0.0.1;allow 172.16.239.242; #只允许Zabbix服务器访问deny all;}监控Nginx运行状态 ①查看Nginx运行状态命令包含状态码 [rootkuang-73 ~]# curl -m 5 -s -w %{http_code} http://192.168.7.6/status ②参数说明 选项m最大传输时间选项s静默执行没有杂七杂八输出选项w命令完成后再输出什么参数 ③优化输出只输出状态码 [rootkuang-73 ~]# curl -m 5 -s -w %{http_code} http://192.168.7.3/status -o /dev/null ④查看线上Nginx的并发连接 由于Nginx上都做有80强制跳转443所以查看443的连接最直接最准确。 #注意其中TIME_WAIT、FIN_WAIT1和FIN_WAIT2在Nginx中不记作连接数内看这类连接的后面都没有对应的nginx:worker在维护这个连接 ⑤查看Nginx与后端建立的连接 #注意由于Nginx并不是和后端统一的建立80端口的连接所以这里只能针对每一个vhost来查找其连接情况 Nginx的并发连接数不包括和后端服务器的连接 ①查看Nginx的Established状态的并发连接数为3 ②查看所有和Nginx前后端有关的连接 由下图可知Nginx的Established并发连接数只是统计了有多少个客户端而没有将和后端服务器建立的连接一起统计。 监控Nginx状态脚本 ①监控Nginx状态脚本 [rootkuang-73 ~]# vim chk_nginx.sh #!/bin/bash Resettem$(tput sgr0) Nginxserverhttp://192.168.7.3/status Check_Nginx_Server() {Status_code$(curl -m 5 -s -w %{http_code} ${Nginxserver} -o /dev/null)if [ $Status_code -eq 000 -o $Status_code -ge 500 ] ; thenecho -e \E[31m check http server error! Response status code is $Resettem $Status_codeelseHttp_content$(curl -s ${Nginxserver})echo -e \E[32m check http server ok! \n $Resettem $Http_contentfi } Check_Nginx_Server②脚本说明 说明1、‘\E[31m’和’\E[32m’分别代表红色和绿色 说明2、tput sgr0指令表示恢复到正常屏幕取消之前修改的颜色 说明3、一般来说状态码为000或者大于等于500为Web服务器运行不正常。 监控Nginx后端健康状况 ​ 严格来说Nginx是没有针对负载均衡后端节点的健康检查的但是可以通过proxy_next_upstream来间接实现但这个还是会把请求转发给故障服务器的然后再转发给别的服务器这样就浪费了一次转发。默认该功能是运行的实验中出现后端服务器down了看起来Nginx没有再发送请求到该后端服务器就是该功能实现的效果其实是转发了给down的那台后端服务器请求不成功再转发给别的后端服务器的 Nginx后端健康监测 ①下载Nginx健康监测模块 https://github.com/yaoweibin/nginx_upstream_check_module ②上传并将该模块打入Nginx补丁 [rootkuang-77 ~]# unzip nginx_upstream_check_module-master.zip [rootkuang-77 ~]# cd /usr/local/nginx-1.14.2/ [rootkuang-77 nginx-1.14.2]#patch -p1 /root/nginx_upstream_check_module-master/check_1.14.0.patch推荐下一款模块因为不需要打补丁这一步骤只需指向该目录即可 ②其他nginx_upstream_check_module模块 [rootkuang-77 ~]# git clone https://github.com/xiaokai-wang/nginx_upstream_check_module.git ③获取原Nginx编译参数 [rootkuang-77 nginx-1.14.2]# /usr/local/nginx/sbin/nginx -V --prefix/usr/local/nginx --usernginx --groupnginx --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_flv_module --with-http_ssl_module --with-http_mp4_module --with-pcre --with-http_v2_module --with-stream④重新构建Nginx并带上补丁模块 [rootkuang-77 nginx-1.14.2]# ./configure --prefix/usr/local/nginx --usernginx --groupnginx --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_flv_module --with-http_ssl_module --with-http_mp4_module --with-pcre --with-http_v2_module --with-stream --add-module/root/nginx_upstream_check_module-master/⑤重新编译Nginx [rootkuang-77 nginx-1.14.2]# make -j 4 ⑥替换原Nginx二进制执行程序 [rootkuang-77 ~]# pgrep nginx [rootkuang-77 ~]# pkill nginx [rootkuang-77 ~]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak [rootkuang-77 ~]# cp /usr/local/nginx-1.14.2/objs/nginx /usr/local/nginx/sbin/nginx⑦修改Nginx配置支持后端健康监测 [rootkuang-77 ~]# vim /usr/local/nginx/conf/nginx.conf #在http代码块中添加如下配置 upstream backend {server 192.168.7.5;server 192.168.7.6;check interval3000 rise2 fall3 timeout3000 typehttp;}server {location /nginx_status {stub_status on;access_log off;}location /nstatus {check_status;access_log off;}}⑧查看后端健康监测效果 server number是后端服务器的数量generation是Nginx reload的次数 ⑨测试后端健康监测 [rootkuang-75 ~]# systemctl stop httpd #关闭其中一个后端服务 日志管理 自定义日志格式 [rootkuang-73 ~]# vim /usr/local/nginx/conf/nginx.conf #上下文为http log_format main $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for;access_log logs/access.log main;#以上的main为格式名称可以修改然后在引用处也要修改并且没有冒号说明是一行的内容脚本切割Nginx日志 ①日志分割脚本 [rootAWKD-NGINX-172 ~]# vim /usr/local/nginx/sbin/nginx_log_cut.sh #!/bin/sh logs_path/usr/local/nginx/logs yesterdaydate -d yesterday %F olddatedate -d 30 days ago %F mkdir -p $logs_path/log-bak/$yesterday cd $logs_pathfor nginx_logs in ls *.log;domv $nginx_logs log-bak/${yesterday}/${yesterday}-${nginx_logs}gzip log-bak/${yesterday}/${yesterday}-${nginx_logs}kill -USR1 cat /usr/local/nginx/logs/nginx.pid done②日志分割定时任务 [rootAWKD-NGINX-172 ~]# crontab -l 10 0 * * * sh /usr/local/nginx/sbin/nginx_log_cut.sh系统logrotate切割日志 ①为什么要分割日志文件 针对于源码编译安装的Nginx需要配置日志切割yum安装的会自动产生Nginx切割配置文件 ②编写Nginx日志切割配置文件 第一种配置文件写法 [rootkuang-73 ~]# vim /etc/logrotate.d/nginx /var/log/nginx/*log { #指定正确的日志位置 create 0644 nginx nginx daily rotate 10 missingok notifempty compress sharedscripts postrotate/bin/kill -USR1 cat /run/nginx.pid 2/dev/null 2/dev/null || true endscript }第二种配置文件写法 [rootkuang-73 ~]# vim /etc/logrotate.d/nginx /var/log/nginx/*log { #指定正确的日志位置 daily rotate 30 missingok dateext compress delaycompress notifempty sharedscripts postrotateif [ -f /usr/local/nginx/nginx.pid ]; then #编译安装的文件位置kill -USR1 cat /usr/local/nginx/nginx.pid #重新加载配置文件fi endscript }优化日志 ①如果一个网页有100个图片那么就会产生100条日志这样非常不可取 location ~* .*\.(gif|png|jpg|jpeg|bmp|zip|swf)$ {expires 10d;access_log off;}location ~* .*\.(js|css)$ {expires 5d;access_log off;}②但是好像并没有关闭访问http://192.168.7.3/index.php时产生的访问图片的日志 [rootkuang-73 ~]# tailf /usr/local/nginx/logs/access.log #动态查看 性能调优 设置CPU亲和力 1、进程数设置 一般我们设置CPU的核心或者两倍核心数 2、设置进程亲和力 [rootkuang-73 ~]# vim /usr/local/nginx/conf/nginx.conf worker_cpu_affinity 0001 0010 0100 1000; #其他配置方式 worker_processes 4; worker_cpu_affinity auto; #[rootkuang-73 ~]# /usr/local/nginx/sbin/nginx -s reload2、查看亲和力 ①一个进程绑定一个CPU核心 [rootkuang-73 ~]# ps -aux | grep nginx root 60761 0.0 0.1 46024 1980 ? Ss 20:26 0:00 nginx: master process /usr/local/nginx/sbin/nginx nobody 61666 0.0 0.1 48536 2020 ? S 20:51 0:00 nginx: worker process nobody 61667 0.0 0.1 48536 2020 ? S 20:51 0:00 nginx: worker process nobody 61668 0.0 0.1 48536 2020 ? S 20:51 0:00 nginx: worker process nobody 61669 0.0 0.1 48536 2020 ? S 20:51 0:00 nginx: worker process [rootkuang-73 ~]# taskset -cp 60761 pid 60761s current affinity list: 0-3 [rootkuang-73 ~]# taskset -cp 61666 pid 61666s current affinity list: 0 [rootkuang-73 ~]# taskset -cp 61667 pid 61667s current affinity list: 1 [rootkuang-73 ~]# taskset -cp 61668 pid 61668s current affinity list: 2资源使用设置 #所有进程最多能打开的文件总数 worker_rlimit_nofile 65535; #文件数资源限制所有Nginx进程能打开的文件总数不管你谁打开的更多或更少还可以设置更大理论上一个Nginx工作进程能打开的为该总数除以进程数但是Nginx分配请求并不均匀所以建议与ulimit -n的值保持一致#单个进程最大连接数 events {worker_connections 65535; #单个进程最大连接数实际运行时该值*进程数不能大于文件总数限制 } #[rootkuang-73 ~]# ulimit -n #系统限制一个进程最多能打开的文件总数 #1024 #系统默认限制为1024 #[rootkuang-73 ~]# ulimit -SHn 65535 #设置为和Nginx设置同步#Nginx事件处理模型 events { use epoll; worker_connections 65535; multi_accept on; }#一次性可以接受多个新连接 multi_accept默认关闭为off #情况1、如果关闭一个进程一次只能接受一个新连接 #情况2、如果开启一个进程一次接受所有新连接epoll可以kqueue不行连接超时时间 1、设置连接超时作用 主要目的是保护服务器资源CPU内存控制连接数因为建立连接也是需要消耗资源的 2、各类连接超时相关参数 keepalive_timeout 60; tcp_nodelay on; client_header_buffer_size 4k; open_file_cache max102400 inactive20s; open_file_cache_valid 30s; open_file_cache_min_uses 1; client_header_timeout 15; #TCP连接后客户端发送header的超时时间超时返回408 client_body_timeout 15; #发送header后等待body的超时时间超时返回408 reset_timedout_connection on; send_timeout 15; #两次请求间隔 server_tokens off; client_max_body_size 10m;3、制造408错误码 ①设置服务器超时 client_header_timeout 15; #TCP连接后客户端发送header的超时时间超时返回408 client_body_timeout 15; #发送header后等待body的超时时间超时返回408 ②客户端去连接服务器确不发送请求 [roottke-node2 ~]# nc 193.112.180.221 80 4、keepalive_timeout 语法 keepalive_timeout timeout [ header_timeout ] 默认值 75s 上下文 http server location​ 说明第一个参数指定了与client的keep-alive连接超时时间。服务器将会在这个时间后关闭连接。可选的第二个参数指定了在响应头Keep-Alive: timeouttime中的time值。这个头能够让一些浏览器主动关闭连接这样服务器就不必要去关闭连接了。没有这个参数nginx不会发送Keep-Alive响应头尽管并不是由这个头来决定连接是否“keep-alive” ​ 两个参数的值可并不相同不同浏览器怎么处理“keep-alive”头 MSIE和Opera忽略掉Keep-Alive: timeout header MSIE保持连接大约60-65秒然后发送TCP RST Opera永久保持长连接 Mozilla keeps the connection alive for N plus about 1-10 seconds Konqueror保持长连接N秒 5、proxy_upstream_fail_timeoutfail_timeout 语法 server address [fail_timeout30s] 默认值 10s 上下文 upstream​ 说明Upstream模块下 server指令的参数设置了某一个upstream后端失败了指定次数max_fails后该后端不可操作的时间默认为10秒。 后端服务器长连接 1、配置长连接目的 Nginx在反向代理HTTP协议的时候默认使用的是HTTP1.0去向后端服务器获取响应的内容后在返回给客户端。注意生产中并没有开启是不是为了减少Nginx的连接数量 2、Nginx和后端服务器长连接配置 http{upstream www{server 192.168.7.7:8080;keepalive 50; #必须配置建议50-100之间}server {location / {proxy_pass http://www;proxy_http_version 1.1; #后端配置支持HTTP1.1必须配置proxy_set_header Connection ; #后端配置支持HTTP1.1必须配置-已测试proxy_set_heaser Host www.baidu.com; #需要将Host设置成为后端可以接收的host否则这里会变成www导致访问异常} }3、长连接效果 当在客户端浏览器访问192.168.7.7的时候在Nginx代理服务器上保持了两个长连接 在后端服务器保持了一个与Nginx代理服务器的连接 gzip压缩 1、gzip压缩上下文为http gzip on; #开启gzip压缩输出 gzip_min_length 1k; #从1k起开始压缩不然有些小于1k的压缩后还比1k大 gzip_buffers 4 32k; #表示申请4个单位为16k的内存作为压缩结果流缓存默认值是申请与原始数据大小相同的内存空间来储存gzip压缩结果 gzip_http_version 1.1; #设置识别http协议版本默认就是1.1版本 gzip_comp_level 6; #压缩等级5和6就行了不要压到9 gzip_types text/css /text/xml appalication/javascript; #压缩哪些媒体text/html默认就压缩 gzip_vary on; #宣告我压缩了2、线上配置 gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on;防盗链 1、防盗链 ①在客户端添加域名解析 192.168.7.3 www.linuxfan.cn 192.168.7.4 www.linuxren.cn ②在防盗链机器上添加测试图片 [rootkuang-73 ~]# cp -rp //usr/share/backgrounds/night.jpg /usr/share/nginx/html/ [rootkuang-73 ~]# systemctl restart nginx ③在盗链机器上链接防盗链图片 [rootkuang-74 ~]# vim /usr/share/nginx/html/index.html html head titlehello world/title /head body www.linuxren.cn img srchttp://www.linuxfan.cn/night.jpg/ /body /html④客户端测试正常访问 可通过访问http://www.linuxren.cn/查看到未处理的防盗链图片 ⑤防盗链机器上配置防盗链策略 [rootkuang-73 ~]# vim /etc/nginx/nginx.conf location ~* .*\.(wma|wmv|asf|mp3|mmf|zip|rar|gif|jpg|jpeg|png|bmp|swf)$ {valid_referers none blocked *.linuxfan.cn linuxfan.cn;if ($invalid_referer) {rewrite ^/ http://www.otherdomin.com/404.jpg;#return 404;} }[rootkuang-73 ~]# systemctl restart nginx ⑥客户端测试防盗链访问 通过访问http://www.linuxren.cn/已经看不到已处理的防盗链图片 #注配置防盗链不能和expire缓存同存 sendfile的优化 ​ Nginx做静态服务器的优化。 ​ sendfile是个比 read 和 write 更高性能的系统接口 不过需要注意的是sendfile 是将 in_fd 的内容发送到 out_fd 。而 in_fd 不能是 socket 也就是只能文件句柄。 所以当 Nginx 是一个静态文件服务器的时候开启 SENDFILE 配置项能大大提高 Nginx 的性能。 但是当 Nginx 是作为一个反向代理来使用的时候SENDFILE 则没什么用了因为 Nginx 是反向代理的时候。 in_fd 就不是文件句柄而是 socket此时就不符合 sendfile 函数的参数要求了。 访问控制 目录访问控制 ①配置访问控制要放在匹配php的前面 location ~* ^/images/.*.(php|php5|sh|py|pl)$ { deny all; } ②创建控制目录下的PHP文件 [rootkuang-73 ~]# cd /usr/local/nginx/html/ [rootkuang-73 html]# mkdir images [rootkuang-73 html]# cp index.php images/ ③测试访问 http://192.168.7.3/images/index.php不能访问 #403 Forbidden禁止访问 ④想增加可以访问的用户 在拒绝所有前添加allow 192.168.7.2; 设置密码访问目录 ①下载密码生成工具 [rootkuang-76 ~]# yum -y install httpd-tools ②生成账号密码 [rootkuang-76 ~]# htpasswd -cb /usr/local/nginx/conf/user.conf zs 123 #创建zs用户并添加密码 [rootkuang-76 ~]# vim /usr/local/nginx/conf/nginx.conf #添加以下内容 location /status { stub_status on; #有的版本直接不需要on这个参数access_log off;auth_basic Nginx Status; #认证提示文字auth_basic_user_file /usr/local/nginx/conf/user.conf; #认证用户文件用htpasswd生成allow 192.168.7.2;deny 192.168.7.0/24;}各云环境白名单控制 Tencent 加白 server {set $clientip $remote_addr;if ( $http_x_real_ip ){set $clientip $http_x_real_ip;}proxy_set_header remote-user-ip $clientip;location ~ ^/v2/gdosapi {allow 101.32.128.230;} }Azure 加白 http {map $http_x_forwarded_for $access{default false;~*101.32.128.230 true;~*101.32.162.39 true;~*20.94.227.90 true;}server {set $clientip $http_x_forwarded_for;proxy_set_header remote-user-ip $clientip;set $x_forwarded_for_noport 1.1.1.1;if ( $http_x_forwarded_for ~ ^(.*):(.*)$ ) {set $x_forwarded_for_noport $1;}proxy_set_header X-Real-IP $x_forwarded_for_noport;} }AWS 加白 http {proxy_set_header remote-user-ip $remote_addr;server {set $clientip $http_x_forwarded_for;proxy_set_header remote-user-ip $clientip;proxy_set_header X-Real-IP $http_x_forwarded_for;}传输加密 本地搭建CA并颁发证书 CA认证中心配置 1、配置CA认证机构 [rootkuang-73 ~]# vim /etc/pki/tls/openssl.cnf basicConstraintsCA:TRUE 2、创建一个证书颁发机构 [rootkuang-73 ~]# /etc/pki/tls/misc/CA -newca #生成CA的公私钥和配置其信息 ①CA证书文件名回车使用默认的名字 ②给CA的私钥添加保护密码123456 ③国家CN ④省份GuangDong ⑤城市ShenZhen ⑥组织名XueGod ⑦组织单位名IT ⑧服务器名ca.xuegod.cn ⑨邮箱1xuegod.cn ⑩challenge password拓展的属性可能某些过程比如申请时用的到不需要的话就回车 ⑩公司名回车 ⑩输入CA私钥的保护密码123456 3、查看CA生成的公私钥 ①生成公私钥后的目录结构 [rootkuang-73 ~]# cd /etc/pki/CA/ [rootkuang-73 CA]# ll -rw-r–r–. 1 root root 4422 1月 4 15:23 cacert.pem #主要包含了CA服务器信息和其根证书最下面是CA的根证书即CA的公钥需要被用户信任和添加的证书 -rw-r–r–. 1 root root 1033 1月 4 15:23 careq.pem drwxr-xr-x. 2 root root 6 4月 11 2018 certs drwxr-xr-x. 2 root root 6 4月 11 2018 crl -rw-r–r–. 1 root root 111 1月 4 15:23 index.txt -rw-r–r–. 1 root root 21 1月 4 15:23 index.txt.attr -rw-r–r–. 1 root root 0 1月 4 15:21 index.txt.old drwxr-xr-x. 2 root root 34 1月 4 15:23 newcerts drwx------. 2 root root 23 1月 4 15:21 private #存放CA的私钥 -rw-r–r–. 1 root root 17 1月 4 15:23 serial ②生成公私钥前的目录结构 [rootkuang-73 ~]# ls /etc/pki/CA/ #以下四个空目录 certs crl newcerts private Web服务器端生成证书请求文件 1、安装nginx和支持ssl的模块 [rootkuang-74 ~]# yum install -y nginx mod_ssl.x86_64 2、生成web server的私钥 ①方法1、生成加密的私钥 [rootkuang-74 ~]# openssl genrsa -des3 -out /etc/httpd/conf.d/server.key #使用des3加密 [rootkuang-74 ~]# cd /etc/httpd/conf.d/ [rootkuang-74 conf.d]# cp server.key server.key.org [rootkuang-74 conf.d]# openssl rsa -in server.key.org -out server.key #去掉私钥的加密因为私钥有加密后面不能使用systemctl启动Nginx而可以使用Nginx启动程序启动所以在加载SSL支持的Nginx并使用私钥时除去必须的口令 ②方法2、生成不加密的私钥 [rootkuang-74 ~]# openssl genrsa -out /etc/httpd/conf.d/test.key #推荐使用该方法没有问题 3、生成证书请求文件 [rootkuang-74 ~]# openssl req -new -key /etc/httpd/conf.d/server.key -out /root/server.csr #-key指定私钥文件位置-out导出位置直接通过私钥去找公钥 #录入证书请求文件信息如果要去CA请求数字签名必须和CA录入信息保持一致就算城市写错了也不行CA服务器生成CA证书时会报错 ①输入CA私钥的保护密码123456 ②国家CN ③省份GuangDong ④城市ShenZhen ⑤组织名XueGod ⑥组织单位名IT ⑦服务器名www.xuegod.cn ⑧邮箱2xuegod.cn ⑨challenge password拓展的属性可能某些过程比如申请时用的到不需要的话就回车 ⑩公司名回车 4、将证书请求文件上传给CA [rootkuang-74 ~]# scp server.csr 192.168.7.3:/root #证书里包含了web服务器信息和公钥 CA认证中心生成证书 1、CA认证中心生成证书 [rootkuang-73 ~]# openssl ca -keyfile /etc/pki/CA/private/cakey.pem -cert /etc/pki/CA/cacert.pem -in /root/server.csr -out /root/server.crt #-keyfile指定私钥-cert指定根证书即CA的公钥 2、将证书传给Web服务器 [rootkuang-73 ~]# scp server.crt 192.168.7.4:/root Web服务器使用证书配置 1、证书文件存储位置 [rootkuang-74 ~]# mv server.crt /etc/httpd/conf.d/ 2、配置Web服务器支持ssl [rootkuang-74 ~]# vim /etc/nginx/conf.d/default.conf server { listen 443 ssl; #server_name www.xuegod.cn; #注意这里没有指定主机名后面也能成功 #ssl on; #注意这里没有开启ssl后面也能成功可能默认开启 keepalive_timeout 70; location / { root /usr/share/nginx/html; index index.html index.htm; } #ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5; ssl_certificate /etc/httpd/conf.d/server.crt; #证书存储位置阿里下载下来的后缀是.pem ssl_certificate_key /etc/httpd/conf.d/server.key; #密钥存储位置 #注意生产中一个域名如edsmall.com下的所有主机如sf.edsmall.com用的是同一个证书和密钥 ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; } 3、重启Web服务器使用ssl ①测试Nginx配置语法 [rootkuang-74 ~]# nginx -t ②重启Nginx服务器 [rootkuang-74 ~]# systemctl restart nginx #如果这里起不来可能的原因是Web的密钥有密码保护按上面的方法去掉密码保护 [rootkuang-74 ~]# nginx #以上不能起来直接使用Nginx的启动程序却能起来 ③查看ssl是否启动 [rootkuang-74 ~]# ss -lntup | grep 443 4、确保模块被加载 ①确保主配置文件导入了子配置文件 [rootkuang-74 ~]# vim /etc/nginx/nginx.conf #上下文为http include /etc/nginx/conf.d/*.conf; ②确保存在ssl模块 [rootkuang-74 ~]# nginx -V 客户端浏览器配置使用根证书 1、修改windows客户端的hosts文件 C:\Windows\System32\drivers\etc 192.168.7.4 www.xuegod.cn 2、到CA认证中心下载根证书 [rootkuang-73 ~]# sz /etc/pki/CA/cacert.pem #保存到桌面 3、IE浏览器中添加根证书 ①打开Internet选项点击证书 ②导入证书到“受信任的根证书” 4、测试使用根证书 ①访问Web服务器 https://www.xuegod.cn Nginx证书使用 尽量用相对路径相对于root根目录提升配置的可移植性。 upstream 71-pre {server 10.81.67.129:80 max_fails10 fail_timeout5;}server {listen 80;server_name 71-pre.edsmall.com;return 301 https://$server_name$request_uri; #return301高效一些#rewrite ^(.*)$ https://$host$1 permanent;access_log logs/71-pre.edsmall.com.access.log main;error_log logs/71-pre.edsmall.com.error.log error;}server {listen 443;server_name 71-pre.edsmall.com;access_log logs/https-71-pre.edsmall.com.access.log main;error_log logs/https-71-pre.edsmall.com.error.log error;ssl on;ssl_certificate sslkey/edsmall.com.pem; #证书公钥ssl_certificate_key sslkey/edsmall.com.key; #证书私钥ssl_session_timeout 5m;ssl_protocols TLSv1 TLSv1.1 TLSv1.2;#停掉SSLv3杜绝贵宾犬漏洞#ssl_ciphers ECDH:AESGCM:HIGH:!RC4:!DH:!MD5:!aNULL:!eNULL;ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;ssl_prefer_server_ciphers on;root /data/nginx/html;location / {proxy_pass http://71-pre;proxy_set_header Host $host;#prwxy_set_header X-Real-IP $remote_addr;proxy_set_header x-forwarded-for $remote_addr;#proxy_set_header X-Forwarded-For $http_x_forwarded_for;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection upgrade;proxy_connect_timeout 600;proxy_read_timeout 600;proxy_send_timeout 600;proxy_intercept_errors on;#error_page 403 404 /404.html;}location /404.html {root /data/nginx/html;}location /nginx_status {stub_status on;access_log off;allow 127.0.0.1;deny all;}error_page 500 502 503 504 /50x.html;location /50x.html {root /opt;}}排错 Nginx后端检查路径写错导致502问题 1、故障信息 https://xqlive.yetingfm.com/live-admin-v1报502错误 http://106.52.179.250:5001/live-admin-v1可以直接访问 2、故障定位 由于是502错误但是后端服务可直接被调用访问所以初步判断是Nginx配置问题 3、查看Nginx配置 发现chech_http_send后端检查的uri有问题分析是因为后端检查的uri写错导致后端检测失败Nginx认为无后端于是向客户端相应502。 4、修改Nginx为正确配置 修改之后访问正常 Nginx环境下http和https(ssl)共存的方法 1、问题描述 给nginx配置SSL证书之后https可以正常访问http访问显示400错误报错如下 400 Bad Request The plain HTTP requset was sent to HTTPS port. Sorry for the inconvenience. Please report this message and include the following information to us. Thank you very much! #说明http的请求被发送到https的端口上去了所以才会出现这样的问题。nginx的配置如下 server {listen 80 default backlog2048;listen 443;server_name domain.cn;root /var/www/html;ssl on;ssl_certificate /etc/nginx/ssl/domain.cn.crt;ssl_certificate_key /etc/nginx/ssl/domain.cn.key;}2、解决方案 把**ssl on**这行去掉ssl写在443端口后面这样http和https的链接都可以用。 server {listen 80 default backlog2048;listen 443 ssl;server_name domain.cn;root /var/www/html;ssl_certificate /etc/nginx/ssl/domain.cn.crt;ssl_certificate_key /etc/nginx/ssl/domain.cn.key;}截断问题 问题现象返回数据很长的情况下数据会被截断。 keepalive_timeout 0; proxy_connect_timeout 1000; proxy_send_timeout 1000; proxy_read_timeout 1000; send_timeout 1000; proxy_http_version 1.1;proxy_buffering on;proxy_buffers 16 512k;proxy_buffer_size 512k;keepalive_timeout 0;proxy_connect_timeout 1000;proxy_send_timeout 1000;proxy_read_timeout 1000;send_timeout 1000;proxy_http_version 1.1;Consul服务动态发现 下载Nginx模块 ①下载nginx_upstream_check_module模块 [rootkuang-75 ~]# git clone https://github.com/xiaokai-wang/nginx_upstream_check_module.git ②下载nginx-upsync-module模块 [rootkuang-75 ~]# git clone https://github.com/weibocom/nginx-upsync-module.git 安装Consul ①下载并安装Consul [rootkuang-75 ~]# wget https://releases.hashicorp.com/consul/1.6.1/consul_1.6.1_linux_amd64.zip [rootkuang-75 ~]# unzip consul_1.6.1_linux_amd64.zip [rootkuang-75 ~]# mv consul /usr/local/ ②启动Consul [rootkuang-75 ~]# cd /usr/local/ [rootkuang-75 local]# nohup ./consul agent -server -bootstrap-expect 1 -data-dir/data/consul -nodeserver1 -bind192.168.7.5 -client0.0.0.0 -ui consul.log 21 安装Nginx ①安装Nginx依赖 [rootkuang-75 ~]# yum -y install zlib zlib-devel pcre pcre-devel openssl openssl-devel automake autoconf gcc gcc-c ②构建Nginx [rootkuang-75 nginx-1.14.2]# ./configure --prefix/usr/local/nginx --usernginx --groupnginx --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_flv_module --with-http_ssl_module --with-http_mp4_module --with-pcre --with-http_v2_module --with-stream --add-module/root/nginx_upstream_check_module/ --add-module/root/nginx-upsync-module ③安装Nginx [rootkuang-75 nginx-1.14.2]# make -j 4 make install 配置动态获取upstream信息 ①server中配置 location / {root html;index index.html index.htm;proxy_pass http://pic_backend;}location /nstatus {check_status;access_log off;}location /upstream_show {upstream_show;}location /upstream_status {stub_status on;access_log off;}②upstream配置 upstream pic_backend {server 192.168.7.5:82;upsync 192.168.7.5:8500/v1/kv/upstreams/pic_backend upsync_timeout6m upsync_interval500ms upsync_typeconsul strong_dependencyoff;upsync_dump_path /usr/local/nginx/conf/servers/servers_pic_backend.conf;check interval1000 rise2 fall2 timeout3000 typehttp default_downfalse;check_http_send HEAD / HTTP/1.0\r\n\r\n;check_http_expect_alive http_2xx http_3xx;} #注意后三行需要添加否则在upstream check status中看不到[rootkuang-75 ~]# mkdir /usr/local/nginx/conf/servers/ [rootkuang-75 ~]# touch /usr/local/nginx/conf/servers/servers_pic_backend.conf [rootkuang-75 ~]# chown -R nginx.nginx /usr/local/nginx/ #启动Nginx [rootkuang-75 ~]# /usr/local/nginx/sbin/nginx -t [rootkuang-75 ~]# /usr/local/nginx/sbin/nginx实现服务动态发现 ①Consul中添加upstream服务器 [rootkuang-75 ~]# curl -X PUT -d ‘{“weight”:10, “max_fails”:2, “fail_timeout”:10, “down”:0}’ http://192.168.7.5:8500/v1/kv/upstreams/pic_backend/192.168.7.6:80 [rootkuang-75 ~]# curl -X PUT -d ‘{“weight”:10, “max_fails”:2, “fail_timeout”:10, “down”:0}’ http://192.168.7.5:8500/v1/kv/upstreams/pic_backend/192.168.7.7:80 ②查看Consul中upstream键值对信息 ③查看Nginx中upstream信息 [rootkuang-75 ~]# curl http://192.168.7.5/upstream_show ④查看备份的upstream配置 [rootkuang-75 ~]# cat /usr/local/nginx/conf/servers/servers_pic_backend.conf ⑤访问Nginx服务测试负载均衡 拓展Consul其他命令 ①修改upstream信息 #注意应用场景切断流量然后在该后端服务器上进行上线发布 [rootkuang-75 ~]# curl -X PUT -d ‘{“weight”:10, “max_fails”:2, “fail_timeout”:10, “down”:1}’ http://192.168.7.5:8500/v1/kv/upstreams/pic_backend/192.168.7.7:80 ②Consul中删除K/V信息 [rootkuang-75 ~]# curl -X DELETE http://192.168.7.5:8500/v1/kv/upstreams/pic_backend/192.168.7.6:80 反代和负载均衡 简单反向代理和负载均衡 简单反向代理 1、带有URI部分的proxy_pass指令将会发生替换 location /uri { proxy_pass http://192.168.7.4/newuri; } ①newuri将会替换掉整个URL中的uri ②访问http://192.168.7.3/uri/a.html将会代理到http://192.168.7.4/newuri/a.html #两个特殊情况不能发生替换 情况1、location定义了一个正则表达式比如location ~ ^/uri { } 这种情况语法测试会报错proxy_pass不能获取在location内由正则表达式给予的URI部分。 情况2、proxy_pass前有rewrite命令 简单负载均衡 1、最简单的负载均衡 ①上下文为http upstream backend { server 192.168.7.4; server 192.168.7.5; } server { location / { proxy_pass http://backend; } ②测试RS的健康监测 将192.168.7.5的端口修改或者服务关闭 Nginx将不再调度到192.168.7.5而只会调度到192.168.7.4 2、配置一台服务器作为backup ①配置backup服务器 upstream backend { server 192.168.7.4; server 192.168.7.5:8000 backup; server 192.168.7.6; } ②使用说明 Nginx只会调度到服务器1和3 而且只有当1和3都挂掉主服务器全部宕机才会调度到backup服务器 标准反向代理配置 ①反向代理 location / {proxy_pass http://sxy;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header x-forwarded-for $remote_addr;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection upgrade; #proxy_http_version 1.1;proxy_connect_timeout 600;proxy_read_timeout 600;proxy_send_timeout 600;}②长连接反向代理 http{upstream www{server 192.168.7.7:8080;keepalive 50; #必须配置建议50-100之间}server {location / {proxy_pass http://www;proxy_http_version 1.1; #后端配置支持HTTP1.1必须配置proxy_set_header Connection ; #后端配置支持HTTP1.1必须配置-已测试上面增加upgrade也可以} }动静分离 网络TOP Nginx192.168.7.3 RS:192.168.7.4 RS:192.168.7.5 RS:192.168.7.61、Nginx负载均衡服务器配置 ①配置反向代理部分 [rootkuang-73 nginx]# vim conf/nginx.conf location / { #在其原有的localtion中添加或修改为如下root html;index index.html index.htm;if ($request_uri ~* \.php$){ #uri指的是除去域名的后面一段proxy_pass http://phpservers;}if ($request_uri ~* \.html$){proxy_pass http://htmlservers;}proxy_pass http://picservers;}②配置负载均衡部分 upstream phpservers {server 192.168.7.4;server 192.168.7.5; } upstream htmlservers {server 192.168.7.5;server 192.168.7.6; } upstream picservers {server 192.168.7.4;server 192.168.7.6; }③重启Nginx服务器加载配置 [rootkuang-73 nginx]# ./sbin/nginx -t #测试一下语法 [rootkuang-73 nginx]# ./sbin/nginx -s reload #重新加载一下2、三台RS配置 [rootkuang-74 ~]# yum -y install httpd php #可以处理动态php页面 [rootkuang-74 ~]# echo ?php phpinfo(); ? /var/www/html/1.php [rootkuang-74 ~]# cp /usr/share/backgrounds/night.jpg /var/www/html/1.jpg [rootkuang-74 ~]# systemctl restart httpd[rootkuang-75 ~]# yum -y install httpd php #可以处理动态php页面 [rootkuang-75 ~]# echo ?php phpinfo(); ? /var/www/html/1.php [rootkuang-75 ~]# echo From 7.5 HTML /var/www/html/1.html [rootkuang-75 ~]# systemctl restart httpd[rootkuang-76 ~]# yum -y install httpd [rootkuang-76 ~]# echo From 7.6 HTML /var/www/html/1.html [rootkuang-76 ~]# cp /usr/share/backgrounds/day.jpg /var/www/html/1.jpg [rootkuang-76 ~]# systemctl restart httpd3、测试负载均衡 ①在CMD中使用curl测试静态页面的负载均衡调度 C:\Windows\system32curl http://192.168.7.3/1.html From 7.6 HTML C:\Windows\system32curl http://192.168.7.3/1.html From 7.5 HTML ②在谷歌无痕浏览器中测试图片页面的负载均衡调度 http://192.168.7.3/1.jpg 4、测试反向代理——动静分离 #注意动静分离主要用在同一个网站中拥有动态和静态的内容需要交给不同服务器处理 ①Nginx调度器上删除负载均衡条目 [rootkuang-73 ~]# vim /usr/local/nginx/conf/nginx.conf upstream phpservers {server 192.168.7.4; } upstream htmlservers {server 192.168.7.5; } upstream picservers {server 192.168.7.6; }②重新加载配置 [rootkuang-73 nginx]# ./sbin/nginx -s reload ③RS上删除用于负载均衡的条目 [rootkuang-75 ~]# rm -rf /var/www/html/1.php [rootkuang-76 ~]# rm -rf /var/www/html/1.html [rootkuang-74 ~]# rm -rf /var/www/html/1.jpg [rootkuang-74 ~]# vim /var/www/html/index.php #在RS1上额外增加动静分离页面 iframe src1.html/iframe img src1.jpg ?php phpinfo(); ?④测试动静分离效果 访问192.168.8.3/index.php也可看见效果 获知后端服务IP地址 ①获知后端IP地址目的 服务器上线时测试可用性时确认某一个访问跳转到后端哪台服务器上 ②Nginx配置 location / {#root html;#index index.html index.htm;add_header backendIP $upstream_addr;add_header backendCode $upstream_status;proxy_pass http://192.168.7.6; }③浏览器访问效果 反向代理设置头部字段 ​ 如果启用缓存来自之前请求的头字段“If-Modified-Since”, “If-Unmodified-Since”, “If-None-Match”, “If-Match”, “Range”, 和 “If-Range” 将不会被代理服务器传递。 日志字段说明 #默认日志格式包含字段 $remote_addr #客户端地址 $remote_user #客户端用户名称 $request #请求的URI和HTTP协议 $http_referer #url跳转来源 $status #HTTP请求状态日志中默认包含#默认日志格式未包含字段 $upstream_status #upstream状态可在Nginx反向代理服务器上增加日志字段来查看 $http_host #请求地址即浏览器中你输入的地址可以通过proxy_set_header Host $http_host;来设置HTTP的Host字段日志中默认不包含 $host #同上 $upstream_addr #后台upstream的地址即真正提供服务的主机地址#Nginx其他相关变量 $proxy_host #跟客户端请求的Host不同这里是配置文件中upstream代理的Host名称Nginx日志中显示客户端IP为真实IP地址 ①默认情况下Nginx代理服务器会将客户端IP修改为自己的IP地址 ②在Nginx代理服务器中添加X-Real-IP字段记录原remote_addr地址 prwxy_set_header X-Real-IP $remote_addr;③在Nginx服务器的日志格式中添加显示X-Real-IP字段 $http_x_real_ip #后端通过X-REAL-IP或者HTTP_X_REAL_IP变量获取④验证Nginx服务器记录客户端信息确实变为了客户端真实IP地址 Nginx日志中显示Host为真实请求Host ①默认情况下Nginx代理服务器会将Host修改为代理配置中upstream的名称 ②在Nginx代理服务器中修改代理Host字段为原Host proxy_set_header Host $host; ③在Nginx服务器的日志格式中添加显示Host字段 KaTeX parse error: Expected EOF, got # at position 14: http_host #̲注意host效果也是一样的 ④验证Nginx服务器日志记录Host信息 Nginx日志中显示客户端请求经过的路径 #注意想要实现本实验需要增加二级Nginx反向代理 ①在一级Nginx代理服务器中向X-Forwarded-For增加客户端IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ②在二级Nginx代理服务器中向X-Forwarded-For增加一级Nginx代理服务器IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ③在Nginx服务器的日志格式中添加显示X-Forwarded-For字段 $http_x_forwarded_for #默认是已添加的 ④验证验证Nginx服务器日志记录X-Forwarded-For信息 正向代理 正向代理概念 1、HTTP/HTTPS正向代理的分类 ①按客户端有无感知的分类 普通代理在客户端需要在浏览器中或者系统环境变量手动设置代理的地址和端口。如squid在客户端指定squid服务器IP和端口3128。 透明代理客户端不需要做任何代理设置“代理”这个角色对于客户端是透明的。如企业网络链路中的Web Gateway设备。 ②按代理是否解密HTTPS的分类 隧道代理 也就是透传代理。代理服务器只是在TCP协议上透传HTTPS流量对于其代理的流量的具体内容不解密不感知。客户端和其访问的目的服务器做直接TLS/SSL交互。本文中讨论的NGINX代理方式属于这种模式。 中间人(MITM, Man-in-the-Middle)代理代理服务器解密HTTPS流量对客户端利用自签名证书完成TLS/SSL握手对目的服务器端完成正常TLS交互。在客户端-代理-服务器的链路中建立两段TLS/SSL会话。如Charles简单原理描述可以参考文章。 #注意这种情况客户端在TLS握手阶段实际上是拿到的代理服务器自己的自签名证书证书链的验证默认不成功需要在客户端信任代理自签证书的Root CA证书。所以过程中是客户端有感的。如果要做成无感的透明代理需要向客户端推送自建的Root CA证书在企业内部环境下是可实现的。 2、为什么正向代理处理HTTPS流量需要特殊处理 作为反向代理时代理服务器通常终结 (terminate) HTTPS加密流量再转发给后端实例。HTTPS流量的加解密和认证过程发生在客户端和反向代理服务器之间。 而作为正向代理在处理客户端发过来的流量时HTTP加密封装在了TLS/SSL中代理服务器无法看到客户端请求URL中想要访问的域名如下图。所以代理HTTPS流量相比于HTTP需要做一些特殊处理。 3、NGINX的解决方案 根据前文中的分类方式NGINX解决HTTPS代理的方式都属于透传(隧道)模式即不解密不感知上层流量。具体的方式有如下7层和4层的两类解决方案。 Nginx七层正向代理 ​ 默认Nginx只能实现http的正向代理不能实现https的正向代理。本地可实现Nginx正向代理可是在阿里云ECS上只能代理国内网站不能代理国外网站。 1、历史背景 早在1998年也就是TLS还没有正式诞生的SSL时代主导SSL协议的Netscape公司就提出了关于利用web代理来tunneling SSL流量的INTERNET-DRAFT。其核心思想就是利用HTTP CONNECT请求在客户端和代理之间建立一个HTTP CONNECT Tunnel在CONNECT请求中需要指定客户端需要访问的目的主机和端口。Draft中的原图如下 2、Nginx添加ngx_http_proxy_connect_module模块 ①NGINX ngx_http_proxy_connect_module模块说明 NGINX作为反向代理服务器官方一直没有支持HTTP CONNECT方法。但是基于NGINX的模块化、可扩展性好的特性阿里的chobits提供了ngx_http_proxy_connect_module模块来支持HTTP CONNECT方法从而让NGINX可以扩展为正向代理。 ②下载ngx_http_proxy_connect_module模块 [rootkuang ~]# git clone https://github.com/chobits/ngx_http_proxy_connect_module.git ③根据Nginx版本号选择补丁的版本 #注意Github中有模块使用说明 [rootkuang nginx-1.14.2]# patch -p1 /root/ngx_http_proxy_connect_module/patch/proxy_connect_rewrite_1014.patch ④编译安装Nginx [rootkuang nginx-1.14.2]# yum -y install zlib zlib-devel pcre pcre-devel openssl openssl-devel [rootkuang nginx-1.14.2]# ./configure --add-module/root/ngx_http_proxy_connect_module/ [rootkuang nginx-1.14.2]# make -j 4 make install 3、Nginx正向代理配置 ①添加Nginx支持正向代理配置 [rootkuang ~]# vim /usr/local/nginx/conf/nginx.conf server {listen 80;server_name localhost;resolver 8.8.8.8;resolver_timeout 30s;set $proxy_remote_address ;set $proxy_local_address ;proxy_connect;proxy_connect_connect_timeout 10s;proxy_connect_read_timeout 150;proxy_connect_send_timeout 10s;proxy_connect_send_lowat 0;proxy_connect_address $proxy_remote_address;proxy_connect_bind $proxy_local_address;access_log logs/proxy.access.log;location / {proxy_pass http://$http_host;proxy_set_header Host $host;}error_page 500 502 503 504 /50x.html;location /50x.html {root html;}}②正向代理配置说明 端口只需任意指定一个通过这一个端口可以去代理80和443端口 协议类型直接指定http也不像网上教程说的那样要使用 s c h e m e 使用 scheme使用 scheme使用scheme只是说用户如果使用的http协议那么正向代理去访问服务的时候也继承并使用http协议如果是https那么就继承https但是不影响正向代理帮你实现http到https的跳转 ③开启路由功能 [rootkuang ~]# echo 1 /proc/sys/net/ipv4/ip_forward 4、Linux上使用七层正向代理 7层需要通过HTTP CONNECT来建立隧道属于客户端有感知的普通代理方式需要在客户端手动配置HTTP(S)代理服务器IP和端口配置之后客户端就知道使用connect方法跟Nginx正向代理服务器建立隧道连接。在客户端用curl 加-x参数访问如下 ​ 从上面-v参数打印出的细节可以看到客户端先往代理服务器39.105.196.164建立了HTTP CONNECT隧道代理回复HTTP/1.1 200 Connection Established后就开始交互TLS/SSL握手和流量了。 5、Windows客户端配置正向代理 ①指定Nginx正向代理服务器上监听的端口即可 ②验证客户端使用正向代理 此时已经可以随意访问强制跳转HTTPS类的网站了 Nginx四层正向代理 1、Nginx四层正向代理的问题 ​ 用NGINX stream在TCP层面上代理HTTPS流量肯定会遇到本文一开始提到的那个问题代理服务器无法获取客户端想要访问的目的域名。因为在TCP的层面获取的信息仅限于IP和端口层面没有任何机会拿到域名信息。要拿到目的域名必须要有拆上层报文获取域名信息的能力所以NGINX stream的方式不是完全严格意义上的4层代理还是要略微借助些上层能力。那就要借助到ngx_stream_ssl_preread_module模块。 ​ 要在不解密的情况下拿到HTTPS流量访问的域名只有利用TLS/SSL握手的第一个Client Hello报文中的扩展地址SNI (Server Name Indication)来获取。NGINX官方从1.11.5版本开始支持利用ngx_stream_ssl_preread_module模块来获得这个能力模块主要用于获取Client Hello报文中的SNI和ALPN信息。对于4层正向代理来说从Client Hello报文中提取SNI的能力是至关重要的否则NGINX stream的解决方案无法成立。同时这也带来了一个限制要求所有客户端都需要在TLS/SSL握手中带上SNI字段否则NGINX stream代理完全没办法知道客户端需要访问的目的域名。 2、Nginx四层代理环境搭建 ①编译安装Nginx [rootkuang-75 nginx-1.15.6]# ./configure \ --userwww \ --groupwww \ --prefix/usr/local/nginx \ --with-http_ssl_module \ --with-http_stub_status_module \ --with-http_realip_module \ --with-threads \ --with-stream \ --with-stream_ssl_preread_module \ --with-stream_ssl_module[rootkuang-75 nginx-1.15.6]# make -j 4 make install ②配置Nginx支持四层正向代理 [rootkuang-75 ~]# vim /usr/local/nginx/conf/nginx.conf stream {resolver 114.114.114.114;server {listen 443;ssl_preread on;proxy_connect_timeout 5s;proxy_pass $ssl_preread_server_name:$server_port;} } #注意对于4层正向代理NGINX对上层流量基本上是透传也不需要HTTP CONNECT来建立隧道。适合于透明代理的模式比如将访问的域名利用DNS解定向到代理服务器。我们可以通过在客户端绑定/etc/hosts来模拟。3、使用四层正向代理服务器 ①绑定正向代理服务器 #注意需要访问的网站都需要一个一个绑定而不是直接配置正向代理服务器 [rootkuang-76 ~]# vim /etc/hosts 192.168.7.5 www.baidu.com ②通过正向代理访问百度 [rootkuang-76 ~]# curl https://www.baidu.com -svo /dev/null 4、常见问题 ①客户端手动设置代理导致访问不成功 4层正向代理是透传上层HTTPS流量不需要HTTP CONNECT来建立隧道也就是说不需要客户端设置HTTP(S)代理。如果我们在客户端手动设置HTTP(s)代理是否能访问成功呢? 我们可以用curl -x来设置代理为这个正向服务器访问测试看看结果 ​ 可以看到客户端试图于正向NGINX前建立HTTP CONNECT tunnel但是由于NGINX是透传所以把CONNECT请求直接转发给了目的服务器。目的服务器不接受CONNECT方法所以最终出现Proxy CONNECT aborted导致访问不成功。 ②客户端没有带SNI导致访问不成功 上文提到用NGINX stream做正向代理的关键因素之一是利用ngx_stream_ssl_preread_module提取出Client Hello中的SNI字段。如果客户端客户端不携带SNI字段会造成代理服务器无法获知目的域名的情况导致访问不成功。 在透明代理模式下用手动绑定hosts的方式模拟我们可以在客户端用openssl来模拟 [rootkuang-76 ~]# openssl s_client -connect www.baidu.com:443 -msg #注意openssl s_client默认不带SNI可以看到上面的请求在TLS/SSL握手阶段发出Client Hello后就结束了。因为代理服务器不知道要把Client Hello往哪个目的域名转发。 如果用openssl带servername参数来指定SNI则可以正常访问成功命令如下 [rootkuang-76 ~]# openssl s_client -connect www.baidu.com:443 -servername www.baidu.com 5、拓展在Windows上使用Nginx四层正向代理 ①添加域名映射 C:\Windows\System32\drivers\etc\hosts 192.168.7.5 www.baidu.com ②Windows访问百度抓包情况如下 #注意火狐浏览器发送Client Hello都会带上SNI字段所以能成功访问 客户端把192.168.7.5当成百度进行访问 ③拓展抓包查看SNI字段 接着正向代理服务器将这个包代理给了百度 Keepalived实现高可用 主备服务器安装Nginx和Keepalived 1、安装Nginx #①安装所需的依赖软件 [rootkuang-76 ~]# yum -y install gcc-c zlib zlib-devel openssl openssl-devel pcre pcre-devel#②安装Nginx [rootkuang-76 ~]# tar -zxvf nginx-1.14.0.tar.gz #上传并解压Nginx安装包 [rootkuang-76 ~]# cd nginx-1.14.0 [rootkuang-76 ~]# ./configure \ --prefix/usr/local/nginx \ --pid-path/var/run/nginx/nginx.pid \ --lock-path/var/lock/nginx.lock \ --error-log-path/var/log/nginx/error.log \ --http-log-path/var/log/nginx/access.log \ --with-http_gzip_static_module \ --http-client-body-temp-path/var/temp/nginx/client \ --http-proxy-temp-path/var/temp/nginx/proxy \ --http-fastcgi-temp-path/var/temp/nginx/fastcgi \ --http-uwsgi-temp-path/var/temp/nginx/uwsgi \ --http-scgi-temp-path/var/temp/nginx/scgi [rootkuang-76 ~]# mkdir -p /var/temp/nginx #安装前创建所需目录 [rootkuang-76 ~]# make make install #编译安装Nginx#③启动Nginx [rootkuang-76 ~]# /usr/local/nginx/sbin/nginx2、安装和配置Keepalived #①安装Keepalived [rootkuang76 ~]# tar -xf keepalived-2.0.12.tar.gz #上传并安装Keepalived [rootkuang76 ~]# cd keepalived-2.0.12/ [rootkuang76 keepalived-2.0.12]# ./configure --prefix/usr/local/keepalived --sysconf/etc #然后系统出现以下警告 *** WARNING - this build will not support IPVS with IPv6. Please install libnl/libnl-3 dev libraries to support IPv6 with IPVS. [rootkuang76 keepalived-2.0.12]# yum -y install libnl libnl-devel [rootkuang76 keepalived-2.0.12]# ./configure --prefix/usr/local/keepalived --sysconf/etc [rootkuang76 ~]# make make install#②Keepalived初始化配置 [rootkuang76 ~]# ln -s /usr/local/keepalived/sbin/keepalived /sbin/ #创建命令快捷键 [rootkuang76 ~]# cp /root/keepalived-2.0.12/keepalived/etc/init.d/keepalived.rh.init /etc/init.d/keepalived #安装启动控制脚本 [rootkuang76 ~]# cp /root/keepalived-2.0.12/keepalived/etc/sysconfig/keepalived /etc/sysconfig/ #新版本Keepalived安装后自动会安装该配置文件此步骤可省略 [rootkuang76 ~]# cp /root/keepalived-2.0.12/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/ #新版本Keepalived安装后自动会安装该配置文件此步骤可省略#③添加Keepalived到系统服务此步骤省略会出问题 [rootkuang76 ~]# chkconfig --add keepalived #添加到系统服务 [rootkuang76 ~]# systemctl enable keepalived.service [rootkuang76 ~]# chkconfig keepalived on #检测是否添加成功#④步骤三添加Keepalived到系统服务的回退方案此步骤同步骤三省略 [rootkuang76 ~]# chkconfig --del keepalived [rootkuang76 ~]# rm -rf /lib/systemd/system/keepalived.service [rootkuang76 ~]# rm -rf /etc/init.d/keepalived #⑤启动Keepalived [rootkuang76 ~]# /etc/init.d/keepalived start配置主备Nginx心跳检测 1、简单Keepalived实现 ①主Nginx的Keepalived配置 [rootkuang73 ~]# vim /etc/keepalived/keepalived.conf global_defs {router_id kuang73 #设置Nginx Master的id在一个网络应该是唯一的 } vrrp_instance VI_1 {state MASTER #指定Keepalived的角色为主interface ens33 #当前进行Vrrp通讯的网络接口卡virtual_router_id 51 #虚拟路由组编号主从要一致priority 100 #优先级数值越大获取处理请求的优先级越高advert_int 1 #检查间隔默认为1sVrrp组播周期秒数authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.7.100} }[rootkuang-73 ~]# /etc/init.d/keepalived restart #重启Keepalived ②备Nginx的Keepalived配置 [rootkuang-76 ~]# vim /etc/keepalived/keepalived.conf global_defs {router_id kuang76 } vrrp_instance VI_1 {state BACKUPinterface ens33virtual_router_id 51priority 50advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.7.100} }[rootkuang-76 ~]# /etc/init.d/keepalived restart #重启Keepalived ③正常访问虚拟IP验证 [rootkuang73 ~]# netstat -antup | grep 80 #通过是否新增连接判断访问的Nginx服务器 ④主Nginx的Keepalived挂掉时访问虚拟IP [rootkuang73 ~]# pkill keepalived 注意当我们配置了Keepalived当主Keepalived的宕机了。会自动更改路由到Backup的Keepalived但是如果Nginx挂掉的话Keepalived就会找不到Nginx服务这样还是会造成Nginx服务不可用访问异常。那么我们就可以在Keepalived中添加心跳script用来检测Nginx心跳如果检测不到Nginx服务就关闭掉Keepalived的进程。这样从机的Keepalive服务就可以被调用。 2、Nginx心跳检测 ①Nginx的心跳检测脚本 [rootkuang73 ~]# vim /usr/local/nginx/sbin/check_nginx_alive.sh #!/bin/sh PATH/bin:/sbin:/usr/bin:/usr/sbin Aps -C nginx --no-header |wc -l if [ $A -eq 0 ]thenecho nginx server is diedkillall keepalived fi[rootkuang73 ~]# chmod 755 /usr/local/nginx/sbin/check_nginx_alive.sh ②Keepalived配置文件中应用心跳检测脚本 [rootkuang73 ~]# vim /etc/keepalived/keepalived.conf vrrp_script check_nginx_alive {script /usr/local/nginx/sbin/check_nginx_alive.shinterval 3 #检测脚本执行的间隔单位是秒weight -10 } global_defs {router_id kuang73 } vrrp_instance VI_1 {state MASTERinterface ens33virtual_router_id 51priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.7.100}track_script {check_nginx_alive #调用检测脚本} }③测试Nginx高可用 [rootkuang73 ~]# pkill nginx #主Ningx宕掉后客户端访问跳到备Nginx 注意上面是主机kuang-73的配置可以看到一共新添加了两个地方主要是添加了一个Shell脚本用于检测Nginx是否存活然后再在Keepalived的配置文件中添加这个这个检测心跳的文件。这个是主机的配置那么从机也需要做相应的修改。那么不管是Keepalived宕机还是Nginx宕机都会切换到可以热备的机器中去这样就达到了Nginx的可高用。 Keepalived脑裂检测 #检测思路正常情况下Keepalived的VIP地址是在主节点上的如果在从节点发现了VIP就设置报警信息 1、Keepalived脑裂检测脚本 [rootkuang-76 ~]# vim check_split_brain.sh #!/bin/bash # 检查脑裂的脚本在备节点上进行部署 LB01_VIP192.168.7.100 LB01_IP192.168.7.3 LB02_IP192.168.7.6 while true doping -c 2 -W 3 $LB01_VIP /dev/nullif [ $? -eq 0 -a ip add|grep $LB01_VIP|wc -l -eq 1 ];thenecho ha is brain.elseecho ha is okfisleep 5 done2、正常执行结果如下 [rootkuang-76 ~]# bash check_split_brain.sh ha is ok ha is ok 3、当发现异常时候的执行结果 [rootkuang-76 ~]# bash check_split_brain.sh ha is ok ha is ok ha is brain. ha is brain. Keepalived拓展 1、配置Keepalived的日志 ①修改Keepalived配置文件 [rootkuang73 ~]# vim /etc/sysconfig/keepalived #修改如下配置内容 KEEPALIVED_OPTIONS“-D -d -S 0” ②Keepalived配置说明 “-D” 就是输出日志的选项 这里的“-S 0”表示local0.* 具体的还需要看一下/etc/syslog.conf文件 ③修改Syslog配置文件 [rootkuang73 ~]# vim /etc/rsyslog.conf #添加以下代码 local0.* /var/log/keepalived.log ④重新启动Keepalived和Syslog服务 [rootkuang73 ~]# systemctl restart rsyslog [rootkuang73 ~]# /etc/ini.d/keepalived restart ⑤然后就可以查看Keepalived的日志了 [rootkuang73 ~]# tail -f /var/log/keepalived.log 2、进程控制软件安装包 [rootkuang-76 ~]# rpm -qf which killall psmisc-22.20-15.el7.x86_64 [rootkuang-76 ~]# rpm -qf which pkill procps-ng-3.3.10-17.el7.x86_64 3、产生脑裂情况 #在主备Nginx的/etc/keepalived/keepalived.conf最后添加如下 #实验不成功未实现脑裂现象 virtual_server 192.168.64.100 80 {delay_loop 6lb_algo rrlb_kind NATpersistence_timeout 50protocol TCP real_server 192.168.64.128 80 {weight 1TCP_CHECK{connect_timeout 3nb_get_retry 3delay_before_retry 3connect_port 80}} }SessionSticky实现会话保持 ​ 此模块是让Nginx基于Cookie实现的会话保持通过在Cookie中写上route路径客户端再次请求时需要带上该Cookie就通过route字段区分要转发的upstream。 ​ 会话粘滞解决了ip_hash两个问题一个是ip_hash只能通过ip来固定负载负载没那么均衡而且经过同一网关的私网网段用户都被固定到一台后端服务器上另一个是当Nginx不在最前端并且有多台Nginx时七层负载均衡前有四层负载均衡的情况Nginx之间就没法保持会话统一了。 Nginx实现SessionSticky调度 ①下载第三方SessionSticky模块 [rootkuang-75 ~]# cd /usr/local/src/ [rootkuang-75 src]# git clone https://github.com/devsbb/nginx-sticky-module-ng.git #要选择较新的版本老版本在编译时很多都会出错 ②编译安装Nginx支持SessionSticky [rootkuang-75 nginx-1.14.2]# ./configure --with-http_perl_module --with-http_stub_status_module --add-module…/nginx-sticky-module #保留原来的参数 [rootkuang-75 nginx-1.14.2]# make -j 4 make install ③配置实用SessionSticky功能 [rootkuang-75 ~]# vim /usr/local/nginx/conf/nginx.conf #上下文为server location / {proxy_pass http://backend; } #上下文为http upstream backend {sticky;server 192.168.7.6;server 192.168.7.7; }SessionStiky实现原理 用户第一次的请求使用RR调度到一个upstream上Session Sticky 模块在upstream 返回响应后向客户的浏览器写入Cookie 默认名为route保存的内容是一个md5 码之后模块接收到客户浏览器的请求时就根据route来决定将请求转发到upstream中哪台服务器上如果发现客户Cookie中不带有route字段则按RR方式调度 缓存 缓存知识总结 1、浏览器的对不同字段的反应 不缓存no-store 需要重新验证no-cache、max-age0 缓存静态资源public、private、max-age≠0 2、代理服务器CDN节点对不同字段的反应 不缓存no-store、no-cache、max-age0、private 缓存静态资源public、max-age≠0 #注意浏览器和代理服务器CDN节点在对待cache超时完全不同cache超时后浏览器只是问一下if-modified-since而代理服务器CDN节点是要真实的200状态码的再请求一下。 3、默认情况下各类缓存控制字段的优先级 对缓存的过期与清除起作用的因素的优先级从高到低一次为 inactive配置项、源服务器设置的Expires、源服务器设置的Max-Age、proxy_cache_valid配置项。 由于腾讯云CDN配置proxy_ignore_headers max-age和proxy_ignore_headers “expires”则只收到proxy_cache_valid直接影响inactive配置时间待后续确定 #以下为腾讯云CDN平台策略 4、腾讯云CDN对Cache-Control字段默认策略 当用户请求您某一业务资源时源站对应的 HTTP Response Header 中存在 Cache-Control 字段此时默认平台策略如下 ①Cache-Control 字段为 Max-Age对该资源的缓存时间以配置的节点缓存过期时间为主不继承 Max-Age 指定时间。Nginx代理缓存中实现的方式为proxy_ignore_headers “max-age”CDN平台也会缓存任何max-age为任何的资源包括max-age0的资源 ②Cache-Control 字段为 no-cache 、 no-store 或 private此时 CDN 节点对此资源不做缓存。 ③无 Cache-Control 字段CDN 会默认添加Cache-Control:max-age 600头部。 5、腾讯云CDN状态码缓存策略 若返回非2XX状态码除404状态码默认缓存10秒其他状态码均默认为不缓存。若源站无法迅速解决非2XX状态码且不希望所有请求全部透传回源站可通过配置状态码缓存过期时间由 CDN 节点直接响应非2XX状态码减轻源站压力。 6、开启缓存后不再透传一些字段 如果启用缓存来自客户端请求的头字段“If-Modified-Since”, “If-Unmodified-Since”, “If-None-Match”, “If-Match”, “Range”, 和 “If-Range” 将不会被代理服务器传递。比如If-Modified-Since就不会代理过去了CDN回源只能是200的状态码没有304状态码。包括腾讯云CDN也是一样的不能缓存的不可能给客户透传304请求而是全部都要200请求。另外腾讯云CLB没有开启缓存所以都会透传客户端的304请求这一点可以证明CLB没有开启缓存。 另外可以使用proxy_set_header自定义回源的头字段。 7、当客户端询问if-modified-sinceCDN节点没有该资源回源时 ①能缓存返回304 ②不能缓存返回200 8、代理服务器CDN节点缓存资源超时的情况 代理服务器上的cache超过了源服务器打上的cache-control时间并不会主动的去再次请求源服务器而是在客户端发出请求后再去源服务器请求然后响应一个304但是X-cache字段打上EXPIRED客户端就知道这是在代理服务器上缓存过期了然后回源取到其本地给我响应的。 9、有缓存的校验过期机制图 各类缓存字段的优先级 1、由于expires是http/1.0版本max-age是http/1.1版本的 ①所以在浏览器一般用http/1.1上max-age覆盖expires ②而在Nginx因为回源默认是用http/1.0所以expires覆盖max-age 2、各字段的缓存优先级 ①以下是对Nginx代理有效 对缓存的过期与清除起作用的因素的优先级从高到低一次为 inactive配置项、源服务器设置的Expires、源服务器设置的Max-Age、proxy_cache_valid配置项 3、浏览器和代理服务器的不同 浏览器和代理服务器在对待cache超时有截然的不同cache超时浏览器只是问一下if-modified-since而代理服务器是要真实的200状态码的再请求一下。 客户端缓存操作 public新打开一个窗口 不会去访问服务器原页面回车不会去访问服务器取自缓存刷新浏览器重新请求服务器单击返回按钮页面取自缓存 private新打开一个窗口浏览器重新发送请求到服务器原页面回车第一次会去请求服务器以后均是来自于缓存刷新浏览器重新请求服务器单击返回按钮页面取自缓存no-cache/no-store打开新窗口、回车 、刷新、单击返回均会访问请求服务器;这里要说明的是no-cache 不是没有缓存只不过每次在向客户端浏览器提供响应数据时缓存都要向服务器评估缓存响应的有效性Cache-Control: no-store这个才是响应不被缓存的意思。 must-revalidation/proxy-revalidation打开新窗口浏览器重新发送请求到服务器原页面回车第一次请求服务器以后均是来自缓存页面刷新浏览器重新请求服务器单击返回按钮页面取自缓存max-agexxx刷新按钮重新发送请求到服务器其他的均是在访问页面XXX秒后一直来自缓存总结 打开新窗口 如果指定cache-control的值为private、no-cache、must-revalidate,那么打开新窗口访问时都会重新访问服务器。而如果指定了max-age值,那么在此值内的时间里就不会重新访问服务器,例如Cache-control: max-age5 表示当访问此网页后的5秒内不会去再次访问服务器.在地址栏回车 如果值为private或must-revalidate,则只有第一次访问时会访问服务器,以后就不再访问。如果值为no-cache,那么每次都会访问。如果值为max-age,则在过期之前不会重复访问。按后退按扭 如果值为private、must-revalidate、max-age,则不会重访问,而如果为no-cache,则每次都重复访问.按刷新按扭 无论为何值,都会重复访问.HTTP协议的Cache -Control指定请求和响应遵循的缓存机制 在请求消息或响应消息中设置 Cache-Control并不会影响另一个消息处理过程中的缓存处理过程。 请求时的缓存指令包括no-cache、no-store、max-age、 max-stale、min-fresh、only-if-cached等。 响应消息中的指令包括public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age。浏览器中关于Cache的3属性: Cache-Control: 设置相对过期时间, max-age指明以秒为单位的缓存时间. 若对静态资源只缓存一次, 可以设置max-age的值为315360000000 (一万年). Http协议的cache-control的常见取值及其组合释义: no-cache: 数据内容不能被缓存, 每次请求都重新访问服务器, 若有max-age, 则缓存期间不访问服务器. no-store: 不仅不能缓存, 连暂存也不可以(即: 临时文件夹中不能暂存该资源) private(默认): 只能在浏览器中缓存, 只有在第一次请求的时候才访问服务器, 若有max-age, 则缓存期间不访问服务器. public: 可以被任何缓存区缓存, 如: 浏览器、服务器、代理服务器等 max-age: 相对过期时间, 即以秒为单位的缓存时间. no-cache, private: 打开新窗口时候重新访问服务器, 若设置max-age, 则缓存期间不访问服务器. private, 正数的max-age: 后退时候不会访问服务器 no-cache, 正数的max-age: 后退时会访问服务器 点击刷新: 无论如何都会访问服务器.Expires: 设置以分钟为单位的绝对过期时间, 优先级比Cache-Control低, 同时设置Expires和Cache-Control则后者生效.Last-Modified: 该资源的最后修改时间, 在浏览器下一次请求资源时, 浏览器将先发送一个请求到服务器上, 并附上If-Unmodified-Since头来说明浏览器所缓存资源的最后修改时间, 如果服务器发现没有修改, 则直接返回304(Not Modified)回应信息给浏览器(内容很少), 如果服务器对比时间发现修改了, 则照常返回所请求的资源. ​ Last-Modified属性通常和Expires或Cache-Control属性配合使用因为即使浏览器设置缓存当用户点击”刷新”按钮时浏览器会忽略缓存继续向服务器发送请求这时Last-Modified将能够很好的减小回应开销。 基于proxy_cache的反向代理缓存 1、特别注意 开启反向代理缓存之后很多字段从客户端发过来就不能透传到源服务器了比如If-Modified-Since就不会代理过去了回源只能是200的状态码没有304状态码 连腾讯云CDN也是一样的不能缓存的不可能给客户透传304而是全部都要200请求腾讯云LB没有开启缓存所以很多都是透传304这一点可以证明CLB没有开启缓存 1、当客户端询问if-modified-since而proxy服务器上没有该资源回源时分两种情况 ①能缓存返回304 ②不能缓存返回200 #注意整个HIT缓存的关键点在三第一客户端请求的方式第一次直接请求第二次问是否改变第二Nginx此时是否有请求内容的缓存第三真实服务器端其实没那么多考虑的只管响应请求不过其有个关键的地方指挥某些资源需不需要在客户端缓存需要缓存的客户端才会在第二次询问资源是否改变否则每次都是直接请求 #注意反向代理缓存的实现跟指令的顺序没关系 1、基于proxy_cache的缓存此验证成功 ①配置Nginx使用proxy_cache缓存 [rootkuang-74 ~]# vim /usr/local/nginx/conf/nginx.conf proxy_cache_path /usr/local/nginx/cache levels1:2 keys_zonecache_one:500m inactive1d max_size30g; #此配置在http上下文中并且要在include导入命令前 add_header X-Cache $upstream_cache_status; #添加之后会显示是否命中只有在以下配置中开启了代理缓存才会显示该字段 location / { proxy_cache cache_one; proxy_cache_key h o s t host hosturi i s a r g s is_args isa​rgsargs; #这个在中途加进去会出问题因为原先可能不是按照这个索引格式来写到缓存里的 proxy_cache_valid 200 304 302 24h; #这里有没有任何状态码都没任何影响 proxy_pass http://192.168.7.3/; } 腾讯云CDN策略若返回非2XX状态码除404状态码默认缓存10秒其他状态码均默认为不缓存。若源站无法迅速解决非2XX状态码且不希望所有请求全部透传回源站可通过配置状态码缓存过期时间由 CDN 节点直接响应非2XX状态码减轻源站压力。 ②参数说明 levels1:2 表示缓存目录的第一级目录是1个字符第二级目录是2个字符 The levels parameter defines hierarchy levels of a cache: from 1 to 3, each level accepts values 1 or 2.最多支持三级字符只能是1或2 inactive1d 表示这个zone中的缓存文件如果在1天内都没有被访问那么文件会被cache manager进程删除掉 max_size30g 表示这个zone的硬盘容量为30GB proxy_cache_valid 200 304 302 24h 设置状态码为200、304和302的响应可以进行缓存并且缓存时间为24小时其目的是为不同的HTTP返回状态码的资源设置不同的缓存时长。 ③缓存访问说明 #前面状态码跟客户端的关联最大200表示客户端第一次访问某页面后面变为304过程是客户端问服务器这个资源有改变没然后服务器回没有变化不管是Nginx回还是后端服务器回 #HIT才是和缓存服务器有紧密联系命中了某索引的缓存就是HIT没有命中就是MISS #注意下图不是第一次访问因为不可能出现第一次访问就HIT的情况 ④客户端的no-cache访问按CtrlF5 #no-cache最准确的解释客户端表示我这次访问和cache没关你直接回我内容就行了 #有cache时是因为客户端询问服务器某资源是否有变更而服务器回复的cache相关描述信息包括上次修改时间和过期时间 客户端的no-cache访问跟缓存服务器不是一回事前者指的是不使用本地的cache问服务器某文件是否改变而是直接请求资源。Nginx有该资源自然就直接返回响应你了而不会去后端请求真实服务器。 #此时的真实服务器已经无关紧要了关掉真实服务器的服务Nginx依然能提供服务只要Nginx上的缓存文件没有删除 ⑤删除Nginx上的缓存 [rootkuang-76 ~]# rm -rf /usr/local/nginx/cache/ 此时直接就报错了因为找不到相应资源后端服务器又关闭了 ⑥启动后端真实服务器 [rootkuang-77 ~]# systemctl start nginx 再刷新两次页面则分别是200的MISS和304的HIT ⑦测试缓存内容即使更新能力 #以下在真实服务器上更改某页面内容 [rootkuang-77 html]# echo haha /usr/share/nginx/html/index.html 使用F5刷新和CtrlF5更新同样访问的是Nginx缓存中的旧内容 proxy_cache_path /var/www/cache levels1:2 keys_zonemy-cache:8m max_size1000m inactive600m; proxy_temp_path /var/www/cache/tmp; real_ip_header X-Forwarded-For;server {listen 80;server_name _;server_tokens off;location / {proxy_pass http://127.0.0.1:8080/;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_cache my-cache;proxy_cache_valid 3s;proxy_no_cache $cookie_PHPSESSID;proxy_cache_bypass $cookie_PHPSESSID;proxy_cache_key $scheme$host$request_uri;add_header X-Cache $upstream_cache_status;} }清除反向代理缓存 1、Nginx缓存配置及nginx ngx_cache_purge模块的使用 ①ngx_cache_purge模块的作用 用于清除指定url的缓存 ②模块下载地址 http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz ③编译安装Nginx [rootkuang-77 ~]# ./configure --prefix/app/nginx --with-http_stub_status_module --with-http_ssl_module --add-module../ngx_cache_purge-2.3 [rootkuang-77 ~]# make [rootkuang-77 ~]# make install④Nginx配置如下 proxy_cache_path /app/proxy_cache_dir levels1:2 keys_zonecache1:200m inactive1d max_size10g; server {listen 80;server_name localhost;location / {root html;index index.html index.htm;}location ~ /purge(/.*) {allow 127.0.0.1;allow 192.168.116.0/24deny all;proxy_cache_purge cache1 $host$1$is_args$args;}location ~ \.(gif|jpg|jpeg|png|bmp|ico)$ {proxy_set_header Host $host;proxy_set_header X-Forwarded-For $remote_addr;proxy_pass http://127.0.0.1:8080;proxy_cache cache1; #设置资源缓存的zoneproxy_cache_key $host$uri$is_args$args; proxy_cache_valid 200 304 12h; #对不同的HTTP状态码设置不同的缓存时间expires 7d; #缓存时间}error_page 500 502 503 504 /50x.html;location /50x.html {root html;}⑤启动Nginx查看进程发现新增了两个进程 2、验证缓存及手动清除指定URL缓存功能 如果在缓存时间之类需要更新被缓存的静态文件怎么办呢这时候就需要手动来清除缓存了 ①访问一张图片 ②更换图片内容然后清除缓存后再访问 http://192.168.116.130/purge/test/n.jpg #访问此URL可以清除缓存 ③再次访问原来的URL图片已更新
http://www.dnsts.com.cn/news/132572.html

相关文章:

  • 网站建设方法营销型网站建设818gx
  • 如何做自己的淘宝优惠券网站h5可视化开发工具
  • 公司网站设计解决方案长沙网站建设论坛
  • 网站开发中网页之间的链接形式凡科网址
  • 杏坛网站制作查询网站有没有备案
  • 商城网站建设注意什么php企业网站开发源码
  • 台州汇客网站建设网络技术专业
  • 网站框架怎么搭建wordpress运行太慢
  • 阿盟住房和城乡建设局门户网站微站官网
  • 网络app开发网站建设免费h5旅游网站模板
  • asp网站上传后台在哪网页美工设计photoshop 规划教材
  • iis7 部署静态网站做知乎网站的图片
  • 让人做网站需要注意哪些问题网站系统怎么做
  • wordpress多站点无法发布文章wordpress cat_name
  • 湖北专业网站建设公司正规的徐州网站建设
  • 网站地图在首页做链接深圳网络推广引流
  • 优化企业网站sem培训班学费哪个好
  • 汕头模板开发建站专精特新中小企业
  • 英文外贸网站推广引流方案
  • 做校园网站的公司深圳大鹏新区葵涌街道
  • 企业网站网络推广厦门网站建设外包
  • 南海区建设网站洛阳网站公司哪家好
  • 网站设计和内容上的不足和建议万网搭建淘宝客网站
  • 网站建设网络推广首选公司百度知道电脑版网页入口
  • 员工做违法网站企业文化
  • 磁县网站建设图片动画制作
  • 建立第一个网站做ppt的网站叫什么软件
  • 邯郸房产网站国外html5网站
  • wordpress 修改建站时间centos怎么装WordPress
  • 国内知名网站青岛最新通知