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


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

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

    NuGet包下载SerivceStack.Redis

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

    1. using ServiceStack.Redis;
    2. using System;
    3. namespace RedisUP
    4. {
    5. class RedisMessgaeQueue:IDisposable
    6. {
    7. private RedisClient redisClient { get; }
    8. /// <summary>
    9. /// 构造函数
    10. /// </summary>
    11. /// <param name="redisHost"></param>
    12. public RedisMessgaeQueue(string redisHost)
    13. {
    14. redisClient = new RedisClient(redisHost);
    15. }
    16. /// <summary>
    17. /// 入队
    18. /// </summary>
    19. /// <param name="QKey"></param>
    20. /// <param name="QMessgae"></param>
    21. /// <returns></returns>
    22. public long EnQueue(string QKey,string QMessgae) {
    23. //1.编码字符串
    24. byte[] bytes = System.Text.Encoding.UTF8.GetBytes(QMessgae);
    25. //2.redis消息队列入队
    26. long count = redisClient.LPush(QKey, bytes);
    27. return count;
    28. }
    29. /// <summary>
    30. /// 出队(非阻塞)==
    31. /// </summary>
    32. /// <param name="QKey"></param>
    33. /// <returns></returns>
    34. public string DeQueue(string QKey)
    35. {
    36. //1.redis消息出队
    37. byte[] bytes = redisClient.RPop(QKey);
    38. string QMessgae = null;
    39. //2.字节转string
    40. if (bytes==null)
    41. {
    42. Console.WriteLine("队列中数据为空");
    43. }
    44. else
    45. {
    46. QMessgae = System.Text.Encoding.UTF8.GetString(bytes);
    47. }
    48. return QMessgae;
    49. }
    50. /// <summary>
    51. /// 出队(阻塞)==
    52. /// </summary>
    53. /// <param name="QKey"></param>
    54. /// <param name="timeSpan">阻塞超时时间(根据时间自动解除阻塞)</param>
    55. /// <returns></returns>
    56. public string BDeQueue(string QKey,TimeSpan? timeSpan)
    57. {
    58. //1.redis消息出队
    59. string QMessgae = redisClient.BlockingPopItemFromList(QKey, timeSpan);
    60. return QMessgae;
    61. }
    62. /// <summary>
    63. /// 获取队列数
    64. /// </summary>
    65. /// <param name="QKey">队列key</param>
    66. /// <returns></returns>
    67. public long GetQueueCount(string QKey)
    68. {
    69. //1.获取队列数
    70. return redisClient.GetListCount(QKey);
    71. }
    72. /// <summary>
    73. /// 关闭redis
    74. /// </summary>
    75. public void Dispose() {
    76. //1.关闭redis
    77. redisClient.Dispose();
    78. }
    79. }
    80. }

    Program

    1. using System;
    2. using System.Threading;
    3. namespace RedisUP
    4. {
    5. class Program
    6. {
    7. static void Main(string[] args)
    8. {
    9. using (RedisMessgaeQueue redisClient = new RedisMessgaeQueue("localhost:6379"))
    10. {
    11. Console.WriteLine("秒杀上游消息....");
    12. while (true)
    13. {
    14. string rm_sum=redisClient.BDeQueue("rm_skills", TimeSpan.FromSeconds(60));
    15. Console.WriteLine("************************开始秒杀下游业务调用****************************");
    16. //消费秒杀上游消息
    17. //秒杀业务处理
    18. HandlerRequest(rm_sum);
    19. Console.WriteLine("************************开始秒杀业务调用完成****************************");
    20. }
    21. }
    22. }
    23. /// <summary>
    24. /// 处理请求
    25. /// </summary>
    26. /// <param name="requestCount"></param>
    27. public static void HandlerRequest(string requestCount)
    28. {
    29. Thread.Sleep(20);
    30. //创建订单
    31. Console.WriteLine("秒杀订单创建成功");
    32. //扣减库存
    33. Console.WriteLine("秒杀订单库存扣减生成");
    34. //扣减余额
    35. Console.WriteLine("用户余额扣减成功");
    36. Console.WriteLine($"处理的请求数:{requestCount}");
    37. }
    38. }
    39. }

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

     NuGet包下载SerivceStack.Redis

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

    1. using ServiceStack.Redis;
    2. using System;
    3. namespace RedisDown
    4. {
    5. class RedisMessgaeQueue:IDisposable
    6. {
    7. private RedisClient redisClient { get; }
    8. /// <summary>
    9. /// 构造函数
    10. /// </summary>
    11. /// <param name="redisHost"></param>
    12. public RedisMessgaeQueue(string redisHost)
    13. {
    14. redisClient = new RedisClient(redisHost);
    15. }
    16. /// <summary>
    17. /// 入队
    18. /// </summary>
    19. /// <param name="QKey"></param>
    20. /// <param name="QMessgae"></param>
    21. /// <returns></returns>
    22. public long EnQueue(string QKey,string QMessgae) {
    23. //1.编码字符串
    24. byte[] bytes = System.Text.Encoding.UTF8.GetBytes(QMessgae);
    25. //2.redis消息队列入队
    26. long count = redisClient.LPush(QKey, bytes);
    27. return count;
    28. }
    29. /// <summary>
    30. /// 出队(非阻塞)==
    31. /// </summary>
    32. /// <param name="QKey"></param>
    33. /// <returns></returns>
    34. public string DeQueue(string QKey)
    35. {
    36. //1.redis消息出队
    37. byte[] bytes = redisClient.RPop(QKey);
    38. string QMessgae = null;
    39. //2.字节转string
    40. if (bytes==null)
    41. {
    42. Console.WriteLine("队列中数据为空");
    43. }
    44. else
    45. {
    46. QMessgae = System.Text.Encoding.UTF8.GetString(bytes);
    47. }
    48. return QMessgae;
    49. }
    50. /// <summary>
    51. /// 出队(阻塞)==
    52. /// </summary>
    53. /// <param name="QKey"></param>
    54. /// <param name="timeSpan">阻塞超时时间(根据时间自动解除阻塞)</param>
    55. /// <returns></returns>
    56. public string BDeQueue(string QKey,TimeSpan? timeSpan)
    57. {
    58. //1.redis消息出队
    59. string QMessgae = redisClient.BlockingPopItemFromList(QKey, timeSpan);
    60. return QMessgae;
    61. }
    62. /// <summary>
    63. /// 获取队列数
    64. /// </summary>
    65. /// <param name="QKey">队列key</param>
    66. /// <returns></returns>
    67. public long GetQueueCount(string QKey)
    68. {
    69. //1.获取队列数
    70. return redisClient.GetListCount(QKey);
    71. }
    72. /// <summary>
    73. /// 关闭redis
    74. /// </summary>
    75. public void Dispose() {
    76. //1.关闭redis
    77. redisClient.Dispose();
    78. }
    79. }
    80. }

    Program

    1. using System;
    2. namespace RedisDown
    3. {
    4. class Program
    5. {
    6. static void Main(string[] args)
    7. {
    8. CreateSkillOrder(5000);
    9. Console.ReadKey();
    10. }
    11. /// <summary>
    12. /// 秒杀方法
    13. /// </summary>
    14. /// <param name="RequestCount">请求的数量</param>
    15. public static void CreateSkillOrder(int RequestCount) {
    16. using (RedisMessgaeQueue redisClient = new RedisMessgaeQueue("localhost:6379"))
    17. {
    18. int HandlerRequestCounts = 2000;//允许请求的数量
    19. for (int i = 0; i < RequestCount; i++)
    20. {
    21. long count = redisClient.GetQueueCount("rm_skills");//当前的请求数量为多少
    22. if (count > HandlerRequestCounts)//判断当前的请求数量是否大于允许请求的数量
    23. {
    24. Console.WriteLine("系统繁忙请稍后....");
    25. }
    26. else
    27. {
    28. //当前请求数量小于允许请求数量,代表还能请求
    29. Console.WriteLine("入队成功");
    30. redisClient.EnQueue("rm_skills", i + "Test");
    31. }
    32. }
    33. }
    34. }
    35. }
    36. }

    启动下游服务

     ​​

    启动上游服务

    秒杀服务dome结束

    4.异步执行

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

    Program

    1. using System;
    2. namespace RedisOne
    3. {
    4. class Program
    5. {
    6. static void Main(string[] args)
    7. {
    8. using (RedisMessgaeQueue redisClient = new RedisMessgaeQueue("localhost:6379"))
    9. {
    10. string order_sn = "123456";
    11. redisClient.EnQueue("Messgar1", order_sn);
    12. redisClient.EnQueue("Messgar2", order_sn);
    13. Console.WriteLine("写入成功");
    14. }
    15. Console.ReadKey();
    16. }
    17. }
    18. }

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

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

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

    Messgae1的Program

    1. using System;
    2. namespace Messgae1
    3. {
    4. class Program
    5. {
    6. static void Main(string[] args)
    7. {
    8. using (RedisMessgaeQueue redisClient = new RedisMessgaeQueue("localhost:6379"))
    9. {
    10. Console.WriteLine("Message1.....");
    11. while (true)
    12. {
    13. string mesg1 = redisClient.BDeQueue("Messgar1", TimeSpan.FromSeconds(60));
    14. if (mesg1!=null)
    15. {
    16. //消费Message1
    17. Console.WriteLine($"消费成功:{mesg1}");
    18. }
    19. else
    20. {
    21. Console.WriteLine($"消费失败!");
    22. }
    23. }
    24. }
    25. }
    26. }
    27. }

     Messgae2的Program

    1. using System;
    2. namespace Messgae2
    3. {
    4. class Program
    5. {
    6. static void Main(string[] args)
    7. {
    8. using (RedisMessgaeQueue redisClient = new RedisMessgaeQueue("localhost:6379"))
    9. {
    10. Console.WriteLine("Message2.....");
    11. while (true)
    12. {
    13. string mesg2 = redisClient.BDeQueue("Messgar2", TimeSpan.FromSeconds(60));
    14. if (mesg2 != null)
    15. {
    16. //消费Message2
    17. Console.WriteLine($"消费成功:{mesg2}");
    18. }
    19. else
    20. {
    21. Console.WriteLine($"消费失败!");
    22. }
    23. }
    24. }
    25. }
    26. }
    27. }

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

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

     运行

     4.7开启RedisOne.exe

     完结

  • 相关阅读:
    Spring Bean的生命周期
    论文解读(BGRL)《Large-Scale Representation Learning on Graphs via Bootstrapping》
    YOLOv8改进RepVGG结构:简单但功能强大的卷积神经网络架构
    Qt之sendEvent
    创新案例|实现YouTube超速增长的3大敏捷组织运营机制(上)
    LCR 146.螺旋遍历数组
    docker 安装mysql、canal、redis实现redis和mysql缓存一致性
    算法试题——每日一练
    国庆假期买哪款耳机好?国庆假期必备蓝牙耳机推荐
    Linux网络-DHCP原理与配置
  • 原文地址:https://blog.csdn.net/weixin_45381269/article/details/127069242