成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

如何用java 5分鐘實(shí)現(xiàn)一個(gè)最簡單的mysql代理服務(wù)器?

JerryZou / 3326人閱讀

摘要:用基于快速實(shí)現(xiàn)一個(gè)最簡單的代理服務(wù)器,只需要分鐘時(shí)間。監(jiān)控統(tǒng)計(jì)客戶端的請求情況,請求分布統(tǒng)計(jì)請求類型等,以此來優(yōu)化數(shù)據(jù)庫的使用。

用java8基于vert.x3 快速實(shí)現(xiàn)一個(gè)最簡單的mysql代理服務(wù)器,只需要5分鐘時(shí)間。

什么是mysql 代理?

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

為什么要使用代理?

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

將不同類型的請求分發(fā)的不同的server以此實(shí)現(xiàn)讀寫分離、負(fù)載均衡。

來自不同客戶端的請求分發(fā)到不同的server實(shí)現(xiàn)后端多租戶數(shù)據(jù)庫服務(wù),當(dāng)然,類似的原理還可以實(shí)現(xiàn)分庫分表、一個(gè)請求寫到多個(gè)server或者不同的源端如消息隊(duì)列。

監(jiān)控統(tǒng)計(jì)客戶端的請求情況,請求分布統(tǒng)計(jì)、請求類型等,以此來優(yōu)化數(shù)據(jù)庫的使用。

總之,可以實(shí)現(xiàn)你想要的諸多功能。

如何用java快速實(shí)現(xiàn)一個(gè)最簡單的代理呢?

首先,準(zhǔn)備開發(fā)工具套件,我們并不會引入過多工具包,僅僅需要:

java8

vert.x 3

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


  io.vertx
  vertx-core
  3.3.2

代碼實(shí)現(xiàn):

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();//創(chuàng)建代理服務(wù)器
      NetClient netClient = vertx.createNetClient();//創(chuàng)建連接mysql客戶端
      netServer.connectHandler(socket -> netClient.connect(port, mysqlHost, result -> {
        //響應(yīng)來自客戶端的連接請求,成功之后,在建立一個(gè)與目標(biāo)mysql服務(wù)器的連接
        if (result.succeeded()) {
          //與目標(biāo)mysql服務(wù)器成功連接連接之后,創(chuàng)造一個(gè)MysqlProxyConnection對象,并執(zhí)行代理方法
          new MysqlProxyConnection(socket, result.result()).proxy();
        } else {
          logger.error(result.cause().getMessage(), result.cause());
          socket.close();
        }
      })).listen(port, listenResult -> {//代理服務(wù)器的監(jiān)聽端口
        if (listenResult.succeeded()) {
          //成功啟動代理服務(wù)器
          logger.info("Mysql proxy server start up.");
        } else {
          //啟動代理服務(wù)器失敗
          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() {
      //當(dāng)代理與mysql服務(wù)器連接關(guān)閉時(shí),關(guān)閉client與代理的連接
      serverSocket.closeHandler(v -> clientSocket.close());
      //反之亦然
      clientSocket.closeHandler(v -> serverSocket.close());
      //不管那端的連接出現(xiàn)異常時(shí),關(guān)閉兩端的連接
      serverSocket.exceptionHandler(e -> {
        logger.error(e.getMessage(), e);
        close();
      });
      clientSocket.exceptionHandler(e -> {
        logger.error(e.getMessage(), e);
        close();
      });
      //當(dāng)收到來自客戶端的數(shù)據(jù)包時(shí),轉(zhuǎn)發(fā)給mysql目標(biāo)服務(wù)器
      clientSocket.handler(buffer -> serverSocket.write(buffer));
      //當(dāng)收到來自mysql目標(biāo)服務(wù)器的數(shù)據(jù)包時(shí),轉(zhuǎn)發(fā)給客戶端
      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為代理服務(wù)器的地址
  PreparedStatement pst = conn.prepareStatement("select * from test;");//準(zhǔn)備執(zhí)行語句
  ResultSet resultSet = pst.executeQuery();
  while (resultSet.next()) {
    System.out.println(resultSet.getLong(1) + ": " + resultSet.getString(2));
  }
} catch (Exception e) {
  e.printStackTrace();
}

不出意外,一切運(yùn)行正常,恭喜你,你已經(jīng)實(shí)現(xiàn)了一個(gè)最簡單的mysql代理服務(wù)器。

寫在最后

vert.x是基于jvm、事件驅(qū)動、異步IO、響應(yīng)式編程工具套件,底層網(wǎng)絡(luò)通信使用netty4,是一個(gè)非常優(yōu)秀的java開發(fā)框架(當(dāng)然,嚴(yán)格意義上講是工具套件),使用vert.x可以快速構(gòu)建的各種應(yīng)用,并且天生分布式,集群管理。
另外,實(shí)現(xiàn)一個(gè)代理服務(wù)器遠(yuǎn)沒有如此簡單,根據(jù)需求的不同,復(fù)雜度也不同,這里僅僅是展示實(shí)現(xiàn)代理的核心代碼,實(shí)現(xiàn)了最基本的代理功能,當(dāng)然了,一切復(fù)雜的需求都可以基于上面的代碼進(jìn)行改造擴(kuò)展.

作者信息
作者系力譜宿云LeapCloud旗下_Maxleap團(tuán)隊(duì)成員:趙靜【原創(chuàng)】
力譜宿云首發(fā)地址:https://blog.maxleap.cn/archi...

相關(guān)文章
次時(shí)代Java編程(一):Java里的協(xié)程
次時(shí)代Java編程(一):續(xù) vertx-sync實(shí)踐

作者往期佳作
構(gòu)建BaaS云數(shù)據(jù)(CloudData)服務(wù)—mongo集群架構(gòu)設(shè)計(jì)

作者往期活動
CloudData-Mongo_微信直播分享
7月酷暑,暢聊Reative工具Vert.x
Vert.x技術(shù)活動后續(xù) | Maxleap Vert.x應(yīng)用實(shí)踐總結(jié)

對我們的活動感興趣的小伙伴,歡迎關(guān)注微信公眾號:MaxLeap_yidongyanfa

活動預(yù)告

報(bào)名鏈接:http://t.cn/Rt9ooRw

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/65004.html

相關(guān)文章

  • 何用Python抓抖音上小姐姐

    摘要:比如分鐘破譯朋友圈測試小游戲文章里用的方法但有些根本就沒有提供網(wǎng)頁端,比如今年火得不行的抖音。所以常用的方式就是通過在電腦上裝一些抓包軟件,將手機(jī)上的網(wǎng)絡(luò)請求全部顯示出來。總結(jié)下,重點(diǎn)是的抓取,關(guān)鍵是配置代理證書,難點(diǎn)是對請求的分析。 爬蟲的案例我們已講得太多。不過幾乎都是 網(wǎng)頁爬蟲 。即使有些手機(jī)才能訪問的網(wǎng)站,我們也可以通過 Chrome 開發(fā)者工具 的 手機(jī)模擬 功能來訪問,以便...

    FingerLiu 評論0 收藏0
  • Java開發(fā) 大廠面試整理

    摘要:用戶態(tài)不能干擾內(nèi)核態(tài)所以指令就有兩種特權(quán)指令和非特權(quán)指令不同的狀態(tài)對應(yīng)不同的指令。非特權(quán)指令所有程序均可直接使用。用戶態(tài)常態(tài)目態(tài)執(zhí)行非特權(quán)指令。 這是我今年從三月份開始,主要的大廠面試經(jīng)過,有些企業(yè)面試的還沒來得及整理,可能有些沒有帶答案就發(fā)出來了,還請各位先思考如果是你怎么回答面試官?這篇文章會持續(xù)更新,請各位持續(xù)關(guān)注,希望對你有所幫助! 面試清單 平安產(chǎn)險(xiǎn) 飛豬 上汽大通 浩鯨科...

    Scorpion 評論0 收藏0
  • 何用Rancher在AWS上運(yùn)行Kubernetes

    摘要:環(huán)境部署第一步,我會按默認(rèn)的向?qū)?chuàng)建一個(gè)新的虛擬私有云,這個(gè)虛擬私有云是為準(zhǔn)備的。的應(yīng)用程序?qū)⒆约涸趦?nèi)運(yùn)行。所有的主機(jī)都可以使用公有的,可如果你是在虛擬私有云上有主機(jī)的話,這就有點(diǎn)麻煩了,所以你可以選擇使用私有而非公有。 眾所周知,亞馬遜有EC2容器服務(wù),它是亞馬遜用于運(yùn)行Docker容器的解決方案。不過我覺得EC2容器服務(wù)不怎么好用,所以現(xiàn)在我要在AWS上測試Rancher和Kube...

    shinezejian 評論0 收藏0
  • 何用Rancher在AWS上運(yùn)行Kubernetes

    摘要:環(huán)境部署第一步,我會按默認(rèn)的向?qū)?chuàng)建一個(gè)新的虛擬私有云,這個(gè)虛擬私有云是為準(zhǔn)備的。的應(yīng)用程序?qū)⒆约涸趦?nèi)運(yùn)行。所有的主機(jī)都可以使用公有的,可如果你是在虛擬私有云上有主機(jī)的話,這就有點(diǎn)麻煩了,所以你可以選擇使用私有而非公有。 眾所周知,亞馬遜有EC2容器服務(wù),它是亞馬遜用于運(yùn)行Docker容器的解決方案。不過我覺得EC2容器服務(wù)不怎么好用,所以現(xiàn)在我要在AWS上測試Rancher和Kube...

    williamwen1986 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<