.net core发布 正在发现数据上下文_使用EF Core实现数据库读写分离
以下文章來源于朝夕Net社區(qū) ,作者Eleven
朝夕Net社區(qū)
朝氣、豐富、活躍的.Net社區(qū),朝夕教育攜百萬粉絲共同打造!有技術(shù),有感悟,有新聞,有照片,有故事,還有夢想!
【精選轉(zhuǎn)載】| 作者/Eleven(朝夕.NET社區(qū))
其實(shí)在部分公司不是很推崇使用ORM框架,說是ORM框架存在性能問題;這句話可以說是讓ORM蒙受不白之冤;
Eleven老師認(rèn)為:沒有低性能的框架,只有不會(huì)使用框架的開發(fā)者!更多時(shí)候,是因?yàn)閿?shù)據(jù)庫的性能問題,ORM在開發(fā)中可以說是被殃及的池魚!
那么本篇文章就介紹如何通過EF Core如何來配合數(shù)據(jù)庫提高性能;那么如何來做的,得先從數(shù)據(jù)庫下手,最常規(guī),最推崇的就是數(shù)據(jù)庫讀寫分離;那么如何使用EF Core配合實(shí)現(xiàn)數(shù)據(jù)庫讀寫分離呢?Eleven老師為你娓娓道來EF Core如何實(shí)現(xiàn)MS SQL Server數(shù)據(jù)庫的讀寫分離實(shí)踐!
1關(guān)于數(shù)據(jù)庫讀寫分離
在實(shí)際開發(fā)工作中,對數(shù)據(jù)的操作有一個(gè)二八原則,20%的操作是數(shù)據(jù)的增刪改,80%的操作是數(shù)據(jù)庫查詢,那么把這80%的數(shù)據(jù)存儲(chǔ)在多個(gè)數(shù)據(jù)庫中,有選擇性的去查詢數(shù)據(jù);必然提高性能;數(shù)據(jù)庫讀寫分離,其實(shí)是一主多從,主庫負(fù)責(zé),增刪改(20%的數(shù)據(jù)操作),從庫負(fù)責(zé)查詢(80%的數(shù)據(jù)查詢);架構(gòu)圖如圖下所示:
這里有三種角色,主庫,發(fā)布服務(wù)器,從庫;三者的關(guān)系為:
主庫發(fā)布數(shù)據(jù)庫結(jié)構(gòu)或者數(shù)據(jù)到發(fā)布服務(wù)器,從庫從發(fā)布服務(wù)器訂閱;
主庫第一次發(fā)布,發(fā)布數(shù)據(jù)庫結(jié)構(gòu);是把數(shù)據(jù)的結(jié)構(gòu),通過鏡像文件發(fā)布到發(fā)布服務(wù)器。
多個(gè)從庫去訂閱,直接通過鏡像拷貝把數(shù)據(jù)庫結(jié)構(gòu)拷貝生成從數(shù)據(jù)庫庫;
那么后面如果主數(shù)據(jù)庫中有數(shù)據(jù)更新,新增、修改、刪除數(shù)據(jù)以后,數(shù)據(jù)庫會(huì)生成日志。
那么主數(shù)據(jù)庫生成日志后把操作日志,發(fā)布到服務(wù)器服務(wù)器,多個(gè)從庫在發(fā)布服務(wù)器訂閱得到日志,然后通過日志恢復(fù)數(shù)據(jù);
通過日志恢復(fù)數(shù)據(jù)很快,但依然有延遲;只不過延遲很小!那么數(shù)據(jù)的扭轉(zhuǎn)過程為:增刪改操作主庫,主庫同步數(shù)據(jù)到從庫,查詢到從庫查詢,這就是讀寫分離;
那如何配置讀寫分離呢?
針對于MS SQL Server,朝夕.NET社區(qū)有專門的配置說明文檔,你可以聯(lián)系助教老師獲取(QQ:986960462)。
2EF Core 多數(shù)據(jù)庫操作數(shù)據(jù)實(shí)現(xiàn)
EFCore的使用,是基于上下文Context來對數(shù)據(jù)完成一一系列增刪改查操作,Context里面包括了對數(shù)據(jù)的各種配置,包括數(shù)據(jù)庫連接,數(shù)據(jù)庫映射等。一個(gè)數(shù)據(jù)庫對應(yīng)一個(gè)Context;那么數(shù)據(jù)庫讀寫分離以后,是多個(gè)數(shù)據(jù)庫了;怎么辦呢?有兩種方案,多數(shù)據(jù)庫多個(gè)Context; 還是每個(gè)數(shù)據(jù)庫對應(yīng)一個(gè)Context; 或者一個(gè)Context多個(gè)數(shù)據(jù)庫連接;如圖2,圖3。
圖2:多個(gè)Context對應(yīng)多個(gè)數(shù)據(jù)庫
圖3:一個(gè)Context多個(gè)連接對應(yīng)不同的數(shù)據(jù)庫
那么這兩種方案哪種更巧妙呢?我們來分析一下:
(1)如果是多個(gè)Context對應(yīng)多個(gè)連接,就需要建立多個(gè)Context類文件;數(shù)據(jù)庫讀寫分離后其實(shí)是無法確定從庫的數(shù)量的,可能隨著業(yè)務(wù)的增長,從數(shù)據(jù)庫可能會(huì)持續(xù)增加,那么增加一個(gè)從數(shù)據(jù)庫;就需要增加一個(gè)Context文件;屆時(shí)就需要修改代碼,那么項(xiàng)目就會(huì)不穩(wěn)定,這是我們開發(fā)者最忌諱的;數(shù)據(jù)庫讀寫分離在大型系統(tǒng)中本為常態(tài),如果每增加一個(gè)從庫,就需要修改一次代碼的話,其實(shí)很難受,代價(jià)很高;所以多個(gè)Context單獨(dú)對應(yīng)數(shù)據(jù)庫來說,并非技術(shù)實(shí)現(xiàn)最佳方案。
(2)如果是一個(gè)Context多個(gè)連接數(shù)據(jù)庫的方案:一個(gè)Context對應(yīng)多個(gè)連接;如果增刪改,就使用連接主庫的數(shù)據(jù)庫鏈接;如果是查詢,就使用,從庫中的任何一個(gè);因?yàn)橹鲝臄?shù)據(jù)庫的結(jié)構(gòu)和數(shù)據(jù)是一種的;這種方案是可行的,那我們就來實(shí)操一下!
第一步:建立一個(gè)Core環(huán)境的類庫;如圖4
圖4
第二步:
Nuget引入程序包:Microsoft.EntityFrameworkCore
PS:支持EFCore;
Nuget引入程序包:Microsoft.EntityFrameworkCore.SqlServer
PS:支持MS SQL Server數(shù)據(jù)庫
第三步:建立Context上下文文件:如圖5
圖5
第四步:就可以在上端調(diào)用;主庫寫入,從庫讀取;可以正常執(zhí)行;如圖6
圖6
我們來分析一下如果代碼這么寫有沒有什么問題。如果代碼這樣寫,上端調(diào)用方,還得決定,究竟使用哪個(gè)數(shù)據(jù)庫;判斷使用的數(shù)據(jù)庫連接字符串;在實(shí)際開發(fā)中,數(shù)據(jù)庫連接字符串肯定是配置在配置文件中的;在Core開發(fā)中像類的實(shí)例創(chuàng)建一定必然是通過容器來創(chuàng)建的;如果有多個(gè)從庫呢?上端還得選擇使用從庫中的那個(gè)字符串;程序開發(fā)中,這樣做不好,上端調(diào)用方需要處理的事情太多,知道的也太多。
其實(shí)上端調(diào)用只需要明確是需要使用主庫(增刪改),還是從庫(查詢);那么這里最后能把實(shí)例的創(chuàng)建和字符串的選擇處理推向一個(gè)工廠來做;工廠接受一個(gè)枚舉參數(shù),知道是使用從庫還是主庫,然后由工廠來讀取配置文件指定究竟來使用哪個(gè)數(shù)據(jù)庫來做數(shù)據(jù)操作;因?yàn)閺臄?shù)據(jù)庫的個(gè)數(shù)是未知的,工廠還可以在選擇從庫(查詢的)的時(shí)候,適當(dāng)?shù)淖鲆恍┎呗詠磉x擇,在查詢的時(shí)候,讓多個(gè)從庫盡可能平均的來分?jǐn)偛樵兊牟僮?#xff1b;從而提高數(shù)據(jù)庫的性能。Ok~ 那我們就來實(shí)操一下!
3使用工廠模式創(chuàng)建DbContext實(shí)例
第一步:創(chuàng)建工廠DbContextFactory如圖7,創(chuàng)建枚舉如圖8
圖7
圖8
第二步:調(diào)用測試 如圖9
圖9
比較一下:我們發(fā)現(xiàn)增加了工廠以后,發(fā)現(xiàn)在上端調(diào)用的時(shí)候,確實(shí)工廠能夠創(chuàng)建不同Context實(shí)例,但是我們增加了創(chuàng)建工廠的成本;還是不夠友好。
進(jìn)一步思考:在創(chuàng)建Context實(shí)例的時(shí)候,是必須要指定就是是使用主庫還是從庫;這個(gè)沒辦法,那么工廠的創(chuàng)建能不能不讓我們自己來寫呢?
當(dāng)然可以,可以把工廠注入到控制器里來,看我實(shí)操。
4重構(gòu):抽象工廠 + 依賴注入
第一步:定義工廠接口:定義一個(gè)創(chuàng)建Context的方法;如圖10
圖10
第二步:工廠實(shí)現(xiàn)工廠接口,上代碼;如圖11
圖11
第三步:注冊服務(wù),構(gòu)造函數(shù)注入:如圖12
圖12
第四步:控制器構(gòu)造函數(shù)注入:如圖13
圖13
第五步:調(diào)試測試;如圖14,把工廠注入到控制器,讓工廠創(chuàng)建Context實(shí)例;數(shù)據(jù)正常查詢;
圖14
那這樣做了以后有什么好處呢?這樣做了之后,無論你有多少個(gè)數(shù)據(jù)庫,只要是做的讀寫分離(數(shù)據(jù)庫結(jié)構(gòu)一致),都可以通過一個(gè)工廠創(chuàng)建出來,工廠在創(chuàng)建從庫對應(yīng)的Context實(shí)例的時(shí)候還可以做負(fù)載均衡;
因?yàn)閿?shù)據(jù)庫的操作80%都是在從庫中查詢,如果從庫多,我可以把這80%的查詢分散到多個(gè)從庫中去查詢,從而提高數(shù)據(jù)庫的性能;怎么實(shí)現(xiàn)呢?請往下看!
5進(jìn)階:實(shí)現(xiàn)從庫的負(fù)載均衡
請看到我們定義的從庫創(chuàng)建實(shí)例部分代碼,已經(jīng)增加了選擇查詢數(shù)據(jù)庫連接的策略;如圖15:
圖15
其實(shí)我們還可以增加另外的一些策略:比方說輪詢策略,如果有十個(gè)從庫,那查詢操作就輪流著來,第一次使用從庫1,第二次使用從庫2 第三次使用從庫3.以此類推;還可以增加配置文件,通過讀取配置文件來決定就是使用哪一種策略;比方說就定義三種策略:隨機(jī)、輪詢、權(quán)重;實(shí)操如下:
第一步:增加配置文件配置究竟選擇哪種策略:圖16
圖16
第二步:定義選擇從庫的策略:如圖17
圖17
6小結(jié)
EF Core通過和MS SQL Server的結(jié)合,不僅可以實(shí)現(xiàn)數(shù)據(jù)庫的讀寫分離,而且可以做到在查詢的時(shí)候,定義不同的策略來實(shí)現(xiàn)不同數(shù)據(jù)庫的查詢,更好的降低數(shù)據(jù)庫的壓力,提高數(shù)據(jù)庫的性能。
當(dāng)然,本文雖然針對的是MS SQL Server,你也可以根據(jù)本文的思想使用EF Core實(shí)現(xiàn)MySQL的讀寫分離,原理都是相通的,只是實(shí)現(xiàn)上稍有一些個(gè)性上的區(qū)別。
總結(jié)
以上是生活随笔為你收集整理的.net core发布 正在发现数据上下文_使用EF Core实现数据库读写分离的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hamming weight_popco
- 下一篇: linux cmake编译源码,linu