主頁 > 軟體設計 > Mysql Connector/J 原始碼分析(LoadBalance)

Mysql Connector/J 原始碼分析(LoadBalance)

2020-10-04 19:57:50 軟體設計

文章目錄

  • 前言
  • 名詞定義
  • 一、Loadbalance的邏輯結構
  • 二、例外處理機制
    • 1.構造階段
      • 小結
    • 2.使用階段
    • 小結
  • 三、autoReconnect選項
    • 作用分析
  • 四、何時重建連接
  • 五、實用性分析
  • 六、總結

前言

本文討論Connector/J 的loadbalance模塊,我們先觀察整個模塊的大概邏輯結構和每一個大組件的作用,然后在代碼層面分析對于例外的控制,這里會有兩個“區分”:1)區分構造連接程序和使用連接程序;2)區分通訊例外和資料例外,最終分析此模式的實用性,

本次分析的版本為5.1.46,若通過maven下載,可添加以下依賴:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.46</version>
</dependency>

我們獲取連接的例子如下:

 Connection conn = null;
    URL =“jdbc:mysql:loadbalance://ip1:port1,ip2:port2,ip3:port3/dbname”;
    try{
        // 注冊 JDBC 驅動
        Class.forName("com.mysql.jdbc.Driver");

        // 打開鏈接
        conn = DriverManager.getConnection(DB_URL,USER,PASS);
    ....

名詞定義

Mysql:Mysql資料庫管理軟體

Mysql服務器:安裝了Mysql資料庫管理軟體的服務器

呼叫方:呼叫DriverManager#getConnection命令獲取連接的一方

一、Loadbalance的邏輯結構

Loadbalance模塊的UML類圖如下:
在這里插入圖片描述主要組件功能如下:

  • MysqlIO:負責與Mysql服務器建立tcp鏈接,
  • ConnectionImpl、JDBC4Connection:通過MysqlIO控制與Mysql服務器間的連接,并設定和記錄各種連接時間
  • MultiHostMySQLConnection、LoadBalancedMySQLConnection、JDBC4LoadBalancedMySQLConnection:通過代理物件LoadBalancedConnectionProxy獲取JDBC4Connection物件,并呼叫JDBC4Connection物件對應的介面方法(從JDBC4MySQLConnection到java.sql.Connection宣告的方法),或者呼叫LoadBalancedConnectionProxy對應的方法,
  • BalanceStrategy介面以及其實作類,以各自的演算法回傳合適的連接物件JDBC4Connection,
  • MultiHostConnectionProxy:作為各種動態類的父類,實作了各種動態類的公共方法,最常見的就是回傳當前連接物件給到MultiHostMySQLConnection及其子類,它還是InvocationHandler介面的直接實作類,它多載了invoke方法,并宣告了由其子類實作的虛方法invokeMore,invoke方法的實作使用了模板方法這種設計模式,通過invoke方法和類的invokeMore方法,一起實作了代理模式,即在被代理方法執行之前和之后都添加了一些行為,
  • LoadBalancedConnectionProxy作為MultiHostMySQLConnection的子類多載了invokeMore方法,在被代理方法執行后,會通過策略物件計算和更新當前連接物件,以供下次使用,

組件呼叫順序:

  • 構造連接時各組件呼叫順序:
<style>#mermaid-svg-mBKrvtMgvlgNiQ9D .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .label text{fill:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .node rect,#mermaid-svg-mBKrvtMgvlgNiQ9D .node circle,#mermaid-svg-mBKrvtMgvlgNiQ9D .node ellipse,#mermaid-svg-mBKrvtMgvlgNiQ9D .node polygon,#mermaid-svg-mBKrvtMgvlgNiQ9D .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-mBKrvtMgvlgNiQ9D .node .label{text-align:center;fill:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .node.clickable{cursor:pointer}#mermaid-svg-mBKrvtMgvlgNiQ9D .arrowheadPath{fill:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-mBKrvtMgvlgNiQ9D .flowchart-link{stroke:#333;fill:none}#mermaid-svg-mBKrvtMgvlgNiQ9D .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-mBKrvtMgvlgNiQ9D .edgeLabel rect{opacity:0.9}#mermaid-svg-mBKrvtMgvlgNiQ9D .edgeLabel span{color:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-mBKrvtMgvlgNiQ9D .cluster text{fill:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-mBKrvtMgvlgNiQ9D .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-mBKrvtMgvlgNiQ9D text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-mBKrvtMgvlgNiQ9D .actor-line{stroke:grey}#mermaid-svg-mBKrvtMgvlgNiQ9D .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .sequenceNumber{fill:#fff}#mermaid-svg-mBKrvtMgvlgNiQ9D #sequencenumber{fill:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D #crosshead path{fill:#333;stroke:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .messageText{fill:#333;stroke:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-mBKrvtMgvlgNiQ9D .labelText,#mermaid-svg-mBKrvtMgvlgNiQ9D .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-mBKrvtMgvlgNiQ9D .loopText,#mermaid-svg-mBKrvtMgvlgNiQ9D .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-mBKrvtMgvlgNiQ9D .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-mBKrvtMgvlgNiQ9D .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-mBKrvtMgvlgNiQ9D .noteText,#mermaid-svg-mBKrvtMgvlgNiQ9D .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-mBKrvtMgvlgNiQ9D .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-mBKrvtMgvlgNiQ9D .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-mBKrvtMgvlgNiQ9D .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-mBKrvtMgvlgNiQ9D .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-mBKrvtMgvlgNiQ9D .section{stroke:none;opacity:0.2}#mermaid-svg-mBKrvtMgvlgNiQ9D .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-mBKrvtMgvlgNiQ9D .section2{fill:#fff400}#mermaid-svg-mBKrvtMgvlgNiQ9D .section1,#mermaid-svg-mBKrvtMgvlgNiQ9D .section3{fill:#fff;opacity:0.2}#mermaid-svg-mBKrvtMgvlgNiQ9D .sectionTitle0{fill:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .sectionTitle1{fill:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .sectionTitle2{fill:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .sectionTitle3{fill:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-mBKrvtMgvlgNiQ9D .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-mBKrvtMgvlgNiQ9D .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-mBKrvtMgvlgNiQ9D .grid path{stroke-width:0}#mermaid-svg-mBKrvtMgvlgNiQ9D .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-mBKrvtMgvlgNiQ9D .task{stroke-width:2}#mermaid-svg-mBKrvtMgvlgNiQ9D .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-mBKrvtMgvlgNiQ9D .taskText:not([font-size]){font-size:11px}#mermaid-svg-mBKrvtMgvlgNiQ9D .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-mBKrvtMgvlgNiQ9D .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-mBKrvtMgvlgNiQ9D .task.clickable{cursor:pointer}#mermaid-svg-mBKrvtMgvlgNiQ9D .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-mBKrvtMgvlgNiQ9D .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-mBKrvtMgvlgNiQ9D .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-mBKrvtMgvlgNiQ9D .taskText0,#mermaid-svg-mBKrvtMgvlgNiQ9D .taskText1,#mermaid-svg-mBKrvtMgvlgNiQ9D .taskText2,#mermaid-svg-mBKrvtMgvlgNiQ9D .taskText3{fill:#fff}#mermaid-svg-mBKrvtMgvlgNiQ9D .task0,#mermaid-svg-mBKrvtMgvlgNiQ9D .task1,#mermaid-svg-mBKrvtMgvlgNiQ9D .task2,#mermaid-svg-mBKrvtMgvlgNiQ9D .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-mBKrvtMgvlgNiQ9D .taskTextOutside0,#mermaid-svg-mBKrvtMgvlgNiQ9D .taskTextOutside2{fill:#000}#mermaid-svg-mBKrvtMgvlgNiQ9D .taskTextOutside1,#mermaid-svg-mBKrvtMgvlgNiQ9D .taskTextOutside3{fill:#000}#mermaid-svg-mBKrvtMgvlgNiQ9D .active0,#mermaid-svg-mBKrvtMgvlgNiQ9D .active1,#mermaid-svg-mBKrvtMgvlgNiQ9D .active2,#mermaid-svg-mBKrvtMgvlgNiQ9D .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-mBKrvtMgvlgNiQ9D .activeText0,#mermaid-svg-mBKrvtMgvlgNiQ9D .activeText1,#mermaid-svg-mBKrvtMgvlgNiQ9D .activeText2,#mermaid-svg-mBKrvtMgvlgNiQ9D .activeText3{fill:#000 !important}#mermaid-svg-mBKrvtMgvlgNiQ9D .done0,#mermaid-svg-mBKrvtMgvlgNiQ9D .done1,#mermaid-svg-mBKrvtMgvlgNiQ9D .done2,#mermaid-svg-mBKrvtMgvlgNiQ9D .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-mBKrvtMgvlgNiQ9D .doneText0,#mermaid-svg-mBKrvtMgvlgNiQ9D .doneText1,#mermaid-svg-mBKrvtMgvlgNiQ9D .doneText2,#mermaid-svg-mBKrvtMgvlgNiQ9D .doneText3{fill:#000 !important}#mermaid-svg-mBKrvtMgvlgNiQ9D .crit0,#mermaid-svg-mBKrvtMgvlgNiQ9D .crit1,#mermaid-svg-mBKrvtMgvlgNiQ9D .crit2,#mermaid-svg-mBKrvtMgvlgNiQ9D .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-mBKrvtMgvlgNiQ9D .activeCrit0,#mermaid-svg-mBKrvtMgvlgNiQ9D .activeCrit1,#mermaid-svg-mBKrvtMgvlgNiQ9D .activeCrit2,#mermaid-svg-mBKrvtMgvlgNiQ9D .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-mBKrvtMgvlgNiQ9D .doneCrit0,#mermaid-svg-mBKrvtMgvlgNiQ9D .doneCrit1,#mermaid-svg-mBKrvtMgvlgNiQ9D .doneCrit2,#mermaid-svg-mBKrvtMgvlgNiQ9D .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-mBKrvtMgvlgNiQ9D .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-mBKrvtMgvlgNiQ9D .milestoneText{font-style:italic}#mermaid-svg-mBKrvtMgvlgNiQ9D .doneCritText0,#mermaid-svg-mBKrvtMgvlgNiQ9D .doneCritText1,#mermaid-svg-mBKrvtMgvlgNiQ9D .doneCritText2,#mermaid-svg-mBKrvtMgvlgNiQ9D .doneCritText3{fill:#000 !important}#mermaid-svg-mBKrvtMgvlgNiQ9D .activeCritText0,#mermaid-svg-mBKrvtMgvlgNiQ9D .activeCritText1,#mermaid-svg-mBKrvtMgvlgNiQ9D .activeCritText2,#mermaid-svg-mBKrvtMgvlgNiQ9D .activeCritText3{fill:#000 !important}#mermaid-svg-mBKrvtMgvlgNiQ9D .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-mBKrvtMgvlgNiQ9D g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-mBKrvtMgvlgNiQ9D g.classGroup text .title{font-weight:bolder}#mermaid-svg-mBKrvtMgvlgNiQ9D g.clickable{cursor:pointer}#mermaid-svg-mBKrvtMgvlgNiQ9D g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-mBKrvtMgvlgNiQ9D g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-mBKrvtMgvlgNiQ9D .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-mBKrvtMgvlgNiQ9D .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-mBKrvtMgvlgNiQ9D .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-mBKrvtMgvlgNiQ9D .dashed-line{stroke-dasharray:3}#mermaid-svg-mBKrvtMgvlgNiQ9D #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-mBKrvtMgvlgNiQ9D #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-mBKrvtMgvlgNiQ9D #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-mBKrvtMgvlgNiQ9D #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-mBKrvtMgvlgNiQ9D #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-mBKrvtMgvlgNiQ9D #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-mBKrvtMgvlgNiQ9D #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-mBKrvtMgvlgNiQ9D #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-mBKrvtMgvlgNiQ9D .commit-id,#mermaid-svg-mBKrvtMgvlgNiQ9D .commit-msg,#mermaid-svg-mBKrvtMgvlgNiQ9D .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-mBKrvtMgvlgNiQ9D .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-mBKrvtMgvlgNiQ9D .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-mBKrvtMgvlgNiQ9D g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-mBKrvtMgvlgNiQ9D g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-mBKrvtMgvlgNiQ9D g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-mBKrvtMgvlgNiQ9D g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-mBKrvtMgvlgNiQ9D g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-mBKrvtMgvlgNiQ9D .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-mBKrvtMgvlgNiQ9D .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-mBKrvtMgvlgNiQ9D .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-mBKrvtMgvlgNiQ9D .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-mBKrvtMgvlgNiQ9D .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-mBKrvtMgvlgNiQ9D .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-mBKrvtMgvlgNiQ9D .edgeLabel text{fill:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-mBKrvtMgvlgNiQ9D .node circle.state-start{fill:black;stroke:black}#mermaid-svg-mBKrvtMgvlgNiQ9D .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-mBKrvtMgvlgNiQ9D #statediagram-barbEnd{fill:#9370db}#mermaid-svg-mBKrvtMgvlgNiQ9D .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-mBKrvtMgvlgNiQ9D .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-mBKrvtMgvlgNiQ9D .statediagram-state .divider{stroke:#9370db}#mermaid-svg-mBKrvtMgvlgNiQ9D .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-mBKrvtMgvlgNiQ9D .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-mBKrvtMgvlgNiQ9D .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-mBKrvtMgvlgNiQ9D .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-mBKrvtMgvlgNiQ9D .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-mBKrvtMgvlgNiQ9D .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-mBKrvtMgvlgNiQ9D .note-edge{stroke-dasharray:5}#mermaid-svg-mBKrvtMgvlgNiQ9D .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-mBKrvtMgvlgNiQ9D .error-icon{fill:#522}#mermaid-svg-mBKrvtMgvlgNiQ9D .error-text{fill:#522;stroke:#522}#mermaid-svg-mBKrvtMgvlgNiQ9D .edge-thickness-normal{stroke-width:2px}#mermaid-svg-mBKrvtMgvlgNiQ9D .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-mBKrvtMgvlgNiQ9D .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-mBKrvtMgvlgNiQ9D .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-mBKrvtMgvlgNiQ9D .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-mBKrvtMgvlgNiQ9D .marker{fill:#333}#mermaid-svg-mBKrvtMgvlgNiQ9D .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-mBKrvtMgvlgNiQ9D { color: rgba(0, 0, 0, 0.75); font: ; }</style> 呼叫者 Driver DriverManager LoadBalancedConnectionProxy JDBC4LoadBalancedMySQLConnection BalanceStrategy JDBC4Connection MysqlIO 呼叫者 Driver DriverManager LoadBalancedConnectionProxy JDBC4LoadBalancedMySQLConnection BalanceStrategy JDBC4Connection MysqlIO
  • 使用連接時各組件呼叫順序:
<style>#mermaid-svg-FWo4uWnVyiqUJGsx .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .label text{fill:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .node rect,#mermaid-svg-FWo4uWnVyiqUJGsx .node circle,#mermaid-svg-FWo4uWnVyiqUJGsx .node ellipse,#mermaid-svg-FWo4uWnVyiqUJGsx .node polygon,#mermaid-svg-FWo4uWnVyiqUJGsx .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-FWo4uWnVyiqUJGsx .node .label{text-align:center;fill:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .node.clickable{cursor:pointer}#mermaid-svg-FWo4uWnVyiqUJGsx .arrowheadPath{fill:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-FWo4uWnVyiqUJGsx .flowchart-link{stroke:#333;fill:none}#mermaid-svg-FWo4uWnVyiqUJGsx .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-FWo4uWnVyiqUJGsx .edgeLabel rect{opacity:0.9}#mermaid-svg-FWo4uWnVyiqUJGsx .edgeLabel span{color:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-FWo4uWnVyiqUJGsx .cluster text{fill:#333}#mermaid-svg-FWo4uWnVyiqUJGsx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-FWo4uWnVyiqUJGsx .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-FWo4uWnVyiqUJGsx text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-FWo4uWnVyiqUJGsx .actor-line{stroke:grey}#mermaid-svg-FWo4uWnVyiqUJGsx .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-FWo4uWnVyiqUJGsx #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .sequenceNumber{fill:#fff}#mermaid-svg-FWo4uWnVyiqUJGsx #sequencenumber{fill:#333}#mermaid-svg-FWo4uWnVyiqUJGsx #crosshead path{fill:#333;stroke:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .messageText{fill:#333;stroke:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-FWo4uWnVyiqUJGsx .labelText,#mermaid-svg-FWo4uWnVyiqUJGsx .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-FWo4uWnVyiqUJGsx .loopText,#mermaid-svg-FWo4uWnVyiqUJGsx .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-FWo4uWnVyiqUJGsx .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-FWo4uWnVyiqUJGsx .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-FWo4uWnVyiqUJGsx .noteText,#mermaid-svg-FWo4uWnVyiqUJGsx .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-FWo4uWnVyiqUJGsx .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-FWo4uWnVyiqUJGsx .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-FWo4uWnVyiqUJGsx .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-FWo4uWnVyiqUJGsx .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-FWo4uWnVyiqUJGsx .section{stroke:none;opacity:0.2}#mermaid-svg-FWo4uWnVyiqUJGsx .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-FWo4uWnVyiqUJGsx .section2{fill:#fff400}#mermaid-svg-FWo4uWnVyiqUJGsx .section1,#mermaid-svg-FWo4uWnVyiqUJGsx .section3{fill:#fff;opacity:0.2}#mermaid-svg-FWo4uWnVyiqUJGsx .sectionTitle0{fill:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .sectionTitle1{fill:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .sectionTitle2{fill:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .sectionTitle3{fill:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-FWo4uWnVyiqUJGsx .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-FWo4uWnVyiqUJGsx .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-FWo4uWnVyiqUJGsx .grid path{stroke-width:0}#mermaid-svg-FWo4uWnVyiqUJGsx .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-FWo4uWnVyiqUJGsx .task{stroke-width:2}#mermaid-svg-FWo4uWnVyiqUJGsx .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-FWo4uWnVyiqUJGsx .taskText:not([font-size]){font-size:11px}#mermaid-svg-FWo4uWnVyiqUJGsx .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-FWo4uWnVyiqUJGsx .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-FWo4uWnVyiqUJGsx .task.clickable{cursor:pointer}#mermaid-svg-FWo4uWnVyiqUJGsx .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-FWo4uWnVyiqUJGsx .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-FWo4uWnVyiqUJGsx .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-FWo4uWnVyiqUJGsx .taskText0,#mermaid-svg-FWo4uWnVyiqUJGsx .taskText1,#mermaid-svg-FWo4uWnVyiqUJGsx .taskText2,#mermaid-svg-FWo4uWnVyiqUJGsx .taskText3{fill:#fff}#mermaid-svg-FWo4uWnVyiqUJGsx .task0,#mermaid-svg-FWo4uWnVyiqUJGsx .task1,#mermaid-svg-FWo4uWnVyiqUJGsx .task2,#mermaid-svg-FWo4uWnVyiqUJGsx .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-FWo4uWnVyiqUJGsx .taskTextOutside0,#mermaid-svg-FWo4uWnVyiqUJGsx .taskTextOutside2{fill:#000}#mermaid-svg-FWo4uWnVyiqUJGsx .taskTextOutside1,#mermaid-svg-FWo4uWnVyiqUJGsx .taskTextOutside3{fill:#000}#mermaid-svg-FWo4uWnVyiqUJGsx .active0,#mermaid-svg-FWo4uWnVyiqUJGsx .active1,#mermaid-svg-FWo4uWnVyiqUJGsx .active2,#mermaid-svg-FWo4uWnVyiqUJGsx .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-FWo4uWnVyiqUJGsx .activeText0,#mermaid-svg-FWo4uWnVyiqUJGsx .activeText1,#mermaid-svg-FWo4uWnVyiqUJGsx .activeText2,#mermaid-svg-FWo4uWnVyiqUJGsx .activeText3{fill:#000 !important}#mermaid-svg-FWo4uWnVyiqUJGsx .done0,#mermaid-svg-FWo4uWnVyiqUJGsx .done1,#mermaid-svg-FWo4uWnVyiqUJGsx .done2,#mermaid-svg-FWo4uWnVyiqUJGsx .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-FWo4uWnVyiqUJGsx .doneText0,#mermaid-svg-FWo4uWnVyiqUJGsx .doneText1,#mermaid-svg-FWo4uWnVyiqUJGsx .doneText2,#mermaid-svg-FWo4uWnVyiqUJGsx .doneText3{fill:#000 !important}#mermaid-svg-FWo4uWnVyiqUJGsx .crit0,#mermaid-svg-FWo4uWnVyiqUJGsx .crit1,#mermaid-svg-FWo4uWnVyiqUJGsx .crit2,#mermaid-svg-FWo4uWnVyiqUJGsx .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-FWo4uWnVyiqUJGsx .activeCrit0,#mermaid-svg-FWo4uWnVyiqUJGsx .activeCrit1,#mermaid-svg-FWo4uWnVyiqUJGsx .activeCrit2,#mermaid-svg-FWo4uWnVyiqUJGsx .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-FWo4uWnVyiqUJGsx .doneCrit0,#mermaid-svg-FWo4uWnVyiqUJGsx .doneCrit1,#mermaid-svg-FWo4uWnVyiqUJGsx .doneCrit2,#mermaid-svg-FWo4uWnVyiqUJGsx .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-FWo4uWnVyiqUJGsx .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-FWo4uWnVyiqUJGsx .milestoneText{font-style:italic}#mermaid-svg-FWo4uWnVyiqUJGsx .doneCritText0,#mermaid-svg-FWo4uWnVyiqUJGsx .doneCritText1,#mermaid-svg-FWo4uWnVyiqUJGsx .doneCritText2,#mermaid-svg-FWo4uWnVyiqUJGsx .doneCritText3{fill:#000 !important}#mermaid-svg-FWo4uWnVyiqUJGsx .activeCritText0,#mermaid-svg-FWo4uWnVyiqUJGsx .activeCritText1,#mermaid-svg-FWo4uWnVyiqUJGsx .activeCritText2,#mermaid-svg-FWo4uWnVyiqUJGsx .activeCritText3{fill:#000 !important}#mermaid-svg-FWo4uWnVyiqUJGsx .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-FWo4uWnVyiqUJGsx g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-FWo4uWnVyiqUJGsx g.classGroup text .title{font-weight:bolder}#mermaid-svg-FWo4uWnVyiqUJGsx g.clickable{cursor:pointer}#mermaid-svg-FWo4uWnVyiqUJGsx g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-FWo4uWnVyiqUJGsx g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-FWo4uWnVyiqUJGsx .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-FWo4uWnVyiqUJGsx .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-FWo4uWnVyiqUJGsx .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-FWo4uWnVyiqUJGsx .dashed-line{stroke-dasharray:3}#mermaid-svg-FWo4uWnVyiqUJGsx #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-FWo4uWnVyiqUJGsx #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-FWo4uWnVyiqUJGsx #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-FWo4uWnVyiqUJGsx #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-FWo4uWnVyiqUJGsx #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-FWo4uWnVyiqUJGsx #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-FWo4uWnVyiqUJGsx #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-FWo4uWnVyiqUJGsx #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-FWo4uWnVyiqUJGsx .commit-id,#mermaid-svg-FWo4uWnVyiqUJGsx .commit-msg,#mermaid-svg-FWo4uWnVyiqUJGsx .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-FWo4uWnVyiqUJGsx .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-FWo4uWnVyiqUJGsx .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-FWo4uWnVyiqUJGsx g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-FWo4uWnVyiqUJGsx g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-FWo4uWnVyiqUJGsx g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-FWo4uWnVyiqUJGsx g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-FWo4uWnVyiqUJGsx g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-FWo4uWnVyiqUJGsx g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-FWo4uWnVyiqUJGsx .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-FWo4uWnVyiqUJGsx .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-FWo4uWnVyiqUJGsx .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-FWo4uWnVyiqUJGsx .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-FWo4uWnVyiqUJGsx .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-FWo4uWnVyiqUJGsx .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-FWo4uWnVyiqUJGsx .edgeLabel text{fill:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-FWo4uWnVyiqUJGsx .node circle.state-start{fill:black;stroke:black}#mermaid-svg-FWo4uWnVyiqUJGsx .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-FWo4uWnVyiqUJGsx #statediagram-barbEnd{fill:#9370db}#mermaid-svg-FWo4uWnVyiqUJGsx .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-FWo4uWnVyiqUJGsx .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-FWo4uWnVyiqUJGsx .statediagram-state .divider{stroke:#9370db}#mermaid-svg-FWo4uWnVyiqUJGsx .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-FWo4uWnVyiqUJGsx .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-FWo4uWnVyiqUJGsx .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-FWo4uWnVyiqUJGsx .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-FWo4uWnVyiqUJGsx .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-FWo4uWnVyiqUJGsx .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-FWo4uWnVyiqUJGsx .note-edge{stroke-dasharray:5}#mermaid-svg-FWo4uWnVyiqUJGsx .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-FWo4uWnVyiqUJGsx .error-icon{fill:#522}#mermaid-svg-FWo4uWnVyiqUJGsx .error-text{fill:#522;stroke:#522}#mermaid-svg-FWo4uWnVyiqUJGsx .edge-thickness-normal{stroke-width:2px}#mermaid-svg-FWo4uWnVyiqUJGsx .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-FWo4uWnVyiqUJGsx .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-FWo4uWnVyiqUJGsx .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-FWo4uWnVyiqUJGsx .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-FWo4uWnVyiqUJGsx .marker{fill:#333}#mermaid-svg-FWo4uWnVyiqUJGsx .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-FWo4uWnVyiqUJGsx { color: rgba(0, 0, 0, 0.75); font: ; }</style> 呼叫者 動態連接 LoadBalancedConnectionProxy JDBC4LoadBalancedMySQLConnection JDBC4Connection MysqlIO BalanceStrategy 更換連接 呼叫者 動態連接 LoadBalancedConnectionProxy JDBC4LoadBalancedMySQLConnection JDBC4Connection MysqlIO BalanceStrategy

二、例外處理機制

1.構造階段

在我們的例里,url以jdbc:mysql:loadbalance:作為前綴,當我們使用DriverManager#getConnection命令獲取連接的時候,跟蹤呼叫鏈會一直來到NonRegisteringDriver#connect方法,而該方法分析引數url后,知道這是使用loadbalance模塊,因此就會進入NonRegisteringDriver#connectLoadBalanced方法,該方法將呼叫LoadBalancedConnectionProxy#createProxyInstance方法獲取連接,

<style>#mermaid-svg-ma13FbpfVIFcVl2u .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-ma13FbpfVIFcVl2u .label text{fill:#333}#mermaid-svg-ma13FbpfVIFcVl2u .node rect,#mermaid-svg-ma13FbpfVIFcVl2u .node circle,#mermaid-svg-ma13FbpfVIFcVl2u .node ellipse,#mermaid-svg-ma13FbpfVIFcVl2u .node polygon,#mermaid-svg-ma13FbpfVIFcVl2u .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-ma13FbpfVIFcVl2u .node .label{text-align:center;fill:#333}#mermaid-svg-ma13FbpfVIFcVl2u .node.clickable{cursor:pointer}#mermaid-svg-ma13FbpfVIFcVl2u .arrowheadPath{fill:#333}#mermaid-svg-ma13FbpfVIFcVl2u .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-ma13FbpfVIFcVl2u .flowchart-link{stroke:#333;fill:none}#mermaid-svg-ma13FbpfVIFcVl2u .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-ma13FbpfVIFcVl2u .edgeLabel rect{opacity:0.9}#mermaid-svg-ma13FbpfVIFcVl2u .edgeLabel span{color:#333}#mermaid-svg-ma13FbpfVIFcVl2u .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-ma13FbpfVIFcVl2u .cluster text{fill:#333}#mermaid-svg-ma13FbpfVIFcVl2u div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-ma13FbpfVIFcVl2u .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-ma13FbpfVIFcVl2u text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-ma13FbpfVIFcVl2u .actor-line{stroke:grey}#mermaid-svg-ma13FbpfVIFcVl2u .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-ma13FbpfVIFcVl2u .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-ma13FbpfVIFcVl2u #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-ma13FbpfVIFcVl2u .sequenceNumber{fill:#fff}#mermaid-svg-ma13FbpfVIFcVl2u #sequencenumber{fill:#333}#mermaid-svg-ma13FbpfVIFcVl2u #crosshead path{fill:#333;stroke:#333}#mermaid-svg-ma13FbpfVIFcVl2u .messageText{fill:#333;stroke:#333}#mermaid-svg-ma13FbpfVIFcVl2u .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-ma13FbpfVIFcVl2u .labelText,#mermaid-svg-ma13FbpfVIFcVl2u .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-ma13FbpfVIFcVl2u .loopText,#mermaid-svg-ma13FbpfVIFcVl2u .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-ma13FbpfVIFcVl2u .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-ma13FbpfVIFcVl2u .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-ma13FbpfVIFcVl2u .noteText,#mermaid-svg-ma13FbpfVIFcVl2u .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-ma13FbpfVIFcVl2u .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-ma13FbpfVIFcVl2u .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-ma13FbpfVIFcVl2u .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-ma13FbpfVIFcVl2u .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ma13FbpfVIFcVl2u .section{stroke:none;opacity:0.2}#mermaid-svg-ma13FbpfVIFcVl2u .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-ma13FbpfVIFcVl2u .section2{fill:#fff400}#mermaid-svg-ma13FbpfVIFcVl2u .section1,#mermaid-svg-ma13FbpfVIFcVl2u .section3{fill:#fff;opacity:0.2}#mermaid-svg-ma13FbpfVIFcVl2u .sectionTitle0{fill:#333}#mermaid-svg-ma13FbpfVIFcVl2u .sectionTitle1{fill:#333}#mermaid-svg-ma13FbpfVIFcVl2u .sectionTitle2{fill:#333}#mermaid-svg-ma13FbpfVIFcVl2u .sectionTitle3{fill:#333}#mermaid-svg-ma13FbpfVIFcVl2u .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ma13FbpfVIFcVl2u .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-ma13FbpfVIFcVl2u .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ma13FbpfVIFcVl2u .grid path{stroke-width:0}#mermaid-svg-ma13FbpfVIFcVl2u .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-ma13FbpfVIFcVl2u .task{stroke-width:2}#mermaid-svg-ma13FbpfVIFcVl2u .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ma13FbpfVIFcVl2u .taskText:not([font-size]){font-size:11px}#mermaid-svg-ma13FbpfVIFcVl2u .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ma13FbpfVIFcVl2u .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-ma13FbpfVIFcVl2u .task.clickable{cursor:pointer}#mermaid-svg-ma13FbpfVIFcVl2u .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-ma13FbpfVIFcVl2u .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-ma13FbpfVIFcVl2u .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-ma13FbpfVIFcVl2u .taskText0,#mermaid-svg-ma13FbpfVIFcVl2u .taskText1,#mermaid-svg-ma13FbpfVIFcVl2u .taskText2,#mermaid-svg-ma13FbpfVIFcVl2u .taskText3{fill:#fff}#mermaid-svg-ma13FbpfVIFcVl2u .task0,#mermaid-svg-ma13FbpfVIFcVl2u .task1,#mermaid-svg-ma13FbpfVIFcVl2u .task2,#mermaid-svg-ma13FbpfVIFcVl2u .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-ma13FbpfVIFcVl2u .taskTextOutside0,#mermaid-svg-ma13FbpfVIFcVl2u .taskTextOutside2{fill:#000}#mermaid-svg-ma13FbpfVIFcVl2u .taskTextOutside1,#mermaid-svg-ma13FbpfVIFcVl2u .taskTextOutside3{fill:#000}#mermaid-svg-ma13FbpfVIFcVl2u .active0,#mermaid-svg-ma13FbpfVIFcVl2u .active1,#mermaid-svg-ma13FbpfVIFcVl2u .active2,#mermaid-svg-ma13FbpfVIFcVl2u .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-ma13FbpfVIFcVl2u .activeText0,#mermaid-svg-ma13FbpfVIFcVl2u .activeText1,#mermaid-svg-ma13FbpfVIFcVl2u .activeText2,#mermaid-svg-ma13FbpfVIFcVl2u .activeText3{fill:#000 !important}#mermaid-svg-ma13FbpfVIFcVl2u .done0,#mermaid-svg-ma13FbpfVIFcVl2u .done1,#mermaid-svg-ma13FbpfVIFcVl2u .done2,#mermaid-svg-ma13FbpfVIFcVl2u .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-ma13FbpfVIFcVl2u .doneText0,#mermaid-svg-ma13FbpfVIFcVl2u .doneText1,#mermaid-svg-ma13FbpfVIFcVl2u .doneText2,#mermaid-svg-ma13FbpfVIFcVl2u .doneText3{fill:#000 !important}#mermaid-svg-ma13FbpfVIFcVl2u .crit0,#mermaid-svg-ma13FbpfVIFcVl2u .crit1,#mermaid-svg-ma13FbpfVIFcVl2u .crit2,#mermaid-svg-ma13FbpfVIFcVl2u .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-ma13FbpfVIFcVl2u .activeCrit0,#mermaid-svg-ma13FbpfVIFcVl2u .activeCrit1,#mermaid-svg-ma13FbpfVIFcVl2u .activeCrit2,#mermaid-svg-ma13FbpfVIFcVl2u .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-ma13FbpfVIFcVl2u .doneCrit0,#mermaid-svg-ma13FbpfVIFcVl2u .doneCrit1,#mermaid-svg-ma13FbpfVIFcVl2u .doneCrit2,#mermaid-svg-ma13FbpfVIFcVl2u .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-ma13FbpfVIFcVl2u .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-ma13FbpfVIFcVl2u .milestoneText{font-style:italic}#mermaid-svg-ma13FbpfVIFcVl2u .doneCritText0,#mermaid-svg-ma13FbpfVIFcVl2u .doneCritText1,#mermaid-svg-ma13FbpfVIFcVl2u .doneCritText2,#mermaid-svg-ma13FbpfVIFcVl2u .doneCritText3{fill:#000 !important}#mermaid-svg-ma13FbpfVIFcVl2u .activeCritText0,#mermaid-svg-ma13FbpfVIFcVl2u .activeCritText1,#mermaid-svg-ma13FbpfVIFcVl2u .activeCritText2,#mermaid-svg-ma13FbpfVIFcVl2u .activeCritText3{fill:#000 !important}#mermaid-svg-ma13FbpfVIFcVl2u .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ma13FbpfVIFcVl2u g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-ma13FbpfVIFcVl2u g.classGroup text .title{font-weight:bolder}#mermaid-svg-ma13FbpfVIFcVl2u g.clickable{cursor:pointer}#mermaid-svg-ma13FbpfVIFcVl2u g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-ma13FbpfVIFcVl2u g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-ma13FbpfVIFcVl2u .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-ma13FbpfVIFcVl2u .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-ma13FbpfVIFcVl2u .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-ma13FbpfVIFcVl2u .dashed-line{stroke-dasharray:3}#mermaid-svg-ma13FbpfVIFcVl2u #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ma13FbpfVIFcVl2u #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ma13FbpfVIFcVl2u #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-ma13FbpfVIFcVl2u #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-ma13FbpfVIFcVl2u #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ma13FbpfVIFcVl2u #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ma13FbpfVIFcVl2u #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ma13FbpfVIFcVl2u #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ma13FbpfVIFcVl2u .commit-id,#mermaid-svg-ma13FbpfVIFcVl2u .commit-msg,#mermaid-svg-ma13FbpfVIFcVl2u .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ma13FbpfVIFcVl2u .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ma13FbpfVIFcVl2u .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ma13FbpfVIFcVl2u g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ma13FbpfVIFcVl2u g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-ma13FbpfVIFcVl2u g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-ma13FbpfVIFcVl2u g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-ma13FbpfVIFcVl2u g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-ma13FbpfVIFcVl2u g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-ma13FbpfVIFcVl2u .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-ma13FbpfVIFcVl2u .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-ma13FbpfVIFcVl2u .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-ma13FbpfVIFcVl2u .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-ma13FbpfVIFcVl2u .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-ma13FbpfVIFcVl2u .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-ma13FbpfVIFcVl2u .edgeLabel text{fill:#333}#mermaid-svg-ma13FbpfVIFcVl2u .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ma13FbpfVIFcVl2u .node circle.state-start{fill:black;stroke:black}#mermaid-svg-ma13FbpfVIFcVl2u .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-ma13FbpfVIFcVl2u #statediagram-barbEnd{fill:#9370db}#mermaid-svg-ma13FbpfVIFcVl2u .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-ma13FbpfVIFcVl2u .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-ma13FbpfVIFcVl2u .statediagram-state .divider{stroke:#9370db}#mermaid-svg-ma13FbpfVIFcVl2u .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-ma13FbpfVIFcVl2u .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-ma13FbpfVIFcVl2u .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-ma13FbpfVIFcVl2u .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-ma13FbpfVIFcVl2u .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-ma13FbpfVIFcVl2u .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-ma13FbpfVIFcVl2u .note-edge{stroke-dasharray:5}#mermaid-svg-ma13FbpfVIFcVl2u .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-ma13FbpfVIFcVl2u .error-icon{fill:#522}#mermaid-svg-ma13FbpfVIFcVl2u .error-text{fill:#522;stroke:#522}#mermaid-svg-ma13FbpfVIFcVl2u .edge-thickness-normal{stroke-width:2px}#mermaid-svg-ma13FbpfVIFcVl2u .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-ma13FbpfVIFcVl2u .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-ma13FbpfVIFcVl2u .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-ma13FbpfVIFcVl2u .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-ma13FbpfVIFcVl2u .marker{fill:#333}#mermaid-svg-ma13FbpfVIFcVl2u .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-ma13FbpfVIFcVl2u { color: rgba(0, 0, 0, 0.75); font: ; }</style> 呼叫方 DriverManager NonRegisteringDriver LoadBalancedConnectionProxy getConnection connect 分析url,發現要使用loadbalance connectLoadBalanced createProxyInstance 呼叫方 DriverManager NonRegisteringDriver LoadBalancedConnectionProxy

在上述呼叫鏈的程序中,并沒有捕獲例外的行為,因此,如果LoadBalancedConnectionProxy#createProxyInstance方法的底層拋出的任何例外都會直接拋向呼叫方,所以呼叫方通常都會有一個獲取SQLException例外的行為,
我們觀察下LoadBalancedConnectionProxy#createProxyInstance方法:

public static LoadBalancedConnection createProxyInstance(List<String> hosts, Properties props) throws SQLException {
        LoadBalancedConnectionProxy connProxy = new LoadBalancedConnectionProxy(hosts, props);

        return (LoadBalancedConnection) java.lang.reflect.Proxy.newProxyInstance(LoadBalancedConnection.class.getClassLoader(), INTERFACES_TO_PROXY, connProxy);
    }

這里只有兩行命令,第一行構造LoadBalancedConnectionProxy物件,根據命令的宣告,它有可能拋出SQLException;第二句是創建動態代理物件,根據命令的宣告,它有可能拋出IllegalArgumentException,這例外是RuntimeException的子類,因此我們只需要著重觀察LoadBalancedConnectionProxy物件的構造程序,

private LoadBalancedConnectionProxy(List<String> hosts, Properties props) throws SQLException {
        super();
	....
        
    }

私有的建構式首先會呼叫父類的建構式,里面會構造JDBC4LoadBalancedMySQLConnection物件,并作為thisAsConnection屬性值,而當前的LoadBalancedConnectionProxy物件作為JDBC4LoadBalancedMySQLConnection物件的thisAsProxy屬性值,在這個程序中,其實不會拋出SQLException例外,
我們再回到LoadBalancedConnectionProxy建構式:

private LoadBalancedConnectionProxy(List<String> hosts, Properties props) throws SQLException {
        super();
	....
        // hosts specifications may have been reset with settings from a previous connection group
        int numHosts = initializeHostsSpecs(hosts, props);

        this.liveConnections = new HashMap<String, ConnectionImpl>(numHosts);
        this.hostsToListIndexMap = new HashMap<String, Integer>(numHosts);
        for (int i = 0; i < numHosts; i++) {
            this.hostsToListIndexMap.put(this.hostList.get(i), i);
        }
        this.connectionsToHostsMap = new HashMap<ConnectionImpl, String>(numHosts);
    ....
        String strategy = this.localProps.getProperty("loadBalanceStrategy", "random");
        if ("random".equals(strategy)) {
            this.balancer = (BalanceStrategy) Util.loadExtensions(null, props, RandomBalanceStrategy.class.getName(), "InvalidLoadBalanceStrategy", null)
                    .get(0);
        } else if ("bestResponseTime".equals(strategy)) {
            this.balancer = (BalanceStrategy) Util
                    .loadExtensions(null, props, BestResponseTimeBalanceStrategy.class.getName(), "InvalidLoadBalanceStrategy", null).get(0);
        } else if ("serverAffinity".equals(strategy)) {
            this.balancer = (BalanceStrategy) Util.loadExtensions(null, props, ServerAffinityStrategy.class.getName(), "InvalidLoadBalanceStrategy", null)
                    .get(0);
        } else {
            this.balancer = (BalanceStrategy) Util.loadExtensions(null, props, strategy, "InvalidLoadBalanceStrategy", null).get(0);
        }
        
		String lbExceptionChecker = this.localProps.getProperty("loadBalanceExceptionChecker", "com.mysql.jdbc.StandardLoadBalanceExceptionChecker");
        this.exceptionChecker = (LoadBalanceExceptionChecker) Util.loadExtensions(null, props, lbExceptionChecker, "InvalidLoadBalanceExceptionChecker", null)
                .get(0);
    ....
        pickNewConnection();
    }

它根據url里的ip:port集合填充了hostsToListIndexMap屬性,key為ip:port的值,value為從0開始的下標值,同時也構造了與ConnectionImpl有關的屬性:liveConnections和connectionsToHostsMap,這兩屬性會在后面添加ConnectionImpl物件,
隨后還會根據url里的loadBalanceStrategy選項構造對應的策略物件,并作為balance屬性值,
最后初始化了例外檢查器exceptionChecker,如果url里有指定的就使用指定的類來構造,沒有的話就使用默認的com.mysql.jdbc.StandardLoadBalanceExceptionChecker物件,
在建構式的方法體里,pickNewConnection方法之前,雖然有些呼叫的方法會拋出例外,但都有捕獲行為,因此到目前為止仍然安全,我們接著進入非常眼熟的pickNewConnection方法一探究竟:

@Override
    synchronized void pickNewConnection() throws SQLException {
    ....
         if (this.currentConnection == null) { // startup
            this.currentConnection = this.balancer.pickConnection(this, Collections.unmodifiableList(this.hostList),
                    Collections.unmodifiableMap(this.liveConnections), this.responseTimes.clone(), this.retriesAllDown);
            return;
        }
   ....
    }

該方法被currentConnection 屬性是否為空區分出兩種呼叫場景,在構造動態代理連接的時候,currentConnection 屬性肯定為空,根據代碼,它會通過balancer的pickConnection方法獲取底層連接,
我們假設balancer使用的是RandomBalanceStrategy,它的pickConnection方法就是隨機的從url里挑出一個ip:port組合并建立連接,若第一次不成功將會再次嘗試隨機挑選ip:port組合并建立連接,在允許嘗試次內成功建立連接的話,就正常回傳,否則會拋出通訊例外,另外,一旦出現資料例外,也會立即拋出例外,由于篇幅關系,在此不貼出代碼了,

小結

在構造動態代理連接時,如果所有的ip:port都未能成功建立連接,通訊例外會拋向呼叫者,如果建立連接中出現資料例外,該例外也會拋向呼叫者,或者說在構造階段,呼叫者能夠感知到資料例外以及極端情況下的通訊例外,

2.使用階段

MultiHostConnectionProxy直接多載了java.lang.reflect.InvocationHandler介面的invoke方法,我們先觀察一下:

public synchronized Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        ....
        try {
            return invokeMore(proxy, method, args);
        } catch (InvocationTargetException e) {
            throw e.getCause() != null ? e.getCause() : e;
        } catch (Exception e) {
            // Check if the captured exception must be wrapped by an unchecked exception.
            Class<?>[] declaredException = method.getExceptionTypes();
            for (Class<?> declEx : declaredException) {
                if (declEx.isAssignableFrom(e.getClass())) {
                    throw e;
                }
            }
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

該方法的省略部分不會拋例外,但它對invokeMore有一個獲取例外的行為,并且區分了InvocationTargetException和其他的情況的例外,從這里來看,底層拋上來的例外都會往呼叫者拋,而invokeMore方法被LoadBalancedConnectionProxy多載,我們進一步觀察下:

@Override
    public synchronized Object invokeMore(Object proxy, Method method, Object[] args) throws Throwable {
       ....
        Object result = null;
        try {
            result = method.invoke(this.thisAsConnection, args);
		....
        } catch (InvocationTargetException e) {
            dealWithInvocationException(e);

        } finally {
        ....
        }

        return result;
    }

在方法里我們看到有捕獲InvocationTargetException 的行為,因為以反射的形式呼叫,所以一旦有問題會以InvocationTargetException的形式拋出,也就是說,底層發生的例外都會被捕獲到,MultiHostConnectionProxy#dealWithInvocationException方法進一步分析原始例外型別:

void dealWithInvocationException(InvocationTargetException e) throws SQLException, Throwable, InvocationTargetException {
        Throwable t = e.getTargetException();

        if (t != null) {
            if (this.lastExceptionDealtWith != t && shouldExceptionTriggerConnectionSwitch(t)) {
                invalidateCurrentConnection();
                pickNewConnection();
                this.lastExceptionDealtWith = t;
            }
            throw t;
        }
        throw e;
    }

從代碼結構上看,例外是一定會往上拋,因為MultiHostConnectionProxy#dealWithInvocationException方法是在LoadBalancedConnectionProxy#invokeMore的catch代碼塊里呼叫,而該catch代碼塊沒有進一步捕獲例外,因此例外將到達MultiHostConnectionProxy#invoke方法里的捕獲例外的代碼塊,前文通過觀察它的捕獲例外代碼塊可知道,例外最侄訓繼續向上層拋,也就是說,在使用連接的程序中,一旦遇到通訊例外或者資料例外,呼叫者都會感知到,當例外發生時,我們可以基本知道它經過的地方:

<style>#mermaid-svg-SuG6i0lxYx8mIKrW .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .label text{fill:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .node rect,#mermaid-svg-SuG6i0lxYx8mIKrW .node circle,#mermaid-svg-SuG6i0lxYx8mIKrW .node ellipse,#mermaid-svg-SuG6i0lxYx8mIKrW .node polygon,#mermaid-svg-SuG6i0lxYx8mIKrW .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-SuG6i0lxYx8mIKrW .node .label{text-align:center;fill:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .node.clickable{cursor:pointer}#mermaid-svg-SuG6i0lxYx8mIKrW .arrowheadPath{fill:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-SuG6i0lxYx8mIKrW .flowchart-link{stroke:#333;fill:none}#mermaid-svg-SuG6i0lxYx8mIKrW .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-SuG6i0lxYx8mIKrW .edgeLabel rect{opacity:0.9}#mermaid-svg-SuG6i0lxYx8mIKrW .edgeLabel span{color:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-SuG6i0lxYx8mIKrW .cluster text{fill:#333}#mermaid-svg-SuG6i0lxYx8mIKrW div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-SuG6i0lxYx8mIKrW .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-SuG6i0lxYx8mIKrW text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-SuG6i0lxYx8mIKrW .actor-line{stroke:grey}#mermaid-svg-SuG6i0lxYx8mIKrW .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-SuG6i0lxYx8mIKrW #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .sequenceNumber{fill:#fff}#mermaid-svg-SuG6i0lxYx8mIKrW #sequencenumber{fill:#333}#mermaid-svg-SuG6i0lxYx8mIKrW #crosshead path{fill:#333;stroke:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .messageText{fill:#333;stroke:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-SuG6i0lxYx8mIKrW .labelText,#mermaid-svg-SuG6i0lxYx8mIKrW .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-SuG6i0lxYx8mIKrW .loopText,#mermaid-svg-SuG6i0lxYx8mIKrW .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-SuG6i0lxYx8mIKrW .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-SuG6i0lxYx8mIKrW .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-SuG6i0lxYx8mIKrW .noteText,#mermaid-svg-SuG6i0lxYx8mIKrW .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-SuG6i0lxYx8mIKrW .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-SuG6i0lxYx8mIKrW .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-SuG6i0lxYx8mIKrW .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-SuG6i0lxYx8mIKrW .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-SuG6i0lxYx8mIKrW .section{stroke:none;opacity:0.2}#mermaid-svg-SuG6i0lxYx8mIKrW .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-SuG6i0lxYx8mIKrW .section2{fill:#fff400}#mermaid-svg-SuG6i0lxYx8mIKrW .section1,#mermaid-svg-SuG6i0lxYx8mIKrW .section3{fill:#fff;opacity:0.2}#mermaid-svg-SuG6i0lxYx8mIKrW .sectionTitle0{fill:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .sectionTitle1{fill:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .sectionTitle2{fill:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .sectionTitle3{fill:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-SuG6i0lxYx8mIKrW .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-SuG6i0lxYx8mIKrW .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-SuG6i0lxYx8mIKrW .grid path{stroke-width:0}#mermaid-svg-SuG6i0lxYx8mIKrW .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-SuG6i0lxYx8mIKrW .task{stroke-width:2}#mermaid-svg-SuG6i0lxYx8mIKrW .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-SuG6i0lxYx8mIKrW .taskText:not([font-size]){font-size:11px}#mermaid-svg-SuG6i0lxYx8mIKrW .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-SuG6i0lxYx8mIKrW .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-SuG6i0lxYx8mIKrW .task.clickable{cursor:pointer}#mermaid-svg-SuG6i0lxYx8mIKrW .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-SuG6i0lxYx8mIKrW .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-SuG6i0lxYx8mIKrW .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-SuG6i0lxYx8mIKrW .taskText0,#mermaid-svg-SuG6i0lxYx8mIKrW .taskText1,#mermaid-svg-SuG6i0lxYx8mIKrW .taskText2,#mermaid-svg-SuG6i0lxYx8mIKrW .taskText3{fill:#fff}#mermaid-svg-SuG6i0lxYx8mIKrW .task0,#mermaid-svg-SuG6i0lxYx8mIKrW .task1,#mermaid-svg-SuG6i0lxYx8mIKrW .task2,#mermaid-svg-SuG6i0lxYx8mIKrW .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-SuG6i0lxYx8mIKrW .taskTextOutside0,#mermaid-svg-SuG6i0lxYx8mIKrW .taskTextOutside2{fill:#000}#mermaid-svg-SuG6i0lxYx8mIKrW .taskTextOutside1,#mermaid-svg-SuG6i0lxYx8mIKrW .taskTextOutside3{fill:#000}#mermaid-svg-SuG6i0lxYx8mIKrW .active0,#mermaid-svg-SuG6i0lxYx8mIKrW .active1,#mermaid-svg-SuG6i0lxYx8mIKrW .active2,#mermaid-svg-SuG6i0lxYx8mIKrW .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-SuG6i0lxYx8mIKrW .activeText0,#mermaid-svg-SuG6i0lxYx8mIKrW .activeText1,#mermaid-svg-SuG6i0lxYx8mIKrW .activeText2,#mermaid-svg-SuG6i0lxYx8mIKrW .activeText3{fill:#000 !important}#mermaid-svg-SuG6i0lxYx8mIKrW .done0,#mermaid-svg-SuG6i0lxYx8mIKrW .done1,#mermaid-svg-SuG6i0lxYx8mIKrW .done2,#mermaid-svg-SuG6i0lxYx8mIKrW .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-SuG6i0lxYx8mIKrW .doneText0,#mermaid-svg-SuG6i0lxYx8mIKrW .doneText1,#mermaid-svg-SuG6i0lxYx8mIKrW .doneText2,#mermaid-svg-SuG6i0lxYx8mIKrW .doneText3{fill:#000 !important}#mermaid-svg-SuG6i0lxYx8mIKrW .crit0,#mermaid-svg-SuG6i0lxYx8mIKrW .crit1,#mermaid-svg-SuG6i0lxYx8mIKrW .crit2,#mermaid-svg-SuG6i0lxYx8mIKrW .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-SuG6i0lxYx8mIKrW .activeCrit0,#mermaid-svg-SuG6i0lxYx8mIKrW .activeCrit1,#mermaid-svg-SuG6i0lxYx8mIKrW .activeCrit2,#mermaid-svg-SuG6i0lxYx8mIKrW .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-SuG6i0lxYx8mIKrW .doneCrit0,#mermaid-svg-SuG6i0lxYx8mIKrW .doneCrit1,#mermaid-svg-SuG6i0lxYx8mIKrW .doneCrit2,#mermaid-svg-SuG6i0lxYx8mIKrW .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-SuG6i0lxYx8mIKrW .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-SuG6i0lxYx8mIKrW .milestoneText{font-style:italic}#mermaid-svg-SuG6i0lxYx8mIKrW .doneCritText0,#mermaid-svg-SuG6i0lxYx8mIKrW .doneCritText1,#mermaid-svg-SuG6i0lxYx8mIKrW .doneCritText2,#mermaid-svg-SuG6i0lxYx8mIKrW .doneCritText3{fill:#000 !important}#mermaid-svg-SuG6i0lxYx8mIKrW .activeCritText0,#mermaid-svg-SuG6i0lxYx8mIKrW .activeCritText1,#mermaid-svg-SuG6i0lxYx8mIKrW .activeCritText2,#mermaid-svg-SuG6i0lxYx8mIKrW .activeCritText3{fill:#000 !important}#mermaid-svg-SuG6i0lxYx8mIKrW .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-SuG6i0lxYx8mIKrW g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-SuG6i0lxYx8mIKrW g.classGroup text .title{font-weight:bolder}#mermaid-svg-SuG6i0lxYx8mIKrW g.clickable{cursor:pointer}#mermaid-svg-SuG6i0lxYx8mIKrW g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-SuG6i0lxYx8mIKrW g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-SuG6i0lxYx8mIKrW .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-SuG6i0lxYx8mIKrW .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-SuG6i0lxYx8mIKrW .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-SuG6i0lxYx8mIKrW .dashed-line{stroke-dasharray:3}#mermaid-svg-SuG6i0lxYx8mIKrW #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-SuG6i0lxYx8mIKrW #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-SuG6i0lxYx8mIKrW #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-SuG6i0lxYx8mIKrW #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-SuG6i0lxYx8mIKrW #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-SuG6i0lxYx8mIKrW #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-SuG6i0lxYx8mIKrW #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-SuG6i0lxYx8mIKrW #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-SuG6i0lxYx8mIKrW .commit-id,#mermaid-svg-SuG6i0lxYx8mIKrW .commit-msg,#mermaid-svg-SuG6i0lxYx8mIKrW .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-SuG6i0lxYx8mIKrW .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-SuG6i0lxYx8mIKrW .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-SuG6i0lxYx8mIKrW g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-SuG6i0lxYx8mIKrW g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-SuG6i0lxYx8mIKrW g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-SuG6i0lxYx8mIKrW g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-SuG6i0lxYx8mIKrW g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-SuG6i0lxYx8mIKrW g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-SuG6i0lxYx8mIKrW .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-SuG6i0lxYx8mIKrW .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-SuG6i0lxYx8mIKrW .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-SuG6i0lxYx8mIKrW .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-SuG6i0lxYx8mIKrW .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-SuG6i0lxYx8mIKrW .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-SuG6i0lxYx8mIKrW .edgeLabel text{fill:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-SuG6i0lxYx8mIKrW .node circle.state-start{fill:black;stroke:black}#mermaid-svg-SuG6i0lxYx8mIKrW .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-SuG6i0lxYx8mIKrW #statediagram-barbEnd{fill:#9370db}#mermaid-svg-SuG6i0lxYx8mIKrW .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-SuG6i0lxYx8mIKrW .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-SuG6i0lxYx8mIKrW .statediagram-state .divider{stroke:#9370db}#mermaid-svg-SuG6i0lxYx8mIKrW .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-SuG6i0lxYx8mIKrW .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-SuG6i0lxYx8mIKrW .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-SuG6i0lxYx8mIKrW .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-SuG6i0lxYx8mIKrW .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-SuG6i0lxYx8mIKrW .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-SuG6i0lxYx8mIKrW .note-edge{stroke-dasharray:5}#mermaid-svg-SuG6i0lxYx8mIKrW .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-SuG6i0lxYx8mIKrW .error-icon{fill:#522}#mermaid-svg-SuG6i0lxYx8mIKrW .error-text{fill:#522;stroke:#522}#mermaid-svg-SuG6i0lxYx8mIKrW .edge-thickness-normal{stroke-width:2px}#mermaid-svg-SuG6i0lxYx8mIKrW .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-SuG6i0lxYx8mIKrW .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-SuG6i0lxYx8mIKrW .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-SuG6i0lxYx8mIKrW .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-SuG6i0lxYx8mIKrW .marker{fill:#333}#mermaid-svg-SuG6i0lxYx8mIKrW .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-SuG6i0lxYx8mIKrW { color: rgba(0, 0, 0, 0.75); font: ; }</style> Method#invoke LoadBalanceConnectionProxy#invokeMore的catch代碼塊 MultiHostConnectionProxy#dealWithInvocationException MultiHostConnectionProxy#invoke的catch代碼塊 呼叫者 Method#invoke LoadBalanceConnectionProxy#invokeMore的catch代碼塊 MultiHostConnectionProxy#dealWithInvocationException MultiHostConnectionProxy#invoke的catch代碼塊 呼叫者

我們把目光放回到MultiHostConnectionProxy#dealWithInvocationException:

void dealWithInvocationException(InvocationTargetException e) throws SQLException, Throwable, InvocationTargetException {
        Throwable t = e.getTargetException();

        if (t != null) {
            if (this.lastExceptionDealtWith != t && shouldExceptionTriggerConnectionSwitch(t)) {
                invalidateCurrentConnection();
                pickNewConnection();
                this.lastExceptionDealtWith = t;
            }
            throw t;
        }
        throw e;
    }

呼叫的shouldExceptionTriggerConnectionSwitch被LoadBalanceConnectionProxy多載了:

@Override
    boolean shouldExceptionTriggerConnectionSwitch(Throwable t) {
        return t instanceof SQLException && this.exceptionChecker.shouldExceptionTriggerFailover((SQLException) t);
    }

我們假設exceptionChecker使用的是默認的com.mysql.jdbc.StandardLoadBalanceExceptionChecker
該類有兩個集合sqlStateList和sqlExClassList,而集合的元素分別來自于url的loadBalanceSQLStateFailover和loadBalanceSQLExceptionSubclassFailover選項,看官可以通過官網了解這兩選項,在此不詳述,
shouldExceptionTriggerFailover方法在以下情況此方法會回傳true:

  • 錯誤碼以08開頭
  • 錯誤碼雖然不以08開頭,但錯誤碼以sqlStateList任一元素值開頭
  • 拋出的例外是通訊例外CommunicationsException
  • 拋出的例外型別是sqlExClassList任一元素的例外型別相等或者是子類,
    也就是說,只要是通訊例外或者用戶指定的例外,該方法都會回傳true,
    我們再次結合MultiHostConnectionProxy#dealWithInvocationException來看:
void dealWithInvocationException(InvocationTargetException e) throws SQLException, Throwable, InvocationTargetException {
        Throwable t = e.getTargetException();

        if (t != null) {
            if (this.lastExceptionDealtWith != t && shouldExceptionTriggerConnectionSwitch(t)) {
                invalidateCurrentConnection();
                pickNewConnection();
                this.lastExceptionDealtWith = t;
            }
            throw t;
        }
        throw e;
    }

如果例外屬于通訊例外以及用戶指定的情況一旦發生,首先更新連接,然后將例外往上拋,

小結

動態代理連接在構造階段和使用階段,一旦遇到任何例外,都會被呼叫者感知到(構造階段遇到所有的ip:port連接失敗才拋出通訊例外),這一點與failover確實不一樣,在使用階段,呼叫者可以馬上停止當前事務程序而重新再來,這樣會讓事務操作變得可以掌控,也可以說事務的原子性得以保證,它的這種特性,也符合我們使用普通Connection時的編程規范(try…事務操作…catch…回滾事務…finally…關閉資源…),因此,如果我們專案一開始比較小,使用普通的Connection模式,到后來需要資料庫結構升級為支持多主機的時候,我們不需要修改代碼,只需要修改下url配置即可,

三、autoReconnect選項

根據官網介紹autoReconnect選項是failover模塊重要選項之一,在loadbalance的描述部分只字未提,但我們通過閱讀代碼時會看到它的身影,本節就一起分析該選項所起到的作用,
該選項對應著autoReconnect屬性,而該項屬性被使用到的地方僅在于
LoadBalancedConnectionProxy#invokeMore方法:

@Override
    public synchronized Object invokeMore(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        if (this.isClosed && !allowedOnClosedConnection(method) && method.getExceptionTypes().length > 0) {
            if (this.autoReconnect && !this.closedExplicitly) {
                // try to reconnect first!
                this.currentConnection = null;
                pickNewConnection();
        	....
        Object result = null;
        try {
            result = method.invoke(this.thisAsConnection, args);
           ....
        return result;
    }

在Method#invke前,它是呼叫pickNewConnection的條件之一,我們分析下各項條件成立的因素:

  • this.isClosed為真值
    該值為真值的地方出現在:
    1)pickNewConnection方法體里,如果url的ip:port都不能成功建立連接,就為真值,
    2)doPing方法體里,如果未能ping成功,就為真值,
    3)執行連接的close方法
    4)執行連接的abortInternal方法
    5)執行連接的abort方法
  • !allowedOnClosedConnection為真值
    只要不執行連接的以下方法就會成立:
    1)連接的getAutoCommit方法
    2)連接的getCatalog方法
    3)連接的getTransactionIsolation方法
    4)連接的getSessionMaxRows方法
  • method.getExceptionTypes().length > 0
    只要方法宣告會拋例外即滿足,
  • this.autoReconnect
    url上添加autoReconnect=true選項即滿足,
  • !this.closedExplicitly
    不執行連接的close方法即可為真:

作用分析

所以假設用戶在url添加了autoReconnect=true的情況下,并且呼叫方呼叫動態連接的上一條命令不是close方法情況下,大致可以梳理出以下2個場景:
1)用戶已經成功獲取動態代理,在使用時由于網路原因使得url里所有的ip:port都不能成功建立連接,前文講述過invokeMore方法遇到通訊例外時,最侄訓執行pickNewConnection方法并拋出通訊例外,如果url里所有的ip:port都未能成功建立連接,isClosed為true,當網路恢復正常,重新執行的操作會先嘗試更新連接,
2)呼叫者先呼叫接連的abort或者abortInternal方法,然后再執行增刪改查的命令,也就是說呼叫方可能通過呼叫abort或者abortInternal方法主動地更換連接,然后再操作資料,

對于前一點,當網路出現極端情況下,極大方便了開發人員,因為他們不必考慮如何解決這種情況下的重連,另外,也可以理解為是一個兜底的保障作用,確保一旦網路恢復后,仍能正常執行SQL操作,
對于第二點,可理解為給呼叫者提供更靈活的手段,在需要的時候呼叫abort或者abortInternal命令更換連接,然后再進行SQL操作,所以說它是讓這個機制更完善,

所以,基于上面的分析,官網上其實可以多作介紹的,

四、何時重建連接

重建連接的操作以LoadBalancedConnectionProxy#pickNewConnection為入口,該方法會輪循url各組ip:port,只要有一組能夠連接成功就算建立了與Mysql的連接,如果沒有一組能夠成功建立連接,設定isClosed為true,
那么該方法中哪些時間點上會被呼叫呢?

  1. 構造動態代理連接j時,LoadBalancedConnectionProxy的建構式會呼叫該方法,
  2. 正式呼叫Method#invoke方法前有可能執行,請看上一節,
  3. 呼叫Method#invoke方法出現了通訊例外,
  4. 執行完commit或者rollback方法后,

所以,如果某個ip:port對應的底層連接能夠正常作業,它就有可能不會被更換,之所以說有可能,是因為當呼叫者關閉自動提交,執行完SQL命令后,發送commit或者rollback命令時,它將被更換,也就是說,當一筆事務完成了就需要更換底層連接,這樣從另一個角度看,它至少保證了事務內的命令只由一個底層的連接傳送,這樣就不會出現一筆事務內的命令有的在A服務器運行有的在B服務器運行,確保資料的一致性,如果呼叫者沒有關閉自動提交,執行查詢命令或者更新單筆資料,底層連接不會更換,

五、實用性分析

動態代理連接在使用中遇到例外能夠被呼叫方即時感知到,這使得loadbalance模式具有使用的價值,故名思義,真讓人以為此模式能起到負載均衡的效果,但根據前面切換連接的分析,并不是那回事,它其實是遇到通訊例外時,更換底層連接,讓呼叫者繼續使用動態代理發送SQL命令,所以,這里涉及到Mysql多機部署和資料一致性的問題,

  • 對于微型專案,可以采用如下結構:
    在這里插入圖片描述讓兩臺Mysql服務器互為主備,

  • 讓高可用性上一個臺階,可使用Percona XtraDB:
    在這里插入圖片描述它可實作集群內所有Mysql服務器資料的強一致性,但是如果成員太多,為保持資料的一致性會導致性能有所下降,

  • 使用資料庫中間件和集群
    在這里插入圖片描述此方法由中間件分析出SQL操作是讀操作還是寫操作,然后將操作分配給專門用于讀的服務器或者專門用于接受寫命令的服務器,此方案要求最高,但它兼顧了高可用和性能,

六、總結

Loadbalance模式具有使用價值,其特點如下:

  • 呼叫者在使用程序中能夠感知到底層發生的例外,另外呼叫者只需構造一個動態代理連接即可,
  • 呼叫者在使用程序中遇到例外,處理方法與使用普通的Connection一樣,使用者如果想從普通的Connection升級到Loadbalance模式,在應用層面只需要修改url,無需改代碼,
  • 可擴展性強,用戶發現資料庫資源占用高,可以多安排設備,然后在url里添加更多的ip:port即可,
  • Loadbalance模式會更換底層連接,所以需要部署多臺Mysql服務器,另外,當前一筆事務正常運行完畢,下一筆事務遇到通訊例外,底層連接就會被替換,下次重新執行第二筆事務將在另外一臺服務器上執行,所以這里存在資料同步問題,所以使用此模式,需要掌握Mysql多機的部署知識,而且必須要將資料的一致性放在最首要的位置來考慮,
  • 高可用性,根據上一點,使用好Loadbalance模式,無形中實作了資料的高可用性,

根據“四、何時重建連接”一節可知,Loadbalace模式通常在遇到通訊例外或者提交/回滾事務的時候才更換連接,它的核心目的只不過是讓呼叫者可以重復使用動態代理連接,此Loadbalance與我們想象中的負載均衡不是同一個概念,如果用戶對回應速度有比較高的要求,這種模式就不能勝任了,后續文章將介紹replication模式,看看它在提高回應速度方面有何設計良方,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/155412.html

標籤:其他

上一篇:Python學習2020/10/2

下一篇:學會這招,小姐姐看你的眼神將不一樣

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more