WEB项目集成 ROCKETMQ

 1.pom.xm



            org.apache.rocketmq
            rocketmq-client
                4.3.0
         

 


 

 

2.spring-mvc-mq.consumer.xml(消费者配置)





    
    
        
          
        
        
        
        
        
        
            
                
                    
                        
                    
                
            
        
    


3.spring-mvc-mq.producer.xml(生成者配置)





    
    
        
        
        
    

4.MQEntity(消息父类)

 


package com.nobuy.entity.mq;


import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.persistence.Entity;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

/**
 * @author Administrator
 *
 */
public class MQEntity implements java.io.Serializable{

    private static final long serialVersionUID = -2551495105702956945L;
    
    private Map extObj = new LinkedHashMap();
    
    private String mqId ;
    
    private String mqKey;

    /**
     * 添加附加字段
     * @param key
     * @param value
     */
    public void addExt(String key , Object value){
        extObj.put(key, value);
    }
    
    /**
     * 获取附加字段
     * @param key
     */
    public void getExt(String key ){
        extObj.get(key);
    }

    public String getMqId() {
        return mqId;
    }

    public void setMqId(String mqId) {
        this.mqId = mqId;
    }

    public String getMqKey() {
        return mqKey;
    }

    public void setMqKey(String mqKey) {
        this.mqKey = mqKey;
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
}

5.LoanRequest.java(测试消费对象)


package com.nobuy.entity.mq;


import java.math.BigDecimal;
import java.util.Date;

import javax.persistence.Entity;

import com.nobuy.entity.mq.MQEntity;

/**
 * 
 * @author Administrator
 */
public class LoanRequest extends MQEntity{

    private static final long serialVersionUID = 5339647958993664240L;
    
    /** 贷款申请编号,前段生存的唯一编号 */
    private String applyNo;
    
    /** 额度编号   */
    private String creditNo;
    
    /**贷款人员工号 */
    private String employeeNo;
    
    /** 贷款金额 */
    private BigDecimal payamt;
    
    /**还款方式
     *     0:多次还本、分次付息
        1:分次还本、分次付息
        2:等额本金
     **/
    private String repayMode;
    
    /**还款期限  1个月、3个月、6个月、9个月、12个月、15个月、18个月、24个月;
     * 1,3, 6
     * */
    private String oprTerm;
    
    /**用途*/
    private String lendPurpose;
    
    //申请日期
    private Date applyDate;
    
    //贷款卡号
    private String loanCardNo;
    
    //开户行
    private String bankName;
    
    //联行行号
    private String bankCode ;
    
    public String getBankName() {
        return bankName;
    }

    public void setBankName(String bankName) {
        this.bankName = bankName;
    }

    public String getBankCode() {
        return bankCode;
    }

    public void setBankCode(String bankCode) {
        this.bankCode = bankCode;
    }

    public String getEmployeeNo() {
        return employeeNo;
    }

    public void setEmployeeNo(String employeeNo) {
        this.employeeNo = employeeNo;
    }

    public BigDecimal getPayamt() {
        return payamt;
    }

    public void setPayamt(BigDecimal payamt) {
        this.payamt = payamt;
    }

    public String getRepayMode() {
        return repayMode;
    }

    public void setRepayMode(String repayMode) {
        this.repayMode = repayMode;
    }

    public String getOprTerm() {
        return oprTerm;
    }

    public void setOprTerm(String oprTerm) {
        this.oprTerm = oprTerm;
    }

    public String getLendPurpose() {
        return lendPurpose;
    }

    public void setLendPurpose(String lendPurpose) {
        this.lendPurpose = lendPurpose;
    }

    public String getLoanCardNo() {
        return loanCardNo;
    }

    public void setLoanCardNo(String loanCardNo) {
        this.loanCardNo = loanCardNo;
    }

    public String getApplyNo() {
        return applyNo;
    }

    public void setApplyNo(String applyNo) {
        this.applyNo = applyNo;
    }

    public String getCreditNo() {
        return creditNo;
    }

    public void setCreditNo(String creditNo) {
        this.creditNo = creditNo;
    }

    public Date getApplyDate() {
        return applyDate;
    }

    public void setApplyDate(Date applyDate) {
        this.applyDate = applyDate;
    }


    
}

6.IConsumer(消费端接口)


package com.nobuy.service.mq;

import org.apache.rocketmq.common.message.MessageExt;

public interface IConsumer {

    /**
     * 消费端解析消息
     * @param msg
     */
    void handlerMessage( MessageExt msg );
    
}

7.IProducer(生产者接口)


package com.nobuy.service.mq;


import org.apache.rocketmq.client.producer.SendCallback;

import com.nobuy.entity.mq.MQEntity;

/**
 * mq消息生产者
 * @author Administrator
 *
 */
public interface IProducer {
    
    /**
     * 同步发送MQ
     * @param topic
     * @param entity
     */
    public void send(String topic, MQEntity entity);

    /**
     * 发送MQ,提供回调函数,超时时间默认3s
     * @param topic 
     * @param entity
     * @param sendCallback
     */
    public void send( String topic, MQEntity entity, SendCallback sendCallback );

    /**
     * 单向发送MQ,不等待服务器回应且没有回调函数触发,适用于某些耗时非常短,但对可靠性要求并不高的场景,例如日志收集。
     * @param topic
     * @param entity
     */
    public void sendOneway(String topic, MQEntity entity);
    
}

8.RocketMqProducerImpl(生成者接口实现)

 


package com.nobuy.service.impl.mq;

import java.text.MessageFormat;
import java.util.UUID;

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.common.message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

import com.nobuy.entity.mq.MQEntity;
import com.nobuy.service.mq.IProducer;
import com.nobuy.utils.mq.SerializableUtil;

import net.sf.json.JSONObject;

public class RocketMqProducerImpl implements IProducer, InitializingBean{
    
    private static Logger logger = LoggerFactory.getLogger(RocketMqProducerImpl.class);
            
    private String namesrvAddr;

    private String producerGroup;

    private Boolean retryAnotherBrokerWhenNotStoreOK;

    private DefaultMQProducer producer;

    

    /**
     * spring 容器初始化所有属性后调用此方法
     */
    public void afterPropertiesSet() throws Exception {
        producer = new DefaultMQProducer();
        producer.setProducerGroup( this.producerGroup );
        producer.setNamesrvAddr( this.namesrvAddr );
        producer.setRetryAnotherBrokerWhenNotStoreOK( this.retryAnotherBrokerWhenNotStoreOK );
//        producer.setVipChannelEnabled(false);
        /*
         * Producer对象在使用之前必须要调用start初始化,初始化一次即可
         * 注意:切记不可以在每次发送消息时,都调用start方法          */         producer.start();         logger.info( "[{}:{}] start successd!",producerGroup,namesrvAddr );     }          /**      * 销毁      */     public void destroy() throws Exception {         if (producer != null) {             logger.info("producer: [{}:{}] end ",producerGroup,namesrvAddr);             producer.shutdown();         }     }     public void send(String topic, MQEntity entity) {         String keys = UUID.randomUUID().toString();         entity.setMqKey(keys);         String tags = entity.getClass().getName();       //  logger.info("业务:{},tags:{},keys:{},entity:{}",topic, tags, keys, entity);         String smsContent = MessageFormat.format("业务:{0},tags:{1},keys:{2},entity:{3}",topic,tags,keys,JSONObject.fromObject(entity).toString());         logger.info(smsContent);                  Message msg = new Message(topic, tags, keys,                 SerializableUtil.toByte(entity));         try {             producer.send(msg);         } catch (Exception e) {             logger.error(keys.concat(":发送消息失败"), e);             throw new RuntimeException("发送消息失败",e);         }      }     public void send(String topic, MQEntity entity, SendCallback sendCallback) {         String keys = UUID.randomUUID().toString();         entity.setMqKey(keys);         String tags = entity.getClass().getName();        // logger.info("业务:{},tags:{},keys:{},entity:{}",topic, tags, keys, entity);         String smsContent = MessageFormat.format("业务:{0},tags:{1},keys:{2},entity:{3}",topic,tags,keys,JSONObject.fromObject(entity).toString());         logger.info(smsContent);                  Message msg = new Message(topic, tags, keys,                 SerializableUtil.toByte(entity));         try {             producer.send(msg, sendCallback);         } catch (Exception e) {             logger.error(keys.concat(":发送消息失败"), e);             throw new RuntimeException("发送消息失败",e);         }      }     public void sendOneway(String topic, MQEntity entity) {         String keys = UUID.randomUUID().toString();         entity.setMqKey(keys);         String tags = entity.getClass().getName();         String smsContent = MessageFormat.format("业务:{0},tags:{1},keys:{2},entity:{3}",topic,tags,keys,JSONObject.fromObject(entity).toString());         logger.info(smsContent);         Message msg = new Message(topic, tags, keys,                 SerializableUtil.toByte(entity));         try {             producer.sendOneway(msg);         } catch (Exception e) {             logger.error(keys.concat(":发送消息失败"), e);             throw new RuntimeException("发送消息失败",e);         }     }          public void setNamesrvAddr(String namesrvAddr) {         this.namesrvAddr = namesrvAddr;     }     public void setProducerGroup(String producerGroup) {         this.producerGroup = producerGroup;     }     public void setProducer(DefaultMQProducer producer) {         this.producer = producer;     }     public void setRetryAnotherBrokerWhenNotStoreOK(             Boolean retryAnotherBrokerWhenNotStoreOK) {         this.retryAnotherBrokerWhenNotStoreOK = retryAnotherBrokerWhenNotStoreOK;     }           }


 


9.AbstractConsumer(消费者父类)

 


package com.nobuy.service.impl.mq;

import org.apache.rocketmq.common.message.MessageExt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.nobuy.entity.mq.MQEntity;
import com.nobuy.service.mq.IConsumer;
import com.nobuy.utils.mq.SerializableUtil;

public abstract class AbstractConsumer implements IConsumer {
    
    protected Logger logger = LoggerFactory.getLogger(AbstractConsumer.class);

    private String classTypeName;
    
    public void handlerMessage(MessageExt msg) {
        try {
            MQEntity entity = doStart(msg);
            execute(entity);
            doEnd(entity);
        } catch (Exception e) {
            logger.error("处理mq消息异常。",e);
        }
    }

    /**
     * 解析mq消息前置处理
     * @param msg
     * @param entity 
     * @throws ClassNotFoundException 
     */
    protected MQEntity doStart(MessageExt msg) throws ClassNotFoundException {
        Class clazz = (Class) Class.forName(classTypeName);
        return SerializableUtil.parse(msg.getBody(), clazz);
    }

    /**
     * 解析mq消息后置处理
     * @param entity
     */
    protected void doEnd(MQEntity entity) {
        
    }

    /**
     * 解析mq消息 MessageExt
     * @param entity
     */
    public abstract void execute(MQEntity entity);

    public void setClassTypeName(String classTypeName) {
        this.classTypeName = classTypeName;
    }
    
    
    
}

 

12.RocketMqConsumerImpl(消费者)

 


package com.nobuy.service.impl.mq;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;


public class RocketMqConsumerImpl implements InitializingBean {

    private static final Logger logger = LoggerFactory.getLogger(RocketMqConsumerImpl.class);
    
    private DefaultMQPushConsumer consumer;
    
    private String namesrvAddr;

    private String consumerGroup;

    private String messageModel;

    private String messageListener;

    private Map handlermap = new HashMap();

    private void initializingMessageSelector() throws InterruptedException, MQClientException {
        consumer = new DefaultMQPushConsumer();
        if( this.consumerGroup != null && this.consumerGroup.trim().length() > 0 ) {
            consumer.setConsumerGroup( this.consumerGroup );
            logger.debug( "set consumer group " + this.consumerGroup );
        }
        consumer.setNamesrvAddr( this.namesrvAddr );
        consumer.setConsumeMessageBatchMaxSize( 1 );
        logger.debug( "set consumer name server address " + this.namesrvAddr );
        logger.debug( "set consumer message batch max size " + 1 );

        if( "BROADCASTING".equals( messageModel ) ) {
            consumer.setMessageModel( MessageModel.BROADCASTING );
            logger.debug( "set consumer message model BROADCASTING" );
        } else {
             if( "CLUSTERING".equals( messageModel ) ) {
                consumer.setMessageModel( MessageModel.CLUSTERING );
                logger.debug( "set consumer message model CLUSTERING" );
            } else {
                logger.debug( "set consumer message model should be BROADCASTING or CLUSTERING" );
                throw new RuntimeException( "set consumer message model should be BROADCASTING or CLUSTERING" );
            }
        }
        /**
         * 订阅指定topic下所有消息
         * 注意:一个consumer对象可以订阅多个topic          */         if( handlermap != null && !handlermap.isEmpty() ) {             for( String topic : handlermap.keySet() ) {                 consumer.subscribe( topic, "*" );                 logger.debug( "consumer subscribe topic " + topic + " *" );             }         } else {             logger.debug( "you should provide at least one message handler." );             throw new RuntimeException( "you should provide at least one message handler." );         }         /**          * 设置Consumer第一次启动是从队列头部开始消费还是队列尾部开始消费
         * 如果非第一次启动,那么按照上次消费的位置继续消费          */         consumer.setConsumeFromWhere( ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET );         if( "CONCURRENTLY".equals( messageListener ) ) {             consumer.registerMessageListener( new MessageListenerConcurrently() {                 /**                  * 默认msgs里只有一条消息,可以通过设置consumeMessageBatchMaxSize参数来批量接收消息                  */                 public ConsumeConcurrentlyStatus consumeMessage( final List msgs, final ConsumeConcurrentlyContext context ) {                     try {                         if( msgs != null && !msgs.isEmpty() ) {                             for( MessageExt msg : msgs ) {                                 logger.debug( String.format( "start consum message: message:id:%s topic:%s tags:%s ", msg.getMsgId(), msg.getTopic(), msg.getTags()) );                                 AbstractConsumer handler = handlermap.get( msg.getTopic() );                                 if( handler != null ) {                                     handler.handlerMessage( msg );                                 }                                 logger.debug( String.format( "consume message success! message:id:%s topic:%s tags:%s ", msg.getMsgId(), msg.getTopic(), msg.getTags()) );                             }                         }                         return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;                     } catch( Exception e ) {                         logger.error( "consume message error!", e );                         return ConsumeConcurrentlyStatus.RECONSUME_LATER;                     }                 }             } );         } else             if( "ORDERLY".equals( messageListener ) ) {             consumer.registerMessageListener( new MessageListenerOrderly() {                 /**                  * 默认msgs里只有一条消息,可以通过设置consumeMessageBatchMaxSize参数来批量接收消息                  */                 public ConsumeOrderlyStatus consumeMessage( final List msgs, final ConsumeOrderlyContext context ) {                     try {                         if( msgs != null && !msgs.isEmpty() ) {                             for( MessageExt msg : msgs ) {                                 logger.debug( String.format( "start consum message: message:id:%s topic:%s tags:%s message:%s", msg.getMsgId(), msg.getTopic(), msg.getTags(), new String( msg.getBody() ) ) );                                 AbstractConsumer handler = handlermap.get( msg.getTopic() );                                 if( handler != null ) {                                     handler.handlerMessage( msg );                                 }                                 logger.debug( String.format( "consume message success! message:id:%s topic:%s tags:%s message:%s", msg.getMsgId(), msg.getTopic(), msg.getTags(), new String( msg.getBody() ) ) );                             }                         }                         return ConsumeOrderlyStatus.SUCCESS;                     } catch( Exception e ) {                         logger.error( "consume message error!", e );                         return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;                     }                 }             } );         }         /**          * Consumer对象在使用之前必须要调用start初始化,初始化一次即可
         */         consumer.start();         logger.debug( "consumer start successd!" );     }     public void afterPropertiesSet() throws Exception {         initializingMessageSelector();     }          public void destroy() throws Exception {         if (consumer != null) {             consumer.shutdown();             logger.debug( "consumer shutdown!" );         }     }     public void setNamesrvAddr( String namesrvAddr ) {         this.namesrvAddr = namesrvAddr;     }     public void setConsumerGroup( String consumerGroup ) {         this.consumerGroup = consumerGroup;     }     public void setMessageModel( String messageModel ) {         this.messageModel = messageModel;     }     public void setMessageListener( String messageListener ) {         this.messageListener = messageListener;     }     public void setHandlermap( Map handlermap ) {         this.handlermap = handlermap;     }      }

13.LoanRequestConsumer(消费者实现)


package com.nobuy.service.impl.mq;

import com.nobuy.entity.mq.MQEntity;

public class LoanRequestConsumer extends AbstractConsumer {

    @Override
    public void execute(MQEntity entity) {
        System.out.println("LoanRequestConsumer 消费消息");
        System.out.println(entity.toString());
    }

}

14SerializableUtil(工具类)


package com.nobuy.utils.mq;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

/**
 * java的序列化和反序列化
 * 
 * @author Administrator
 */
public class SerializableUtil {

    @SuppressWarnings("unchecked")
    public static  T parse(byte[] rec, Class classType) {
        ByteArrayInputStream arrayInputStream = null;
        ObjectInputStream objectInputStream = null;
        try {
            arrayInputStream = new ByteArrayInputStream(rec);
            objectInputStream = new ObjectInputStream(arrayInputStream);
            T t = (T) objectInputStream.readObject();
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            closeQuietly(arrayInputStream);
            closeQuietly(objectInputStream);
        }
        return null;
    }

    public static byte[] toByte(Object obj) {
        ByteArrayOutputStream arrayOutputStream = null;
        ObjectOutputStream objectOutputStream = null;
        try {
            arrayOutputStream = new ByteArrayOutputStream();
            objectOutputStream = new ObjectOutputStream(arrayOutputStream);
            objectOutputStream.writeObject(obj);
            objectOutputStream.flush();
            byte[] rtn = arrayOutputStream.toByteArray();
            return rtn;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            closeQuietly(objectOutputStream);
            closeQuietly(arrayOutputStream);
        }
        return null;
    }
    
    public static void closeQuietly(InputStream in){
        if(in!=null){
            try {
                in.close();
            } catch (Exception e) {
            }
        }
    }
    
    public static void closeQuietly(OutputStream out){
        if(out!=null){
            try {
                out.close();
            } catch (Exception e) {
            }
        }
    }
    
    

}

 


15.ProducerTest(生成者test)


package com.nobuy.mq;


import java.math.BigDecimal;
import java.util.Date;

import org.jeecgframework.core.util.ApplicationContextUtil;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import com.nobuy.entity.mq.LoanRequest;
import com.nobuy.service.mq.IProducer;
import com.nobuy.service.pay.PayServiceI;


@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {"classpath*:spring*.xml"})
public class ProducerTest {
    
    @Autowired
    private IProducer producer;

    @Test
    public void testSendMq() {
        LoanRequest loanRequest= new LoanRequest();
        loanRequest.setApplyNo("loan00005432231");
        loanRequest.setCreditNo("credit0000001");
        loanRequest.setEmployeeNo("test1");
        loanRequest.setLendPurpose("test1");
        loanRequest.setLoanCardNo("362226197403220017");
        loanRequest.setBankCode(null);
        loanRequest.setBankName(null);
        loanRequest.setOprTerm("12");
        loanRequest.setPayamt(new BigDecimal(100000));
        loanRequest.setRepayMode("0"); //0   1    2
        loanRequest.setApplyDate(new Date());
        producer.send("loanRequest", loanRequest);
    }
    
}

转载后稍加修改

出自:https://www.cnblogs.com/yun965861480/p/7384915.html

 

你可能感兴趣的:(java)