package com.meritdata.cloud.cosp.rabbitmq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* @author : xuxw.
* Create Date : 2021-05-07
* Create Time : 19:37
* Description : Rabbitmq基础配置
* Project Name : COSP
* Package Name : com.meritdata.cloud.cosp.rabbitmq
*/
@Configuration
@Slf4j
@ConfigurationProperties(prefix = "cosp.rabbitmq", ignoreUnknownFields = true)
public class RabbitmqConfig {
/**
* 挂载点
*/
private String virtualHost;
/**
* IP地址
*/
private String host;
/**
* 端口
*/
private int port;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 最小的消费者数量
*/
private int listenerSimpleConcurrency;
/**
* 最大的消费者数量
*/
private int listenerSimpleMaxConcurrency;
/**
* 指定一个请求能处理多少个消息,如果有事务的话,必须大于等于transaction数量.
*/
private int listenerSimplePrefetch;
private Map<String, String> queueNames =new HashMap<>();
@Bean(name = "rabbitmqConnectionFactory")
public CachingConnectionFactory rabbitmqCachingConnectionFactory() {
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
cachingConnectionFactory.setHost(host);
cachingConnectionFactory.setPort(port);
cachingConnectionFactory.setUsername(username);
cachingConnectionFactory.setPassword(password);
cachingConnectionFactory.setVirtualHost(virtualHost);
cachingConnectionFactory.setPublisherReturns(true);
cachingConnectionFactory.setPublisherConfirms(true);
return cachingConnectionFactory;
}
/**
* singleton can't set multi times callback
* @return
*/
@Bean(name = "rabbitmqTemplate")
public RabbitTemplate rabbitmqTemplate(@Qualifier("rabbitmqConnectionFactory")CachingConnectionFactory cachingConnectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(cachingConnectionFactory);
rabbitTemplate.setMandatory(true);
rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
if (ack) {
log.info("rabbitmq message send succeed:correlationData({}),ack({}),cause({})",correlationData, ack, cause);
} else {
log.info("rabbitmq message send failed:correlationData({}),ack({}),cause({})",correlationData, ack, cause);
}
});
rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
log.info("rabbitmq message lose:exchange({}),route({}),replyCode({}),replyText({}),message:{}", exchange, routingKey, replyCode, replyText, message);
});
return rabbitTemplate;
}
@Bean(name = "rabbitmqSingleListenerContainer")
public SimpleRabbitListenerContainerFactory rabbitmqSingleListenerContainer(SimpleRabbitListenerContainerFactoryConfigurer factoryConfigurer,
@Qualifier("rabbitmqConnectionFactory")CachingConnectionFactory cachingConnectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(cachingConnectionFactory);
factory.setMessageConverter(new Jackson2JsonMessageConverter());
factory.setConcurrentConsumers(1);
factory.setMaxConcurrentConsumers(1);
factory.setPrefetchCount(1);
factory.setTxSize(1);
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
return factory;
}
@Bean(name = "rabbitmqMultiListenerContainer")
public SimpleRabbitListenerContainerFactory rabbitmqMultiListenerContainer(SimpleRabbitListenerContainerFactoryConfigurer factoryConfigurer,
@Qualifier("rabbitmqConnectionFactory")CachingConnectionFactory cachingConnectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factoryConfigurer.configure(factory, cachingConnectionFactory);
factory.setMessageConverter(new Jackson2JsonMessageConverter());
factory.setConcurrentConsumers(listenerSimpleConcurrency);
factory.setMaxConcurrentConsumers(listenerSimpleMaxConcurrency);
factory.setPrefetchCount(listenerSimplePrefetch);
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
return factory;
}
public String getVirtualHost() {
return virtualHost;
}
public void setVirtualHost(String virtualHost) {
this.virtualHost = virtualHost;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getListenerSimpleConcurrency() {
return listenerSimpleConcurrency;
}
public void setListenerSimpleConcurrency(int listenerSimpleConcurrency) {
this.listenerSimpleConcurrency = listenerSimpleConcurrency;
}
public int getListenerSimpleMaxConcurrency() {
return listenerSimpleMaxConcurrency;
}
public void setListenerSimpleMaxConcurrency(int listenerSimpleMaxConcurrency) {
this.listenerSimpleMaxConcurrency = listenerSimpleMaxConcurrency;
}
public int getListenerSimplePrefetch() {
return listenerSimplePrefetch;
}
public void setListenerSimplePrefetch(int listenerSimplePrefetch) {
this.listenerSimplePrefetch = listenerSimplePrefetch;
}
public Map<String, String> getQueueNames() {
return queueNames;
}
public void setQueueNames(Map<String, String> queueNames) {
this.queueNames = queueNames;
}
}
package com.meritdata.cloud.cosp.rabbitmq;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
/**
* @author : xuxw.
* Create Date : 2021-05-08
* Create Time : 10:35
* Description : rabbitmq工具类
* Project Name : COSP
* Package Name : com.meritdata.cloud.cosp.rabbitmq
*/
@Slf4j
@Component
public class RabbitmqUtil {
/**
* @param rabbitTemplate
* @param exchangeName
* @param content
* @param <T>
*/
public <T> void sendMessage(RabbitTemplate rabbitTemplate, String exchangeName, String content) {
this.sendMessage(rabbitTemplate, exchangeName, null, content);
}
/**
* Message persistent: Set the deliveryMode of the message to 2 and the consumer can continue to consume
* the messages after persistence after restarting;
* Use convertAndSend to send a message. The message is persistent by default. The following is the source code:
* new MessageProperties() --> DEFAULT_DELIVERY_MODE = MessageDeliveryMode.PERSISTENT --> deliveryMode = 2;
*
* @param rabbitTemplate
* @param exchangeName
* @param routingKeyName
* @param content
* @param <T>
*/
public <T> void sendMessage(RabbitTemplate rabbitTemplate, String exchangeName, String routingKeyName, String content) {
// log.info("message send :exchangeName({}), routingKeyName({}), content({}), flag({})", exchangeName, routingKeyName, content);
MessageProperties properties = new MessageProperties();
properties.setContentType(MessageProperties.CONTENT_TYPE_JSON);
try {
if (StringUtils.isNotEmpty(routingKeyName)) {
rabbitTemplate.convertAndSend(exchangeName,
routingKeyName,
MessageBuilder.withBody(content.getBytes("UTF-8")).andProperties(properties).build());
} else {
rabbitTemplate.convertAndSend(exchangeName,
MessageBuilder.withBody(content.getBytes("UTF-8")).andProperties(properties).build());
}
} catch (Exception e) {
log.error("error message :", e);
}
}
}
package com.meritdata.cloud.cosp.profilemanagement.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.meritdata.cloud.cosp.common.entity.CustGroup;
import com.meritdata.cloud.cosp.common.utils.TextCompressUtil;
import com.meritdata.cloud.cosp.profilemanagement.entity.CustGroupRel;
import com.meritdata.cloud.cosp.profilemanagement.service.IGroupExternalTransport;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.meritdata.cloud.cosp.rabbitmq.RabbitmqConfig;
import com.meritdata.cloud.cosp.rabbitmq.RabbitmqUtil;
import java.util.*;
import java.util.stream.Collectors;
/**
- @Author 72745
- @Date 2021/5/7 18:52
- @Version 1.0
- 发送端
*/
@Service
@Slf4j
public class GroupExternalTransportService implements IGroupExternalTransport {
@Autowired
private RabbitmqUtil rabbitmqUtil;
@Autowired
private RabbitmqConfig rabbitmqConfig;
@Autowired
@Qualifier("rabbitmqTemplate")
private RabbitTemplate rabbitmqTemplate;
// 队列名
private final String QUEUE_NAME="cust-group-transport";
@Override
@Async
public void transport(CustGroup group, List<CustGroupRel> groupRels) {
try {
String queuename = rabbitmqConfig.getQueueNames().get(QUEUE_NAME);
if(Strings.isBlank(queuename)){
return;
}
Date updateDate = group.getUpdateDate();
System.out.println(updateDate);
JSONObject map = new JSONObject();
map.put("id", group.getId());
map.put("name", group.getName());
map.put("typeId", group.getTypeId());
map.put("custNum", group.getCustNum());
map.put("status", group.getStatus());
map.put("createUser", group.getCreateUser());
map.put("createDate", group.getCreateDate());
map.put("updateUser", group.getUpdateUser());
map.put("updateDate", group.getUpdateDate());
map.put("createUserName", group.getCreateUsername());
JSONArray custGroupList = new JSONArray();
for (CustGroupRel c : groupRels) {
JSONObject jsonObject = JSON.parseObject(c.getCustJson());
custGroupList.add(jsonObject);
}
map.put("custList", custGroupList);
String base64 = TextCompressUtil.compressBase64(map.toString());
rabbitmqUtil.sendMessage(rabbitmqTemplate, queuename, base64);
} catch (Exception e) {
log.error("mq发送消息失败",e);
}
}
}
package com.meritdata.cloud.cosp.bank.service.impl;
import com.meritdata.cloud.cosp.bank.config.ThreadConfig;
import com.meritdata.cloud.cosp.bank.service.IRabbitCustGroupService;
import com.meritdata.cloud.cosp.bank.service.IRabbitmqMoneyService;
import com.meritdata.cloud.cosp.bank.service.IRabbitmqService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @author : xuxw.
* Create Date : 2021-05-08
* Create Time : 13:43
* Description : rabbitmq消息处理类 接收端
* Project Name : COSP
* Package Name : com.meritdata.cloud.cosp.bank.service.impl
*/
@Slf4j
@Service
@Component
public class RabbitmqService implements IRabbitmqService {
@Value("${cosp.rabbitmq.queue-names.cust-group-transport:}")
private String[] queueNames;
@Autowired
private IRabbitCustGroupService iRabbitCustGroupService;
@Autowired
private IRabbitmqMoneyService iRabbitmqMoneyService;
@Autowired
private ThreadConfig threadConfig;
@Bean
public String[] queueNames() {
return queueNames;
}
@Override
@RabbitListener(queues = "#{queueNames}")
@RabbitHandler
@Transactional
public void process(Object data) {
ThreadPoolTaskExecutor cachedThreadPool = threadConfig.asyncServiceExecutor();
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
iRabbitmqMoneyService.process(data);
}
});
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
iRabbitCustGroupService.process(data);
}
});
}
}
rabbitmq配置
cosp.rabbitmq.virtual-host=/
cosp.rabbitmq.host=127.0.0.1
cosp.rabbitmq.port=5672
cosp.rabbitmq.username=msdp
cosp.rabbitmq.password=msdp
cosp.rabbitmq.listener-simple-concurrency=5
cosp.rabbitmq.listener-simple-max-concurrency=20
cosp.rabbitmq.listener-simple-prefetch=5
cosp.rabbitmq.queue-names.cust-group-transport=CUST_GROUP
cosp.rabbitmq.queue-name.cust-static-tag-queue=CUST_STATICS_TAG_QUEUE
package com.meritdata.cloud.cosp.profilemanagement.controller;
import com.meritdata.cloud.cosp.rabbitmq.RabbitmqUtil;
import com.meritdata.cloud.resultmodel.ResultBody;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.UUID;
/**
-
@author : xuxw.
-
Create Date : 2021-05-08
-
Create Time : 13:30
-
Description : rabbitmq rest测试接口
-
Project Name : COSP
-
Package Name : com.meritdata.cloud.cosp.profilemanagement.controller
*/
@RequestMapping("/cosp/rabbitmq-test")
@RestController
@CrossOrigin
@Slf4j
@Api(value = “Rabbitmq测试接口”, tags = “Rabbitmq测试接口”)
public class RabbitmqController {/**
- 这里写死了,实际开发请按照代码规范编写,从nacos上获取
- 这里定义的queue名称要和消费端的队列名称一致,否则消费端获取不到消息,
- 如cosp-bank-service模块的RabbitmqService类上定义的队列名称和这里是一样的
*/
// @Value("${cosp.rabbitmq.admin.queue:}")
private String defaultQueue = “CUST_GROUP”;
@Autowired
private RabbitmqUtil rabbitmqUtil;@Autowired
@Qualifier(“rabbitmqTemplate”)
private RabbitTemplate rabbitmqTemplate;@ApiOperation(value = “Rabbitmq测试接口—”)
@ResponseBody
@RequestMapping(value = “/send-message”, method = RequestMethod.GET)
public ResultBody sendMessage(){
ResultBody result = new ResultBody();
try {
result.setSuccess(true);
JSONObject jsonObject = new JSONObject();
jsonObject.put(“id”, UUID.randomUUID().toString());
jsonObject.put(“data”, “测试消息” + new Date().getTime());
rabbitmqUtil.sendMessage(rabbitmqTemplate, defaultQueue, jsonObject.toString());
}catch (Exception e){
log.error(“Rabbitmq测试接口失败”,e);
return ResultBody.failure(“Rabbitmq测试接口失败”);
}
return result;
}
}