负载均衡故障排错指南 (6)

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介:

负载均衡中的TCP协议

熟悉TCP协议的一些工作原理,是进行负载均衡故障排查的基础。因此,本文将带领大家了解有关TCP/IP协议的一些基础,并了解在增加了负载均衡之后,TCP/IP协议交互发生的一些变化。如果你已经对TCP协议了如指掌,你可以无视本文。

在负载均衡中,TCP可以说是最重要的协议了。因为,我们经常遇到的一些应用层协议,如:HTTP、HTTPS、FTP,全都跑在TCP协议之上。UDP虽然也很重要,但其协议交互相较于TCP来说,要简单得多。因此,让我们先来看看TCP的交互过程。

学习TCP协议中的几个关键

首先,我们必须明白,互联网协议的分层设计,是非常非常伟大的构想。如果不是这样,互联网根本不可能发展到今天如此复杂、如此丰富的境地。因此,我们要了解的第一点就是:TCP协议是运行在IP协议层之上的,是承载其他应用协议的基础。

其次,在平时进行负载均衡的故障排查时,在排除网络连通性问题之后,我们首先要搞清楚的,就是客户端与服务器之间是否成功建立了TCP连接。因此,第二个关键点:TCP协议是基于连接的协议——这一点是TCP与UDP的根本区别。也是导致TCP复杂性的根本原因。

最后,TCP协议看起来简单,了解了TCP三次握手建立连接以及连接拆除的两个FIN过程后,对于大多数TCP方面的故障,你都能从分析TCP交互过程中找到故障排查的思路。但是,TCP协议实际上很复杂。单单是与TCP协议相关的RFC就有几十个。因此,第三个关键点:还是那句老话,你对TCP协议的理解有多深,决定了你分析或解决问题的水平。

TCP的数据包结构

在了解TCP协议交换过程之前,我们首先需要简单的了解一下TCP数据帧的帧结构。

首先,TCP协议是封装在IP协议中的。剥去IP协议头部,紧接着就是TCP的头了。

   

在TCP协议中,有几个关键的字段是我们一定要搞明白的。搞不懂这几个字段的含义,那我们就无法解读采用类似wireshark这样的抓包工具捕获的数据了。

1) Source port number,发送这个数据包的客户端/服务器使用的端口(小心点!我可没说是客户端或服务器服务器端口啊,是发送该数据包所使用的端口)

2) Destination port number,接收这个数据包的客户端/服务器使用的端口

3) Sequence number和Acknowledgment number,用于确认是否收到了对方发送的数据。一般简称SYN number和ACK number

4) 数据包标记位,表示当前数据包类型的,一般情况下,我们经常会碰到以下几种:SYN、SYN+ACK、ACK、FIN、FIN+ACK、RST。

TCP状态转换图

简单的说,TCP建立连接的过程就像是打电话,你需要先拿起电话(系统获取Socket),拨个号码(发出建立连接的请求),对方接听(确认连接建立),当然,实际的过程会稍微有些区别。

下面这张图,摘自大名鼎鼎的 W. Richard Steven的互联网圣经《TCP/IP Illustrated, Volume 1: The Protocols》的英文版。国内有这本书的中文版,名叫《TCP/IP协议详解,卷1》。但是,如果你的英语还可以的话,非常建议你直接阅读英文版。因为中文版的翻译中充满了错误和误导。仅仅是这张TCP状态转换图就有多处翻译错误或不当的地方。有兴趣的童鞋可以分析比较一下,看看到底有哪些东西翻译得有问题。

想看懂上面这张TCP状态转换图,以下几个关键点是一定要搞清楚并铭记在心的:

1) 图下面的图例是一定要仔细阅读的:实线箭头代表客户端状态转换;虚线箭头代表服务器端状态转换。

2) recv表示客户端/服务器在收到该数据包时发生的状态变迁;send表示在客户端/服务器在发出某种数据包后发生状态变迁。

3) 整个TCP状态转换中最关键的有两个部分:连接建立和连接拆除。

4) TCP连接建立的过程俗称三次握手,是由客户端主动发起的;连接拆除可以由客户端或服务器主动发起,主动发起方在发出关闭连接的请求后,进入Active Close状态,而接收到关闭连接请求的一方则进入Passive close状态。

5) 主动发起TCP连接关闭的一方(进入Active close状态)会在双方确认关闭连接后,进入TIME_WAIT状态,并在2MSL时间之后,才能将连接删除。

了解这张图,我们才能更好的读懂我们从Linux或windows上看到的当前系统TCP/UDP连接状态。下面的例子是我从自己笔记本上抓到的当前系统连接状态,让我们看看当前我的笔记本上对外的连接都有哪些,分别是什么状态:

 

 
  1. C:\>netstat -an 
  2.  
  3. 活动连接 
  4.   
  5.  协议    本地地址               外部地址                状态 
  6.  TCP    127.0.0.1:5354         0.0.0.0:0              LISTENING 
  7.  TCP    127.0.0.1:5354         127.0.0.1:49167        ESTABLISHED 
  8.  TCP    127.0.0.1:27015        0.0.0.0:0              LISTENING 
  9.  TCP    127.0.0.1:49167        127.0.0.1:5354         ESTABLISHED 
  10.  TCP    127.0.0.1:49206        0.0.0.0:0              LISTENING 
  11.  TCP    127.0.0.1:52056        127.0.0.1:52057        ESTABLISHED 
  12.  TCP    127.0.0.1:52057        127.0.0.1:52056        ESTABLISHED 
  13.  TCP    127.0.0.1:52059        127.0.0.1:52060        ESTABLISHED 
  14.  TCP    127.0.0.1:52060        127.0.0.1:52059        ESTABLISHED 
  15.  TCP    192.168.0.25:139       0.0.0.0:0              LISTENING 
  16.  TCP    192.168.0.25:52444     119.147.45.221:443     ESTABLISHED 
  17.  TCP    192.168.0.25:53291     119.147.45.221:443     CLOSE_WAIT 
  18.  TCP    192.168.0.25:53556     128.241.217.208:80     TIME_WAIT 
  19.  TCP    192.168.0.25:53557     128.241.217.193:80     TIME_WAIT 
  20.  TCP    192.168.0.25:53568     172.16.16.8:80         SYN_SENT 

首先,我的笔记本上有几个侦听状态的端口(状态为LISTENING),比如:192.168.0.25上的139端口。其它客户端可以尝试与我笔记本上的139端口建立连接。

其次,有几个已经建立的TCP连接(状态为ESTABLISHED),从192.168.0.25的52444端口到119.147.45.221的443端口。还有几个正在关闭的连接,比如:从192.168.0.25的53291端口到119.147.45.221的443端口。

另外,大家可能还注意到,有两种不同的连接关闭的状态:CLOSE_WAIT和TIME_WAIT。大家可以先参照上面的TCP状态转换图来看看这两种状态有什么区别。后文中还有说明。

最后,还有一个正在建立的连接(SYN_SENT),从192.168.0.25的53568端口到172.16.16.8的80端口,发出了SYN,正在等待SYN ACK。

TCP连接建立及拆除过程

上图是一个典型的TCP连接建立和拆除的过程,此外,我图中增加了TCP状态转换的过程,大家可以与前面的TCP状态转换图对照着看。从这张图中,我们可以更清楚的看到客户端与服务器连接建立和拆除的各阶段。

TCP连接建立的过程:

1)客户端打开一个连接,并向目标服务器发送SYN,进入SYN_SENT状态;

2)服务器收到客户端的SYN,并向客户端返回SYN+ACK,进入SYN_RCVD状态;

3)客户端向服务器返回ACK,确认连接建立,此时客户端进入ESTABLISHED状态;服务器收到该ACK包后,也进入ESTABLISHED状态。

此时,客户端和服务器完成TCP三次握手,建立TCP连接。需要注意的是,在这整个交互的过程中,客户端需要使用相同的IP地址及端口号,与相同的服务器地址和端口号进行交互。

在客户端/服务器完成数据的传输之后,任何一方都可主动关闭连接。

TCP连接拆除的过程:

1)客户端(或服务器)向对端发送FIN,要求主动关闭该TCP连接。主动关闭连接方进入FIN1_WAIT状态(在这里,我们简称主动关闭连接的一方为A)。

2)对端(被动关闭连接的一方,我们简称P)收到FIN后,会发送ACK确认,进入CLOSE_WAIT状态;而A收到该ACK后,会进入FIN2_WAIT状态。

3)如果P确认数据已经发送完毕,连接可以关闭,那么P也会向A发送FIN,此时,P进入LAST_ACK状态。

4)A收到FIN之后,会进入TIME_WAIT状态,并向P发送ACK确认收到该FIN包。此时,A上的该连接并不会直接删除,而是等待2MSL时间后才会删除该连接。

5)P收到最后的一个ACK后,确认连接关闭,进入CLOSED状态,从本地会话表中删除该会话信息。

通常情况下,我们需要仔细的了解TCP建立会话的过程中每个数据包的作用和意义,而对于TCP连接拆除的过程,一般都不会太过于关注。但是,如果你在某些情况下需要进行负载均衡的性能测试,那么,这个过程就完全不能忽略了。至于原因,我们以后再说。

Telnet——验证TCP连接的简单工具

通常情况下,我们可以利用Telnet来验证TCP连接是否能够成功建立,即客户端与服务器是否能够成功的进行三次握手进入TCP的ESTABLISHED状态。

默认情况下,Linux、Windows XP等操作系统默认都会有Telnet这个程序,但是对于Windows 7,你要小心一点,这个程序变成了选装程序了。

在命令行下输入telnet x.x.x.x port,(x.x.x.x代表你要连接的地址,port代表你要连接的服务器的端口号)系统会提示正在连接到x.x.x.x地址。

 

  

如果telnet能够成功的建立TCP连接,命令行提示符会清空,或者显示一些文字。命令行窗口可以允许你输入一些命令与远端进行交互。

如果telnet无法成功的建立TCP连接,在经过几次SYN重传之后,系统会提示“无法打开到主机的连接”

 



本文转自 virtualadc 51CTO博客,原文链接:http://blog.51cto.com/virtualadc/796001

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
5月前
|
消息中间件 运维 负载均衡
【Kafka】Kafka 实现负载均衡与故障转移
【4月更文挑战第5天】【Kafka】Kafka 实现负载均衡与故障转移
|
1月前
|
负载均衡 网络协议 Unix
Nginx负载均衡与故障转移实践
Nginx通过ngx_http_upstream_module模块实现负载均衡与故障转移,适用于多服务器环境。利用`upstream`与`server`指令定义后端服务器组,通过`proxy_pass`将请求代理至这些服务器,实现请求分发。Nginx还提供了多种负载均衡策略,如轮询、权重分配、IP哈希等,并支持自定义故障转移逻辑,确保系统稳定性和高可用性。示例配置展示了如何定义负载均衡设备及状态,并应用到具体server配置中。
|
2月前
|
消息中间件 负载均衡 Kafka
Kafka 实现负载均衡与故障转移:深入分析 Kafka 的架构特点与实践
【8月更文挑战第24天】Apache Kafka是一款专为实时数据处理和流传输设计的高性能消息系统。其核心设计注重高吞吐量、低延迟与可扩展性,并具备出色的容错能力。Kafka采用分布式日志概念,通过数据分区及副本机制确保数据可靠性和持久性。系统包含Producer(消息生产者)、Consumer(消息消费者)和Broker(消息服务器)三大组件。Kafka利用独特的分区机制实现负载均衡,每个Topic可以被划分为多个分区,每个分区可以被复制到多个Broker上,确保数据的高可用性和可靠性。
45 2
|
5月前
|
域名解析 缓存 运维
【域名解析DNS专栏】DNS解析策略:如何实现负载均衡与故障转移
【5月更文挑战第23天】DNS在互联网中扮演关键角色,将域名转换为IP地址。本文探讨DNS的负载均衡和故障转移技术,以增强服务可用性和性能。负载均衡包括轮询(简单分配流量)和加权轮询(按服务器处理能力分配)。故障转移通过主备策略和TTL值实现快速切换,确保服务连续性。实践案例展示了在电商网站如何应用这些策略。DNS策略优化可提升网站速度和稳定性,借助云服务和智能工具,DNS管理更加高效。
452 1
【域名解析DNS专栏】DNS解析策略:如何实现负载均衡与故障转移
|
4月前
|
负载均衡 算法 应用服务中间件
解密Nginx负载均衡:实现流量分发与故障转移
解密Nginx负载均衡:实现流量分发与故障转移
162 0
|
5月前
|
负载均衡 算法 应用服务中间件
解密Nginx负载均衡:实现流量分发与故障转移
解密Nginx负载均衡:实现流量分发与故障转移
133 1
|
5月前
|
负载均衡 算法 Nacos
【Ribbon实现客户端负载均衡和故障转移】—— 每天一点小知识
【Ribbon实现客户端负载均衡和故障转移】—— 每天一点小知识
211 0
|
SQL 存储 分布式计算
Flume学习---2、Flume进阶(事务)、负载均衡、故障转移、聚合
Flume学习---2、Flume进阶(事务)、负载均衡、故障转移、聚合
|
监控 负载均衡
Flume学习---2、Flume进阶(事务)、负载均衡、故障转移、聚合(二)
Flume学习---2、Flume进阶(事务)、负载均衡、故障转移、聚合(二)
|
SQL 存储 分布式计算
Flume学习---2、Flume进阶(事务)、负载均衡、故障转移、聚合(一)
Flume学习---2、Flume进阶(事务)、负载均衡、故障转移、聚合(一)