前言git
本文非 Surging 官方教程,只是本身學習的總結。若有哪裏不對,還望指正。github
我對 surging 的見解web
我目前所在的公司採用架構就是相似與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性能做者有過測試),還體如今開發上,只要稍有基礎就能輕易駕馭,剩下就是整合業務進行開發了。sql
這是Surging做者的PC電腦全套運行測試的數據,能夠說是很是厲害了。相信在部署集羣的環境中,多實例,性能確定不存在問題。數據庫
歡迎補充...windows
服務註冊中心的選擇:目前 Surging 提供了 Zookeeper、Consul 做爲服務註冊中心,後期還可能會把 service-fabric 加入進來,中文官方地址:https://docs.microsoft.com/zh-cn/azure/service-fabric/api
Event Bus 的選擇:Surging 一樣提供了多種選擇,有 RabbitMQ,Kafka 等選擇。緩存
Redis安全
具體使用哪一種,就看本身的技術棧啦
運行下面腳本,生成user表
clone代碼 git clone https://github.com/billyang/SurgingDemo.git
nuget
引用,直接從 surging 項目引用,沒有拷貝一份放在本身的解決方案,D:\git\surging
D:\git\SurgingDemo
Surging
和SurgingDemo
在同一個目錄這樣作的好處:
Surging.ApiGateway 提供了服務管理以及網關統一訪問入口。 目前開發還不完善,若是如今要用於正式開發建議本身要部分重寫 ApiGateway,加入權限驗證。相信等到1.0版本做者也會把數據監控、流量控制、數據安全、分流控制、身份認證等管理功能加入,固然這些功能並不會影響正常使用。
服務管理使用 consul,由於調試簡單,只需 consul agent -dev 便可開啓consul
假設你已經把SurgingDemo已運行起來了,便可對根據Dapper對User進行增刪改查
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 }
Task<UserDto> GetUserById(Int64 id); Task<Boolean> UpdateUser(UserDto user); Task<Boolean> DeleteUser(Int64 userId);
如:
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 }
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: