实用接地气的 .NET 微服务框架
前言
微服务架构已经成为搭建高效、可扩展系统的关键技术之一,然而,现有许多微服务框架往往过于复杂,使得我们普通开发者难以快速上手并体验到微服务带了的便利。为了解决这一问题,于是作者精心打造了一款最接地气的 .NET 微服务框架,帮助我们轻松构建和管理微服务应用。
本框架不仅支持 Consul 服务注册与发现,还自带了一系列高级特性,包括配置中心、链路跟踪(APM)、服务网关等,极大地简化了微服务的开发和运维过程。
此外框架还实现了 Saga 分布式事务、RabbitMQ 事件总线等功能,确保系统能够高效处理复杂的业务逻辑。更重要的是提供了一个人性化的 Dashboard 管理面板,使得监控和管理微服务集群变得方便。
通过本文的介绍大家可以学习到如何快速上手并充分利用这些特性,从而构建出既高效又稳定的微服务应用。
项目介绍
Wing 致力于打造一个功能强大且易于使用的 .NET 微服务框架,支持 .NET 6+ 运行平台。
该框架具备以下特点:
1、服务注册与发现:支持 Consul 服务注册与发现机制,确保服务间的自动发现和动态管理。
2、服务间通讯:支持 HTTP 和 gRPC 两种调用方式,内置负载均衡器,实现高效的服务间通信。
3、服务策略与异常处理:提供服务策略配置,支持服务异常降级处理,确保系统的稳定性和可靠性。
4、Saga 分布式事务:支持三种恢复策略(向前恢复、向后恢复、先前再后),确保事务的一致性和完整性。
5、配置中心:内置配置中心,实现服务配置的在线集中统一管理。
6、链路追踪与性能监控:支持 HTTP/gRPC/SQL 的链路追踪(APM)及耗时分析统计,帮助开发者快速定位性能瓶颈。
7、服务网关:内置服务网关,支持全局服务策略和个性化服务策略配置,简化服务入口管理。
8、事件总线:支持 RabbitMQ 事件总线,实现服务间的异步通信和事件传递。
9、管理界面:提供人性化的 Dashboard 管理界面,便于监控和管理整个微服务集群。
Wing 框架为开发者提供一个强大而直观的开发平台,帮助快速构建和管理高效、可扩展的微服务应用。
快速入门
1、服务注册
什么是服务注册?
服务注册是指服务启动后将该服务的IP、端口等信息注册到Consul
。
创建一个Web API 项目
提前准备:安装并启动Consul
打开 Visual Studio 2022 并创建Web API项目
安装依赖包
dotnet add package Wing.Consul
Program代码
builder.Services.AddWing();
添加配置
{
// 是否启用配置中心,默认启用
"ConfigCenterEnabled": false,
"Consul": {
"Url": "http://localhost:8500",
"Service": {
//Http Grpc
"Option": "Http",
"HealthCheck": {
"Url": "http://localhost:1210/health",
//单位:秒
"Timeout": 10,
//单位:秒
"Interval": 10
},
"Name": "Wing.Demo_1.2.1",
"Host": "localhost",
"Port": 1210,
"Tag": "",
"LoadBalancer": {
//RoundRobin WeightRoundRobin LeastConnection
"Option": "WeightRoundRobin",
//权重
"Weight": 60
},
"Scheme": "http",
"Developer": "linguicheng"
},
//定时同步数据时间间隔,单位:秒 小于等于0表示立即响应
"Interval": 10,
//数据中心
"DataCenter": "dc1",
//等待时间,单位:分钟
"WaitTime": 3
}
}
查看运行效果
程序运行后,打开consul UI管理界面,可以看到注册服务Wing.Demo_1.2
,具体如下图所示:
2、启动UI
Wing.UI
是Wing
微服务框架中的一个可视化操作管理系统,主要功能有服务治理、配置中心、APM管理、Saga分布式事务查询。
安装依赖包
安装服务注册nuget包Wing.Consul
,UI可视化界面管理nuget包Wing.UI
,选择对应的数据库驱动(参考FreeSql官网),以SqlServer为例,安装FreeSql.Provider.SqlServer
。
dotnet add package Wing.UI
dotnet add package FreeSql.Provider.SqlServer
Program代码
using Wing;
var builder = WebApplication.CreateBuilder(args);
builder.Host.AddWing(builder => builder.AddConsul());
builder.Services.AddWing().AddWingUI(FreeSql.DataType.SqlServer);
查看运行效果
程序运行后,浏览器访问 ,运行效果如下图:
可以看到示例 1.2 注入的服务`Wing.Demo_1.2
3、服务发现与调用
什么是服务发现?
服务发现是指服务启动后将服务注册信息定时同步刷新到本地或实时获取Consul
的服务信息。
安装依赖包
dotnet add package Wing.Consul
Grpc健康检查
protobuf文件
syntax = "proto3";
package grpc.health.v1;
message HealthCheckRequest {
string service = 1;
}
message HealthCheckResponse {
enum ServingStatus {
UNKNOWN = 0;
SERVING = 1;
NOT_SERVING = 2;
}
ServingStatus status = 1;
}
service Health {
rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);
}
HealthCheck代码
public class HealthCheck : Health.HealthBase
{
public override Task<HealthCheckResponse> Check(HealthCheckRequest request, ServerCallContext context)
{
return Task.FromResult(new HealthCheckResponse() { Status = HealthCheckResponse.Types.ServingStatus.Serving });
}
public override async Task Watch(HealthCheckRequest request, IServerStreamWriter<HealthCheckResponse> responseStream, ServerCallContext context)
{
await responseStream.WriteAsync(new HealthCheckResponse()
{ Status = HealthCheckResponse.Types.ServingStatus.Serving });
}
}
Program代码
using Wing;
var builder = WebApplication.CreateBuilder(args);
builder.Host.AddWing(builder => builder.AddConsul());
// Add services to the container.
builder.Services.AddGrpc();
builder.Services.AddWing();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
app.Run();
运行效果
运行当前程序并启动示例 1.3,浏览器访问 ,可以看到注入的Grpc服务Wing.Demo_1.4
,运行效果如下图:
在示例 1.2 中调用当前Grpc服务中SayHello
方法,代码如下:
[HttpGet("hello")]
public Task<string> SayHello()
{
return _serviceFactory.InvokeAsync("Wing.Demo_1.4", async serviceAddr =>
{
var channel = GrpcChannel.ForAddress(serviceAddr.ToString());
var greeterClient = new Greeter.GreeterClient(channel);
var result = await greeterClient.SayHelloAsync(new HelloRequest { Name = "Wing" });
return result.Message;
});
}
运行示例 1.2,浏览器访问 http://localhost:1210/weatherforecast/hello ,运行效果如下图:
4、启动服务网关
服务网关是系统对外的唯一入口,它封装了系统内部架构,为每个客户端提供了定制的API,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有非业务功能。
安装依赖包
安装服务注册nuget包Wing.Consul
,服务网关nuget包Wing.Gateway
,选择对应的数据库驱动(参考FreeSql官网open in new window),以SqlServer为例,安装FreeSql.Provider.SqlServer
,请求日志支持本地消息队列和分布式消息队列进行异步持久化,基本上不影响网关性能。如果不想记录请求日志,可以不安装该包。
如果想启用EventBus
记录请求日志,需要安装RabbitMQ nuget包Wing.RabbitMQ
。
dotnet add package Wing.Consul
dotnet add package Wing.Gateway
dotnet add package Wing.RabbitMQ
dotnet add package FreeSql.Provider.SqlServer
Program代码
using Wing;
var builder = WebApplication.CreateBuilder(args);
builder.Host.AddWing(builder => builder.AddConsul());
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddWing()
.AddPersistence(FreeSql.DataType.SqlServer)
.AddGateWay()
.AddEventBus();// 如果不想使用EventBus记录请求日志,可以删除此行代码
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
添加配置
{
// 是否启用配置中心,默认启用
"ConfigCenterEnabled": false,
"Consul": {
"Url": "http://localhost:8500",
"Service": {
//Http Grpc
"Option": "Http",
"HealthCheck": {
"Url": "http://localhost:1510/health",
//单位:秒
"Timeout": 10,
//单位:秒
"Interval": 10
},
"Name": "Wing.Demo_1.5",
"Host": "localhost",
"Port": 1510,
"LoadBalancer": {
//RoundRobin WeightRoundRobin LeastConnection
"Option": "WeightRoundRobin",
//权重
"Weight": 50
},
"Scheme": "http",
"Developer": "linguicheng"
},
//定时同步数据时间间隔,单位:秒 小于等于0表示立即响应
"Interval": 10,
//数据中心
"DataCenter": "dc1",
//等待时间,单位:分钟
"WaitTime": 3
},
"ConnectionStrings": {
"Wing": "Data Source=192.168.56.96;User Id=sa;Password=wing123.;Initial Catalog=Wing;TrustServerCertificate=true;Pooling=true;Min Pool Size=1"
},
//自动同步实体结构到数据库
"UseAutoSyncStructure": true,
// 如果不启用EventBus,可以删除RabbitMQ配置
"RabbitMQ": {
"HostName": "192.168.56.99",
"UserName": "admin",
"Password": "admin",
"VirtualHost": "/",
"Port": 5672,
//消息过期时间,单位:毫秒,过期会自动路由到死信队列,小于或等于0则永久有效
"MessageTTL": 0,
"ExchangeName": "Sample.GateWay",
//每次投递消息数量
"PrefetchCount": 1
},
"Gateway": {
// 请求日志
"Log": {
// 是否启用网关日志记录
"IsEnabled": true,
// 是否启用事件总线(RabbitMQ)存储日志,生产环境推荐启用,可以提升程序的性能
"UseEventBus": false
}
}
}
查看运行效果
运行示例 1.2 并启动当前示例程序,浏览器访问,运行效果如下图:
运行示例 1.3,浏览器访问,可以看到网关请求日志,运行效果如下图:
服务地址组成
请求服务地址默认是{网关IP或域名}/{服务名}/{服务路由},例如:http://localhost:1510/Wing.Demo_1.2/weatherforecast
注意:更多具体内容可以访问Wing 官方文档,具体内容如下所示
项目地址
Github:https://linguicheng.github.io/Wing
Gitee:https://gitee.com/linguicheng/Wing
文档地址:https://linguicheng.github.io/Wing
示例地址:https://gitee.com/linguicheng/wing-demo
开源协议:基于MIT协议永久开源免费使用
最后
如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。
也可以加入微信公众号[DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!
实用接地气的 .NET 微服务框架的更多相关文章
- Java微服务框架一览
引言:本文首先简单介绍了微服务的概念以及使用微服务所能带来的优势,然后结合实例介绍了几个常见的Java微服务框架. 微服务在开发领域的应用越来越广泛,因为开发人员致力于创建更大.更复杂的应用程序,而这 ...
- 基于thrift的微服务框架
前一阵开源过一个基于spring-boot的rest微服务框架,今天再来一篇基于thrift的微服务加框,thrift是啥就不多了,大家自行百度或参考我之前介绍thrift的文章, thrift不仅支 ...
- 基于spring-boot的rest微服务框架
周末在家研究spring-boot,参考github上的一些开源项目,整了一个rest微服务框架,取之于民,用之于民,在github上开源了,地址如下: https://github.com/yjmy ...
- [goa]golang微服务框架学习--安装使用
当项目逐渐变大之后,服务增多,开发人员增加,单纯的使用go来写服务会遇到风格不统一,开发效率上的问题. 之前研究go的微服务架构go-kit最让人头疼的就是定义服务之后,还要写很多重复的框架代码, ...
- 【GoLang】go 微服务框架 && Web框架学习资料
参考资料: 通过beego快速创建一个Restful风格API项目及API文档自动化: http://www.cnblogs.com/huligong1234/p/4707282.html Go 语 ...
- 【GoLang】golang 微服务框架 go-kit
golang-Microservice Go kit - A toolkit for microservices kubernetes go-kit_百度搜索 Peter Bourgon谈使用Go和& ...
- Java微服务框架
Java的微服务框架dobbo.spring boot.redkale.spring cloud 消息中间件RabbitMQ.Kafka.RocketMQ
- 基于.NET CORE微服务框架 -surging的介绍和简单示例 (开源)
一.前言 至今为止编程开发已经11个年头,从 VB6.0,ASP时代到ASP.NET再到MVC, 从中见证了.NET技术发展,从无畏无知的懵懂少年,到现在的中年大叔,从中的酸甜苦辣也只有本人自知.随着 ...
- 基于.NET CORE微服务框架 -谈谈surging API网关
1.前言 对于最近surging更新的API 网关大家也有所关注,也收到了不少反馈提出是否能介绍下Api网关,那么我们将在此篇文章中剥析下surging的Api 网关 开源地址:https://git ...
- 基于.NET CORE微服务框架 -浅析如何使用surging
1.前言 surging受到大家这么强烈的关注,我感到非常意外,比如有同僚在公司的分享会上分享surging, 还有在博客拿其它的RPC框架,微服务做对比等等,这些举动都让我感觉压力很大,毕竟作为个人 ...
随机推荐
- AT_abc215F 题解
考虑二分答案. 假设当前二分的答案为 \(k\),那么对于每个点,距离大于等于 \(k\) 的点构成了平面上 \(4\) 个子平面. 那么只需查询子平面中是否存在点即可,类似于窗口的星星,把问题转换成 ...
- Microsoft Compatibility telemetry占cpu资源高
1.在Windows10系统卡的时候,打开任务管理器,发现Microsoft Compatibility telemetry占用了大量的系统资源,特别是CPU占用率非常高. 位置:控制面板->管 ...
- Quartus Ⅱ调用FIFO IP核方法实现求和(Mega Wizard)
摘要:本次实验学习记录主题为"FIFO_IP核实现算术求和",主要内容是上位机通过串口向FPGA发送一定规格的数字矩阵,FPGA对矩阵处理,按规定逻辑实现求和运算,将结果返回串口转 ...
- iOS开发基础99-内购in_app
今天后台支付校验模块报错,拿到凭证去苹果校验返回的结果如下: { "receipt": { "receipt_type": "Production&q ...
- Display、Visibility 和 Opacity 的区别
<style> .d1{ display: none; } .d2{ visibility: visible; } .d3{ opacity: 0; } </style> &l ...
- [oeasy]python0002_终端_CLI_GUI_编程环境_游戏_真实_元宇宙 🥊
回忆 上次 了解了 python 语言的特点 历史悠久 功能强大 深受好评 已成趋势 3大主流操作系统 mac windows linux 添加图片注释,不超过 140 ...
- [oeasy]python0109_tty_打字头_电传打字机_字模_点阵字库
点阵字库 回忆上次内容 上次回顾了 字符字型 的 进化过程 从 谷腾堡 活字 到 罗马正字 和 意大利斜体 罗马帝国战斗力的征服 和 基督教文化传播 使得 拉丁字符 在日耳曼语地区广泛传播 种葡萄 ...
- 构建基于Java Spring Boot和Uniapp的心理小程序:从零到一的完整指南
构建基于Java Spring Boot和Uniapp的心理小程序:从零到一的完整指南 前言 大家好,今天我们来聊聊如何使用Java Spring Boot和Uniapp构建一个心理小程序.这个项目不 ...
- mybatisplus轻松完成一次模糊+分页查询
之前一直用mybatis+pageinfo完成模糊+分页查询,还需要手写sql语句,之前一直没做尝试,今天试了试mybatisplus一个人完成模糊+分页,挺简单的 有一个小插曲是,我的前端接受的da ...
- yum密钥报错
解决报错 [root@node3 mnt]# cat /etc/yum.repos.d/local.repo [BaseOS_repo] baseurl = file:///mnt/BaseOS en ...