一  定时任务基础:

MQ:Message Queue
消息队列服务器:MSMQ、ActiveMQ、Redis等
项目任务:确定邮件的发送,重置密码的发送(发送可能会很慢,而且有可能还需要重试),用消息队列把注册过程和邮件发送过程分开

二  示例:

//testMessageQueue.csProj

namespace testMessageQueue
{
class Program
{
static void Main(string[] args)
{
/*
while(true)
{
string email=Console.ReadLine();
using(IRedisClient client=RedisManager.ClientManager.GetClient())
{
client.EnqueueItemOnList("TestEmail", email);
}
}
*/ using(IRedisClient client=RedisManager.ClientManager.GetClient())
{
while(true)
{
string email = client.DequeueItemFromList("TestEmail");
if(email==null)
{
Console.WriteLine("等待输入");
Thread.Sleep();
continue;
}
Console.WriteLine("发送邮箱:eamil=" + email);
}
} Console.ReadKey();
}
} public class RedisManager
{
public static PooledRedisClientManager ClientManager { get; private set; } //内部可写,外部只能读
static RedisManager()
{
RedisClientManagerConfig redisConfig = new RedisClientManagerConfig();
redisConfig.MaxWritePoolSize = ;
redisConfig.MaxReadPoolSize = ;
ClientManager = new PooledRedisClientManager(new string[] { "127.0.0.1" }, new string[] { "127.0.0.1" }, redisConfig); //在哪几个ip上进行集群的读写分离操作 }
}
}

testMessageQueue.csProj

三  定时任务框架:

//testQuartz.csProj

namespace testQuartz
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} /// <summary>
/// 定时任务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnQuartz_Click(object sender, EventArgs e)
{
//每隔一段时间执行一个任务
ISchedulerFactory sf = new StdSchedulerFactory();
IScheduler sched = sf.GetScheduler(); //获得一个计划任务
JobDetail job = new JobDetail("job1", "group1", typeof(MyJog)); ////MyJog为实现了IJob接口的类
DateTime dt = TriggerUtils.GetNextGivenSecondDate(null, ); //5秒后开始第一次运行
TimeSpan interval = TimeSpan.FromSeconds(); //时间段--每隔5s执行一次
//每若干小时运行一次,小时间隔由appsettings中的IndexIntervalHour参数指定
Trigger trigger = new SimpleTrigger("trigger1", "group1", "job1", "group1", dt, null, SimpleTrigger.RepeatIndefinitely, interval);
sched.AddJob(job, true);
sched.ScheduleJob(trigger);
sched.Start();
} }
class MyJog : IJob
{
public void Execute(JobExecutionContext context)
{
MessageBox.Show("我执行了l");
}
}
}

四  实例:

(1)原理:

Quartz.Net实现:每10分钟定时发送系统数据:新增用户数据
每次用户注册的时候,都把用户的注册信息:用户名、邮箱、手机号等.除了正常的注册之外,额外再把这些数据放入消息队列。
每隔5分钟,定时从消息队列中取出新注册用户信息,然后发送邮件给业务人员.
SendNewRegUserEmailJob.cs
1 直接Global不行: RupengTimer类库 //如鹏定时任务类库(因为在Global中进行会有兼容性问题)
2 Console控制台程序也不可以: Application.Run(new FormMain()); //加载WinForm时直接启动WinForm程序,因为上面是在WinForm中测试成功的
3 WinForm中执行定时任务还是不行: 因为时间(与世界标准时间是差8h) ---革零为致时间与北京(东八区)时间差8h
DateTime.Now 应该是: DateTime dt = TriggerUtils.GetNextGivenSecondDate(null, 1);

(2)逻辑:

每10分钟定时发送系统数据:新增用户数据

1 当用户邮箱被激活,更新激活状态后,获得用户数据
2 拼接用户数据的字符串 (用户名、邮箱、手机号)
3 把这个字符串 入队列集合 (Redis_Front_QueueList_AddUser)

4 执行定时任务框架 (单独RupengTimer类库与进程中,Global中有兼容性问题)
5 执行出队列任务,获得字符串
6 如果字符串不为null或长度大于0,发送邮件

(3)步骤:

//入队列 (把新增用户信息入队列)

        /// <summary>
/// 入队列:用于存储新增用户,出队列时发送给指定邮箱
/// </summary>
/// <param name="context"></param>
/// <param name="username">用户名</param>
public static void RedisEnqueueForUserRegister(HttpContext context, string username)
{
#region 逻辑
//1 当用户邮箱被激活,更新激活状态后,获得用户数据
//2 拼接用户数据的字符串 (用户名、邮箱、手机号)
//3 把这个字符串 入队列集合 (Redis_Front_QueueList_AddUser)
#endregion
#region 获得用户数据
object obj = new MyORM_BLL().SelectModelByUserName(typeof(TD_USER), , "T", username);
if (obj == null)
{
RazorHelper.RazorParse(context, "~/error.cshtml", new { Msg = "数据库错误,未找到该激活用户 username=" + username });
context.Response.End();
}
TD_USER user = obj as TD_USER;
#endregion
StringBuilder sb = new StringBuilder();
#region 拼接用户数据的字符串
sb.Append("用户名:" + user.USERNAME + "|");
sb.Append("姓名:" + user.REALNAME + "|");
sb.Append("手机:" + user.MOBILE + "|");
sb.AppendLine("邮箱:" + user.EMAIL + "|");
#endregion
using(IRedisClient client=RedisManager.ClientManager.GetClient())
{
client.EnqueueItemOnList(ConstStringHelper.REDIS_FRONT_QUEUELIST_ADDUSER, sb.ToString());
}
}

LoginHelper.RedisEnqueueForUserRegister()

//窗体加载,就执行定时任务

namespace DIDAO.TimerForm
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
} /// <summary>
/// 窗体一加载,就执行定时任务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormMain_Load(object sender, EventArgs e)
{
Timer.TimeSchedule.TimeExecuteSchedule(typeof(SendEmailForAddUser), "triggerAddUser", "groupAddUser", "jobAddUser"); }
}

TimerForm.FormMain.Load()

//定时任务

namespace DIDAO.Timer
{
/// <summary>
/// 定时任务
/// </summary>
public class TimeSchedule
{
/// <summary>
/// 执行定时任务(用于类型type中的任务)
/// </summary>
public static void TimeExecuteSchedule(Type type, string triggerName, string groupName, string jobName)
{
//每隔一段时间执行一个任务
ISchedulerFactory sf = new StdSchedulerFactory();
IScheduler sched = sf.GetScheduler(); //获得一个计划任务
JobDetail job = new JobDetail(jobName, groupName, type); ////MyJog为实现了IJob接口的类
//DateTime dt = TriggerUtils.GetNextGivenSecondDate(null, 5); //5秒后开始第一次运行
//DateTime dt = DateTime.Now; //立即执行
DateTime dt = TriggerUtils.GetNextGivenSecondDate(null, ); //1s后开始执行
TimeSpan interval = TimeSpan.FromMinutes(); //时间段--每隔60s执行一次
//每若干小时运行一次,小时间隔由appsettings中的IndexIntervalHour参数指定
Trigger trigger = new SimpleTrigger(triggerName, groupName, jobName, groupName, dt, null, SimpleTrigger.RepeatIndefinitely, interval);
sched.AddJob(job, true);
sched.ScheduleJob(trigger);
sched.Start();
}
}

Timer.TimeSchedule.cs

//出队列 发送邮件(新注册用户信息)

namespace DIDAO.Timer
{
public class SendEmailForAddUser:IJob
{
/// <summary>
/// 接收方邮件地址(发送 新用户注册信息时)
/// </summary>
private string receiveEmailAddress = ConfigurationManager.AppSettings["receiveEmailAddress"]; //发送方邮箱地址 /// <summary>
/// 出队列 发送新注册用户信息
/// </summary>
/// <param name="context"></param>
public void Execute(JobExecutionContext context)
{
#region 逻辑
//4 执行定时任务框架 (单独RupengTimer类库与进程中,Global中有兼容性问题)
//5 执行出队列任务,获得字符串
//6 如果字符串不为null或长度大于0,发送邮件
#endregion
using(IRedisClient client=RedisManager.ClientManager.GetClient())
{
StringBuilder sb = new StringBuilder();
while(true)
{
string item = client.DequeueItemFromList(ConstStringHelper.REDIS_FRONT_QUEUELIST_ADDUSER);
if (item == null)
{
if(sb==null || sb.Length<=)
{
return; //执行下一次定时任务
}
//发送邮件
SendEmailHelper.SendMail(receiveEmailAddress, "DIDAO邮件:新用户注册信息", sb.ToString());
sb.Clear();
}
else
{
sb.AppendLine(item);
}
}
} }
}
}

Timer.SendEmailForAddUser:IJob

Quartz 定时任务(含Redis)的更多相关文章

  1. springboot集成shiro集成mybatis-plus、redis、quartz定时任务

    完整项目代码位于码云上,点击获取:Git地址 主要介绍一下重点配置地方: 一.application.yml文件 server: port: 8084 servlet: context-path: / ...

  2. Quartz定时任务学习(二)web应用/Quartz定时任务学习(三)属性文件和jar

    web中使用Quartz 1.首先在web.xml文件中加入 如下内容(根据自己情况设定) 在web.xml中添加QuartzInitializerServlet,Quartz为能够在web应用中使用 ...

  3. quartz定时任务框架的使用

    quartz定时任务时间设置 这些星号由左到右按顺序代表 :     *    *     *     *    *     *   *                                 ...

  4. Quartz定时任务学习(二)web应用

    web中使用Quartz 1.首先在web.xml文件中加入 如下内容(根据自己情况设定) 在web.xml中添加QuartzInitializerServlet,Quartz为能够在web应用中使用 ...

  5. Quartz定时任务使用小记(11月22日)

    骤然接触quartz,先从小处着手,why,what,how quartz定时任务: 为什么使用quartz定时任务,以及定时任务在实际应用场景下的特定需求. 1.用户方面的需要,为了提供更好的使用体 ...

  6. quartz定时任务时间配置

    quartz定时任务时间设置描述(2011-03-03 16:23:50)转载▼标签: quartz时间it 分类: 凌乱小记  这些星号由左到右按顺序代表 :     *    *     *    ...

  7. 对quartz定时任务的初步认识

    已经好久没有写技术博文了,今天就谈一谈我前两天自学的quartz定时任务吧,我对quartz定时任务的理解,就是可以设定一个时间,然后呢,在这个时间到的时候,去执行业务逻辑,这是我的简单理解,接下来看 ...

  8. Spring整合Quartz定时任务执行2次,Spring定时任务执行2次

    Spring整合Quartz定时任务执行2次,Spring定时任务执行2次 >>>>>>>>>>>>>>>&g ...

  9. Quartz 定时任务时间设置

    转自https://blog.csdn.net/zdx1515888659/article/details/79158169 quartz定时任务时间设置: 这些星号由左到右按顺序代表 : * * * ...

  10. quartz定时任务及时间设置

    quartz 定时任务时间设置1.这些星号由左到右按顺序代表 :     *    *     *     *    *     *   *                               ...

随机推荐

  1. CentOS 6.5下Redmine的安装配置

    首先引用百度介绍下redmine: Redmine是用Ruby开发的基于web的项目管理软件,是用ROR框架开发的一套跨平台项目管理系统,据说是源于Basecamp的ror版而来,支持多种数据库,有不 ...

  2. MySQL数据库基本操作(四)

    在进行查询之前,我们要先建好关系表,并往数据表中插入些数据.为查询操作做好准备. 五张关系表的创建: #创建并进入数据库: mysql> CREATE DATABASE `info`; Quer ...

  3. java.lang.ClassFormatError Duplicate field name&signature in class file XXXXXX【转】

    本文转载自:https://blog.csdn.net/ylchou/article/details/7739742 2012-7-5 15:06:25org.apache.catalina.core ...

  4. js学习笔记1(变量、作用域、内存)

    写在前面,舍弃叽叽歪歪,只做学习笔记,认真踏实. 学习书籍:javascript高级程序设计3版. 章节4.1 基本类型和引用类型 1.基本类型在内存中占据固定大小的空间,所以保存在栈内存中. 2.从 ...

  5. SQL题

    1.取出sql表中第31到40的记录(以自动增长ID为主键) sql server方案: select top 10 * from t where id not in (select top 30 i ...

  6. 手动用maven安装jar的命令

    手动用maven安装jar的命令: mvn install:install-file -DgroupId=com.oracle.jdbc -DartifactId=ojdbc5 -Dversion=1 ...

  7. Exception in thread "main" java.util.concurrent.ExecutionException: org.apache.kafka.common.errors.TimeoutException: Expiring 1 record(s) for topic_test_1219-2: 30010 ms has passed since batch creatio

    代码如下 public static void producer1() throws ExecutionException, InterruptedException { Properties pro ...

  8. Flume具体应用(多案例)

    日志采集 对于flume的原理其实很容易理解,我们更应该掌握flume的具体使用方法,flume提供了大量内置的Source.Channel和Sink类型.而且不同类型的Source.Channel和 ...

  9. java——base64 加密和解密

    base64 一.加密 *.若有要求输入字符必须为UTF-8: 则需str.getByte("utf-8");  //在getByte()中指定utf-8编码,否则中文字符将被加密 ...

  10. HRBUST 2072 树上求最大异或路径值

    一个很经典的套路 思想是 F [u,v] = F[1,u] ^ F[1,v] 这样就转化成了n个数两两异或 求最大值 可以用字典树来做 每次用当前数去树中寻求最大xor值 然后把这个数字插进去 就相当 ...