反向代理
<h2>反向代理</h2>
<ul>
<li>反向代理服务器,介于用户和真实服务器之间,提供请求和响应的中转服务</li>
<li>对于用户而言,访问反向代理服务器就是访问真实服务器</li>
<li>反向代理可以有效降低服务器的负载消耗,提升效率</li>
</ul>
<h2>反向代理优势</h2>
<ul>
<li>隐藏真实服务器</li>
<li>便于横向扩充后端动态服务</li>
<li>动静分离,提升系统健壮性</li>
</ul>
<h2>动静分离</h2>
<ul>
<li>在web服务器架构中,将静态页面与动态页面或者静态内容接口和动态内容接口分开不同系统访问的架构设计方法,进而提升整个服务访问性能和可维护性</li>
</ul>
<h2>使用Nginx作为反向代理时支持的协议</h2>
<ul>
<li>四层 tcp/udp
<ul>
<li>tcp, udp</li>
</ul></li>
<li>七层 http
<ul>
<li>fastcgi, scgi, uwsgi, http, grpc, memcached, websocket</li>
</ul></li>
</ul>
<h2>upstream模块</h2>
<ul>
<li>
<p>说明</p>
<ul>
<li>用下定义上游服务的相关信息</li>
<li>默认已被编译进nginx,禁用须通过--without-http_upstream_module</li>
<li>上下文</li>
<li>http</li>
</ul>
</li>
<li>
<p>提供指令</p>
<ul>
<li>upstream</li>
<li>
<p>段名,以{开始, }结束,中间定义上游服务url</p>
</li>
<li>server</li>
<li>
<p>定义上游服务地址</p>
</li>
<li>zone</li>
<li>
<p>定义共享内存,用于跨worker子进程</p>
</li>
<li>keepalive</li>
<li>
<p>对上游服务启用长连接</p>
</li>
<li>keepalive_requests</li>
<li>
<p>一个长连接最多请求个数</p>
</li>
<li>keepalive_timeout</li>
<li>空闲情形下,一个长连接的超时时长</li>
</ul>
</li>
<li>
<p>server address [parameters],parameters可选值</p>
<ul>
<li>weight = number</li>
<li>
<p>权重值,默认为1</p>
</li>
<li>max_conns = number</li>
<li>
<p>上游服务器的最大并发连接数</p>
</li>
<li>fail_timeout = time</li>
<li>
<p>服务器不可用的判定时间</p>
</li>
<li>max_fails = number</li>
<li>
<p>服务器不可用的检查次数</p>
</li>
<li>backup</li>
<li>
<p>备份服务器,仅当其他服务器都不可用时</p>
</li>
<li>down</li>
<li>标记服务器长期不可用,离线维护</li>
</ul>
</li>
<li>
<p>upstream配置示例</p>
<pre><code class="language-nginx">upstream back_end{
server 127.0.0.1:8080 weight=3 max_conns=100 fail_timeout=10s max_fails=2;
keepalive 32;
keepalive_requests 50;
keepalive_timeout 30s;
}</code></pre>
</li>
</ul>
<h2>proxy_poass指令用法常见误区</h2>
<h4>带/与不带/用法区别</h4>
<ul>
<li>不带/
<ul>
<li>意味着nginx不会修改用户url,而是直接透传给上游的应用服务器</li>
</ul></li>
<li>带/
<ul>
<li>意味着nginx会修改用户url,修改方法:将location后的url从用户的url中删除</li>
</ul></li>
</ul>
<h4>proxy_pass URL</h4>
<ul>
<li>
<p>要点:URL结尾有无/</p>
</li>
<li>
<p>不带/</p>
<pre><code class="language-nginx"># http://127.0.0.1
location /proxy/ {
proxy_pass http://127.0.0.1:8008;
}</code></pre>
<ul>
<li>解释:上游服务器的URL末尾不带/则转发到上游服务,请求URL会被透传到上游服务器</li>
<li>示例:假如上图中请求/proxy/abc/test.html,经代理后转发到上游URL依然是/proxy/abc/test.html</li>
</ul>
</li>
<li>
<p>带/</p>
<pre><code class="language-nginx"># http://127.0.0.1/
location /proxy/ {
proxy_pass http://127.0.0.1:8080/;</code></pre>
<ul>
<li>解释:上游服务器的URL末尾带/则转发到上游服务,URL中的location匹配部分会被删除掉</li>
</ul>
<p>示例:例如上图中请求到Nginx是/proxy/abc/test.html,经代理后转发到上游URL则变成/abc/test.html</p>
</li>
</ul>
<h2>Nginx修改用户发来的请求行和请求包体</h2>
<ul>
<li>
<p>请求行</p>
<pre><code class="language-nginx">proxy_method method ;
proxy_http_version 1.0|1.1 ;</code></pre>
</li>
<li>
<p>请求头</p>
<pre><code class="language-nginx">proxy_set_header field value ;
# 若修改后的field的value为空,则Nginx不会将该头部字段发送到上游服务器
proxy_pass_request_headers on | off ;
# on Nginx透传用户请求头部给上游服务器;off Nginx不发送用户请求头部给上游服务器
proxy_set_body
proxy_pass_request_body</code></pre>
</li>
</ul>
<h2>nginx接收包体的两种方式</h2>
<ul>
<li>接收完全部包体再发送
<ul>
<li>适用场景</li>
<li>吞吐量要求高,上游服务并发处理能力低</li>
</ul></li>
<li>一边接收包体一边发送
<ul>
<li>适用场景</li>
<li>更及时的响应,减少nginx磁盘IO</li>
</ul></li>
</ul>
<h2>Nginx接收用户请求包体的处理方式相关指令</h2>
<pre><code class="language-nginx">proxy_request_buffering on;
client_max_body_size 1M
client_body_buffer_size 16k;
client_body_in_single_buffer on;
# 指示是否将请求体完整的写入到一个连续的内存中,默认未off;若为on,则Nginx会保证在请求体不大于client_body_buffer_size时,都存放到一块连续的内存中,但超过大小时仍然会整体写入到磁盘的临时文件中
client_body_temp_path client_body_temp;
client_body_in_file_only on;
off # 禁用文件写入
clean # 请求体将被写入文件,但在处理完请求后删除
off # 请求体将被写入文件,处理完请求后不删除
proxy_buffer_size size</code></pre>