RabbitMQ之消息模式简单易懂,超详细分享

前言

上一篇对RabbitMQ的流程和相关的理论进行初步的概述,如果小伙伴之前对消息队列不是很了解,那么在看理论时会有些困惑,这里以消息模式为切入点,结合理论细节和代码实践的方式一起来学习。

正文

常用的模式有Simple、Work、Fanout、Direct、Topic、Headers,可以通过设置交换机类型和配置参数来实现各个模式;接下来就分别进行实操演示吧。

以下演示都是通过管理员的账号进行。其实每种模式其实很大一部分操作都是一样的,所以公共部分不会重复截图说明,不过会针对不同的配置进行说明。

1. 简单模式(Simple)

简单模式顾名思义就是简单,不用配置太多的东西,如下图所示:

033ff07a4e59607a42e09c33c229fb22.png

上图解析:

  • P:表示生产者,负责推送消息;

  • C:表示消费者,负责接收消息;

  • 中间红色部分:代表的是队列(Queue);

小伙伴可能会奇怪,这里没有交换机吗?

其实是有的,上一篇说流程的时候,消息肯定是要通过交换机转发到队列中的,这里没有指定,那是因为用到了默认的交换机,具体看以下演示。

1.1 Web管理界面进行演示

对于Web界面演示来说,只需要将消息能生产、投递、消费即可,我们不用去弄一个生产者和消费者,生产者和消费者都是业务处理逻辑用的,所以通常都是根据业务需求就行实现的;话不多说开始演示吧。

根据上图所示,我们只需要创建一个队列即可,然后就可以进行消息模拟发送和消费了。

44ca22e0a063041a37cd9e0ad135ce3a.png

此时并没有指定交换机绑定,点击队列名看详情中的Bindings,有一个默认的交换机已经和队列进行绑定

c99a1015b0fc2005fd379cab581ca614.png

队列详情页面的说明,在上篇文章中就已经标注了,这里就不再赘述。

有了绑定关系之后,就可以在默认的交换机页面开始模拟转发消息;首先进入Exchanges管理页面,点击默认交换机(AMQP default)进入详情开始发布消息:

f8a69d6b70cf3d287bac864baf182226.png

消息发送成功之后就会在队列界面看到消息情况:

f074fff80473910dd0df43d2d6879f51.png

队列里面有了消息之后,就可以模拟消费者进行消息消费,点击队列名进入详情,可在详情也模拟消费:

962e6fa2afeba093ab2610b1c9fb2952.png

如上所示,简单模式整个消费流程就通过Web页面模拟完了。但在消费消息时,提供了Ack Mode模式(消息确认模式)选择来进行消费,可选择的模式如下:

  • Nack message requeue true:获取消息,但是不会向Server做ack应答确认(即不告诉服务器消息被消费了),消息重新入队。即队列中的消息不会被删除掉;

  • Automatic Ack:获取消息,向Server做应答确认(即会告诉服务器消息被消费了),消息不重新入队,将会从队列中删除;

  • Reject requeue true:拒绝获取消息(即拒绝处理消息),消息重新入队;

  • Reject requeue false:拒绝获取消息(即拒绝处理消息),消息不重新入队,将会被删除;

到这关于简单模式下的界面演示就结束了,其中描述的细节内容是共用的,在其他模式下的操作也类似,后续不做重复说明。

1.2 代码进行演示

这里就用控制台的方式,一步一步的实现。这里需要引入Nuget包:RabbitMQ.Client。生产者的整体代码如下:

36cc736f7de9a020c2979ea5a40f821e.png

接下来就一步一步来调试,看看消息是怎么一步一步发出去的;

  • 创建连接

    刚开始没有任何连接,如下:

    eae5e521a81c7aa3cf503efb2d07ed24.png

    代码继续下一步,连接就有了:

    2a92826dcf540747e594f2ffc7aa05e0.png

    此时就可以理解为网络连接上了,但通道还没有创建出来,如下:

    44a4ea9c77b580adbc00b322aac3c007.png
  • 根据连接创建通道

    通道根据连接进行创建,目的是为了提高传输效率,共用一个连接,不然频繁的创建和销毁连接会占资源,影响性能

    c6f2c5ed1dc77f8aa69a18bcf72e67a4.png
  • 定义队列

    有连接和通道之后理论就可以直接发消息了,但直接通信会相互依赖比较强,达不到解耦合的效果。所以需要定义一个队列将消息存放到里面,客户端想用了自己来消费就行,另外队列还可以达到一定的削峰作用

    a6ccc23247614a00fc4290755c28ed90.png

    创建队列的时候需要传几个参数,分别意思如下:

    参数1:queue, 队列的名称;

    参数2:durable, 队列是否持久化;如果为true,服务器重启之后队列还在,不会被清除;否则就被清掉。

    参数3:exclusive ,是否排他,即是否私有的,如果为true,会对当前队列加锁,其他的通道不能访问,并且连接自动关闭;

    参数4:autoDelete, 是否自动删除,当最后一个消费者断开连接之后是否自动删除消息;

    参数5:arguments, 用来设置队列附加参数,如设置队列的有效期、队列的消息生命周期、消息的最大长度等;

  • 发送消息

    经过以上步骤,就可以发送消息了,如上没有定义交换机,那就是绑定了默认交换机。

    54bacfc1343b419df726d8955c6f2a03.png

    发送时的几个参数意思如下:

    参数1:exchange,交换机,这里没有指定交换机。

    参数2:routingKey,路由key,即指定队列,简单模式下,路由key默认就是队列名

    参数3:basicProperties, 配置其他相关属性

    参数4:body ,需要发送的消息内容

以上的生产者完成了,现在再来一个消费者演示一下消息消费,消费者整体代码如下:

33449b82a2ce883230b815f25fc9475f.png

效果如下:

e4beb2f2ef602f1150c8b80fa18139b5.png

在整个过程中,还是会先建立连接,创建通道,指定队列;不同的是增加对接收数据的处理。

是不是用起来比较简单方便,主要是在复杂项目中,消息队列的作用真的很大。来,接着往下说说其他模式。

2. 工作模式(Work)

工作模式是考虑到多个消费者情况下,消息如何被消费的,主要有两种方案,轮询分发和公平分发;

  • 轮询分发:消费者依次轮着消费消息,直到消息消费完为止,按均分配。

  • 公平分发:根据消费者能力进行分发,即处理快的消费就多,处理慢的就消费就少,能者多劳。

f315697994788a0b9d930faf9ef73d2a.png

上图解析:

  • P:表示生产者,负责推送消息;

  • C1、C2:表示多个消费者,都可以从同一个队列接收消息;

  • 中间红色部分:代表的是队列(Queue);

这两种方式需要多个消费者,在界面不太好模拟,所以就直接上代码演示了。

2.1 轮询分发

在简单模式基础上稍微改动一下代码即可。在生产者中发多条消息出来,然后启用多个消费者就可以进行模拟如下:

生产者代码整体如下:

75dad0594e0957e9ca302f90bd3fe5b6.png

消费者代码整体如下:

2007a98b163750538bb0756c1a15c135.png

两个消费者的代码都是一样,没有变动;两个消费者的都是在消费同一个队列的消息,可以先启动两个消费者,然后在启动生产者,效果如下:

f58081badac87d5a32db8b879180c553.png

由上可见,默认情况下其实采用的是轮询方式。

2.2 公平分发

在实际业务中,有些业务处理比较耗时,有些处理耗时不长,如上案例,假如奇数消息需要处理比较耗时,那么对应的消费者就压力比较大。这种情况可以通过公平分发的方式进行业务处理,处理快点的就多处理点。

如何才能知道消费者处理业务完成呢?消费者处理完成之后主动上报是最好不过的,所以只需要在消费者端将自动确认机制改为手动确认即可,即:业务处理完成之后,手动上报确认状态。

生产者的代码不需要变动,只需要稍微改改消费者代码即可,这里模拟两个不同处理能力的消费者:

  • 消费者1处理一条消息业务需要500毫秒;

  • 消费者2处理一条消息业务需要2秒;

消费者1整体代码如下:

65232c4760351e1c7d36767c26efd695.png

消费者2整体代码如下,主要是模拟时间不一样:

ba52edf8eff4734205a2347c60ec106f.png

先启动两个消费者,再启动生产者,看看消费情况,如下:

9097585694f7288e9fea8d70935f59ce.png

以上演示就是公平分发模式的演示,其中有两个关键的步骤:

  • 设置每次消费的消息条数,可以根据实际业务情况配置,这里设置的是每次取一条。通过 channel.BasicQos进行设置。

  • 将消息确认模式改为自动模式,这样就可以根据实际业务处理情况反馈确认信息,服务器就会将消息处理掉,即删除消息。所以一般在实际业务场景大都会推荐使用手动确认的方式,这样避免业务未处理导致消息就被服务器给清掉的情况。

3. 发布订阅模式(Fanout)

Fanout模式是一种发布订阅模式,是一种广播机制,不需要指定路由Key。这种模式的交换机就会将消息广播到绑定的所有队列上去,只要有消费者订阅对应的队列,就会收到消息。如下图:

d7e2feadf3c23294fc2036ee73b458de.png

上图解析:

  • P:表示生产者,负责推送消息;

  • X:表示交换机,图中表示一个交换机绑定了多个队列;

  • C1、C2:表示多个消费者,都可以从同一个队列接收消息;

  • 中间红色部分:代表的是队列(Queue);

在这种模式下,消息会一次性被多个消费者消费。

3.1 Web管理界面进行演示
  • 先创建一个Fanout模式的交换机;

    fd19212df195661ddb62575e94e15b86.png
  • 创建两个队列(根据实际需要创建多个),并将队列绑定到上一步创建的交换机上;

    这里演示就创建两个队列,分别是FanoutQ1和FanoutQ2

    d536b34638e0b3c9ca0f10ebffeb22bb.png

    在队列详情页或交换机详情页都可以进行交换机和队列的绑定,这里分别在FanoutQ1和FanoutQ2队列详情页进行绑定,如下:

    6d02a81d7ba55c29fa1e8d1b0b4f8ab7.png

    同样的方式绑定FanoutQ2,  绑定完成之后,可以在交换机详情页看到对应的绑定队列:

    4c4cee7201e76b38df1f1ec685b61d55.png
  • 通过交换机上投递消息,看效果;

    此时通过FanoutExchange交换机投递消息,绑定到此交换机上的队列都能收到:

    25d2e9dc9e42ae14f8bf52b0250264ed.png

    查看队列消息情况,可以看到两个队列都接收到消息了。

    d157126b101047555f6a2100ffea323a.png
3.2 代码进行演示

其实代码和操作Web一样,只是用代码实现生产者和消费者而已。

  • 生产者的代码

    71c50c30bfcb8d086c62d10e2d15d662.png

    因为Fanout交换机不用关注RoutingKey,所以在发布消息时,第二个参数不需要传递RoutingKey。

  • 消费者1的代码

    a5922457fb7efa8703730addd30dba41.png

    消费者比较关注的是交换机需要和生产者指定的是同一个,队列和交换机有绑定。

  • 消费者2的代码,其实和消费者1基本一样,只是定义的队列不一样

    f05e3664331d44fd767575ace139b926.png
  • 先启动消费者,然后启动生产者,看效果

    5969cc3303b7cf3d01522abf06666bd8.png

    这里是控制台程序,为了显示方便就先启动消费者,后期的生产者,实际应用场景先启动谁都行。

4. 路由模式(Direct)

Direct模式是在Fanout基础增加RoutingKey条件, 即交换机不会将消息现全部投递到所有队列,而是只投递到对应RoutingKey下的队列。如图:

7323ae25ac3327dca065ca866bbe174a.png

上图解析:

  • P:表示生产者,负责推送消息;

  • X:表示交换机,指定类型为direct,图中表示一个交换机绑定了多个队列;

  • 中间箭头上的error、info、warning代表具体的RoutingKey;

  • C1、C2:表示多个消费者,都可以从同一个队列接收消息;

  • 中间红色部分:代表的是队列(Queue);

Direct模式其实在实际应用场景中用的比较多的,默认的Exhanges也是Direct模式, 很多关于消息队列的框架,默认也是采用这种模式,主要原因是根据RoutingKey精确的处理对应的业务,不会由于考虑不周到,导致消息处理有不确定性,性能相对也不错

4.1 Web管理界面进行演示
  • 先创建一个Direct模式的交换机;

    aa80914afff4868e5f1dd0eb349539b7.png
  • 创建两个队列,然后将队列绑定到上一步创建的交换机上,并指定对应的RoutingKey;

    bbf61adc76109b3b29464ca8896c2288.png

    创建队列完成之后,还需要绑定到交换机上,上一种模式演示的是从队列详情中维护绑定关系,这次从交换机详情中进行演示,如下:

    绑定第1个队列,指定RoutingKey是order,模拟处理订单的:

    81e10f660d5e5270f3a598e363e3b8cf.png

    绑定第2个队列,指定RoutingKey是msg,模拟处理消息的:

    e3477cc8dcff045476d4827dc8429d50.png

    有了绑定关系,就可以测试验证了。

    注:这里的RoutingKey可以根据实际情况随意指定的。

  • 向交换机上投递消息,看效果;

    模拟发布一个RoutingKey为order的消息:

    c94d0936216e4b90087a333e78742f01.png

    再发布一个消息,指定RoutingKey为msg,如下:

    85a2e01f0a0e2c3871fc3892a2ebab39.png

    两个消息都发布成功,而是指定对应的RoutingKey进行投递,所以现在绑定到此交换机上两个队列中分别有一条数据,查看队列的消息概况:

    e4fed63511a2611cdafe5a6e1c373f84.png

    可以进入队列详情,通过GetMessage获取到具体的消息内容,这里就不截图了,上面已经演示过。

4.2 代码进行演示

在Fanout的代码基础上稍微改动即可,主要改动点就是改变交换机的类型,并在队列和交换机绑定时设置对应的RoutingKey,发布消息的时候指定交换机和RoutingKey。

  • 生产者代码

    4b6b7b93ac901d2f4610e6625d58a552.png
  • 消费者1代码,主要是绑定队列时指定的RoutingKey为order

    5605ddbc472f31c43970c269e8adc5a5.png
  • 消费者2代码,主要是绑定队列时指定的RoutingKey为msg

    535d21bdf38cb6e32b345a4ae5433972.png
  • 运行起来看效果:

    0e9ebda8df824d7b9f55b814790a71ac.png

    如上演示效果,和Web演示一样,只有精确匹配到RoutingKey才能消费到对应的消息数据。

5. 主题模式(Topic)

Topic模式是在Direct模式基础增加模糊匹配RoutingKey,Direct精确匹配RoutingKey,Topic可以通*或#进行模糊匹配,从而把消息投递到对应的队列中,如图:

a0157308e88c7a74fda372c97c241a32.png

上图解析:

  • P:表示生产者,负责推送消息;

  • X:表示交换机,指定类型为topic,图中表示一个交换机绑定了多个队列;

  • 中间箭头上的文字代表模糊匹配的RoutingKey;其中*表示匹配RoutingKey中的一个词,#号表示匹配RoutingKey的零个或多个词,匹配符需要与点号(.)搭配使用。*.orange.test.# 示例中orange算一个词,test算一个词,即通过点号(.)分开的就称为一个词。

  • C1、C2:表示多个消费者,都可以从同一个队列接收消息;

  • 中间红色部分:代表的是队列(Queue);

5.1 Web管理界面进行演示
  • 先创建一个Topic模式的交换机;

    e26db81684394a48739324371856dd55.png
  • 创建两个队列,然后将队列绑定到上一步创建的交换机上,并指定对应的RoutingKey;

    eb9a3218904c4d014f605fa96944510c.png

    将队列绑定到交换机上,这里还是在交换机详情中进行演示,如下:

    30cb02bdbda35698b4c5a3fefe619899.png

    同样的步骤分别对TopicQ1和TopicQ2进行规则绑定,如下:

    现在的TopicExchange的绑定关系如下:

    80e635701402e57dd020e472fc70be65.png

    有了关系之后就可以进行验证效果了。

  • 向交换机上投递消息,会根据RoutingKey的模糊匹配规则将消息投递到对应的队列中,看效果;

    先指定order.create.test发布消息,看看会匹配哪些队列:

    45459595564e4b77073763ee5b72a413.png

    TopicQ2接收到消息,匹配到路由规则order.#

    b5552438f50a3127d66fe7dad06f5125.png

    再指定RoutingKey 为order.update 发布一个消息,如下:

    c4ed784985cb5c2ebef1f0a79cc190a8.png

    TopicQ1和TopicQ2都收到消息了,匹配到路由规则order.#和order.*,如下:

    84fe33e22efe55b536334337fb1ef1ba.png

    再指定RoutingKey 为order发布一个消息,就会匹配到order.#,这里就不截图了。

    以上测试说明:在Topic类型交换机和队列绑定关系时,可以指定RoutingKey的匹配规则,星号、#号、点号搭配使用,其中*表示匹配RoutingKey中的一个词,#号表示匹配RoutingKey的零个或多个词

    更多情况,小伙伴们自己动手试试。

5.2 代码进行演示

在Direct的代码基础上稍微改动即可,主要改动点就是改变交换机的类型,并在队列和交换机绑定时设置对应的RoutingKey,这里的RoutingKey是一个规则,是星号、#号、点号和每个词的组合,发布消息的时候指定交换机和RoutingKey,RoutingKey会去匹配绑定的规则。

  • 生产者代码

    d028210c62d4c4b762c524d7d227b1ac.png
  • 消费者1代码,指定路由匹配规则为order.#

    8aaf1b360be5a0f7d89db634756d518a.png
  • 消费者2代码,指定路由匹配规则为order.*

    589fcd6da1f4b6fd65a10861bffc3bce.png
  • 演示效果,将生产者和消费者都启动

    5672762b0e7222defa1ffac88ec73c9d.png

    如上图,和Web演示一样,#号匹配0个和多个词,*号只能匹配一个词。 符号可以与词任意组合,小伙伴可以根据业务情况自行发挥。

6. 参数模式(Headers)

Headers模式不是通过RoutingKey进行匹配投递消息,而是匹配请求头中所带的键值进行消息投递,所以创建队列是需要设置绑定的头部信息,有两种模式:全部匹配和部分匹配。

  • 全部匹配:x-match=all,表示所有的键值都匹配了才行。

  • 部分匹配:x-match=any,表示只要其中有键值对匹配就行。

5.1 Web管理界面进行演示
  • 先创建一个Headers模式的交换机;

    96f3f692bcc3a5755a670e9a4781707d.png
  • 创建两个队列,然后将队列绑定到上一步创建的交换机上,可以指定Headers的参数;

    e712a42d5d19da2dd3698588ab0dd10c.png

    将队列绑定到交换机上,这里还是在交换机详情中进行演示,如下:

    这里不使用RoutingKey的方式,而是通过设置参数的形式进行绑定,后续投递消息的时候就匹配参数,如果能匹配上,就将消息投递到对应的队列。

    绑定HeaderQ1队列:

    c305952d4a35a3d6431d299240a11c6f.png

    同样的方式绑定HeaderQ2队列,只是只添加了一个键值对,order:111,最后HeaderExchange交换机的绑定关系如下:

    1f51b1b1fe7ff222f601e44f5c248194.png

    关系绑定好之后就可以进行测试效果了。

  • 向交换机上投递消息,会根据检查Headers参数的条件是否符合,若符合将消息投递到对应的队列中,看效果;

    设置两个参数进行发布,如下:

    0a6070d304b036a5607e1df7dd2dba32.png

    可以看到两个队列都匹配到了,因为order和msg键值对匹配到HeaderQ1,order的键值对匹配到HeaderQ2,如果只设置一个order简直对呢:

    5f1c5aeb5e9ec7f991843cf406edaedd.png

    此时只有HeaderQ2才能精确匹配,HeaderQ1没有全部匹配,所以对应队列没有收到消息,如下:

    d36993b3636b9d1fc28fc8507f6c9435.png

    由此可见,在界面上没有指定x-match绑定的话,默认是all,就是要全部匹配才投递消息到对应队列

    这里继续新增一个HeaderQ3的队列,创建方式和上面不一样,只是在绑定交换机的时候增加x-match 为 any,如下:

    f8d603a6a1b7cf11c6454b8447e294d5.png

    绑定成功之后,现在关系如下,其中order的键值对是在每个绑定中都有,如下:

    af02aecfa6229cfbb672efa2eb5cf473.png

    测试发消息之前,把之前消息都清空了,也就是队列中的消息都是空的,这次我们再指定order为111的参数进行发布消息,看看有哪些队列收到消息呢:

    586622d5e248a9f60c3802cecf6d9fed.png

    消息发出后,之后HeaderQ2和HeaderQ3收到消息,HeaderQ2只有一个order参数,精确匹配上了,HeaderQ3有多个参数,但设置了x-match为any,所以只要匹配其中一个即可。HeaderQ1多个参数需要全部匹配才行,所以没有接收到消息:

    158f3d9a4d503ab8cffe3a2f51e0e84c.png
5.2 代码进行演示

Headers模式是根据参数进行匹配,不是通过RoutingKey,所以只需要在绑定队列时设置好参数,在发送消息的时候也设置好参数,这样就会根据匹配原则去匹配参数,如果匹配上,消息就投递到对应的队列,供消费者进行消费。这里为了演示比较清晰一点,使用一个生产者,三个消费者的形式进行演示。

  • 生产者

    43111006641c06af31d9dcd36241a9ff.png

    代码中关键的部分是指定交换机的类型为Headers,然后模拟了两类参数的形式投递消息,方便用于测试参数匹配模式的测试。

  • 消费者1,绑定参数为order:111和msg:222

    2e6ce8f0cb2983998c0f9b8d94bb2020.png
  • 消费者2,和消费者1代表基本一样,只是绑定参数不一样;

    72c7b49a25485bf9afaaafb04f0e537e.png
  • 消费者3,代表基本和消费者1一样,只是在参数指定的时候增加了x-match来指定匹配模式,这里指定为any,也就是只要其中有部分匹配上也可以消费到消息。

    ee4b91dfe7be7b442751aec7d2f41ed2.png
  • 演示效果,启动生产者和消费者:

    73028409ab248ab369cc9037dcc8eeb6.png

    如上图,消费者3指定了匹配模式为部分匹配,所以可以接收到一个参数的消息,而消费者1需要精确匹配,所以不能接收到。

关于常用的消息模式就聊到这吧,小伙伴们可以根据自己的业务场景进行使用,相关演示代码的地址如下:

码云:https://gitee.com/CodeZoe/dot-net-core-study-demo/tree/main/RabbitMQDemo

总结

RabbitMQ提供了多种模式应对各种业务,但匹配条件越是模糊或者参数化,那性能相对比较弱。再回顾一些常用的消息队列组件,是不是很多都是默认使用Direct模式,精确匹配的RoutingKey可以针对具体不同业务处理,匹配性能也相对比较高;当然其他模式小伙伴也可以针对业务情况进行使用。

后续的文章将继续分享RabbitMQ消息确认机制、死信队列、磁盘监控等相关知识点的应用,关注“Code综艺圈”,和我一起学习吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/282711.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jvm系列(八):jvm知识点总览

在江湖中要练就绝世武功必须内外兼备,精妙的招式和深厚的内功,武功的基础是内功。对于武功低(就像江南七怪)的人,招式更重要,因为他们不能靠内功直接去伤人,只能靠招式,利刃上优势来…

计算机基础知识的文献,四 计算机文献检索基础知识(原理、结构和功能)

1.计算机检索原理计算机一方面接受用户的检索提问,一方面从数据库中读取文献记录,然后把两者进行比较,即检索提问标识与文献记录标识进行匹配运算,如果比较的结果一致,那么这篇文献就会作为命中文献在检索结果中显示&a…

C# 基于.NET6的CM+Fody+HC入门实战项目(经典)

概述上期我们概述了CMFodyHC,如果之前没有阅读,可以先了解下:C# 为什么说CMFodyHC是WPF开发的最强组合?今天基于最新的VS版本、最新的CM框架版本,.NET基于6.0,搭建了一个WPF入门学习项目实例,关…

Kong入门学习实践(2)实验环境搭建

【API网关】| 总结/Edison Zhou最近在学习Kong网关,因此根据老习惯,我会将我的学习过程记录下来,一来体系化整理,二来作为笔记供将来翻看。由于我司会直接使用Kong企业版,学习过程中我会使用Kong开源版。本篇&#xff…

我的未来计算机作文,我的未来作文(精选4篇)

我的未来作文(精选4篇)在平平淡淡的日常中,大家总免不了要接触或使用作文吧,作文根据体裁的不同可以分为记叙文、说明文、应用文、议论文。怎么写作文才能避免踩雷呢?以下是小编收集整理的我的未来作文,仅供参考,大家一…

RDS for MySQL Mysqldump常见问题及处理

2019独角兽企业重金招聘Python工程师标准>>> 摘要: RDS for MySQL Mysqldump 常见问题和处理 GTID 特性相关 避免表级锁等待 设置导出字符集 其他导出时需要注意的选项 举例 RDS for MySQL 不支持的选项 RDS for MySQL 逻辑备份 1. GTID 特性相关 MySQ…

《ASP.NET Core 6框架揭秘》实例演示[27]:ASP.NET Core 6 Minimal API的模拟实现

Minimal API仅仅是在基于IHost/IHostBuilder的服务承载系统上作了小小的封装而已,它利用WebApplication和WebApplicationBuilder这两个类型提供了更加简洁的API,同时提供了与现有API的兼容。[本文节选《ASP.NET Core 6框架揭秘》第17章]一、基础模型二、…

高性能Server---Reactor模型

无处不在的C/S架构 在这个充斥着云的时代,我们使用的软件可以说99%都是C/S架构的! 你发邮件用的Outlook,Foxmail等你看视频用的优酷,土豆等你写文档用的Office365,googleDoc,Evernote等你浏览网页用的IE,Chrome等(B/S是特殊的C/S)……C/S架构…

springmvc_3(将数据放入map中)

jsp页面 结果 转载于:https://www.cnblogs.com/mohehpc/p/6491376.html

聊聊策略模式

1、简介策略模式就是把各个平等的具体实现进行抽象、封装成为独立的算法类,然后通过上下文和具体的算法类来进行交互。各个策略算法都是平等的,地位是一样的,正是由于各个算法的平等性,所以它们才是可以相互替换的。虽然我们可以动…

张旭升20162329 2006-2007-2 《Java程序设计》第一周学习总结

20162329 2006-2007-2 《Java程序设计》第一周学习总结 教材学习内容总结 通过打书上的代码熟悉了Java编程的基本过程 教材学习中的问题和解决过程 1.因为我的虚拟机不可用所以我在Windows中安装了bash和git,但是由于Windows下bash中没有中文而且我英语又不是很好所…

《图解 HTTP》读书笔记(未完待续)

ARP 协议(Address Resolution Protocol)一种以解析地址的协议,根据通信双方的 IP 地址就可以查出对应的 MAC 地址。MAC( Media Access Control Address)地址是指网卡所属的固定的地址MIME,多部分对象集合&a…

.NET 实现启动时重定向程序运行路径及 Windows 服务运行模式部署

日常工作中有时候会遇到需要将程序直接在服务器上运行,而不依赖于 IIS 托管的情况,直接运行有两种方式,一种是部署为 服务模式,另一种则是 直接启动 .NET 发布之后的 exe 文件以 控制台模式运行,控制台模式运行主要问题…

Unexpected end of JSON input while parsing near错误解决方式(网上的方法)

原本是想创建一个create-react-app来着,但是在创建的中间会出现Unexpected end of JSON input while parsing near... 的错误。 在网上找到了一些方法,首先是清空npm的缓存。 npm cache clean --force 氮素,然并卵。near后面的内容变化了一下…

Xmemcached学习笔记一(安装memcached)

memcached有三种java客户端 第一种:Com.danga 包下面的memcached,需引入jar(本人用的是memcached-2.5.2.jar 文末附上附件需要的可以下载) 第二种:spyMemcached 第三种:XMemcached 据说第三种是使用最简单,最好用的&a…

WrapPanel 实现虚拟化

WrapPanel 实现虚拟化控件名:VirtualizingWrapPanel作者:WPFDevelopersOrg原文链接: https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用大于等于.NET40;Visual Studio 2022;项目使用 MIT 开源许可协议;众…

如何证明 ConcurrentDictionary 字典操作不全是线程安全的

前言最近,看到一篇文章,讲到《ConcurrentDictionary字典操作竟然不全是线程安全的?》。首先,这个结论是正确的,但文中给出的一个证明例子,我觉得是有问题的。相关代码如下:using System.Collect…

16-djongo中间件学习

目录 前戏 我们在前面的课程中已经学会了给视图函数加装饰器来判断是用户是否登录,把没有登录的用户请求跳转到登录页面。我们通过给几个特定视图函数加装饰器实现了这个需求。但是以后添加的视图函数可能也需要加上装饰器,这样是不是稍微有点繁琐。 学完…

Eclipse控制项目的访问名称

Eclipse控制web项目的访问名称 web项目的访问路径(名称)修改 1.点击项目右键-》properties找到Context root 修改成我们需要的名字即可转载于:https://www.cnblogs.com/pypua/articles/7379950.html

计算机一级选择题已做完确认,计算机一级选择题(附答案)

点击蓝字关注我们(1)按照需求功能的不同,信息系统已形成各种层次,计算机应用于管理是开始于:()A)信息处理B)人事管理C)决策支持D)事务处理正确答案:A解析:计算机用于管理,起源于计算机在办公应用中对大量信息、数据的处…