1. 程式人生 > >記一次使用Cobar踩到的坑

記一次使用Cobar踩到的坑

起因

起因是因為日誌裡經常報出鎖等待超時的錯誤,並且這個是環環相扣的,一個鎖等待會直接引發另外的鎖等待,所以危害非常嚴重,影響非常深遠。尋找原因發現是C3P0報出了DEADLOCK,如下圖所示:
這裡寫圖片描述

分析

可以看出來ScatteredAcquireTask,也就是獲取連線的任務,全部卡在那不動了。那顯然是無法獲取新的資料庫連線了。正好前一天剛剛進行過架構上的調整——從應用直連Mysql變化到中間添加了一層Cobar(關於Cobar,它是一個Mysql代理中介軟體,用來處理分庫)。猜測就是切換到Cobar的問題,但是究竟是什麼問題呢?下面我們來一起分析一下:

首先是切換到Cobar前的伺服器結構圖:

N臺應用 –> 1臺Mysql

下面是新增Cobar後的:

N臺應用 –> 2臺Cobar -> N臺Mysql

那麼兩者之間到底有什麼區別呢?我在本地做了一個測試,將C3P0的初始連線數設定到5000,也就是模擬在大量的連線請求下資料庫的反應,看看是否會出現ScatteredAcquireTask卡住的情況。5000個連線建立完成了,但是出乎意料的是,我用show processlist檢視Mysql執行緒時,居然並沒有看到執行緒的增長,而是和剛才一樣。到這裡我差不多已經意識到了問題所在,為了證實這一點,我又用直連資料庫的方式起了5000個連線,這次資料庫連線果斷就上去了。恩,看到這裡大家應該也都猜到了吧,與Cobar

建立連線,並不表示與Mysql建立連線,其實在我們的應用到Mysql這段道路上存在著兩個“池”,一個是我們應用和Cobar之間的資料庫連線池,還有一個是Cobar和Mysql之間的連線池。應用和Cobar之間的連線數並不存在瓶頸,並且我們也知道它們之間是用NIO通訊的。但是CobarMysql之間呢?OH,由於Cobar只實現了一半的NIO,所以和Mysql之間還是走的BIO

這裡還需要說明的一點是,我們公司的Cobar伺服器是DBA來搭建和維護的。所以對我們後端開發來說所有的配置都是不透明的,我們不熟悉Cobar的配置也不知道有哪些東西可配置。但是憑藉剛才的猜想,已經差不多知道瓶頸就是Cobar

Mysql之間。

解決

跟隨著自己的猜想,果斷百度了一下Cobar的配置引數,發現有一個引數名為PoolSize,用來設定Cobar與後端資料來源連線池大小。將其調大,即將問題解決。

並且事後在檢視Cobaralarm日誌時,發現出問題的時間段內正好打出如下的日誌,也更加證實了我的猜想!
這裡寫圖片描述