作者:路路

热爱技术、乐于分享的技术人,目前主要从事数据库相关技术的研究。

本文来源:原创投稿

*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

前言

对于计算机学科来说,计算机网络相关知识的重要性不言而喻。平时我们框架用的多了,对于底层网络 IO 的处理关注的并不算多(如果不让你用 Spring,你还能写出个 Web 接口吗?),但对于中间件以及框架的开发者来说,网络 IO 的处理却是最需要关注的地方。

DBLE 的网络模块没有用任何框架,完全是通过原生 JDK 纯手写的。研读 DBLE 网络模块的源码,能够让你对网络 IO 的处理有更进一步的理解。为什么连接 DBLE 能够像连接 MySQL 一样?为什么 DBLE 的性能能够如此高?希望通过本系列文章,能够帮助大家对DBLE的网络模块有更深入的了解,更进一步,希望能够帮助大家对高性能网络 IO 有更深入的了解。

本篇作为 《DBLE 网络模块源码解析》的第一篇,主要讲讲网络 IO 的基础知识。

一、TCP/IP 协议栈

TCP/IP 协议在一定程度上参考了 OSI 的体系结构。OSI 模型共有七层,从下到上分别是物理层、数据链路层、网络层、运输层、会话层、表示层和应用层。但是这显然是有些复杂的,所以在 TCP/IP 协议中,它们被简化为了四个层次,从下到上依次是链路层、网络层、传输层和应用层。

不同层之间的数据封装如下图所示:

TCP/IP 协议栈不同层之间的数据封装

从上图可以看出上一层的协议数据都是作为下一层协议的消息体来传输的。所以协议从上到下,是一层一层封装的结构。

二、MySQL 协议

MySQL 协议在 TCP/IP 协议栈中是处于应用层这一层。从而能够知道 MySQL 协议数据是作为 TCP 协议中的消息体部分来传输的。

因为 TCP 为面向流的协议,没有界限,会存在粘包拆包问题,需要在应用层解决。常见的解决方法有:

1. 消息定长,例如每个报文的大小为固定长度 100 字节,如果不够,空位补空格;

2. 在包尾增加回车换行符进行分割,例如 FTP 协议;

3. 将消息分为消息头和消息体,消息头中包含表示消息总长度(或者消息体长度)的字段;

4. 更复杂的应用层协议。

MySQL 协议是通过消息定长和在消息头中包含消息体长度字段的方法来解决 TCP 粘包问题的。如下图所示:

https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_packets.html

MySQL协议

连接 DBLE 既然能像连接 MySQL 一样,那 DBLE 一定要能够处理 MySQL 的数据包,如何处理这些数据包在代码里都有体现,我将在网络模块源码解析里详细讲解 DBLE 对于 MySQL 数据包的处理。

三、BIO 与 NIO

DBLE 性能能够如此之高,与它的高性能网络 IO 处理离不开关系。DBLE 中处理前端客户端连接及后端 MySQL 数据库连接都使用了 NIO 的方式,即 IO 多路复用技术

在网络连接数较少的情况下通过 BIO+ 多线程的方式也能够比较快速的处理请求,但随着连接数的增多,线程间的切换带来的性能损耗将大于多线程处理带来的性能提升,从而导致整体性能下降。

而 NIO 即 IO 多路复用技术,能够通过少量线程管理更多的连接。NIO 不会为每个连接创建一个处理线程,而只是在连接有数据的时候进行处理。NIO 再加上请求数据处理异步化,是 DBLE 高性能的秘密。

下期预告

本篇文章为 DBLE 网络模块源码解析的第一篇,主要介绍了关于网络 IO 的一些基础知识。包括 TCP/IP 协议栈、应用层 MySQL 协议、BIO 和 NIO 相关知识,为后面的源码解析做个铺垫,下一篇将从源码角度详细讲解 DBLE 的网络处理逻辑,希望能够对大家有所帮助。