騰訊QQ團隊開源分布式后臺毫秒服務引擎全解析:引擎架構、RPC、灰度……

騰訊QQ團隊將于12月4日開源一個服務開發運營框架,叫做毫秒服務引擎(Mass Service Engine in Cluster,MSEC),它集RPC、名字發現服務、負載均衡、業務監控、灰度發布、容量管理、日志管理、Key-Value存儲于一體,目的是提高開發與運營的效率和質量。

毫秒服務引擎的創作沖動和構建經驗,來自QQ后臺團隊超過10年的運營思考。它是一整套解決方案,但也可以拆分來使用其中的監控、Key-Value存儲單品。

典型用戶群體

毫秒服務引擎非常容易搭建和上手,使用它,初學者從零開始開發一個分布式后臺demo并運行起來,只需要2個小時。基本上是一個小時完成框架搭建,一個小時完成開發上線,特別適合互聯網初創公司。

功能與優勢

模塊間訪問采用RPC的方式,開發者不用關注網絡與報文格式,像寫單機程序一樣開發分布式服務。

  1. 負載自動均衡與容錯,對于單機故障、局部網絡波動等狀況自動應對,服務高可用性。
  2. 支持C/C++、Java、PHP語言,馬上還會推出支持Python語言;如果選擇C/C++語言,支持協程,兼具開發和運行效率。
  3. Web化的管理界面,在Web界面完成配置、發布、監控、日志、Key-Value存儲集群管理等所有操作。
  4. 需要復雜部署的服務器都采用Docker鏡像的方式安裝,使得部署與上手非常容易。
  5. 相比使用其他開源組件拼湊起來的解決方案,毫秒服務引擎更加的體系化,對團隊的規范更加到位。

毫秒服務引擎設計背景

對于互聯網服務后臺團隊,開發框架的選擇是非常關鍵的問題,10年的海量服務經驗和教訓使得我們團隊深刻認識到:

  1. 要盡早規范團隊的開發服務框架,避免到了后期,各種開發語言混雜、各類存儲組件充斥、重復編碼、每個模塊形態不統一、文檔缺失、監控癱瘓、人員離職造成大量信息丟失,最后積重難返、痛苦不堪;
  2. 沒有框架來規范,團隊的隨意性就太大,合作效率就大打折扣,甚至于內耗、反復的挖坑填坑,系統的成敗過于依靠人的意識和水平;
  3. 規范,不能靠文檔、不能靠勞動紀律、不能靠苦口婆心、不能靠人員意識、不能靠運動式的整頓,要靠技術框架上切實的限制與貼心保護。

如果有機會從零開始定義一個理想的開發框架,我們覺得需要考慮下面9點。

  1. 同步編碼異步執行。兼顧運行效率和編碼效率,希望代碼寫起來是同步和順序的,而執行的時候是異步的。
  2. IDL/RPC。支持IDL(接口描述語言)和RPC,減少網絡協議相關的重復工作,協議有比較好的擴展性;遠程調用友好且高效,做到覆蓋主要的開發語言。
  3. LB。對服務間的調用選路進行統一的管理,對單機故障和網絡波動等常見情況有自動容錯,我們簡稱load balance(LB)。
  4. 存儲服務化。這個其實和開發框架關系不太緊密,這里提一下,強調存儲應該有統一的組件且由專業的團隊運維,就像共有云一樣。
  5. 過載保護。框架必須有成熟自帶的過載保護機制,不需要業務開發人員關注或者關注很少。
  6. 基礎的監控和告警。RPC調用、機器的CPU/網絡活動、任務并發度、時延、進程監控和秒起等基礎信息,要有上報、統計和告警,不需要業務開發人員關注。
  7. 完整的業務流轉呈現。統一日志,在一個地方能夠清晰的呈現某次業務處理過程的流轉詳細情況:經過了哪些模塊間調用,調用參數是怎樣的,每個模塊處理的重要分支和結果是怎樣的,最好圖形化呈現。支持染色和不同的日志詳細級別。
  8. 中央總控。整個系統的配置和文檔等重要信息,例如每個模塊有哪些機器,分布在哪些機房、容量冗余情況、模塊間調用關系、訪問控制的配置動態管理甚至電子流,都希望能統一在一個地方Web化的管理起來,并且與運營的系統是直接聯系直接生效的。
  9. 云調度。容量的自動調度。例如要進行某個運營活動需要大量的擴容,只需要把設備放進去,就能自動的擴縮容。當某個城市機房故障,能夠自動調度容量到其他城市。

毫秒服務引擎架構

整個系統由下面幾部分組成,如圖所示。

**Web Console:**整個系統的運營管理中心,包括:

  • Tomcat提供Web管理界面,管理的數據保存在MySQL里。

  • LB是名字發現服務和負載均衡,remote_shell是遠程文件傳輸與遠程命令執行服務。

**Log服務器:**提供業務Log的存儲和查詢服務。Log存儲在MySQL表里。

**Monitor服務器:**提供業務上報信息的存儲和查詢服務。業務上報信息存儲在內存里,推薦內存8G~16G。定時dump到磁盤的方式防止數據掉電丟失。

**業務運營服務器:**部署開發框架和業務邏輯代碼,處理業務請求。

**key-value存儲服務:**相對整個框架比較獨立,按需選用。

服務標準化運營

一套互聯網后臺服務的開發和運營涉及非常多的細節。

  1. 訪問其他服務模塊,服務端IP如何管理?網絡報文格式是怎樣的?

  2. 有哪些配置文件? 用到哪些第三方的庫?

  3. 業務邏輯和基礎框架是如何分離的?

  4. 對外提供怎樣的網絡接口?怎么對外提供接口API和文檔?

  5. 運營機器上的安裝目錄準備怎么安排? 有哪些運維腳本和工具?

  6. 應該監控哪些指標?應該記錄哪些日志?

  7. 還有很多…

上面種種細節,每個程序員實現起來都有不同的做法。經驗證明,如果后臺各個模塊沒有標準化和規范化,可能導致:同一個團隊開發的服務,千差萬別千奇百怪,負責運維的同事面對的多個模塊“長”的都不一樣,程序框架完全不一樣,安裝目錄亂七八糟,無法規模化的高效運維。

服務的質量完全依賴團隊成員的技能和意識,有的成員可能會做得比較好,配置文件命名易懂、文檔及時更新與代碼保持一致、有對服務做細致的監控上報和日志記錄,提供了運維腳本,但是也有的成員的工作讓人抓狂。

每當有團隊成員離職和工作交接,交接本身就是工作量很大,交接時間長,交接質量不好,文檔缺失,很多信息在交接過程中丟失,運營事故往往頻發。

經驗難以得到傳承,一塊石頭反復絆倒各個成員和業務模塊,運營事故雷同、頻出,團隊挫折感倍增、服務可用性低下。

也曾經有過做事比較規范的時候,但是這些規范通常靠耳提面命、人口相傳,靠管理者運動式的整頓,有時候管理焦點沒有持續跟進,或者隨著人員更替,團隊又把這些寶貴的經驗丟棄了,變得無序。

所以服務標準化是后臺技術團隊組建開始的第一要務。

兩個誤區

**誤區一:**找幾個開源的組件用起來就好了唄。

  • 通常的開源的組件,只是在某一方面上規范了服務,有的是規范了網絡調用,有的是規范了如何監控,有的是規范了如何記錄遠程記錄,其實這還遠遠不夠,例如配置文件、接口定義、使用到的外部庫、安裝目錄的結構等非常多的細節,必須統一管理、有唯一出處。

**誤區二:**你說的我都懂,我們團隊剛起步,業務需求多,時間緊,先野蠻生長,打破條條框框,后面再規范再改。

  • 一開始沒有標準化,后面當代碼和模塊都多起來了,且都處于運營狀態,再改再標準化,難度非常大,成本非常大,風險非常大;另外工欲善其事必先利其器,一開始就標準化好,其實可以讓業務跑的更快。

如何實現服務標準化?

首先,每個服務的配置都Web化、集中管理起來。

部署在哪些IP上?

有且只有一個配置文件。
Protocol buffer的接口定義文件。
引用了哪些外部庫?例如openssl。
業務邏輯和基礎框架分離,業務邏輯以插件形式提供。
然后,每個業務模塊部署的目錄結構都是確定的。
如上圖所示:

  • 業務部署的目錄都是/msec/一級業務名/二級業務名;

  • 都包含bin etc log 等幾個目錄;

  • bin里面是啟停腳本、業務插件msec.so和外部庫(如果有);

  • etc里面是配置文件config.ini;

  • Log里面是本地的日志文件。

另外,程序員不能隨意打破上面的方式。例如臨時的另外搞一個自己配置文件什么的,他如果這樣做,那下次發布的時候目錄會被覆蓋,個性化的東西會被刪除掉。

后臺服務的RPC和路由管理

互聯網服務的后臺,硬件通常是由大量的廉價機器組成;軟件架構通常采取大系統小做、分而治之的思想。這就決定了業務邏輯涉及到大量的網路IO,同時單機故障、網絡局部故障是運營的常態。那么,RPC和路由管理就顯得尤其重要了。毫秒服務引擎為此提供了一個完整的解決方案。

  • RPC的概念其實出現已經很久了,記得筆者讀大學的時候,接觸到RPC的概念,總覺得不重要,多此一舉。 我掌握好Socket通信這個利器和TCP/IP協議族原理,什么功能不能實現?

  • RPC就跟本地函數調用一樣寫代碼,確實開發效率比較高;我自己把Socket相關函數好好封裝一下,讓代碼復用起來,開發效率也很高。

  • 不懂或者不關注網絡通信底層原理,光會函數調來調去,這樣的程序員太沒有出息了!

后來,筆者開始帶團隊,親身經歷了一些團隊協作和IT服務運營過程中的故事,才發現RPC非常關鍵。如果沒有很好的實現RPC和路由管理,IT系統服務質量會過度的依賴人的意識,而這個通常成本非常高、效果也不好。

毫秒服務引擎是怎么做的?

首先,毫秒服務引擎將每個服務部署在哪些IP上這些信息集中管理起來,即使是調用外部的非標準服務(我們叫異構服務),也需要將該外部服務的接口IP配置到毫秒服務引擎管理系統里。這樣涉及到的IP信息就不會散落在代碼和各種配置文件里了。

服務之間的調用,統一采用CallMethod()函數的方式,避免代碼千奇百怪;按服務名字調用和接口名調用。
RPC背后的路由算法對于單機故障、網絡局部波動等異常,自動容錯。簡單的說,路由算法按一定的規則輪轉的選擇被調用模塊的接口機,并統計過去一段時間的調用成功率、時延信息,根據這些信息調整該接口機被選擇到的比例。如果某個接口機故障了,那么就不會發送請求給它,從而實現自動容錯。

毫秒服務引擎框架本身,在RPC執行的時候,就上報了很多基礎屬性和日志,這樣保證了服務監控和告警等運營措施不依賴與人的意識。下圖是叫做getMP3List這樣一個RPC調用的請求數和成功數,這些是不需要業務開發者工作就自動上報。

每個請求有唯一ID來標識,通過該ID,毫秒服務引擎可以在框圖中直觀的呈現該請求經過的模塊、模塊間的RPC名字等信息,這個同樣不需要業務開發者的工作就自動實現。

后臺服務的灰度發布與監控

灰度發布和監控是互聯網海量服務必備的兩大利器,能夠極大提高后臺服務可用性和運營水平,背后的哲學是持續交付、用戶測試和盡在掌控。

在騰訊,有一個課程系列,叫做《海量服務之道》,包含十多門課程和方法論,是技術同事必修和必知必會的,其中兩門課程就是《灰度發布》和《全方位監控》。

筆者在加入騰訊QQ后臺團隊之前,曾經在電信行業、金融行業做過幾年開發工作。剛進入騰訊時,覺得技術上很多地方讓人耳目一新。

  • 后臺系統都是部署在非常多的廉價服務器上,每個人都會管理非常多的機器,讓人覺得很有成就感很富有。

  • 有比較精確的設備預算計算模型,每個服務器的性能在考慮容災冗余的前提下,通常被壓榨到剛剛好,負責人會深入的洞悉整個系統的性能、容災、柔性等方方面面。能負責一個海量的系統是很榮耀的一件事情。

  • 沒有專職的測試人員,經過開發者自測后,灰度發布加詳細的監控,主要的系統幾乎每兩周都會被發布一輪,作為后臺技術人員,自己的工作直接影響數以億計的用戶,有點手握核彈處于上帝視角的感覺。

  • 監控系統(我們內部一個叫monitor的系統)真的是太方便了,一條條曲線直觀的展示整個系統運作的各種指標,如果有異常短信和電話就會響起來,讓人覺得一切盡在掌控,有一種面對著大量儀表盤操控著航母游弋或者是戰斗機掛著核彈翱翔的感覺。

好了,趕緊結束程序員意淫的美好感覺,我想說的重點是:灰度發布和監控真的是互聯網海量服務必備的兩大利器,能夠極大的提高后臺服務可用性和運營水平。

當然,灰度發布不只是一部分一部分的發布新代碼,監控也不只是繪制曲線和告警短信那么簡單,這里面深究下去會有很多東西,背后的哲學是持續交付、用戶測試和盡在掌控。

毫秒服務引擎是怎么做的?

#####灰度發布 在服務配置管理頁點擊“制定發布計劃”。

選擇這一次灰度要發布的目標機器和發布類型。
在接下來的向導中選擇正確版本的配置文件、外部庫、業務插件等,這樣就完成了發布計劃的制作。
接著,點擊菜單 “運維->發布”,可以查詢所有發布計劃,對于已經發布的計劃,可以做回滾操作。點擊詳情可以查看發布計劃更詳細信息,并執行發布。

監控

關于監控,在“RPC和路由管理”那里講得已經比較詳細了,這里不贅述。只說明一下:除了RPC和框架本身自動上報的一些信息,還支持業務自定義上報信息(例如我想上報第28級VIP用戶登錄的次數),且支持對于關鍵指標的波動、最大值、最小值設置告警。

KV存儲集群的設計要點

Key-Value存儲系統,是非常普遍的需求,幾乎每個在線的互聯網后臺服務都需要KV存儲,我們團隊在KV存儲方面,經歷過幾個時期,我自己深感要做好不容易。

第一個時期,很早期的時候,我們的數據存儲在MySQL表里,按照用戶賬號簡單的分庫分表,為了保證訪問高并發,利用每個MySQL服務器的內存做數據緩存;主備兩套分布在不同IDC,業務邏輯自己做副本同步。當時主要的問題是:內存的數據結構擴展困難、運維工作瑣碎、數據同步機制本身的缺陷導致不能做異地IDC部署,這些缺點對于業務飛速發展、一地機房已經不夠用的局面非常被動。

第二個時期,我們設計了新的KV存儲系統,其用戶數據結構容易擴展、具備可以多地部署的數據同步機制,很好的應對了新時期業務發展的需要。為了設備成本考慮,我們把數據做冷熱分離,訪問頻繁的數據會加載到專門的Cache層,且對于不同的訪問模型,掛載不同架構的Cache,另外一個File層專門做數據持久化。這樣的設計,使得架構太復雜,bug收斂速度慢,運維工作相比以前甚至更復雜了。

第三個時期,為了應對普遍的KV存儲需求,我們以公共組件的形式重新設計了KV存儲,作為團隊標準的組件之一,得到了大規模的應用。結合同期抽象出來的邏輯層框架、路由管理等其他組件,團隊的公共基礎組件和運維設施建設的比較完備了,整個業務的開發和運維實現了標準化。但這個階段就用了我們團隊足足2年多時間。

不同于無數據的邏輯層框架,KV存儲系統的架構設計會更復雜、運維工作更繁瑣、運營過程中可能出現的狀況更多、bug收斂時間會更長。一句話:團隊自己做一個KV存儲系統是成本很高的,而且也有比較高的技術門檻。

設計一個KV存儲,需要考慮至少這些方面。

  1. 如何組織機器的存儲介質,通常是內存、磁盤文件;例如用hash的方式組織內存。

  2. 如何設計用戶的數據結構,使得通用、易于擴展、存儲利用率高;例如PB序列化、Json、XML方式。

  3. 友好的訪問接口,而不只是get/set一整個value。

  4. 如何做集群分布、如何sharding、如何做到方便的擴縮容;例如一致性hash算法。

  5. 如何做數據冗余、副本間如何同步、一致性問題;副本間如何選舉master。

  6. 備份與恢復、數據校驗與容錯。

  7. 讀寫性能。

  8. 其他可能的特殊需求:例如我們設計過一個KV存儲,用于存儲一些公眾號的個數不受限粉絲列表。

上面8點,業內的KV存儲組件一般都會考慮到,或者各有特色,各自優勢在伯仲之間。但是綜合過去的經驗教訓,我們覺得有一點很容易被忽視:可運維性、運維自動化、黑盒化運維。

舉一個例子,前面提到的我們第二個時期的KV存儲系統,剛開始應用的時候,一次擴容過程會有10多步的運維操作,包括load數據、做增量同步、多次修改機器狀態、數據比對等等,需要運維同事以高度的責任心來完成。另外就是運維同事必須如該KV存儲架構設計者一樣深刻理解系統背后的原理和細節,否則就不能很好的執行運維操作,這個要求也非常高,新老交接周期長,還容易出運維事故。

基于上面的考慮,同事為了讓用戶更容易學習和接受,毫秒服務引擎在Redis Cluster的基礎上,實現了運維Web化,并加上了集群的監控。

通過Web界面方便進行

集群概要狀態查看。

可以在Web上方便的完成日常的運維操作:新搭集群、擴縮容、故障機器的恢復。
請求量、內存使用、CPU等各種狀態信息可直觀監控,也可以按IP粒度查看。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/448733.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/448733.shtml
英文地址,請注明出處:http://en.pswp.cn/news/448733.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

古代隱士如何忙衣食

三歲娃兒都曉得,吃飯穿衣是維持生命的基本條件,想瀟灑地“舊山歸隱浪搖青,綠鬢山童一帙經”,就得準備足夠的柴米油鹽。 所謂隱士,須得強調是“士”,即讀書人。手無縛雞之力,不仕就無俸祿&…

一個秘密

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 這是一個秘密, 一個不想說出來,卻真實的秘密: --- --- 本來我不想說, 可是最近的一切…

程序員如何在大公司做管理

本文被記錄的最大初衷在于從創業公司的CEO轉變成阿里巴巴的一名開發專家,打心底觸動了心靈最深處的一次學習經歷,無論成長、挫折、困難、收獲都烙在心里。 寫文章的思路: 背景(認清現狀)管理(闡述自己的理解…

WebGL之物體選擇

原文地址: WebGL之物體選擇 使用WebGL將圖形繪制到畫布后,如何與外部進行交互?這其中最關鍵的就是如何實現物體的選擇。比如鼠標點擊后判斷是否選中了某個圖形或圖形的某個部分。 本節實現的效果: WebGL選中物體 如何實現選中物體 顏色區分法 《WebGL編程…

中國歷史上影響最大的10首詩

中國是詩歌的國度,有許多詩都有很大的影響。這里所謂影響“最大”(而不是“最好”)的十首詩,除了要寫得好之外,還必須通俗易懂、易記。 第一首:李白的《靜夜思》 床前明月光,疑是地上霜。 舉頭望明月,低頭…

XML建模

建模分兩步&#xff1a;1、以面向對象的編程思想&#xff0c;描述xml資源文件。 2、將xml文件中內容封裝進model實體對象。 導入文件&#xff1a;config.xml <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE config[<!ELEMENT config (acti…

Docker 方式安裝部署 rocketMQ 、部署 圖形化界面控制臺、rocketMQ 控制臺

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 直接上官網&#xff0c;找到工程&#xff0c;clone 到本地&#xff0c;地址&#xff1a;https://github.com/apache/rocketmq-extern…

迭代器(iterator)

Date: 2019-05-23 Author: Sun 為何要引入迭代器&#xff1f; ? 通過列表生成式&#xff0c;我們可以直接創建一個列表&#xff0c;但是&#xff0c;受到內存限制&#xff0c;列表容量肯定是有限的&#xff0c;而且創建一個包含100萬個元素的列表&#xff0c;不僅占用很大的存…

初識python之函數基礎

課堂筆記&#xff1a; 1、什么是函數&#xff1f;函數相當于工具&#xff0c;需要事先準備好&#xff0c;在需要用時再使用。2、如何使用函數&#xff1f;函數必須先定義、后調用。3、函數的語法:# def 函數名(參數1,參數2...):# """# 注釋# 函數的說明# 水…

java 的幾種對象 (PO,VO,DAO,BO,POJO) 解釋

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、PO:persistant object 持久對象,可以看成是與數據庫中的表相映射的java對象。最簡單的PO就是對應數據庫中某個表中的一條記錄&#x…

【隨想】每日兩題Day.22

題目&#xff1a;102. 二叉樹的層序遍歷 給你二叉樹的根節點 root &#xff0c;返回其節點值的 層序遍歷 。 &#xff08;即逐層地&#xff0c;從左到右訪問所有節點&#xff09;。 示例 1&#xff1a; 輸入&#xff1a;root [3,9,20,null,null,15,7] 輸出&#xff1a;[[3],[…

幫助子女成功的十大路徑

美國全國家長協會(National PTA)建議指出&#xff1a;作為家長您對你子女的成功起著非常重要的影響作用&#xff0c;并舉出幫助子女成功的十種路徑。 1、與子女溝通 如果我們盡早地與子女溝通&#xff0c;提供給他們信息與行為準則&#xff0c;獲得子女的信任&#xff0c;在…

shell關閉指定進程

例如要關閉jupyter-notebook這個進程&#xff1a; ps -ef | grep jupyter-notebook | grep -v grep | cut -c 9-15 | xargs kill -9 說明&#xff1a;管道符“|”用來隔開兩個命令&#xff0c;管道符左邊命令的輸出會作為管道符右邊命令的輸入。 “ps -ef” 查看所有進程  …

垃圾回收算法與垃圾回收器

Java與C等語言最大的技術區別&#xff1a;自動化的垃圾回收機制&#xff08;GC&#xff09; 為什么要了解GC和內存分配策略 1、面試需要 2、GC對應用的性能是有影響的&#xff1b; 3、寫代碼有好處 棧&#xff1a;棧中的生命周期是跟隨線程&#xff0c;所以一般不需要關注 堆&a…

提高孩子睡眠質量 學業事半功倍

睡眠如同大腦的食物。在睡眠期間&#xff0c;許多重要的身體機能靜靜地發生著作用。省略睡眠是有害的&#xff0c;如果一個嚴重缺覺的人開著車&#xff0c;他會臉色蒼白、喜怒無常、反應遲鈍&#xff0c;可能是致命的危險。缺少睡眠讓青少年很難與人相處&#xff0c;學業表現不…

實體類(VO,DO,DTO)的劃分

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 從領域建模中的實體劃分、項目中的實際應用情況兩個角度&#xff0c;對這幾個概念進行簡析。 得出的主要結論是&#xff1a;在項目應用…

IIS新建站點服務器,localhost能登錄但是IP訪問登錄不了。

IIS服務器新建站點之后&#xff0c;瀏覽頁面&#xff0c;服務器本地是可以登錄&#xff0c;但是localhost換成IP就無法訪問。其他站點IP卻可以訪問。 1.如果瀏覽直接失敗&#xff0c;說明端口號需要更換。 2.如果出現IP不能訪問&#xff0c;localhost能訪問&#xff0c;需要在高…

eclipse問題_Alt+/不給提示,只補充代碼問題的解決方案

今天用eclipse敲代碼的時候遇到的問題 我還以為是沖突什么的 還重新裝了軟件 最后才發現原來是快捷鍵設置的問題 解決方案&#xff1a; 1&#xff1a;打開菜單window→Preferences&#xff0c;然后在窗口的左側樹選擇General->Keys 2&#xff1a;在下圖中的5框的地方輸入“w…

領域驅動設計:淺析 VO、DTO、DO、PO 概念、區別、用處

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 本篇文章主要討論一下我們經常會用到的一些對象&#xff1a;VO、DTO、DO和PO。 由于不同的項目和開發人員有不同的命名習慣&#xff0c…

動腦的生活教育

心理學家華生曾經說過&#xff1a;“如果給我一打孩子&#xff0c;我可以把他們變成律師、醫師、科學家&#xff0c;或是強盜、土匪。”華生認為&#xff0c;教育孩子就如同馬戲團的馴獸師訓練野獸一樣&#xff0c;是“刺激”與“反應”的聯結&#xff0c;不需要任何的“思考”…