Redis 消息队列中的异步场景封装

Redis 消息队列中的异步场景封装

场景样式:
积分服务和短信服务订阅消息队列,消息队列推送消息到积分服务,短信服务,这样创建订完单响应给客户端只需要花费1s,但是又不会影响订单服务的并发量。
在这里插入图片描述
准备工作:
安装windows下的redis.
在项目中添加引用服务:ServiceStack.Redis

1.创建一个项目:MyRedis
1.1创建一个异步的类:RmOrder来进行订单积分和短信发送


```csharp
using MyRedis.MQ;
using System;
using System.Collections.Generic;
using System.Data.Odbc;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MyRedis.Async
{
    class RmOrder
    {
        public string CreateOrder()
        {
            //统计时间
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            //1.订单生成
            string order_sn = this.OrderGenrator();

            //1.1存储到数据库
            Thread.Sleep(1000);
            Console.WriteLine($"订单:{order_sn}保存成功");

            2.添加积分
            //Console.WriteLine($"*********************开始调用积分服务*********************");
            //RmOrderPoints rmOrderPoints = new RmOrderPoints();
            //rmOrderPoints.AddPoints(order_sn);
            //Console.WriteLine($"*********************积分服务调用完成*********************");

            3.发送短信
            //Console.WriteLine($"*********************开始调用短信服务*********************");
            //RmOrderSms rmOrderSms = new RmOrderSms();
            //rmOrderSms.SendSms(order_sn);
            //Console.WriteLine($"*********************短信服务调用完成*********************");

            //redis 优化
            using (var messageQueue = new RedisMessageQueue("localhost:6379"))
            {
                //1.发送积分消息
                messageQueue.EnQueue("rm_points",order_sn);

                //2.发送短信信息
                messageQueue.EnQueue("rm_sms", order_sn);
            }
                

            stopwatch.Stop();
            Console.WriteLine($"订单完成耗时:{stopwatch.ElapsedMilliseconds} ms");
            return order_sn;
        }

        /// <summary>
        /// 订单生成器
        /// </summary>
        /// <returns></returns>
        private string OrderGenrator()
        {
            Random random = new Random();
            return "R" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + random.Next(1000,9999).ToString();
        }
    }
}


1.2创建一个类:RedisMessageQueue来封装Redis的消息队列,继承IDisposable

```csharp
using ServiceStack.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyRedis.MQ
{
    class RedisMessageQueue : IDisposable
    {
        /// <summary>
        /// redis客户端
        /// </summary>
        public RedisClient redisClient { get; }

        public RedisMessageQueue(string redisHost)
        {
            redisClient = new RedisClient(redisHost);
        }

        /// <summary>
        /// 入队
        /// </summary>
        /// <param name="QKey">入队Key</param>
        /// <param name="QMessage">入队消息</param>
        /// <returns></returns>
        public long EnQueue(string QKey, string QMessage)
        {
            //1.编码字符
            byte[] bytes = Encoding.UTF8.GetBytes(QMessage);

            //2.redis消息队列入队
            long count = redisClient.LPush(QKey, bytes);

            return count;
        }

        /// <summary>
        /// 出队(非阻塞)==拉
        /// </summary>
        /// <param name="QKey">入队Key</param>
        /// <returns></returns>
        public string DeQueue(string QKey)
        {
            //1.redis 消息出队
            byte[] bytes = redisClient.RPop(QKey);
            string Qmessage = null;

            //2.字节转string
            if (bytes == null)
            {
                Console.WriteLine("队列中数据为空");
            }
            else {
                Qmessage = Encoding.UTF8.GetString(bytes);
            }

            return Qmessage;
        }

        /// <summary>
        /// 出队(阻塞)==推,数据实时性高
        /// </summary>
        /// <param name="QKey">入队Key</param>
        /// <param name="timespan">阻塞超时时间</param>
        /// <returns></returns>
        public string BDeQueue(string QKey,TimeSpan? timespan)
        {
            //1.redis 消息出队
            string Qmessage = redisClient.BlockingDequeueItemFromList(QKey, timespan);
            return Qmessage;
        }

        /// <summary>
        /// 获取队列数量
        /// </summary>
        /// <param name="QKey">队列Key</param>
        /// <returns></returns>
        public long GetQueueCount(string QKey)
        {
            return redisClient.GetListCount(QKey);
        }

        public void Dispose()
        {
            //1.关闭redis
            redisClient.Dispose();
        }
    }
}

2.添加一个新建项:MyRedisRmPoints 根据订单增加积分以及反馈积分消息
2.1.添加类 RmOrderPoints

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MyRedisRmPoints.Async
{
    class RmOrderPoints
    {
        /// <summary>
        /// 根据订单增加积分
        /// </summary>
        /// <param name="order_sn"></param>
        public void AddPoints(string order_sn)
        {
            //1.调用积分服务
            Thread.Sleep(1000);

            //2.发送积分成功
            Console.WriteLine($"增加积分:order_sn:{order_sn} 成功");
        }
    }
}

2.1.在program里面进行积分消息的优化

using MyRedisRmPoints.Async;
using MyRedisRmPoints.MQ;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyRedisRmPoints
{
    class Program
    {
        static void Main(string[] args)
        {
            //redis 优化
            using (var messageQueue = new RedisMessageQueue("localhost:6379"))
            {
                Console.WriteLine("积分消息......");
                //1.获取积分消息
                while (true)
                {
                    string rm_points = messageQueue.BDeQueue("rm_points", TimeSpan.FromSeconds(60));

                    //2.消费积分消息
                    RmOrderPoints rmOrderPoints = new RmOrderPoints();
                    rmOrderPoints.AddPoints(rm_points);
                }                
            }
        }
    }
}

3.添加一个新建项:MyRedisRmSms 根据订单发送短信以及反馈短信发送状态
2.1.添加类 RmOrderSms

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MyRedisRmSms.Async
{
    class RmOrderSms
    {
        /// <summary>
        /// 根据订单发送短信
        /// </summary>
        /// <param name="order_sn"></param>
        public void SendSms(string order_sn)
        {
            //1.调用第三方短信接口
            Thread.Sleep(1000);

            //2.发送短信成功
            Console.WriteLine($"发送短信:order_sn:{order_sn} 成功");
        }
    }
}

2.2.在program里面进行发送短信的优化

using MyRedisRmSms.Async;
using MyRedisRmSms.MQ;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyRedisRmSms
{
    class Program
    {
        static void Main(string[] args)
        {
            //redis 优化
            using (var messageQueue = new RedisMessageQueue("localhost:6379"))
            {
                Console.WriteLine("短信消息......");
                //1.获取短信消息
                while (true)
                {
                    string rm_sms = messageQueue.BDeQueue("rm_sms", TimeSpan.FromSeconds(60));

                    //2.消费短信消息
                    RmOrderSms rmOrderSms = new RmOrderSms();
                    rmOrderSms.SendSms(rm_sms);
                }
            }
        }
    }
}

4.在MyRedis项目里的program中完成对订单的异步调用服务、

RmOrder rmOrder = new RmOrder();
rmOrder.CreateOrder();

5.重新生成各个项目,在资源文件夹之中找到对应的Dubug目录,进行服务调用
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值