分布式异步队列学习总结4(生产者和消费者)

本文通过.NET Core演示了RabbitMQ的单生产者单消费者模式以及多生产者多消费者模式,展示了如何使用事件消费者监听消息并处理。此外,还介绍了如何设置消息队列的优先级,以实现VIP优先处理的场景。这些示例有助于理解RabbitMQ在消息传递和流量控制中的应用。
摘要由CSDN通过智能技术生成

生产者向RabbitMQ服务发送消息,消费者从RabbitMQ服务中获取消息。

单生产者单消费者模式

使用程序演示单生产者和单消费者模型:

项目结构为两个.net Core 控制台程序应用程序

程序需要添加引用 RabbitMQ.Client

AspNetCore.RabbitMQ.MessageConsumer_01.MessageConsumer(消费者)

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;

namespace AspNetCore.RabbitMQ.MessageConsumer_01.MessageConsumer
{
    public class ProductionConsumer
    {
        public static void Show()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (IConnection connection = factory.CreateConnection())
            {
                //创建信道
                using (IModel channel = connection.CreateModel())
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    try
                    {
                        //声明队列
                        channel.QueueDeclare(queue: "OnlyProducerMessage", durable: true, exclusive: false, autoDelete: false, arguments: null);

                        //声明路由
                        channel.ExchangeDeclare(exchange: "OnlyProducerMessageExChange", type: ExchangeType.Direct, durable: true, autoDelete: false, arguments: null);

                        //绑定队列和路由
                        channel.QueueBind(queue: "OnlyProducerMessage", exchange: "OnlyProducerMessageExChange", routingKey: string.Empty, arguments: null);


                        //基于当前信道创建事件
                        var consumer = new EventingBasicConsumer(channel);
                        consumer.Received += (model, ea) =>
                        {
                            var body = ea.Body;
                            var message = Encoding.UTF8.GetString(body.ToArray());
                            Console.WriteLine($"消费者01 接收消息:{message}");
                        };

                        channel.BasicConsume(queue: "OnlyProducerMessage", autoAck: true, consumer: consumer);
                        Console.WriteLine("按下回车退出啊");
                        Console.ReadLine();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }

                }
            }

        }
    }
}

 Main程序中调用下Show方法 

class Program
    {
        static void Main(string[] args)
        {
            ProductionConsumer.Show();
        }
    }

namespace AspNetCore.RabbitMQ.MessageProducer.MessageProducer(生产者)

using RabbitMQ.Client;
using System;
using System.Text;

namespace AspNetCore.RabbitMQ.MessageProducer.MessageProducer
{
    /// <summary>
    /// 生产者
    /// </summary>
    public class ProductionConsumer
    {
        public static void Show()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (IConnection connection = factory.CreateConnection())
            {
                //创建信道
                using (IModel channel = connection.CreateModel())
                {
                 
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("生产者已准备就绪......");

                    int i = 1;
                    {
                        while (true)
                        {
                            IBasicProperties basicProperties = channel.CreateBasicProperties();
                            basicProperties.Persistent = true;

                            string message = $"消息{i}";
                            byte[] body = Encoding.UTF8.GetBytes(message);
                            channel.BasicPublish(exchange: "OnlyProducerMessageExChange", routingKey: string.Empty, basicProperties: basicProperties, body: body);
                            Console.WriteLine($"消息{message}已发送");
                            i++;
                        }
                    }
                }
            }

        }
    }
}

Main程序中调用下Show方法 

class Program
    {
        static void Main(string[] args)
        {
            ProductionConsumer.Show();
        }
    }

启动两个程序:

启动消费者,在项目目录中进入命令窗口执行dotnet 启动命令

以同样的方式,启动生产者

消费者和生产者都启动以后,可以看到两个命令窗口打印如下信息:

多生产者多消费者模式

模拟多个生产者和多个消费者的情况

AspNetCore.RabbitMQ.MessageConsumer_01.MessageConsumer(消费者)

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;

namespace AspNetCore.RabbitMQ.MessageConsumer_01.MessageConsumer
{
    public class MultiProductionConsumer
    {
        public static void Show1()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (var connection = factory.CreateConnection())
            {
                //创建信道
                using (var channel = connection.CreateModel())
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    try
                    {
                        //声明队列
                        //channel.QueueDeclare(queue: "OnlyProducerMessage", durable: true, exclusive: false, autoDelete: false, arguments: null);

                        //声明路由
                        //channel.ExchangeDeclare(exchange: "OnlyProducerMessageExChange", type: ExchangeType.Direct, durable: true, autoDelete: false, arguments: null);

                        //绑定队列和路由
                        //channel.QueueBind(queue: "OnlyProducerMessage", exchange: "OnlyProducerMessageExChange", routingKey: string.Empty, arguments: null);


                        //基于当前信道创建事件
                        var consumer = new EventingBasicConsumer(channel);
                        consumer.Received += (model, ea) =>
                        {
                            var body = ea.Body;
                            var message = Encoding.UTF8.GetString(body.ToArray());
                            Console.WriteLine($"消费者01 接收消息:{message}");
                        };

                        channel.BasicConsume(queue: "MultiProducerMessage", autoAck: true, consumer: consumer);
                        Console.WriteLine("按下回车退出啊");
                        Console.ReadLine();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }

                }
            }

        }


        public static void Show2()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (var connection = factory.CreateConnection())
            {
                //创建信道
                using (var channel = connection.CreateModel())
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    try
                    {
                        //声明队列
                        //channel.QueueDeclare(queue: "OnlyProducerMessage", durable: true, exclusive: false, autoDelete: false, arguments: null);

                        //声明路由
                        //channel.ExchangeDeclare(exchange: "OnlyProducerMessageExChange", type: ExchangeType.Direct, durable: true, autoDelete: false, arguments: null);

                        //绑定队列和路由
                        //channel.QueueBind(queue: "OnlyProducerMessage", exchange: "OnlyProducerMessageExChange", routingKey: string.Empty, arguments: null);


                        //基于当前信道创建事件
                        var consumer = new EventingBasicConsumer(channel);
                        consumer.Received += (model, ea) =>
                        {
                            var body = ea.Body;
                            var message = Encoding.UTF8.GetString(body.ToArray());
                            Console.WriteLine($"消费者02 接收消息:{message}");
                        };

                        channel.BasicConsume(queue: "MultiProducerMessage", autoAck: true, consumer: consumer);
                        Console.WriteLine("按下回车退出啊");
                        Console.ReadLine();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }

                }
            }

        }



        public static void Show3()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (var connection = factory.CreateConnection())
            {
                //创建信道
                using (var channel = connection.CreateModel())
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    try
                    {
                        //声明队列
                        //channel.QueueDeclare(queue: "OnlyProducerMessage", durable: true, exclusive: false, autoDelete: false, arguments: null);

                        //声明路由
                        //channel.ExchangeDeclare(exchange: "OnlyProducerMessageExChange", type: ExchangeType.Direct, durable: true, autoDelete: false, arguments: null);

                        //绑定队列和路由
                        //channel.QueueBind(queue: "OnlyProducerMessage", exchange: "OnlyProducerMessageExChange", routingKey: string.Empty, arguments: null);


                        //基于当前信道创建事件
                        var consumer = new EventingBasicConsumer(channel);
                        consumer.Received += (model, ea) =>
                        {
                            var body = ea.Body;
                            var message = Encoding.UTF8.GetString(body.ToArray());
                            Console.WriteLine($"消费者03 接收消息:{message}");
                        };

                        channel.BasicConsume(queue: "MultiProducerMessage", autoAck: true, consumer: consumer);
                        Console.WriteLine("按下回车退出啊");
                        Console.ReadLine();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }

                }
            }

        }
    }
}

 Main程序中调用下Show方法 

 class Program
    {
        static void Main(string[] args)
        {
            //ProductionConsumer.Show();

            //多消费者
            {
                Task.Run(() => { MultiProductionConsumer.Show1(); });
                Task.Run(() => { MultiProductionConsumer.Show2(); });
                Task.Run(() => { MultiProductionConsumer.Show3(); });
            }
            Console.ReadLine();
        }
    }

AspNetCore.RabbitMQ.MessageProducer.MessageProducer(生产者)

using RabbitMQ.Client;
using System;
using System.Text;
using System.Threading;

namespace AspNetCore.RabbitMQ.MessageProducer.MessageProducer
{
    /// <summary>
    /// 生产者
    /// </summary>
    public class MultiProductionConsumer
    {
        public static void Show(string No)
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (IConnection connection = factory.CreateConnection())
            {
                //创建信道
                using (IModel channel = connection.CreateModel())
                {
                    //声明队列
                    channel.QueueDeclare(queue: "MultiProducerMessage", durable: true, exclusive: false, autoDelete: false, arguments: null);

                    //声明路由
                    channel.ExchangeDeclare(exchange: "MultiProducerMessageExChange", type: ExchangeType.Direct, durable: true, autoDelete: false, arguments: null);

                    //绑定队列和路由
                    channel.QueueBind(queue: "MultiProducerMessage", exchange: "MultiProducerMessageExChange", routingKey: string.Empty, arguments: null);


                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine($"生产者{No}已准备就绪......");

                    int i = 1;
                    {
                        while (true)
                        {
                            string message = $"生产者{No},消息{i}";
                            byte[] body = Encoding.UTF8.GetBytes(message);
                            channel.BasicPublish(exchange: "MultiProducerMessageExChange", routingKey: string.Empty, basicProperties: null, body: body);
                            Console.WriteLine($"消息{message}已发送");
                            i++;
                            Thread.Sleep(200);
                        }
                    }
                }
            }

        }
    }
}

  Main程序中调用下Show方法 

 class Program
    {
        static void Main(string[] args)
        {
            //ProductionConsumer.Show();

            //多生产者
            {
                //这是添加命令行功能
                IConfigurationRoot config = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddCommandLine(args)
                    .Build();

                string strMinute = config["minute"];//什么时间开始执行
                string No = config["no"];//生产者编号
                int minute = Convert.ToInt32(strMinute);

                bool flag = true;
                while (flag)
                {
                    if (DateTime.Now.Minute == minute)
                    {
                        Console.WriteLine($"到{strMinute}分钟,开始写入消息...");
                        flag = false;
                        MultiProductionConsumer.Show(No);
                    }
                }

            }
        }
    }

同时启动三个生产者服务,命令中的minute参数代表程序执行的分钟数字,从几分钟开始执行(表示当前时间的分钟数,13代表21:13开始执行)。no参数表示服务的编号,用于方便观察打印信息。

接着启动消费者服务

可以看到三个生产者同时向消息队列中发送消息。消费者服务开启三个线程,模拟三个消费者同时接收不同生产者发送的消息。

应用案例:商品秒杀实现

一共有10个商品,实现10个商品卖出后不再调用数据库进行操作(过滤无效请求,减少数据库压力)。

下面程序中写的生成者和消费者是从消息队列的角度出发的,发送数据的为生产者,接收数据的为

消费者。

AspNetCore.RabbitMQ.MessageConsumer_01.MessageConsumer(消费者)

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;

namespace AspNetCore.RabbitMQ.MessageConsumer_01.MessageConsumer
{
    public class SeckillConsumer
    {
        public static void Show()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (IConnection connection = factory.CreateConnection())
            {
                //创建信道
                using (IModel channel = connection.CreateModel())
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    try
                    {
                        //声明队列
                        channel.QueueDeclare(queue: "SeckillProducerMessage", durable: true, exclusive: false, autoDelete: false, arguments: null);

                        //声明路由
                        channel.ExchangeDeclare(exchange: "SeckillProducerMessageExChange", type: ExchangeType.Direct, durable: true, autoDelete: false, arguments: null);

                        //绑定队列和路由
                        channel.QueueBind(queue: "SeckillProducerMessage", exchange: "SeckillProducerMessageExChange", routingKey: string.Empty, arguments: null);


                        //基于当前信道创建事件
                        var consumer = new EventingBasicConsumer(channel);
                        int count = 0;
                        consumer.Received += (model, ea) =>
                        {
                            if (count >= 10)
                            {
                                Console.WriteLine("商品秒杀结束,已经不再调用数据库操作");
                            }
                            else
                            {
                                var body = ea.Body;
                                var message = Encoding.UTF8.GetString(body.ToArray());
                                Console.WriteLine($"{message} 秒杀成功");
                                count++;
                            }

                        };

                        channel.BasicConsume(queue: "SeckillProducerMessage", autoAck: true, consumer: consumer);
                        Console.WriteLine("按下回车退出啊");
                        Console.ReadLine();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }

                }
            }

        }
    }
}

main方法:

  class Program
    {
        static void Main(string[] args)
        {
            SeckillConsumer.Show();
            Console.ReadLine();
        }
    }

AspNetCore.RabbitMQ.MessageProducer.MessageProducer(生产者)

using RabbitMQ.Client;
using System;
using System.Text;

namespace AspNetCore.RabbitMQ.MessageProducer.MessageProducer
{
    /// <summary>
    /// 单生产者
    /// </summary>
    public class ProductionConsumer
    {
        /// <summary>
        /// 秒杀商品
        /// </summary>
        public static void SkillShow()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (IConnection connection = factory.CreateConnection())
            {
                //创建信道
                using (IModel channel = connection.CreateModel())
                {

                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("秒杀已准备就绪......");

                    int i = 1;
                    {
                        while (true)
                        {
                            IBasicProperties basicProperties = channel.CreateBasicProperties();
                            basicProperties.Persistent = true;

                            string message = $"粉丝{i}";
                            byte[] body = Encoding.UTF8.GetBytes(message);
                            channel.BasicPublish(exchange: "SeckillProducerMessageExChange", routingKey: string.Empty, basicProperties: basicProperties, body: body);
                            Console.WriteLine($"{message}开始抢购");
                            i++;
                        }
                    }
                }
            }

        }
    }
}

main方法:

class Program
    {
        static void Main(string[] args)
        {
            ProductionConsumer.SkillShow();
        }
    }

启动服务:

 

从打印信息可以看出,前10个用户请求处理完成后,后面的请求就不再调用数据库进行处理。达到了数据库限流的目的。

队列优先级

通过设置Priority的值来控制消息队列中消息被处理的优先级。

应用案例:VIP学员和普通学员同时向老师请教问题,老师优先解答VIP学员的提问。

AspNetCore.RabbitMQ.MessageConsumer_01.MessageConsumer(消费者)

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;

namespace AspNetCore.RabbitMQ.MessageConsumer_01.MessageConsumer
{
    public class PriorityQueue
    {
        public static void Show()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (IConnection connection = factory.CreateConnection())
            {
                //创建信道
                using (IModel channel = connection.CreateModel())
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    try
                    {
                        //基于当前信道创建事件
                        var consumer = new EventingBasicConsumer(channel);
                        consumer.Received += (model, ea) =>
                        {
                            var body = ea.Body;
                            var message = Encoding.UTF8.GetString(body.ToArray());
                            Console.WriteLine($"{message}");
                        };

                        Console.WriteLine("消费者准备就绪......");

                        //处理消息
                        channel.BasicConsume(queue: "PriorityQueue", autoAck: false, consumer: consumer);

                        Console.ReadLine();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }

                }
            }

        }
    }
}

main方法:

class Program
    {
        static void Main(string[] args)
        {
            //优先级队列
            PriorityQueue.Show();

            Console.ReadLine();
        }
    }

AspNetCore.RabbitMQ.MessageProducer.MessageProducer(生产者)

using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Text;

namespace AspNetCore.RabbitMQ.MessageProducer.MessageProducer
{
    public class PriorityQueue
    {
        public static void Show()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (IConnection connection = factory.CreateConnection())
            {
                //创建信道
                using (IModel channel = connection.CreateModel())
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("生产者已准备就绪......");

                    channel.QueueDeclare(queue: "PriorityQueue", durable: true, exclusive: false, autoDelete: false, arguments: new Dictionary<string, object>()
                    {
                        //最大级别255
                        { "x-max-priority",10} //指定队列要支持优先级设置
                    });

                    //声明交换机exchange
                    channel.ExchangeDeclare(exchange: "PriorityQueueExchange", type: ExchangeType.Direct, durable: true, autoDelete: false,
                        arguments: null);

                    //绑定exchange和queue
                    channel.QueueBind(queue: "PriorityQueue", exchange: "PriorityQueueExchange", routingKey: "PriorityKey");

                    //待发送的消息
                    {
                        string[] questionList = { "vip学员1 来请教", "甲同学 来请教", "乙同学 来请教", "丙同学 来请教", "丁同学 来请教", "vip学员2 来请教" };

                        //设置消息优先级
                        IBasicProperties props = channel.CreateBasicProperties();
                        foreach (string questionMsg in questionList)
                        {
                            if (questionMsg.StartsWith("vip"))
                            {
                                props.Priority = 9;
                            }
                            else
                            {
                                props.Priority = 1;
                            }
                            channel.BasicPublish(exchange: "PriorityQueueExchange", routingKey: "PriorityKey", basicProperties: props, body: Encoding.UTF8.GetBytes(questionMsg));
                            Console.WriteLine($"{questionMsg}已发送");
                        }
                    }
                }
            }
        }

    }
}

main方法:

class Program
    {
        static void Main(string[] args)
        {
            //队列优先级
            PriorityQueue.Show();

            Console.ReadLine();
        }
    }

启动服务:

从运行结果可以看出,虽然 vip学员2 最后一个进行提问(消息最后添加到队列中),但是因为设置了props.Priority = 9,非VIP学员props.Priority = 1,所以会优先于非VIP学员处理。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
go实战微服务分布式系统(distributed system)是建立在网络之上的软件系统。正是因为软件的特性,所以分布式系统具有高度的内聚性和透明性。因此,网络和分布式系统之间的区别更多的在于高层软件(特别是操作系统),而不是硬件。在一个分布式系统中,一组独立的计算机展现给用户的是一个统一的整体,就好像是一个系统似的。系统拥有多种通用的物理和逻辑资源,可以动态的分配任务,分散的物理和逻辑资源通过计算机网络实现信息交换。系统中存在一个以全局的方式管理计算机资源的分布式操作系统。通常,对用户来说,分布式系统只有一个模型或范型。在操作系统之上有一层软件中间件(middleware)负责实现这个模型。一个著名的分布式系统的例子是万维网(World Wide Web),在万维网中,所有的一切看起来就好像是一个文档(Web页面)一样。 [1] 在计算机网络中,这种统一性、模型以及其中的软件都不存在。用户看到的是实际的机器,计算机网络并没有使这些机器看起来是统一的。如果这些机器有不同的硬件或者不同的操作系统,那么,这些差异对于用户来说都是完全可见的。如果一个用户希望在一台远程机器上运行一个程序,那么,他必须登陆到远程机器上,然后在那台机器上运行该程序。 [1] 分布式系统和计算机网络系统的共同点是:多数分布式系统是建立在计算机网络之上的,所以分布式系统与计算机网络在物理结构上是基本相同的。 [1] 他们的区别在于:分布式操作系统的设计思想和网络操作系统是不同的,这决定了他们在结构、工作方式和功能上也不同。网络操作系统要求网络用户在使用网络资源时首先必须了解网络资源,网络用户必须知道网络中各个计算机的功能与配置、软件资源、网络文件结构等情况,在网络中如果用户要读一个共享文件时,用户必须知道这个文件放在哪一台计算机的哪一个目录下;分布式操作系统是以全局方式管理系统资源的,它可以为用户任意调度网络资源,并且调度过程是“透明”的。当用户提交一个作业时,分布式操作系统能够根据需要在系统中选择最合适的处理器,将用户的作业提交到该处理程序,在处理器完成作业后,将结果传给用户。在这个过程中,用户并不会意识到有多个处理器的存在,这个系统就像是一个处理器一样。 [1] 内聚性是指每一个数据库分布节点高度自治,有本地的数据库管理系统。透明性是指每一个数据库分布节点对用户的应用来说都是透明的,看不出是本地还是远程。在分布式数据库系统中,用户感觉不到数据是分布的,即用户不须知道关系是否分割、有无副本、数据存于哪个站点以及事务在哪个站点上执行等。  什么是微服务?维基上对其定义为:一种软件开发技术- 面向服务的体系结构(SOA)架构样式的一种变体,将应用程序构造为一组松散耦合的服务。在微服务体系结构中,服务是细粒度的,协议是轻量级的。微服务(或微服务架构)是一种云原生架构方法,其中单个应用程序由许多松散耦合且可独立部署的较小组件或服务组成。这些服务通常● 有自己的堆栈,包括数据库和数据模型;● 通过REST API,事件流和消息代理的组合相互通信;● 和它们是按业务能力组织的,分隔服务的线通常称为有界上下文。尽管有关微服务的许多讨论都围绕体系结构定义和特征展开,但它们的价值可以通过相当简单的业务和组织收益更普遍地理解:● 可以更轻松地更新代码。● 团队可以为不同的组件使用不同的堆栈。● 组件可以彼此独立地进行缩放,从而减少了因必须缩放整个应用程序而产生的浪费和成本,因为单个功能可能面临过多的负载。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值