<menu id="ycqsw"></menu><nav id="ycqsw"><code id="ycqsw"></code></nav>
<dd id="ycqsw"><menu id="ycqsw"></menu></dd>
  • <nav id="ycqsw"></nav>
    <menu id="ycqsw"><strong id="ycqsw"></strong></menu>
    <xmp id="ycqsw"><nav id="ycqsw"></nav>
  • mysql代理服務器(云數據庫和普通數據庫)


    用java8基于vert.x3 快速實現一個最簡單的mysql代理服務器,只需要5分鐘時間。

    如何用java 5分鐘實現一個最簡單的mysql代理服務器?

    什么是mysql 代理?

    mysql代理是介于client端和mysql服務端中間層服務,如下圖所示:

    如何用java 5分鐘實現一個最簡單的mysql代理服務器?

    這里寫圖片描述

    為什么要使用代理?

    大部人都知道使用代理的好處,畢竟,隨著互聯網越來越普及,互聯網系統越來越龐大、復雜,性能要求越來越高,為了讓整個系統具有更好的擴展性、更高的性能、解藕等多種特性,在數據庫層面引入代理層是目前互聯網系統常見的架構設計方案??偟膩碚f,在數據庫層面引入代理會帶來以下好處:

    • 將不同類型的請求分發的不同的server以此實現讀寫分離、負載均衡。
    • 來自不同客戶端的請求分發到不同的server實現后端多租戶數據庫服務,當然,類似的原理還可以實現分庫分表、一個請求寫到多個server或者不同的源端如消息隊列。
    • 監控統計客戶端的請求情況,請求分布統計、請求類型等,以此來優化數據庫的使用。
    • 總之,可以實現你想要的諸多功能。

    如何用java快速實現一個最簡單的代理呢?

    首先,準備開發工具套件,我們并不會引入過多工具包,僅僅需要:

    • java8
    • vert.x 3

    如果你是用maven做為項目管理工具,請將vert.x 3引入:

    <dependency>
     <groupId>io.vertx</groupId>
     <artifactId>vertx-core</artifactId>
     <version>3.3.2</version>
    </dependency>
    

    代碼實現:

    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可以快速構建的各種應用,并且天生分布式,集群管理。

    另外,實現一個代理服務器遠沒有如此簡單,根據需求的不同,復雜度也不同,這里僅僅是展示實現代理的核心代碼,實現了最基本的代理功能,當然了,一切復雜的需求都可以基于上面的代碼進行改造擴展。

    如何用java 5分鐘實現一個最簡單的mysql代理服務器?

    版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。

    發表評論

    登錄后才能評論
    国产精品区一区二区免费