关于nginx-module:Nginx入门笔记

目录什么是反向代理 正向代理反向代理Nginx过程模型 Worker抢占机制Nginx事件处理配置文件 配置构造次要配置常用命令日志宰割 定时工作宰割日志配置一个动态文件应用GZIP压缩Location匹配规定跨域的形式 同源策略跨域资源共享 反向代理两者比拟配置防盗链负载平衡 负载平衡算法负载平衡实例长连贯优化nginx缓存 管制浏览器缓存反向代理缓存配置SSL证书 证书装置(腾讯云)HTTP 主动跳转 HTTPS 的平安配置(可选)参考NginxNginx是高性能的http和反向代理web服务器,同时也提供IMAP/POP3/SMTP服务 次要性能有 反向代理通过配置文件实现集群和负载平衡动态资源虚拟化什么是反向代理正向代理正向代理→代理客户端:客户端无奈间接从将申请送达指标服务器,能够通过可能申请到指标服务器的代理服务器转发申请到指标服务器,并将从指标服务器获取的内容返回给客户端,这就是正向代理。 正向代理的典型用处是为在防火墙内的局域网客户端提供拜访Internet的路径,就比如说咱们再居家办公的时候须要通过vpn拜访内网环境,vpn起到的作用就是正向代理。 正向代理能够应用缓存个性缩小网络使用率。 反向代理反向代理→代理服务端:客户端不晓得服务器的理论地址,通过拜访代理服务器由其将申请转发到相应的服务器上。 反向代理的作用 爱护和隐匿原始服务器 反向代理能够不让客户端间接拜访到原始资源服务器 负载平衡 反向代理服务器能够将多个客户端申请通过负载平衡算法将这些申请散发到不同的服务器上以加重单个服务器的压力,当然,反向代理服务器也能够有多个组成代理服务器集群。 缓存 反向代理服务器能够像正向代理服务器那样领有缓存的作用,能够将原始资源服务器返回的动态资源等数据进行缓存,进步申请效率,这也是CDN技术的外围。 路由 能够通过域名中的路由等信息将申请进行散发到不同的服务器上,这点与负载平衡有点像,然而负载平衡次要目标是为了均衡各个服务器的压力,路由是将需要不同的申请散发到不同的服务器。 Nginx过程模型nginx中可分为主过程(master)和工作过程(worker),master过程次要是用来治理woker进行,工作过程能够有多个,然而默认只有1个。 [root@VM-24-13-centos nginx-1.22.0]# ps aux|grep nginxroot 2868 0.0 0.0 22292 1456 ? Ss Jul25 0:00 nginx: master process ./nginxnobody 18991 0.0 0.0 24376 1768 ? S 20:24 0:00 nginx: worker process能够通过worker_processes配置来指定工作进行的数量 #user nobody;worker_processes 2;[root@VM-24-13-centos nginx-1.22.0]# ps aux|grep nginxroot 2868 0.0 0.0 22292 1456 ? Ss Jul25 0:00 nginx: master process ./nginxnobody 23812 0.0 0.0 24376 1492 ? S 20:49 0:00 nginx: worker processnobody 23813 0.0 0.0 24376 1492 ? S 20:49 0:00 nginx: worker processmaster过程次要是发送以下命令给worker过程使其进行、重启等 ...

August 21, 2022 · 7 min · jiezi

关于nginx-module:ngtemplate-使用过程中默认参数不能按照期望工作的问题单步调试

<article class=“article fmt article-content”><p>本文波及到的代码,位于这个 Github 仓库:https://github.com/wangzixi-d…</p><h1>问题形容</h1><p>我应用如下代码进行 ng-template 模板的参数传递:</p><pre><code class=“html”><ng-template #inputTemplateWithContent let-param let-name=“name”> <div>参数1: {{param}}</div> <div>参数2: {{name}}</div></ng-template></code></pre><p><span class=“img-wrap”></span></p><p>这里对于上图的代码地位 2,我用关键字 <code>let-</code>,定义了一个仅模板里可能拜访的局部变量 <code>name</code>,其数据源来自传入该模板的上下文对象 context 的同名属性 <code>name</code>。</p><p>而对于代码地位1 处的 param,我没有指定其映射到上下文对象中的属性名,因而我冀望它应用上下文对象里的默认<code>同名</code>属性,因而最初第一个 div 元素里应该显示属性 <code>param</code> 的值:<code>默认值</code>。</p><p><span class=“img-wrap”></span></p><p>然而理论的执行后果却是,第一个 div 元素显示的值为空:</p><p><span class=“img-wrap”></span></p><h1>问题剖析</h1><p>这个问题的本源是如何将上下文对象里的某个属性作为<code>默认</code>属性,传递给模板。</p><p>在 Angular 官网里找到了这样的对于默认值的文档:</p><p><span class=“img-wrap”></span></p><p>上下文对象的精确含意:</p><blockquote>附加到 EmbeddedViewRef 的上下文对象。 这应该是一个 JSON 对象,该对象的键将可用于本地模板 let 申明的绑定。 在上下文对象中应用键 $implicit 会将其值设置为默认值。</blockquote><p>文档提到,默认属性应该用 <code>$implicit</code> 来标识。</p><p>咱们在源代码里依据关键字 <code>$implicit</code> 搜寻,找到了常量 <code>IMPLICIT_REFERENCE</code>,再依据该常量搜寻,就能找到 Angular 框架源代码解析 <code>$implicit</code> 之处:</p><p><span class=“img-wrap”></span></p><p>这里咱们就能找到 Angular 解析 template variable 的逻辑:</p><p><span class=“img-wrap”></span></p><p><code>InterpolationConfig</code> 的 start 和 end 符号:<code>{{</code>, <code>}}</code></p><p><span class=“img-wrap”></span></p><h1>解决方案</h1><p>将下图图例1地位处的 <code>param</code> 批改成 <code>$implicit</code> 即可:</p><p><span class=“img-wrap”></span></p><h1>总结</h1><p>从上面这个调用栈里还能察看到模板里蕴含的 HTML 元素,在内存中对应的 DOM 节点:</p><p><span class=“img-wrap”></span></p><p>ng-template, ng-container 和 br,别离对应 HTML 文件里上面三个元素:</p><p><span class=“img-wrap”></span></p></article> ...

March 5, 2022 · 1 min · jiezi

Nginx-层面配置基础用户验证

原文链接: 何晓东 博客 应用场景:大概是在内部网站需要外部用户访问到,同时不能给访问者网站账号权限,所以在 nginx 层面进行限制。例如外包项目,内部员工有账号进行文档的操作,外包员工没有内部账号,但需要让他们能够看到文档,所以在 nginx 层面设置用户验证是最佳最简单的选择,多数情况下雇主方不会给外包员工开一个基础访问权限的账号。在 nginx 层面进行进行用户认证的前置条件:需要有对应的密码创建程序,如apache2-utils(Debian,Ubuntu)或 httpd-tools(RHEL / CentOS / Oracle Linux),不同操作系统是不同的软件。 创建账户密码文件使用命令 sudo htpasswd -c /etc/apache2/.htpasswd user1 创建第一个账户,然后按下 Enter 键输入密码,同样的命令,没有 -c 参数创建第二个用户及密码, -c 参数为创建文件,在第二次及以后的命令中不需要再次创建文件。确认一下文件及账号信息生成成功,使用命令 cat /etc/apache2/.htpasswd 查看文件内容,应该为账号及加密后的密码,如:user1:$apr1$/woC1jnP$KAh0SsVn5qeSMjTtn0E9Q0 等。配置 nginx 进行 http 基础用户验证使用 auth_basic 指令指定设置受保护区域的名称,此名称会显示在账号密码弹窗上,使用 auth_basic_user_file 指令设置带有账户密码信息的 .htpasswd 路径。例如配置: location /api { auth_basic "Administrator's Area"; auth_basic_user_file /etc/apache2/.htpasswd; }此外,如果某个区块不想继承整个认证体系,可以在区块内设置 auth_basic off,即用户认证关闭状态。例如配置: server { ... auth_basic "Administrator's Area"; auth_basic_user_file conf/htpasswd; location /public/ { auth_basic off; }}通过 ip 地址将认证与访问限制相结合HTTP基本认证可以通过IP地址有效地与访问限制相结合。您可以实现至少两种方案: ...

July 1, 2019 · 1 min · jiezi

Nginx-配置进行AB测试

原文链接: 何晓东 博客 应用场景:电商活动,准备了A B两套风格的促销页面,想让一半人看到 A 页面,另一半人看到 B 页面,这样来测试两种的转化成交效果。其他在大版本升级测试的时候,防止有bug,可以将小规模流量分发到最新代码的服务器。前置条件:nginx 需要安装 ngx_http_split_clients_module 模块,借助这个模块的 split_clients 指令完成分流,示例配置如: http { split_clients "${remote_addr}AAA" $variant { 0.5% .one; 2.0% .two; * ""; } server { location / { index index${variant}.html; } }以上的配置会将原始 ip 地址加上 AAA 使用 MurmurHash2 算法进行 hash,在此示例中,如果哈希值从 0 到 21474835(0.5%)对应于变量 $variant 的 ".one" 值, 哈希值从 21474836 到 107374180(2%)对应于值 ".two",哈希值从 107374181 到 4294967295 对应于值""(一个空字符串)。就这么简单就实现了分流到不同的页面,之后可以统计这个不同页面的转化成交率。 © 原创文章,内容翻译自 ngx_http_split_clients_module 文档 一如既往推荐一些 付费课程,通过我的二维码购买可以享受八折优惠。

June 26, 2019 · 1 min · jiezi

Nginx-http资源请求限制三种方法

原文链接:何晓东 博客 前置条件:nginx 需要有 ngx_http_limit_conn_module 和 ngx_http_limit_req_module 模块,可以使用命令 2>&1 nginx -V | tr ' ' '\n'|grep limit 检查有没有相应模块,如果没有请重新编译安装这两个模块。测试版本为:nginx版本为1.15+ 限制链接数1.使用 limit_conn_zone 指令定义密钥并设置共享内存区域的参数(工作进程将使用此区域来共享密钥值的计数器)。第一个参数指定作为键计算的表达式。第二个参数 zone 指定区域的名称及其大小: limit_conn_zone $binary_remote_addr zone=addr:10m;2.在 location {}, server {} 或者 http {} 上下文中使用 limit_conn 指令来应用限制,第一个参数为上面设定的共享内存区域名称,第二个参数为每个key被允许的链接数: location /download/ { limit_conn addr 1;}使用 $binary_remote_addr 变量作为参数的时候,是基于 IP 地址的限制,同样可以使用 $server_name 变量进行给定服务器连接数的限制: http { limit_conn_zone $server_name zone=servers:10m; server { limit_conn servers 1000; }}限制请求速率速率限制可用于防止 DDoS,CC 攻击,或防止上游服务器同时被太多请求淹没。该方法基于 leaky bucket 漏桶算法,请求以各种速率到达桶并以固定速率离开桶。在使用速率限制之前,您需要配置 "漏桶" 的全局参数: ...

May 22, 2019 · 2 min · jiezi

nginx-对同一-ip-访问请求速率限制

模块ngx_http_limit_req_module主要用到的指令 limit_req limit_req_log_level limit_req_status limit_req_zone 所述ngx_http_limit_req_module模块(0.7.21)用于限制每一个定义的键值的请求的处理速率,特别是从一个单一的IP地址的请求的处理速率。使用“漏桶”方法进行限制。 示例配置http { limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; ... server { ... location / search / { limit_req zone=one burst=5; }指令句法: limit_req zone=name [burst=number] [nodelay | delay=number];默认: -语境: http,server,location设置共享内存区域和请求的最大突发大小。如果请求速率超过为区域配置的速率,则延迟处理,以便以定义的速率处理请求。过多的请求被延迟,直到它们的数量超过最大突发大小,在这种情况下请求以错误终止。默认情况下,最大突发大小等于零。例如,指令 limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;server { location / search / { limit_req zone=one burst=5; }平均每秒允许不超过1个请求,突发不超过5个请求。 如果不希望在请求受限的情况下延迟过多的请求,nodelay则应使用以下参数: limit_req zone=one burst=5 nodelay;delay参数(1.15.7)指定在该过度请求成为被延迟请求的最大值。默认值为零,即所有过多的请求都会延迟。 可以有多个limit_req指令。例如,以下配置将限制来自单个IP地址的请求的处理速率,同时限制虚拟服务器的请求处理速率: limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;limit_req_zone $server_name zone=perserver:10m rate=10r/s;server { ... limit_req zone=perip burst=5 nodelay; limit_req zone=perserver burst=10;}当且仅当limit_req 当前级别没有指令时,这些指令才从先前级别继承 。 ...

May 2, 2019 · 1 min · jiezi

openresty/nginx升级http2

http2需要https支持,假设你已经有https证书从源码编译安装openresty解压:tar -xzvf openresty-VERSION.tar.gzcd openresty-VERSION/三连:./configuremakesudo make install此时安装的openresty配置http2会报错 the “http2” parameter requires ngx_http_v2_module重新编译:./configure –with-http_v2_module编译完成后make (不要make insall ,会覆盖安装)编译出的nginx在 openresty-1.13.6.2/build/nginx-1.13.6/objs/里我们之拥替换此二进制文件就好了nginx -s stop先停止nginx将openresty-1.13.6.2/build/nginx-1.13.6/objs/nginx 复制到/usr/local/openresty/nginx/sbin不先停止nginx的话会出现 cp: 无法创建普通文件’./nginx’: 文本文件忙然后将listen的http2配置上启动nginx应该就可以看到如果替换了新编译的nginx二进制文件还是使用http1.1,检查一下openssl版本和编译的模块,openssl版本需大于1.0.1才能支持http2

March 8, 2019 · 1 min · jiezi

Nginx基础笔记

压力测试工具:abab -n 请求数 -c 并发数 请求urlNginx:Nginx (engine x) 是一个高性能的HTTP和反向代理服务,也是一个IMAP/POP3/SMTP服务。特点:IO多路复用epoll轻量级CPU亲和(affinity):把每个worker进程固定在一个cpu上执行,减少切换cpu的cache miss,获得更好的性能sendfile:静态文件不经过用户空间,直接通过内核进行传输版本分类Mainline version 开发版(有更新的功能,但不一定稳定)Stable version 稳定版(经过测试,有更好的稳定性)Legacy version 历史版本命令nginx -V 查看nginx版本及编译的模块信息nginx -t -c .conf文件路径 检查配置文件语法是否正确nginx -s reload -c .conf文件路径 重启配置文件配置语法nginx.conf#运行用户user nobody;#启动进程,通常设置成和cpu的数量相等worker_processes 1; #全局错误日志及PID文件#error_log logs/error.log;#error_log logs/error.log notice;#error_log logs/error.log info; #pid logs/nginx.pid; #工作模式及连接数上限events { #epoll是多路复用IO(I/O Multiplexing)中的一种方式, #仅用于linux2.6以上内核,可以大大提高nginx的性能 use epoll; #单个后台worker process进程的最大并发链接数 worker_connections 1024; # 并发总数是 worker_processes 和 worker_connections 的乘积 # 即 max_clients = worker_processes * worker_connections # 在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4 为什么 # 为什么上面反向代理要除以4,应该说是一个经验值 # 根据以上条件,正常情况下的Nginx Server可以应付的最大连接数为:4 * 8000 = 32000 # worker_connections 值的设置跟物理内存大小有关 # 因为并发受IO约束,max_clients的值须小于系统可以打开的最大文件数 # 而系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右 # 我们来看看360M内存的VPS可以打开的文件句柄数是多少: # $ cat /proc/sys/fs/file-max # 输出 34336 # 32000 < 34336,即并发连接总数小于系统可以打开的文件句柄总数,这样就在操作系统可以承受的范围之内 # 所以,worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置 # 使得并发总数小于操作系统可以打开的最大文件数目 # 其实质也就是根据主机的物理CPU和内存进行配置 # 当然,理论上的并发总数可能会和实际有所偏差,因为主机还有其他的工作进程需要消耗系统资源。 # ulimit -SHn 65535 } http { #设定mime类型,类型由mime.type文件定义 include mime.types; default_type application/octet-stream; #设定日志格式 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; #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件, #对于普通应用,必须设为 on, #如果用来进行下载等应用磁盘IO重负载应用,可设置为 off, #以平衡磁盘与网络I/O处理速度,降低系统的uptime. sendfile on; #tcp_nopush on; #连接超时时间 #keepalive_timeout 0; keepalive_timeout 65; tcp_nodelay on; #开启gzip压缩 gzip on; gzip_disable “MSIE [1-6].”; #设定请求缓冲 client_header_buffer_size 128k; large_client_header_buffers 4 128k; #设定虚拟主机配置 server { #侦听80端口 listen 80; #定义使用 www.nginx.cn访问 server_name www.nginx.cn; #定义服务器的默认网站根目录位置 root html; #设定本虚拟主机的访问日志 access_log logs/nginx.access.log main; #默认请求 location / { #定义首页索引文件的名称 index index.html index.htm; } # 定义错误提示页面 error_page 500 502 503 504 /50x.html; location = /50x.html { } #静态文件,nginx自己处理 location ~ ^/(images|javascript|js|css|flash|media|static)/ { #过期30天,静态文件不怎么更新,过期可以设大一点, #如果频繁更新,则可以设置得小一点。 expires 30d; } #禁止访问 .htxxx 文件 location ~ /.ht { deny all; } }}日志类型error.log 格式:error_log log_file level; 错误日志,保存nginx运行中的错误信息access.log格式:access_log log_file log_format定义名称(固定输出格式); 访问日志,保存访问信息变量http请求变量:arg_PARAMETER http_HEADER(如:http_user_agent)sent_http_HEADER内置变量自定义变量常用模块http_sub_status_module nginx客户端的状态(可以配置在server和location下)stub_status;具体使用结果:https://blog.csdn.net/echizao…http_sub_module HTTP内容替换(http|server|location)sub_filter string(要替换的内容) replacement(替换的内容);sub_filter_once off;默认为on 默认匹配所有内容,on只匹配一次sub_filter_last_modified on;默认为off 判断服务器文件是否发生过变更,不变更则不重新加载http_random_index_module 目录中选择一个随机主页(配置在location中)random_index on;默认为offlimit_conn_module 连接频率限制limit_conn_zone key zone=name:size;(http)limit_conn zone number;(http|server|location)limit_req_modele 请求频率限制limit_req_zone key zone=name:size rate=rate;(http)如:limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;limit_req zone=name burst=number [nodelay];(http\server\location)http_access_module 基于ip的控制访问(通过$remote_addr实现,代理模式就失去了作用,x-forword-for,geo模块,自定义变量解决)allow address | CIDR(网段) | unix: | all;(http\server\location\limit_except)deny address | CIDR | unix: | all;(http\server\location\limit_except)http_auth_basic_module 基于用户的信任登录(弊端解决:1结合lua实现高效验证,2利用nginx-auth-ldap模块,实现nginx和ldap打通)auth_basic string | off;默认off(http\server\location\limit_except);auth_basic_user_file file;(http\server\location\limit_except); file为一个用户名密码文件 file生成方式:htpasswd -c 文件名 用户名 然后就会让输入两次密码 命令在httpd-tools中 ...

February 16, 2019 · 2 min · jiezi

Nginx反向代理理解误区之proxy_cookie_domain

基本内容Nginx做反向代理的时候,我们一般习惯添加proxy_cookie_domain配置,来做cookie的域名转换,比如…location /api { proxy_pass https://b.test.com; proxy_cookie_domain b.test.com a.test.com;} …在之前的博客中我也是这么写的,但是最近在项目中发现,不配置这个属性,依然运转正常,背后冷风阵阵,我发现自己一直以来可能又理解错了这个选项,然后还在这给别人讲。。。我们首先来看下proxy_cookie_domain的官方定义,Syntax: proxy_cookie_domain off;proxy_cookie_domain domain replacement;Default: proxy_cookie_domain off;Context: http, server, locationThis directive appeared in version 1.1.15.Sets a text that should be changed in the domain attribute of the “Set-Cookie” header fields of a proxied server response. Suppose a proxied server returned the “Set-Cookie” header field with the attribute “domain=localhost”. The directive proxy_cookie_domain localhost example.org will rewrite this attribute to “domain=example.org”.翻译过来就是proxy_cookie_domain参数的作用是转换response的set-cookie header中的domain选项,由后端设置的域名domain转换成你的域名replacement,来保证cookie的顺利传递并写入到当前页面中,注意proxy_cookie_domain负责的只是处理response set-cookie头中的domain属性,仅此而已。但是我们知道response在写set-cookie的时候,domain是一个可选项,并不是必填项,所以经常能看到如下这种情况这个时候由于set-cookie本身就没有domain内容,proxy_cookie_domain也就不没有必要了,这也是为什么在部分项目中不配置proxy_cookie_domain依然正常的原因。但是对于一些设置了domain的项目,比如这种情况下当你用nginx做反向代理的时候,就必须要转换一下了。误区回溯说到这里,我们再看看之前的错误理解:“proxy_cookie_domain的作用是实现前后端cookie域名转换,保证顺利传递”乍一看好像也没错,但是现在想想,理解还是不够啊,因为proxy_cookie_domain的作用是单向的,并不是双向转换的。我们先看下cookie的传递过程,盗一张图先(懒得画了。。。)浏览器在发送请求的时候,会在request header中带上cookie项(有内容的话),此时的cookie是一个字符串,一个key=value并用分号分割的字符串,其中并不包含任何域名信息。这是因为浏览器在设置cookie选项的时候,所选取的内容都是缓存中接口域名下的。然后request的只要请求发送出去之后,cookie中有关domain信息其实是不存在的,它只是一个普通的字符串,随便proxy_pass到任何位置,都会正常携带下去。因此在前端到后端的request的过程中,proxy_cookie_domain是没用的而server端在做响应的时候,通过set-cookie的domain属性,可以控制cookie的生效域名目标,做到诸如二级域名cookie分离等等,如果前端接收到的set-cookie的domain和当前域名不一致,或者一级域名不一致(二级域名可以共享一级域名下的cookie),这个cookie在后续的通信中就是无效的,所以这里才需要去做domain的转换,也就是说response中set-cookie的domain转换才是有意义的,这也正是proxy_cookie_domain的作用所在。当reseponse的set-cookie中domain不去设置时,cookie顺利传入浏览器中,浏览器会自动设置这个cookie的生效域名为当前域名。和这个类似的还有proxy_cookie_path属性,同样的该属性仅作用在修改response set-cookie的path属性,而一般情况下,用的也比较少。唠叨两句很多问题,有时候都是太过理所当然的以为它是怎么样的,并且生效了、达到目的了,我们就认为它是这样的了,但往往大脸就会在后面不期而至。多学习,多去关注一些底层的原理,才会发现自己理解的错误,望诸君共勉~如果错误,欢迎指出~ ...

January 29, 2019 · 1 min · jiezi