Orleans解决并发之痛(四):Streams

Orleans 提供了 Stream扩展编程模型。此模型提供了一套API,使处理流更简单和更健壮。Stream默认提供了两种Provider,不同的流类型可能使用不同的Provider来处理,Simple Message Stream Provider 和 Azure Queue Stream Provider。Stream Providers兼容现有的队列技术,比如: Event Hubs、ServiceBus、Azure Queues、Apache Kafka,不再需要编写额外的代码来配合这些队列技术的使用。

关于为什么Orleans会提供Stream扩展编程模型?

当今已经有一系列技术可以来构建一个流处理系统。包括持久存储流数据方面,如:Event Hubs、Kafka;数据流计算操作方面,如: Azure Stream Analytics、Apache Storm、Apache Spark Streaming, 而这些技术并不适合细粒度的自由格式的流数据计算, 或者支持的并不好,因为实际情况下可能需要对不同的数据流执行不同的操作,Orleans Streams目的就是解决这类问题,Stream编程模型和发布订阅模式挺相似。

上述提到的一些技术我并没有详细学习,后面会了解并对比,如果已熟悉的可以先思考并给我普及普及。

Orleans Stream大概实现的步骤如下:

  1. 获取 StreamProvider

  2. 获取 IAsyncStream<T>

  3. 订阅者订阅一个Stream

  4. 发布者向某个Stream发布消息

Silo配置文件OrleansConfiguration.xml修改

在Globals节点中添加:

<StorageProviders>
    <Provider Type="Orleans.Storage.MemoryStorage" Name="PubSubStore" />
</StorageProviders>
<StreamProviders>
    <Provider Type="Orleans.Providers.Streams.SimpleMessageStream.SimpleMessageStreamProvider" Name="SMSProvider"/>
</StreamProviders>

Name为PubSubStore的StorageProvider是必须的,Stream内部需要它来跟踪所有流订阅,记录各个流的发布者和订阅者的关系,本例中使用MemoryStorage,实际生产环境这是不对的。

Name为SMSProvider的StreamProvider指定了消息的发布形式,Orleans当前提供的两种StreamProvider:Simple Message Stream ProviderAzure Queue Stream Provider 都是可靠的。

Simple Message Stream Provider:不保证可靠的交付,失败的消息不会自动重新发送,但可以根据返回的Task状态来判断是否重新发送,事件执行顺序遵循FIFO原则。

Azure Queue Stream Provider:事件被加入Azure Queue, 如果传送或处理失败,事件不会从队列中删除,并且稍后会自动重新被发送,因此事件执行顺序不遵循FIFO原则。

获取 StreamProvider

var streamProvider = this.GetStreamProvider("SMSProvider");

SMSProvider 对应配置文件中Name为SMSProvider的StreamProvider

获取 IAsyncStream<T>

var streamId = this.GetPrimaryKey();
var stream = streamProvider.GetStream<string>(streamId, "GrainStream");

GetStream 需要两个参数,通过两个值定位唯一的Stream:
streamId:Guid类型,stream标识
streamNamespace:字符串,stream的命名空间

订阅一个Stream

订阅Stream分为隐式和显式订阅。

隐式订阅

隐式订阅的订阅者是唯一的,不存在对一个Stream的多次订阅,也不能取消订阅。

Interface:

public interface IImplicitSubscriberGrain : IGrainWithGuidKey
{
}

Grain:

[ImplicitStreamSubscription("GrainImplicitStream")]
public class ImplicitSubscriberGrain : Grain, IImplicitSubscriberGrain, IAsyncObserver<string>
{
    protected StreamSubscriptionHandle<string> streamHandle;

    public override async Task OnActivateAsync()
    {
        var streamId = this.GetPrimaryKey();
        var streamProvider = this.GetStreamProvider("SMSProvider");
        var stream = streamProvider.GetStream<string>(streamId, "GrainImplicitStream");
        streamHandle = await stream.SubscribeAsync(OnNextAsync);
    }

    public override async Task OnDeactivateAsync()
    {
        if (streamHandle != null)
            await streamHandle.UnsubscribeAsync();
    }

    public Task OnCompletedAsync()
    {
        return Task.CompletedTask;
    }

    public Task OnErrorAsync(Exception ex)
    {
        return Task.CompletedTask;
    }

    public Task OnNextAsync(string item, StreamSequenceToken token = null)
    {
        Console.WriteLine($"Received message:{item}");
        return Task.CompletedTask;
    }
}
  1. 在Grain上标记 ImplicitStreamSubscription 属性,变量值为命名空间;

  2. 在Grain的OnActivateAsync方法体中调用SubscribeAsync;

  3. 实现IAsyncObserver接口,当发布者向Stream发送消息,订阅者接到消息后将执行OnNextAsync;

  4. 隐式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值