前言
在上一篇博客中,为了解释ThreadLocal的应用场景,所以提到了JDBC
中的connection
。用过的朋友们一定熟悉下面的代码。具体就是先获取一个connnection,然后在connection中进行CURD。或者是基于ORM
框架如hibernate
、Mybatis
,但其实他们的底层都是基于mysql-connector-java.jar
。
很多时候我们并不清楚程序是如何和数据库进行交互的,比如简单的查询命令,程序是如何从MySQL中获取的呢?这个就是我这篇博客的主题,我会简单解释一下MySQL的网络通信协议,以及所需的技术栈。
原本想在网上找一下有没有类似的轮子,发现多数是将jdbc重新分装一些,本质使用的还是Java中实现好的connector。所以在后续的博客中根据协议去实现自己的connector.jar
MySQL连接方式
根据网上查到资料,MySQL目前有五种连接方式,分别是TCP/IP,TLS/SSL,Unix Sockets,Shared Memory,Named pipes,下面我们就来看看这五种的区别:
方式 | 默认开启 | 支持系统 | 只支持本机 | 如何开启 | 参数配置 |
---|---|---|---|---|---|
TCP/IP | 是 | 所有系统 | 否 | –skip-networking=yes/no. | –port –bind-address |
TLS/SSL | 是 | 所有系统(基于TCP/IP)之上 | 否 | –ssl=yes/no. | –ssl-* options |
Unix Sockets | 是 | 类Unix系统 | 是 | 设置–socket= |
–socket=socket path |
Shared Memory | 否 | Windows系统 | 是 | –shared-memory=on/off. | –shared-memory-base-name= |
Named pipes | 否 | Windows系统 | 否 | –enable-named-pipe=on/off. | –socket= |
首先看一下Unix Sockets和Shared Memory都是只支持本机的,所以如果你的程序和数据库是在一台机子的,就可以考虑这两种协议。
这两种协议我也不是很清楚,所以本文是基于我比较熟悉的TCP/IP协议。
MySQL通信协议
借网上一张图,简单的给大家解释一下MySQL通信过程中数据包。
用户发送CRUD操作给数据库的数据包过程:
- 首先Client先与Server通过TCP三次握手建立连接
- 建立连接之后,Server发送Handshake数据包给Client,Handshake含有数据库的版本、协议版本、用于后期加密的Salt等。
- Client接收到Server的Handshake包之后,解析其中数据,最主要是获得Salt,然后把用户名、密码(利用salt+sha1进行加密)、schema(要操作的数据库名)等信息打包成一个AuthPacket,用来认证请求。
- Server接受到AuthPacket之后,对其的身份进行验证,验证成功发送一个OK Packet。否则发送Error Packet。
- Client接受到OK Packet之后就发送Query Packet给Server。
- Server返回结果查询的,将Result Packet返回给Client。
- Client解析Result Packet完毕,发送Request Quit。
- 四次握手断开连接。
上述是一次Query数据库的过程,其中涉及到数据包,后面将会用WireShark
来详细解释上诉包的数据结构。
技术栈
有了上面的铺垫,我想你们大致也有了一个思路了。这里可以利用Socket或者NIO来实现数据库的通信。然后通过了解MySQL的网络协议数据包的结构,用WireShark来分析,分析之后打包发送。
其中wireShark和网络协议是这块技术的核心。另外编程中涉及到一些加密的皮毛,进制位上的转换的细节等,这写在后面会详细的解释。
下一篇主要是针对wireShark的使用,以及MySQL网络协议数据包的解析。这两部分结合一起说明效果会更好。