springboot整合使用activemq
ActiveMq是一个基于JMS消息代理的实现。所谓JMS就是java消息服务,它是一个规范。就像JDBC一样是实现功能的标准。
同时还有一种规范,AMQP(更先进的消息代理协议),也是一种规范,并且兼容JMS,实现这个规范的最著名的是RabbitMq.
但是这里先按下不说,今天只说ActiveMq.
ActiveMq用于消息异步处理,流量削峰,系统消息通讯。有两种常用的方式:队列(queue)和topic(主题)。
queue用于点对点式的消息通信,topic用于发布订阅的消息通信。
点对点模式:一个消息只能被一个消费者消费(相当于一套说辞,一次只撩一个妹纸)
发布/订阅模式:一个消息可以同时被订阅的消费者消费(花心的汉子,一套说辞,撩多个妹纸)
SpringBoot整合ActiveMq,无论是点对点,还是发布订阅都需要做一些准备工作.
准备:
1.启动activemq
启动后可以访问http://localhost:8161/进入管理界面
2.pom文件中对activemq进行配置
<dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-client</artifactId> <version>5.15.3</version> </dependency>
3.配置ActiveMq的消息代理地址
##配置ActiveMq消息代理的地址
activemq:
broker-url: tcp://localhost:61616
user: admin
password: admin
pool:
enabled: false
packages:
trust-all: true
整合点对点模式:
1.在方法中发送消息
使用springboot为我们配置好的JmsTemplate
@Autowired private JmsTemplate jmsTemplate; @PostMapping("/findOneUser") public JSONObject findOneUser(HttpServletRequest request){ JSONObject json = new JSONObject(); try { String userphone = request.getParameter("userphone"); User user = userService.getUserById(userphone); json = JSON.parseObject(JSON.toJSONString(user)); jmsTemplate.convertAndSend("user",user);//这个是p2p //使用topic // producer.Send(user); } catch (Exception e) { e.printStackTrace(); } return json; }
2.配置消息消费者
@Component public class ReceiveMsgTest { @JmsListener(destination = "user") public void ReceiveUserMsg(User user ){ System.out.println("消费消息: "+user +LocalDateTime.now()); } }
3.测试:
使用postman发送请求,观察控制台和管理界面
2018-05-05 14:51:07.991 INFO 11940 --- [nio-8080-exec-2] o.a.c.c.C.[.[localhost].[/magicabc.web] : Initializing Spring FrameworkServlet 'dispatcherServlet' 2018-05-05 14:51:07.991 INFO 11940 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started 2018-05-05 14:51:08.008 INFO 11940 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 17 ms 2018-05-05 14:51:08.073 INFO 11940 --- [nio-8080-exec-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2018-05-05 14:51:08.470 INFO 11940 --- [nio-8080-exec-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2018-05-05 14:51:08.488 DEBUG 11940 --- [nio-8080-exec-2] c.m.w.m.mapper.IUserDao.getUserById : ==> Preparing: SELECT `userphone`, `username`, `password`, `headimagepath`, `sex`, `childAge`, `heartTime`, childName, grade, registerRationId, `hbintegral`, `dckintegral`, `jbnum` ,referrer,address, `isagent`, `activity`, `channel` , `openid`, `headurl`, `nickname`, `englishName`, `birthday`, `telephone`, `remark`, `relevanceCC`, `equipmentflag` FROM user WHERE userphone =? LIMIT 0, 1000 ; 2018-05-05 14:51:08.510 DEBUG 11940 --- [nio-8080-exec-2] c.m.w.m.mapper.IUserDao.getUserById : ==> Parameters: 18550444038(String) 2018-05-05 14:51:08.541 DEBUG 11940 --- [nio-8080-exec-2] c.m.w.m.mapper.IUserDao.getUserById : <== Total: 1 1111111111############ 2018-05-05 14:51:08.543 DEBUG 11940 --- [nio-8080-exec-2] c.m.w.m.mapper.IUserDao.getUserById : ==> Preparing: SELECT `userphone`, `username`, `password`, `headimagepath`, `sex`, `childAge`, `heartTime`, childName, grade, registerRationId, `hbintegral`, `dckintegral`, `jbnum` ,referrer,address, `isagent`, `activity`, `channel` , `openid`, `headurl`, `nickname`, `englishName`, `birthday`, `telephone`, `remark`, `relevanceCC`, `equipmentflag` FROM user WHERE userphone =? LIMIT 0, 1000 ; 2018-05-05 14:51:08.543 DEBUG 11940 --- [nio-8080-exec-2] c.m.w.m.mapper.IUserDao.getUserById : ==> Parameters: 18550444038(String) 2018-05-05 14:51:08.570 DEBUG 11940 --- [nio-8080-exec-2] c.m.w.m.mapper.IUserDao.getUserById : <== Total: 1 222222222############ 消费消息: User{arr=null, userphone='18550444038', username='武la福', password='e10adc3949ba59abbe56e057f20f883e', headimagepath='http://qinmi-10040507.cos.ap-shanghai.myqcloud.com/152446583644989_769675.jpg', sex=1, childAge=1, heartTime='2018-04-16 10:39', childName='武la福', grade='0', registerRationId='null', hbintegral=0, dckintegral=0, jbnum=0, referrer='18501230041', orders=null, address='null', size=0, money=0.0, isagent=0, activity='null', channel='null', openid='null', headurl='null', nickname='null', englishName='null', birthday='2017-04-23', telephone='null', remark='null', relevanceCC='null', equipmentflag=0}2018-05-05T14:51:08.718
整合发布订阅模式:
1.配置主题
@Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { /* @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("*.html").addResourceLocations("classpath:/templates/"); }*/ @Bean public Topic userTopic(){ return new ActiveMQTopic("user.topic"); } }
2.配置生产者
@Component public class Producer { @Autowired private JmsTemplate jmsTemplate; @Autowired private Topic topic; public void Send(User user){ jmsTemplate.convertAndSend(this.topic,user); } }
3.配置多个消费者,订阅同一个主题
@Component public class Customer1 { @JmsListener(destination = "user.topic") public void receive(User user){ System.out.println("Customer1"+user); } }
@Component public class Customer2 { @JmsListener(destination = "user.topic") public void receive(User user){ System.out.println("Customer2"+user); } }
4.开启对发布订阅的支持
因为springboot 默认支持的是queue,所以要使用topic需要手动设置
## springboot 默认activemq是queue方式,如果要使用topic需要自己指定
jms:
pub-sub-domain: false
5.修改业务代码:
@Autowired private JmsTemplate jmsTemplate; @Autowired private Producer producer; @PostMapping("/findOneUser") public JSONObject findOneUser(HttpServletRequest request){ JSONObject json = new JSONObject(); try { String userphone = request.getParameter("userphone"); User user = userService.getUserById(userphone); json = JSON.parseObject(JSON.toJSONString(user)); jmsTemplate.convertAndSend("user",user);//这个是p2p //使用topic producer.Send(user); } catch (Exception e) { e.printStackTrace(); } return json; }
6.测试:
2018-05-05 14:59:43.672 INFO 5560 --- [nio-8080-exec-1] o.a.c.c.C.[.[localhost].[/magicabc.web] : Initializing Spring FrameworkServlet 'dispatcherServlet' 2018-05-05 14:59:43.672 INFO 5560 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started 2018-05-05 14:59:43.688 INFO 5560 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 16 ms 2018-05-05 14:59:43.763 INFO 5560 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2018-05-05 14:59:44.166 INFO 5560 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2018-05-05 14:59:44.172 DEBUG 5560 --- [nio-8080-exec-1] c.m.w.m.mapper.IUserDao.getUserById : ==> Preparing: SELECT `userphone`, `username`, `password`, `headimagepath`, `sex`, `childAge`, `heartTime`, childName, grade, registerRationId, `hbintegral`, `dckintegral`, `jbnum` ,referrer,address, `isagent`, `activity`, `channel` , `openid`, `headurl`, `nickname`, `englishName`, `birthday`, `telephone`, `remark`, `relevanceCC`, `equipmentflag` FROM user WHERE userphone =? LIMIT 0, 1000 ; 2018-05-05 14:59:44.187 DEBUG 5560 --- [nio-8080-exec-1] c.m.w.m.mapper.IUserDao.getUserById : ==> Parameters: 18550444038(String) 2018-05-05 14:59:44.224 DEBUG 5560 --- [nio-8080-exec-1] c.m.w.m.mapper.IUserDao.getUserById : <== Total: 1 1111111111############ 2018-05-05 14:59:44.226 DEBUG 5560 --- [nio-8080-exec-1] c.m.w.m.mapper.IUserDao.getUserById : ==> Preparing: SELECT `userphone`, `username`, `password`, `headimagepath`, `sex`, `childAge`, `heartTime`, childName, grade, registerRationId, `hbintegral`, `dckintegral`, `jbnum` ,referrer,address, `isagent`, `activity`, `channel` , `openid`, `headurl`, `nickname`, `englishName`, `birthday`, `telephone`, `remark`, `relevanceCC`, `equipmentflag` FROM user WHERE userphone =? LIMIT 0, 1000 ; 2018-05-05 14:59:44.226 DEBUG 5560 --- [nio-8080-exec-1] c.m.w.m.mapper.IUserDao.getUserById : ==> Parameters: 18550444038(String) 2018-05-05 14:59:44.254 DEBUG 5560 --- [nio-8080-exec-1] c.m.w.m.mapper.IUserDao.getUserById : <== Total: 1 222222222############ Customer1User{arr=null, userphone='18550444038', username='武la福', password='e10adc3949ba59abbe56e057f20f883e', headimagepath='http://qinmi-10040507.cos.ap-shanghai.myqcloud.com/152446583644989_769675.jpg', sex=1, childAge=1, heartTime='2018-04-16 10:39', childName='武la福', grade='0', registerRationId='null', hbintegral=0, dckintegral=0, jbnum=0, referrer='18501230041', orders=null, address='null', size=0, money=0.0, isagent=0, activity='null', channel='null', openid='null', headurl='null', nickname='null', englishName='null', birthday='2017-04-23', telephone='null', remark='null', relevanceCC='null', equipmentflag=0} Customer2User{arr=null, userphone='18550444038', username='武la福', password='e10adc3949ba59abbe56e057f20f883e', headimagepath='http://qinmi-10040507.cos.ap-shanghai.myqcloud.com/152446583644989_769675.jpg', sex=1, childAge=1, heartTime='2018-04-16 10:39', childName='武la福', grade='0', registerRationId='null', hbintegral=0, dckintegral=0, jbnum=0, referrer='18501230041', orders=null, address='null', size=0, money=0.0, isagent=0, activity='null', channel='null', openid='null', headurl='null', nickname='null', englishName='null', birthday='2017-04-23', telephone='null', remark='null', relevanceCC='null', equipmentflag=0} 消费消息: User{arr=null, userphone='18550444038', username='武la福', password='e10adc3949ba59abbe56e057f20f883e', headimagepath='http://qinmi-10040507.cos.ap-shanghai.myqcloud.com/152446583644989_769675.jpg', sex=1, childAge=1, heartTime='2018-04-16 10:39', childName='武la福', grade='0', registerRationId='null', hbintegral=0, dckintegral=0, jbnum=0, referrer='18501230041', orders=null, address='null', size=0, money=0.0, isagent=0, activity='null', channel='null', openid='null', headurl='null', nickname='null', englishName='null', birthday='2017-04-23', telephone='null', remark='null', relevanceCC='null', equipmentflag=0}2018-05-05T14:59:44.352
topic模式成功。
但是要注意的是,由于在配置文件中将jms的使用模式。pub-sub-domain设置为true,所以之前使用的queue失效,虽然从结果上看是消费成功,但是从管理后台上可以清楚看到,它的模式变为了topic.
至于需不需要queue和topic兼容,我个人觉得这种使用场景几乎没有,topic完全可以替代。