前言

在互联网时代,分布式应用、系统变得越来越多,我们在使用 .Net 技术构建分布式系统的时候,需要使用到一些组件或者是助手库来帮助我们提高生产力以及应用程序解耦,但是纵观.Net圈,能够符合要求的这样的组件并不是很多,并且没有一个通用的抽象组件能够将这些接口集成起来,今天就为大家介绍一款开源的组件库 Foundatio,他们同样出自于Exceptionless团队之手,下面就来看看吧。

目录

Foundatio 介绍

GitHub : https://github.com/exceptionless/Foundatio

Foundatio 是一个插件式的,松耦合的一套构建分布式应用的程序库,出自于Exceptionless团队。

Foundatio 同时支持 .NET Framework 4.6 和 .NET Core。

通过 Foundatio 我可以获得哪些帮助呢

  • 如果你是面对接口(抽象)构建的程序,你可以很容易的对接口实现进行切换。
  • 具有友好的依赖注入,还在使用 .Net Framework的朋友可以体验一下,它具有比Autofac,Unity等更简易的操作和更友好的接口。
  • 可以更加方便的使用缓存了,Foundatio帮助我们封装了很多缓存的客户端实现,比如RedisCache、InMemoryCache、ScopedCache等等。
  • 消息总线,你不必自己构建或者使用复杂且昂贵的NServiceBus了,很多时候我们仅仅需要的是一个可以在本地或者云上运行的简单的消息总线。
  • 存储,现在你可以很方便的通过一致的接口来使用分布式存储了,包括内存文件存储文件夹文件存储,Azure文件存储AWS S3文件存储

Foundatio 主要包含以下模块:

  • 缓存(Caching)
  • 队列(Queues)
  • 锁(Locks)
  • 消息(Messaging)
  • 工作任务(Jobs)
  • 文件存储(File Storage)
  • 度量(Metrics)
  • 日志(Logging)

这些组件都以NuGet包的形式提供出来供我们很方便的使用,

下面依次来看看每一个组件的用途和使用方法吧。

Getting Started

缓存

缓存是一种空间换时间的技术,你可以通过缓存来快速的获取一些数据。

Foundatio Cache 提供了一致的接口ICacheClient 来很容易的存储或者读取缓存数据,并且提供了4中不同的缓存客户端的实现。他们分别是:

1、InMemoryCacheClient:内存缓存的实现,这种缓存的生命周期为当前进程, 有一个MaxItems属性,可以设置最多缓存多少条数据。

2、HybridCacheClientInMemoryCacheClient 具有相同的实现,但是此接口提供、IMessageBus 可以用来跨线程之间的同步。

3、RedisCacheClient:一个 Redis 客户端的实现。

4、RedisHybridCacheClient:一个RedisCacheClientInMemoryCacheClient 的混合实现,通过RedisMessageBus来保持内存缓存跨线程之间的同步。

注意:如果本地缓存的项已经存在,在调用Redis进行序列化保存的时候可能会有性能问题。

5、ScopedCacheClient:传入ICacheClientscope,scope 可以设置一个字符串,来制定一个缓存键前缀,这样可以很方便的进行批量存储和删除。

例子:

using Foundatio.Caching;

ICacheClient cache = new InMemoryCacheClient();
await cache.SetAsync("test", 1);
var value = await cache.GetAsync<int>("test");

队列

提供了一个先进,先出的消息管道,Foundatio 提供了一个IQueue接口,并且拥有 4 种不同的队列实现。

1、InMemoryQueue:一个内存队列实现,队列的生命周期为当前进程。

2、RedisQueue:一个 Redis 队列实现。

3、AzureServiceBusQueue:一个基于Azure的服务消息队列实现。

4、AzureStorageQueue:一个基于Azure的存储队列实现。

例子:

using Foundatio.Queues;

IQueue<SimpleWorkItem> queue = new InMemoryQueue<SimpleWorkItem>();

await queue.EnqueueAsync(new SimpleWorkItem {
Data = "Hello"
}); var workItem = await queue.DequeueAsync();

锁主要是确保无论在什么时候资源只被消费一次,Foundatio 提供了一个ILockProvider接口,并且有两种不同的锁机制的实现。

1、CacheLockProvider:一个缓存锁实现进程间通讯。

2、ThrottlingLockProvider:只允许一定数量的请求进入ILockProvider的实现。你可以使用这个api调用外部服务,它将通过这个节气门锁来限制所有的请求。

这里使用了Throttle这个单词,中文意思是节气门。为了方便理解给大家科普一下:在汽车的汽油机系统中,节气门是一个很重要的组件,是用来控制气体进入引擎的一套可控的阀门。

流程大概就是 空气-->节气门-->气缸,相当于是汽车发动机的咽喉,车子加速是否灵活,与节气门的清洁是很有关系的。所以此处用了Throttle这个单词,非常的形象。

需要注意的时候,所有的锁都是基于ICacheClient的,所以要确保你代码中的锁是否跨机器的。

例子:

using Foundatio.Lock;
using Foundatio.Messaging; ILockProvider locker = new CacheLockProvider(new InMemoryCacheClient(), new InMemoryMessageBus());
await locker.AcquireAsync("test");
// ... ILockProvider locker = new ThrottlingLockProvider(new InMemoryCacheClient(), 1, TimeSpan.FromMinutes(1));
ILock locks = await locker.AcquireAsync("test");
// ...

消息

允许通过你的应用程序发布订阅消息。Foundatio 提供了一个IMessageBus接口,并且有4 种不同的实现。

1、InMemoryMessageBus:一个内存消息总线实现。这个消息总线的生命周期为当前进程。

2、RedisMessageBus:一个 Redis 消息总线实现。

3、RabbitMQMessageBus:一个 RabbitMQ 消息总线实现。

4、AzureServiceBusMessageBus:一个Azure Service消息总线实现。

例子

using Foundatio.Messaging;

public class Program
{ public static void Main(string[] args) { MessageBusTest(); Console.ReadKey();
} public static async void MessageBusTest() { IMessageBus messageBus = new InMemoryMessageBus();
messageBus.Subscribe<SimpleMessageA>(msg => {
Console.WriteLine(msg.Data);
}); await messageBus.PublishAsync(new SimpleMessageA { Data = "Hello" });
} public class SimpleMessageA
{
public string Data { get; set; }
}
}

工作任务

允许你运行一个长时间的任务,并且不用担心会被终止。Foundatio提供了一下不同的方法来定义一个Job。

1、Jobs:提供了一、IJob 接口,和一个默认的基类JobBase。直接上代码吧:

using Foundatio.Jobs;

public class HelloWorldJob : JobBase {
public int RunCount { get; set; } protected override Task<JobResult> RunInternalAsync(JobRunContext context) {
RunCount++;
return Task.FromResult(JobResult.Success);
}
} var job = new HelloWorldJob();
await job.RunAsync(); // job.RunCount = 1;
await job.RunContinuousAsync(iterationLimit: 2); // job.RunCount = 3;
await job.RunContinuousAsync(cancellationToken: new CancellationTokenSource(TimeSpan.FromMilliseconds(10)).Token); // job.RunCount > 10;

2、Queue Processor Jobs:和上面的Jobs差不多,只是这个是基于队列的。

using Foundatio.Jobs;

public class HelloWorldQueueJob : QueueJobBase<HelloWorldQueueItem> {
public int RunCount { get; set; } public HelloWorldQueueJob(IQueue<HelloWorldQueueItem> queue) : base(queue) {} protected override Task<JobResult> ProcessQueueEntryAsync(QueueEntryContext<HelloWorldQueueItem> context) {
RunCount++; return Task.FromResult(JobResult.Success);
}
} public class HelloWorldQueueItem {
public string Message { get; set; }
} // Register the queue for HelloWorldQueueItem.
container.RegisterSingleton<IQueue<HelloWorldQueueItem>>(() => new InMemoryQueue<HelloWorldQueueItem>()); // To trigger the job we need to queue the HelloWorldWorkItem message.
// This assumes that we injected an instance of IQueue<HelloWorldWorkItem> queue var job = new HelloWorldQueueJob();
await job.RunAsync(); // job.RunCount = 0; The RunCount wasn't incremented because we didn't enqueue any data. await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });
await job.RunAsync(); // job.RunCount = 1; await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });
await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });
await job.RunUntilEmptyAsync(); // job.RunCount = 3;

3、Work Item Jobs:这种类型的Job适合于那些不经常发生,但是应该在一个Job(例如:删除一个实体,有很多子级)。

using System.Threading.Tasks;
using Foundatio.Jobs; public class HelloWorldWorkItemHandler : WorkItemHandlerBase
{
public override async Task HandleItemAsync(WorkItemContext ctx) {
var workItem = ctx.GetData<HelloWorldWorkItem>(); // We can report the progress over the message bus easily.
// To recieve these messages just inject IMessageSubscriber
// and Subscribe to messages of type WorkItemStatus
await ctx.ReportProgressAsync(0, "Starting Hello World Job");
await Task.Delay(TimeSpan.FromSeconds(2.5));
await ctx.ReportProgressAsync(50, String.Format("Reading value"));
await Task.Delay(TimeSpan.FromSeconds(.5));
await ctx.ReportProgressAsync(70, String.Format("Reading value."));
await Task.Delay(TimeSpan.FromSeconds(.5));
await ctx.ReportProgressAsync(90, String.Format("Reading value.."));
await Task.Delay(TimeSpan.FromSeconds(.5)); await ctx.ReportProgressAsync(100, workItem.Message);
}
} public class HelloWorldWorkItem
{
public string Message { get; set; }
} // Register the shared job.
var handlers = new WorkItemHandlers();
handlers.Register<HelloWorldWorkItem, HelloWorldWorkItemHandler>(); // Register the handlers with dependency injection.
container.RegisterSingleton(handlers); // Register the queue for WorkItemData.
container.RegisterSingleton<IQueue<WorkItemData>>(() => new InMemoryQueue<WorkItemData>()); // The job runner will automatically look for and run all registered WorkItemHandlers.
new JobRunner(container.GetInstance<WorkItemJob>(), instanceCount: 2).RunInBackground(); await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });

文件存储

Foundatio File Storage 提供了一致的接、IFileStorage 来很容易的存储或者读取文件,并且提供了4中不同的文件存储的实现。他们分别是:

1、InMemoryFileStorage:基于内存的文件存储,生命周期为当前进程。

2、FolderFileStorage:文件夹存储,存储到硬盘中。

3、AzureFileStorage:Azure Blob 存储的实现。

4、S3Storage:AWS S3 存储的实现。

建议在服务中注入IFileStorage接口的时候,使用单例方式注入。

例子:

using Foundatio.Storage;

IFileStorage storage = new InMemoryFileStorage();
await storage.SaveFileAsync("test.txt", "test");
string content = await storage.GetFileContentsAsync("test.txt")

度量

关于Metrics的概念,可以参考 这篇博文

提供了一个IMetricsClient 接口,并且有 4 中不同的实现:

1、InMemoryMetricsClient:内存 metrics 的实现。

2、RedisMetricsClient:Redis metrics 的实现。

3、StatsDMetricsClient:statsd metrics 的实现。

4、MetricsNETClientMetrics.NET 的实现。

建议在服务中注入IMetricsClient接口的时候,使用单例方式注入。

例子:

await metrics.CounterAsync("c1");
await metrics.GaugeAsync("g1", 2.534);
await metrics.TimerAsync("t1", 50788);

日志

提供了一个流畅型的日志 api, 可用于在应用程序记录日志消息。并且可以在不需要改变应用程序代码的情况下,切换各个日志框架。

例子:

ILoggerFactory loggerFactory = new LoggerFactory();
ILogger log = loggerFactory.CreateLogger("Program");
log.Info("Application starting up"); // OR
log.Info().Message("Application starting up").Write(); log.Error(ex, "Writing a captured exception out to the log."); // Or
log.Error().Exception(ex).Message("Writing a captured exception out to the log.").Write();

示例程序源码

示例程序GitHub:

https://github.com/exceptionless/Foundatio.Samples

总结

感谢 Exceptionless 团队给我们提供了这么简单易用的 Foundatio 框架,还在等什么,快在你的项目中用起来吧。

如果您觉得本文对您有帮助,想让更多人了解Exceptionless,感谢您帮忙点的【推荐】。

如果您对 Exceptionless 感兴趣或者是想学习 Exceptionless 的代码,可以加入群

Exceptionless QQ群:330316486


本文地址:http://www.cnblogs.com/savorboard/p/exceptionless-foundatio.html

作者博客:Savorboard

欢迎转载,请在明显位置给出出处及链接

免费开源的 .NET 分布式组件库 Exceptionless Foundatio的更多相关文章

  1. 免费开源的DotNet任务调度组件Quartz.NET(.NET组件介绍之五)

    很多的软件项目中都会使用到定时任务.定时轮询数据库同步,定时邮件通知等功能..NET Framework具有“内置”定时器功能,通过System.Timers.Timer类.在使用Timer类需要面对 ...

  2. beeshell —— 开源的 React Native 组件库

    介绍 beeshell 是一个 React Native 应用的基础组件库,基于 0.53.3 版本,提供一整套开箱即用的高质量组件,包含 JavaScript(以下简称 JS)组件和复合组件(包含 ...

  3. 免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)

    前面介绍了六种.NET组件,其中有一种组件是写文件的压缩和解压,现在介绍另一种文件的解压缩组件SharpZipLib.在这个组件介绍系列中,只为简单的介绍组件的背景和简单的应用,读者在阅读时可以结合官 ...

  4. 免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)

    在生活中有一种东西几乎已经快要成为我们的另一个电子”身份证“,那就是二维码.无论是在软件开发的过程中,还是在普通用户的日常中,几乎都离不开二维码.二维码 (dimensional barcode) , ...

  5. 1、小程序Vant_WebApp组件库的安装步骤和简单使用

    Vant 1.小程序对于npm的支持 目前,小程序当中已经支持使用npm安装的第三方包,通过使用这些第三方包,我们可以提高对小程序开发的效率,但是在小程序当中使用所谓的npm包有如下的三个限制 不能支 ...

  6. C#实现多级子目录Zip压缩解压实例 NET4.6下的UTC时间转换 [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 asp.net core异步进行新增操作并且需要判断某些字段是否重复的三种解决方案 .NET Core开发日志

    C#实现多级子目录Zip压缩解压实例 参考 https://blog.csdn.net/lki_suidongdong/article/details/20942977 重点: 实现多级子目录的压缩, ...

  7. asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程

    最近在学习张善友老师的NanoFabric 框架的时了解到Exceptionless : https://exceptionless.com/ !因此学习了一下这个开源框架!下面对Exceptionl ...

  8. Net Core免费开源分布式异常日志收集框架Exceptionless

    asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 https://www.cnblogs.com/yilezhu/p/9193723.htm ...

  9. 【转】asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程

    最近在学习张善友老师的NanoFabric 框架的时了解到Exceptionless : https://exceptionless.com/ !因此学习了一下这个开源框架!下面对Exceptionl ...

随机推荐

  1. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  2. Asp.net MVC 传递数据 从前台到后台,包括单个对象,多个对象,集合

    今天为大家分享下 Asp.net MVC 将数据从前台传递到后台的几种方式. 环境:VS2013,MVC5.0框架 1.基本数据类型 我们常见有传递 int, string, bool, double ...

  3. 预览github里面的网页或dome

    1.问题所在: 之前把项目提交到github都可以在路径前面加上http://htmlpreview.github.io/?来预览demo,最近发现这种方式预览的时候加载不出来css,js(原因不详) ...

  4. .NET平台开源项目速览(18)C#平台JSON实体类生成器JSON C# Class Generator

    去年,我在一篇文章用原始方法解析复杂字符串,json一定要用JsonMapper么?中介绍了简单的JSON解析的问题,那种方法在当时的环境是非常方便的,因为不需要生成实体类,结构很容易解析.但随着业务 ...

  5. java单向加密算法小结(2)--MD5哈希算法

    上一篇文章整理了Base64算法的相关知识,严格来说,Base64只能算是一种编码方式而非加密算法,这一篇要说的MD5,其实也不算是加密算法,而是一种哈希算法,即将目标文本转化为固定长度,不可逆的字符 ...

  6. python学习笔记(python介绍)

    为什么要学python? python和shell的比较,和PHP.和JAVA比较 运维开发只是用到python的很小一部分 python在一些知名公司的应用: 谷歌:python的创始人原来在谷歌工 ...

  7. 【夯实Mysql基础】MySQL性能优化的21个最佳实践 和 mysql使用索引

    本文地址 分享提纲: 1.为查询缓存优化你的查询 2. EXPLAIN 你的 SELECT 查询 3. 当只要一行数据时使用 LIMIT 1 4. 为搜索字段建索引 5. 在Join表的时候使用相当类 ...

  8. Android之Pull解析XML

    一.Pull解析方法介绍 除了可以使用SAX和DOM解析XML文件,也可以使用Android内置的Pull解析器解析XML文件.Pull解析器的运行方式与SAX解析器相似.它也是事件触发的.Pull解 ...

  9. 自建git node pm2 (不赘述,就说遇见的问题)

    //======================[git]部分 主题部分还是按照网上的办法进行安装. 安装的话  分为两个办法(一个是yum (contos办法)  或者sudo(ubuntu办法) ...

  10. JAVA 设计模式之策略模式

    定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换. 类型:行为类模式 策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换.在前面说过 ...