Maven-RabbitMQ-连接池

1.导入依赖

	<dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.12.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client -->
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.20.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.14.0</version>
        </dependency>
    </dependencies>

2.自定义RabbitMQ连接池

/**
 * 自定义RabbitMQ连接池
 */
public class RabbitMqChannelPool extends GenericObjectPool<Channel> {
    public RabbitMqChannelPool(PooledObjectFactory<Channel> factory) {
        super(factory);
    }

    public RabbitMqChannelPool(PooledObjectFactory<Channel> factory, GenericObjectPoolConfig config) {
        super(factory, config);
    }

    public RabbitMqChannelPool(PooledObjectFactory<Channel> factory, GenericObjectPoolConfig config, AbandonedConfig abandonedConfig) {
        super(factory, config, abandonedConfig);
    }
}

3.自定义RabbitMQ连接池工厂

/**
 * 自定义RabbitMQ连接池工厂
 */
public class RabbitMqChannelPoolFactory implements PooledObjectFactory<Channel> {
    private Connection connection;

    public RabbitMqChannelPoolFactory(){
        try {
            //创建连接工厂
            ConnectionFactory factory = new ConnectionFactory();
            //设置host
            factory.setHost("127.0.0.1");
            factory.setPort(5672);
            factory.setUsername("admin");
            factory.setPassword("admin");
            factory.setVirtualHost("/");
            factory.setConnectionTimeout(15000);
            connection = factory.newConnection();
        } catch (IOException | TimeoutException e) {
            e.printStackTrace();
        }
    }

    @Override
    public PooledObject<Channel> makeObject() throws Exception {
        // 池对象创建实例化资源
        return new DefaultPooledObject<>(connection.createChannel());
    }

    @Override
    public void destroyObject(PooledObject<Channel> p) throws Exception {
        // 池对象销毁资源
        if (p != null && p.getObject() != null && p.getObject().isOpen()) {
            p.getObject().close();
        }
    }

    @Override
    public boolean validateObject(PooledObject<Channel> p) {
        // 验证资源是否可用
        return p.getObject() != null && p.getObject().isOpen();
    }

    @Override
    public void activateObject(PooledObject<Channel> p) {

    }

    @Override
    public void passivateObject(PooledObject<Channel> p) {

    }
}

4.channel管理

/**
 * channel管理
 **/
public class RabbitMqChannelService {
    private RabbitMqChannelPool pool;

    public static RabbitMqChannelService getInstance() {
        return SingletonHolder.INSTANCE;
    }

    /**
     * 获取channel对象
     * pool.borrowObject()是线程安全的
     *
     * @return 结果
     * @throws Exception 异常
     */
    public Channel getChannel() throws Exception {
        return pool.borrowObject();
    }

    /**
     * 归还channel对象
     *
     * @param channel 结果
     */
    public void returnChannel(Channel channel) {
        pool.returnObject(channel);
    }

    private static class SingletonHolder {
        private final static RabbitMqChannelService INSTANCE = new RabbitMqChannelService();
    }

    private RabbitMqChannelService() {
        initPool();
    }

    /**
     * 初始化pool
     */
    private void initPool() {
        RabbitMqChannelPoolFactory factory = new RabbitMqChannelPoolFactory();
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        // 设置最大连接数
        config.setMaxTotal(300);
        // 最大空闲连接数
        config.setMaxIdle(20);
        // 最小空闲连接数
        config.setMinIdle(10);
        // 空闲连接检测周期
        config.setTimeBetweenEvictionRunsMillis(6000);
        // 达到此空闲时间后,连接将被移除
        config.setSoftMinEvictableIdleTimeMillis(20000);
        // 连接资源耗尽后最大等待时间
        config.setMaxWaitMillis(10000);

        pool = new RabbitMqChannelPool(factory, config);
    }
}

5.RabbitMQ生产者

/**
 * RabbitMQ生产者
 */
public class RabbitMqProducer {

    private String queueName;

    public RabbitMqProducer(String queueName) {
        this.queueName = queueName;
    }

    /**
     * 发送信息
     *
     * @param obj 发送的内容
     */
    public void sendMessage(Serializable obj) {
        RabbitMqChannelService rabbitMqChannelService = RabbitMqChannelService.getInstance();
        Channel channel = null;
        try {
            channel = rabbitMqChannelService.getChannel();
            // 为这个通道申明一个队列,如果这个队列不存在,他将在服务器上创建
            channel.queueDeclare(queueName, true, false, false, null);
            channel.basicPublish("", queueName, null, SerializationUtils.serialize(obj));
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        } finally {
            if (null != channel) {
                rabbitMqChannelService.returnChannel(channel);
            }
        }
    }
}

6.RabbitMQ消费者

/**
 * RabbitMQ消费者
 */
public class RabbitMqConsumer implements Consumer {

    private static String queueName;

    private Channel channel;

    private RabbitMqConsumer() {
        init();
    }

    private static class SingletonHolder {
        private static final RabbitMqConsumer INSTANCE = new RabbitMqConsumer();
    }

    public static RabbitMqConsumer getInstance(String queueName) {
        if (null == RabbitMqConsumer.queueName) {
            RabbitMqConsumer.queueName = queueName;
        }

        return SingletonHolder.INSTANCE;
    }

    /**
     * 设置接收消息queue
     */
    private void init() {
        try {
            channel = RabbitMqChannelService.getInstance().getChannel();
            System.out.println("启动RabbitMQ监听器:" + channel + "监听QUEUE【" + queueName + "】");
            // 为这个通道申明一个队列,如果这个队列不存在,他将在服务器上创建,防止不存在时报错
            channel.queueDeclare(queueName, true, false, false, null);
            // 开启接收信息,自动确认
            channel.basicConsume(queueName, true, this);
            // 开启接收信息,手动确认
            // channel.basicQos(0, 1, false); // 限流-一次只取一条
            // channel.basicConsume(queueName, false, this);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        } finally {
            if (null != channel) {
                System.out.println("channel ---》" + channel);
                // 不能归还,归还后有可能被关闭导致消费者阻塞
//                rabbitMqChannelService.returnChannel(channel);
            }
        }

    }

    /**
     * 当用户注册时调用
     */
    @Override
    public void handleCancelOk(String consumerTag) {
        System.out.println("Consumer " + consumerTag + " registered");
    }

    /**
     * 当有可用新消息时调用
     */
    @Override
    @SuppressWarnings("unchecked")
    public void handleDelivery(String consumerTag, Envelope env, AMQP.BasicProperties props, byte[] body) {
        SimpleDateFormat sdf = new SimpleDateFormat("", Locale.SIMPLIFIED_CHINESE);
        sdf.applyPattern("yyyy年MM月dd日 HH时mm分ss秒");
        System.out.println("------------------------------[{}]MQ监听器执行开始[{}]---------------------------");
        System.out.println("队列名称:" + env.getRoutingKey());
        System.out.println("当前时间:" + sdf.format(System.currentTimeMillis()));
        Map<String, String> map = (HashMap<String, String>) SerializationUtils.deserialize(body);
        System.out.println("接收消息:" + map.toString());
        System.out.println("------------------------------------------------------------------------------");
        //     channel.basicAck(env.getDeliveryTag(), false);
        System.out.println("------------------------------[{}]MQ监听器执行结束[{}]---------------------------");
        System.out.println("队列名称:" + env.getRoutingKey());
        System.out.println("当前时间:" + sdf.format(System.currentTimeMillis()));
        System.out.println("------------------------------------------------------------------------------");
    }

    @Override
    public void handleCancel(String consumerTag) {
    }

    @Override
    public void handleConsumeOk(String consumerTag) {
    }

    @Override
    public void handleRecoverOk(String consumerTag) {
    }


    @Override
    public void handleShutdownSignal(String consumerTag, ShutdownSignalException arg1) {
    }
}

7.测试

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        String queueName = "testQueue";
        // 需要提前启动消费者监听queue,否则监听不到生产者生产的消息
        RabbitMqConsumer.getInstance(queueName);
        // 启动rabbitMq生产者
        RabbitMqProducer producer = new RabbitMqProducer(queueName);
        Map<String, String> map = new HashMap<>(16);
        map.put("date", "date");
        map.put("time", "time");
        map.put("userId", "userId");
        producer.sendMessage((Serializable) map);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值