美團點評智能支付核心交易系統的可用性實踐

来源:https://www.cnblogs.com/xiexj/archive/2018/04/19/8886356.html
-Advertisement-
Play Games

本文是我原創,原文首發於美團點評技術博客,原文地址是:https://mp.weixin.qq.com/s/pxNRzWs3sZmbr-K18FvnrA 背景 每個系統都有它最核心的指標。比如在收單領域:進件系統第一重要的是保證入件準確,第二重要的是保證上單效率。清結算系統第一重要的是保證準確打款, ...


本文是我原創,原文首發於美團點評技術博客,原文地址是:https://mp.weixin.qq.com/s/pxNRzWs3sZmbr-K18FvnrA

 

背景

每個系統都有它最核心的指標。比如在收單領域:進件系統第一重要的是保證入件準確,第二重要的是保證上單效率。清結算系統第一重要的是保證準確打款,第二重要的是保證及時打款。我們負責的系統是美團點評智能支付的核心鏈路,承擔著智能支付100%的流量,內部習慣稱為核心交易。因為涉及美團點評所有線下交易商家、用戶之間的資金流轉,對於核心交易來說:第一重要的是穩定性,第二重要的還是穩定性。

問題引發

作為一個平臺部門,我們的理想是第一階段快速支持業務;第二階段把控好一個方向;第三階段觀察好市場的方向,自己去引領一個大方向。

理想很豐滿,現實是自從2017年初的每日幾十萬訂單,到年底時,單日訂單已經突破700萬,系統面臨著巨大的挑戰。支付通道在增多;鏈路在加長;系統複雜性也相應增加。從最初的POS機到後來的二維碼產品,小白盒、小黑盒、秒付……產品的多元化,系統的定位也在時刻的發生著變化。而系統對於變化的應對速度像是一個在和兔子賽跑的烏龜。

 

 

由於業務的快速增長,就算系統沒有任何發版升級,也會突然出現一些事故。事故出現的頻率越來越高,系統自身的升級,也經常是困難重重。基礎設施升級、上下游升級,經常會發生“蝴蝶效應”,毫無徵兆的受到影響。

 

問題分析

核心交易的穩定性問題根本上是怎麼實現高可用的問題。

可用性指標

業界高可用的標準是按照系統宕機時間來衡量的:

 

因為業界的標準是後驗的指標,考慮到對於平時工作的指導意義,我們通常採用服務治理平臺OCTO來統計可用性。計算方法是:

 

可用性分解

業界系統可靠性還有兩個比較常用的關鍵指標:

  • 平均無故障時間(Mean Time Between Failures,簡稱MTBF):即系統平均能夠正常運行多長時間,才發生一次故障

  • 平均修複時間(Mean Time To Repair,簡稱MTTR):即系統由故障狀態轉為工作狀態時修理時間的平均值

對於核心交易來說,可用性最好是無故障。在有故障的時候,判定影響的因素除了時間外,還有範圍。將核心交易的可用性問題分解則為:

 

問題解決

1. 發生頻率要低之別人死我們不死

1.1 消除依賴、弱化依賴和控制依賴

用STAR法則舉一個場景:

情境(situation)


我們要設計一個系統A,完成:使用我們美團點評的POS機,通過系統A連接銀行進行付款,我們會有一些滿減,使用積分等優惠活動。

任務(task)


分析一下對於系統A的顯性需求和隱性需求:

1>需要接收上游傳過來的參數,參數里包含商家信息、用戶信息、設備信息、優惠信息。
2>生成單號,將交易的訂單信息落庫。
3>敏感信息要加密。
4>要調用下游銀行的介面。
5>要支持退款。
6>要把訂單信息同步給積分核銷等部門。    
7>要能給商家一個查看訂單的界面。
8>要能給商家進行收款的結算。
基於以上需求,分析一下怎樣才能讓裡面的最核心鏈路“使用POS機付款”穩定。

 
行動(action)

分析一下:需求1到4是付款必需鏈路,可以做在一個子系統里,姑且稱之為收款子系統。5到8各自獨立,每個都可以作為一個子系統來做,具體情況和開發人員數量、維護成本等有關係。

值得註意的是需求5-8和收款子系統的依賴關係並沒有功能上的依賴,只有數據上的依賴。即他們都要依賴生成的訂單數據。

收款子系統是整個系統的核心,對穩定性要求非常高。其他子系統出了問題,收款子系統不能受到影響。

基於上面分析,我們需要做一個收款子系統和其他子系統之間的一個解耦,統一管理給其他系統的數據。這裡稱為“訂閱轉發子系統”,只要保證這個系統不影響收款子系統的穩定即可。

粗略架構圖如下:

 

結果(result)

從上圖可以看到,收款子系統和退款子系統、結運算元系統、信息同步子系統、查看訂單子系統之間沒有直接依賴關係。這個架構達到了消除依賴的效果。收款子系統不需要依賴數據訂閱轉發子系統,數據訂閱轉發子系統需要依賴收款子系統的數據。我們控制依賴,數據訂閱轉發子系統從收款子系統拉取數據,而不需要收款子系統給數據訂閱轉發子系統推送數據。這樣,數據訂閱轉發子系統掛了,收款子系統不受影響。

再說數據訂閱轉發子系統拉取數據的方式。比如數據存在MySQL資料庫中,通過同步Binlog來拉取數據。如果採用消息隊列來進行數據傳輸,對消息隊列的中間件就有依賴關係了。如果我們設計一個災備方案:消息隊列掛了,直接RPC調用傳輸數據。對於這個消息隊列,就達到了弱化依賴的效果。

1.2 事務中不包含外部調用

外部調用包括對外部系統的調用和基礎組件的調用。外部調用具有返回時間不確定性的特征,如果包含在了事務里必然會造成大事務。資料庫大事務會造成其它對資料庫連接的請求獲取不到,從而導致和這個資料庫相關的所有服務處於等待狀態,造成連接池被打滿,多個服務直接宕掉。如果這個沒做好,危險指數五顆星。下麵的圖顯示出外部調用時間的不可控:

 

解決方法:

  • 排查各個系統的代碼,檢查在事務中是否存在RPC調用、HTTP調用、消息隊列操作、緩存、迴圈查詢等耗時的操作,這個操作應該移到事務之外,理想的情況是事務內只處理資料庫操作。

  • 對大事務添加監控報警。大事務發生時,會收到郵件和簡訊提醒。針對資料庫事務,一般分為1s以上、500ms以上、100ms以上三種級別的事務報警。

  • 建議不要用XML配置事務,而採用註解的方式。原因是XML配置事務,第一可讀性不強,第二切麵通常配置的比較泛濫,容易造成事務過大,第三對於嵌套情況的規則不好處理。

  •  

1.3    設置合理的超時和重試

對外部系統和緩存、消息隊列等基礎組件的依賴。假設這些被依賴方突然發生了問題,我們系統的響應時間是:內部耗時+依賴方超時時間*重試次數。如果超時時間設置過長、重試過多,系統長時間不返回,可能會導致連接池被打滿,系統死掉;如果超時時間設置過短,499錯誤會增多,系統的可用性會降低。

舉個例子:

 

服務A依賴於兩個服務的數據完成此次操作。平時沒有問題,假如服務B在你不知道的情況下,響應時間變長,甚至停止服務,而你的客戶端超時時間設置過長,則你完成此次請求的響應時間就會變長,此時如果發生意外,後果會很嚴重。

Java的Servlet容器,無論是Tomcat還是Jetty都是多線程模型,都用Worker線程來處理請求。這個可配置有上限,當你的請求打滿Worker線程的最大值之後,剩餘請求會被放到等待隊列。等待隊列也有上限,一旦等待隊列都滿了,那這台Web Server就會拒絕服務,對應到Nginx上返回就是502。如果你的服務是QPS較高的服務,那基本上這種場景下,你的服務也會跟著被拖垮。如果你的上游也沒有合理的設置超時時間,那故障會繼續向上擴散。這種故障逐級放大的過程,就是服務雪崩效應。

解決方法:

  • 首先要調研被依賴服務自己調用下游的超時時間是多少。調用方的超時時間要大於被依賴方調用下游的時間。

  • 統計這個介面99%的響應時間是多少,設置的超時時間在這個基礎上加50%。如果介面依賴第三方,而第三方的波動比較大,也可以按照95%的響應時間。

  • 重試次數如果系統服務重要性高,則按照預設,一般是重試三次。否則,可以不重試。

1.4    解決慢查詢

慢查詢會降低應用的響應性能和併發性能。在業務量增加的情況下造成資料庫所在的伺服器CPU利用率急劇攀升,嚴重的會導致資料庫不響應,只能重啟解決。關於慢查詢,可以參考我們技術博客之前的文章《MySQL索引原理及慢查詢優化》。

 

解決方法:

  • 將查詢分成實時查詢、近實時查詢和離線查詢。實時查詢可穿透資料庫,其它的不走資料庫,可以用Elasticsearch來實現一個查詢中心,處理近實時查詢和離線查詢。

  • 讀寫分離。寫走主庫,讀走從庫。

  • 索引優化。索引過多會影響資料庫寫性能。索引不夠查詢會慢。DBA建議一個數據表的索引數不超過4個。

  • 不允許出現大表。MySQL資料庫的一張數據表當數據量達到千萬級,效率開始急劇下降。

1.5 熔斷

在依賴的服務不可用時,服務調用方應該通過一些技術手段,向上提供有損服務,保證業務柔性可用。而系統沒有熔斷,如果由於代碼邏輯問題上線引起故障、網路問題、調用超時、業務促銷調用量激增、服務容量不足等原因,服務調用鏈路上有一個下游服務出現故障,就可能導致接入層其它的業務不可用。下圖是對無熔斷影響的魚骨圖分析:

 

解決方法:

  • 自動熔斷:可以使用Netflix的Hystrix或者美團點評自己研發的Rhino來做快速失敗。

  • 手動熔斷:確認下游支付通道抖動或不可用,可以手動關閉通道。

 

2. 發生頻率要低之自己不作死

 

自己不作死要做到兩點:第一自己不作,第二自己不死。

2.1 不作

關於不作,我總結了以下7點:

1>不當小白鼠:只用成熟的技術,不因技術本身的問題影響系統的穩定。
2>職責單一化:不因職責耦合而削弱或抑制它完成最重要職責的能力。
3>流程規範化:降低人為因素帶來的影響。
4>過程自動化:讓系統更高效、更安全的運營。
5>容量有冗餘:為了應對競對系統不可用用戶轉而訪問我們的系統、大促來臨等情況,和出於容災考慮,至少要保證系統2倍以上的冗餘。
6>持續的重構:持續重構是確保代碼長期沒人動,一動就出問題的有效手段。
7>漏洞及時補:美團點評有安全漏洞運維機制,提醒督促各個部門修複安全漏洞。

 

2.2 不死

關於不死,地球上有五大不死神獸:能在惡劣環境下停止新陳代謝的“水熊蟲”;可以返老還童的“燈塔水母”;在硬殼裡休養生息的“蛤蜊”;水、陸、寄生樣樣都成的“渦蟲”;有隱生能力的“輪蟲”。它們的共通特征用在系統設計領域上就是自身容錯能力強。這裡“容錯”的概念是:使系統具有容忍故障的能力,即在產生故障的情況下,仍有能力將指定的過程繼續完成。容錯即是Fault Tolerance,確切地說是容故障(Fault),而並非容錯誤(Error)。

 

 

3. 發生頻率要低之不被別人搞死

3.1 限流

在開放式的網路環境下,對外系統往往會收到很多有意無意的惡意攻擊,如DDoS攻擊、用戶失敗重刷。雖然我們的隊友各個是精英,但還是要做好保障,不被上游的疏忽影響,畢竟,誰也無法保證其他同學哪天會寫一個如果下游返回不符合預期就無限次重試的代碼。這些內部和外部的巨量調用,如果不加以保護,往往會擴散到後臺服務,最終可能引起後臺基礎服務宕機。下圖是對無限流影響的問題樹分析:

 

解決方法:

  • 通過對服務端的業務性能壓測,可以分析出一個相對合理的最大QPS。

  • 流量控制中用的比較多的三個演算法是令牌桶、漏桶、計數器。可以使用Guava的RateLimiter來實現。其中SmoothBurstry是基於令牌桶演算法的,SmoothWarmingUp是基於漏桶演算法的。

  • 核心交易這邊採用美團服務治理平臺OCTO做thrift截流。可支持介面粒度配額、支持單機/集群配額、支持指定消費者配額、支持測試模式工作、及時的報警通知。其中測試模式是只報警並不真正節流。關閉測試模式則超過限流閾值系統做異常拋出處理。限流策略可以隨時關閉。

  • 可以使用Netflix的Hystrix或者美團點評自己研發的Rhino來做特殊的針對性限流。

 

4. 故障範圍要小之隔離

隔離是指將系統或資源分割開,在系統發生故障時能限定傳播範圍和影響範圍。

伺服器物理隔離原則

① 內外有別:內部系統與對外開放平臺區分對待。
② 內部隔離:從上游到下游按通道從物理伺服器上進行隔離,低流量服務合併。
③ 外部隔離:按渠道隔離,渠道之間互不影響。

線程池資源隔離

  • Hystrix通過命令模式,將每個類型的業務請求封裝成對應的命令請求。每個命令請求對應一個線程池,創建好的線程池是被放入到ConcurrentHashMap中。
    註意:儘管線程池提供了線程隔離,客戶端底層代碼也必須要有超時設置,不能無限制的阻塞以致於線程池一直飽和。

信號量資源隔離

  • 開發者可以使用Hystrix限制系統對某一個依賴的最高併發數,這個基本上就是一個限流策略。每次調用依賴時都會檢查一下是否到達信號量的限制值,如達到,則拒絕。

 

5. 故障恢復要快之快速發現

發現分為事前發現、事中發現和事後發現。事前發現的主要手段是壓測和故障演練;事中發現的主要手段是監控報警;事後發現的主要手段是數據分析。

5.1 全鏈路線上壓測

你的系統是否適合全鏈路線上壓測呢?一般來說,全鏈路壓測適用於以下場景:

① 針對鏈路長、環節多、服務依賴錯綜複雜的系統,全鏈路線上壓測可以更快更準確的定位問題。
② 有完備的監控報警,出現問題可以隨時終止操作。
③ 有明顯的業務峰值和低谷。低谷期就算出現問題對用戶影響也比較小。

全鏈路線上壓測的目的主要有:

① 瞭解整個系統的處理能力
② 排查性能瓶頸
③ 驗證限流、降級、熔斷、報警等機制是否符合預期並分析數據反過來調整這些閾值等信息
④ 發佈的版本在業務高峰的時候是否符合預期
⑤ 驗證系統的依賴是否符合預期

全鏈路壓測的簡單實現:

① 採集線上日誌數據來做流量回放,為了和實際數據進行流量隔離,需要對部分欄位進行偏移處理。
② 數據著色處理。可以用中間件來獲取和傳遞流量標簽。
③ 可以用影子數據表來隔離流量,但是需要註意磁碟空間,建議如果磁碟剩餘空間不足70%採用其他的方式隔離流量。
④ 外部調用可能需要Mock。實現上可以採用一個Mock服務隨機產生和線上外部調用返回時間分佈的時延。

壓測工具上,核心交易這邊使用美團點評開發的pTest。

 

 

6. 故障恢復要快之快速定位

定位需要靠譜的數據。所謂靠譜就是和要發現的問題緊密相關的,無關的數據會造成視覺盲點,影響定位。所以對於日誌,要制定一個簡明日誌規範。另外系統監控、業務監控、組件監控、實時分析診斷工具也是定位的有效抓手。

 

 

7. 故障恢復要快之快速解決

要解決,提前是發現和定位。解決的速度還取決於是自動化的、半自動化的還是手工的。核心交易有意向搭建一個高可用系統。我們的口號是:“不重覆造輪子,用好輪子。”這是一個集成平臺,職責是:“聚焦核心交易高可用,更好、更快、更高效。”

美團點評內部可以使用的用於發現、定位、處理的系統和平臺非常多,但是如果一個個打開鏈接或者登陸系統,勢必影響解決速度。所以我們要做集成,讓問題一站式解決。希望達到的效果舉例如下:

 

工具介紹

Hystrix

Hystrix實現了斷路器模式來對故障進行監控,當斷路器發現調用介面發生了長時間等待,就使用快速失敗策略,向上返回一個錯誤響應,這樣達到防止阻塞的目的。這裡重點介紹一下Hystrix的線程池資源隔離和信號量資源隔離。

線程池資源隔離

 


優點

  • 使用線程可以完全隔離第三方代碼,請求線程可以快速放回。

  • 當一個失敗的依賴再次變成可用時,線程池將清理,並立即恢復可用,而不是一個長時間的恢復。

  • 可以完全模擬非同步調用,方便非同步編程。

缺點

  • 線程池的主要缺點是它增加了CPU,因為每個命令的執行涉及到排隊(預設使用SynchronousQueue避免排隊),調度和上下文切換。

  • 對使用ThreadLocal等依賴線程狀態的代碼增加複雜性,需要手動傳遞和清理線程狀態(Netflix公司內部認為線程隔離開銷足夠小,不會造成重大的成本或性能的影響)。

信號量資源隔離

開發者可以使用Hystrix限制系統對某一個依賴的最高併發數。這個基本上就是一個限流策略,每次調用依賴時都會檢查一下是否到達信號量的限制值,如達到,則拒絕。

 


優點

  • 不新起線程執行命令,減少上下文切換。

缺點

  • 無法配置斷路,每次都一定會去嘗試獲取信號量。

比較一下線程池資源隔離和信號量資源隔離

  • 線程隔離是和主線程無關的其他線程來運行的;而信號量隔離是和主線程在同一個線程上做的操作。

  • 信號量隔離也可以用於限制併發訪問,防止阻塞擴散,與線程隔離的最大不同在於執行依賴代碼的線程依然是請求線程。

  • 線程池隔離適用於第三方應用或者介面、併發量大的隔離;信號量隔離適用於內部應用或者中間件;併發需求不是很大的場景。

     

Rhino

Rhino是美團點評基礎架構團隊研發並維護的一個穩定性保障組件,提供故障模擬、降級演練、服務熔斷、服務限流等功能。和Hystrix對比:

  • 內部通過CAT(美團點評開源的監控系統,參見之前的博客“深度剖析開源分散式監控CAT”)進行了一系列埋點,方便進行服務異常報警。

  • 接入配置中心,能提供動態參數修改,比如強制熔斷、修改失敗率等。

總結思考

王國維 在《人間詞話》里談到了治學經驗,他說:古今之成大事業、大學問者,必經過三種之境界:

第一種境界
昨夜西風凋碧樹。獨上高樓,望盡天涯路。
第二種境界
衣帶漸寬終不悔,為伊消得人憔悴。
第三種境界
眾里尋他千百度,驀然迴首,那人卻在,燈火闌珊處。

核心交易的高可用目前正在經歷第一種:高瞻遠矚認清前人所走的路,以總結和學習前人的經驗做為起點。

下一階段,既然認定了目標,我們會嘔心瀝血孜孜以求,持續發展高可用。最終,當我們做了很多的事情,回過頭來看,相信會對高可用有更清晰和深入的認識。敬請期待我們下一次的分享~~

關於作者

曉靜,20歲時畢業於東北大學電腦系。在畢業後的第一家公司由於出眾的語言天賦,在1年的時間里從零開始學日語並以超高分通過了國際日語一級考試,擔當兩年日語翻譯的工作。後就職於人人網,轉型做互聯網開發。中國科學院心理學研究生。有近百個技術發明專利,創業公司合伙人。有日本東京,美國矽谷技術支持經驗。目前任美團點評技術專家,負責核心交易。(歡迎關註靜兒的個人技術公眾號:編程一生  ) 

 

 

----------  END  ----------

招聘信息

美團金融核心交易招聘實習生,要求:19年即將畢業的研究生,Java方向,有技術追求。高速發展的業務需要高速發展的團隊,作為核心部門,我們急需相信技術改變世界的你!有意者請關註我的個人技術公眾號並留言。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 線程分為:單線程和多線程 單線程:一個正在運行的程式(即進行)至少有一個線程,這個線程叫做主線程,只有一個主線程的程式叫做單線程程式,主線程負責執行所有代碼的執行(UI展現及刷新、網路請求、本地存儲等),這些代碼只能順序執行,不能併發執行。 多線程:有多個線程的程式叫做多線程程式,主線程可以開闢多個 ...
  • $scope.yearList = [ {k : "2014", v : "2014"}, {k : "2015", v : "2015"}, {k : "2016", v : "2016"}, {k : "2017", v : "2017"}, ... ...
  • 本文章適合具有一定程式編程語言基礎的人士閱讀,最好學完Java基礎再來閱讀本文章更容易理解語言初學者會看起來比較費勁,不易理解 一.導入腳本 在html導入Javascript的格式是: 兩個關鍵屬性:deter,async deter:defer屬性告訴瀏覽器要等整個頁面載入以後、解析完畢才執行該 ...
  • Ionic基於AngularJS構建而成,所以學習一些AngularJS的知識很有必要。Ionic並沒有獨立開發一套完整的Web應用框架,而是對AngularJS進行了擴展,給它添加了大量界面組件和其他的移動端友好的特性。 1.index.html 首先會進入index頁面,裡面引入了angular ...
  • 預設為今年 var date = new Date; $scope.year = date.getFullYear(); //年份減 $scope.yearPrev = function(){ $scope.year -- ; ... ...
  • 1 文件上傳 2 3 4 5 6 7 1 ...
  • 徹底理解瀏覽器的緩存機制 2018/04/16 概述 瀏覽器的緩存機制也就是我們說的HTTP緩存機制,其機制是根據HTTP報文的緩存標識進行的,所以在分析瀏覽器緩存機制之前,我們先使用圖文簡單介紹一下HTTP報文,HTTP報文分為兩種: HTTP請求(Request)報文,報文格式為:請求行 – H ...
  • 由於項目需求,需要寫一個數字增/減量的動畫特效,最後找到了CountUp.js CountUp.js是一個無依賴,輕量級的JavaScript“類”,可用於快速創建以更有趣的方式顯示數字數據的動畫。 使用需引入countUp.js文件,以下例子還引用了jquery.js countUp.js文件地址 ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...