主頁 > 後端開發 > Mysql Connector/J 原始碼分析(LoadBalance)

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

2020-10-04 18:20:21 後端開發

文章目錄

  • 前言
  • 名詞定義
  • 一、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/houduan/155184.html

標籤:python

上一篇: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)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more