前言
需求:Mongodb监控库的变更,同时根据变更类型,通过kafka将变更信息发送到某个topic。
实现
ReactiveMongo
流式处理。
public class ChangeStream implements CommandLineRunner{
@Autowired
ReactiveMongoTemplate reactiveMongoTemplate;
@Autowired
KafkaSendService kafkaSendService;
@Override
public void run(String... args) throw Exception{
Flux<ChangeStreamEvent<User>> changeStream = reactiveMongoTemplate
.changeStream("User",ChangeStreamOptions.empty(),User.class);
changeStream.filter(e->OperationType.INSERT==e.getOperationType)
.doOnNext(e->{
//Insert逻辑处理
})
}
}
问题:
项目中用到了普通mongodb,配置文件中配置集群、用户名、密码,密码采用密文,
但reactiveMongo读取时无法使用密文。
解决:
普通mongodb能够使用密文,是自定义了MongoConfig,config中定义了factory、
clent、converter、template。client中进行解密操作。
因此可以定义reactiveMongoConfig继承AbstractReactiveMongoConfiguration,
实现这些东西。
未测试证明该解决方法。
MessageListener
流式遇到问题后,使用普通方法实现。
//定义一个MessageListenerContainer
@Bean
MessageListenerContainer messageListenerContainer(MongoTemplate mongoTemplate){
Executor executor = Executors.newFixedThreadPool(5);
return new DefaultMessageListenerContainer(mongoTemplate,executor){
@Override
public boolean isAutoStartup(){
return true;
}
}
}
//定义一个MessageListener
public class MongoMessageListener implements MessageListener<ChangeStreamDocument<Document>,User>{
@Autowired
KafkaSendService kafkaSendService;
@Override
public void onMessage(Message<ChangeStreamDocument<Document>,User> message){
OperationType operationType = message.getRaw().getOperationType();
//根据操作类型进行不同处理
}
}
//配置注册Listener、启动
public class ChangeStream implements CommandLineRunner{
@Autowired
private MongoMessageListener mongoMessageListener;
@Autowired
private MessageListenerContainer messageListenerContainer;
@Override
public void run(String... args) throws Exception{
ChangeStreamRequest<User> request = ChangeStreamRequest.builder(mongoMessageListener)
.collection("User")
.filter(Aggregation.newAggregation(Aggregation.match(Criteria.where("operationType").in("insert","update","replace"))))
.build();
messageListenerContainer.register(request,User.class);
}
}