MyCat如何处理认证Auth协议
MyCat Server的前世今生本人就不做阐述了,能看到这篇文章的人,应该已经了解了。
作为Mysql的中间件,Mycat有两种连接,一种是让用户看起来是用Mysql的,处理Mysql请求的前端连接FrontendConnection。另外一种,是实际与后端Mysql物理库交换数据的后端连接BackendConnection。
前端连接,是用户与mycat沟通的桥梁。
我使用的客户端是mysql.exe
不管你是用Mysql的图形界面工具,还是用Mysql的命令行工具。如mysql.exe,在进行mysql -u username -ppassword -Pport -hHost的时候。第一步要做的就是给Mysql或者Mycat发送connect请求。
Mycat处理Auth请求和Mysql处理请求的过程并没有什么区别。本人仅就Mycat处理的相关过程,即从代码角度做简单描述。
传统的Mysql认证协议过程如下:
Client Server | handshake | |<-------------------| | authentication | |------------------->| | auth result | |<-------------------| | |
Mycat模拟的就是一个MysqlServer,故而与Mysql的协议过程相同
public void register(Selector selector) throws IOException { super.register(selector); if (!isClosed.get()) { // 生成认证数据 byte[] rand1 = RandomUtil.randomBytes(8); byte[] rand2 = RandomUtil.randomBytes(12); // 保存认证数据 byte[] seed = new byte[rand1.length + rand2.length]; System.arraycopy(rand1, 0, seed, 0, rand1.length); System.arraycopy(rand2, 0, seed, rand1.length, rand2.length); this.seed = seed; // 发送握手数据包 HandshakePacket hs = new HandshakePacket(); hs.packetId = 0; hs.protocolVersion = Versions.PROTOCOL_VERSION; hs.serverVersion = Versions.SERVER_VERSION; hs.threadId = id; hs.seed = rand1; hs.serverCapabilities = getServerCapabilities(); hs.serverCharsetIndex = (byte) (charsetIndex & 0xff); hs.serverStatus = 2; hs.restOfScrambleBuff = rand2; hs.write(this); }
上面代码片段,是用户发出连接请求后,MyCatServer accept连接,立即发出的握手包。
这里插一句,MycatServer的Acceptor,使用NIO框架,在每一个accept的请求到来后,立即注册其到Read事件中。
前端连接FrontedConnection继承了父类register的同时,还将握手包送发出去了。
MyCatserver给客户端发送的HandshakePacket中,包含了
packetId:包的ID
threadid:发送此包的线程id
seed:加密数据用的byte[]的前半部分
serverCapabilities:服务端属性
serverCharsetIndex:服务端字符集
serverStatus:服务端状态
restOfScrambleBuff:加密数据用的byte[]后半部分
客户端收到握手包之后,会将用户名,以及用seed加密后的密码,还有字符集,数据库等等连接参数发送一个认证包过来。就在mysql -u username -ppassword -Pport -hHost执行命令并在Tcp连接建立后。
在MyCat中,处理这个认证数据包AuthPacket的是FrontendConnection,FrontendConnection在构造的时候首先绑定了一个数据处理的Handler--FrontendAuthenticator
public FrontendConnection(SocketChannel channel) { super(channel); Socket socket = channel.socket(); this.host = socket.getInetAddress().getHostAddress(); this.port = socket.getPort(); this.localPort = socket.getLocalPort(); this.handler = new FrontendAuthenticator(this); }
当客户端发送Auth认证信息过来后,MyCat通过FrontendConnection取得数据,并将数据异步交给handler处理。
if (data[4] == MySQLPacket.COM_QUIT) { this.getProcessor().getCommands().doQuit(); this.close("quit cmd"); return; } // 异步处理前端数据 // processor.getHandler().execute(new Runnable() processor.getExecutor().execute(new Runnable() { @Override public void run() { try { handler.handle(data); } catch (Throwable t) { error(ErrorCode.ERR_HANDLE_DATA, t); } } });
此时,刚建立连接的FrontendConnetion持有的是FrontendAuthenticator的实例handler
handler首先用户密码的正确性。查找当前配置的用户表中有误此用户
checkUser(String user, String host)
然后,用发送给客户端的seed做了密码加密,并和客户端的进行比对:
encryptPass = SecurityUtil.scramble411(pass.getBytes(), source.getSeed());
然后检查数据库是否存在checkSchema(String database, String user)
当一切检查完毕后,向客户端发送Ok数据包。
protected void success(AuthPacket auth) { source.setAuthenticated(true); source.setUser(auth.user); source.setSchema(auth.database); source.setCharsetIndex(auth.charsetIndex); source.setHandler(new FrontendCommandHandler(source)); if (LOGGER.isInfoEnabled()) { StringBuilder s = new StringBuilder(); s.append(source).append('\'').append(auth.user).append("' login success"); byte[] extra = auth.extra; if (extra != null && extra.length > 0) { s.append(",extra:").append(new String(extra)); } LOGGER.info(s.toString()); } ByteBuffer buffer = source.allocate(); source.write(source.writeToBuffer(AUTH_OK, buffer)); }
客户端收到此包后,就可以发送各种sql语句,进行数据库操作了。在上面我们也看到了
前端连接也绑定了新的Handler--FrontendCommandHandler, 用于处理各种sql语句类型。进行数据处理分发。
笔者第一次写blog,此次的blog也是自己阅读MyCat代码的一次笔记。 主要从代码角度介绍了MyCat如何模仿MysqlServer进行Auth认证,具体的Auth包协议格式,网上已经有不少博文有描述。
后续将继续就MyCat,在阅读代码的过程中,记下自己的理解。与大家互相探讨。
版权声明:本文为博主原创文章,未经博主允许不得转载。
相关推荐
Mycat源码分析Mycat源码分析Mycat源码分析Mycat源码分析Mycat源码分析
在源码中,我们可以研究Mycat如何识别和处理读写请求,并智能地路由到相应的数据库。 再者,Mycat支持主从数据同步。当主数据库发生写操作时,Mycat会将变更同步到从数据库,确保数据的一致性。这部分源码涉及到了...
通过对源码的阅读,我们可以深入了解其工作流程和设计理念,例如,SQL解析模块使用了Antlr工具生成SQL解析树,事务处理模块则实现了2PC协议。 8. **插件系统** Mycat支持插件扩展,允许开发者自定义SQL解析、数据...
深入研究Mycat-Server 1.6的源码,可以帮助开发者理解其内部机制,比如连接管理、SQL解析、事务处理、负载均衡等模块。源码阅读有助于定制化开发和优化性能,例如针对特定业务场景调整分片策略,或者改进SQL执行效率...
### Mycat从入门到精通之Mycat源码分析 #### 一、NIO源码分析 Mycat作为一个高性能的数据库中间件,在其架构设计上充分利用了Java NIO技术来提升性能。NIO(Non-blocking I/O)是非阻塞I/O的简称,通过采用非阻塞...
1. **Mycat2简介** Mycat2是在Mycat基础上的升级,旨在解决原有版本的一些问题并引入新的特性。它是一款基于Java开发的数据库中间件,主要功能包括数据库分片、读写分离、数据复制等,能够有效地提升数据库系统的...
1. **数据分片**:Mycat通过数据分片策略,将大数据分散存储在多个数据库实例上,从而实现水平扩展,提高数据库处理能力。分片策略包括范围分片、哈希分片、复合分片等,可以根据业务需求灵活选择。 2. **读写分离*...
Mycat-server-1.6.7.6-release.jar 源码所需的pom.xml文件
Mycat2 v1.21-2022-4-7源码(Mycat2-1.21-2022-4-7.zip)
当增加到三台MyCat时,无论使用哪种代理,QPS和TPS都有显著提升,说明在后端MySQL具备足够IO能力的情况下,增加MyCat节点能够有效提升系统处理能力。 表结构方面,测试用的sbtestX表采用InnoDB引擎,具有自动增长的...
【标题】"兼容高版本驱动的mycat1.6.6源码"涉及的主要知识点是Mycat数据库中间件与MySQL驱动以及Druid连接池的兼容性问题。Mycat是一款开源的分布式数据库系统,它作为数据库中间件,用于解决大数据量、高并发场景下...
《深入剖析Mycat-Server源码:Eclipse调试与Maven实践》 Mycat,作为一款开源的分布式数据库中间件,广泛应用于大数据环境下的高并发、高性能场景。其核心在于提供数据分片、读写分离以及负载均衡等功能,为大型...
《深入解析mycat1.6源码:一次技术探索之旅》 Mycat,作为一款开源的分布式数据库中间件,广泛应用于大型分布式系统中,它实现了数据分片、读写分离、故障切换等功能,为高并发、大数据量的场景提供了优秀的解决...
Mycat是一款基于Java开发的开源数据库中间件,其主要功能是实现数据库的分布式处理,支持分库分表,提供读写分离、数据路由、故障切换等能力。Mycat通过将大表横向拆分为多个小表,分散到不同的数据库服务器上,从而...
Mycat 2.0 预览版。 基于Nio实现,有效管理线程,解决高并发问题。 前后端共享buffer,支持全透传和半透传,极致提升内核性能,稳定性和兼容性。 功能特性 支持SQL92标准。 支持单库内任意sql。 支持读写...
【标题】"mycat1.6.5源码,分库分表,分布式"涉及到的是一个开源数据库中间件——Mycat,它主要用于解决大数据量下的高性能、高可用性问题,通过分库分表策略来分散数据库负载,实现数据的分布式处理。 【描述】中...
Mycat跨分片聚合处理、Mycat跨分片JOIN、Mycat分布式事务 第6课 Mycat性能测试与调优 Mycat性能参数及调优 Mycat性能测试 第7课 Mycat高可用方案 读写分离机制 集群机制 高可靠性的几种生产方案 第8课 ...
基于MyCat1.6正式版的源码修改的,支持subTables的按月分表正则配置 subTables=“ tableName_$201701-?” subTableWay="BYMONTH" 表示从201701月份开始进行分表处理,?表示当前日期的月份,是动态的。只需配置开始...
Mycat从入门到精通视频教程目录介绍: 第1课 Mycat前世今生 Mycat的历史、背后的团队、发展现状、RoadMap等 第2课 Mycat原理与入门 Mycat的原理、主要功能、配置和使用入门 第3课 Mycat故障排查指南 常见问题 日志...
### 关系型数据的分布式处理系统MyCAT:深入解析与应用 #### 1. MyCAT 概述 ##### 1.1 背景 随着信息技术的快速发展,传统的数据库技术面临着越来越大的挑战。特别是当数据库应用扩展到互联网级别时,集中式...