ActiveMQ服务监控Hawtio
官方网站
https://hawt.io
独立jar包的形式运行
java -jar
hawtio
单程序运行,可以对多个远程ActiveMQ服务器进行监控
嵌入ActiveMQ
-
下载war包
-
复制到webapps下
jetty.xml bean标签下添加
<bean class="org.eclipse.jetty.webapp.WebAppContext">
<property name="contextPath" value="/hawtio" />
<property name="war" value="${activemq.home}/webapps/hawtio.war" />
<property name="logUrlOnStart" value="true" />
</bean>
activeMQ下添加
export ACTIVEMQ_OPTS='-Xms1G -Xmx1G -Dhawtio.realm=activemq -Dhawtio.role=admins -Dhawtio.rolePrincipalClasses=org.apache.activemq.jaas.GroupPrincipal -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config="%ACTIVEMQ_CONF%\login.config"'
JMS消息结构
Message主要由三部分组成,分别是Header,Properties,Body, 详细如下:
Header | 消息头,所有类型的这部分格式都是一样的 |
---|---|
Properties | 属性,按类型可以分为应用设置的属性,标准属性和消息中间件定义的属性 |
Body | 消息正文,指我们具体需要消息传输的内容。 |
Header
JMS消息头使用的所有方法:
public interface Message {
public Destination getJMSDestination() throws JMSException;
public void setJMSDestination(Destination destination) throws JMSException;
public int getJMSDeliveryMode() throws JMSException
public void setJMSDeliveryMode(int deliveryMode) throws JMSException;
public String getJMSMessageID() throws JMSException;
public void setJMSMessageID(String id) throws JMSException;
public long getJMSTimestamp() throws JMSException'
public void setJMSTimestamp(long timestamp) throws JMSException;
public long getJMSExpiration() throws JMSException;
public void setJMSExpiration(long expiration) throws JMSException;
public boolean getJMSRedelivered() throws JMSException;
public void setJMSRedelivered(boolean redelivered) throws JMSException;
public int getJMSPriority() throws JMSException;
public void setJMSPriority(int priority) throws JMSException;
public Destination getJMSReplyTo() throws JMSException;
public void setJMSReplyTo(Destination replyTo) throws JMSException;
public String getJMScorrelationID() throws JMSException;
public void setJMSCorrelationID(String correlationID) throws JMSException;
public byte[] getJMSCorrelationIDAsBytes() throws JMSException;
public void setJMSCorrelationIDAsBytes(byte[] correlationID) throws JMSException;
public String getJMSType() throws JMSException;
public void setJMSType(String type) throws JMSException;
}
消息头分为自动设置和手动设置的内容
自动头信息
有一部分可以在创建Session和MessageProducer时设置
属性名称 | 说明 | 设置者 |
---|---|---|
JMSDeliveryMode | 消息的发送模式,分为NON_PERSISTENT和PERSISTENT,即非持久性模式的和持久性模式。默认设置为PERSISTENT(持久性)。一条持久性消息应该被传送一次(就一次),这就意味着如果JMS提供者出现故障,该消息并不会丢失; 它会在服务器恢复正常之后再次传送。一条非持久性消息最多只会传送一次,这意味着如果JMS提供者出现故障,该消息可能会永久丢失。在持久性和非持久性这两种传送模式中,消息服务器都不会将一条消息向同一消息者发送一次以上(成功算一次)。 | send |
JMSMessageID | 消息ID,需要以ID:开头,用于唯一地标识了一条消息 | send |
JMSTimestamp | 消息发送时的时间。这条消息头用于确定发送消息和它被消费者实际接收的时间间隔。时间戳是一个以毫秒来计算的Long类型时间值(自1970年1月1日算起)。 | send |
JMSExpiration | 消息的过期时间,以毫秒为单位,用来防止把过期的消息传送给消费者。任何直接通过编程方式来调用setJMSExpiration()方法都会被忽略。 | send |
JMSRedelivered | 消息是否重复发送过,如果该消息之前发送过,那么这个属性的值需要被设置为true, 客户端可以根据这个属性的值来确认这个消息是否重复发送过,以避免重复处理。 | Provider |
JMSPriority | 消息的优先级,0-4为普通的优化级,而5-9为高优先级,通常情况下,高优化级的消息需要优先发送。任何直接通过编程方式调用setJMSPriority()方法都将被忽略。 | send |
JMSDestination | 消息发送的目的地,是一个Topic或Queue | send |
JMSDeliveryMode
MessageProducer producer = session.createProducer(topic);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
JMSExpiration
//将过期时间设置为1小时(1000毫秒 *60 *60)
producer.setTimeToLive(1000 * 60 * 60);
JMSPriority
producer.setPriority(9);
手动头信息
属性名称 | 说明 | 设置者 |
---|---|---|
JMSCorrelationID | 关联的消息ID,这个通常用在需要回传消息的时候 | client |
JMSReplyTo | 消息回复的目的地,其值为一个Topic或Queue, 这个由发送者设置,但是接收者可以决定是否响应 | client |
JMSType | 由消息发送者设置的消息类型,代表消息的结构,有的消息中间件可能会用到这个,但这个并不是是批消息的种类,比如TextMessage之类的 | client |
从上表中我们可以看到,系统提供的标准头信息一共有10个属性,其中有6个是由send方法在调用时设置的,有三个是由客户端(client)设置的,还有一个是由消息中间件(Provider)设置的。
下一代 ActiveMQ Artemis
为下一代事件驱动的消息传递应用程序提供高性能、无阻塞的体系结构。
- 包含JNDI,具有完整的JMS 1.1 & 2.0客户端实现
- 高可用性共享存储、网络复制能力
- 简单而强大的寻址模型协议
- 灵活的负载均衡分配能力
- 针对低延迟持久性和JDBC的高级日志实现
- 与ActiveMQ 5的高功能奇偶校验,以简化迁移
官方文档:http://activemq.apache.org/components/artemis/migration
- netty
- 自己的存储
- 优化传输流程
- 更高的性能
- 不再把所有的协议转换成openwire
高级使用
1、JMSCorrelationID:用于消息之间的关联,给人一种会话的感觉
2、JMSReplyTo:发送方可以接受到消息消费确认的地址
-
ActiveMQ5.10.x 以上版本必须使用 JDK1.8 才能正常使用。
-
ActiveMQ5.9.x 及以下版本使用 JDK1.7 即可正常使用。
3、ActiveMQ如何防止消息丢失?会不会丢消息?
做高可用
死信队列重投
持久化存储
ack确认
消息重投
记录日志
接收(消费)确认
broker负载/限流
4、如何防止重复消费?
消息幂等处理
java map ConcurrentHashMap -> putIfAbsent或者guava cache