Surging 微服務框架使用入門
前言
本文非 Surging 官方教程,只是自己學習的總結。如有哪裏不對,還望指正。?
我對 surging 的看法
我目前所在的公司采用架構就是類似與Surging的RPC框架,在.NET 4.0框架上搭建Socket RPC,通過分組輪詢的方式調度RPC,經歷過3次雙十一的考驗,實際最高時有800多人同時作業,同時並發達到600人/連接rpc?,24小時不間斷作業,這是實際數據,理論上更高,只需要加RPC就可以了,剩下的就看數據庫以及緩存的性能了,說到數據庫,這又是另外一個技術棧了。雖然這個數據並不能說明RPC有多高效,但確是實實在在的現場數據。
surging的出現給了我眼前一亮的感覺,內部RPC,外部網關。原來這就是微服務框架,數據監控、流量控制、分流控制、重試、熔斷........。居然還能這樣做,盡管部分術語你可能很早很早就聽過了,但卻沒有形成一個框架,或者使用起來很困難。surging 恰恰就是這樣一個集大成者的框架,所有這些surging幫你做了,而且非常非常高效。這個高效不僅僅體現在surging的性能上(surging性能作者有過測試),還體現在開發上,只要稍有基礎就能輕易駕馭,剩下就是整合業務進行開發了。
一、準備
服務註冊中心的選擇:目前 Surging 提供了 Zookeeper、Consul 作為服務註冊中心,後期還可能會把?service-fabric?加入進來,中文官方地址:https://docs.microsoft.com/zh-cn/azure/service-fabric/
Event Bus 的選擇:Surging 同樣提供了多種選擇,有 RabbitMQ,Kafka 等選擇。
具體使用哪種,就看自己的技術棧啦
?二、示例開發
1.在sqlserver中建立Test 數據庫
運行下面腳本,生成user表
test.db
2.運行Surging Demo
clone代碼?git clone https://github.com/billyang/SurgingDemo.git
因為本示例項目沒有從nuget
?引用,直接從 surging 項目引用,沒有拷貝一份放在自己的解決方案,
假設目錄結構如下:
D:\git\surging
D:\git\SurgingDemo
最終保持Surging
和SurgingDemo
在同一個目錄
這樣做的好處:
是和 surging 保持最新代碼
是方便學習surging和調試,畢竟你想使用surging、理解surging才是踏出第一步
?
ApiGateway 使用 surging 的例子,當然正式開發建議自己重寫 ApiGateway
服務管理使用 consul,因為調試簡單,只需 consul agent -dev 即可開啟consul
在 windows 中啟動:
發布網關 1. ApiGateway ? ? ? ? ? ? ? ?dotnet run Surging.ApiGateway
啟用服務 2. Server ? ? ? ? ? ? ?dotnet Bill.Demo.Services.Server.dll
發布客戶端(本示例使用 web mvc) 3. Bill.Demo.Web ? ? ? ? ? ? ? dotnet run Bill.Demo.Web
假設你已經把SurgingDemo已運行起來了,即可對根據Dapper對User進行增刪改查?
?
三、介紹一下本示例各項目的職責
Bill.Demo.Core 用戶定義數據模型
Bill.Demo.DapperCore (Dapper倉儲,其中倉儲需繼承 UserRepository: Surging.Core.CPlatform.Ioc.BaseRepository)
public class UserRepository: BaseRepository, IBaseRepository<User>
? ? {
? ? ? ? /// <summary>
? ? ? ? /// 創建一個用戶
? ? ? ? /// </summary>
? ? ? ? /// <param name="entity">用戶</param>
? ? ? ? /// <param name="connectionString">鏈接字符串</param>
? ? ? ? /// <returns></returns>
? ? ? ? public Task<Boolean> CreateEntity(User entity, String connectionString = null)
? ? ? ? {
? ? ? ? ? ? using (IDbConnection conn = DataBaseConfig.GetSqlConnection(connectionString))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? string insertSql = @"INSERT? INTO dbo.auth_User
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ( TenantId ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Name ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Password ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SecurityStamp ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? FullName ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Surname ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PhoneNumber ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IsPhoneNumberConfirmed ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? EmailAddress ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IsEmailConfirmed ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? EmailConfirmationCode ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IsActive ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PasswordResetCode ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LastLoginTime ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IsLockoutEnabled ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? AccessFailedCount ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LockoutEndDateUtc
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )
? ? ? ? ? ? ? ? ? ? ? ? ? ? VALUES? ( @tenantid ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @name ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @password ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @securitystamp ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @fullname ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @surname ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @phonenumber ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @isphonenumberconfirmed ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @emailaddress ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @isemailconfirmed ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @emailconfirmationcode ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @isactive ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @passwordresetcode ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @lastlogintime ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @islockoutenabled ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @accessfailedcount ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @lockoutenddateutc
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? );";
? ? ? ? ? ? ? ? return Task.FromResult<Boolean>(conn.Execute(insertSql, entity) > 0);
? ? ? ? ? ? }
? ? ? ? }
? ?}
Bill.Demo.IModuleServices (和Surging項目一樣,定義模塊服務接口以及領域模型)
Task<UserDto> GetUserById(Int64 id); ? ? ? ? ? ? ? ?Task<Boolean> UpdateUser(UserDto user); ? ? ? ?Task<Boolean> DeleteUser(Int64 userId);
Bill.Demo.ModuleServices (和Surging項目一樣,實現模塊服務)
如:
public async Task<UserDto> GetUserById(Int64 id)
? ? ? ? {
? ? ? ? ? ? var user = await _repository.GetEntityById(id);
? ? ? ? ? ? return new UserDto()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Id = user.Id,
? ? ? ? ? ? ? ? EmailAddress = user.EmailAddress,
? ? ? ? ? ? ? ? Name = user.Name,
? ? ? ? ? ? ? ? PhoneNumber = user.PhoneNumber,
? ? ? ? ? ? ? ? Surname = user.Surname,
? ? ? ? ? ? ? ? TenantId = user.TenantId,
? ? ? ? ? ? ? ? FullName = user.FullName,
? ? ? ? ? ? };
? ? ? ? }
? ? ? ? public async Task<Boolean> UpdateUser(UserDto user)
? ? ? ? {
? ? ? ? ? ? var entity = await _repository.GetEntityById(user.Id);
? ? ? ? ? ? entity.Name = user.Name;
? ? ? ? ? ? entity.Password = user.Password;
? ? ? ? ? ? entity.FullName = user.FullName;
? ? ? ? ? ? entity.Surname = user.Surname;
? ? ? ? ? ? entity.EmailAddress = user.EmailAddress;
? ? ? ? ? ? entity.PhoneNumber = user.PhoneNumber;
? ? ? ? ? ? return await _repository.Update(entity);
? ? ? ? }
? ? ? ? public async Task<Boolean> DeleteUser(Int64 userId)
? ? ? ? {
? ? ? ? ? ? return await _repository.Delete(userId);
? ? ? ? }
Bill.Demo.Services.Server 服務
Bill.Demo.Web 客戶端
? ? ? ? public async Task<IActionResult> Delete(Int64 id)
? ? ? ? {
? ? ? ? ? ? var service = ServiceLocator.GetService<IServiceProxyFactory>();
? ? ? ? ? ? var userProxy = service.CreateProxy<IUserService>("User");
? ? ? ? ? ? await userProxy.DeleteUser(id);
? ? ? ? ? ? return RedirectToAction("User");
? ? ? ? }
? ? ? ? public async Task<JsonResult> GetUser(Int64 id)
? ? ? ? {
? ? ? ? ? ? var service = ServiceLocator.GetService<IServiceProxyFactory>();
? ? ? ? ? ? var userProxy = service.CreateProxy<IUserService>("User");
? ? ? ? ? ? var output= await userProxy.GetUserById(id);
? ? ? ? ? ? return new JsonResult(output);
? ? ? ? }
? ? ? ? public async Task<JsonResult> Update(UserDto dto)
? ? ? ? {
? ? ? ? ? ? var service = ServiceLocator.GetService<IServiceProxyFactory>();
? ? ? ? ? ? var userProxy = service.CreateProxy<IUserService>("User");
? ? ? ? ? ? var output = await userProxy.UpdateUser(dto);
? ? ? ? ? ? return new JsonResult(output);
? ? ? ? }
原文地址: https://www.cnblogs.com/billyang/p/8376076.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
Surging 微服務框架使用入門