`
bailei120
  • 浏览: 11528 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

MyCat源码解读(1)Auth协议处理

阅读更多

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如何识别和处理读写请求,并智能地路由到相应的数据库。 再者,Mycat支持主从数据同步。当主数据库发生写操作时,Mycat会将变更同步到从数据库,确保数据的一致性。这部分源码涉及到了...

    Mycat1.6源码

    通过对源码的阅读,我们可以深入了解其工作流程和设计理念,例如,SQL解析模块使用了Antlr工具生成SQL解析树,事务处理模块则实现了2PC协议。 8. **插件系统** Mycat支持插件扩展,允许开发者自定义SQL解析、数据...

    mycat-server 1.6 源码包 可直接运行

    深入研究Mycat-Server 1.6的源码,可以帮助开发者理解其内部机制,比如连接管理、SQL解析、事务处理、负载均衡等模块。源码阅读有助于定制化开发和优化性能,例如针对特定业务场景调整分片策略,或者改进SQL执行效率...

    Mycat从入门到精通之Mycat源码分析.pptx

    ### Mycat从入门到精通之Mycat源码分析 #### 一、NIO源码分析 Mycat作为一个高性能的数据库中间件,在其架构设计上充分利用了Java NIO技术来提升性能。NIO(Non-blocking I/O)是非阻塞I/O的简称,通过采用非阻塞...

    Mycat2 v1.21-2022-4-7源码(Mycat2-1.21-2022-4-7.tar.gz)

    1. **Mycat2简介** Mycat2是在Mycat基础上的升级,旨在解决原有版本的一些问题并引入新的特性。它是一款基于Java开发的数据库中间件,主要功能包括数据库分片、读写分离、数据复制等,能够有效地提升数据库系统的...

    Mycat-Server-1.6(源码)

    1. **数据分片**:Mycat通过数据分片策略,将大数据分散存储在多个数据库实例上,从而实现水平扩展,提高数据库处理能力。分片策略包括范围分片、哈希分片、复合分片等,可以根据业务需求灵活选择。 2. **读写分离*...

    Mycat-server-1.6.7.6-release.jar 源码所需的pom.xml文件

    Mycat-server-1.6.7.6-release.jar 源码所需的pom.xml文件

    Mycat2 v1.21-2022-4-7源码(Mycat2-1.21-2022-4-7.zip)

    Mycat2 v1.21-2022-4-7源码(Mycat2-1.21-2022-4-7.zip)

    MyCat测试报告(单机MyCAT对比多机MyCAT)1

    当增加到三台MyCat时,无论使用哪种代理,QPS和TPS都有显著提升,说明在后端MySQL具备足够IO能力的情况下,增加MyCat节点能够有效提升系统处理能力。 表结构方面,测试用的sbtestX表采用InnoDB引擎,具有自动增长的...

    兼容高版本驱动的mycat1.6.6源码

    【标题】"兼容高版本驱动的mycat1.6.6源码"涉及的主要知识点是Mycat数据库中间件与MySQL驱动以及Druid连接池的兼容性问题。Mycat是一款开源的分布式数据库系统,它作为数据库中间件,用于解决大数据量、高并发场景下...

    Mycat-Server-master 源码、可直接在eclipse中调试

    《深入剖析Mycat-Server源码:Eclipse调试与Maven实践》 Mycat,作为一款开源的分布式数据库中间件,广泛应用于大数据环境下的高并发、高性能场景。其核心在于提供数据分片、读写分离以及负载均衡等功能,为大型...

    mycat1.6jar包反编译的源码

    《深入解析mycat1.6源码:一次技术探索之旅》 Mycat,作为一款开源的分布式数据库中间件,广泛应用于大型分布式系统中,它实现了数据分片、读写分离、故障切换等功能,为高并发、大数据量的场景提供了优秀的解决...

    Mycat-server-1.6

    Mycat是一款基于Java开发的开源数据库中间件,其主要功能是实现数据库的分布式处理,支持分库分表,提供读写分离、数据路由、故障切换等能力。Mycat通过将大表横向拆分为多个小表,分散到不同的数据库服务器上,从而...

    mycat2.0源码

    Mycat 2.0 预览版。 基于Nio实现,有效管理线程,解决高并发问题。 前后端共享buffer,支持全透传和半透传,极致提升内核性能,稳定性和兼容性。 功能特性 支持SQL92标准。 支持单库内任意sql。 支持读写...

    mycat1.6.5源码,分库分表,分布式

    【标题】"mycat1.6.5源码,分库分表,分布式"涉及到的是一个开源数据库中间件——Mycat,它主要用于解决大数据量下的高性能、高可用性问题,通过分库分表策略来分散数据库负载,实现数据的分布式处理。 【描述】中...

    Mycat从入门到精通视频教程

    Mycat跨分片聚合处理、Mycat跨分片JOIN、Mycat分布式事务 第6课 Mycat性能测试与调优 Mycat性能参数及调优 Mycat性能测试 第7课 Mycat高可用方案 读写分离机制 集群机制 高可靠性的几种生产方案 第8课 ...

    mycat修改源码扩展subTables 支持按月分表 $201701-? 配置

    基于MyCat1.6正式版的源码修改的,支持subTables的按月分表正则配置 subTables=“ tableName_$201701-?” subTableWay="BYMONTH" 表示从201701月份开始进行分表处理,?表示当前日期的月份,是动态的。只需配置开始...

    mycat从入门到跑路

    Mycat从入门到精通视频教程目录介绍: 第1课 Mycat前世今生 Mycat的历史、背后的团队、发展现状、RoadMap等 第2课 Mycat原理与入门 Mycat的原理、主要功能、配置和使用入门 第3课 Mycat故障排查指南 常见问题 日志...

    关系型数据的分布式处理系统MyCAT

    ### 关系型数据的分布式处理系统MyCAT:深入解析与应用 #### 1. MyCAT 概述 ##### 1.1 背景 随着信息技术的快速发展,传统的数据库技术面临着越来越大的挑战。特别是当数据库应用扩展到互联网级别时,集中式...

Global site tag (gtag.js) - Google Analytics