Surging微服务框架使用入门

来源: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

{

///

/// 创建一个用户

///

///

用户

///

链接字符串

///

public Task 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(conn.Execute(insertSql, entity) > 0);

}

}

}

Bill.Demo.IModuleServices

(和Surging项目一样,定义模块服务接口以及领域模型)

Task GetUserById(Int64 id);

Task UpdateUser(UserDto user);

Task DeleteUser(Int64 userId);

Bill.Demo.ModuleServices

(和Surging项目一样,实现模块服务)

如:

public async Task 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 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 DeleteUser(Int64 userId)

{

return await _repository.Delete(userId);

}

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 GetUser(Int64 id)

{

var service = ServiceLocator.GetService();

var userProxy = service.CreateProxy("User");

var output= await userProxy.GetUserById(id);

return new JsonResult(output);

}

public async Task Update(UserDto dto)

{

var service = ServiceLocator.GetService();

var userProxy = service.CreateProxy("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恤¥抢先预览(长按复制整段文案,打开手机淘宝即可进入活动内容)

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180410B0M8ZX00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券