当前位置: 首页 > news >正文

.Net Redis的秒杀Dome和异步执行

1.先到官网下载Redis部署好 Redis 教程 | 菜鸟教程

2.创建一个上游业务项目(这里用控制台项目了,Framwork4.7.2)

NuGet包下载SerivceStack.Redis

 创建一个RedisMessgaeQueue(Redis连接帮助类)

using ServiceStack.Redis;
using System;

namespace RedisUP
{
    class RedisMessgaeQueue:IDisposable
    {
        private RedisClient redisClient { get; }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="redisHost"></param>
        public RedisMessgaeQueue(string redisHost)
        {
            redisClient = new RedisClient(redisHost);
        }
        /// <summary>
        /// 入队
        /// </summary>
        /// <param name="QKey"></param>
        /// <param name="QMessgae"></param>
        /// <returns></returns>
        public long EnQueue(string QKey,string QMessgae) {
            //1.编码字符串
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(QMessgae);
            //2.redis消息队列入队
            long count = redisClient.LPush(QKey, bytes);
            return count;
        }
        /// <summary>
        /// 出队(非阻塞)==拉
        /// </summary>
        /// <param name="QKey"></param>
        /// <returns></returns>
        public string DeQueue(string QKey)
        {
            //1.redis消息出队
            byte[] bytes = redisClient.RPop(QKey);
            string QMessgae = null;
            //2.字节转string
            if (bytes==null)
            {
                Console.WriteLine("队列中数据为空");
            }
            else
            {
                QMessgae = System.Text.Encoding.UTF8.GetString(bytes);
            }
            return QMessgae;
        }
        /// <summary>
        /// 出队(阻塞)==推
        /// </summary>
        /// <param name="QKey"></param>
        /// <param name="timeSpan">阻塞超时时间(根据时间自动解除阻塞)</param>
        /// <returns></returns>
        public string BDeQueue(string QKey,TimeSpan? timeSpan)
        {
            //1.redis消息出队
            string QMessgae = redisClient.BlockingPopItemFromList(QKey, timeSpan);
            return QMessgae;
        }
        /// <summary>
        /// 获取队列数
        /// </summary>
        /// <param name="QKey">队列key</param>
        /// <returns></returns>
        public long GetQueueCount(string QKey)
        {
            //1.获取队列数
            return redisClient.GetListCount(QKey);
        }
        /// <summary>
        /// 关闭redis
        /// </summary>
        public void Dispose() { 
            //1.关闭redis
             redisClient.Dispose();
        }
    }
}

Program

using System;
using System.Threading;

namespace RedisUP
{
    class Program
    {
        static void Main(string[] args)
        {
            using (RedisMessgaeQueue redisClient = new RedisMessgaeQueue("localhost:6379"))
            {
                Console.WriteLine("秒杀上游消息....");

                while (true)
                {
                    string rm_sum=redisClient.BDeQueue("rm_skills", TimeSpan.FromSeconds(60));

                    Console.WriteLine("************************开始秒杀下游业务调用****************************");
                    //消费秒杀上游消息
                    //秒杀业务处理
                    HandlerRequest(rm_sum);
                    Console.WriteLine("************************开始秒杀业务调用完成****************************");
                }

            }
        }
        /// <summary>
        /// 处理请求    
        /// </summary>
        /// <param name="requestCount"></param>
        public static void HandlerRequest(string requestCount)
        {
            Thread.Sleep(20);
            //创建订单
            Console.WriteLine("秒杀订单创建成功");
            //扣减库存
            Console.WriteLine("秒杀订单库存扣减生成");
            //扣减余额
            Console.WriteLine("用户余额扣减成功");
            Console.WriteLine($"处理的请求数:{requestCount}");
        }
    }
}

 3.创建一个下游业务项目(这里用控制台项目了,Framwork4.7.2)

 NuGet包下载SerivceStack.Redis

 创建一个RedisMessgaeQueue(Redis连接帮助类)

using ServiceStack.Redis;
using System;

namespace RedisDown
{
    class RedisMessgaeQueue:IDisposable
    {
        private RedisClient redisClient { get; }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="redisHost"></param>
        public RedisMessgaeQueue(string redisHost)
        {
            redisClient = new RedisClient(redisHost);
        }
        /// <summary>
        /// 入队
        /// </summary>
        /// <param name="QKey"></param>
        /// <param name="QMessgae"></param>
        /// <returns></returns>
        public long EnQueue(string QKey,string QMessgae) {
            //1.编码字符串
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(QMessgae);
            //2.redis消息队列入队
            long count = redisClient.LPush(QKey, bytes);
            return count;
        }
        /// <summary>
        /// 出队(非阻塞)==拉
        /// </summary>
        /// <param name="QKey"></param>
        /// <returns></returns>
        public string DeQueue(string QKey)
        {
            //1.redis消息出队
            byte[] bytes = redisClient.RPop(QKey);
            string QMessgae = null;
            //2.字节转string
            if (bytes==null)
            {
                Console.WriteLine("队列中数据为空");
            }
            else
            {
                QMessgae = System.Text.Encoding.UTF8.GetString(bytes);
            }
            return QMessgae;
        }
        /// <summary>
        /// 出队(阻塞)==推
        /// </summary>
        /// <param name="QKey"></param>
        /// <param name="timeSpan">阻塞超时时间(根据时间自动解除阻塞)</param>
        /// <returns></returns>
        public string BDeQueue(string QKey,TimeSpan? timeSpan)
        {
            //1.redis消息出队
            string QMessgae = redisClient.BlockingPopItemFromList(QKey, timeSpan);
            return QMessgae;
        }
        /// <summary>
        /// 获取队列数
        /// </summary>
        /// <param name="QKey">队列key</param>
        /// <returns></returns>
        public long GetQueueCount(string QKey)
        {
            //1.获取队列数
            return redisClient.GetListCount(QKey);
        }
        /// <summary>
        /// 关闭redis
        /// </summary>
        public void Dispose() { 
            //1.关闭redis
             redisClient.Dispose();
        }
    }
}

Program

using System;

namespace RedisDown
{
    class Program
    {
        static void Main(string[] args)
        {
            CreateSkillOrder(5000);
            Console.ReadKey();
        }
        /// <summary>
        /// 秒杀方法
        /// </summary>
        /// <param name="RequestCount">请求的数量</param>
        public static void CreateSkillOrder(int RequestCount) {
            using (RedisMessgaeQueue redisClient = new RedisMessgaeQueue("localhost:6379"))
            {
                int HandlerRequestCounts = 2000;//允许请求的数量
                for (int i = 0; i < RequestCount; i++)
                {
                    long count = redisClient.GetQueueCount("rm_skills");//当前的请求数量为多少

                    if (count > HandlerRequestCounts)//判断当前的请求数量是否大于允许请求的数量
                    {
                        Console.WriteLine("系统繁忙请稍后....");
                    }
                    else
                    {
                        //当前请求数量小于允许请求数量,代表还能请求
                        Console.WriteLine("入队成功");
                        redisClient.EnQueue("rm_skills", i + "Test");
                    }
                }

            }
        }
    }
}

启动下游服务

 ​​

启动上游服务

秒杀服务dome结束

4.异步执行

4.1先创建一个控制台FramWork项目RedisOne(命名随意)>NuGet包下载ServiceStack.Redis>添加RedisMessgaeQueue(Redis连接帮助类)>这个类代码在上面

Program

using System;

namespace RedisOne
{
    class Program
    {
        static void Main(string[] args)
        {
            using (RedisMessgaeQueue redisClient = new RedisMessgaeQueue("localhost:6379"))
            {
                string order_sn = "123456";
                redisClient.EnQueue("Messgar1", order_sn);
                redisClient.EnQueue("Messgar2", order_sn);
                Console.WriteLine("写入成功");
            }
            Console.ReadKey();
        }
    }
}

4.2跟上面一样再创建两个控制台项目分别为Messgae1和Messgae2

4.3两个项目都NuGet包下载ServiceStack.Redis

4.4两个项目都添加RedisMessgaeQueue(Redis连接帮助类)>这个类代码在上面

Messgae1的Program

using System;

namespace Messgae1
{
    class Program
    {
        static void Main(string[] args)
        {
            using (RedisMessgaeQueue redisClient = new RedisMessgaeQueue("localhost:6379"))
            {
                Console.WriteLine("Message1.....");
                while (true)
                {
                    string mesg1 = redisClient.BDeQueue("Messgar1", TimeSpan.FromSeconds(60));
                    if (mesg1!=null)
                    {
                        //消费Message1
                        Console.WriteLine($"消费成功:{mesg1}");
                    }
                    else
                    {
                        Console.WriteLine($"消费失败!");
                    }
                    
                }

            }
        }
    }
}

 Messgae2的Program

using System;

namespace Messgae2
{
    class Program
    {
        static void Main(string[] args)
        {
            using (RedisMessgaeQueue redisClient = new RedisMessgaeQueue("localhost:6379"))
            {
                Console.WriteLine("Message2.....");
                while (true)
                {
                    string mesg2 = redisClient.BDeQueue("Messgar2", TimeSpan.FromSeconds(60));
                    if (mesg2 != null)
                    {
                        //消费Message2
                        Console.WriteLine($"消费成功:{mesg2}");
                    }
                    else
                    {
                        Console.WriteLine($"消费失败!");
                    }

                }

            }
        }
    }
    
}

4.5代码部署完成后分别给项目Messgae1,Messgae2,RedisOne重新生成

4.6生成完后打开Messgae1,Messgae2项目的路径>运行Messgae1.exe,Messgae2.exe

 运行

 4.7开启RedisOne.exe

 完结

相关文章:

  • 开学总动员!2022华为开发者大赛等你来挑战!
  • 【WACV2022】DAQ | 首尔大学首次为超分辨率网络提出逐通道分布自适应量化方法,效果显著
  • STM32 Bootloader跳转后不执行程序的问题解决记录
  • 阿里内部人手一份!P8大佬也叫好的 高性能MySQL系列
  • 408数据结构学习强化——常见数据结构定义和算法总结
  • 全栈Python自动化测试学习资料【付费资源、看到即赚到,】
  • Shell 文件目录类(二)
  • 吴恩达机器学习重点记录
  • Pytorch创建多任务学习模型
  • js之页面列表加载常用方法总结
  • 基于STC89C52单片机的脉搏测量仪设计
  • 你不知道的达梦数据库
  • 3. python:列表、元组、字典、集合
  • 【Linux】Tomcat简介及二进制安装
  • 【Java基础】Java8集合[ArrayList 常用方法讲解](源码分析+底层原理)
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • 03Go 类型总结
  • create-react-app做的留言板
  • ES学习笔记(12)--Symbol
  • Flannel解读
  • Git的一些常用操作
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • iOS小技巧之UIImagePickerController实现头像选择
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • leetcode386. Lexicographical Numbers
  • Redis 中的布隆过滤器
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 精彩代码 vue.js
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • postgresql行列转换函数
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ​插件化DPI在商用WIFI中的价值
  • ​香农与信息论三大定律
  • #Ubuntu(修改root信息)
  • (+4)2.2UML建模图
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (39)STM32——FLASH闪存
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (第一天)包装对象、作用域、创建对象
  • (二)springcloud实战之config配置中心
  • (二)WCF的Binding模型
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • ../depcomp: line 571: exec: g++: not found
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .Family_物联网
  • .net core 连接数据库,通过数据库生成Modell
  • .NET CORE使用Redis分布式锁续命(续期)问题