RabbitMQ--03--SpringAMQP(SpringBoot集成RabbitMQ)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • SpringAMQP
    • 1.SpringBoot 的支持
        • https://spring.io/projects/spring-amqp
    • 2.RabbitTemplate
    • 3.@RabbitListener(终极监听方案)
    • 4.RabbitConfig---rabbitmq配置类
  • SpringBoot集成RabbitMQ 案例
    • 配置
        • 导入maven坐标
        • yml配置
    • 1.基本消息队列
      • 1、创建队列
      • 2、发布消息
      • 3、接受消息
    • 2.工作消息队列(Work Queue)
      • 1、发布消息
      • 2、接受消息
      • 3、控制台输出结果
      • 4、消息预取问题
    • 3.发布订阅模式之模式(Fanout)
          • ==生产者将消息发送到fanout交换器==
      • 1、Fanout配置类(@Bean声明)
      • 2、发送消息
      • 3、接受消息
    • 4.路由模式(Direct)
          • ==生产者将消息发送到direct交换器==
      • 1、声明(基于@RabbitListener声明)
      • 2、发送给blue
      • 3、发送给red
    • 5.主题模式(Topic)
          • ==生产者将消息发送到 topic交换器==
      • 1、声明
      • 2、发送消息(测试1)
      • 3、发送消息(测试2)


SpringAMQP

在这里插入图片描述

1.SpringBoot 的支持

  • SpringBoot 已经提供了对 AMQP 协议完全支持的 spring-boot-starter-amqp 依赖,引入此依赖即可快速方便的在 SpringBoot 中使用 RabbitMQ。
https://spring.io/projects/spring-amqp

在这里插入图片描述

2.RabbitTemplate

  • RabbitTemplate 是 SpringBoot AMQP 提供的快速发 RabbitMQ 消息的模板类,与 RestTemplate 有类似之处,意指方便、简单、快速的发 RabbitMQ 消息。
@Slf4j
@Component
public class ClientReportTopicProducer {@Autowiredprivate RabbitTemplate rabbitTemplate;private static final String ROUTING_KEY = "report";public void send(String param) {rabbitTemplate.send(TopicConst.CLIENT_REPORT_TOPIC, ROUTING_KEY, new Message(param.getBytes(), new MessageProperties()));}
}

在这里插入图片描述

send:将消息发送到指定的交换机和路由键中。

convertAndSend:将Java对象转换为消息,然后将其发送到指定的交换机和路由键中。

sendAndReceive:发送一个请求消息并接收一个响应消息。

convertSendAndReceive:将Java对象转换为请求消息,发送请求消息,并接收响应消息。

convertSendAndReceiveAsType:将Java对象转换为请求消息,发送请求消息,并接收响应消息,并将响应消息转换为指定类型的Java对象。

convertSendAndReceiveAsType:将Java对象转换为请求消息,发送请求消息,并接收响应消息,并将响应消息转换为指定类型的Java对象。

sendWithMessagePostProcessor:发送消息,并在发送之前进行处理。

execute:执行Rabbit操作并返回一个结果。

receive:从队列接收一条消息。

receiveAndConvert:从队列接收一条消息,并将其转换为Java对象。

receiveAndReply:从队列接收一条请求消息,并发送一个响应消息。

convertSendAndReceiveAsType:将Java对象转换为请求消息,发送请求消息,并接收响应消息,并将响应消息转换为指定类型的Java对象。

convertSendAndReceiveAsType:将Java对象转换为请求消息,发送请求消息,并接收响应消息,并将响应消息转换为指定类型的Java对象。

convertSendAndReceiveAndReplyHeader:将Java对象转换为请求消息,并发送请求消息。接收到请求消息后,将其转换为响应消息,并设置响应消息的头信息。

convertAndSend:将Java对象转换为消息,并发送消息。

convertAndSend:将Java对象转换为消息,并发送消息。在发送之前,先对消息进行处理。

convertAndSend:将Java对象转换为消息,并发送消息。在发送之前,先对消息进行处理,并指定响应消息的类型。

convertAndSend:将Java对象转换为消息,并发送消息。在发送之前,先对消息进行处理,并指定响应消息的类型和交换机。

send:将消息发送到指定的交换机和路由键中。

send:将消息发送到指定的交换机和路由键中。在发送之前,先对消息进行处理。

send:将消息发送到指定的交换机和路由键中。在发送之前,先对消息进行处理,并指定响应消息的类型。

sendAndReceive:发送一个请求消息并接收一个响应消息。

sendAndReceive:发送一个请求消息并接收一个响应消息。在发送之前,先对消息进行处理。

sendAndReceive:发送一个请求消息并接收一个响应消息。在发送之前,先对消息进行处理,并指定响应消息的类型。

sendAndReceive:发送一个请求消息并接收一个响应消息。在发送之前,先对消息进行处理,并指定响应消息的类型和交换机。

setConnectionFactory:设置RabbitMQ连接工厂。

getConnectionFactory:获取RabbitMQ连接工厂。

setExchange:设置默认的交换机。

getExchange:获取默认的交换机。

setRoutingKey:设置默认的路由键。

getRoutingKey:获取默认的路由键。

setQueue:设置默认的队列。

getQueue:获取默认的队列。

setMandatory:设置消息是否强制路由到队列。

isMandatory:检查消息是否强制路由到队列。

setReplyTimeout:设置接收响应消息的超时时间。

getReplyTimeout:获取接收响应消息的超时时间。

setChannelTransacted:设置通道是否应该在事务中使用。

isChannelTransacted:检查通道是否应该在事务中使用。

setConfirmCallback:设置确认回调。

getConfirmCallback:获取确认回调。

setReturnCallback:设置返回回调。

getReturnCallback:获取返回回调。

setBeforePublishPostProcessor:设置发布之前的后处理器。

getBeforePublishPostProcessor:获取发布之前的后处理器。

setAfterReceivePostProcessor:设置接收后的后处理器。

getAfterReceivePostProcessor:获取接收后的后处理器。

setUsePublisherConnection:设置是否应该使用发布者连接。

isUsePublisherConnection:检查是否应该使用发布者连接。

setApplicationContext:设置应用程序上下文。

3.@RabbitListener(终极监听方案)

使用此方案做监听消息功能,就可以把之前的 SimpleMessageListenerContainer 进行监听的方案舍弃掉了,就是这么的喜新厌旧,不过之前的 SimpleMessageListenerContainer 也不是一无是处,学过之后可以更好的理解内部的一些逻辑。

@RabbitListener 的特点:

  • RabbitListener 是 SpringBoot 架构中监听消息的终极方案。
  • RabbitListener 使用注解声明,对业务代码无侵入。
  • RabbitListener 可以在 SpringBoot 配置文件中进行配置。

@RabbitListener 本身是 Java 中的注解,可以搭配其他注解一起使用:

  • @Exchange:自动声明 Exchange。
  • @Queue:自动声明队列。
  • @QueueBinding:自动声明绑定关系。
package com.rabbitmqdemoconsumer.rabbitmq;import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class SpringRabbitLeistener {@RabbitListener(queues = "MqTest1")public void listenSimpleQueueMessage1(String msg){System.out.println("consume1接收到的消息:"+msg);}@RabbitListener(queues = "MqTest1")public void listenSimpleQueueMessage2(String msg){System.out.println("consume2接收到的消息:"+msg);}
}

4.RabbitConfig—rabbitmq配置类

声明式实现(推荐)

@Slf4j
@Configuration
public class RabbitConfig {public static final String EXCHANGE_NAME = "exchange.cat.dog";public static final String EXCHANGE_DLX  = "exchange.dlx";public static final String QUEUE_NAME    = "queue.cat";public static final String QUEUE_DLX     = "queue.dlx";public static final String KEY_NAME      = "key.yingduan";public static final String KEY_DLX       = "#";@BeanConnectionFactory connectionFactory() {CachingConnectionFactory connectionFactory = new CachingConnectionFactory();connectionFactory.setHost("127.0.0.1");connectionFactory.setUsername("admin");connectionFactory.setPassword("kzh_mxg4vfb2QRP*xkv");return connectionFactory;}@BeanRabbitAdmin rabbitAdmin(@Autowired ConnectionFactory connectionFactory) {return new RabbitAdmin(connectionFactory);}@BeanExchange exchange() {return new DirectExchange(EXCHANGE_NAME);}@BeanQueue queue() {return new Queue(QUEUE_NAME);}@BeanBinding binding() {// 目的地名称、目的地类型、绑定交换机、绑定 key、参数return new Binding(QUEUE_NAME, Binding.DestinationType.QUEUE, EXCHANGE_NAME, KEY_NAME, null);}//死信队列机制  死信队列需要在创建 Queue 时指定对应属性:@BeanQueue queue() {// 配置声明队列时使用的参数Map<String, Object> args = new HashMap<>(1);// 设置死信队列指向的交换机args.put("x-dead-letter-exchange", EXCHANGE_DLX);return new Queue(QUEUE_NAME, true, false, false, args);}}

注意,以上配置再启动 SpringBoot 并不会立马创建交换机、队列、绑定,SpringBoot AMQP 有懒加载,需要等到使用 connection 时才会创建。什么是使用 connection 呢?

  • 比如创建 connection
@Bean
ConnectionFactory connectionFactory() {CachingConnectionFactory connectionFactory = new CachingConnectionFactory();connectionFactory.setHost("127.0.0.1");connectionFactory.setUsername("admin");connectionFactory.setPassword("kzh_mxg4vfb2QRP*xkv");connectionFactory.createConnection();return connectionFactory;
}
  • 再比如监听了队列
@RabbitListener(queues = {"test"})
void test() {log.info("【测试监听消息】");
}

SpringBoot集成RabbitMQ 案例

配置

导入maven坐标
<!--rabbitmq--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>
yml配置
spring:rabbitmq:addresses: 192.168.100.120:5672,192.168.100.121:5672,192.168.100.122:5672username: adminpassword: admin#开启消息确认模式,新版本已经弃用#publisher-confirms: true#开启消息送达提示publisher-returns: true# springboot.rabbitmq.publisher-confirm 新版本已被弃用,现在使用 spring.rabbitmq.publisher-confirm-type = correlated 实现相同效果publisher-confirm-type: correlatedvirtual-host: /listener:type: simplesimple:acknowledge-mode: auto #确认模式prefetch: 1 #限制每次发送一条数据。concurrency: 3 #同一个队列启动几个消费者max-concurrency: 3 #启动消费者最大数量#重试策略相关配置retry:# 开启消费者(程序出现异常)重试机制,默认开启并一直重试enabled: true# 最大重试次数max-attempts: 5# 重试间隔时间(毫秒)initial-interval: 3000

RabbitMQ 参数配置说明

spring:rabbitmq:host: 127.0.0.1 #ipport: 5672      #端口username: guest #账号password: guest #密码virtualHost:    #链接的虚拟主机addresses: 127.0.0.1:5672     #多个以逗号分隔,与host功能一样。requestedHeartbeat: 60 #指定心跳超时,单位秒,0为不指定;默认60spublisherConfirms: true  #发布确认机制是否启用#确认消息已发送到交换机(Exchange)#publisher-confirm-type参数有三个可选值:#SIMPLE:会触发回调方法,相当于单个确认(发一条确认一条)。#CORRELATED:消息从生产者发送到交换机后触发回调方法。#NONE(默认):关闭发布确认模式。#publisher-confirm-type: correlated #发布确认机制是否启用 高版本Springboot使用替换掉publisher-confirms:truepublisherReturns: true #发布返回是否启用connectionTimeout: #链接超时。单位ms。0表示无穷大不超时### ssl相关ssl:enabled: #是否支持sslkeyStore: #指定持有SSL certificate的key store的路径keyStoreType: #key store类型 默认PKCS12keyStorePassword: #指定访问key store的密码trustStore: #指定持有SSL certificates的Trust storetrustStoreType: #默认JKStrustStorePassword: #访问密码algorithm: #ssl使用的算法,例如,TLSv1.1verifyHostname: #是否开启hostname验证### cache相关cache:channel: size: #缓存中保持的channel数量checkoutTimeout: #当缓存数量被设置时,从缓存中获取一个channel的超时时间,单位毫秒;如果为0,则总是创建一个新channelconnection:mode: #连接工厂缓存模式:CHANNEL 和 CONNECTIONsize: #缓存的连接数,只有是CONNECTION模式时生效### listenerlistener:type: #两种类型,SIMPLE,DIRECT## simple类型simple:concurrency: #最小消费者数量maxConcurrency: #最大的消费者数量transactionSize: #指定一个事务处理的消息数量,最好是小于等于prefetch的数量missingQueuesFatal: #是否停止容器当容器中的队列不可用## 与direct相同配置部分autoStartup: #是否自动启动容器acknowledgeMode: #表示消息确认方式,其有三种配置方式,分别是none、manual和auto;默认autoprefetch: #指定一个请求能处理多少个消息,如果有事务的话,必须大于等于transaction数量defaultRequeueRejected: #决定被拒绝的消息是否重新入队;默认是true(与参数acknowledge-mode有关系)idleEventInterval: #container events发布频率,单位ms##重试机制retry: stateless: #有无状态enabled:  #是否开启maxAttempts: #最大重试次数,默认3initialInterval: #重试间隔multiplier: #对于上一次重试的乘数maxInterval: #最大重试时间间隔direct:consumersPerQueue: #每个队列消费者数量missingQueuesFatal:#...其余配置看上方公共配置## template相关template:mandatory: #是否启用强制信息;默认falsereceiveTimeout: #`receive()`接收方法超时时间replyTimeout: #`sendAndReceive()`超时时间exchange: #默认的交换机routingKey: #默认的路由defaultReceiveQueue: #默认的接收队列## retry重试相关retry: enabled: #是否开启maxAttempts: #最大重试次数initialInterval: #重试间隔multiplier: #失败间隔乘数maxInterval: #最大间隔

1.基本消息队列

在这里插入图片描述

1、创建队列

  • 访问接口:http://localhost:15672,账号密码都为guest

在这里插入图片描述

2、发布消息

@SpringBootTest
class RabbitMQDemoPublishApplicationTests {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testvoid contextLoads() {String queue="MqTest1";String message="message1";rabbitTemplate.convertAndSend(queue,message);}}

在这里插入图片描述

3、接受消息

package com.rabbitmqdemoconsumer.rabbitmq;import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class SpringRabbitLeistener {@RabbitListener(queues = "MqTest1")public void listenSimpleQueueMessage(String msg){System.out.println("接收到的消息:"+msg);}
}

在这里插入图片描述

2.工作消息队列(Work Queue)

  • 可以提高消息处理速度,避免队列消息堆积

在这里插入图片描述

1、发布消息

@SpringBootTest
class RabbitMQDemoPublishApplicationTests {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testvoid contextLoads() {String queue="MqTest1";String message="message1";for (int i=0;i<10;i++){rabbitTemplate.convertAndSend(queue,message);}}}

2、接受消息

package com.rabbitmqdemoconsumer.rabbitmq;import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class SpringRabbitLeistener {@RabbitListener(queues = "MqTest1")public void listenSimpleQueueMessage1(String msg){System.out.println("consume1接收到的消息:"+msg);}@RabbitListener(queues = "MqTest1")public void listenSimpleQueueMessage2(String msg){System.out.println("consume2接收到的消息:"+msg);}
}

3、控制台输出结果

consume1接收到的消息:message1
consume2接收到的消息:message1
consume1接收到的消息:message1
consume2接收到的消息:message1
consume1接收到的消息:message1
consume2接收到的消息:message1
consume1接收到的消息:message1
consume2接收到的消息:message1
consume1接收到的消息:message1
consume2接收到的消息:message1

4、消息预取问题

  • 但是此时有一个问题就是消息预取,比如队列有10条消息,两个消费者各自直接先预取5个消息,如果一个消费者接受消息的速度慢,一个快,就会导致一个消费者已经完成工作,另一个还在慢慢处理,会造成消息堆积消费者身上,要解决这个问题需要在yml文件配置相关配置
  rabbitmq:host: 43.140.244.236port: 5672username: guestpassword: guestvirtual-host: /listener:simple:prefetch: 1 #每次只能取一个,处理完才能取下一个消息

3.发布订阅模式之模式(Fanout)

exchange是交换机,负责消息路由,但不存储消息,路由失败则消息丢失

生产者将消息发送到fanout交换器
  • fanout交换机非常简单。它只是将接收到的所有消息广播给它所知道的所有队列

在这里插入图片描述
在这里插入图片描述

1、Fanout配置类(@Bean声明)

package com.rabbitmqdemoconsumer.config;import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class FanountConfig {//交换机声明@Beanpublic FanoutExchange fanoutExchange(){return new FanoutExchange("FanountExchange");}//声明队列1@Beanpublic Queue Fanount_Qeueue1(){return new Queue("Fanount_Qeueue1");}//声明队列2@Beanpublic Queue Fanount_Qeueue2(){return new Queue("Fanount_Qeueue2");}//绑定交换机和队列@Beanpublic Binding bindingFanount_Qeueue1(Queue Fanount_Qeueue1,FanoutExchange fanoutExchange){return BindingBuilder.bind(Fanount_Qeueue1).to(fanoutExchange);}@Beanpublic Binding bindingFanount_Qeueue2(Queue Fanount_Qeueue2,FanoutExchange fanoutExchange){return BindingBuilder.bind(Fanount_Qeueue2).to(fanoutExchange);}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、发送消息

首先发送10条消息,经过交换机转发到队列
在这里插入图片描述

@SpringBootTest
class RabbitMQDemoPublishApplicationTests {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testvoid contextLoads2() {String exchange="FanountExchange";String message="message";for (int i=0;i<10;i++){rabbitTemplate.convertAndSend(exchange,"",message);}}}

在这里插入图片描述

3、接受消息

 //监听交换机Fanount_Qeueue1@RabbitListener(queues = "Fanount_Qeueue1")public void listenFanountQeueue1(String msg){System.out.println("Fanount_Qeueue1接收到的消息:"+msg);}//监听交换机Fanount_Qeueue2@RabbitListener(queues = "Fanount_Qeueue2")public void listenFanountQeueue2(String msg){System.out.println("Fanount_Qeueue2接收到的消息:"+msg);}

在这里插入图片描述

4.路由模式(Direct)

  • 会将消息根据规则路由到指定的队列
生产者将消息发送到direct交换器

在这里插入图片描述
在这里插入图片描述

1、声明(基于@RabbitListener声明)

package com.rabbitmqdemoconsumer.rabbitmq;import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class SpringRabbitLeistener {/*** 绑定交换机和队列,并为key赋值* @param msg*/@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "DirectQueue1"),exchange = @Exchange(name = "DirectExchange",type = ExchangeTypes.DIRECT),key = {"red","blue"}))public void listenDirectQueue1(String msg){System.out.println("listenDirectQueue1接收到的消息:"+msg);}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "DirectQueue2"),exchange = @Exchange(name = "DirectExchange",type = ExchangeTypes.DIRECT),key = {"red","yellow"}))public void listenDirectQueue2(String msg){System.out.println("listenDirectQueue2接收到的消息:"+msg);}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、发送给blue

发送消息
在这里插入图片描述

 
@SpringBootTest
class RabbitMQDemoPublishApplicationTests {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testvoid contextLoads2() {String exchange="DirectExchange";String message="HelloWorld";for (int i=0;i<10;i++){rabbitTemplate.convertAndSend(exchange,"blue",message);}}}

在这里插入图片描述

3、发送给red

发送消息

@SpringBootTest
class RabbitMQDemoPublishApplicationTests {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testvoid contextLoads2() {String exchange="DirectExchange";String message="HelloWorld";for (int i=0;i<10;i++){rabbitTemplate.convertAndSend(exchange,"red",message);}}}

在这里插入图片描述

5.主题模式(Topic)

生产者将消息发送到 topic交换器

在这里插入图片描述

Queue与Exchange指定BindingKey可以使用通配符:

#:代指0个或多个单词

*:代指一个单词

在这里插入图片描述

1、声明

@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "TopicQueue1"),exchange = @Exchange(name = "TopicExchange",type = ExchangeTypes.TOPIC),key = {"china.#"}))
public void listenTopicQueue1(String msg){System.out.println("listenTopicQueue1接收到的消息:"+msg);
}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "TopicQueue2"),exchange = @Exchange(name = "TopicExchange",type = ExchangeTypes.TOPIC),key = {"#.news"}
))
public void listenTopicQueue2(String msg){System.out.println("listenTopicQueue2接收到的消息:"+msg);
}

在这里插入图片描述
在这里插入图片描述

2、发送消息(测试1)

package com.rabbitmqdemo;import org.junit.jupiter.api.Test;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class RabbitMQDemoPublishApplicationTests {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testvoid contextLoads2() {String exchange="TopicExchange";String message="HelloWorld";for (int i=0;i<10;i++){rabbitTemplate.convertAndSend(exchange,"china.news",message);}}}

在这里插入图片描述

3、发送消息(测试2)

package com.rabbitmqdemo;import org.junit.jupiter.api.Test;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class RabbitMQDemoPublishApplicationTests {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testvoid contextLoads2() {String exchange="TopicExchange";String message="HelloWorld";for (int i=0;i<10;i++){rabbitTemplate.convertAndSend(exchange,"china.weather",message);}}}

在这里插入图片描述

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

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

相关文章

【鸿蒙HarmonyOS开发笔记】通知模块之为通知添加行为意图

概述 WantAgent提供了封装行为意图的能力&#xff0c;这里所说的行为意图主要是指拉起指定的应用组件及发布公共事件等能力。HarmonyOS支持以通知的形式&#xff0c;将WantAgent从发布方传递至接收方&#xff0c;从而在接收方触发WantAgent中指定的意图。例如&#xff0c;在通…

处理器方法的返回值--返回对象Object

处理器方法也可以返回Object对象。这个Object可以是Integer&#xff0c;String&#xff0c;自定义对象&#xff0c; Map&#xff0c;List 等。但返回的对象不是作为逻辑视图出现的&#xff0c;而是作为直接在页面显示的数据出现的。 返回对象&#xff0c;需要使用ResponseBody注…

Aspose.PDF功能演示:在 JavaScript 中优化 PDF 文件

PDF 文件是一种普遍存在的文档共享格式&#xff0c;但它们有时可能会很大&#xff0c;导致加载时间变慢并增加存储要求。优化 PDF 文件对于确保无缝的用户体验至关重要&#xff0c;尤其是在 Web 应用程序中。因此&#xff0c;在这篇博文中&#xff0c;我们将探讨如何使用 JavaS…

Java二阶知识点总结(七)SVN和Git

SVN 1、SVN和Git的区别 SVN是集中式的&#xff0c;也就是会有一个服务器保存所有代码&#xff0c;拉取代码的时候只能从这个服务器上拉取&#xff1b;Git是分布式的&#xff0c;也就是说每个人都保存有所有代码&#xff0c;如果要获取代码&#xff0c;可以从其他人手上获取SV…

改进粒子群优化算法||粒子群算法变体||Improved particle swarm optimization algorithm

粒子群算法&#xff08;Particle Swarm Optimization&#xff0c;PSO&#xff09;是一种基于群体智能的优化算法&#xff0c;其思想来源于鸟群寻食和鱼群捕食等自然现象。PSO算法通过模拟群体智能的行为&#xff0c;以一种启发式的方式寻找最优解&#xff0c;因此具有全局搜索能…

【python】2.pycharm中请选择有效的python解释器

欢迎来CILMY23的博客喔&#xff0c;本篇为【python】2.pycharm中请选择有效的python解释器&#xff0c;感谢观看&#xff0c;支持的可以给个一键三连&#xff0c;点赞关注收藏。 前言 在上一篇博客中&#xff0c;我们已经在电脑上安装了python3.12.2和pycharm&#xff0c;本期…

C数据类型(C语言)---变量的类型决定了什么?

目录 数据类型&#xff08;Data Type&#xff09; 变量的类型决定了什么&#xff1f; &#xff08;1&#xff09;不同类型数据占用的内存大小不同 如何计算变量或类型占内存的大小 &#xff08;2&#xff09;不同数据类型的表数范围不同 &#xff08;3&#xff09;不同类型…

jmx_prometheus_javaagent-0.19.0.jar+Prometheus+Grafana 监控Tongweb嵌入式(by lqw)

文章目录 1.思路2.部署准备3.应用jar包修改配置和导入tw嵌入式的依赖&#xff08;参考&#xff09;4.Prometheus部署5.Prometheus配置6.安装和配置Grafana 1.思路 Tongweb嵌入式最终是把依赖打入到java应用&#xff08;也就是jar包里&#xff09;&#xff0c;然后启动jar包进行…

GaussDB(分布式)实例故障处理

一、说明 GaussDB Kernel实例出现故障时&#xff0c;可以按照本节的办法进行实例快速修复。 1、执行gs_om -t status --detail查看集群状态&#xff0c;cluster_state为Normal&#xff0c;balanced为No&#xff0c;请重置实例状态。 2、执行gs_om -t status --detail查看集群…

02分布式搜索引擎ES

elasticsearch查询 1.DSL查询文档1.1.DSL查询分类1.2.全文检索查询1.3.精准查询1.4.地理坐标查询1.5.复合查询 2.搜索结果处理2.1.排序2.2.分页2.3.高亮2.4.总结 3.RestClient查询文档3.1.快速入门3.2.match查询3.3.精确查询3.4.布尔查询3.5.排序、分页3.6.高亮 1.DSL查询文档 …

springboot+itextpdf+thymeleaf+ognl根据静态模版文件实现动态生成pdf文件并导出demo

第一步&#xff1a;导入maven依赖 <!-- 导出为PDF依赖包 --><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId></dependency><dependency><groupId>com.itextpdf</groupId><art…

EF数据持久化(三层架构,客户增删)

效果图 点击新增按钮 点击添加 添加成功展示新增数据 点击删除&#xff0c;出现删除选项&#xff0c;点击确定根据id删除成功 成功删除 实现过程 Model设置具体流程在下面链接中 https://blog.csdn.net/Mr_wangzu/article/details/136805824?spm1001.2014.3001.5501 DAL …

棋盘问题(递推,递归)

//新生训练 #include <iostream> #include <algorithm> using namespace std; char a[10][10]; char limit[10]; int n, k; int ans 0; void dfs(int u, int cnt) {int m;if (cnt k){ans;return;}if (u > n){return;}for (int i 1; i < n; i){if (a[u][i]…

HTML静态网页成品作业(HTML+CSS)——动漫猫和老鼠网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

Maxwell监听mysql的binlog日志变化写入kafka消费者

一. 环境&#xff1a; maxwell:v1.29.2 (从1.30开始maxwell停止了对java8的使用&#xff0c;改为为11) maxwell1.29.2这个版本对mysql8.0以后的缺少utf8mb3字符的解码问题&#xff0c;需要对原码中加上一个部分内容 &#xff1a;具体也给大家做了总结 &#xff1a; 关于v1.…

uniapp、vue2.6、H5,利用腾讯TRTC,快速跑通1v1视频功能

多人视频聊天室搭建&#xff0c;官网已有相关demo和案例&#xff0c;需要快速搭建多人聊天室直接进入以下网站&#xff1a; 实时音视频 Web & H5 (Vue2/Vue3)-视频通话&#xff08;含 UI&#xff09;-文档中心-腾讯云说明&#xff1a;https://cloud.tencent.com/document/…

【C语言】循环语句(语句使用建议)

文章目录 **while循环****while循环的实践****补充:if语句与while语句区别****for循环(使用频率最高)****for循环的实践****while循环和for循环的对比****Do-while循环****break和continue语句****循环的嵌套****goto语句(不常用)****循环语句的效率(来自于高质量的C/C编程书籍…

css 如何获取分辨率(使用@media查询)

在CSS中&#xff0c;可以使用media查询来应对不同的屏幕分辨率。例如&#xff0c;您可以为不同的屏幕宽度设置不同的样式规则。 /* 针对屏幕宽度小于600px的样式 */ media screen and (max-width: 599px) {body {background-color: lightblue;} }/* 针对屏幕宽度大于或等于600…

使用光标精灵更换电脑鼠标光标样式,一键安装使用

想要让自己在使用电脑时更具个性化&#xff0c;让工作和娱乐更加愉快&#xff0c;改变你的电脑指针光标皮肤可能是一个简单而有效的方法。很多人或许并不清楚如何轻松地调整电脑光标样式&#xff0c;下面我就来分享一种简单的方法。 电脑光标在系统里通常只有几种默认图案&…

流畅的 Python 第二版(GPT 重译)(一)

前言 计划是这样的&#xff1a;当有人使用你不理解的特性时&#xff0c;直接开枪打死他们。这比学习新东西要容易得多&#xff0c;不久之后&#xff0c;活下来的程序员只会用一个容易理解的、微小的 Python 0.9.6 子集来编写代码 。 Tim Peters&#xff0c;传奇的核心开发者&am…