码出高效:Java开发手册-第1章(5)

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 本书源于影响了全球250万名开发工程师的《阿里巴巴Java开发手册》,作者静心沉淀,对Java规约的来龙去脉进行了全面而彻底的内容梳理。本书以实战为中心,以新颖的角度全面阐述面向对象理论,逐步深入地探索怎样成为一位优秀开发工程师。比如:如何驾轻就熟地使用各类集合框架;如何得心应手地处理高并发多线程问题;如何顺其自然地写出可读性强、可维护性好的优雅代码。 本书旁征博引、文风轻松,秉持“图胜于表,表胜于言”的理念,深入浅出地将计算机基础、面向对象思想、JVM探源、数据结构与集合、并发与多线程、单元测试等知识客观、立体地呈现出来。紧扣学以致用......

1.5.3 TCP 建立连接

      传输控制协议(Transmission Control Protocol,TCP),是一种面向连接、确保数据在端到端间可靠传输的协议。面向连接是指在发送数据前,需要先建立一条虚拟的链路,然后让数据在这条链路上“流动”完成传输。为了确保数据的可靠传输,不仅需要对发出的每一个字节进行编号确认,校验每一个数据包的有效性,在出现超时情况时进行重传,还需要通过实现滑动窗口和拥塞控制等机制,避免网络状况恶化而最终影响数据传输的极端情形。每个TCP 数据包是封装在IP 包中的,每一个IP 头的后面紧接着的是TCP 头,TCP 报文格式如图1-17 所示。

17.jpg

图1-17 TCP 报文格式

      协议第一行的两个端口号各占两个字节,分别表示了源机器和目标机器的端口号。这两个端口号与IP 报头中的源IP 地址和目标IP 地址所组成的四元组可唯一标识一条TCP 连接。由于TCP 是面向连接的,因此有服务端和客户端之分。需要服务端先在相应的端口上进行监听,准备好接收客户端发起的建立连接请求。当客户端发起第一个请求建立连接的TCP 包时,目标机器端口就是服务端所监听的端口号。比如广为人知的端口号——HTTP 服务的80 端口、HTTPS 服务的443 端口、SSH 服务的22 端口等。可通过netstat 命令列出机器上已建立的连接信息,其中包含唯一标识一条连接的四元组,以及各连接的状态等内容,如图1-18 所示,图中的红框代表端口号。

18.jpg

图1-18 IP 地址与端口信息

      协议第二行和第三行是序列号,各占4 个字节。前者是指所发送数据包中数据部分第一个字节的序号,后者是指期望收到来自对方的下一个数据包中数据部分第一个字节的序号。

      由于TCP 报头中存在一些扩展字段,所以需要通过长度为4 个bit 的头部长度字段表示TCP 报头的大小,这样接收方才能准确地计算出包中数据部分的开始位置。TCP 的FLAG 位由6 个bit 组成, 分别代表SYN、ACK、FIN、URG、PSH、RST,都以置1 表示有效。我们重点关注SYN、ACK 和FIN。SYN(Synchronize Sequence Numbers)用作建立连接时的同步信号;ACK(Acknowledgement)用于对收到的数据进行确认,所确认的数据由确认序列号表示;FIN(Finish)表示后面没有数据需要发送,通常意味着所建立的连接需要关闭了。

      TCP 报头中的其他字段可以阅读RFC793 来掌握,本书在此不加赘述。接下来重点分析TCP 中连接建立的原理。图1-19 展示了正常情形下通过三次握手建立连接的过程。A 与B 的机器标识并不是绝对意义上的服务器与客户端。发起请求的也可能是服务器,向另一台其他后端服务器发送TCP 连接请求。前者需要在后者发起连接建立请求时先打开某个端口等待数据传输,否则将无法正常建立连接。三次握手指的是建立连接的三个步骤:

  • A 机器发出一个数据包并将SYN 置 1,表示希望建立连接。这个包中的序列号假设是x 。
  • B 机器收到 A 机器发过来的数据包后,通过 SYN 得知这是一个建立连接的请求,于是发送一个响应包并将SYN 和ACK 标记都置1。假设这个包中的序列号是y ,而确认序列号必须是x +1,表示收到了A 发过来的SYN。在TCP 中,SYN 被当作数据部分的一个字节。
  • A 收到 B 的响应包后需进行确认,确认包中将 ACK 置 1,并将确认序列号设置为y +1,表示收到了来自B 的SYN。

19.jpg

图1-19 TCP 三次握手创建连接

      这里为什么需要第3 次握手?它有两个主要目的:信息对等和防止超时。先从信息对等角度来看,如表1-8 所示,双方只有确定4 类信息,才能建立连接。在第2 次握手后,从B 机器视角看还有两个红色的NO 信息无法确认。在第3 次握手后,B 机器才能确认自己的发报能力和对方的收报能力是正常的。

表1-8 TCP 三次握手待确认信息20.jpg

      连接三次握手也是防止出现请求超时导致脏连接。TTL 网络报文的生存时间往往都会超过TCP 请求超时时间,如果两次握手就可以创建连接,传输数据并释放连接后,第一个超时的连接请求才到达B 机器的话,B 机器会以为是A 创建新连接的请求,然后确认同意创建连接。因为A 机器的状态不是SYN_SENT,所以直接丢弃了B 的确认数据,以致最后只是B 机器单方面创建连接完毕,简要示意图如图1-20所示。

21.jpg

图1-20 两次握手导致的TCP 脏连接

      如果是三次握手,则B 机器收到连接请求后,同样会向A机器确认同意创建连接,但因为A 机器不是SYN_SENT 状态,所以会直接丢弃,B 机器由于长时间没有收到确认信息,最终超时导致连接创建失败,因而不会出现脏连接。根据抓包分析,呈现出三次握手请求过程,SYN+ACK 的应答,告诉A 机器期望下一个数据包的第一个字节序号为1,如图1-21 所示。

22.jpg

图1-21 TCP 三次握手抓包分析

      从编程的角度,TCP 连接的建立是通过文件描述符(File Descriptor,fd)完成的。通过创建套接字获得一个fd,然后服务端和客户端需要基于所获得的fd 调用不同的函数分别进入监听状态和发起连接请求。由于fd 的数量将决定服务端进程所能建立连接的数量,对于大规模分布式服务来说,当fd 不足时就会出现“open too many files”错误而使得无法建立更多的连接。为此,需要注意调整服务端进程和操作系统所支持的最大文件句柄数。通过使用ulimit -n 命令来查看单个进程可以打开文件句柄的数量。如果想查看当前系统各个进程产生了多少句柄,可以使用如下的命令:

lsof -n | awk '{print $2}'| sort|uniq -c |sort -nr|more

      执行结果如图1-22 所示,左侧列是句柄数,右侧列是进程号。lsof 命令用于查看当前系统所打开fd 的数量。在Linux 系统中,很多资源都是以fd 的形式进行读写的,除了提到的文件和TCP 连接,UDP 数据报、输入输出设备等都被抽象成了fd。

23.jpg

图1-22 文件句柄与进程ID 的对应关系

      想知道具体的PID 对应的具体应用程序是谁,使用如下命令即可:

ps -ax|grep 32764

      Java 进程示例如图1-23 所示。

24.jpg

图1-23 根据进程ID 查询具体进程

      TCP 在协议层面支持Keep Alive 功能,即隔段时间通过向对方发送数据表示连接处于健康状态。不少服务将确保连接健康的行为放到了应用层,通过定期发送心跳包检查连接的健康度。一旦心跳包出现异常不仅会主动关闭连接,还会回收与连接相关的其他用于提供服务的资源,确保系统资源最大限度地被有效利用。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
11天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的服装商城管理系统
基于Java+Springboot+Vue开发的服装商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的服装商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
33 2
基于Java+Springboot+Vue开发的服装商城管理系统
|
9天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的大学竞赛报名管理系统
基于Java+Springboot+Vue开发的大学竞赛报名管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的大学竞赛报名管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
23 3
基于Java+Springboot+Vue开发的大学竞赛报名管理系统
|
10天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的蛋糕商城管理系统
基于Java+Springboot+Vue开发的蛋糕商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的蛋糕商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
21 3
基于Java+Springboot+Vue开发的蛋糕商城管理系统
|
10天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的美容预约管理系统
基于Java+Springboot+Vue开发的美容预约管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的美容预约管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
21 3
基于Java+Springboot+Vue开发的美容预约管理系统
|
11天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的房产销售管理系统
基于Java+Springboot+Vue开发的房产销售管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的房产销售管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
25 3
基于Java+Springboot+Vue开发的房产销售管理系统
|
12天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的反诈视频宣传系统
基于Java+Springboot+Vue开发的反诈视频宣传系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的反诈视频宣传管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
41 4
基于Java+Springboot+Vue开发的反诈视频宣传系统
|
13天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的健身房管理系统
基于Java+Springboot+Vue开发的健身房管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的健身房管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
42 5
基于Java+Springboot+Vue开发的健身房管理系统
|
10天前
|
存储 网络协议 Java
Java NIO 开发
本文介绍了Java NIO(New IO)及其主要组件,包括Channel、Buffer和Selector,并对比了NIO与传统IO的优势。文章详细讲解了FileChannel、SocketChannel、ServerSocketChannel、DatagramChannel及Pipe.SinkChannel和Pipe.SourceChannel等Channel实现类,并提供了示例代码。通过这些示例,读者可以了解如何使用不同类型的通道进行数据读写操作。
Java NIO 开发
|
12天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的医院门诊预约挂号系统
基于Java+Springboot+Vue开发的医院门诊预约挂号系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的门诊预约挂号管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
33 2
基于Java+Springboot+Vue开发的医院门诊预约挂号系统
|
13天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的家具管理系统
基于Java+Springboot+Vue开发的家具管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的家具管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
32 2
基于Java+Springboot+Vue开发的家具管理系统
下一篇
无影云桌面