前言
本文非 Surging 官方教程,只是自己學習的總結。如有哪里不對,還望指正。
我對 surging 的看法
我目前所在的公司采用架構就是類似與Surging的RPC框架,在.NET 4.0框架上搭建Socket RPC,通過分組輪詢的方式調度RPC,經歷過3次雙十一的考驗,實際最高時有800多人同時作業,同時並發達到600人/連接rpc ,24小時不間斷作業,這是實際數據,理論上更高,只需要加RPC就可以了,剩下的就看數據庫以及緩存的性能了,說到數據庫,這又是另外一個技術棧了。雖然這個數據並不能說明RPC有多高效,但確是實實在在的現場數據。
surging的出現給了我眼前一亮的感覺。surging 是一個分布式微服務框架,提供高性能RPC遠程服務調用,采用Zookeeper、Consul作為surging服務的注冊中心,集成了哈希,隨機,輪詢、壓力最小優先作為負載均衡的算法,RPC集成采用的是netty框架,采用異步傳輸。內部RPC,外部網關。原來這就是微服務框架,數據監控、流量控制、分流控制、重試、熔斷........。居然還能這樣做,盡管部分術語你可能很早很早就聽過了,但卻沒有形成一個框架,或者使用起來很困難。surging 恰恰就是這樣一個集大成者的框架,所有這些surging幫你做了,而且非常非常高效。這個高效不僅僅體現在surging的性能上(surging性能作者有過測試),還體現在開發上,只要稍有基礎就能輕易駕馭,剩下就是整合業務進行開發了。
這是Surging作者的PC電腦全套運行測試的數據,可以說是非常厲害了。相信在部署集群的環境中,多實例,性能肯定不存在問題。
Surging 分布式微服務框架適合做什么
- 企業級互聯網架構平台;
- 傳統大型項目,伸縮性很強的項目,可應對突發的流量暴增(比如雙十一訂單暴增);
- 移動互聯網項目,比如為了因對突發的因營銷等帶來的流量暴增,評論暴增等等情況;
歡迎補充...
一、准備
服務注冊中心的選擇:目前 Surging 提供了 Zookeeper、Consul 作為服務注冊中心,后期還可能會把 service-fabric 加入進來,中文官方地址:https://docs.microsoft.com/zh-cn/azure/service-fabric/
Event Bus 的選擇:Surging 同樣提供了多種選擇,有 RabbitMQ,Kafka 等選擇。
Redis
具體使用哪種,就看自己的技術棧啦
二、示例開發
1.在sqlserver中建立Test 數據庫
運行下面腳本,生成user表
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才是踏出第一步
Surging.ApiGateway 提供了服務管理以及網關統一訪問入口。 目前開發還不完善,如果現在要用於正式開發建議自己要部分重寫 ApiGateway,加入權限驗證。相信等到1.0版本作者也會把數據監控、流量控制、數據安全、分流控制、身份認證等管理功能加入,當然這些功能並不會影響正常使用。
服務管理使用 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)

1 public class UserRepository: BaseRepository, IBaseRepository<User> 2 { 3 /// <summary> 4 /// 創建一個用戶 5 /// </summary> 6 /// <param name="entity">用戶</param> 7 /// <param name="connectionString">鏈接字符串</param> 8 /// <returns></returns> 9 public Task<Boolean> CreateEntity(User entity, String connectionString = null) 10 { 11 using (IDbConnection conn = DataBaseConfig.GetSqlConnection(connectionString)) 12 { 13 string insertSql = @"INSERT INTO dbo.auth_User 14 ( TenantId , 15 Name , 16 Password , 17 SecurityStamp , 18 FullName , 19 Surname , 20 PhoneNumber , 21 IsPhoneNumberConfirmed , 22 EmailAddress , 23 IsEmailConfirmed , 24 EmailConfirmationCode , 25 IsActive , 26 PasswordResetCode , 27 LastLoginTime , 28 IsLockoutEnabled , 29 AccessFailedCount , 30 LockoutEndDateUtc 31 ) 32 VALUES ( @tenantid , 33 @name , 34 @password , 35 @securitystamp , 36 @fullname , 37 @surname , 38 @phonenumber , 39 @isphonenumberconfirmed , 40 @emailaddress , 41 @isemailconfirmed , 42 @emailconfirmationcode , 43 @isactive , 44 @passwordresetcode , 45 @lastlogintime , 46 @islockoutenabled , 47 @accessfailedcount , 48 @lockoutenddateutc 49 );"; 50 return Task.FromResult<Boolean>(conn.Execute(insertSql, entity) > 0); 51 } 52 } 53 }
Bill.Demo.IModuleServices (和Surging項目一樣,定義模塊服務接口以及領域模型)
Task<UserDto> GetUserById(Int64 id); Task<Boolean> UpdateUser(UserDto user); Task<Boolean> DeleteUser(Int64 userId);
Bill.Demo.ModuleServices (和Surging項目一樣,實現模塊服務)
如:
1 public async Task<UserDto> GetUserById(Int64 id) 2 { 3 var user = await _repository.GetEntityById(id); 4 return new UserDto() 5 { 6 Id = user.Id, 7 EmailAddress = user.EmailAddress, 8 Name = user.Name, 9 PhoneNumber = user.PhoneNumber, 10 Surname = user.Surname, 11 TenantId = user.TenantId, 12 FullName = user.FullName, 13 }; 14 } 15 16 public async Task<Boolean> UpdateUser(UserDto user) 17 { 18 var entity = await _repository.GetEntityById(user.Id); 19 entity.Name = user.Name; 20 entity.Password = user.Password; 21 entity.FullName = user.FullName; 22 entity.Surname = user.Surname; 23 entity.EmailAddress = user.EmailAddress; 24 entity.PhoneNumber = user.PhoneNumber; 25 26 return await _repository.Update(entity); 27 28 } 29 30 public async Task<Boolean> DeleteUser(Int64 userId) 31 { 32 return await _repository.Delete(userId); 33 }
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); }
碼托管在github,https://github.com/billyang/SurgingDemo
Surging: