新增通讯方式 - 分布式事件总线
iohao opened this issue · comments
简单介绍
分布式事件总线是 ioGame 提供的通讯方式之一。该通讯方式与 Guava EventBus、Redis 发布订阅、MQ ... 等产品类似。
如果使用 Redis、MQ ...等中间件,需要开发者额外的安装这些中间件,并支付所占用机器的费用;使用 Guava EventBus 则只能在当前进程中通信,无法实现跨进程。
而 ioGame 提供的分布式事件总线,拥有上述两者的优点。此外,还可以有效的帮助企业节省云上 Redis、 MQ 这部分的支出。
事件发布后,除了当前进程所有的订阅者能接收到,远程的订阅者也能接收到(支持跨机器、跨进程、跨不同类型的多个逻辑服)。可以代替 redis pub sub 、 MQ ,并且具备全链路调用日志跟踪,这点是中间件产品做不到的。
ioGame 分布式事件总线,特点
- 使用方式与 Guava EventBus 类似
- 具备全链路调用日志跟踪。(这点是中间件产品做不到的)
- 支持跨多个机器、多个进程通信
- 支持与多种不同类型的多个逻辑服通信
- 纯 javaSE,不依赖其他服务,耦合性低。(不需要安装任何中间件)
- 事件源和事件监听器之间通过事件进行通信,从而实现了模块之间的解耦
- 当没有任何远程订阅者时,将不会触发网络请求。(这点是中间件产品做不到的)
ioGame 支持的通讯方式分为两大类,即路由类和主题类,而分布式事件总线属于主题类通讯。主题类通讯方式的特点是可与多种不同类型的多个逻辑服通信。
通讯方式特点:分布式事件总线
事件发布后,除了当前进程所有的订阅者能接收到,远程的订阅者也能接收到(跨机器、跨进程)。可以代替 redis pub sub 、 MQ ,并且具备全链路调用日志跟踪,这点是中间件产品做不到的。
示例代码中提供了同步、异步的编码风格。
void eventBus() {
int userId = 100;
// 事件源
YourEventMessage yourEventMessage = new YourEventMessage(userId);
// 异步执行 - 事件发布后,只会交给 flowContext 关联的业务框架中的订阅者处理
flowContext.fireMe(yourEventMessage);
// 同步执行 - 事件发布后,只会交给 flowContext 关联的业务框架中的订阅者处理
flowContext.fireMeSync(yourEventMessage);
// 异步执行 - 事件发布后,当前进程所有的订阅者都会接收到。(同进程启动了多个逻辑服)
flowContext.fireLocal(yourEventMessage);
// 同步执行 - 事件发布后,当前进程所有的订阅者都会接收到。(同进程启动了多个逻辑服)
flowContext.fireLocalSync(yourEventMessage);
// 异步执行 - 除了当前进程所有的订阅者能接收到,远程的订阅者也能接收到(跨机器、跨进程)
flowContext.fire(yourEventMessage);
}
大多数情况下,在发布事件时,使用 fire 方法就足够了。因为除了当前进程所有的订阅者能接收到,远程的订阅者也能接收到(跨机器、跨进程)
需要注意的是,如果没有任何远程订阅者,将不会触发网络请求。简单的说,事件发布后,当其他进程(其他机器)没有相关订阅者时,只会在内存中传递事件给当前进程的相关订阅者。所以,可以将该通讯方式当作 guava EventBus 来使用。
订阅者 - 示例
flowContext.fire(yourEventMessage);
,fire 是发布事件的方法,当事件发布后,下面中的订阅者会接收到事件源。
用户逻辑服的订阅者
public class UserEventBusSubscriber {
@EventSubscribe
public void userLogin(YourEventMessage message) {
log.info("event - 玩家[{}]登录,记录登录时间", message.getUserId());
}
}
邮件逻辑服的订阅者
public class EmailEventBusSubscriber {
@EventSubscribe
public void mail(YourEventMessage message) {
long userId = message.getUserId();
log.info("event - 玩家[{}]登录,发放 email 奖励", userId);
}
}
文档 - 分布式事件总线 (yuque.com)