- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将我的 nestjs 应用程序的 cqrs 设置与外部消息服务(例如 Redis)集成。我找到了 pull request和 comment在nestJS github上说我应该能够将我的查询/事件/命令总线与cqrs 7.0版以来的外部服务集成。
我一直在尝试实现这一点,但我无法从nestjs 中找到关于该主题的太多信息。我唯一能找到的是 outdated configuration example和 open topic在 github 上创建有关如何实现此功能的教程。我设法通过取消我可以在 github 上找到的关于这个主题的有限帮助来替换默认的发布者和订阅者,但我真的不明白如何使用它来连接到外部服务,或者这是否是最好的方法这个问题。
EventBus
import { RedisEventSubscriber } from '../busses/redisEventSubscriber';
import { RedisEventPublisher } from '../busses/redisEventPublisher';
import { OnModuleInit } from '@nestjs/common';
import { ModuleRef } from "@nestjs/core";
import { CommandBus, EventBus as NestJsEventBus } from "@nestjs/cqrs";
export class EventBus extends NestJsEventBus implements OnModuleInit {
constructor( commandBus: CommandBus, moduleRef: ModuleRef) {
super(commandBus, moduleRef);
}
onModuleInit() {
const subscriber = new RedisEventSubscriber();
subscriber.bridgeEventsTo(this._subject$);
this.publisher = new RedisEventPublisher();
}
}
出版商
export class RedisEventPublisher implements IEventPublisher {
publish<T extends IEvent = IEvent>(event: T) {
console.log("Event published to Redis")
}
}
订阅者
export class RedisEventSubscriber implements IMessageSource {
bridgeEventsTo<T extends IEvent>(subject: Subject<T>) {
console.log('bridged event to thingy')
}
}
如果之前使用外部消息系统设置了 nestjs 的任何人可以分享他们的想法或分享如何正确执行此操作的资源,我们将不胜感激。
最佳答案
所以几天后,我设法找到了两种连接到外部事件总线的方法。我发现我真的不需要外部命令或查询总线,因为它们是通过 API 调用进来的。因此,如果您想使用 NestJS 连接到外部事件总线,这是我发现的两个选项:
这两种方法的主要区别在于它们连接到外部事件总线的方式以及它们处理传入消息的方式。根据您的需要,一个可能比另一个更适合您,但我选择了第一个选项。
自定义发布者和订阅者
在我的应用程序中,我已经通过使用 NestJS 中的 EventBus 类并为我的事件调用 .publish()
对我的事件总线进行手动发布调用。我创建了一个服务,它与自定义发布者和自定义订阅者一起围绕本地 NestJS 事件总线。
eventBusService.ts
export class EventBusService implements IEventBusService {
constructor(
private local: EventBus, // Injected from NestJS CQRS Module
@Inject('eventPublisher') private publisher: IEventPublisher,
@Inject('eventSubscriber') subscriber: IMessageSource) {
subscriber.bridgeEventsTo(this.local.subject$);
}
publish(event: IEvent): void {
this.publisher.publish(event);
};
}
事件服务使用自定义订阅者使用 .bridgeEventsTo()
将来自远程事件总线的任何传入事件重定向到本地事件总线。自定义订阅者使用 redis NPM 包的客户端与事件总线通信。
subscriber.ts
export class RedisEventSubscriber implements IMessageSource {
constructor(@Inject('redisClient') private client: RedisClient) {}
bridgeEventsTo<T extends IEvent>(subject: Subject<T>) {
this.client.subscribe('Foo');
this.client.on("message", (channel: string, message: string) => {
const { payload, header } = JSON.parse(message);
const event = Events[header.name];
subject.next(new event(data.event.payload));
});
}
};
此函数还包含将传入的 Redis 事件映射为事件的逻辑。为此,我创建了一个字典,将我的所有事件保存在 app.module 中,以便我可以查找事件是否知道如何处理传入事件。然后,它使用新事件调用 subject.next()
,以便将其放在内部 NestJS 事件总线上。
publisher.ts
为了根据我自己的事件更新其他系统,我创建了一个发布者,将数据发送到 Redis。
export class RedisEventPublisher implements IEventPublisher {
constructor(@Inject('redisClient') private client: RedisClient) {}
publish<T extends IEvent = IEvent>(event: T) {
const name = event.constructor.name;
const request = {
header: {
name
},
payload: {
event
}
}
this.client.publish('Foo', JSON.stringify(request));
}
}
和订阅者一样,这个类使用 NPM 包客户端向 Redis 事件总线发送事件。
微服务设置
某些部分的微服务设置与自定义事件服务方法非常相似。它使用相同的发布者类,但订阅设置的完成方式不同。它使用 NestJS 微服务包来设置一个微服务,监听传入的消息,然后调用 eventService 将传入的事件发送到事件总线。
eventService.ts
export class EventBusService implements IEventBusService {
constructor(
private eventBus: EventBus,
@Inject('eventPublisher') private eventPublisher: IEventPublisher,) {
}
public publish<T extends IEvent>(event: T): void {
const data = {
payload: event,
eventName: event.constructor.name
}
this.eventPublisher.publish(data);
};
async handle(string: string) : Promise<void> {
const data = JSON.parse(string);
const event = Events[data.event.eventName];
if (!event) {
console.log(`Could not find corresponding event for
${data.event.eventName}`);
};
await this.eventBus.publish(new event(data.event.payload));
}
}
NestJS 有关于如何设置混合服务的文档,可以找到 here .微服务包为您提供了一个 @EventPattern()
装饰器,您可以使用它为传入的事件总线消息创建处理程序,您只需将它们添加到 NestJS Controller 并注入(inject) eventService。
controller.ts
@Controller()
export default class EventController {
constructor(@Inject('eventBusService') private eventBusService:
IEventBusService) {}
@EventPattern(inviteServiceTopic)
handleInviteServiceEvents(data: string) {
this.eventBusService.handle(data)
}
}
因为我不想创建一个混合应用程序来监听传入的事件,所以我决定使用第一个选项。代码很好地组合在一起,而不是使用带有 @EventPattern()
装饰器的随机 Controller 。
这需要很长时间才能弄清楚,所以我希望它对将来的人有所帮助。 :)
关于NestJS 使用 Redis 实现外部事件总线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64769673/
我有一个关于 Redis Pubsub 的练习,如下所示: 如果发布者发布消息但订阅者没有收到服务器崩溃。订阅者如何在重启服务器时收到该消息? 请帮帮我,谢谢! 最佳答案 在这种情况下,消息将永远消失
我们正在使用 Service Stack 的 RedisClient 的 BlockingDequeue 来保存一些数据,直到它可以被处理。调用代码看起来像 using (var client =
我有一个 Redis 服务器和多个 Redis 客户端。每个 Redis 客户端都是一个 WebSocket+HTTP 服务器,其中包括管理 WebSocket 连接。这些 WebSocket+HTT
我有多个 Redis 实例。我使用不同的端口创建了一个集群。现在我想将数据从预先存在的 redis 实例传输到集群。我知道如何将数据从一个实例传输到集群,但是当实例多于一个时,我无法做到这一点。 最佳
配置:三个redis集群分区,跨三组一主一从。当 Master 宕机时,Lettuce 会立即检测到中断并开始重试。但是,Lettuce 没有检测到关联的 slave 已经将自己提升为 master
我想根据从指定集合中检索这些键来删除 Redis 键(及其数据集),例如: HMSET id:1 password 123 category milk HMSET id:2 password 456
我正在编写一个机器人(其中包含要禁用的命令列表),用于监视 Redis。它通过执行禁用命令,例如 (rename-command ZADD "")当我重新启动我的机器人时,如果要禁用的命令列表发生变化
我的任务是为大量听众使用发布/订阅。这是来自 docs 的订阅的简化示例: r = redis.StrictRedis(...) p = r.pubsub() p.subscribe('my-firs
我一直在阅读有关使用 Redis 哨兵进行故障转移的内容。我打算有1个master+1个slave,如果master宕机超过1分钟,就把slave变成master。我知道这在 Sentinel 中是
与仅使用常规 Redis 和创建分片相比,使用 Redis 集群有哪些优势? 在我看来,Redis Cluster 更注重数据安全(让主从架构解决故障)。 最佳答案 我认为当您需要在不丢失任何数据的情
由于 Redis 以被动和主动方式使 key 过期, 有没有办法得到一个 key ,即使它的过期时间已过 (但 在 Redis 中仍然存在 )? 最佳答案 DEBUG OBJECT myKey 将返回
我想用redis lua来实现monitor命令,而不是redis-cli monitor。但我不知道怎么办。 redis.call('monitor') 不起作用。 最佳答案 您不能从 Redis
我读过 https://github.com/redisson/redisson 我发现有几个 Redis 复制设置(包括对 AWS ElastiCache 和 Azure Redis 缓存的支持)
Microsoft.AspNet.SignalR.Redis 和 StackExchange.Redis.Extensions.Core 在同一个项目中使用。前者需要StackExchange.Red
1. 认识 Redis Redis(Remote Dictionary Server)远程词典服务器,是一个基于内存的键值对型 NoSQL 数据库。 特征: 键值(key-value)型,value
1. Redis 数据结构介绍 Redis 是一个 key-value 的数据库,key 一般是 String 类型,但 value 类型多种多样,下面就举了几个例子: value 类型 示例 Str
1. 什么是缓存 缓存(Cache) 就是数据交换的缓冲区,是存贮数据的临时地方,一般读写性能较高。 缓存的作用: 降低后端负载 提高读写效率,降低响应时间 缓存的成本: 数据一致性成本 代码维护成本
我有一份记录 list 。对于我的每条记录,我都需要进行一些繁重的计算,因为我要在Redis中创建反向索引。为了达到到达记录,需要在管道中执行多个redis命令(sadd为100 s + set为1
我有一个三节点Redis和3节点哨兵,一切正常,所有主服务器和从属服务器都经过验证,并且哨兵配置文件已与所有Redis和哨兵节点一起更新,但是问题是当Redis主服务器关闭并且哨兵希望选举失败者时再次
我正在尝试计算Redis中存储的消息之间的响应时间。但是我不知道该怎么做。 首先,我必须像这样存储chat_messages的时间流 ZADD conversation:CONVERSATION_ID
我是一名优秀的程序员,十分优秀!