Scenario

  1. create event
  2. invite user
  3. notify users at specific time
  4. notify user periodically

Service

  1. User Service. 负责管理用户数据。
  2. Event Service. 负责管理用户创建的 Events
  3. Notification Service。负责notify用户某个 event 到了

Storage

created_by (谁创建的)

strategy (一次性的,还是周期的。如果是周期的,那么周期的策略是什么.
每周,还是每周末,还是什么,可以用一个具体的结构化数据表示出来,并serialize成json之类的存起来)
next_notify_time(下一次什么时候提醒,注意这里是下一次什么时候提醒,而不是第一次什么时候提醒)
attendes: many to many 的 users(实际上会存成另外一张表,记录哪个用户参与了哪个event)

freq  *(

 ; either UNTIL or COUNT may appear in a 'recur',
 ; but UNTIL and COUNT MUST NOT occur in the same 'recur'

 ( ";" "UNTIL" "=" enddate ) /
 ( ";" "COUNT" "=" 1*DIGIT ) /

 ; the rest of these keywords are optional,
 ; but MUST NOT occur more than once

 ( ";" "INTERVAL" "=" 1*DIGIT )          /
 ( ";" "BYDAY" "=" bywdaylist )          /
 ( ";" "BYMONTHDAY" "=" bymodaylist )    /
 ( ";" "BYYEARDAY" "=" byyrdaylist )     /
 ( ";" "BYWEEKNO" "=" bywknolist )       /
 ( ";" "BYMONTH" "=" bymolist )          
 )

freq : 事件重复频率,有效值:DAILY(按天),WEEKLY(按周),MONTHLY(按月),YEARLY(按年)

  • UNTIL: 重复结束日期 格式:20130102T170000Z(2013-1-2 下午5点结束)
  • COUNT: 重复多少次后结束,该字段与UNTIL两者只有出现一次
  • INTERVAL: 事件重复的间隔,如按天重复时,INTERVAL=2,则表明每2天重复一次,默认值 为1
  • BYDAY: 表示一周的某一天,有效值:MO(周一),TU(周二),WE(周三),TH(周四),FR(周五),SA(周六),SU(周日) , 示例: BYDAY=MO,TH,SU 表示重复日期包括周一,周四,周日. 每个值前面可以用 ”+”, “-” 修饰,表示第几个和倒数第几个日子,如 BYDAY = 2MO 表示第2个星期一发生; BYDAY=MO,-1SU 表示每个星期一和最后一个星期日发生
  • BYMONTHDAY: 表示一月的第几天发生,有效值是 [1 ~ 31] 和 [-31 ~ -1] ,如: BYMONTHDAY=2,18 表示一月的第2天,第18天发生; BYMONTHDAY=-1 表示一月的最后一天
  • BYYEARDAY: 表示一年的第几天发生,有效值是 [1 ~ 366] 和 [-366 ~ -1], 如 BYYEARDAY=125 表示一年的第125年发生; BYYEARDAY=-1 表示一年的最后一天发生
  • BYWEEKNO: 表示一年的第几周发生, 有效值是 [1 ~ 53] 和 [-53 ~ -1], 如 BYWEEKNO=2,23 表示一年的第2周,第23周发生
  • BYMONTH: 表示一年中的第几个月发生, 有效值是 [1 ~ 12]

需要注意几点:

  • 如果各字段所设置的值是无效的,如 BYMONTHDAY=30 ,则会忽略该值
  • 如果某条事件的重复规则表达式缺少一些必要字段,如 YEARLY;BYMONTH=1 ,表示按年重复,每年的1月某日发生,现在缺少”日”字段,则从该事件的”开始日期”中获得

按天重复

目标: 按天重复, 且每3天重复一次

表达式: DAILY;INTERVAL=3


目标: 按天重复, 重复到今年结束

表达式: DAILY;UNTIL=20140101T000000Z


目标: 按天重复, 重复20次

表达式: DAILY;COUNT=20


按周重复

目标 : 每周二,周四,周日重复,每隔2周发生一次

表达式: WEEKLY;INTERVAL=2;BYDAY=TU,TH,SU


按年重复

目标 : 每年的七月,八月两月最后一天

表达式: YEARLY;BYMONTH=7,8;BYMONTHDAY=-1


父亲节

目标 : 每年六月的第三个星期日

表达式: YEARLY;BYMONTH=6;BYDAY=3SU


除夕

目标 : 农历每年的最后一天

表达式: YEARLY;BYMONTH=12;BYMONTHDAY=-1


感恩节

目标 : 每年11月的第四个星期四

表达式: YEARLY;BYMONTH=11;BYDAY=4TH


母亲节

目标 : 每年5月的第二个星期日

表达式: YEARLY;BYMONTH=5;BYDAY=2SU

  • nextOccurDate: 根据传入的时间计算出以该时间为起始值的下一次事件发生的时间

  • includes(theDay): 判断指定时间是否是该事件的发生时间点系列之一

主要难Scale 的是,如果是发邮件提醒的那种events,要从服务器端来处理。那么一个进程扫描整个数据库看看到时间的 events有哪些这个是很慢很慢的。所以需要多加机器,通过sharding分开处理。我的想法是按照 created_by 的 user_id 进行 sharding 来让 events存在不同的数据库里。然后弄若干个进程,每个进程负责一个 micro sharding (一个进程负责不了一整个数据库,所以可以按照 micro sharding 来分任务),然后每个进程 Regular 的扫描自己的 micro sharding 中到期的 events,然后创建提醒任务,丢给 MessageQueue。

results matching ""

    No results matching ""