使用redis實現生產者消費者模式


  本次主要分享一下使用redis做緩存隊列,實現生產者消費者模式。

  首先先來看一下redis提供的列表操作接口。像ListRightPush就和符合隊列先進先出的原則。

  然后圍繞這個列表已下單為例簡要實現生產者和消費者兩端的模塊。

  生產者Controller

     IApplicationContext ctx = ContextRegistry.GetContext();
        /// <summary>
        /// 
        /// </summary>
        public void Order()
        {
            OrderRequest order = new OrderRequest { Mobile = "15100000001", GoodsName = "抱枕", Price = 1, OrderId = "1111" };
            Thread t1 = new Thread(new ParameterizedThreadStart(WriteQueue));
            t1.Start(order);
            order = new OrderRequest { Mobile = "15100000002", GoodsName = "堅果", Price = 2, OrderId = "1112" };
            Thread t2 = new Thread(new ParameterizedThreadStart(WriteQueue));
            t2.Start(order);
            order = new OrderRequest { Mobile = "15100000003", GoodsName = "羽絨服", Price = 3, OrderId = "1113" };
            Thread t3 = new Thread(new ParameterizedThreadStart(WriteQueue));
            t3.Start(order);
            order = new OrderRequest { Mobile = "15100000004", GoodsName = "闊腿褲", Price = 4, OrderId = "1114" };
            Thread t4 = new Thread(new ParameterizedThreadStart(WriteQueue));
            t4.Start(order);
            order = new OrderRequest { Mobile = "15100000005", GoodsName = "芒果", Price = 5, OrderId = "1115" };
            Thread t5 = new Thread(new ParameterizedThreadStart(WriteQueue));
            t5.Start(order);
            order = new OrderRequest { Mobile = "15100000006", GoodsName = "啞鈴", Price = 6, OrderId = "1116" };
            Thread t6 = new Thread(new ParameterizedThreadStart(WriteQueue));
            t6.Start(order);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        private void WriteQueue(Object obj)
        {
            //通過spring容器創建對象
            IBLLQueue BLLQueue = ctx.GetObject<BLLQueue>("IBLLQueue");
            BLLQueue.WriteRedisQueue((OrderRequest)obj);
        }   
    /// <summary>
    /// 訂單對象
    /// </summary>
  public class OrderRequest
 { /// <summary>
        /// 訂單Id /// </summary>
        public string OrderId { get; set; } /// <summary>
        /// 手機 /// </summary>
        public string Mobile { get; set; } /// <summary>
        /// 物品名稱 /// </summary>
        public string GoodsName { get; set; } /// <summary>
        /// 價格 /// </summary>
        public double Price { get; set; } }

  接口和實現類

 
   public interface IBLLQueue
    {
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        void WriteRedisQueue(OrderRequest order);
    }

 public class BLLQueue : IBLLQueue
    {
        private string key = "OrderQueue";
        readonly static object _locker = new object();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="WriteRedisQueue"></param>
        public void WriteRedisQueue(OrderRequest order)
        {
            //添加到下單隊列
            lock (_locker)
            {
                var json = JsonHelper.SerializeObject(order);
                var result = (int)RedisService.ListRightSet(key, json);
            }
        }
    }

  redis幫助類

        /// <summary>
        /// ListGet
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static RedisValue[] ListGet(string key)
        {
            return Db.ListRange(key);
        }
        /// <summary>
        /// ListSet(尾)
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static long ListRightSet(string key, string value)
        {
            return Db.ListRightPush(key, value);
        }
        /// <summary>
        /// ListSet(頭)
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static long ListLeftSet(string key, string value)
        {
            return Db.ListLeftPush(key, value);
        }
        /// <summary>
        /// ListRemove
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static long ListRemove(string key, string value)
        {
            return Db.ListRemove(key, value);
        }
        /// <summary>
        /// ListLength
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static long ListLength(string key)
        {
            return Db.ListLength(key);
        }

  運行方法,通過可視化工具可看到redis列表結果:

 

  2.通過控制台輸出程序簡單實現消費者模塊。

  main函數:

      static void Main(string[] args)
        {
            Queue queue = new Queue();
            queue.run();
        }

  訂單消費者實現方法:

 public class Queue
    {
        private string key = "OrderQueue";
        private bool flg = true;
        readonly static object _locker = new object();
        public void run()
        {
            try
            {
                lock (_locker)
                {
                    while (flg)
                    {
                        if (RedisService.ListLength(key) > 0)
                        {
                            Take();
                        }
                        flg = false;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        public void Take()
        {
            var list = RedisService.ListGet(key).ToList();
            foreach (var item in list)
            {
                var order = JsonHelper.DeserializeJsonToObject<OrderRequest>(item);
                if (order != null)
                {
                    Console.WriteLine("訂單編號:" + (order.OrderId ?? "") + "   物品名稱:" + (order.GoodsName ?? "") + "   手機:" + (order.Mobile ?? "") + "   價格:" + order.Price);
                }
                //移除隊列
                RedisService.ListRemove(key, item);
            }
        }
}

  執行結果:

  這樣本次的案例就算小功告成。這邊有簡單使用spring.net。以前有使用過spring,年代久遠,目前自己正在重新學習當中,往后再分享這一塊學習心得。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM