本文共 3959 字,大约阅读时间需要 13 分钟。
在用户绑定手机号注册并补充个人信息后,通过会员生日信息进行营销是非常有价值的。然而,这一过程需要定时任务来推送营销信息,这在微服务架构下如何实现是一个值得深入探讨的问题。本文将从定时任务的选型、构建以及实际应用三个方面,带你一起解决这一问题。
选择适合的定时任务框架对于实现分布式定时任务至关重要。常见的解决方案主要有以下几种:
考虑到项目复杂度和分布式需求,本次选择基于注解的@EnableScheduling方案。
在Spring Boot项目中,添加定时任务支持非常简单。以下是基本实现步骤:
添加定时任务启动类
@SpringBootApplication@EnableSchedulingpublic class ParkingScheduleJobApplication { public static void main(String[] args) { SpringApplication.run(ParkingScheduleJobApplication.class, args); }}新增任务执行类
@Component@Logpublic class UserBirthdayBasedPushTask { @Scheduled(cron = "0/5 * * * * ?") public void scheduledTask() { log.info("Task running at = " + LocalDateTime.now()); }}处理多实例任务问题
在多实例环境下,同一时间只能有一个实例执行任务。为此,我们需要结合ShedLock框架实现任务锁。在分布式环境下,保证同一时间只有一个实例执行任务至关重要。通过ShedLock框架,我们可以通过数据库锁机制实现这一点。
引入ShedLock依赖
net.javacrumbs.shedlock shedlock-core 4.5.0 net.javacrumbs.shedlock shedlock-spring 4.5.0 net.javacrumbs.shedlock shedlock-provider-jdbc-template 4.5.0
修改启动类
@SpringBootApplication@EnableScheduling@EnableSchedulerLock(defaultLockAtMostFor = "30s")public class ParkingScheduleJobApplication { public static void main(String[] args) { SpringApplication.run(ParkingScheduleJobApplication.class, args); } @Bean public LockProvider lockProvider(DataSource dataSource) { return new JdbcTemplateLockProvider(dataSource); }}任务执行类中添加锁注解
@Component@Log@SchedulerLock(name = "scheduledTaskName")public class UserBirthdayBasedPushTask { @Autowired private MemberServiceClient memberService; @Scheduled(cron = "0/5 * * * * ?") public void scheduledTask() { try { List members = memberService.list(); for (Member member : members) { if (member.getBirth().equals(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))) { log.info("send sms to " + member.getPhone()); } } } catch (BusinessException e) { log.error("catch exception " + e.getMessage()); } log.info("Task running at = " + LocalDateTime.now()); }} 在完成基本框架后,我们需要实现会员生日信息推送营销短信的功能。为此,我们需要:
定义接口
@FeignClient(value = "member-service", fallback = MemberServiceFallback.class)public interface MemberServiceClient { @RequestMapping(value = "/member/list", method = RequestMethod.POST) public String list() throws BusinessException;}实现业务逻辑
@Component@Logpublic class UserBirthdayBasedPushTask { @Autowired private MemberServiceClient memberService; @Scheduled(cron = "0/5 * * * * ?") @SchedulerLock(name = "scheduledTaskName") public void scheduledTask() { try { String members = memberService.list(); List array = JSONArray.parseArray(members, Member.class); DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime time = LocalDateTime.now(); String curTime = df.format(time); for (Member one : array) { if (curTime.equals(one.getBirth())) { log.info("send sms to " + one.getPhone()); } } } catch (BusinessException e) { log.error("catch exception " + e.getMessage()); } log.info("Task running at = " + LocalDateTime.now()); }} 通过以上步骤,我们成功实现了会员生日信息推送营销短信的功能。在实际应用中,建议根据具体需求调整定时任务的执行频率,并注意数据库锁机制的配置,以确保任务的唯一性和高效性。
转载地址:http://wlhfk.baihongyu.com/