Replies: 3 comments
-
使用场景在上面用了图文的方式来描述脉冲通讯这个术语,相信你对这个术语有一定的了解了。下面让我们进入一个业务场景,来说明脉冲通讯是如何解决的。 业务需求描述假设我们有这么一种业务场景,每隔一段时间需要将当前每个游戏对外服在线的玩家数量的数据给到数据收集服务器。 对于这种需求,我们可以用不同的方式来实现,这里介绍这么几种方式,分别是:
http 的实现方式在游戏对外服增加一个定时器,周期性的将当前最新数据上传到指定的 URL 。(这个 URL 是数据收集服务器提供的一个 http 服务)。 redis 发布订阅的实现方式在游戏对外服增加一个定时器,周期性的将当前最新数据用事件发布;游戏服务器作为发布者,数据收集服务器作为订阅者。这种实现方式还需要安装一个中间件来支持。 引发的问题我们先来两种假设,分别是:
让我们来看一下,这两个实现方式是如何应对这两个假设的。
我们可以发现,当数据收集服务器宕机时,无论是采用 HTTP 传输还是使用 Redis 进行传输,都会触发数据上报操作,而不关心对方是否还活着。当业务不需要时,这两种方式都需要移除相关的代码,否则会一直执行相关业务,且一旦业务代码有变动,就会出现风险。 这两种方式将会一直占用机器资源,会不断地上报数据,而不考虑对方是否存活、存在或能否消费。 为了解决这些问题,我们可以使用脉冲通讯。脉冲通讯可以解决上述问题,可以避免不必要的数据上报操作,从而减少资源消耗。 脉冲通讯的实现方式数据收集服务器作为【脉冲生产者】发送一个脉冲信号请求,而游戏对外服作为一个【脉冲消费者】接收到脉冲信号请求后,开始收集在线玩家的数据,并将这些收集的数据响应给脉冲请求者(也就是脉冲生产者)。 使用脉冲的优势在于:
|
Beta Was this translation helpful? Give feedback.
-
示例代码游戏对外服相关代码在游戏对外服增加一个脉冲消费者,用于获取当前在线玩家的数据 // 脉冲消费者
public class ExternalPulseConsumer implements PulseConsumer<ExternalPulseMessage> {
@Override
public String channel() {
// 脉冲频道
return "EXTERNAL_ONLINE_CHANNEL";
}
@Override
public Serializable accept(ExternalPulseMessage externalPulseMessage, PulseSignalRequest request) {
// 得到在线玩家数量
int online = ...;
ExternalPulseMessage message = new ExternalPulseMessage();
message.online = online;
return message;
}
}
// 数据载体
@FieldDefaults(level = AccessLevel.PUBLIC)
public class ExternalPulseMessage implements Serializable {
@Serial
private static final long serialVersionUID = -6577839933796123088L;
long online;
}
// Runner 机制
public class ExternalPulseRunner implements PulseRunner {
@Override
public void onStart(PulseProducers pulseProducers, PulseConsumers pulseConsumers) {
// 将 ExternalPulseConsumer 添加到脉冲消费者管理器中
pulseConsumers.addPulseConsumer(new ExternalPulseConsumer());
}
}
// 游戏对外服
public class MyExternalServer extends ExternalBrokerClientStartup {
@Override
public BarSkeleton createBarSkeleton() {
// 游戏对外服不需要业务框架,这里给个空的
BarSkeletonBuilder builder = BarSkeleton.newBuilder();
// 使用 Runner 机制来扩展,添加脉冲相关的
builder.addRunner(new ExternalPulseRunner());
return builder.build();
}
} 数据收集服务器相关代码在数据收集服务器增加一个脉冲生产者,用于请求游戏对外服; // 脉冲生产者
@Slf4j
class ExternalPulseProducer implements PulseProducer<ExternalPulseMessage> {
@Override
public String channel() {
// 脉冲频道
return "EXTERNAL_ONLINE_CHANNEL";
}
@Override
public PulseSignalRequest createMessage() {
// 脉冲信号请求
PulseSignalRequest request = new PulseSignalRequest();
/*
* 添加信号类型:游戏对外服。
* 也就是说,这个脉冲信号只会在游戏对外服接收。
*
* 如果想在游戏逻辑服、Broker(游戏网关)也触发,可以参考下面的代码。
*
*/
request.addSignalType(SignalType.external);
// 让脉冲信号在游戏逻辑服也能触发
// request.addSignalType(SignalType.logic);
// 让脉冲信号在 Broker(游戏网关)也能触发
// request.addSignalType(SignalType.broker);
return request;
}
@Override
public void accept(ExternalPulseMessage message, PulseSignalResponse response) {
/*
* 接收脉冲信号响应,由脉冲消费者响应的数据。
*
* 注意:如果有 N 台游戏对外服,那么这个方法将会调用 N 次。
*/
log.info("message : {} {}", message.online, response);
}
@Override
public int period() {
// 每隔 60 秒,会触发一次脉冲信号请求。
return 60;
}
}
// Runner 机制
public class DataPulseRunner implements PulseRunner {
@Override
public void onStart(PulseProducers pulseProducers, PulseConsumers pulseConsumers) {
// 将 ExternalPulseProducer 添加到脉冲生产者管理器中
pulseProducers.addPulseProducer(new ExternalPulseProducer());
}
}
// 数据收集逻辑服
public class DataLogicServer extends AbstractBrokerClientStartup {
@Override
public BarSkeleton createBarSkeleton() {
// 业务框架构建器 配置
var config = new BarSkeletonBuilderParamConfig();
// 业务框架构建器
var builder = config.createBuilder();
// 使用 Runner 机制来扩展,添加脉冲相关的
builder.addRunner(new DataPulseRunner());
return builder.build();
}
@Override
public BrokerClientBuilder createBrokerClientBuilder() {
BrokerClientBuilder builder = BrokerClient.newBuilder();
builder.appName("数据收集逻辑服");
return builder;
}
} 示例小结由于上面是完整的代码,实际上核心使用代码只有3个类,分别是:
|
Beta Was this translation helpful? Give feedback.
-
小结通过介绍,我们知道了脉冲通讯术语的解释,脉冲特性、使用场景、优势等。 我们通过一个示例,知道了脉冲通讯在特定的场景下有巨大的优势!关于脉冲通讯更多的应用场景发挥,如同业务框架插件一样,取决于开发者的想象力。
|
Beta Was this translation helpful? Give feedback.
-
在线文档 https://www.yuque.com/iohao/game/zgaldoxz6zgg0tgn
脉冲通讯方式简介
脉冲通讯与发布订阅类似,但是它除了具备发布订阅的无需反馈的方式,还增加了接收消息响应的动作,这是它与发布订阅的重要区别。
需要注意的是,脉冲通讯只是一种通讯方式,不能完全取代发布订阅,而是适用于一些特殊的业务场景。虽然在理论上,这些特殊的业务场景可以使用发布订阅来完成,但这会让代码变得复杂。
脉冲通讯简图
脉冲与发布订阅类似,但与其不同的是,脉冲具备接收消息响应动作的功能。当脉冲生产者发送【脉冲信号请求】时,脉冲消费者接收该请求并执行相应方法后,会向脉冲生产者发送【脉冲信号响应】。这使得脉冲在功能上与发布订阅有所区别。
如果用一句话来描述脉冲通讯,那么就是:
比发布订阅多了响应消息。
功能对比
脉冲通讯与发布订阅的功能对比。
Beta Was this translation helpful? Give feedback.
All reactions