查看原文
其他

【.NET Core】 Surging微服务框架使用入门

DotNet 2019-07-31

(点击上方蓝字,可快速关注我们)


来源:bill.yang 

cnblogs.com/billyang/p/8376076.html


前言


本文非 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(https://github.com/billyang/SurgingDemo/blob/master/src/sql/surgingdemo.sql)


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);

}


码托管在github:https://github.com/billyang/SurgingDemo


Surging:


博客:http://www.cnblogs.com/fanliang11/


开源:https://github.com/dotnetcore/surging


看完本文有收获?请转发分享给更多人

关注「DotNet」,提升.Net技能 

淘口令复制以下红色内容,再打开手淘即可购买

范品社,使用¥极客T恤¥抢先预览(长按复制整段文案,打开手机淘宝即可进入活动内容)

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存