QingCloud 文档 – 常见问题 - kaiyun官方网站下载手机网页 /network/loadbalancer/faq/ Recent content in 常见问题 on QingCloud 文档 Hugo -- gohugo.io Network: 如何排查负载均衡后端不可用问题? /network/loadbalancer/faq/after_end_miss/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/after_end_miss/ <h2 id="问题现象">问题现象</h2> <p>通过控制台看到到后端服务器的状态为<code>不可用</code>,如下图。</p> <p><img src="../../_images/afterendmissing.png" alt=""></p> <h2 id="排查方法">排查方法</h2> <ol> <li> <p>确认lb和后端云服务器网络相同(属于同一私有网)。</p> </li> <li> <p>运行命令<code>netstat -an | grep 80</code>查看本地服务是否正常,服务端口是否处于监听状态。</p> <p><img src="../../_images/end_netstat.png" alt=""></p> </li> <li> <p>查看云服务器是否绑定安全组,且安全组是否放行相应端口。</p> <p><img src="../../_images/group.png" alt=""></p> </li> <li> <p>通过其他网络相同云服务器测试主机网络和端口是否正常。</p> <p><img src="../../_images/ping_telnet.png" alt=""></p> </li> <li> <p>若以上排查均无问题依然显示不可用,可<a href="https://console.qingcloud.com/tickets/">提交工单</a>联系技术支持协助排查。</p> </li> </ol> Network: 访问负载均衡器返回502/503/504是什么原因? /network/loadbalancer/faq/lb_502_503_504/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/lb_502_503_504/ <h2 id="错误代码说明">错误代码说明</h2> <p>代理服务器常见错误代码:</p> <ul> <li><strong>502(Bad Gateway)</strong>:作为代理或网关使用的服务器从请求响应链的下一条链路上收到了一条伪响应。</li> <li><strong>503(Service Unavailable)</strong>:说明服务器现在无法为请求提供服务(暂时不可用),将来可以。</li> <li><strong>504 (Gateway Time-out)</strong>:作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器或者辅助服务器收到响应。</li> </ul> <h2 id="原因分析">原因分析</h2> <p>访问负载均衡器时返回502/503/504时,说明请求已经到达了负载均衡器,负载均衡器和后端交互时出现了问题。</p> <ul> <li> <p><strong>负载均衡器返回502原因</strong></p> <p>502状态码错误提示表明负载均衡可以将来自客户端的请求转发到后端服务器,但是由于服务器中 Web 应用处理异常,导致出现该提示,所以排错的方向是针对服务器中 Web 应用的配置以及运行情况进行分析。</p> </li> <li> <p><strong>负载均衡器返回503原因</strong></p> <p>503状态码表示后端服务不可用,负载均衡器无法将请求发送到后端服务器,所以排查方向主要针对于负载均衡器和后端服务器之间的网络问题,以及后端服务器是否存活等问题进行分析。</p> </li> <li> <p><strong>负载均衡器返回504原因</strong></p> <p>504状态码表示该负载均衡器能够连接后端服务器,但在读取服务器响应的时候超时了。所在排查问题时,应该注意负载均衡器的超时时间、后端服务器服务器负载、网络延迟、后端服务器的进程是否正常等问题。</p> </li> </ul> <h2 id="处理方法">处理方法</h2> <ul> <li> <p><strong>负载均衡问题</strong></p> <ol> <li> <p>检查负载均衡状态,查看是否存在健康检查失败的情况,如果有则需要先排查健康检查失败原因。</p> </li> <li> <p>负载均衡器开启 rsyslog,通过日志来排查问题。</p> </li> <li> <p>在七层(HTTP/HTTPS)监听配置中,连接请求超时时间默认值为50秒,若后端云服务器对 PHP 请求的处理时间超过60秒,此时负载均衡器会返回504状态码。</p> <blockquote> <p><strong>说明</strong></p> <p>如果无法确定是否是负载均衡器的问题,可以在客户端的hosts文件中,将域名解析至后端服务器的IP地址上进行访问。由此来绕过负载均衡器。来检测访问是否正常。</p> </blockquote> </li> </ol> </li> <li> <p><strong>后端服务器问题</strong></p> <p>如果5XX状态码间断发生,很可能是某一台后端实例的问题。在客户端的 hosts 文件中,将域名解析至后端服务器的 IP 地址上进行访问,检查是否是某一台后端问题。</p> <p>如果确定是后端服务器问题,请按照以下步骤进行排查:</p> <ol> <li>检查服务器 CPU,内存,磁盘IO等负载是否正常。此外对于部分服务来说,数据盘的使用空间也会影响到服务是否正常。</li> <li>结合业务日志排查问题。</li> <li>检查服务器网络,防火墙是否有开启限制,检查 TCP、UDP连接池是否占满。</li> </ol> </li> </ul> Network: 负载均衡器如何支持多证书? /network/loadbalancer/faq/lb_bind_multi_cert/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/lb_bind_multi_cert/ <h2 id="操作场景">操作场景</h2> <p>本文指导用户通过 HTTPS 和 SSL 监听器绑定多个 SSL 证书,实现同一个监听器根据多个域名自动选择 SSL 证书加密传输访问后端的需求。</p> <h2 id="前提条件">前提条件</h2> <ul> <li> <p>已创建 HTTPS/SSL 监听器,具体步骤可参考<a href="/network/loadbalancer/manual/monitor/create_https_monitor/">添加 HTTPS 监听器</a>、<a href="/network/loadbalancer/manual/monitor/create_https_monitor/">添加 SSL 监听器</a>。</p> </li> <li> <p>已创建 SSL 证书并完成验证,具体步骤可参考 SSL 证书<a href="/site/ssl/manual/user_guide/">购买指南</a>、<a href="/site/ssl/manual/manualq/">验证指南</a>。</p> </li> </ul> <h2 id="操作步骤">操作步骤</h2> <ol> <li> <p>登录管理控制台,选择<strong>产品与服务</strong> &gt; <strong>网络服务</strong> &gt; <strong>负载均衡器</strong>,进入<strong>负载均衡器</strong>页面。</p> </li> <li> <p>在负载均衡器列表,找到目标实例,点击实例 ID 号,进入实例详情页。</p> </li> <li> <p>选择监听协议为 HTTPS 或 SSL 的监听器,点击右上角的<strong>操作</strong> &gt; <strong>修改</strong>。</p> <p><img src="../../_images/image-20210731223446774.png" alt="img"></p> </li> <li> <p>在弹出的修改监听器属性中点击<strong>添加服务器证书</strong>,选择证书并添加即可。</p> <blockquote> <p><strong>说明</strong></p> <p>可通过多次点击<strong>添加服务器证书</strong>来添加多个证书。</p> </blockquote> <p><img src="../../_images/image-20210731223532098.png" alt="image-20210731223532098"></p> </li> </ol> Network: 开启 HTTP2 不生效怎么办? /network/loadbalancer/faq/enable_http2_not_take_effect/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/enable_http2_not_take_effect/ <h2 id="问题现象">问题现象</h2> <p>在 HTTPS 监听器中勾选了 <strong>启用HTTP2.0</strong>,但通过 curl 命令发现还是使用的 HTTP1.1 协议。</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>curl -v --http2 https://test.com </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>*** </span></span><span style="display:flex;"><span>*** </span></span><span style="display:flex;"><span>&gt; GET / HTTP/1.1 </span></span><span style="display:flex;"><span>*** </span></span></code></pre></div><h2 id="解决办法">解决办法</h2> <p>查看 curl 返回信息中关于 ALPN 的日志,该日志为 HTTPS 上协商 HTTP 版本的过程。</p> <ol> <li> <p>重启负载均衡器。</p> <p>部分用户使用的 LB 为较早之前创建的,镜像版本不支持开启 HTTP2.0 ,此时可以重启下 LB,会自动更新到最新的镜像版本,并支持开启 HTTP2.0。</p> </li> <li> <p>启用 TCP 监听器。</p> <p>部分用户在后端开启了 HTTP2 ,LB 不支持在 LB 及后端同时开启 HTTP2。此时需要使用 TCP 监听器,端口为后端服务监听的端口。</p> <p><img src="../../_images/http2_enabled_does_not_take_effect_1.png" alt=""></p> </li> </ol> Network: 如何检查负载均衡器会话保持是否生效? /network/loadbalancer/faq/lb_check_session_hold/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/lb_check_session_hold/ <p>您可以通过 curl 命令测试会话保持是否生效。</p> <h2 id="背景信息">背景信息</h2> <p>负载均衡器支持源 IP 地址、负载均衡器 Cookie 、植入 Cookie 前缀、重写 Cookie 、后端 Cookie 实现会话保持,详见<a href="/network/loadbalancer/manual/monitor/lb_session_hold/">会话保持</a>。</p> <h2 id="准备工作">准备工作</h2> <p>在后端云服务器中创建测试页面,测试页面的名称需要一致,分别写入不同的内容,以此区分每个后端。</p> <h2 id="四层监听测试">四层监听测试</h2> <blockquote> <p><strong>说明</strong></p> <p>四层监听基于源 IP 算法作为负载方式来实现会话保持。</p> </blockquote> <p>运行以下命令,多次访问测试页面,查看返回结果是否一致,若返回结果一致说明会话保持已生效,反之则说明会话保持无效</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span> curl http://1.1.1.1/check.html </span></span></code></pre></div><h2 id="七层监听测试">七层监听测试</h2> <blockquote> <p><strong>说明</strong></p> <p>如果会话保持默认模式是植入 Cookie ,而 curl 命令默认不保存和发送 Cookie。需要预先保存相应的 Cookie,再进行测试。否则,curl 测试结果将是随机的,影响测试结果的准确性。</p> </blockquote> <ol> <li> <p>访问测试页面,保存 Cookie 值。</p> <pre tabindex="0"><code>curl -D test.cookie http://1.1.1.1/check.html </code></pre></li> <li> <p>使用保存的 Cookie 多次访问,查看返回结果。</p> <p>如果多次访问返回结果一致,说明会话保持已生效,反之则说明会话保持无效</p> <pre tabindex="0"><code>curl -b test.cookie http://1.1.1.1/check.html </code></pre></li> </ol> <h2 id="相关问题">相关问题</h2> <p><a href="../resolve_check_session_hold/">如何排查负载均衡器会话保持不生效问题?</a></p> Network: 如何开启HTTP2 ? /network/loadbalancer/faq/lb_turn_on_http2/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/lb_turn_on_http2/ <h2 id="背景信息">背景信息</h2> <p>目前 HTTP2 的使用越来越广泛,相对来说,HTTP2 会比 HTTP1.1 更加地高效。HTTP2 最大的特点是使用多路复用,对同一个域的服务器只建立一次 TCP 连接,加载多个资源,使用二进制帧传输,同时会对 HTTP 头部进行压缩。HTTP2 在实现上基本上只支持 HTTPS 。</p> <p>开·云app官方版下载支持在负载均衡器上开启 HTTP2,由于负载均衡器节点和后端在一个内网中,速度很快,故后端业务无需支持 HTTP2。</p> <h2 id="操作步骤">操作步骤</h2> <ol> <li> <p>创建或修改 HTTPS 监听器时,点击下方的<strong>显示高级选项</strong>。</p> <p><img src="../../_images/lb_turn_on_http2_1.png" alt=""></p> </li> <li> <p>在附加选项中勾选<strong>启用HTTP2.0</strong>。</p> <p><img src="../../_images/lb_turn_on_http2_2.png" alt=""></p> </li> </ol> Network: 如何排查负载均衡器会话保持不生效问题? /network/loadbalancer/faq/resolve_check_session_hold/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/resolve_check_session_hold/ <p>若负载均衡器会话保持不生效,可通过如下步骤进行排查:</p> <ol> <li>查看后端服务器组上是否开启了会话保持。</li> <li>查看后端云服务器的健康检查状态是否正常,如果异常,流量会切换到其他后端云服务器,导致会话保持失效。</li> <li>如果选择的是源 IP 算法,需要注意请求到达弹性负载均衡之前 IP 是否发生变化。</li> <li>如果是 HTTP 或 HTTPS 监听器,配置了会话保持,需要注意发送的请求是否带有 Cookie ,如果带有 Cookie ,则观察该 Cookie 值是否发生了变化(因为七层会话保持基于 Cookie )。</li> </ol> Network: 如何启用 WebSocket 支持? /network/loadbalancer/faq/enable_websocket/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/enable_websocket/ <p>负载均衡器详情界面,设置监听器的界面开启Keep-Alive,可以通过 Connection 字段配置 Keep-Alive ,保持 TCP 连接不中断</p> Network: 负载均衡器支持什么类型的会话保持? /network/loadbalancer/faq/seesion_support_type/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/seesion_support_type/ <p>负载均衡器支持基于源 IP 和 cookie 植入的会话保持。详见<a href="/network/loadbalancer/manual/monitor/lb_session_hold/">会话保持说明</a>。</p> Network: 七层(HTTP/HTTPS)健康检查异常 /network/loadbalancer/faq/http_check_failed/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/http_check_failed/ <p>本文介绍负载均衡器七层健康检查出现异常时的解决方法。</p> <h2 id="问题现象">问题现象</h2> <p>负载均衡器上配置了如下图的基于七层方式的健康检查,但是健康检查结果显示为<code>不活跃</code>。</p> <img src="../../_images/http_check_faild.png" alt="http_check_faild" style="zoom:60%;" /> <h2 id="排查方法">排查方法</h2> <p>七层(HTTP/HTTPS)健康检查是基于第七层的 HTTP 协议进行的,会和业务进行交互,所以首先应该定位问题,主要分为以下几步:</p> <ol> <li> <p><strong>定位健康检查失败问题出现在第七层还是第四层。</strong></p> <p>点击监听器的<strong>操作</strong> &gt; <strong>修改</strong> &gt; <strong>显示高级选项</strong>,将健康检查修改为 <code>TCP</code>,观察后端服务器的状态是否为活跃状态:</p> <ul> <li>如果仍旧是<code>不活跃</code>状态,则说明健康检查问题出在第四层,请参考<a href="../tcp_check_fialed/">四层(TCP/UDP)健康检查出现异常</a>进行解决。</li> <li>如果是<code>活跃</code>状态,则说明是后端服务本身配置有问题。继续进行下一步分析。</li> </ul> </li> <li> <p><strong>登录后端服务器,检查健康检查 URL 是否正常。</strong></p> <p>登录到后端服务器上使用 curl 命令访问健康检查接口,根据返回的 HTTP 状态码排查问题。</p> <p>如果返回的 HTTP 状态码为 4xx 或者 5xx,那么 LB 去检查时遇到 4xx 或者 5xx 就会判断为服务不可用,此时则需要根据服务日志来排查后端服务问题。</p> <p>以下排查方法供您参考:</p> <pre tabindex="0"><code>root@web:~# curl http://172.16.6.20/health #检查命令 curl http://&lt;ip&gt;:&lt;port&gt;/&lt;url&gt; &lt;html&gt; &lt;head&gt;&lt;title&gt;404 Not Found&lt;/title&gt;&lt;/head&gt; &lt;body bgcolor=&#34;white&#34;&gt; &lt;center&gt;&lt;h1&gt;404 Not Found&lt;/h1&gt;&lt;/center&gt; &lt;hr&gt;&lt;center&gt;nginx/1.14.0 (Ubuntu)&lt;/center&gt; &lt;/body&gt; &lt;/html&gt; root@web:~# cat /var/www/html/health #配置健康检查接口 i am ok root@web:~# curl http://172.16.6.20/health #此时本地调用是成功的,控制台也可以看到健康检查成功了 i am ok </code></pre><p>如果返回的 HTTP 状态码小于400,此时则需要判断是否为健康检查超时所导致的。</p> </li> <li> <p><strong>检查健康检查 URL 是否存在超时情况。</strong></p> <p>因为健康检查是有超时时间的,如果超时时间设置过短,也可能引起健康检查失败。</p> <p>遇到此类情况,可以尝试适当调长超时时,并检查后端服务器的资源使用情况、LB 节点到后端服务器的网络情况,也可以在后端服务器上使用 curl 命令来健康检查接口的检测访问时长。</p> <p><img src="../../_images/time_out.png" alt=""></p> </li> </ol> Network: 如何分析 rsyslog 日志? /network/loadbalancer/faq/haproxy_log/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/haproxy_log/ <p>针对负载均衡器相关的问题排查,通常会通过配置 rsyslog 来进行分析问题所在,本文详细介绍如何分析 TCP 及 HTTP 转发日志。</p> <p>更多关于 HAProxy 日志的详细说明,请参见 <a href="http://cbonte.github.io/haproxy-dconv/2.5/configuration.html#8">HAProxy 官网文档</a>。</p> <h2 id="tcp-转发日志">TCP 转发日志</h2> <p><strong>日志格式示例:</strong></p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>&gt;&gt;&gt; Mar <span style="color:#ae81ff">29</span> 12:16:55 198.19.56.127 <span style="color:#ae81ff">\ </span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> haproxy<span style="color:#f92672">[</span>686<span style="color:#f92672">]</span>: 111.47.226.115:17652 <span style="color:#f92672">[</span>29/Mar/2021:10:32:46.135<span style="color:#f92672">]</span> <span style="color:#ae81ff">\ </span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> lbl-l1rmzsj5 lbl-l1rmzsj5_default/lbb-mfc8im36 1/0/6249762 <span style="color:#ae81ff">92826</span> -- 1/1/1/0/0 0/0 </span></span><span style="display:flex;"><span><span style="color:#75715e">#日志各字段格式如下:</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#haproxy[686]: #process_name &#39;[&#39; pid &#39;]:&#39;</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#111.47.226.115:17652 #client_ip &#39;:&#39; client_port</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#[29/Mar/2021:10:32:46.135] #&#39;[&#39; accept_date &#39;]&#39;</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#lbl-l1rmzsj5 #frontend_name</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#lbl-l1rmzsj5_default/lbb-mfc8im36 #backend_name &#39;/&#39; server_name </span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#1/0/6249762 #Tw &#39;/&#39; Tc &#39;/&#39; Tt*</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#92826 #bytes_read*</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#-- #termination_state</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#1/1/1/0/0 #actconn &#39;/&#39; feconn &#39;/&#39; beconn &#39;/&#39; srv_conn &#39;/&#39; retries* </span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#0/0 #srv_queue &#39;/&#39; backend_queue</span> </span></span></code></pre></div><p>字段说明:</p> <table> <thead> <tr> <th style="text-align:left">字段</th> <th style="text-align:left">说明</th> </tr> </thead> <tbody> <tr> <td style="text-align:left">client_ip</td> <td style="text-align:left">连接到 haproxy 的客户端的 IP 地址</td> </tr> <tr> <td style="text-align:left">client_port</td> <td style="text-align:left">发起连接的客户端的 TCP 端口。</td> </tr> <tr> <td style="text-align:left">accept_date</td> <td style="text-align:left">haproxy 接收到连接的确切时间。</td> </tr> <tr> <td style="text-align:left">frontend_name</td> <td style="text-align:left">接收及处理客户端请求的监听器,为“负载均衡器监听器 ID”。</td> </tr> <tr> <td style="text-align:left">backend_name</td> <td style="text-align:left">指定的管理服务器连接的监听器,由“{监听器ID}_default”组成。<br/>若未设置切换规则,与 “frontend_name” 相同。</td> </tr> <tr> <td style="text-align:left">server_name</td> <td style="text-align:left">连接被转发到的最后一个后端,为“后端服务器名称”。</td> </tr> <tr> <td style="text-align:left">Tw</td> <td style="text-align:left">在各种队列中等待的总时间(毫秒)。 如果连接在到达队列之前被中止,它可以是“-1”。</td> </tr> <tr> <td style="text-align:left">Tc</td> <td style="text-align:left">等待连接建立到最终服务器的总时间(毫秒),包括重试次数。 如果在建立连接之前连接被中止,它可以是“-1”。</td> </tr> <tr> <td style="text-align:left">Tt</td> <td style="text-align:left">在接受和最后一次关闭之间经过的总时间(毫秒)。 涵盖了所有可能的处理,但如果指定了“选项logasap”,则在发出日志的时刻计时停止。 该情况下,在该值之前加上“+”号,表示最后一个会更大。</td> </tr> <tr> <td style="text-align:left">bytes_read</td> <td style="text-align:left">发送日志时,从服务器发送到客户端的总字节数。</td> </tr> <tr> <td style="text-align:left">termination_state</td> <td style="text-align:left">会话结束时会话的条件。这表示在会话状态,哪一方导致了会话结束,以及什么原因。 正常标志应为“ - ”,表示会话已由两端关闭,缓冲区中没有剩余数据。</td> </tr> <tr> <td style="text-align:left">actconn</td> <td style="text-align:left">会话记录时进程上的并发连接总数。</td> </tr> <tr> <td style="text-align:left">feconn</td> <td style="text-align:left">会话记录时前端上的并发连接总数。</td> </tr> <tr> <td style="text-align:left">beconn</td> <td style="text-align:left">会话记录时由后端处理的并发连接的总数。</td> </tr> <tr> <td style="text-align:left">srv_conn</td> <td style="text-align:left">会话记录时服务器上仍然处于活动状态的并发连接总数。</td> </tr> <tr> <td style="text-align:left">retries</td> <td style="text-align:left">尝试连接到服务器时此会话遇到的连接重试次数。</td> </tr> <tr> <td style="text-align:left">srv_queue</td> <td style="text-align:left">在服务器队列中之前处理的请求的总数。</td> </tr> <tr> <td style="text-align:left">backend_queue</td> <td style="text-align:left">在后端的全局队列中之前处理的请求的总数。</td> </tr> </tbody> </table> <h2 id="http-转发日志">HTTP 转发日志</h2> <p><strong>日志格式示例:</strong></p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>&gt;&gt;&gt; Jun <span style="color:#ae81ff">22</span> 13:47:56 198.19.173.227 <span style="color:#ae81ff">\ </span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> haproxy<span style="color:#f92672">[</span>40849<span style="color:#f92672">]</span>: 42.91.108.84:11918 <span style="color:#f92672">[</span>22/Jun/2020:13:47:50.784<span style="color:#f92672">]</span> <span style="color:#ae81ff">\ </span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> lbl-2tqyo6fr lbl-2tqyo6fr_default/lbb-jdbamki3 1/0/2/5900/5903 <span style="color:#ae81ff">200</span> <span style="color:#ae81ff">518</span> - - ---- <span style="color:#ae81ff">\ </span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> 154/150/140/20/0 0/0 <span style="color:#f92672">{</span>haproxy.1wt.eu<span style="color:#f92672">}</span> <span style="color:#f92672">{}</span> <span style="color:#e6db74">&#34;GET /index.html HTTP/1.1&#34;</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#日志各字段格式如下:</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#haproxy[40849]: #process_name &#39;[&#39; pid &#39;]:&#39; </span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#42.91.108.84:11918 #client_ip &#39;:&#39; client_port</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#[22/Jun/2020:13:47:50.784] #&#39;[&#39; request_date &#39;]&#39;</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#lbl-2tqyo6fr #frontend_name</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#lbl-2tqyo6fr_default/lbb-jdbamki3 #backend_name &#39;/&#39; server_name </span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#1/0/2/5900/5903 #TR &#39;/&#39; Tw &#39;/&#39; Tc &#39;/&#39; Tr &#39;/&#39; Ta*</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#200 #status_code</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#518 #bytes_read* </span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#- #captured_request_cookie</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#- #captured_response_cookie</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#---- #termination_state </span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#154/150/140/20/0 #actconn &#39;/&#39; feconn &#39;/&#39; beconn &#39;/&#39; srv_conn &#39;/&#39; retries*</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#0/0 #srv_queue &#39;/&#39; backend_queue</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#{haproxy.1wt.eu} #&#39;{&#39; captured_request_headers* &#39;}&#39;</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#{} #&#39;{&#39; captured_response_headers* &#39;}&#39;</span> </span></span><span style="display:flex;"><span><span style="color:#75715e">#&#34;GET /index.html HTTP/1.1&#34; #&#39;&#34;&#39; http_request &#39;&#34;&#39;</span> </span></span></code></pre></div><p><strong>字段说明:</strong></p> <table> <thead> <tr> <th>字段</th> <th>说明</th> </tr> </thead> <tbody> <tr> <td>client_ip</td> <td>连接到 haproxy 的客户端的 IP 地址</td> </tr> <tr> <td>client_port</td> <td>发起连接的客户端的 TCP 端口。</td> </tr> <tr> <td>accept_date</td> <td>通过 haproxy(log field%tr)接收到 HTTP 请求的第一个字节的确切时间。</td> </tr> <tr> <td>frontend_name</td> <td>接收及处理客户端请求的监听器,为“负载均衡器监听器 ID”。</td> </tr> <tr> <td>backend_name</td> <td>指定的管理服务器连接的监听器,由“{监听器ID}_default”组成。<br/>若未设置切换规则,与 “frontend_name” 相同。</td> </tr> <tr> <td>server_name</td> <td>连接被转发到的最后一个后端,为“后端服务器名称”。</td> </tr> <tr> <td>TR</td> <td>在接收到第一个字节后,等待来自客户端(不包括正文)的完整 HTTP 请求花费的总时间(毫秒)。 <br/> 如果接收到完整的请求或接收到错误的请求之前连接被中止,它可以是“-1”。</td> </tr> <tr> <td>Tw</td> <td>各种队列中等待的总时间(毫秒)。 <br/>如果连接在到达队列之前被中止,它可以是“-1”。</td> </tr> <tr> <td>Tc</td> <td>等待连接建立到最终服务器的总时间(毫秒),包括重试次数。 <br/>如果在建立连接之前连接被中止,它可以是“-1”。</td> </tr> <tr> <td>Tr</td> <td>从 HTTP 连接后到服务器发给 LB 的第一个报文所用的总时间。Tr 高说明后端慢。<br/>如果在接收到报文之前连接被中止,它可以是“-1”。</td> </tr> <tr> <td>Ta</td> <td>请求在 haproxy 中保持活动的时间,这是在接收到的请求的第一个字节和发送的最后一个字节之间经过的总时间(以毫秒为单位)。</td> </tr> <tr> <td>status_code</td> <td>返回给客户端的 HTTP 状态代码。 <br/>这种状态通常由服务器设置,但是当服务器无法到达或其响应被 haproxy 阻止时也可以通过 haproxy 设置。</td> </tr> <tr> <td>bytes_read</td> <td>发送日志时,从服务器发送到客户端的总字节数。</td> </tr> <tr> <td>captured_request_cookie</td> <td>一个可选的“name = value”条目,指示客户端在请求中具有此cookie。 cookie 名称及其最大长度由前端配置中的“capture cookie”语句定义。 <br/>当该选项未设置时,该字段是单个破折号(’ - ‘)。</td> </tr> <tr> <td>termination_state</td> <td>会话结束时会话的条件。 <br/>这表示会话状态,哪一方导致会话结,以及什么原因(超时,错误,…)。</td> </tr> <tr> <td>actconn</td> <td>会话记录时进程上的并发连接总数。</td> </tr> <tr> <td>feconn</td> <td>会话记录时前端上的并发连接总数。</td> </tr> <tr> <td>beconn</td> <td>会话记录时由后端处理的并发连接的总数。</td> </tr> <tr> <td>srv_conn</td> <td>会话记录时服务器上仍然处于活动状态的并发连接总数。</td> </tr> <tr> <td>retries</td> <td>尝试连接到服务器时此会话遇到的连接重试次数。</td> </tr> <tr> <td>srv_queue</td> <td>在服务器队列中之前处理的请求的总数。</td> </tr> <tr> <td>backend_queue</td> <td>在后端的全局队列中之前处理的请求的总数。</td> </tr> <tr> <td>captured_request_headers</td> <td>由于在前端存在“捕获请求头”语句,在请求中捕获的标题列表。</td> </tr> <tr> <td>captured_response_headers</td> <td>由于在前端存在“捕获响应头”语句,在响应中捕获的标题列表。</td> </tr> <tr> <td>http_request</td> <td>完整的 HTTP 请求行,包括方法,请求和 HTTP 版本字符串。</td> </tr> </tbody> </table> Network: 如何获取来访者的真实 IP? /network/loadbalancer/faq/lb_get_real_ip/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/lb_get_real_ip/ <h2 id="方法一">方法一</h2> <p>在负载均衡器的监听器页面,点击<strong>操作</strong>&gt;<strong>修改</strong>,修改监听器设置,设置通过 HTTP 的头字段为 X-Forwarded-For 获取客户端的真实 IP,如下图。</p> <p><img src="../../_images/lb_get_real_ip_01.png" alt="image-2021051716362309"></p> <ul> <li> <p>该功能未开启时,通过 access.log 查看到客户端的 IP 地址实际上是负载均衡器节点 IP ,一般为198.19.x.x。</p> <p><img src="../../_images/lb_get_real_ip_04.png" alt="image-20210517181448847"></p> </li> <li> <p>该功能开启后,通过访问 access.log 查看的日志如下。</p> <p><img src="../../_images/lb_get_real_ip_05.png" alt="image-20210517181544091"></p> </li> </ul> <h2 id="方法二">方法二</h2> <p>通过开启透明代理(可能会导致内网请求失败),请在只提供公网服务(绑定了公网 IP)时开启,一般用于 TCP 协议的监听器。建议使用 tcpdump 命令抓包来获取真实 IP。</p> <p><img src="../../_images/lb_get_real_ip_02.png" alt="image-2021051716362309"></p> Network: 如何开启长连接? /network/loadbalancer/faq/lb_long_connection/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/lb_long_connection/ <h2 id="http-监听开启长连接">HTTP 监听开启长连接</h2> <p>如图,在 HTTP 监听器设置中,勾选上 <code>keep-alive</code> 即可。</p> <img src="../../_images/lb_long_connection01.png" alt="image" style="zoom:80%;" /> <h2 id="tcp-监听开启长连接">TCP 监听开启长连接</h2> <p>TCP 监听默认开启长连接。</p> <p>负载方式推荐使用<code>最少连接</code>:优先将请求发给拥有最少连接数的后端服务器,常用于长连接服务,例如数据库连接等服务。</p> Network: 使用 UDP 协议健康检查有什么注意事项? /network/loadbalancer/faq/udp_healthy_check_notes/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/udp_healthy_check_notes/ <p>UDP 方式会结合 ICMP Echo Request 和 UDP port probe 两种方式来检查,需注意:</p> <ul> <li>对于监听器为 UDP 端口组,且健康检查为 UDP 时,健康检查只会检测端口组的第一个端口。</li> <li>需保证后端能够正确响应 ICMP Echo Request(即返回 ICMP Echo Reply包,ICMP code: 0/0),并且能返回 ICMP Destination Port Unreachable 包,ICMP code: 3/3)。如果后端有加载安全组或者有其安全组策略,要保证其上行中相应的策略是放行的。</li> </ul> Network: 四层(TCP/UDP)健康检查出现异常 /network/loadbalancer/faq/tcp_check_fialed/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/tcp_check_fialed/ <p>本文介绍负载均衡器四层健康检查出现异常的解决方法。</p> <h2 id="问题现象">问题现象</h2> <p>负载均衡器上配置了如下图的基于四层方式的健康检查,但是健康检查结果显示为<code>不活跃</code>。</p> <img src="../../_images/tcp_check_faild.png" style="zoom:80%;" /> <h2 id="原因分析">原因分析</h2> <p>TCP 和 UDP 的健康检查是基于第四层协议进行的,所以只会探测到端口是否存活,并不会去检测业务是否正常。所以一般来说如果四层健康检查失败,可能有以下原因:</p> <ul> <li>后端服务器和负载均衡器之间的网络不通。</li> <li>后端服务器上的端口并没有存活。</li> </ul> <h2 id="排查方法">排查方法</h2> <ol> <li> <p><strong>检查负载均衡器上所配置的后端服务器的端口是否存活。</strong></p> <ol> <li> <p>在后端服务器上执行两个命令:</p> <pre tabindex="0"><code>telnet &lt;$ip&gt; &lt;port&gt; #此命令用来探测这台机器的80端口是否能够正常连接 </code></pre></li> <li> <p>如果上述命令执行失败的话,就需要检查后端业务是否正常运行,或者后端服务器监听的端口和负载均衡器上所配置的端口是否一致。</p> <p>以下排查过程可供您参考(以 nginx 为例)。</p> <pre tabindex="0"><code>root@web:~# systemctl status nginx.service #查看nginx状态是否正常 ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: inactive (dead) since Sun 2021-05-30 14:19:48 CST; 43s ago root@web:~# systemctl start nginx.service #启动nginx状态是否正常 root@web:~# ss -nutlp |grep 80 #检查80端口是否正常 root@web:~# ss -nutlp |grep nginx #检查nginx所启动的端口 tcp LISTEN 0 128 0.0.0.0:81 0.0.0.0:* users:((&#34;nginx&#34;,pid=24741,fd=6),(&#34;nginx&#34;,pid=24739,fd=6)) tcp LISTEN 0 128 [::]:81 [::]:* users:((&#34;nginx&#34;,pid=24741,fd=7),(&#34;nginx&#34;,pid=24739,fd=7)) root@web:~# vim /etc/nginx/sites-enabled/default #修改nginx端口,此处也可将负载均衡器配置的端口修改为81 root@web:~# systemctl restart nginx.service #重启nginx root@web:~# telnet 172.16.6.20 80 #测试端口连通性 Trying 172.16.6.20... Connected to 172.16.6.20. Escape character is &#39;^]&#39;. #出现此符号证明连接正常。 ^CConnection closed by foreign host. root@web:~# </code></pre></li> </ol> </li> <li> <p><strong>检查后端服务器和负载均衡器之间的网络连通性。</strong></p> <ol> <li> <p>在负载均衡器的详情页<strong>网络</strong>区域,找到<strong>内网IP</strong>,检查安全组中是否有放行这些 IP。</p> <img src="../../_images/slb_node_ip.png" style="zoom:80%;" /> </li> <li> <p>登录后端服务器检查 iptables 是否有对这些 IP 做限制。如果有则删除对应限制。</p> <pre tabindex="0"><code>root@web:~# ping 172.16.6.4 #可以看到此时ping slb的节点ip是不能通的。 PING 172.16.6.4 (172.16.6.4) 56(84) bytes of data. ^C --- 172.16.6.4 ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1011ms root@web:~# iptables -nL --line-number Chain INPUT (policy ACCEPT) num target prot opt source destination 1 DROP all -- 172.16.6.0/24 0.0.0.0/0 2 DROP all -- 192.19.0.0/16 0.0.0.0/0 Chain FORWARD (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination root@web:~# iptables -t filter -D INPUT 1 root@web:~# iptables -t filter -D INPUT 1 root@web:~# iptables -nL --line-number Chain INPUT (policy ACCEPT) num target prot opt source destination Chain FORWARD (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination root@web:~# ping 172.16.6.4 #可以看到此时ping slb的节点ip已经能通了 PING 172.16.6.4 (172.16.6.4) 56(84) bytes of data. 64 bytes from 172.16.6.4: icmp_seq=1 ttl=63 time=1.49 ms 64 bytes from 172.16.6.4: icmp_seq=2 ttl=63 time=1.49 ms </code></pre></li> </ol> </li> </ol> Network: 业务日志中出现“Connection reset by peer”的错误 /network/loadbalancer/faq/connection_peer/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/connection_peer/ <h2 id="问题现象">问题现象</h2> <p>负载均衡后端配置 TCP 服务端口后,后端业务日志中频繁出现类似如下网络连接异常的错误信息。首先可以通过抓包分析这条日志产生是否是负载均衡器的锁发出的请求导致,如果不是则需要检查其他地方配置是否有问题。本文主要分析由负载均衡器产生的问题。</p> <p><img src="../../_images/peer_reset.png" alt="img"></p> <h2 id="问题原因">问题原因</h2> <p>该问题和负载均衡的健康检查机制有关。由于 TCP 对上层业务状态无感知,同时,为降低负载均衡健康检查成本和对后端业务的冲击,负载均衡针对 TCP 协议服务端口的健康检查只会做简单的 TCP 三次握手,而后直接发送 RST 包断开 TCP 连接。</p> <p>简单的来说,四层健康检查,会对后端服务器发起一次请求,后端服务器的服务端口只要应答了负载均衡器则认为此次检查是成功的,就会主动关闭连接,并未进行业务层面上的数据交互,从而导致上层业务(例如 Java 连接池等)认为相应的连接是异常的。</p> <h2 id="解决方法">解决方法</h2> <p>对于以上情况主要有两种解决方法。</p> <ul> <li> <p>方法1:更换 TCP 协议为 HTTP 协议。</p> <p>此方案是将健康检查更换七层健康检查,会进行业务层面的数据交互,所以也需要后端服务提供相应的接口去供 LB 进行健康检查。</p> </li> <li> <p>方法2:在业务层面,对来自 LB 服务器 IP 地址段的相关请求做日志过滤,忽略相关错误信息。</p> <p>此方案仍旧是基于第四层的健康检查,因为业务日志中出现此报错就已经代表四层健康检查成功了,所这个报错本身就可以忽略。</p> </li> </ul> Network: 长连接和会话保持有什么关系? /network/loadbalancer/faq/long_cnet_session_hold/ Mon, 01 Jan 0001 00:00:00 +0000 /network/loadbalancer/faq/long_cnet_session_hold/ <p>长连接和会话保持没有必然联系。长连接是指在一个连接上可以连续发送多个数据包,在连接保持期间,如果没有数据包发送,需要双方发链路检测包。会话保持是指弹性负载均衡将属于同一个会话的请求都转发到同一个服务器进行处理。</p>