负载均衡设备位于客户端和真实服务器之间,一旦访问发生问题,在客户经过简单诊断后,负载均衡设备往往会成为首要被怀疑的对象。客户一般这样质疑:为什么我直接访问服务器没有问题,通过你的设备访问就不行了呢? 质疑的确实有道理,但大多数事情往往不是非一即二这样简单,有很多东西都在互相影响,这就使得真相迷雾重重。

某一天接到某客户报障,说是通过负载均衡设备访问某一业务的时候,页面无法打开或者等半天后只打开了部分页面,而客户端如果直接访问服务器,则可以顺利打开页面。

事情很明显,这中间肯定是有问题存在。登录负载均衡设备检查配置和log,并取一些内部诊断信息,没发现什么错误,只剩下唯一的办法:去客户现场抓包分析。

于是开始抓包,同时抓回了出现问题的服务的数据包和其他没有出现问题的服务的数据包。

经过分析,果然有所不同,下面是有问题的抓包内容(抓包1):

10.52.127.108为客户端地址

10.0.1.112为VIP

10.0.1.99为真实服务器地址

由于是以旁路方式部署,需要转换源IP, 10.0.1.123为经过负载均衡设备转换的客户端地址(snat地址)

负载均衡的VIP配置为HTTP模式,这表示负载均衡设备是以proxy的方式来处理连接,也就是对每个连接,客户端先跟负载均衡设备完成一个三次握手,然后负载均衡设备再跟真实服务器完成一个三次握手。

访问流程:

1) 10.52.127.108访问10.0.1.112

2) 负载均衡设备与客户端完成三次握手

3)然后负载均衡设备把源IP: 10.52.127.108转换成10.0.1.123向服务器10.0.1.99发起连接

4)服务器10.0.1.99与负载均衡设备完成三次握手。

下图是访问没有问题的服务的抓包内容(抓包2):

10.0.76.2为客户端地址

10.0.1.113为VIP

10.0.1.104为真实服务器地址

由于是以旁路方式部署,同样需要把客户端源IP转换为 10.0.1.123

访问流程跟抓包1相同。

仔细比较两个抓包内容,终于发现了差异出现在MSS值的协商上。

首先我们描述一下Client访问Server过程中MSS值的协行过程:

1) 客户端在向服务器发出SYN包的时候,会带上客户端设备可以接受的最大MSS值,意思是服务器发送到客户端的每个包的内容大小都不能大于这个值。

2) 服务器向客户端回复SYN,ACK包的时候,会比较客户端发来的MSS值和自己设定的MSS值,取两者的最小值作为自己可以接受的最大MSS值返回给客户端,意思是告诉客户端发送到服务器的每个包的内容大小都不能大于这个值。

3) 在实际的传输中,双方往往会取二者中的最小值作为双方互相发送的包大小的最大值。

基于以上通信流程我们来分析一下以上的两个抓包内容:

抓包1:

客户端发出SYN包,标明自己可接受的最大MSS值为1460,负载均衡设备回应自己可接受的MSS值为1400,协商成功后,双方交互的包大小不会大于1400。

负载均衡设备向服务器发出自己的可接受MSS值为1380,服务器回应自己可接受的MSS值120,协商成功后,负载均衡设备发给服务器的包就不能大于120了。

问题正是出在最后跟服务器协商出的大小为120的MSS值上。

我们看到客户端向负载均衡设备发出的第一个请求包大小为905字节,这个包大小不大于1400,所以负载均衡设备接收到了,接着负载均衡设备要把该请求发给选定的服务器10.0.1.99,由于服务器可接收的包不能大于120,所以负载均衡设备只能把客户端发来的请求包分成八个小包发送给服务器,然后一些不可控制的问题就出现了,客户端发出请求包后,需要等待应答,但由于负载均衡设备把一个包分解成8个包后,使得负载均衡设备跟服务器之间的交互时间变长,这个过程中客户端可能会超时重发请求包,而负载均衡设备跟服务器之间那八个小包的处理还可能出现丢包,重传,重装等问题。最关键是客户端在该连接的所有请求发完后如果是发送一个RST包来关闭连接,那么即使该连接上还有内容没传输完,该条连接也会关闭,由于一个请求包分成太多的小包传输,一旦发生客户端发出RST包的这种情况,基本上都会导致数据不能传输完毕,以上种种原因导致了页面不能打开或者不能完全打开的现象。

我们再分析抓包2:

客户端发出SYN包,标明自己可接受的最大MSS值为1460,负载均衡设备回应自己可接受的MSS值为1400,协商成功后,双方交互的包大小不会大于1400。这一点跟抓包1相同。

负载均衡设备向服务器发出自己的可接受最大MSS值为1380,服务器回应自己可接受的MSS值1380,协商成功后,所以双方会以1380的MSS值互相通信。

无论是客户端跟负载均衡设备还是负载均衡设备跟服务器之间,都是一个请求一个应答就能完成交互,不会发生要把包分割的现象,所以不会出现抓包1所出现的问题。

网络通信中由于MTU的设置不当引发的问题屡见不鲜,比如在存在ADSL设备的情况下,如果把设备的MTU设置成1500, 往往客户端的访问会出现问题,这是因为ADSL的PPPoE协议在MTU中占去8个字节,也就是ADSL的MTU最大值最多为1492, 如果客户端跟服务器设的很大,传输的数据包恰好大于1492字节,将导致数据包不能通过。  在程序设计中,程序所取MSS值往往是本机的MTU-40(TCP和IP头各占20个字节,MTU一般设成1500), 所以基本上所有设备所能接受的最大MSS值不可能会大于1500-40=1460, 那么再考虑到网络中可能会存在PPPoE,×××等设备会占用更多MTU字节,所以各家网络设备厂商提供的网络设备会进一步减小MSS值的设置,一般网络设备设定的MSS值大小为1400左右。

显然1400字节左右的MSS值是网络通信中的正常值,所以服务器返回一个120字节的MSS值这是一个不正常的现象,所以问题的根源在于服务器返回的MSS值不合适,那么这个值是谁返回的呢? 是服务器,也就是说该返回哪个值主动权在于服务器,所以我们诊断问题原因出在服务器上。

接下来的处理需要去检查服务器为什么返回这个值,跟负载均衡设备无关了。但仍然有追踪的价值,因为服务器并不是一直返回120这个值,而是有些时候会协商成1380,这时候访问是正常的,有些时候是返回120,这时候就自然访问不正常。

客户的服务器装的是HP操作系统,应用软件是Oracle的ebs,在我们把问题定位到了服务器后,客户也找了HP的工程师来检查和分析,但无法找出原因。

个人分析问题原因可能出现在如下几个方面:

1) HP操作系统或者网卡驱动程序关于MTU的定义存在可变值,或者

2) Oracle ebs的底层通信程序在MSS值的协商时,会根据一些条件改变MSS值

以上仅仅是猜测,因为没有以上两个厂家的资深工程师的深度参与,无法最终定位结果,所以该问题成为了一个疑案。

各位读了这篇文章的朋友,如果熟悉HP操作系统和Oracle ebs或者遇到有类似的case,欢迎一起来讨论一下。

(wyl)

转载于:https://blog.51cto.com/virtualadc/692407

负载均衡故障诊断:一个MSS值引发的疑案相关推荐

  1. 一个mss大小引发的思考

    最近收到一个某地区拨打电话失败的概率性问题,据测试部门的同事反馈,发生的概率为 1/10.即拨打10次电话,基本上就会出现一次,出现问题后,再次拨打又好了,没啥规律,没有必现路径,真是奇怪了.每次遇到 ...

  2. 负载均衡 一直跑一个服务器_终于把服务器负载均衡和客户端负载均衡讲清楚了...

    服务端负载均衡 我们常说的负载均衡都是指服务端负载均衡,服务端负载均衡又分为硬件负载均衡,软件负载均衡. 硬件负载均衡主要是在各服务器节点 前加上负载均衡的设备,如F5 软件负载均衡主要指的是在服务器 ...

  3. 负载均衡轮询算法和服务器性能,负载均衡算法

    对于要实现高性能集群,选择好负载均衡器很重要,同时针对不同的业务场景选择合适的负载均衡算法也是非常重要的. 一.负载均衡算法分类 任务平分类 负载均衡系统将收到的任务平均分配给服务器进行处理,这里的& ...

  4. 负载均衡解析与Nginx实战

    1. 负载均衡的概念 1.1 什么是负载均衡 Load Balancing,即负载均衡,是一种计算机技术,用来在多个计算机(计算机集群).网络连接.CPU.磁盘驱动器或其他资源中分配负载,以达到最优化 ...

  5. 负载均衡中使用 Redis 实现共享 Session

    最近在研究Web架构方面的知识,包括数据库读写分离,Redis缓存和队列,集群,以及负载均衡(LVS),今天就来先学习下我在负载均衡中遇到的问题,那就是session共享的问题. 一.负载均衡 负载均 ...

  6. nginx或httpd实现负载均衡tomcat(三)

    接博客nginx或httpd实现反向代理tomcat并实现会话保持(二) 实例四:使用httpd负载均衡后端tomcat服务 第一步:准备两个tomcat服务器节172.16.240.203 修改to ...

  7. 运维工程师必备之负载 均衡集群及LVS详解

    原文地址:运维工程师必备之负载 均衡集群及LVS详解作者:蚁巡运维平台 来源: chrinux 的BLOG 时间: 2013-07-01 14:00 此博文主要介绍集群和负载均衡的基本理论和类别,内容 ...

  8. 在Linux下用LVS和Ipvsadm做Web负载均衡

    在Linux下用LVS和Ipvsadm做Web负载均衡,如果想对负载均衡有一个全面.宏观上的理解,可以看:服务器负载均衡技术的原理及应用. 一.简介及环境配置 在Linux下用 LVS和Ipvsadm ...

  9. java 取绝对值_Java实现一致性哈希算法,并搭建环境测试其负载均衡特性

    实现负载均衡是后端领域一个重要的话题,一致性哈希算法是实现服务器负载均衡的方法之一,你很可能已在一些远程服务框架中使用过它.下面我们尝试一下自己实现一致性哈希算法. 一. 简述一致性哈希算法 这里不详 ...

最新文章

  1. 【Android游戏开发二十三】自定义ListView【通用】适配器并实现监听控件!
  2. 2019第十届蓝桥杯比赛总结(B组c/c++)
  3. [云炬创业学笔记]第一章创业是什么测试8
  4. Chrome的一点小问题
  5. PHP的curl实现get,post 和 cookie(几个实例)
  6. 【资料篇】你需要掌握SEO的8个常用知识点
  7. javascript小技巧(转)
  8. linux 查看手机硬件信息失败,linux下硬件信息的查看总结
  9. 有关SQL Server中日期的常见问题解答
  10. mds算法 java_对OAF开发中的MDS的初步研究(转)
  11. Java中的try/catch/finally
  12. 错误:created a ThreadLocal with key of type ……but failed to remove it when the web application was sto
  13. 统计学的Python实现-013:频度分布表
  14. Sentaurus Process Refinement Boxes
  15. 来啦!iphone ios免越狱,个性化修改微信提示音!
  16. vue-echart简单使用
  17. git报错:fatal: unable to access ‘...‘: Failed to connect to github port 443: Timed out
  18. 打通最后100米:苏宁小店如何成为家门口的“共享冰箱”
  19. grep指令与ps指令的详细使用说明
  20. 各大电商平台竞价比价API,实时监控类目大数据

热门文章

  1. questions in the wind
  2. 有向图的拓扑排序的理解和简单实现(Java)
  3. react生命周期-新增与替换
  4. js立即调用的函数表达式
  5. kvm之三:本地安装虚拟机
  6. hdu 1166 敌兵布阵
  7. php短信接口源码,比较简单,但也实用
  8. ASP 投票系统所用技术小结
  9. c++ uint32转为int_【转】用python将GBK编码文件转为UTF-8编码文件
  10. 神经网络的反向传导到底是在干什么?