軟體開發中常見的幾種不同服務模型包括SaaS(軟體即服務)、LaaS(許可即服務)、PaaS(平臺即服務)、CaaS(容器即服務)、IaaS(基礎設施即服務)和FaaS(功能即服務)。 很多人認為IaaS和FaaS是趨勢,是未來軟體設計與開發人員的基本必備技能,PowerDotNet和PowerDo ...
軟體開發中常見的幾種不同服務模型包括SaaS(軟體即服務)、LaaS(許可即服務)、PaaS(平臺即服務)、CaaS(容器即服務)、IaaS(基礎設施即服務)和FaaS(功能即服務)。
很多人認為IaaS和FaaS是趨勢,是未來軟體設計與開發人員的基本必備技能,PowerDotNet和PowerDotNetCore也特別註重這方面的設計開發和積累,目前已經做出了一些嘗試、實踐和探索。
PowerDotNet和PowerDotNetCore實現的公共服務按照主要功能模塊進行劃分,可以分為基礎設施、框架工具以及業務(微)服務三大類,客戶端和前端也小有所成,工作量較為飽和。
根據個人經驗,框架類庫和各種流行中間件代碼質量相對都比較高. 直接原因是需求明確,邏輯變動少,再加上有很多牛人出手或者設計優秀比較具有前瞻性,實現之後,通常都會穩定很多年不變。
PowerDotNet和PowerDotNetCore實現的公共服務雖然不完全等同於框架類庫和中間件,但也最大程度將穩定的改動極少的部分抽象提取出來沉澱固化,隔離變化點,面向介面編程應對變化。
面向對象編程的很多原則和規範同樣適用於PowerDotNet和PowerDotNetCore,經過積累、改進和優化,PowerDotNet經受了多次大規模實踐的檢驗,也逐漸形成了自己的一套平臺技術規約和接入規範。
本文結合自己的開發實踐經驗,給PowerDotNet和PowerDotNetCore應用開發、部署和運維等事項記個流水賬,畢竟積累歷史較為悠久且內容豐富,就算淡忘了也能做為參考文檔使用,咩哈哈。
一、根應用
在PowerDotNet和PowerDotNetCore中,DBKey是應用的起點和基石,是所有PowerDotNet和PowerDotNetCore應用中唯一需要配置資料庫連接串用戶名和密碼的地方。
一開始DBKeyApi服務在資料庫管理平臺進行管理,後續開發DataX應用的時候,經過重構和完善,所有關係型資料庫、NoSQL、NewSQL等連接和元數據管理都被劃分到DataX數據同步平臺。
1、DBKeyApi
DBKey服務所在的應用名稱叫Power.DataX.DBKeyApi,這是PowerDotNet必選應用,基於WebApi開發的服務介面,性能中規中矩,滿足絕大多數業務需求。
DBKeyApi需要對敏感字元串進行加密解密處理,目前PowerDotNet和PowerDotNetCore預設直接使用Framework下的DESUtil類(也可配置使用AES),需要在本地配置文件中新增加密和解密組件配置。
PowerDotNet同時還開發了Power.DataX.ThriftDBKeyApi和Power.DataX.GrpcDBKeyApi兩個備選應用。
(1)、Power.DataX.ThriftDBKeyApi
這是備選應用,基於Thrift協議開發的服務介面,對比下來,性能最好。
(2)、Power.DataX.GrpcDBKeyApi
這也是備選應用,基於Grpc協議開發的服務介面,對比下來,性能最差。
如果追求極致的性能體驗,建議使用Thrift協議,根據我的性能測試對比,Thirft>WebApi>Grpc,預設推薦使用WebApi,畢竟DBKey服務屬於數據量極少的字典型應用,訪問量並不大。
2、外部依賴
DBKeyApi是應用的基石介面,不依賴任何外部API服務,不接入配置中心、日誌平臺和監控平臺,也不使用消息隊列和分散式緩存,可以說是PowerDotNet和PowerDotNetCore中最簡單最穩定的應用。
3、安全調用
API服務開發好了總是需要被調用,對於內容敏感的DBKey服務,PowerDotNet做了最為嚴格的安全規約,調用方有IP和功能變數名稱白名單限制,所有調用DBKey的應用必須添加應用安全訪問審計日誌。
在PowerDotNet的服務治理平臺中,所有應用對DBKey服務的調用都需要進行嚴格審核和授權,APP、客戶端、前端等應用禁止直接通過內部或者外部網關調用DBKey服務。
4、心跳檢查
DBKey服務支持心跳檢查,服務啟動後會定時(預設5秒)非同步發送心跳包到註冊中心,PowerDotNet和PowerDotNetCore服務治理框架對所有服務介面都支持心跳檢查。
因為DBKey是根應用,也就是需要被第一個部署和啟動的應用,而註冊中心是後續依賴DBKey的應用,那麼我們就會有疑問:註冊中心沒有啟動的情況下心跳檢查不是一種浪費嗎?
這個問題很好解決,一種是直接將PowerDotNet配置的心跳檢查設置為禁用,另一種是對心跳檢查結果進行特殊code處理,註冊中心不啟動的情況下,忽略心跳結果,延遲當前間隔的6倍時間再發送心跳。
除了普通介面和頁面應用自動內置了心跳健康檢查,其他如關係型資料庫、NoSQL、Redis、MQ等都自動根據DBKey實現了簡易心跳檢查(判斷連接是否成功),排查問題有立竿見影的效果。
PowerDotNet和PowerDotNetCore從最初的設計開始算起,心跳就是最基礎最核心最穩定的功能之一,可以說很多系統可靠性和可用性的基礎就是心跳健康檢測。
二、根服務
有根應用,就有根服務。根應用和根服務就像核彈一樣,可以不用,但不能沒有^_^。
DBKeyApi應用下的所有介面都是全局系統根服務,但是PowerDotNet和PowerDotNetCore的系統根服務遠遠不止DBKeyApi下的服務。
PowerDotNet全局根服務介面名稱,不可被修改或清理(移除)。在服務治理平臺,根服務被修改時,系統會給出明顯的錯誤提示。
下麵根據系統分組的不同列舉幾個PowerDotNet和PowerDotNetCore中典型的根服務。
1、資料庫管理
(1)、查詢DB信息
(2)、查詢DBKey和DB類型信息
(3)、清理DBKey本地緩存
2、應用基礎
(1)、查詢系統信息
(2)、查詢應用信息(不含應用密鑰)
(3)、查詢應用密鑰
(4)、應用移入集群
(5)、應用移出集群
3、配置中心
(1)、查詢應用配置信息
(2)、根據版本號增量查詢配置
(3)、回調通知已獲取最新版本配置的應用和伺服器
(4)、查詢應用配置的DBKey信息
4、監控預警
(1)、添加日誌
(2)、添加監控
5、ETCD
(1)、查詢ETCD路由分組
(2)、刷新ETCD鍵值對
6、服務治理
(1)、註冊應用伺服器
(2)、下線應用伺服器
(3)、註冊API服務
(4)、下線API服務
(5)、查詢API服務信息
(6)、查詢可用的應用部署信息
(7)、心跳檢查
(8)、查詢伺服器信息
(9)、人工註冊API服務
(10)、查詢緩存統計信息
上面列舉的監控預警和ETCD介面都是可選的根服務,PowerDotNet內置了很多開關,如果你有更好的監控預警和一致性方案,完全可以自己按需二次開發。
三、監控預警
1、日誌平臺
記錄日誌API介面,不依賴於平臺基礎和服務治理根服務介面,也不依賴配置中心,僅依賴於DBKey服務。
DBKey服務不依賴於日誌平臺,日誌平臺則直接調用DBKey的服務。日誌API介面需要保證極高的性能和穩定性,當然應對業務和流量變化的可控的開關必不可少。
日誌平臺支持分片查詢,建議按照應用進行查詢,應用必選,支持全鏈路調用鏈跟蹤查詢。
日誌平臺支持敏感信息過濾功能,預設情況下,DEV和Test環境可配置為不過濾敏感信息,便於發現並快速排查問題。
2、監控平臺
記錄監控API介面,不依賴於平臺基礎和服務治理根服務介面,也不依賴配置中心,僅依賴於DBKey服務和日誌平臺。
和日誌API介面非常類似,監控API介面也需要保證極高的性能和穩定性,當然應對業務和流量變化的可控的開關也是必不可少。
四、平臺基礎
1、應用基礎
應用基礎根服務直接調用DBKey服務,同時也依賴日誌平臺和監控平臺,但不需要接入配置中心。
當然日誌平臺和監控平臺是可選的,可按需要進行配置。因為應用基礎也是字典型應用,穩定後改動極少,為了保證穩定和性能,依賴的外部服務當然是越少越好。
註意,平臺應用基礎服務依賴緩存,如使用Redis分散式緩存,建議配置分散式緩存優先 :
<add key="RedisCacheFirst" value="1"/>
2、配置中心
配置中心直接調用DBKey服務,同時也依賴日誌平臺和監控平臺,當然日誌平臺和監控平臺是可選的,可按需要進行配置。
配置中心定時非同步拉取數據,間隔時間預設為15秒,可以配置ConfigRefreshSeconds達到動態控制的目標,建議是15的整數倍。配置中心通過ETCD或者RDBMS和Redis達到配置“及時”更新的目的。
PowerDotNet創建的預設Power.Platform.RootApp是一個虛擬根應用,主要用於供其他新應用複製配置用,減少開發人員的配置工作量。
PowerDotNet開發的配置中心客戶端,對外暴露的類ConfigClientTool和KVConfigService,推薦ConfigClientTool類,但是如果需要取非當前應用的配置,可以使用KVConfigService類。
對於一些緩存數據,建議應用拼接緩存鍵的時候加上緩存版本CacheVersion,這樣可以集中控制數據變更。
通過DBKey服務獲取的資料庫連接串通常不會修改,所以建議緩存鍵不帶版本CacheVersion,且緩存時間長一點,系統預設緩存一天。
對於需要心跳檢查的應用,在配置中心配置心跳健康檢查相關參數時,建議將心跳間隔時間設置為緩存時間的五分之一或十分之一,系統數據正常緩存5分鐘,心跳間隔時間可以設置為1到2分鐘或30秒。
配置中心支持配置自動伺服器註冊參數,平臺部署的伺服器,如選擇docker容器,請降低docker銷毀頻率或者優先將docker設置固定ip地址,否則頻繁註冊伺服器容易導致服務不可達問題,畢竟心跳保活有時間間隔。
五、服務治理
1、對內網關
直接調用DBKey根服務和平臺基礎根服務,依賴日誌平臺、監控平臺和配置中心,不需要向註冊中心註冊伺服器和介面信息。日誌平臺和監控平臺是可選的,可按需要進行配置。
因為對內網關和註冊中心的緊密關係,對內網關又被稱為註冊中心網關。
2、對外網關
和對內網關類似,對外網關直接調用DBKey根服務和平臺基礎根服務,依賴日誌平臺、監控平臺和配置中心,不需要向註冊中心註冊伺服器和介面信息。日誌平臺和監控平臺是可選的,可按需要進行配置。
但是,對外網關對安全性要求極高,必須嚴格授權訪問的服務介面,添加安全審計日誌,而且通過對外網關調用的介面必須要進行簽名和token校驗,否則網關會直接報錯。
對內和對外網關主要業務邏輯差不多,對外網關多了些安全審計需求,通過配置中心的SecureGateway配置可以輕鬆切換對內或對外網關控制。
支付網關是一種特別典型的對外網關,大中型電商系統幾乎都會有完備的支付網關解決方案和實現,在移動互聯網時代,支付網關更加不可或缺。
3、網關調用
通常根據公司的業務需要,API服務網關可以拆分為線上(對外)網關和線下(對內)網關。
一個非常經典的示例,外部商戶系統和內部財務系統都需要調用支付服務,根據實際業務需要,可能外部商戶系統走公網通過線上網關調用支付介面,而內部財務系統則走內網通過線下網關調用支付介面。
線上網關可以根據業務規模,繼續進行拆分為PC網關、移動端網關、第三方應用網關等。如果業務數據量不大,終端調用也不複雜,可能一個線上網關就足夠應對業務需求。
如果業務邏輯複雜,調用量很大,終端類型很多,每種終端的業務邏輯差異也較大,線上網關可能就需要繼續拆分。
有些公司還需要為開放平臺或者合作商戶等開發專用的安全網關,網關選擇就更複雜更豐富了。
4、客戶端調用
除了通過網關進行API服務調用,也可以在配置中心配置客戶端形式的直接服務調用,支持主流的服務鑒權、負載均衡、黑白名單、限流、熔斷等功能。
上圖簡單展示了業務微服務通過客戶端方式調用基礎設施微服務,同理,業務微服務之間的調用或者基礎設施微服務之間互調也適用。
對於內網應用服務或者追求更高性能的應用服務,推薦使用客戶端形式的直接服務調用。
5、網關心跳
心跳檢查主要有推模式和拉模式兩種,PowerDotNet兩種心跳模式都支持,通過服務端BroadCast廣播進行健康檢查性能較差,註冊中心不採用此方案。
每一個接入註冊中心的應用API服務都會被自動賦予一個心跳檢查框架服務方法,這個心跳檢測根服務僅限內部調用。
應用伺服器會主動向註冊中心發送心跳包,實現心跳健康檢查功能,對於調用客戶端或網關而言,從註冊中心查詢到的心跳正常的應用伺服器部署列表被認為是正常可用的。
如果部署的應用伺服器返回心跳停止,網關會嘗試調用API伺服器的心跳介面,超時時間預設為2秒,如果沒有返回正常心跳結果,就認為服務真的下線,移除緩存中的部署信息。
如果網關將檢測下線的部署伺服器移除後,發現所有的部署信息都不存在了,重新讀取遠程部署伺服器信息,做兜底嘗試,這個過程都是非同步完成,整體性能沒有太大影響。
如果網關調用API伺服器心跳成功,則網關會調用平臺基礎心跳介面,代替某個具體的API服務發送一次心跳,這個邏輯主要是為了防止某些Web伺服器因為環境或心跳時間間隔不當導致的保活滯後。
6、註冊中心
註冊中心直接依賴對內網關、日誌平臺和監控平臺,間接調用DBKey根服務和平臺應用基礎根服務。
註冊中心基礎服務,通過對內網關進行應用伺服器、API介面的註冊、查詢和下線,支持Power.Apix、WebApi、WebService、WCF、Thrift、gRPC和.Net Remoting等形式的RPC介面。
註冊中心專門開發了客戶端,支持自動註冊實體類,實體類的集合類型建議使用具體類型,而不是介面,比如推薦使用List而不是IList。
註冊中心強烈建議介面開發過程中不要再使用Hashtable、ArrayList、DataTable和DataSet等類型,也不要使用指代不明的字典和dynamic類型,API介面類型越具體越好。
註冊中心客戶端目前支持集成Power.Apix、WebApi、WebService、WCF、Thrift、gRPC和.Net Remoting等形式的介面併進行統一網關調用或直接遠程調用,減少客戶端各種服務調用配置。
註意:註冊中心基礎服務不需要通過註冊中心客戶端自動註冊伺服器和API介面信息,因為這樣容易造成迴圈依賴,雖然註冊中心基礎服務也是介面。
在PowerDotNet和PowerDotNetCore中,開發API介面服務,可通過ApiCallClassAttribute和ApiCallMethodAttribute兩個特性,自動定位唯一服務方法。
但是介面中調用實際方法並不是通過ApiCallMethodAttribute來定位,而是根據註冊時反射的服務方法,註冊服務的時候有唯一別名和方法名,通常這兩個都是相同的。
註冊中心的服務治理支持白名單和黑名單功能,黑名單目前已經實現了IP、用戶、系統、APP黑名單功能,這些都需要元數據支持,服務治理平臺可以配置出萬能黑名單功能。
7、自我保護
心跳健康檢查的優點很明顯,通用且實現簡單,但在SOA和微服務架構下,服務間通常都是跨進程調用,網路通信往往會面臨著各種問題,比如微服務正常,但是網路分區發生故障,導致心跳檢查失敗。
預設情況下,如果註冊中心在60秒內沒有接收到某個服務實例的心跳,會自動註銷下線該服務實例。為什麼是60秒心跳失敗就自動下線呢?
因為PowerDotNet和PowerDotNetCore註冊中心的預設心跳間隔為15秒,心跳支持3次重試,加上網路延遲和重試等待時間,60秒是一個較為合適易記的數字。
在配置中心我們可以配置心跳健康檢查時間間隔(預設15秒),所以60秒只是預設情況,實際的時長應該是應用配置的心跳健康檢查間隔時間的4倍。
註冊中心除了通過應用心跳健康檢查實現服務可用性,也可以配置(配置分組SafeGuard)自我保護機制(參考了Eureka),防止因為網路分區故障心跳健康檢查誤判導致的服務不可用問題。
因為網路問題導致固定時間內大量服務實例被註銷下線,可能會嚴重威脅整個SOA或微服務架構的可用性,我們寧可將現有的服務節點都保留,也不能盲目註銷下線任何健康的服務,這就是所謂的兜底思維。
PowerDotNet註冊中心開發的自我保護機制主要邏輯如下:
(1)註冊中心在運行期間會去統計15分鐘(可配置)內應用服務心跳失敗比例,如果心跳失敗比例低於80%(可配置),註冊中心即會進入自我保護機制(可在配置中心配置開關控制);
(2)進入自我保護機制後,通常認為現在註冊列表中的應用服務節點都是穩定可靠的,哪怕是長時間沒收到心跳而應該過期的服務節點,也不會再去主動註銷移除並下線;
(3)註冊中心仍然能夠接受新服務的註冊和查詢請求,並通過ETCD嘗試同步數據,但不會強制要求這些新增的服務被全部同步(預設ETCD來同步)到其它節點上,保證當前節點依然可用;
(4)當網路穩定心跳健康檢查恢復以後,當前實例新的註冊信息會被全部同步到其它節點中,也就是達到註冊服務的最終一致性,這時候註冊中心自動關閉自我保護機制。
特別註意,如果在自我保護開啟後在保護期內剛好有某個服務提供者非正常下線,服務消費者就會有一個無效的服務實例,此時調用這個實例的服務就會失敗,服務消費者要有一些容錯機制,比如重試等。
目前PowerDotNet和PowerDotNetCore服務消費客戶端支持簡單重試(預設3次,可配置)和自動切換可用服務實例嘗試,如果所有服務實例都調用不通,客戶端拋出異常,自動非同步發出心跳檢查嘗試。
8、斷路器
在分散式系統中,重覆故障可能會導致雪球效應並使整個系統癱瘓。為了限制操作的持續時間,我們可以使用超時機制,因為超時可以防止掛起操作並保持系統響應。
但是,在微服務中合適的超時設置是不可能精確到每個介面方法的,根據個人開發經驗,系統里通常都是配置一個大概的全局超時時間或框架預設超時時間。
系統處於高度動態的環境下,一段時間內,某些介面調用多,某些介面調用少,網路帶寬占用也隨著介面調用而改變,超時時間不可能隨著環境和資源變化而動態改變。
有些公司會通過配置中心來自動適配超時時間,但是哪怕可以通過配置中心動態配置超時時間,開發和業務又不可能隨時隨地修改發佈合適的超時配置來適應環境變化。
為瞭解決靜態超時機制的不足,我們可以使用斷路器來處理錯誤,相對靈活動態應對環境變化。
斷路器(Circuit Breaker)以現實世界的電子元件命名,因為它們的作用是相同的。斷路器的主要工作原理是:
(1)、當特定類型的錯誤在短時間內多次發生時,斷路器會被打開;
(2)、開路的斷路器可以防止進一步的請求,就像我們平時所說的電路跳閘一樣;
(3)、斷路器通常在一定時間後關閉,在這期間可以為底層服務提供足夠的空間來恢復。
一些斷路器也具有半開狀態。在這種狀態下,服務發送第一個請求以檢查系統可用性,同時讓其他請求失敗。如第一個請求成功,它將使斷路器恢復到關閉狀態並使流量流動。否則,它保持打開。
總的來說,斷路器的核心功能主要就是三大塊:
(1)、調用數據度量統計,比如介面異常或者超時次數等
(2)、維護斷路器自身的狀態,包括Closed(關閉)、Open(打開)和Half Open(半開)三種狀態
(3)、基於前兩點保護包裹在斷路器中執行的調用
目前PowerDotNet和PowerDotNetCore實現的預設斷路器按照介面消費者介面調用異常和超時總次數,進行斷路器狀態的變更及快速失敗返回處理,個人認為這是最簡單的斷路器實現。
想給介面消費者應用添加調用介面斷路器功能,手動在配置中心點點,配置好三個參數發佈後就可以正常使用了,可任意控制斷路器開關啟停,極致的便利。
9、API風格
PowerDotNet和PowerDotNetCore的服務治理平臺早期支持RPC和REST兩種常見風格的API命名,隨著開發迭代積累,越來越發現REST相對RPC沒有任何優勢,多數情況下反而成為開發和管理的負擔。
信奉REST教條的老學究們在口頭理論上說的頭頭是道,開發者卻為想URL名、寫對接文檔以及返回code而苦不堪言,這些明明都是可以通過看RPC介面名和說明就能分分鐘搞定的事情。
PowerDotNet和PowerDotNetCore的服務治理平臺目前已經從REST邪路回歸到RPC正途,尤其是所有基礎設施服務做了微服務改造後,極大地降低了開發者心智負擔,顯著減少了API對接工作量。
RPC風格的API命名也很有講究和規律,最直接最推崇的命名方式是【公司.產品線.系統.子系統.服務類名.服務方法】或者【公司.系統.子系統.服務類名.服務方法】,看公司規模大小,按需選擇介面命名方式。
六、基礎設施
基礎設施即服務。PowerDotNet和PowerDotNetCore現有的基礎設施服務已完成微服務改造,在穩定性可靠性高可用性最大程度得到保障的前提下,部署運維方便程度也有了極大提升。
將PowerDotNet和PowerDotNetCore依賴的所有基礎設施服務抽象併進行統一管理,能夠最大限度的復用,降低開發運營成本,提升開發效率。
下麵列舉下PowerDotNet和PowerDotNetCore主要應用和服務的依賴關係和啟動順序。
1、啟動Power.DataX的Power.DataX.DBKeyApi服務
最穩定的介面服務,零依賴。
2、啟動Power.XLogger的Power.XLogger.WebApi服務
僅依賴Power.DataX的DBKey服務, 如日誌服務使用隊列,還需啟動隊列消費者Power.XLogger.MQConsumer。
3、啟動Power.XMonitor的Power.XMonitor.WebApi服務
依賴Power.DataX的DBKey服務和Power.XLogger,如監控使用隊列 ,還需啟動隊列消費者Power.XMonitor.MQConsumer。
4、啟動Power.Platform的Power.Platform.WebApi服務
依賴Power.DataX的DBKey服務、Power.XLogger和Power.XMonitor,這個應用包含了應用基礎服務和配置中心相關服務。
5、啟動Power.RegistryCenter的網關Power.SGS.Gateway服務
依賴Power.DataX的DBKey服務、Power.XLogger、Power.XMonitor和Power.Platform
6、啟動Power.RegistryCenter的Power.SGS.RegistryWebApi服務
依賴Power.SGS.Gateway、Power.DataX的DBKey服務、Power.XLogger、Power.XMonitor和Power.Platform
7、啟動其他框架服務
PowerDotNet和PowerDotNetCore開發的其他常用框架服務,比如消息隊列、緩存、數據同步、定時任務等等,這些應用就無所謂順序了。
以上可以認為是PowerDotNet和PowerDotNetCore的平臺基礎設施,搭建好環境並啟動服務以後可以按需開發很多種形式的應用。
強烈建議將PowerDotNet和PowerDotNetCore的平臺基礎設施服務以非Web宿主的形式部署運行起來,這樣便於後續編寫啟動腳本來控制啟動順序。
目前可以通過bat腳本啟動這些基礎設施服務,對於多機器多容器多集群部署,總體複雜度可控,不過隨著外部依賴和部署複雜度的增加,腳本複雜度必然也會隨之增加。
PowerDotNet基礎設施服務看上去有點多,但如果你折騰過Dubbo、Nacos(Apollo)、Envoy、Redis等自建微服務環境或直接使用SpringCloud全家桶,PowerDotNet實在是太易用太人性化了。
從基礎設施服務可以看出,目前PowerDotNet和PowerDotNetCore還是屬於輕量級侵入式的名字服務範疇,不支持目前大廠比較流行的非侵入性的服務網格(Service Mesh)。
註:服務網格(Service Mesh)是一個對於業務開發而言“非侵入性”的基礎設施層,通常採用邊車(SideCar)模式,用於處理服務間通信。典型代表包括Istio和Linkerd,還有後起之秀Dapr。
PowerDotNet和PowerDotNetCore核心功能已成熟穩定,且性能良好,能滿足絕大多數業務場景,對於服務網格,正如奧卡姆剃刀原理所說,如無必要,勿增實體,目前沒有進化到這個階段的迫切需求。
PowerDotNet和PowerDotNetCore基礎設施在通用性、可用性和易用性方面已經得到了充分驗證,遵循KISS原則,簡單即是美,反對恐龍設計,堅持自我,我就是我,是顏色不一樣的煙火,咩哈哈。
保證基礎設施的高可用是PowerDotNet開發的重中之重,目前主要技術選型都有完善的後臺管理和監控工具,也有兜底解決方案,比如添加備用節點排除單點,添加可啟停配置開關等,這些都是管理後臺點點按鈕的事情。
網路和IO是電腦上最典型的兩個瓶頸,尤其是網路,在互聯繫統中網路通常是最容易爆出問題的節點,同時也是各個大中小廠工程師們甩鍋的萬能藉口^_^。
PowerDotNet源於SOA架構,主要基礎設施原來是兩個單體服務,現在也按照微服務架構徹底拆分了,但是相比單體服務,拆分後出現事件的概率反而極低。
原因我猜可能是網路問題有了極大改善,因為千兆網卡對中小公司可以算是標配,現在中大型公司自建IDC多數都是萬兆網卡,土豪公司用RDMA網卡也不稀奇。
PowerDotNet和PowerDotNetCore雖然內部基礎設施服務較多,調用關係複雜,調用鏈路冗長,但是在服務治理平臺治理下,已經在實踐中證明能夠保證服務的穩定可靠。
基礎設施服務除了要求穩定可靠之外,還要求像普通業務邏輯型API服務一樣支持無感橫向擴容,服務治理平臺支持所有API服務的無感橫向擴容,對於分散式場景下的穩定性保障非常有意義。
七、框架工具
這部分偏重於框架的工具服務能極大提升開發者工作效率,減少重覆建設,比如定時任務調度平臺、數據同步平臺、緩存平臺、消息平臺、文件平臺等等。
框架工具建議技術選型優先選擇成熟穩定用戶眾多資料齊全的,不迷信大廠或所謂大牛的新作品,當然私下自己學習參考這些新作品毫無問題,但一定要謹慎在生產環境推廣使用,否則出現問題自己體會吧。
這些框架工具服務當前都是可選或者可擴展的,預設技術選型都是主流技術產品,預留出可擴展的介面定義,對於豐富PowerDotNet和PowerDotNetCore的技術選型大有裨益。
八、代碼生成
PowerDotNet和PowerDotNetCore的自動代碼生成工具主要包括基於DBKey和自研ORM一鍵前後端代碼生成、服務代理自動生成、配置文件生成和自動心跳集成工具等。
有了這些輔助代碼生成工具,對於日常開發工作而言,可以至少減少百分之八十的工作量,解放開發者的雙手,讓開發人員將更多時間和精力集中放在更有價值的事情上。
九、服務編排
我們開發的絕大多數業務邏輯型應用服務天生就會產生依賴關係(比如對保持高度穩定的基礎設施產生依賴),尤其是流行的SOA或者微服務架構,有時候調用鏈的複雜程度非常恐怖。
舉例來說,比如支付系統中的信用卡服務,在支付系統內部,信用卡服務依賴支付基礎、風控等服務,在公司內部可能還依賴個人用戶服務,在公司外部還依賴銀行、銀聯、清算中心等等。
為了編排服務的啟動順序,PowerDotNet參考了網上很多文章,比如Docker-compose、Docker Swarm、Helm、Kustomize、Apache Mesos和Google Kubernetes(K8S)等等解決方案。
經過權衡對比後,還是認為這些解決方案太重太複雜,單單一個重寫以支持容器部署就有不少的工作量,更不要說還需要人工寫很多易錯的啟動腳本,和PowerDotNet的初衷背道而馳。
服務編排是PowerDotNet和PowerDotNetCore需要解決的一大技術難題,我個人所服務過的公司沒有一家有完美的解決方案,也許K8S是個不錯的選擇,或者土豪一把直接使用雲服務。
所謂傻人有傻福,笨人有笨方法,對於調用關係複雜的應用部署,PowerDotNet提供了簡易自檢程式,可以在啟動服務前,在自檢小程式中輸入服務名稱檢測服務是否可達。
同時服務治理平臺Power.RegistryCenter提供了快速調用服務助手,可以通過切換應用伺服器地址進行心跳健康檢查來達到檢測服務是否可用的目的,對於一般應用也堪堪夠用。
十、應用開發
亂花漸欲迷人眼,CRUD特別繁。現在的應用程式越來越呈現出依賴項多,業務流程冗長,調用鏈複雜等技術特點,由此也產生了很多依賴複雜的開發套件和工具,也出現了Serverless等新的架構模式。
和很多流行的全家桶式開發套件有異曲同工之妙,通過PowerDotNet和PowerDotNetCore的基礎設施、框架工具和自動代碼生成工具,開發人員可以快速無障礙的流水線式開發業務邏輯型應用程式。
本文不直接比較流行的全家桶套件和PowerDotNet(PowerDotNetCore)的優缺點,看前面本系列的介紹你應該能感受到PowerDotNet和PowerDotNetCore的易用性。
下麵簡單演示下在PowerDotNet和PowerDotNetCore環境中如何快速開發接入一個新應用,讓你直觀理解到開發業務邏輯型應用程式是多麼快速而幸福的事情。
1、創建應用
系統應用平臺負責創建系統和應用。
新增應用歸屬哪個產品線哪個系統,需要和業務部門負責人溝通好,應用開發和負責人都是必填的,後續監控預警發送郵件等都需要這些人員信息。
應用密鑰是必須的,對於內網應用,調用非敏感介面通常可以放行,但是如果服務治理中心勾選了驗證簽名,應用密鑰是最重要的驗簽參數,所以需要應用開發者妥善保管。
如果應用密鑰因為安全需要必須進行變更,需要業務部門負責人審核才能修改,否則密鑰修改而應用端沒有及時更新造成大面積簽名失敗事件。
2、配置中心
系統應用平臺可直接初始化應用配置。
所有需要接入配置中心的新應用,都可以在系統應用平臺初始化應用配置,系統應用平臺提供快捷工具分組拷貝或者導入配置,非常方便。
如果是前端、客戶端、APP等不需要接入配置中心的應用,可跳過自動初始化應用配置這一步,當然某些特殊情況下也支持客戶端通過網關自動獲取配置中心配置。
初始化的配置中,除了通用配置參數,心跳,服務治理,DBKey、RPC、緩存、文件、日誌、監控等配置參數應有盡有,開發人員通常點點按鈕改幾個配置參數就好。
如果配置中心的配置直接複製於同系統下的相似應用,絕大多數情況下一個參數都不用改動,對於開發人員而言簡直摸魚偷懶神器。
特別提醒,日誌資料庫的DBKey約定都以LogDB_開頭,比如:LogDB_Writer_MySQL,LogDB_Writer_PostgreSQL,LogDB_Writer_MongoDB,LogDB_Writer_ElasticSearch。
對於不需要應用自己直接寫日誌資料庫記錄日誌的情況,可以在配置中心配置日誌服務地址,間接通過日誌平臺記錄日誌,這也是PowerDotNet推薦的做法。
3、應用示例
PowerDotNet有很多腳手架模板,包括WebForms、MVC、Winform、RF、Android、VUE、React、WebApi、WebService、Apix、WCF、.NET Remoting、Hessian、gRPC、Thrift等。
這些腳手架內置了接入PowerDotNet或PowerDotNetCore的預設配置,絕大多數應用只需要對預設配置稍作修改,開箱即用,大大降低了開發人員搭建環境的時間成本。
通過PowerDotNet和PowerDotNetCore,最多5分鐘就能創建一個自動集成網關、配置中心、註冊中心、緩存、日誌、監控等服務的新應用,想想用SpringCloud寫個HelloWorld搭建環境要折騰多久。
有了PowerDotNet和PowerDotNetCore基礎設施服務和框架工具的強有力的支撐,開發人員寫一個兩個應用,十個八個應用,幾十上百個應用甚至成千上萬個應用都不在話下。
(1)、後端應用
我們以一個典型的WebApi服務來舉例,新增一個應用,名稱叫Power.BaseData.WebApi,那麼這個應用的預設配置文件如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?xml version="1.0" encoding="utf-8" ?> <appSettings> <add key="SystemCode" value="BaseData" /> <add key="AppName" value="Power.BaseData.WebApi" /> <!--配置是否本地優先--> <add key="LocalFirst" value="0" /> <!--網關相關配置 支持多個 以;或,分隔開--> <add key="GatewayURL" value="網關1;網關2;網關3"/> <!--API相關配置--> <!--自動推送Api介面服務實體--> <add key="App.AutoPushClazz" value="true" /> <!--服務負載均衡類型 Random表示隨機 Polling表示輪詢--> <add key="App.LoadBalance" value ="Random"/> <!--服務介面是否為本地部署 調試選項用到 對應的是遠程伺服器部署--> <add key="App.UseLocal" value ="false"/> <!--應用入口URL 由協議、主機或功能變數名稱及埠號構成 80或443埠可以省略--> <add key="App.HostUrl" value="http://{ServerIP}:{Port}" /> <!--實際部署宿主應用類型 參考:WebApi、WebService、WCF、WindowsService、WinForm等--> <add key="App.DeployAppType" value="WebApi" /> <!--資料庫相關配置--> <add key="DBType" value="MySQL"/> <!--啟用的資料庫類型 目前支持SQLServer、MySQL和PostgreSQL--> <add key="BaseDataDB_Writer_MySQL" value="BaseDataDB_Writer_MySQL"/> <!--日誌資料庫類型 目前支持SQLServer、MySQL、PostgreSQL、MongoDB和ElasticSearch--> <add key="LogDB_Writer_MongoDB" value="LogDB_Writer_MongoDB"/> </appSettings>AppConfig
在系統應用平臺我們可以對IP、埠、功能變數名稱等進行申請和綁定操作。
上面的配置中,App.HostUrl可以通過占位符自動解析應用伺服器IP(當然也可以自己直接手動綁定IP或功能變數名稱),埠號則需要在系統應用平臺指定,防止應用程式埠衝突,埠分配必須規範有序。
在開發環境中,我們可以將是否為本地部署App.UseLocal配置為true,這樣服務治理平臺就知道這是一個調試伺服器,暫時不拉人集群給其他服務調用,對開發調試排除干擾非常有用。
一個後端服務,配置文件通常只有上面這麼多。其實示例中API相關配置(App.HostUrl必選)、資料庫相關配置都是可選的,這些都可以在配置中心處理。也就是說一個後端新應用,配置可精簡到只有5個。
如果某些應用的App.HostUrl就沒有,PowerDotNet自定義了一套規則,可以像下麵這樣配置:
<add key="App.HostUrl" value="none://{ServerIP}:noport" />
歸根結底,一個新應用,最多只需要SystemCode、AppName、LocalFirst、GatewayURL最後再加一個App.HostUrl這5個配置,不能再多了,這樣就能享受到PowerDotNet開發的便利,咩哈哈。
(2)、客戶端應用
在PowerDotNet和PowerDotNetCore中,所有非後端應用都必須通過服務治理平臺的網關間接調用介面完成交互,所有非後端應用都不能直接調用敏感介面,如DBKey、支付、財務、結算、人員信息等介面。
以一個WinForm程式舉例,應用名稱叫Power.BaseData.ApixTool,這是一個調用Apix介面的WinForm程式,它的預設配置可能是下麵這樣的:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?xml version="1.0" encoding="utf-8" ?> <appSettings> <add key="SystemCode" value="BaseData" /> <add key="AppName" value="Power.BaseData.ApixTool" /> <!--配置是否本地優先--> <add key="LocalFirst" value="0" /> <!--網關相關配置 支持多個 以;或,分隔開--> <add key="GatewayURL" value="網關1;網關2;網關3"/> <!--自動推送Api介面服務實體--> <add key="AppSecret" value="應用密鑰" /> </appSettings>AppConfig
客戶端程式預設配置只是把App.HostUrl換成AppSecret,AppSecret內容可以是明文也可以是密文,如果是內網客戶端,被調用的服務都沒有勾選驗證簽名和token,AppSecret配置也不是必須的。
(3)、前端應用
最典型的就是Angular、VUE、React、Svelte等SPA單頁應用,配置好網關、系統、應用名和應用密鑰,通過Axios模板方法調用網關就可以間接通過服務治理平臺和後端服務進行數據交互。
上面示例是React應用,對於後端介面,除了驗簽,可能還會有登錄token校驗邏輯,PowerDotNet和PowerDotNetCore都支持。
(4)、其他應用
其他應用包括安卓、RF、Pad、iOS等等形式的應用,和客戶端應用非常類似,配置好網關、系統、應用名和應用密鑰,就可以通過網關間接和後端服務進行數據交互,簡直神速。
4、服務治理
如果新增的應用是後臺服務介面,可通過配置中心自動註冊服務介面,也可以在服務治理平臺管理後臺人工註冊服務介面,預設註冊的新介面都會自動加入服務消費白名單。
新增應用如果需要調用並消費其他應用的API服務,分兩種情況進行處理:
(1)、網關間接調用介面,要看服務治理中心授權的服務是否勾選驗簽和驗證token,如果是外網網關,必須構造簽名和token驗證,否則介面消費驗證不通過。
(2)、客戶端直接調用介面,也要看服務治理中心授權的服務是否勾選驗簽和驗證token,當然如果是內網不敏感介面,直接調用即可。
5、集群管理
系統應用平臺可進行大規模集群管理。
所有後端應用,都可以在系統應用平臺將應用拉入某個數據中心的集群,便於集群管理,當然對於一些不需要集群管理的後臺管理系統,這不是必須的。
對於所有後端服務介面應用,註冊應用API介面後,必須在系統應用平臺將應用拉入某個數據中心的集群,進行集群管理,發佈時可通過拉入拉出集群控制伺服器是否可達。
系統應用進行集群化管理可以實現應用的優雅上線和下線功能,軟體可以控制的事情就不要讓硬體來做,PowerDotNet能完成的事情就不要讓其他軟體來做。
6、日誌管理
如果新增應用在配置中心接入了日誌平臺,登錄日誌平臺管理後臺,自動同步DBKey即可在日誌平臺查詢日誌。
7、監控管理
如果新增應用在配置中心接入了監控平臺,登錄監控平臺管理後臺,可以看到監控收集到的數據,尤其是對於後端應用,監控平臺能及時預警發現問題。
十一、數據處理
我們平常所開發的大部分業務邏輯型應用程式都是數據密集型(data-intensive)而非計算密集型(compute-intensive),也就是說系統的瓶頸通常都來自於對數據的處理而非CPU。
資料庫、消息隊列、緩存、文件等中間件或軟體工具都可以被統稱為數據系統,隨著技術的不斷發展,它們之間的界限也越來越模糊。
比如某些NoSQL數據存儲軟體可以被當成消息隊列用(參考Redis),而消息隊列則帶有類似資料庫的持久保證(比如RabbitMQ、RocketMQ和Kafka等)。
PowerDotNet和PowerDotNetCore平臺化軟體的設計與實現偏重於數據處理,對主流的技術選型都做了大量深度開發,簡化運維部署的複雜度,提高數據系統的高可用性。
同時業務功能模型選擇也有很多講究,比如支付和財務平臺系統的壓力非常大,所以系統互聯互通的時候,優先推薦拉模式,而不是支付和財務平臺主動推送模式,雖然支付財務主動推送是標配。
對於經典的發佈-訂閱模式,建議採用消息匯流排進行統一管理,PowerDotNet和PowerDotNetCore不建議接入應用方直接使用各種中間件的發佈訂閱功能,否則高併發下容易產生性能問題。
PowerDotNet和PowerDotNetCore已經開發出了典型的數據處理為主的公共服務平臺,如支付、財務、結算、CRM等系統,後續文章會講講支付平臺、財務平臺等系統的架構設計與開發。
作者:Jeff Wong
出處:http://jeffwongishandsome.cnblogs.com/
本文版權歸作者和博客園共有,歡迎圍觀轉載。轉載時請您務必在文章明顯位置給出原文鏈接,謝謝您的合作。