企业应用中微服务架构的应用
立即解锁
发布时间: 2025-08-25 01:04:34 阅读量: 1 订阅数: 8 


C# 8与.NET Core 3实战软件架构精髓
### 企业应用中微服务架构的应用
#### 1. 引言
在企业应用开发中,微服务架构正发挥着越来越重要的作用。本文将详细介绍如何实现一个名为 LogStore 的微服务,包括通信接收端的实现、服务逻辑的编写、微服务主机的定义以及与服务的通信等方面。
#### 2. 实现通信接收端
要实现 LogStore 微服务,首先需要添加对 Interaction 库的引用,它会自动创建对远程库和 IdempotencyTools 项目的引用。然后,LogStore 类必须实现 ILogStore 接口。
```csharp
internal sealed class LogStore : StatefulService, ILogStore
{
private IReliableQueue<IdempotentMessage<PurchaseInfo>> LogQueue = null;
public async Task<bool> LogPurchase(IdempotentMessage<PurchaseInfo> idempotentMessage)
{
if (LogQueue == null) return false;
using (ITransaction tx = this.StateManager.CreateTransaction())
{
await LogQueue.EnqueueAsync(tx, idempotentMessage);
await tx.CommitAsync();
return true;
}
}
}
```
当服务从远程运行时接收到 LogPurchase 调用时,会将消息放入 LogQueue 中,避免调用者阻塞等待消息处理完成,从而实现了同步消息传递协议的可靠性和异步消息处理的性能优势。
需要注意的是,LogQueue 作为所有分布式集合的最佳实践,是在 RunAsync 方法中创建的。如果在 Azure Service Fabric 运行时调用 RunAsync 之前收到第一个调用,LogQueue 可能为 null,此时方法将返回 false 表示服务尚未准备好。
此外,还需要实现 CreateServiceReplicaListeners() 方法来返回服务想要激活的所有监听器。对于远程通信,可以使用预定义的方法:
```csharp
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
return this.CreateServiceRemotingReplicaListeners<LogStore>();
}
```
CreateServiceRemotingReplicaListeners 是远程通信库中定义的扩展方法,它为主要副本和次要副本(用于只读操作)创建监听器。创建客户端时,可以指定通信是仅针对主要副本还是也针对次要副本。
如果想使用不同的监听器,需要创建一个 ServiceReplicaListener 实例的 IEnumerable。每个监听器的构造函数需要三个参数:
- 一个接收可靠服务上下文对象作为输入并返回 ICommunicationListener 接口实现的函数。
- 监听器的名称。当服务有多个监听器时,此参数为必需项。
- 一个布尔值,如果监听器必须在次要副本上激活,则为 true。
例如,添加自定义和 HTTP 监听器的代码如下:
```csharp
return new ServiceReplicaListener[]
{
new ServiceReplicaListener(context =>
new MyCustomHttpListener(context, "<endpoint name>"),
"CustomWriteUpdateListener", true),
new ServiceReplicaListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "<endpoint name>" (url, listener) =>
{
return new WebHostBuilder()
.UseKestrel()
.ConfigureServices(
services => services
.AddSingleton<StatefulServiceContext>(serviceContext)
.AddSingleton<IReliableStateManager>(this.StateManager))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener,
ServiceFabricIntegrationOptions.UseUniqueServiceUrl)
.UseUrls(url)
.Build();
})
"HttpReadOnlyListener",
true)
};
```
#### 3. 实现服务逻辑
服务逻辑由 Service Fabric 运行时调用 RunAsync 时作为独立线程启动的任务执行。创建 IHost 并将所有任务设计为 IHostedService 实现是一个好的实践,因为 IHostedService 实现是独立的软件块,更易于单元测试。
这里将实现一个名为 ComputeStatistics 的 IHostedService,用于计算每个位置的每日收入。它使用一个分布式字典,键是位置名称,值是 RunningTotal 类的实例。
```csharp
namespace LogStore
{
public class RunningTotal
{
public DateTime Day { get; set; }
public decimal Count { get; set; }
public RunningTotal Update(DateTimeOffset time, decimal value)
{
var normalizedTime = time.ToUniversalTime();
var newDay = new DateTime(normalizedTime.Year, normalizedTime.Month, normalizedTime.Day);
var result = newDay > Day && Day != DateTime.MinValue ?
new RunningTotal
{
Day = Day,
Count = Count
}
: null;
if (newDay > Day) Day = newDay;
if (result != null) Count = value;
else Count += value;
return result;
}
}
}
```
ComputeStatistics 类需要一些参数才能正常工作:
- 包含所有传入消息的队列。
- IReliableStateManager 服务,用于创建存储数据的分布式字典。
- ConfigurationPackage 服务,用于读取服务设置文件 Settings.xml 中定义的设置以及应用清单中可能覆盖的设置。
```csharp
namespace LogStore
{
public class ComputeStatistics : BackgroundService
{
IReliableQueue<IdempotentMessage<PurchaseInfo>> queue;
IReliableStateManager stateManager;
ConfigurationPackage configurationPackage;
public ComputeStatistics(
IReliableQueue<IdempotentMessage<PurchaseInfo>> queue,
IReliableStateManager stateMa
```
0
0
复制全文
相关推荐










