zoukankan      html  css  js  c++  java
  • 微服务框架

    【.NET CORE】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:gitsurging
    D:gitSurgingDemo

    最终保持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)
    复制代码
    1 public class UserRepository: BaseRepository, IBaseRepository
    2 {
    3 ///


    4 /// 创建一个用户
    5 ///

    6 /// 用户
    7 /// 链接字符串
    8 ///
    9 public Task 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(conn.Execute(insertSql, entity) > 0);
    51 }
    52 }
    53 }
    复制代码
    Bill.Demo.IModuleServices (和Surging项目一样,定义模块服务接口以及领域模型)
    Task GetUserById(Int64 id);

        Task<Boolean> UpdateUser(UserDto user);
    
        Task<Boolean> DeleteUser(Int64 userId);
    

    Bill.Demo.ModuleServices (和Surging项目一样,实现模块服务)
    如:

    复制代码
    1 public async Task 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 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 DeleteUser(Int64 userId)
    31 {
    32 return await _repository.Delete(userId);
    33 }
    复制代码
    Bill.Demo.Services.Server 服务
    Bill.Demo.Web 客户端
    复制代码
    public async Task Delete(Int64 id)
    {
    var service = ServiceLocator.GetService();
    var userProxy = service.CreateProxy("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

  • 相关阅读:
    自定义Response
    并发编程之进程
    并发编程知识储备
    正则表达式和re模块
    Scrapy框架
    http协议和Chrome抓包工具
    requests库
    Beautifulsoup
    xpath
    Mysql一些操作
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/8762584.html
Copyright © 2011-2022 走看看