public class UserEvent {
int userId;
long loginTime;
long jobId;
long jobAttachTime;
long jobdetachTime;
long workTime;
long logoutTime;
long activeTime;
EventType eventType;
}
我有一个应用程序,该应用程序根据登录,作业附加,作业分离和注销等用户操作在Kafka主题上发送事件。
每个事件在UserEvent
对象以及userId
和eventType
中都有一些信息,
例如,登录事件具有loginTime
;
作业附加事件具有属性jobId
,jobAttachTime
。
同样,注销事件具有属性logoutTime
。
我的要求是在收到每个用户的注销事件后,将所有这些事件的信息汇总到一个对象中。
因此,在登出事件之后, UserEvent 对象将具有loginTime
,logoutTime
,计算得出的workTime
,activeTime
等等
Kafka KStreams和/或KTables 如何实现?
答案 0 :(得分:1)
为了聚合UserEvent,您需要一个键(例如:session id)来过滤所有事件中通用的会话。假设您为每个用户事件附加了sessionID,该ID对于每个会话都是唯一的,但对于在该会话期间发生的所有用户事件来说,都是相同的。
可以使用GroupBy().aggregate()
通过以下方式实现:(考虑到您具有与会话ID等效的属性,该属性可以唯一地用作键)
// Let's say there is a sessionID
KTable<String, UserEvent> userEventSummary = userEvents
.groupBy(event -> event.get("sessionId"))
.aggregate((userEventSummary,userEvent)->{
userEventSummary = userEvent;
if(new!= null){
String loginEvent = new.get("eventType").get("eventName");
if(loginEvent.equals("login")){
userEventSummary.setLoginTime(new.getLoginTime());
}
if(loginEvent.equals("logOut")){
long workTime = Math.abs(userEvent.getLogOutTime()-userEventSummary.getLoginTime());
userEventSummary.setWorkTime(workTime);
userEventSummary.setActiveTime(workTime);
}
}
return userEventSummary;
});
// if default value for logoutTime is 0, filter the user events which don't have logout time yet
KTable<String, UserEvent> loggedOutEventSummary = userEventSummary.filter(event-> event.getLogOutTime()!= 0);
它将为通过具有注销事件的用户事件过滤的每个用户操作返回汇总状态。
答案 1 :(得分:0)
final KStream<Integer, UserEvent> kStream = builder.stream("test-topic");
kStream.groupByKey().aggregate(() -> new UserEvent(),
(Integer userId, UserEvent userEvent, UserEvent userEventSummary) -> {
if (userEvent.getEventType().equals(EventType.LOGIN)) {
// Event Processing logic for Login event
} else if (userEvent.getEventType().equals(EventType.LOGOUT)) {
// Event Processing logic for Logout event
}
return userEventSummary;
});