前言
嘿,小夥伴們!最近看到了一個 .NET 8.0 的小項目偽微服務框架,非常適合想要快速搭建小型應用項目或是想要學習.NET 8.0及新的技術,但又不知道從哪裏學起的朋友。這個框架可以幫助我們簡化開發流程,同時還能適應不斷變化的需求。
它雖然簡化了很多複雜的微服務特性,但仍保留了關鍵的微服務理念,讓我們可以專注於業務邏輯而不是底層細節,並且達到實操效果。
想要快速上手 .NET 8.0,不妨試試這個框架。項目已經在 GitHub 上開源了,歡迎大家前來圍觀、提供建議或貢獻代碼。希望這個框架能夠幫助更好的幫助我們工作中遇到的問題。
項目介紹
為什麼説是偽微服務框架,常見微服務框架可能還包括服務容錯、服務間的通信、服務追蹤和監控、服務註冊和發現等等,而這裏為了在使用中的更簡單,將很多東西進行了簡化或者省略了。
簡化微服務概念:作者雖然稱為“偽微服務”,但本框架依然具備一些關鍵的微服務特性,如模塊化設計和服務解耦。它通過減少複雜的服務間通信、容錯機制和服務發現等功能,使開發更加高效且易於管理。
技術棧:集成了一些比較實用的新技術,包括EF Core、Redis、RabbitMQ和MySQL,確保應用高效又能應對高併發場景。
易用性:該框架的目標是儘可能地簡化開發過程,提供完整的接口和文檔,能夠迅速上手,並將更多精力集中在業務邏輯上。
持續優化:儘管目前仍處於早期階段,但作者承諾將持續改進和完善該項目。這包括但不限於引入更多高級特性、增強現有功能以及提升整體性能。
項目核心
對象映射:使用 AutoMapper 自動處理對象之間的映射,讓你無需手動編寫繁瑣的轉換代碼。
查詢封裝:通過 Ardalis.Specification 和 LinqKit.Core 封裝 EF Core 查詢,讓數據獲取變得更簡單直觀。
數據庫交互:在 EF Core 中重寫了 SaveChangesInterceptor,實現了軟刪除功能,並自動管理創建時間和更新時間字段。
整體架構:採用了整潔的架構設計,便於理解和維護。
業務功能:已經預置了一些基本的業務功能,開箱即用。
依賴注入:內置了依賴注入容器,方便管理組件和服務。
認證與授權:使用雙 token 實現了安全登錄和無感知的前端 token 刷新。
分佈式 ID 生成:集成了 Snowflake 分佈式 ID 生成器,確保全局唯一標識符。
緩存與鎖:通過 Redis 實現了分佈式緩存和分佈式鎖,提高了系統的可用性和併發性能。
消息隊列:利用 RabbitMQ 封裝了異步任務處理機制,如文件上傳和下載。
定時任務:結合 Cronos 和 BackgroundService 實現了秒級定時任務。
數據初始化:使用 BackgroundService 進行數據初始化,比如字典數據的加載。
日誌記錄:採用 Serilog 記錄異常日誌,並通過 Docker 部署實現日誌的可視化監控。
操作日誌:通過自定義過濾器和反射記錄操作日誌,便於追蹤用户行為。
權限驗證:實現了權限驗證過濾器,確保用户只能訪問被授權的資源。
統一響應格式:使用 IAsyncResultFilter 統一了返回給前端的數據格式。
Excel 操作:集成 EPPlus 庫,支持 Excel 導入和導出。
一鍵部署:支持使用 goploy 快速部署前後端應用。
API 文檔:通過 Swagger 自動生成 RESTful API 文檔,方便前端和後端開發人員協作。
配置加載:自動加載 appsettings.json 文件中的配置信息。
項目框架
通過Github下載項目源碼,我們可以查看項目框架,具體如下圖所示:
1、Libraries
包含各種外部類庫,對其深加工使用在項目中
2、Services/Basic
微服務基礎支撐子系統
3、Services/NCDP
微服務業務子系統
4、Services/SystemService
微服務系統服務(包括數據庫的更新、定時任務、數據初始化、Swagger承載、RabbitMQ隊列事件處理器等)
5、sun.Core
sun.Core作為了中轉,其他外部或者自己封裝的類庫,在引用的時候都是在sun.Core中進行的引用。
算是間接引用,來簡化項目中的依賴關係。
同時在sun.Core也封裝了一些核心組件和服務。
6、sun.Infrastructure
主要封裝一些通用的方法,以及基礎設施組件,供外部使用。
項目説明
關於項目詳細使用情況可以查看作者整理的文章鏈接 https://www.cnblogs.com/aehyok/p/18058032 ,希望能夠幫助大家更好的理解項目和學習知識點,提升自己的技術能力,下面只展示了部分內容。
1、業務功能
目前基本實現的功能包括:用户管理、角色管理、區域管理、查看日誌(登錄日誌和操作日誌)、菜單管理、權限控制、系統管理等功能。
2、生成文檔工具
Swagger 生成REST APIs文檔工具包含可以承載多個微服務項目,通過右上角進行切換,便可以查看當前微服務項目的接口文檔,並可以進行測試
測試接口直接可在swagger ui上進行
統一添加接口中的Header參數
通過對Swagger UI進行部分的自定義,使的更好的適配自己的項目,比如添加登錄,這樣接口便直接可以在swagger UI上面進行。
3、分佈式雪花Id生成器
Snowflake 所使用的開源類庫:https://github.com/stulzq/snowflake-net
/// <summary> /// 分佈式雪花Id生成器 /// </summary> public class SnowFlake { /// <summary> /// 通過靜態類只實例化一次IdWorker 否則生成的Id會有重複 /// </summary> private static readonly Lazy<IdWorker> _instance = new(() => { var commonOptions = App.Options<CommonOptions>(); return new IdWorker(commonOptions.WorkerId, commonOptions.DatacenterId); }); public static IdWorker Instance = _instance.Value; }
其中 WorkerId和DatacenterId保持不同的話,例如兩個微服務WorkerId一個為1一個為2,那麼在同一毫秒數生成的Id肯定是不同的。
同一個IdWorker在一個毫秒中可以生成4096個序列號 足夠大型系統使用了,不怕重複的問題。
4、分佈式緩存和分佈式鎖
Redis 統一封裝實現分佈式緩存和分佈式鎖,所使用的開源類庫:https://github.com/2881099/csredis
目前主要封裝了幾個常用的接口方法
public interface IRedisService { /// <summary> /// 查看服務是否運行 /// </summary> /// <returns></returns> bool PingAsync(); /// <summary> /// 根據key獲取緩存 /// </summary> /// <param name="key"></param> /// <returns></returns> Task<T> GetAsync<T>(string key); /// <summary> /// 設置指定key的緩存值(不過期) /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> Task<bool> SetAsync(string key, object value); /// <summary> /// 設置指定key的緩存值(可設置過期時間和Nx、Xx) /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expire"></param> /// <param name="exists"></param> /// <returns></returns> Task<bool> SetAsync(string key, object value, TimeSpan expire, RedisExistence? exists = null); /// <summary> /// 設置指定key的緩存值(可設置過期秒數和Nx、Xx) /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expireSeconds">過期時間單位為秒</param> /// <param name="exists"></param> /// <returns></returns> Task<bool> SetAsync(string key, object value, int expireSeconds = -1, RedisExistence? exists = null); /// <summary> /// 刪除Key /// </summary> /// <param name="key"></param> /// <returns></returns> Task<long> DeleteAsync(string key); Task<Dictionary<string,string>> ScanAsync(); }
主要是為了保持與redis cli中的方法一致,選了這個類庫,當然你也可以選擇其他的類庫 還是蠻多的。
同時還封裝了一個接口用於前端監測所有的key和value。
public async Task<dynamic> ScanAsync(PagedQueryModelBase model) { List<string> list = new List<string>(); //根沐model.Keyword進行模糊匹配 var scanResult = await RedisHelper.ScanAsync(model.Page, $"*{model.Keyword}*", model.Limit); list.AddRange(scanResult.Items); var values = await RedisHelper.MGetAsync(list.ToArray()); var resultDictionary = list.Zip(values, (key, value) => new { key, value }) .ToDictionary(item => item.key, item => item.value); dynamic result = new ExpandoObject(); result.Items = resultDictionary; result.Cursor = scanResult.Cursor; // 下一次要通過這個Cursor獲取下一頁的keys return result; }
5、自動化部署
通過google/zx使用nodejs開發了一個腳本,用於自動化部署
可以參考Github的地址:https://github.com/aehyok/zx-deploy
主要是用於開發環境,通過
pnpm sun-baisc pnpm sun-ncdp pnpm sun-systemserivce
當然你還可以通過組合命令進行部署,例如想一起部署三個服務
pnpm sun-all
其實就是
"pnpm sun-ncdp && pnpm sun-basic && pnpm sun-systemservice"
這裏我用的&&相當於上面三個命令串行執行,先執行sun-ncdp,再執行sun-basic,最後執行sun-systemservice。
如果你的電腦或者服務器性能足夠好,可以使用&符號,這樣就是並行執行,三個服務同時啓動,這樣可以節省時間。
以上僅展示了項目的部分內容,還有許多其他的技術應用和功能需要大家去發現。
然後我們可以下載源碼參考文檔並進行實際操作,以便全面瞭解整個項目的技術應用和特性。
項目地址
Github:https://github.com/aehyok/.NET8.0
最後