-1

假设有一个系统在发生某些事情时会填充数据库中的行:

  • 当用户简单地登录时,会在数据库中插入一行,其中登录类型和时间在表中user_logins
  • 当操作员向用户拨打电话时,在表中的数据库中插入带有操作员 ID、用户 ID 和日期的行outgoing_calls
  • 当操作员不接听用户呼叫时,将带有日期、用户 ID 和呼叫类型的行插入到数据库中

然后在某个时间段结束后,比如一个月,我们需要一个关于谁打电话给谁,多少电话没有接听等的报告。应该使用什么模式来组织这个功能?

乍一看,这个过程似乎记录了很多,但记录是我们以某种格式(date-processId-messageWithPlaceHolders)存储消息时的过程。因此,为此使用日志系统不是很合适。

从另一个角度来看,它看起来像事件处理,但是当“事件”发生时不需要做任何动作,没有监听器,没有队列。只需存储到数据库以供进一步报告。

那么应该使用什么模式或技术来有效地实现这个功能呢?

4

2 回答 2

1

您的要求是每月生成一份谁呼叫谁的报告,以便您可以了解您的呼叫是否成功(或任何原因)。

您无需考虑与日志记录或事件处理或任何东西的相似性。只需从上到下分析问题,即可完成任务所需的最少工作量:

  • 您需要每月生成一份报告
  • 为此,您需要运行一个至少每月生成一次结果的作业
  • 为此,您需要以您的工作可以理解的格式存储您的事件。

所以一个好的解决方案是每月运行一个批处理作业。这可以是手动运行的 java 进程、cron 作业、hadoop 任务……取决于您的技术堆栈。您的事件需要在它们发生时存储。同样,根据您的堆栈,它可以是关系数据库、键值存储、带有日志行的文件......,任何在您的技术堆栈中最容易使用的东西。

所有这些选项都可以是好的,但有些可能更好。例如,我建议不要使用纯字符串日志记录。您需要提取时间、数字等结构化属性,因此更喜欢一种有助于保持类型安全的格式。

于 2016-05-01T13:22:12.687 回答
0

我会使用 just-implement-it-in-your-business-service 模式:

void login(User user) {
    entityManager.persist(new UserLogin(user));
}

void call(Operator op, User user) {
    entityManager.persist(new PhoneCall(op, user));
}

void missedCall(User user, Operator op) {
    entityManager.persist(new MissedCall(user, op));
}

这是假设您的业务服务在未接电话时收到通知。如果仅仅没有答案就应该触发数据库更新,我会改变逻辑并记录成功的答案:

void answeredCall(UserCall call, Operator op) {
    entityManager.merge(call).setAnsweredBy(op);
}

并报告电话在哪里call.answeredBy is null

无论哪种情况,我都会通过查询数据库来进行报告。

选择

如果您的业务服务中的大多数操作都需要如此记录,我可能会使用 AOP 拦截器自动执行此操作。

于 2016-05-01T13:22:44.100 回答