为什么要用?
消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。实现高性能,高可用,可伸缩和最终一致性架构。是大型分布式系统不可缺少的中间件。消息形式支持点对点和订阅-发布。
使用场景
参考 消息队列使用场景
activemq
根据操作系统自己选择下载:http://activemq.apache.org/components/classic/download/
安装&启动
Windows:直接解压到安装目录,成功后打开命令行(cmd),到安装目录的bin目录下,启动命令 activemq start
Unix:
wget http://activemq.apache.org/path/tofile/apache-activemq-x.x.x-bin.tar.gz
cd [activemq_install_dir]
tar zxvf activemq-x.x.x-bin.tar.gz
cd [activemq_install_dir]/bin
./activemq start
./activemq stop
其他方式请查阅官方文档
启动成功
springboot整合
依赖(连接池的坑)
<!--引入消息队列 activemq-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<!--连接池 spring 1.可以使用 spring 2. 则要引入其他依赖-->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
</dependency>
<!--连接池 spring 2. -->
<dependency>
<groupId>org.messaginghub</groupId>
<artifactId>pooled-jms</artifactId>
</dependency>
配置
#activemq
spring.activemq.broker-url=tcp://127.0.0.1:61616
spring.activemq.user=admin
spring.activemq.password=admin
#其他可参考配置
# 在考虑结束之前等待的时间
#spring.activemq.close-timeout=15s
# 默认代理URL是否应该在内存中。如果指定了显式代理,则忽略此值。
#spring.activemq.in-memory=true
# 是否在回滚回滚消息之前停止消息传递。这意味着当启用此命令时,消息顺序不会被保留。
#spring.activemq.non-blocking-redelivery=false
# 等待消息发送响应的时间。设置为0等待永远。
#spring.activemq.send-timeout=0
#默认情况下activemq提供的是queue模式,若要使用topic模式需要配置下面配置
#spring.jms.pub-sub-domain=true
# 是否信任所有包
#spring.activemq.packages.trust-all=
# 要信任的特定包的逗号分隔列表(当不信任所有包时)
#spring.activemq.packages.trusted=
# 当连接请求和池满时是否阻塞。设置false会抛“JMSException异常”。
#spring.activemq.pool.block-if-full=true
# 如果池仍然满,则在抛出异常前阻塞时间。
#spring.activemq.pool.block-if-full-timeout=-1ms
# 是否在启动时创建连接。可以在启动时用于加热池。
#spring.activemq.pool.create-connection-on-startup=true
# 是否用Pooledconnectionfactory代替普通的ConnectionFactory。
#spring.activemq.pool.enabled=false
# 连接过期超时。
#spring.activemq.pool.expiry-timeout=0ms
# 连接空闲超时
#spring.activemq.pool.idle-timeout=30s
# 连接池最大连接数
#spring.activemq.pool.max-connections=1
# 每个连接的有效会话的最大数目。
#spring.activemq.pool.maximum-active-session-per-connection=500
# 当有"JMSException"时尝试重新连接
#spring.activemq.pool.reconnect-on-exception=true
# 在空闲连接清除线程之间运行的时间。当为负数时,没有空闲连接驱逐线程运行。
#spring.activemq.pool.time-between-expiration-check=-1ms
# 是否只使用一个MessageProducer
#spring.activemq.pool.use-anonymous-producers=true
启动类加上@EnableJms注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableJms
public class LoveMasterApplication {
public static void main(String[] args) {
SpringApplication.run(LoveMasterApplication.class, args);
}
/**
* 使用RestTemplate消费服务
* RestTemplate可以使用Ribbon作为负载均衡组件,在nacos-consumer工程中引入ribbon的依赖
* @return
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Bean(name = "queue")
public Queue getTestQueue(){//两个静态变量分别是订阅的queue和topic
//"registry.queue"
Queue queue = new ActiveMQQueue(ActiveMQConstans.REGISTRU_MESSAGE_QUEUE);
return queue;
}
@Bean(name = "topic")
public Topic getTestTopic(){
//"registry.topic"
Topic topic = new ActiveMQTopic(ActiveMQConstans.REGISTRU_MESSAGE_TOPIC);
return topic;
}
发布
@Service//这个接口实现自己测试时可以不用
public class ProducerService implements Producer {
@Autowired private JmsMessagingTemplate jmsMessagingTemplate;//spring提供
@Autowired private Queue queue;//启动类中注册的
@Autowired private Topic topic;
@Override
public <String> void sendMessageByQueue(Queue queue, String t) {
if (queue == null)
queue=this.queue;
jmsMessagingTemplate.convertAndSend(queue,t);//具体方法调用
}
@Override
public <String> void sendMessageByTopic(Topic topic, String t) {
if (topic == null)
topic=this.topic;
jmsMessagingTemplate.convertAndSend(topic,t);
}
}
@Service
public class UserService extends BaseService {//模拟注册后向注册用户发布注册成功消息
@Autowired
private UserMapper userMapper;
@Autowired
private ProducerService producerService;
public String registry(User user){
user.setCreateTime(new Date());
int success = userMapper.insert(user);
if (success > 0){
//Queue queue = new ActiveMQQueue("registry.queue");
producerService.sendMessageByQueue(null, JSON.toJSONString(user));
this.setResult("",user);
}
return this.getResult();
}
}
订阅
@Service
public class RegistryMessageService extends BaseService {
@Autowired
private RegistryMessageMapper registryMessageMapper;
@JmsListener(destination = ActiveMQConstans.REGISTRU_MESSAGE_QUEUE)
public void save(String userMessage){
System.out.println(userMessage);
User user = JSON.parseObject(userMessage,User.class);
RegistryMessage message = new RegistryMessage();
message.setUserId(user.getId());
message.setTitle("用户注册提示");
message.setContent(user.getNickName() + " 勇士,欢迎您的加入!");
message.setCreateTime(new Date());
registryMessageMapper.insert(message);
}
}
测试