免费开源的 .NET 分布式组件库 Exceptionless Foundatio

前言

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

目录

  • Foundatio 介绍

  • Getting Started
    缓存
    队列

    消息
    工作任务
    文件存储
    度量
    日志

  • 示例程序源码

  • 总结

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:一个RedisCacheClient 、InMemoryCacheClient 的混合实现,通过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 HelloWorld

QueueItem.
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 WorkItemStatusawait 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、MetricsNETClient:Metrics.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"); // ORlog.Info().Message("Application starting up").Write();log.Error(ex, "Writing a captured exception out to the log."); // Orlog.Error().Exception(ex).Message("Writing a captured exception out to the log.").Write();

示例程序源码

示例程序GitHub:

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

总结

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

相关文章:

  • 免费开源分布式系统日志收集框架 Exceptionless

  • 使用 Exceptionless 作为 Log Server 搭配 NLog 记录系统日志

  • 使用Elasticsearch 与 NEST 库 构建 .NET 企业级搜索

  • 为elasticsearch集成一些实用 插件以及配置的开箱即用的版本

  • Exceptionless 本地部署


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


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/328413.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 8 中 Date与LocalDateTime、LocalDate、LocalTime互转

转载自 Java 8 中 Date与LocalDateTime、LocalDate、LocalTime互转Java 8中 java.util.Date 类新增了两个方法&#xff0c;分别是from(Instant instant)和toInstant()方法 // Obtains an instance of Date from an Instant object. public static Date from(Instant instant) …

mysql 删除过期日志_【转】对mysql日志进行操作的总结包括 启用,过期自动删除 等...

近段时间一直在研究mysql的日志系统,在网上看了N多mysql日志操作的文章&#xff0c;但都过于零乱&#xff0c;为了让自己以后不再搞忘&#xff0c;特作出以下总结&#xff1a;1. 以前我错误的认为mysql的日志可以恢复到任何时间的状态&#xff0c;其实并不是这样&#xff0c;这…

vo listVO paggerHelper mapper使用原则

注意 列表页面就显示这张表就好了 pageHelper 用2个mapper没有问题 xxxlistVO就好了详情哪里在展示多张表 不用分页你想链接几张表都可以 xxxVO 所有VO不要包含子对象注意一般vo对象中不可以包含对象&#xff01;&#xff01;&#xff01;&#xff01;&#xff…

Visual Studio 2015 for Linux更好地支持Linux下的开发

Visual C for Linux扩展使Visual Studio 2015的用户可以在VS2015中编写C或者C代码&#xff0c;并将代码部署到基于Linux的系统中去编译和调试。源代码和项目文件通过SSH传输到远程机上&#xff0c;程序的输出将显示在Visual Studio上。 Microsoft的Marc Goodner分享了更多有关新…

Google浏览器截长图 不需要借助任何插件!!!

1打开“谷歌浏览器”&#xff0c;右键单击网页空白处&#xff0c;然后点击“检查”。 2打开“开发者模式”&#xff0c;按“Ctrlshiftp”。 3.在输入框中输入“cpture”。 4.出现的三个模式分别为“截取全屏”、“node模式”和“当前范围”&#xff0c;选择想要的模式。 5.…

tomcat7.0.42如何设置mysql数据库连接池

转载自 tomcat7.0.42如何设置mysql数据库连接池 如何在tomcat7.0.42中设置mysql数据库连接池????eclipse如何绑定tomcat??按网上教程总不成功!怎么办server.xml<Resource name"jdbc/test" auth"Container" type"javax.sql.DataSource"…

自包含 .NET Core应用程序

.NET 是完全开源的&#xff0c;而且 .NET Core 是一个您可以免费下载的开源与跨平台 framework。您可以到 http://dot.net 获取 Mac、Windows 与大多数的 Unix 系统的版本。还可以使用免费、跨平台的 Visual Studio Code&#xff0c;用VS code您就可以随时随地编写 C# 与 F#。 …

php如何求同列元素之和_求得这个数组中各个元素之和

给定一个数组&#xff1a;$ar array(1,2,3,4,5);如果要求得这个数组中各个元素之和。方法一、很自然的用foreach实现$sum 0;foreach ($ar as $v) {$sum$v;}echo $sum;方法二、我们可以用array_reduce实现。它是专门用来迭代数组的。该函数最多接收三个参数。第一个参数接收数…

关于Tomcat与MySQL连接池问题的详解

转载自 关于Tomcat与MySQL连接池问题的详解研究了一天&#xff0c;终于有所收获&#xff0c;希望对大家有所帮助。首先请大家注意&#xff1a;这里尤其讨论Tomcat5.5版本中遇到的问题&#xff0c;为什么尤其单对这个版本&#xff0c;我一会儿便加以说明。问题一&#xff1a;C…

ASP.NET Core中间件(Middleware)实现WCF SOAP服务端解析

ASP.NET Core中间件(Middleware)进阶学习实现SOAP 解析。 本篇将介绍实现ASP.NET Core SOAP服务端解析&#xff0c;而不是ASP.NET Core整个WCF host。 因为WCF中不仅仅只是有SOAP&#xff0c; 它还包含很多如消息安全性&#xff0c;生成WSDL&#xff0c;双工信道&#xff0c;非…

java异常了还会往下走吗_异常一个问题,请帮下忙:处理异常后,程序会继续往下运行吗...

import java.util.*;public class PrintBig{public static void main(String[] args){Scanner in new Scanner(System.in);int sum;int count0;System.out.println("输入10个整数");for(int i0;i<10;i){sum in.nextInt();try{Integer k new Integer(sum);}catc…

新闻发布项目——访问温馨提示

1.本项目开发的软件&#xff1a;MyEclipse10.0tomcat7.0sql servel2012 2.本项目所有的CSS下载地址&#xff1a;Jsp实现新闻发布系统的CSS界面 3.本项目所有的JS下载地址&#xff1a;Jsp实现新闻发布系统的JS界面 4.本项目所有的图片下载地址&#xff1a;Jsp实现新闻发布系统的…

Tomcat 使用apr优化

转载自 Tomcat 使用apr优化最近业务服务器出现了一些问题&#xff0c;Nginx傲娇了&#xff0c;准备把加Nginx插件上的一些处理逻辑扔到后端的Tomcat的业务处理里面去&#xff0c;考虑到tomcat目前本来就压力山大&#xff0c;所以弄了弄apr库来优化tomcat的并发能力。&#xf…

ASP.NET Core MVC 配置全局路由前缀

前言 大家好&#xff0c;今天给大家介绍一个 ASP.NET Core MVC 的一个新特性&#xff0c;给全局路由添加统一前缀。严格说其实不算是新特性&#xff0c;不过是Core MVC特有的。 应用背景 不知道大家在做 Web Api 应用程序的时候&#xff0c;有没有遇到过这种场景&#xff0c;就…

java jpa saveall方法优化_JPA批量插入(saveAll)

有时候要从第三方导入数据&#xff0c;一般量都比较大&#xff0c;除了方法用异步线程Async之外&#xff0c;如果每条记录都调用一次save显然对数据库压力很大。可以使用JPA的批量保存方法saveAll(Iterable entities)。由于JPA的批量保存和批量修改是同一个方法&#xff0c;所以…

js截取字符串的后几位数 省份证号*隐藏

js截取字符串的后几位数 代码如下&#xff1a; var str"abcdefghhhh";//截取后4位 str.substring(str.length-4)&#xff1b; js * 代替 var str ’331023187609300311‘&#xff1b; //18位省份证号 前三位显示中间10位有8个*代替后5位显示 331********00…

java 单一职责原则_设计模式之单一职责原则

对类来说&#xff0c;即一个类应用只负责一项职责&#xff0c;如类A负责两个不同的职责&#xff1a;职责1&#xff0c;职责2.当职责1需求变更时&#xff0c;可造成职责2执行错误&#xff0c;所以需要将类A的粒度分解为A1&#xff0c;A2.降低类的复杂度&#xff0c;一个类只负责…

TypeScript 2.0 正式发布

9 月 22 日&#xff0c;TypeScript 2.0 正式发布了。 TypeScript 是微软开发的开源的编程语言&#xff0c;主要负责人是 C# 之父 Anders Hejlsberg。 TypeScript 成功将 JavaScript 的潜能与静态类型结合了起来&#xff0c;而且编译为 JavaScript。编译时类型检查可以避免很多潜…