.Net Core微服务架构技术栈的那些事
一、前言
? ? ? ? ?大家一直都在談?wù)撐⒎?wù)架構(gòu),園子里面也有很多關(guān)于微服務(wù)的文章,前幾天也有一些園子的朋友問我微服務(wù)架構(gòu)的一些技術(shù),我這里就整理了微服務(wù)架構(gòu)的技術(shù)棧路線圖,這里就分享出來和大家一起探討學(xué)習(xí),同時讓新手對微服務(wù)相關(guān)技術(shù)有一個更深入的了解。
二、技術(shù)棧
2.1 工欲善其事,必先利其器
現(xiàn)在互聯(lián)網(wǎng)盛行的年代,互聯(lián)網(wǎng)產(chǎn)品也層出不窮,受歡迎的互聯(lián)網(wǎng)產(chǎn)品都有一個比較牛的技術(shù)團隊,我這里分享下.net 微服務(wù)架構(gòu)技術(shù)棧圖如下:
俗話說得好:工欲善其事,必先利其器。一個優(yōu)秀的工程師應(yīng)該善于使用框架和工具,在微服務(wù)這一塊的技術(shù)選型并非一蹴而就,需要經(jīng)過日積月累和落地的項目才能完善。下文我會一一分享技術(shù)棧中的主要框架和工具的使用場景,這篇文章就不一一分享實戰(zhàn)例子。
2.2 微服務(wù)
微服務(wù)如何“微”?
微服務(wù),當(dāng)然核心是主題是“微”,怎么微呢?應(yīng)該如何微呢?在我剛來杭州的時候接觸過一個電商系統(tǒng)的單體架構(gòu),系統(tǒng)比較龐大,結(jié)合了各種電商該擁有的業(yè)務(wù)邏輯和場景, 代碼也比較難于維護,前前后后接手的人也比較多,代碼耦合度太高,改個業(yè)務(wù)邏輯基本上是牽一發(fā)而動全身,跟我上個月分享的關(guān)于Asp.Net Core 中IdentityServer4 授權(quán)中心之應(yīng)用實戰(zhàn)的文章中的電商系統(tǒng)最初的架構(gòu)圖類似,如下:那針對這個架構(gòu)就有可“微”之談了。
這里針對該單體架構(gòu)可以做如下幾個原則上進行“微”服務(wù):
根據(jù)業(yè)務(wù)來進行拆分,一個業(yè)務(wù)一個服務(wù)原則進行拆分,做到通用性業(yè)務(wù)服務(wù)模塊,這樣業(yè)務(wù)之間可以做到高內(nèi)聚低耦合。后面隨意改動哪一塊業(yè)務(wù),只需要去改動這一塊的業(yè)務(wù)微服務(wù)即可,其他業(yè)務(wù)不會受到影響。
一個業(yè)務(wù)模塊一個獨立的數(shù)據(jù)庫為原則,相互平行的業(yè)務(wù)做到不需要相互依賴調(diào)用。
外層API網(wǎng)關(guān)進行業(yè)務(wù)邏輯的整合。
一個業(yè)務(wù)數(shù)據(jù)庫一個微服務(wù)為原則。
結(jié)合分布式服務(wù),可以快速版本迭代,發(fā)布平滑發(fā)布,不受時間影響,每時每刻都可以發(fā)布,無需半夜等到12點進行發(fā)布。(比較痛苦的發(fā)布,猶如三日凌空般(有點夸張),曾經(jīng)有段時間是每周都有那么幾個晚上痛苦的發(fā)布,一發(fā)布就可能是凌晨4,5點,很多時候發(fā)布完,還要經(jīng)過各種測試,最后發(fā)現(xiàn)問題還得線上改bug,我們回去的時候別的同事已經(jīng)來上班了;當(dāng)時我們的技術(shù)大佬說過這么一句話:“他連續(xù)一周都沒看到過他的兒子,回去的時候,他兒子早就睡著了,起來上班的時候,他兒子已經(jīng)去學(xué)校了”,大家一定也有過這樣的發(fā)布經(jīng)歷。)
按照上面的原則后,原來的電商單體架構(gòu)微服務(wù)后架構(gòu)圖如下:架構(gòu)圖粗略的畫了下,能夠表明意思即可,微服務(wù)、Docker、k8s那一塊簡要的概括,沒有詳細畫出具體的圖。
微服務(wù)集群
微服務(wù)已經(jīng)“微”好了,那需要一個服務(wù)發(fā)現(xiàn)的數(shù)據(jù)中心,這里就該用到Consul了,Consul主要用來注冊服務(wù),及服務(wù)發(fā)現(xiàn),以及服務(wù)的健康檢查,我們可以根據(jù)需要針對某些業(yè)務(wù)服務(wù)進行自動擴容,添加服務(wù)器及擴張服務(wù)集群,一臺服務(wù)掛了,Consul會自動選擇可用的服務(wù)節(jié)點進行連接使用,這樣整體電商系統(tǒng)穩(wěn)定性大大增大。需要了解Consul更加詳細的特性和搭建,可以點擊5分鐘看懂微服務(wù)架構(gòu)下的Consul 特性及搭建 一文閱讀。
微服務(wù)如何保證數(shù)據(jù)的一致性
以前單體架構(gòu)應(yīng)用,對于業(yè)務(wù)之間的耦合是通過事務(wù)保證數(shù)據(jù)的一致性的,那對于微服務(wù)而言怎么做到數(shù)據(jù)的一致性呢?上門也說了,微服務(wù)應(yīng)該做到業(yè)務(wù)之間沒有依賴關(guān)系,每一個業(yè)務(wù)都是獨立的一個服務(wù),那這樣怎么保證業(yè)務(wù)與之間的數(shù)據(jù)的一致性也存在很大的一個問題,也是業(yè)界對微服務(wù)爭議比較大的一個話題,那到底該如何保證數(shù)據(jù)的一致性?
在分布式系統(tǒng)架構(gòu)中有一個CAP理論:任何分布式系統(tǒng)只可同時滿足一致性(Consistency)、可用性(Availability)、分區(qū)容錯性(Partition tolerance)中的兩點,沒法三者兼顧。對于分布式系統(tǒng)來說,分區(qū)容錯性是基本要求,否則就失去了價值。因此,就只能在可用性和一致性之間做出選擇。如果選擇提供一致性需要付出在滿足一致性之前阻塞其他并發(fā)訪問的代價。這可能持續(xù)一個不確定的時間,尤其是在系統(tǒng)已經(jīng)表現(xiàn)出高延遲時或者網(wǎng)絡(luò)故障導(dǎo)致失去連接時。依據(jù)目前的成功經(jīng)驗,可用性一般是更好的選擇,但是在服務(wù)和數(shù)據(jù)庫之間維護數(shù)據(jù)一致性是非常根本的需求,微服務(wù)架構(gòu)中選擇滿足最終一致性。
最終一致性是指系統(tǒng)中的所有數(shù)據(jù)副本經(jīng)過一段時間后,最終能夠達到一致的狀態(tài)。這里所說的一段時間,也要是用戶可接受范圍內(nèi)的一段時間。
從一致性的本質(zhì)來看,就是在一個業(yè)務(wù)邏輯中包含的所有服務(wù)要么都成功,要么都失敗。那我們又該如何選擇方向,來保證成功還是保證失敗呢?就是就需要根據(jù)業(yè)務(wù)模式做出選擇。實現(xiàn)最終一致性有三種模式:可靠事件模式、業(yè)務(wù)補償模式、TCC模式,這里就不再延伸,后面有機會再來分享學(xué)習(xí)。
2.3 微服務(wù)開源框架
我這里微服務(wù)架構(gòu)使用的是開源微服務(wù)框架 core-grpc 開源框架源代碼地址:https://github.com/overtly/core-grpc 前面我分享過一篇關(guān)于微服務(wù)架構(gòu)應(yīng)用實戰(zhàn)中簡單描述了微服務(wù)的基本概念和利弊,這里就不再分享,具體應(yīng)用也可以點擊【.net core】電商平臺升級之微服務(wù)架構(gòu)應(yīng)用實戰(zhàn)(core-grpc) 閱讀
2.4 ORM框架
微服務(wù)中使用的ORM Dapper ,而使用的的第三方開源組件是core-data,開源作者對dapper 進行了一次封裝,開源框架源代碼地址:https://github.com/overtly/core-data
core-data主要優(yōu)勢:
官方建議使用DDD 領(lǐng)域驅(qū)動設(shè)計思想開發(fā)
支持多種數(shù)據(jù)庫,簡單配置添加鏈接的配置即可
多數(shù)據(jù)庫的支持
支持分表操作,自定義分表策略的支持
支持表達式方式編寫,減少寫Sql語句機械性工作
可對Dapper 進行擴展
性能依賴于Dapper 本身的性能,Dapper 本身是輕量級ORM ,官方測試性能都強于其他的ORM
2.5 分布式跟蹤系統(tǒng)
隨著微服務(wù)架構(gòu)的流行,一些微服務(wù)架構(gòu)下的問題也會越來越突出,比如一個請求會涉及多個服務(wù),而服務(wù)本身可能也會依賴其他服務(wù),整個請求路徑就構(gòu)成了一個網(wǎng)狀的調(diào)用鏈,而在整個調(diào)用鏈中一旦某個節(jié)點發(fā)生異常,整個調(diào)用鏈的穩(wěn)定性就會受到影響,所以會深深的感受到 “銀彈” 這個詞是不存在的,每種架構(gòu)都有其優(yōu)缺點 。
對以上情況, 我們就需要一些可以幫助理解系統(tǒng)行為、用于分析性能問題的工具,以便發(fā)生故障的時候,能夠快速定位和解決問題,這時候 APM(應(yīng)用性能管理)工具就該閃亮登場了。目前主要的一些 APM 工具有: Cat、Zipkin、Pinpoint、SkyWalking,這里主要介紹 SkyWalking ,它是一款優(yōu)秀的國產(chǎn) APM 工具,包括了分布式追蹤、性能指標分析、應(yīng)用和服務(wù)依賴分析等。
2.6 系統(tǒng)日志集成
龐大的系統(tǒng)中離不開日志系統(tǒng),排查問題,記錄相關(guān)敏感信息等都需要一個日志系統(tǒng),這里選擇使用ExceptionLess 日志系統(tǒng),日志寫入到ES中,并支持可視化UI進行日志管理,查詢,平常遇到問題,直接通過日志管理后臺進行排查。
2.7 消息隊列
消息隊列中間件是分布式系統(tǒng)中重要的組件,主要解決應(yīng)用耦合,異步消息,流量削鋒等問題。實現(xiàn)高性能、高可用、可伸縮和最終一致性架構(gòu)。使用較多的消息隊列有ActiveMQ、RabbitMQ、ZeroMQ、Kafka、MetaMQ、RocketMQ。
2.8 任務(wù)調(diào)度
這里主要使用的是Quartz.Net 進行作業(yè)任務(wù)調(diào)度,任務(wù)調(diào)用有什么用處呢?,比如我們需要統(tǒng)計一個數(shù)據(jù),但是實時統(tǒng)計需要一大堆的連表查詢,并且比較損耗數(shù)據(jù)庫的性能,因此可以選擇使用任務(wù)調(diào)度的方案進行數(shù)據(jù)統(tǒng)計作業(yè),半夜某個時間點去統(tǒng)計前一天的數(shù)據(jù)。
2.9 NoSql
Nosql 主要是非關(guān)系型數(shù)據(jù)庫,比如MongDB、 Redis、Memcache等,可以用來在API網(wǎng)關(guān)和數(shù)據(jù)庫層面做一層數(shù)據(jù)緩存,訪問一些不是經(jīng)常更新的數(shù)據(jù),把它緩存起來,每次網(wǎng)絡(luò)請求過來就可以先通過從分布式緩存中進行數(shù)據(jù)讀取,減少對數(shù)據(jù)庫的查詢壓力,提高系統(tǒng)的吞吐量。
2.10 可視化數(shù)據(jù)管理及分析(Kibana)
Kibana 是為 Elasticsearch設(shè)計的開源分析和可視化平臺。你可以使用 Kibana 來搜索,查看存儲在 Elasticsearch 索引中的數(shù)據(jù)并與之交互。你可以很容易實現(xiàn)高級的數(shù)據(jù)分析和可視化,以圖標的形式展現(xiàn)出來。Kibana 的使用場景,應(yīng)該集中在兩方面:
實時監(jiān)控 通過 histogram 面板,配合不同條件的多個 queries 可以對一個事件走很多個維度組合出不同的時間序列走勢。時間序列數(shù)據(jù)是最常見的監(jiān)控報警了。問題分析
關(guān)于 elk 的用途,可以參照其對應(yīng)的商業(yè)產(chǎn)品 splunk 的場景:使用 Splunk 的意義在于使信息收集和處理智能化。而其操作智能化表現(xiàn)在:搜索,通過下鉆數(shù)據(jù)排查問題,通過分析根本原因來解決問題;實時可見性,可以將對系統(tǒng)的檢測和警報結(jié)合在一起,便于跟蹤 SLA 和性能問題;歷史分析,可以從中找出趨勢和歷史模式,行為基線和閾值,生成一致性報告。
2.11 Prometheus
Prometheus是一套開源的系統(tǒng)監(jiān)控報警框架。Prometheus作為新一代的云原生監(jiān)控系統(tǒng),相比傳統(tǒng)監(jiān)控監(jiān)控系統(tǒng)(Nagios或者Zabbix)擁有如下優(yōu)點。
優(yōu)勢
易于管理
輕易獲取服務(wù)內(nèi)部狀態(tài)
高效靈活的查詢語句
支持本地和遠程存儲
采用http協(xié)議,默認pull模式拉取數(shù)據(jù),也可以通過中間網(wǎng)關(guān)push數(shù)據(jù)
支持自動發(fā)現(xiàn)
可擴展
易集成
好了到了這里,大多已經(jīng)介紹完了,其他幾個大家都是比較常見常使用的技術(shù),就不一一介紹了。
2.12 .Net Core 虛擬化
.Net Core 新一代的.Net Core 跨平臺開發(fā)框架,可以脫離windows 環(huán)境,搭建在linux等平臺上,那怎樣搭建呢?當(dāng)然可以使用當(dāng)前比較流行的Docker容器,把.net core 項目虛擬化 搭建在Docker 容器中運行,不依賴于任何平臺和環(huán)境,只需要通過命令制作好鏡像即可,同時也可以借助K8s來進行多容器應(yīng)用部署、編排、更新等。
什么是k8s呢?
Kubernetes是一個開源的,用于管理云平臺中多個主機上的容器化的應(yīng)用,Kubernetes的目標是讓部署容器化的應(yīng)用簡單并且高效(powerful),Kubernetes提供了應(yīng)用部署,規(guī)劃,更新,維護的一種機制。
Kubernetes一個核心的特點就是能夠自主的管理容器來保證云平臺中的容器按照用戶的期望狀態(tài)運行著(比如用戶想讓apache一直運行,用戶不需要關(guān)心怎么去做,Kubernetes會自動去監(jiān)控,然后去重啟,新建,總之,讓apache一直提供服務(wù)),管理員可以加載一個微型服務(wù),讓規(guī)劃器來找到合適的位置,同時,Kubernetes也系統(tǒng)提升工具以及人性化方面,讓用戶能夠方便的部署自己的應(yīng)用(就像canary deployments)。
現(xiàn)在Kubernetes著重于不間斷的服務(wù)狀態(tài)(比如web服務(wù)器或者緩存服務(wù)器)和原生云平臺應(yīng)用(Nosql),在不久的將來會支持各種生產(chǎn)云平臺中的各種服務(wù),例如,分批,工作流,以及傳統(tǒng)數(shù)據(jù)庫。
在Kubenetes中,所有的容器均在Pod中運行,一個Pod可以承載一個或者多個相關(guān)的容器,在后邊的案例中,同一個Pod中的容器會部署在同一個物理機器上并且能夠共享資源。一個Pod也可以包含O個或者多個磁盤卷組(volumes),這些卷組將會以目錄的形式提供給一個容器,或者被所有Pod中的容器共享,對于用戶創(chuàng)建的每個Pod,系統(tǒng)會自動選擇那個健康并且有足夠容量的機器,然后創(chuàng)建類似容器的容器,當(dāng)容器創(chuàng)建失敗的時候,容器會被node agent自動的重啟,這個node agent叫kubelet,但是,如果是Pod失敗或者機器,它不會自動的轉(zhuǎn)移并且啟動,除非用戶定義了 replication controller。
用戶可以自己創(chuàng)建并管理Pod,Kubernetes將這些操作簡化為兩個操作:基于相同的Pod配置文件部署多個Pod復(fù)制品;創(chuàng)建可替代的Pod當(dāng)一個Pod掛了或者機器掛了的時候。而Kubernetes API中負責(zé)來重新啟動,遷移等行為的部分叫做“replication controller”,它根據(jù)一個模板生成了一個Pod,然后系統(tǒng)就根據(jù)用戶的需求創(chuàng)建了許多冗余,這些冗余的Pod組成了一個整個應(yīng)用,或者服務(wù),或者服務(wù)中的一層。一旦一個Pod被創(chuàng)建,系統(tǒng)就會不停的監(jiān)控Pod的健康情況以及Pod所在主機的健康情況,如果這個Pod因為軟件原因掛掉了或者所在的機器掛掉了,replication controller 會自動在一個健康的機器上創(chuàng)建一個一摸一樣的Pod,來維持原來的Pod冗余狀態(tài)不變,一個應(yīng)用的多個Pod可以共享一個機器。
我們經(jīng)常需要選中一組Pod,例如,我們要限制一組Pod的某些操作,或者查詢某組Pod的狀態(tài),作為Kubernetes的基本機制,用戶可以給Kubernetes Api中的任何對象貼上一組 key:value的標簽,然后,我們就可以通過標簽來選擇一組相關(guān)的Kubernetes Api 對象,然后去執(zhí)行一些特定的操作,每個資源額外擁有一組(很多) keys 和 values,然后外部的工具可以使用這些keys和vlues值進行對象的檢索,這些Map叫做annotations(注釋)。
Kubernetes支持一種特殊的網(wǎng)絡(luò)模型,Kubernetes創(chuàng)建了一個地址空間,并且不動態(tài)的分配端口,它可以允許用戶選擇任何想使用的端口,為了實現(xiàn)這個功能,它為每個Pod分配IP地址。
現(xiàn)代互聯(lián)網(wǎng)應(yīng)用一般都會包含多層服務(wù)構(gòu)成,比如web前臺空間與用來存儲鍵值對的內(nèi)存服務(wù)器以及對應(yīng)的存儲服務(wù),為了更好的服務(wù)于這樣的架構(gòu),Kubernetes提供了服務(wù)的抽象,并提供了固定的IP地址和DNS名稱,而這些與一系列Pod進行動態(tài)關(guān)聯(lián),這些都通過之前提到的標簽進行關(guān)聯(lián),所以我們可以關(guān)聯(lián)任何我們想關(guān)聯(lián)的Pod,當(dāng)一個Pod中的容器訪問這個地址的時候,這個請求會被轉(zhuǎn)發(fā)到本地代理(kube proxy),每臺機器上均有一個本地代理,然后被轉(zhuǎn)發(fā)到相應(yīng)的后端容器。Kubernetes通過一種輪訓(xùn)機制選擇相應(yīng)的后端容器,這些動態(tài)的Pod被替換的時候,Kube proxy時刻追蹤著,所以,服務(wù)的 IP地址(dns名稱),從來不變。
所有Kubernetes中的資源,比如Pod,都通過一個叫URI的東西來區(qū)分,這個URI有一個UID,URI的重要組成部分是:對象的類型(比如pod),對象的名字,對象的命名空間,對于特殊的對象類型,在同一個命名空間內(nèi),所有的名字都是不同的,在對象只提供名稱,不提供命名空間的情況下,這種情況是假定是默認的命名空間。UID是時間和空間上的唯一。
2.13 自動化集成部署
為什么需要自動化集成部署?
我從以下幾點來分析為什么需要自動化集成部署:
你要相信的是所有的人工部署、發(fā)布、更新都是不可靠的,自動化智能部署可以減少事故率。
人為備份、發(fā)布更新都是效率非常低的。
如果某個項目需要更新,但是這個微服務(wù)有十幾臺負載,那你人為一臺一臺服務(wù)器更新發(fā)布是不是很繁瑣,更加容易出事故呢?
什么是自動化集成部署?
通過jenkins、gitlab、docker等工具,以及依賴事先寫好的腳本監(jiān)聽代碼提交動態(tài)、自動化構(gòu)造項目鏡像、推送鏡像到鏡像倉庫、Docker 拉起鏡像、啟動項目等系列自動化腳本處理,可以平滑的一臺一臺服務(wù)停止并且更新;一切操作無需人為的干預(yù),甚至出現(xiàn)問題可以一鍵回滾操作。
自動化集成部署有哪些優(yōu)勢
一切自動化,無需人為干預(yù),提高效率,專業(yè)的人做專業(yè)的事情,開發(fā)做好開發(fā)的事情即可,運維做好運維的事情。
發(fā)布可追溯
隨時人為干預(yù)回滾(通過腳本回顧上一步自動化備份的項目鏡像)
平滑發(fā)布,不影響用戶體驗,一臺一臺服務(wù)器切斷,發(fā)布更新。
三、結(jié)束語
今天寫的有點多了,畫了一張圖就停不下來了,本文分析了.net core 微服務(wù)架構(gòu)中用到的系列技術(shù)使用場景和用途,沒有一點實戰(zhàn)性東西,目的是讓小白有一個明確的技術(shù)方向,進一步掌握微服務(wù)架構(gòu)相關(guān)的技術(shù);也讓自己對以往的經(jīng)驗進行梳理和總結(jié),這樣才能朝著更大的目標前進。后面我會持續(xù)給大家?guī)砀嗟母韶浐蛯崙?zhàn)性東西,歡迎關(guān)注【dotNET博士】微信公眾號
往期精彩回顧
【.net core】電商平臺升級之微服務(wù)架構(gòu)應(yīng)用實戰(zhàn)
Asp.Net Core 中IdentityServer4 授權(quán)中心之應(yīng)用實戰(zhàn)
Asp.Net Core 中IdentityServer4 授權(quán)中心之自定義授權(quán)模式
Asp.Net Core 中IdentityServer4 授權(quán)流程及刷新Token
Asp.Net Core 中IdentityServer4 實戰(zhàn)之 Claim詳解
Asp.Net Core 中IdentityServer4 實戰(zhàn)之角色授權(quán)詳解
Asp.Net Core 中間件應(yīng)用實戰(zhàn)中你不知道的那些事
Asp.Net Core Filter 深入淺出的那些事-AOP
Asp.Net Core EndPoint 終結(jié)點路由工作原理解讀
ASP.NET CORE 內(nèi)置的IOC解讀及使用
??給個[在看],是對我最大的支持??
總結(jié)
以上是生活随笔為你收集整理的.Net Core微服务架构技术栈的那些事的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IdentityServer 部署踩坑记
- 下一篇: ASP.NET Core分布式项目实战(