涓€銆佸墠瑷€鏈€杩戝湪榧撴崳demo搴旂敤鐨勬椂鍊欙紝鍙戠幇涓€涓猟ruid杩炴帴姹犲鑷寸殑绾跨▼闃诲闂銆傚厛澹版槑涓€涓嬶紝杩欎釜闂鏄痙ruid1.1.23涔嬪墠鐨刡ug锛屽苟涓嶆槸璇磀ruid鏈夋槑鏄剧殑鎬ц兘闂銆傚叾瀹瀏ithub涓婃湁鐩稿叧闂锛歨ttps://github.com/alibaba/dr...锛涗篃鍙互鍏虫敞涓€涓媎ruid鍚勪釜鐗堟湰鐨勫彂甯冧俊鎭細https://github.com/alibaba/dr....鍙戠幇杩欎釜闂鐨勬椂鍊欙紝骞朵笉鐭ラ亾鍏跺疄鏄竴涓猙ug锛屼竴鐩村湪fixed锛屾墍浠ユ妸鍒嗘瀽杩囩▼鐨勪竴浜涚嚎绱㈣褰曚笅鏉ワ紝浠婂ぉ涓昏鍒嗕韩鎺掗敊鐨勬€濊矾銆?.Let'sGo(1)涓ラ噸绾跨▼闃诲浜嬩欢璧锋簮浜庡湪鍑嗗瀹㈡埛鐨刣emo鐜鏃惰繘琛屼簡涓€杞帇鍔涙祴璇曪紙楠岃瘉鐜锛夈€傚湪鍘嬪姏娴嬭瘯涓紝鍙戠幇璁块棶鏁版嵁搴撶殑鎺ュ彛鍝嶅簲鏃堕棿寮傚父楂樸€傝櫧鐒舵湁鎰忚繘琛屼簡寰幆鏁版嵁搴撶殑鎿嶄綔锛堜竴娆ttp璇锋眰锛?0娆ysql鏌ヨ锛夛紝浣嗘槸瀵逛簬鍙繘琛岀畝鍗曟煡璇㈢殑sql鏉ヨ锛屾帴鍙g殑鍝嶅簲鏃堕棿灏辨樉寰楀紓甯镐簡銆傚厛鏌ョ湅搴旂敤鏈嶅姟鐨勮祫婧愪娇鐢ㄦ儏鍐碉紝涓€鍒囨甯革紱妫€鏌vm鐨勮繍琛岀姸鎬併€傚湪鐑偣鏂规硶銆愭柟娉曟秷鑰楃殑CPU璧勬簮銆戜腑锛屾垜浠彲浠ョ湅鍒皕ip鍘嬬缉鐩稿叧鐨勬柟娉曞湪娑堣€桟PU璧勬簮鏃舵€绘槸鎺掑湪绗竴浣嶏細灞曞紑鏂规硶璋冪敤閾撅紝鍙戠幇鏄被鍔犺浇瀵艰嚧鐨勶紱銆愪綘鑳界‘瀹氾紝搴旂敤纭畾鍦ㄥ摢閲岋紵鏈夐棶棰樸€憈hreaddump锛屾煡鐪嬬嚎绋嬪湪骞蹭粈涔堬紝鏌ョ湅绫诲姞杞界浉鍏崇殑瀹屾暣绾跨▼鏍堛€傚湪threaddump涓彂鐜颁竴涓ぇ闂锛?7%鐨勪笟鍔$嚎绋嬮兘澶勪簬闃诲鐘舵€侊細鍒嗘瀽threaddump鎵惧嚭闃诲鐨勪富瑕佸師鍥犮€傚彂鐜版槸绫诲姞杞芥搷浣滃鑷村ぇ閲忕嚎绋嬮樆濉炪€傜被鍔犺浇鎿嶄綔鍏跺疄鏄痙ruid鐩稿叧鐨勬柟娉曞紩璧风殑锛堝悗闈細璇村叾瀹炴槸杩炴帴妫€娴嬪紩璧风殑锛夛紱椤圭洰涓娇鐢ㄧ殑druid杩炴帴姹犵殑涓€浜涢厤缃弬鏁帮細initialSize:5minIdle:5maxIdle:5maxActive:5maxWait:60000timeBetweenEvictionRunsMillis:60000minEvictableIdleTimeMillis:300000validationQuery:SELECT1FROMDUALpoolPreparedStatements:truetestWhileIdle:true//DetecttestOnBorrowwhenobtainingconnection:true//妫€娴媡estOnReturn:true杩斿洖杩炴帴鏃舵棤娉曡鏁帮紝'wall'鐢ㄤ簬闃茬伀澧欒繃婊ゅ櫒锛歴tat,wall,slf4jmaxPoolPreparedStatementPerConnectionSize:20useGlobalDataSourceStat:trueconnectionProperties:druid.stat.mergeSql=true;druid.stat.slowSqlMillis=1000鍙互鐪嬪埌锛岃繖閲屽湪杩炴帴妫€娴嬮厤缃腑閮芥坊鍔犱簡锛屽嵆鍦ㄨ繛鎺ヨ幏鍙栥€佽繑鍥炶繛鎺ャ€佽繛鎺ョ┖闂查樁娈甸兘浼氳繘琛岃繛鎺ユ娴嬨€傘€愯€冭檻鎬ц兘褰卞搷锛氫竴鑸笉寮€鍚痶estOnReturn鍜宼estOnReturn锛岃€屾槸浣跨敤testWhileIdle鍜宼imeBetweenEvictionRunsMillis鏉ユ娴嬬┖闂茶繛鎺ャ€戙€冧笅闈㈢畝鍗曞垎鏋愪竴涓媎ruid鐨勯儴鍒嗘簮鐮佸拰druid1.1.23鐗堟湰涔嬪墠bug鐨勭浉鍏虫簮鐮併€倀ips馃弾锛氬彲浠ョ洿鎺ヨ烦杞埌鍚庨潰鐨刧etLastPacketReceivedTimeMs绔犺妭鐩存帴杩涘叆druidbug鐩稿叧闂锛?浜?杩炴帴妫€娴嬮儴鍒嗘簮鐮?.getConnectionDirect鈥斺€旇繛鎺ユ娴嬪叆鍙h皟鐢╣etConnection()鑾峰彇杩炴帴鍚庯紝鏈€缁堜細璋冪敤com.alibaba.druid銆俻ool.DruidDataSource#getConnectionDirect鏂规硶銆傚湪getConnectionDirect鏂规硶涓細鍒ゆ柇鏄惁閬靛惊杩炴帴妫€娴嬬殑閫昏緫銆備互涓嬩负涓昏婧愮爜锛堝叾浠栧垎鏀€昏緫鍥犵瘒骞呭師鍥狅紝宸插幓鎺夌粏鑺傦紝鍙嚜琛岄槄璇伙級锛歱ublicDruidPooledConnectiongetConnectionDirect(longmaxWaitMillis)throwsSQLException{intnotFullTimeoutRetryCnt=0;for(;;){//DruidPooledConnection灏佽鐗╃悊杩炴帴瀵硅薄DruidPooledConnectionpoolableConnection;try{//杩欐槸杩炴帴妫€娴嬬殑鏍稿績浠g爜poolableConnection=getConnectionInternal(maxWaitMillis);}catch(GetConnectionTimeoutExceptionex){if(notFullTimeoutRetryCnt<=this.notFullTimeoutRetryCount&&!isFull()){notFullTimeoutRetryCnt++;if(LOG.isWarnEnabled()){LOG.warn("鑾峰彇杩炴帴瓒呮椂閲嶈瘯锛?+notFullTimeoutRetryCnt);}缁х画;}鎵斿墠;锛堟牴鎹笂闈㈢殑閰嶇疆锛屼細鍏堣緭鍏ヨ繖娈典唬鐮侊級if(testOnBorrow){booleanvalidate=testConnectionInternal(poolableConnection.holder,poolableConnection.conn);if(!validate){if(LOG.isDebugEnabled()){LOG.debug("璺宠繃涓嶉獙璇佽繛鎺ャ€?);}discardConnection(poolableConnection.holder);缁х画;}}else{if(poolableConnection.conn.isClosed()){discardConnection(poolableConnection.holder);//浼犲叆null锛岄伩鍏峜ontinue閲嶅鍏抽棴锛泒//鏄惁寮€鍚┖闂叉娴嬶紝浼氭牴鎹┖闂叉椂闂达紝鍒ゆ柇鏄惁杩涜杩炴帴妫€娴媔f(testWhileIdle){//......}}//removeAbandoned鍙傛暟鏄惁寮€鍚紙涓嶆帹鑽愶紝灏嗚幏鍙栫嚎绋嬪爢鏍堜俊鎭?if(removeAbandoned){//......}if(!this.defaultAutoCommit){poolableConnection.setAutoCommit锛堝亣锛夛紱}杩斿洖poolableConnection;}}2銆倀estConnectionInternal-杩炴帴妫€娴嬫牳蹇冧唬鐮乧om.alibaba.druid.pool.DruidAbstractDataSource#testConnectionInternal鏄繛鎺ユ娴嬬殑鏍稿績浠g爜鍚敤testOnReturn鍜宼estOnReturn鍚庯紝鏍稿績杩炴帴娴嬭瘯閫昏緫灏卞湪杩欍€備袱涓叧閿柟娉曪細validConnectionChecker.isValidConnection()瀹為檯涓婅皟鐢ㄤ簡com.alibaba.druid.pool.vendor.MySqlValidConnectionChecker#isValidConnection()銆備富瑕佸仛涓や欢浜嬶細1.鍏堝悜mysql鏈嶅姟鍣ㄥ彂閫乸ing淇℃伅锛屾娴媡cp杩炴帴鏄惁鍙敤锛?銆佹墽琛寁alidationQuery閰嶇疆鐨凷QL鏌ヨ璇彞锛汳ySqlUtils.getLastPacketReceivedTimeMs()鐢ㄤ簬鑾峰彇杩炴帴绌洪棽鏃堕棿銆傝繖涓柟娉曚篃鏄粖澶╃嚎绋嬭鍫电殑缃瓉绁搁锛沺rotectedbooleantestConnectionInternal(DruidConnectionHolderholder,Connectionconn){//......othertry{if(validConnectionChecker!=null){//isValidConnection纭疄鍋氫簡妫€娴嬫柟娉曪紝浼氬仛涓や欢浜?/1.棣栧厛鍙戦€佸悜mysql鏈嶅姟鍣╬ing淇℃伅锛屾娴媡cp杩炴帴鏄惁鍙敤锛?/2.鎵цvalidationQuery閰嶇疆鐨凷QL鏌ヨ璇彞锛沚ooleanvalid=validConnectionChecker.isValidConnection(conn,validationQuery,validationQueryTimeout);longcurrentTimeMillis=System.currentTimeMillis();if(holder!=null){holder.lastValidTimeMillis=currentTimeMillis;holder.lastExecTimeMillis=currentTimeMillis;}//濡傛灉鏄痬ysql鏁版嵁搴擄紝閫氳繃杩炴帴娴嬭瘯锛屽垯杈撳叆濡備笅浠g爜濡傛灉(lastPacketReceivedTimeMs>0){longmysqlIdleMillis=currentTimeMillis-lastPacketReceivedTimeMs;if(lastPacketReceivedTimeMs>0//&&mysqlIdleMillis>=timeBetweenEvictionRunsMillis){discardConnection(holder);StringerrorMsg="涓㈠純闀挎椂闂存湭鏀跺埌鐨勮繛鎺ャ€?+",jdbcUrl:"+jdbcUrl+",version:"+VERSION.getVersionNumber()+",lastPacketReceivedIdleMillis:"+mysqlIdleMillis;鏃ュ織璀﹀憡锛堥敊璇秷鎭級锛涜繑鍥炲亣锛泒}}if(valid&&onFatalError){lock.lock();灏濊瘯{濡傛灉(onFatalError){onFatalError=false;}}鏈€鍚巤lock.unlock();}}杩斿洖鏈夋晥锛泒//...others}}3.getLastPacketReceivedTimeMs-绾跨▼闃诲鐨勭姜榄佺ジ棣栵紝婕忔礊鎵€鍦╟om.alibaba.druid.util.MySqlUtils#getLastPacketReceivedTimeMs1銆?.23鐗堟湰涔嬪墠鐨勫疄鐜?***druid1.1.23鐗堟湰涔嬪墠鐨勬簮鐮佸疄鐜?/publicstaticlonggetLastPacketReceivedTimeMs(Connectionconn)throwsSQLException{//绗竴娆℃墽琛岃繖娈典唬鐮佹椂锛宑lass_connectionImpl鍒濆鍊间负null锛屾墍浠ヤ細enteriflogicif(class_connectionImpl==null&&!class_connectionImpl_Error){try{//鍐欐mysql-connector-java5class//鎵€浠ヤ娇鐢?+鐗堟湰鐨勯┍鍔紝浼氬嚭鐜癈lassNotFound鐨勯棶棰榗lass_connectionImpl=Utils.loadClass("com.mysql.jdbc.MySQLConnection");}catch(Throwableerror){class_connectionImpl_Error=true;}}}淇鍚庣殑浠g爜瀹炵幇澧炲姞浜嗗mysql-connector-java6鐨勬敮鎸侊紱/***Druidversion1.1.23andlatersourceimplementations*@paramconn:濡傛灉閰嶇疆浜嗚嚜瀹氫箟Filter锛屼紶鍏ョ殑conn涓篊onnectionProxyImpl绫诲瀷锛屽惁鍒欐槸ConnectionImpl绫诲瀷*/publicstaticlonggetLastPacketReceivedTimeMs(Connectionconn)throwsSQLException{//濡傛灉閰嶇疆浜嗚嚜瀹氫箟Filter锛岃繖閲岀殑class_connectionImpl涓簄ullif(class_connectionImpl==null&&!class_connectionImpl_Error){try{//鍔犺浇mysql杩炴帴classclass_connectionImpl=Utils.loadClass("com.mysql.jdbc.MySQLConnection");濡傛灉(class_connectionImpl==null){class_connectionImpl=Utils.loadClass("com.mysql.cj.MysqlConnection");if(class_connectionImpl!=null){mysqlJdbcVersion6=t鍚庢倲;}}}catch(Throwable閿欒){class_connectionImpl_Error=true;}}.....}涓嶆槸锛屼富瑕佹槸MySQL椹卞姩鍖呯殑鐗堟湰闂銆俤ruid1.1.23涔嬪墠鐨勭増鏈‖缂栫爜浜唌ysql-connector-java5鐨勭被鍚嶏紝濡傛灉椤圭洰涓厤缃簡com.mysql.cj.*鐩稿叧鐨勫寘锛屼細瀵艰嚧涓€绯诲垪鐨勯棶棰橈細loadClass鏄竴涓悓姝ユ柟娉曪紝瀵艰嚧澶氱嚎绋嬩笅绾跨▼闃诲锛汼pringBoot鍔ㄦ€佺被鍔犺浇鏃讹紝鏈€缁堜細璋冪敤鍏惰嚜瀹氫箟鐨勭被鍔犺浇鍣↙aunchedURLClassLoader锛屽姞杞借繃绋嬩腑浼氶亶鍘咮OOT-INF/lib/涓嬬殑鎵€鏈塲ar鍖呭拰BOOT-INF/classes/涓嬬殑瀛楄妭鐮佹枃浠讹紱銆恓ar鏂瑰紡閮ㄧ讲銆戣В鏋愬唴閮╦ar锛屾墽琛岃В鍘嬫搷浣滐紱com.mysql.cj.*鐩稿叧鍖呬笉瀛樺湪锛屾墍浠ユ瘡娆¤繛鎺ユ祴璇曢兘浼氶噸澶嶄笂闈㈢殑鎿嶄綔锛?.鏈€鍚庝唬鐮佺粨鏉燂紝娌′粈涔堝ソ璇寸殑馃锛屽ぇ瀹跺彲浠ユ煡鐪嬭嚜宸辩殑druid鐗堟湰銆傚鏋滅増鏈?1.1.23锛岃鍗囩骇銆傚鏋滄偍鏈変换浣曢棶棰橈紝璇风暀瑷€璁ㄨ銆?/p>
