用java8基于vert.x3 快速实现一个最简单的mysql代理服务器,只需要5分钟时间。

什么是mysql 代理?

mysql代理是介于client端和mysql服务端中间层服务,如下图所示:

这里写图片描述

为什么要使用代理?

大部人都知道使用代理的好处,毕竟,随着互联网越来越普及,互联网系统越来越庞大、复杂,性能要求越来越高,为了让整个系统具有更好的扩展性、更高的性能、解藕等多种特性,在数据库层面引入代理层是目前互联网系统常见的架构设计方案。总的来说,在数据库层面引入代理会带来以下好处:

  • 将不同类型的请求分发的不同的server以此实现读写分离、负载均衡。
  • 来自不同客户端的请求分发到不同的server实现后端多租户数据库服务,当然,类似的原理还可以实现分库分表、一个请求写到多个server或者不同的源端如消息队列。
  • 监控统计客户端的请求情况,请求分布统计、请求类型等,以此来优化数据库的使用。
  • 总之,可以实现你想要的诸多功能。

如何用java快速实现一个最简单的代理呢?

首先,准备开发工具套件,我们并不会引入过多工具包,仅仅需要:

  • java8
  • vert.x 3

如果你是用maven做为项目管理工具,请将vert.x 3引入:

io.vertx vertx-core 3.3.2

代码实现:

package com.maxleap.mysqlproxy;import io.vertx.core.AbstractVerticle;import io.vertx.core.Vertx;import io.vertx.core.logging.Logger;import io.vertx.core.logging.LoggerFactory;import io.vertx.core.net.NetClient;import io.vertx.core.net.NetServer;import io.vertx.core.net.NetSocket;/** * @author sneaky * @since 1.0.0 */public class MysqlProxyServer { private static final Logger logger = LoggerFactory.getLogger(MysqlProxyServer.class); public static void main(String[] args) { Vertx.vertx().deployVerticle(new MysqlProxyServerVerticle()); } public static class MysqlProxyServerVerticle extends AbstractVerticle { private final int port = 3306; private final String mysqlHost = "10.10.0.6"; @Override public void start() throws Exception { NetServer netServer = vertx.createNetServer();//创建代理服务器 NetClient netClient = vertx.createNetClient();//创建连接mysql客户端 netServer.connectHandler(socket -> netClient.connect(port, mysqlHost, result -> { //响应来自客户端的连接请求,成功之后,在建立一个与目标mysql服务器的连接 if (result.succeeded()) { //与目标mysql服务器成功连接连接之后,创造一个MysqlProxyConnection对象,并执行代理方法 new MysqlProxyConnection(socket, result.result()).proxy(); } else { logger.error(result.cause().getMessage(), result.cause()); socket.close(); } })).listen(port, listenResult -> {//代理服务器的监听端口 if (listenResult.succeeded()) { //成功启动代理服务器 logger.info("Mysql proxy server start up."); } else { //启动代理服务器失败 logger.error("Mysql proxy exit. because: " + listenResult.cause().getMessage(), listenResult.cause()); System.exit(1); } }); } } public static class MysqlProxyConnection { private final NetSocket clientSocket; private final NetSocket serverSocket; public MysqlProxyConnection(NetSocket clientSocket, NetSocket serverSocket) { this.clientSocket = clientSocket; this.serverSocket = serverSocket; } private void proxy() { //当代理与mysql服务器连接关闭时,关闭client与代理的连接 serverSocket.closeHandler(v -> clientSocket.close()); //反之亦然 clientSocket.closeHandler(v -> serverSocket.close()); //不管那端的连接出现异常时,关闭两端的连接 serverSocket.exceptionHandler(e -> { logger.error(e.getMessage(), e); close(); }); clientSocket.exceptionHandler(e -> { logger.error(e.getMessage(), e); close(); }); //当收到来自客户端的数据包时,转发给mysql目标服务器 clientSocket.handler(buffer -> serverSocket.write(buffer)); //当收到来自mysql目标服务器的数据包时,转发给客户端 serverSocket.handler(buffer -> clientSocket.write(buffer)); } private void close() { clientSocket.close(); serverSocket.close(); } }}

测试一下

try { Class.forName(name);//指定连接类型 Connection conn = DriverManager.getConnection(url, user, password);//url为代理服务器的地址 PreparedStatement pst = conn.prepareStatement("select * from test;");//准备执行语句 ResultSet resultSet = pst.executeQuery(); while (resultSet.next()) { System.out.println(resultSet.getLong(1) + ": " + resultSet.getString(2)); }} catch (Exception e) { e.printStackTrace();}

不出意外,一切运行正常,恭喜你,你已经实现了一个最简单的mysql代理服务器。

写在最后

vert.x是基于jvm、事件驱动、异步IO、响应式编程工具套件,底层网络通信使用netty4,是一个非常优秀的java开发框架(当然,严格意义上讲是工具套件),使用vert.x可以快速构建的各种应用,并且天生分布式,集群管理。

另外,实现一个代理服务器远没有如此简单,根据需求的不同,复杂度也不同,这里仅仅是展示实现代理的核心代码,实现了最基本的代理功能,当然了,一切复杂的需求都可以基于上面的代码进行改造扩展。

preparestatement方法用多次_如何用java 5分钟实现一个最简单的mysql代理服务器?相关推荐

  1. mysql 最近5分钟_如何5分钟实现一个最简单的MySQL代理服务器?

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 什么是MySQL代理? MySQL代理是介于client端和MySQL服务端中间层服务,如下图所示: 为什么要使用代理? 大部人都知道使用代理的好处,毕竟 ...

  2. java控制器文件内容替换_如何用Java来进行文件切割和简单的内容过滤的实现

    一 由来 去年由于项目的需求,要将一个任意一个文件制作成一个xml文件,并且需要保持文件内容本身不产生变化,还要能够将这个xml重新还原为原文件.如果小型的文件还好处理,大型的xml,比如几个G的文件 ...

  3. 如何用命令行写java程序_如何用java实现doc命令行

    如何用java实现doc命令行, dir显示当前所有目录下的文件 cd 文件目录 进入到该目录 cd ..退到上级目录,一面是我写的代码,调试了. 不过有点小bug就是当你进去的是文件就会提示空指针异 ...

  4. java判断那个时间更晚_如何用Java判断日期是早于还是晚于另一个日期

    如何用Java判断日期是早于还是晚于另一个日期 另一个工作中常见的操作就是如何判断给定的一个日期是大于某天还是小于某天?在Java 8中,LocalDate类有两类方法isBefore()和isAft ...

  5. java 判断手机运营商_如何用java判断手机号运营商?

    如何用java实现判断手机号的运营商?因为每个号段都是工信部规定划分给指定运营商的,所以我们可以通过手机号码的号段来判断. 现在手机号的号段那么多,要怎样方便的的判断呢?于是我们就想到了正则表达式,在 ...

  6. java 判断手机号_如何用java判断手机号运营商?

    如何用java实现判断手机号的运营商?因为每个号段都是工信部规定划分给指定运营商的,所以我们可以通过手机号码的号段来判断. 现在手机号的号段那么多,要怎样方便的的判断呢?于是我们就想到了正则表达式,在 ...

  7. java 网络爬虫_如何用Java实现网络爬虫

    原标题:如何用Java实现网络爬虫 微信公众号"书圈"后台回复[Javapachong1],下载本例的PPT和源码 作品描述 本章作品是一个能够抓取指定网站ACM比赛信息的爬虫.A ...

  8. java中循环输入_如何用java循环输入并且当输入0时结束循环?

    如何用java循环输入并且当输入0时结束循环? import java.util.Scanner; public class Avg { public static void main(String[ ...

  9. 余数定理_如何用Java实现余数定理

    余数定理 by Anuj Pahade 由Anuj Pahade 如何用Java实现余数定理 (How to implement the Chinese Remainder Theorem in Ja ...

最新文章

  1. Leetcode 200. 岛屿数量 解题思路及C++实现
  2. 深入浅出python机器学习_4.3.2_岭回归的参数调节-2_绘制折线图
  3. db2 删除存储过程_数据库教程-SQL Server存储过程使用及异常处理
  4. 计算机考研8,计算机考研每日一练:第八天
  5. [深度学习-实践]条件生成对抗网络cGAN的例子-Tensorflow2.x Keras
  6. 共识指数榜单0904
  7. 传说中Python最难理解的点|看这完篇就够了
  8. [2018.03.14 T2] 树(tree)
  9. Bootstrap系列---按钮
  10. Science Advances:恐惧学习中内侧前额叶和杏仁核theta振荡同步活动
  11. Java的ASCII编码表
  12. mysql ndb_MySQL NDB Cluster概述
  13. 马斯洛需求层次理论与消费者需求
  14. 笔记本未指定打印机服务器,打印机出现在未指定里怎么办?可以这样解决
  15. Psim仿真_pi输出加限幅(疑惑)
  16. Easyrecovery 专业的手机数据恢复软件
  17. npm-run-all 同时运行多条命令
  18. 星座图matlab是什么意思,如何理解Matlab星座图16QAM
  19. warning: statement has no effect [-Wunused-value]
  20. Shellshock 破壳漏洞(CVE-2014-6271)

热门文章

  1. finecms控制器与html,使用@ HTML.Action与参数,以C#控制器
  2. redux异步action_redux-thunk 和 redux-saga 的区别?
  3. ssm插入数据时候栈溢出_程序员算法与数据结构基础中的基础,栈与递归
  4. 未来不是计算机发展的方向,未来人类的方向,或许不是人工智能,而是智能人类...
  5. Linux accept tcp,Linux TCP accept without SYN|ACK
  6. 服务器操作系统锁定设置,服务器操作系统锁定设置
  7. vim之格式化代码功能——gg=G
  8. document.domain ajax,PHP ajax跨子域的解决方案之document.domain+iframe实例分析
  9. 5.0安装没有costom mysql_mysql5.0 64位
  10. appium java版本错误_java – 无法创建新会话. appium代码中的错误