JDBC做過JAVA開發的都知道JDBC是干什么的,RestApi其實就是http的調用,http的調用就是調用第三方的服務的時候,第三方的服務并不是在自己的系統范圍內,如果出現不穩定掛掉,對自身來說是不可控了,所以第三方服務而言對我們而言是非常的明感的。JDBC和RestApi的監控對系統來講意義很大,數據庫得多重要,在系統的內部進行監控更能良好的反應sql的執行性能。
源碼:https://github.com/limingIOS/netFuture/tree/master/源碼/『互聯網架構』調?鏈系統工程結構(111)
(一)JDBC調用攔截
- JDBC插樁目的
哪些監控懟開發運維來說最有用的。
- SQL語句、SQL參數、用了多長時間、SQL類型、結果集大小、返回字段、規范、Join次數
- 攔截監聽SQL語句
- 找出慢查詢語句
- 模型結構
字段類型描述sqltextsql語句paramsjson參數resultSizeint結果大小urlvarchar數據庫連接路徑userNamevarchar數據庫用戶名errortext異常堆棧useTimeint用時
- JDBC插樁位置
這些user,框架,連接池,驅動都依賴jdbc,jdbc是一個什么東西?jdbc是一種規范,一堆接口組成的規范j2se,由驅動來實現的。servlet也是一種接口規范,是j2ee的規范,由Tomcat,jetty等容器實現的。任任何一層都可以做為插樁的切入點,但是選用User 層、框架層、連接池&數據源層、驅動層其實現是多樣的,無法做到普適性。所以在此選用JDBC 作為插樁切入 點。
- JDBC插樁機制
從上圖可以分析出JDBC執行過程
1.從驅動獲取連接(Connection)
2.基于連接構建預處理對象(prepareStatement)
3.執行SQL
4.讀取結果集(ResultSet)
5.關閉釋放連接。
其中涉及對象構建邏輯如下:
Driver==》Connection==》prepareStatement==》ResultSet
(二)Http調用攔截
- Http埋點目的
很多時候我們會調用第三方API。比如:消息推送、短信發送、第三方支付接口等,因為服務是第三方提供,如果服務出現性能或可用性問題對于我方而言不可控,所以這類接口的穩定性是我們需要重點關注的對象。
通常這類接口會基于Http協議實現,所對Htpp協議監控,即實現了對第三方接口的監控。
- Http埋點位置
1.user層:無法判斷User具體執行方法,基于配置又做不到普適性。
2.Http協議層:能找到具體方法,也能做到普適性。需要對Http協議進行全面解析,而且Http協議為文本協議,解析難度更大,實現成本居高。
3.專有SDK、與自定義封裝的Http工具包,跟具體業務偶合同樣無法做到普適應。
4.java net URL 與 HttpClient 都是Http client 基于二者實現可以在一定程度上達成我們的目標。
- Http埋點機制(java.net.URL)
URL常用寫法:
URL url = new URL("https://www.baidu.com"); URLConnection conn = url.openConnection(); conn.setDoInput(true); conn.setDoOutput(true); conn.connect(); OutputStream output = conn.getOutputStream(); output.write("a=c&b=1".getBytes()); InputStream input = conn.getInputStream(); byte[] bytes = IOUtils.readFully(input, -1, false); System.out.println(new String(bytes));
URL 裝載執行過程:
- URL 基于protocol 構建對應 UrlStreamHandler
- UrlStreamHandler.openConnection() 打開連接,返回URlConnection
- URlConnection 設置連接屬性
- URlConnection 打開 outPutStream 寫入參數
- URlConnection 打開 inPutStream讀取結果
其中涉及對象構建邏輯如下:
URL==》URLStreamHandler==》URLConnection==》outPutStream、InputStream。
如果上述過程加一層<u>靜態代理</u>即可監控這些對象所有的執行過程從而得到所需監控數據:
URL==》Proxy(URLStreamHandler)==》Proxy(URLConnection)==》Proxy(outPutStream)、Proxy(InputStream)。
- URL的類結構
怎么樣才能加上這層代理呢?其關鍵方法在于 通過靜態代理的方式。 <u>java.net.URL#setURLStreamHandlerFactory。</u>該方法允許用戶自定義URL協議實現.
PS:太復雜了,看源碼debug看比較好,jdbc和restApi通過的proxy代理的方式。