日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

简单好用!利用Spring AOP技术10分钟实现一个数据库读写分离方案

發布時間:2025/3/21 javascript 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单好用!利用Spring AOP技术10分钟实现一个数据库读写分离方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

最近我們的APP在線用戶越來越多,接口的響應速度也是越來越慢,經過運維排查發現是由于并發查詢太多導致的數據庫壓力比較大,架構師經過調研給出了數據庫讀寫分離的解決方案,為了快速解決問題,我們最終采用AOP技術實現了數據庫讀寫分離方案。

目錄

  • 什么是數據庫讀寫分離以及為什么要讀寫分離?
  • 數據庫讀寫分離實現方式及優缺點分析
  • 用AOP實現的數據庫讀寫分離方案
  • 總結
  • 什么是數據庫讀寫分離以及為什么要讀寫分離?

    數據庫讀寫分離,顧名思義就是將數據庫的讀操作和寫操作分開。

    傳統項目架構中,所有的操作都在同一個數據庫執行,在并發量很小的時候這并不會出現什么問題,但是在并發量很大時單個數據庫就會出現性能問題。

    假設單個數據庫的QPS為1000,數據庫的并發量為2000,狼多肉少的情況下接口響應速度變慢也就不足為怪了。

    數據庫讀寫分離方案的出現就是為了解決這個問題的。

    項目采用數據庫讀寫分離方案之后共有4個數據庫,其中1個主數據庫和3個從數據庫,主從之間采用binlog文件的方式進行數據同步。主數據庫負責處理所有的寫操作,從數據庫異步進行數據同步;所有的讀操作會平均分散到3個從數據庫上執行。

    數據庫讀寫分離之后,主數據庫處理寫操作,多個從數據庫組成集群共同提供查詢服務,原本大并發量的查詢操作將被平均分到3個數據庫上,從而降低了每個數據庫的并發,提升額查詢效率;同時還將數據做了冗余備份,增加了系統的抗風險能力。

    數據庫讀寫分離實現方式及優缺點分析

    根據解決方式所在的層面不同,數據庫讀寫分離主要有3種解決方案:

    1、應用層面

    實現方式主要是在應用層加一個數據源路由層,將查詢操作路由到從庫,將寫入操作路由到主庫。

    優點:方案實現起來比較輕便、路由策略可自由控制,擴展性強。

    缺點:功能有限,個人要實現完整的方案難度較大,且該方案與代碼強耦合,跨語言不通用。

    2、中間件層面

    實現方式是在應用和數據庫之間加一層代理,由代理來轉發操作請求。像阿里的MyCat、360的Atlas、美團的DBProxy等都是此類實現方案。

    優點:解決方案與應用層代碼解耦,通用性較好。

    缺點:應用和數據庫之間增加了代理層,連接由直連改為代理會導致性能有所下降。

    3.數據庫驅動層面

    實現方式是提供一個支持數據庫讀寫分離的驅動。像Mysql自帶的ReplicationDriver驅動、當當開源的Sharding-JDBC、淘寶開源的TDDL等解決方案都是基于數據庫驅動層面實現的。

    優點:功能豐富、集成方式較簡單,應用層面改動較小。

    缺點:需使用特定數據庫驅動,擴展性較低。

    用AOP實現的數據庫讀寫分離方案

    采用這個方案一是因為足夠輕便,不需要額外增加什么東西;二是因為AOP技術門檻較低,實現起來比較快速。

    先介紹一下我們項目的技術背景,項目采用SpringBoot框架開發,采用Mybatis作為ORM層,請求的調用鏈一般就是Controller調用Service,Service調用Mapper。

    方案架構圖:

    主要原理:

    一般來講,我們對于方法的命名會遵循一定的規范,比如插入方法我們會以insert或者save等關鍵字開頭,更新方法我們會以update或edit等關鍵字開頭,查詢方法則會以select或find等關鍵字開頭。這種命名習慣可以很好的達到代碼自解釋性,讓人一眼就能望文知意。

    我們正好可以利用這個特點來自定義一個AOP切面切到所有Service實現類里的所有方法,再根據方法開頭的關鍵字來切換不同的數據源,最終達到寫入操作路由到主數據庫,查詢操作路由到三臺從庫的目的。

    實現步驟:

    1、定義并配置好主數據庫和從數據庫數據源信息。

    2、將Mybatis默認使用的數據源改成我們自定義的可動態切換的RoutingDataSource。

    在RoutingDataSource里,我們將關鍵字與數據源一一對應起來存入map,key-value對應關系:

    write->writeDatasource

    read0->read1Datasource

    read1->read2Datasource

    read2->read3Datasource

    3、繼承Spring框架的AbstractRoutingDataSource抽象類自定義一個RoutingDataSource類,并實現determineCurrentLookupKey方法,該方法就是我們實現數據源切換的關鍵所在。

    determineCurrentLookupKey方法中,我們從DataSourceContext中獲取數據源對應的key值。

    4、看一下DataSourceContext里面的邏輯:

    在DataSourceContext里我們定義了一個ThreadLocal變量用來保存該線程所使用的的數據源信息,并且對外提供了兩個切換數據源的方法switchToReadDatasource和switchToWriteDatasource。

    5、最后來看一下AOP切面類:

    我們使用@Before注解定義2個切入點,在方法執行前進行切換數據源的增強處理。

    在攔截到以select、get、find等關鍵字開頭的讀方法時我們切換至讀數據源,攔截到以insert、update、delete等關鍵字開頭的寫方法時我們切換至寫數據源。

    寫個測試類來測試一下:

    我們先插入一條數據、再來讀取這條數據,看下執行結果:

    可以看到,對于insert操作程序自動切換到了write數據源,對于select操作程序又隨機切換到了read2數據源。

    總結

    一般來講大部分項目都是讀多寫少,數據量和并發量上去之后,單個數據庫往往會面臨比較大的性能壓力,數據庫讀寫分離方案正好適用于這種讀多寫少的應用場景

    讀寫分離更多的是擴展了數據庫的讀能力,多個數據庫共同分擔讀操作可以顯著提高系統并發能力。

    任何方案有優點肯定也會有缺點,讀寫分離也不例外。讀寫分離需要對數據庫進行主從架構的改造,增加了系統的復雜性,同時主從之間數據同步也會存在延時,對于需要查詢精確數據的業務來說可能并不合適。

    對于輕量級的業務來講,如果需要快速實現數據庫的讀寫分離可以采用AOP自己實現讀寫分離方案;如果有足夠的人力和技術,可以從系統層面對項目進行讀寫分離的改造,個人傾向于采用驅動層的一些開源解決方案,如Sharding-JDBC。

    總結

    以上是生活随笔為你收集整理的简单好用!利用Spring AOP技术10分钟实现一个数据库读写分离方案的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。