ActiveMQ学习(二)

消息的发送策略

持久化消息,默认情况下,生产者发送的消息时持久化的。消息发送到broker后,producer会等待broker对这条消息的处理情况的反馈,默认情况是同步的需要堵塞等待,效率较低可以设置消息发送端发送持久化消息的异步方式。

connectionFactory.setUseAsyncSend(true)

回执窗口大小设置,通过这个来控制borker在确认收到消息前,生产者能发送的最大数据量(字节)

connectionFactory.setProducerWindowSize()

非持久性消息,非持久化消息模式下,默认就是异步发送过程

textMessage.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENCE)

如果需要对非持久化消息的每次发送的消息都获得broker的回执的话

connectionFactory.setAlwaysSyncSend()

consumer获取消息时pull还是broker主动push?

默认情况下,mq服务器(broker)采用异步方式向客户端主动推送消息(push)。也就是说broker在向某个消费者会话推送消息后,不会等待消费者响应消息,知道消费者处理完消息以后,主动向broker返回处理结果。

预读取消息数量:

broker端一旦有消息,就主动按照默认设置的规则推送给当前活动的消费者。每次推送都有一定的数量限制,而这个数量限制就是prefetchSize。

Queue:

持久化消息:prefetchSize:1000

非持久化消息:prefetchSize:1000

topic:

持久化消息 prefetchSize:100

非持久化消息 prefectSize:32766

假如prefetchSize=0,此时对于consumer来说,就是一个pull模式。

消息确认

ACK_TYPE,消费者和broker交换ACK指令时,还需要告诉broker ACK_TYPE。

ACK_TYPE表示确认指令的类型,broker可以根据不同的ACK_TYPE去针对当前消息做不同的应对策略

REDELIVERED_ACK_TYPE (broker会重新发送该消息)  重发侧策略

DELIVERED_ACK_TYPE  消息已经接收,但是尚未处理结束

STANDARD_ACK_TYPE  表示消息处理成功

ACK_TYPE是开发人员看不到的是底层的机制。

activeMQ结合Spring开发

Spring提供了对JMS的支持,需要添加Spring支持JMS的包

添加jar包:(接收端与发送端相同)

配置Spring文件:(接收端与发送端相同)

<bean id="connectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
         <property name="connectionFactory">
             <bean class="org.apache.activemq.ActiveMQConnectionFactory">
                 <property name="brokerURL">
                     <value>tcp://192.168.74.131:61616</value>
                 </property>
             </bean>
         </property>
         <property name="maxConnections" value="50"/>
     </bean>
     <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
         <constructor-arg index="0" value="spring-queue"/>
     </bean>

   <!--<bean id="destinationTopic" class="org.apache.activemq.command.ActiveMQTopic">
         <constructor-arg index="0" value="spring-topic"/>
     </bean>-->

     <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
         <property name="connectionFactory" ref="connectionFactory"/>
         <property name="defaultDestination" ref="destination"/>
         <property name="messageConverter">
             <bean class="org.springframework.jms.support.converter.SimpleMessageConverter"/>
         </property>
     </bean>

发送端代码:

public class SpringJmsSender {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context=
                new ClassPathXmlApplicationContext(
                        "classpath:META-INF/spring/service-jms.xml");

        JmsTemplate jmsTemplate=(JmsTemplate) context.getBean("jmsTemplate");

        jmsTemplate.send(new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                TextMessage message=session.createTextMessage();
                message.setText("Hello,mic");
                return message;
            }
        });
    }
}

接收端代码:

public class SpringJmsReceiver {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context=
                new ClassPathXmlApplicationContext(
                        "classpath:META-INF/spring/service-jms.xml");
        
        JmsTemplate jmsTemplate=(JmsTemplate) context.getBean("jmsTemplate");

        String msg=(String)jmsTemplate.receiveAndConvert();

        System.out.println(msg); 
    }
}

以上为queue方式,将其改完发布订阅模式:

修改配置文件:

<bean id="connectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
         <property name="connectionFactory">
             <bean class="org.apache.activemq.ActiveMQConnectionFactory">
                 <property name="brokerURL">
                     <value>tcp://192.168.74.131:61616</value>
                 </property>
             </bean>
         </property>
         <property name="maxConnections" value="50"/>
     </bean>
    

   <bean id="destinationTopic" class="org.apache.activemq.command.ActiveMQTopic">
         <constructor-arg index="0" value="spring-topic"/>
     </bean>

     <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
         <property name="connectionFactory" ref="connectionFactory"/>
         <property name="defaultDestination" ref="destinationTopic"/>
         <property name="messageConverter">
             <bean class="org.springframework.jms.support.converter.SimpleMessageConverter"/>
         </property>
     </bean>

再将其改为时间通知方式来配置消费者:

更改消费端Spring的配置:

<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="destination" ref="destinationTopic"/>
        <property name="messageListener" ref="messageListener"/>
    </bean>

    <bean id="messageListener" class="com.gupao.vip.mic.dubbo.jms.SpringJmsListener"/>

增加监听类:

public class SpringJmsListener implements MessageListener{

    @Override
    public void onMessage(Message message) {
        try {
            System.out.println(((TextMessage)message).getText());
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

更改启动类:

public class SpringJmsReceiver {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context=
                new ClassPathXmlApplicationContext(
                        "classpath:META-INF/spring/service-jms.xml");
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
       
    }
}

ActiveMQ支持的传输协议

client端和broker端的通讯协议

TCP可靠性高)UDP(可能会丢包) 、NIO(访问量大)、

SSL(加密)、Http 、Https 、vm

生产者与消费者协议能不一样吗?

不能,因为不同协议端口号不能一样。

如何修改协议或端口号?

在conf/activemq.xml中修改

ActiveMQ持久化存储

1.kahaDB 默认的存储方式(持久化存储,存储在根目录的kahaDB文件下),在activemq.xml中配置

2.AMQ基于文件的存储方式,写入速度快,容易恢复,文件默认32M大小

3.JDBC基于数据库存储之JDBC Store。 配置完成后启动activemq,会在数据库中生成三个表

ACTIVEMQ_ACKS 存储持久订阅的信息

ACTIVEMQ_LOCK  锁表(用来做集群时,实现master选举的表)

ACTIVEMQ_MSGS  消息表

如何配置activeMQ基于jdbc存储?

首先配置:

然后,添加jar包依赖

4.JDBC Message store with activeMQ joural   这种方式克服了 JDBC Store的不足,用快速的缓存写入技术,大大提高了性能

JDBC Store和 JDBC Message Store with ActiveMQ Journal的区别:

Jdbc with journal的性能优表jdbc

Jdbc用于 master/ slave模式的数据库分享

 Jdbc with journal不能用于 master/ slave模式

一般情况下,推荐使用 jdbc with journal

5.levelDB

5.8之后引入的持久化策略,通常用于集群配置,levelDB是能够处理十亿级别规模的key-value型数据持久性存储的C++程序库,由Google发起并开源。LevelDB只能由本操作系统的其他进程调用,所以不具备网络性。如果需要网络上的远程进程操作levelDB,那么就要自行封装服务层。

ActiveMQ的网络连接

activeMQ如果要实现扩展性和高可用性的话,就要用到网络连接模式

NetworkConnector,主要用于配置broker与broker之间的通信连接

如上图所示,服务器s1与s2通过NetworkConnector相连,则生产者P1发送消息,消费者C3和C4都可以接收到。生产者P3发送的消息,消费者C1和C2同样也可以接收到。

静态网络连接

通过在activemq.xml中配置服务器列表实现静态网络连接

丢失的消息

在s1上注册10条消息,通过c4访问呢s2服务器,取出一条消息,发现10条消息都转移到了s2服务器,s1服务器上剩余消息为0,此时,c1与c2访问s1服务器也无法再取出消息。c3与c4访问s2服务器仍然可以继续取出消息。

从5.6版本开始,在destinationPolicy上新增了一个选项replayWhenNoConsumers属性,这个属性可以用来解决broker1上有需要转发的消息但是没有消费者时,把消息回流到原始的broker。同时把enableAudit设置为false,防止消息回流后被当做重复消息而不被分发。通过如下配置,即可完成消息回流处理:

动态网络连接

静态网络连接当机器特别多时,由于每个都是互相连接的,配置将会非常繁琐。

动态网络连接,使用multicast

networkConnector是一个高性能方案,并不是一个高可用方案,因为当没有消费者时,时有a1和a2两台服务器,往A1上发送10条消息,然后没有消费者消费,此时a1挂掉了,消费者读取a2,也读取不到消息。

通过zookeeper+activemq实现高可用方案

高可用方案:(master/slave模型)master对外服务,slave同步数据,当master挂掉时,从slave中选举出新的master,这个master数据是最新的,继续提供服务。

首先搭建好,zookeeper集群环境与activeMQ集群环境

1.修改activeMQ

参数的含义:

directory:levelDB数据文件存储的位置

replicas:replicas”参数非常重要,默认为3,表示消息最多可以备份在几个broker实例上,同是只有当“replicas/2 + 1”个broker存活时(包含master),集群才有效,才会选举master和备份消息,此值必须>=2。Client发送给Master的持久化消息(包括ACK和事务),master首先在本地保存,然后立即同步(sync)给选定的(replicas/2)个slaves,只有当这些节点也同步成功后,此消息的交互才算结束;对于剩下的replicas个节点,master采用异步的方式(async)转发。这种设计要求,可以保证集群中消息的可靠性,只有当(replicas/2 + 1)个节点物理故障,才会有丢失消息的风险。通常replicas为3,这要求开发者需要至少部署3个broker实例。如果replicas过大,会严重影响master的吞吐能力,因为它在sync消息的过程中会消耗太多的时间。

bind:用来负责slave和master的数据同步的端口和ip

zkAddress:表示zookeeper的服务端地址

hostname:服务名称,通常用本机ip命名

2.启动zookeeper集群

3.启动activeMQ集群

然后发现activeMQ在zookeeper的znode上注册了activeMQ服务:

这里最先启动的是activeMQ就是master,只有一个activeMQ对外提供服务,其余的都是备份服务器,当它挂掉时,会通过master选举选举出新的master。此时访问192.168.74.131:2181可以访问到zctiveMQ管理界面,而其他的ip访问不到。

另外还有jdbc存储的主从方案(基于LOCK锁表的操作实现master/slave,数据可以持久化存储,但是性能会依赖mysql或oracle),基于共享文件系统的主从方案(挂载网络磁盘,将数据文件保存到指定磁盘即可完成master/slave模式)

高可用+高性能方案

每一个broker集群都通过zk集群实现master选举,master之间通过网络双向连接传递消息

activeMQ容错的链接

具体看下这个博客:https://www.cnblogs.com/Eternally-dream/p/9890659.html

ActiveMQ监控

activemq自带的管理界面功能十分简单,只能查看activeMQ当前的Queue和Topics等简单信息,不能监控ActiveMQ自身运行的信息。

hawtio

HawtIO 是一个新的可插入式 HTML5 面板,设计用来监控 ActiveMQ, Camel等系统;ActiveMQ在5.9.0版本曾将hawtio嵌入自身的管理界面,但是由于对hawtio的引入产生了争议,在5.9.1版本中又将其移除,但是开发者可以通过配置,使用hawtio对ActiveMQ进行监控。本文介绍了通过两种配置方式,使用hawtio对ActiveMQ进行监控。

  1. http://hawt.io/getstarted/index.html 下载hawtio的应用程序
  2. 下载好后拷贝到ActiveMQ安装目录的webapps目录下,改名为hawtio.war并解压到到hawtio目录下
  3. 编辑ActiveMQ安装目录下conf/jetty.xml文件,在第75行添加以下代码

<bean class="org.eclipse.jetty.webapp.WebAppContext">        
        <property name="contextPath" value="/hawtio" />        
        <property name="war" value="${activemq.home}/webapps/hawtio" />        
        <property name="logUrlOnStart" value="true" />  
</bean>

     4.修改bin/env文件

Dhawtio.realm=activemq -Dhawtio.role=admins
-Dhawtio.rolePrincipalClasses=org.apache.activemq.jaas.GroupPrincipal

需要注意的是-Dhawtio的三个设定必须放在ACTIVEMQ_OPTS设置的最前面(在内存参数设置之后),否则会出现验证无法通过的错误(另外,ACTIVEMQ_OPTS的设置语句不要回车换行)

    5.启动activeMQ服务。访问http://ip:8161/hawtio.  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值