I'm new to ActiveMQ Artemis and ask community to check if I am right in configuration of HA cluster of brokers or may be I should configure them in another way as I haven't found detailed tutorial on my case. All of the brokers run on the same machine.
The scenario:
There is a master node on 61617 port and two slave nodes (slave1, slave2) on ports 61618 and 61619. If master node dies, one of slaves become active (replication mode).
It's necessary for the consumer to communicate with cluster as a "black-box". By that I mean that the change of master (i.e. when master dies) shouldn't have any effect on consumer (i.e. the way it connects to the cluster).
What I managed to do (as I understand for this case we should configure only cluster, acceptor, and connector properties, thus I attach only this part of configuration of brokers):
master broker:
<connectors>
<connector name="artemis">tcp://localhost:61617</connector>
</connectors>
<ha-policy>
<replication>
<master/>
</replication>
</ha-policy>
<acceptors>
<acceptor name="artemis">tcp://localhost:61617</acceptor>
</acceptors>
<cluster-user>cluster</cluster-user>
<cluster-password>cluster</cluster-password>
<broadcast-groups>
<broadcast-group name="bg-group1">
<group-address>231.7.7.7</group-address>
<group-port>9876</group-port>
<broadcast-period>5000</broadcast-period>
<connector-ref>artemis</connector-ref>
</broadcast-group>
</broadcast-groups>
<discovery-groups>
<discovery-group name="dg-group1">
<group-address>231.7.7.7</group-address>
<group-port>9876</group-port>
<refresh-timeout>10000</refresh-timeout>
</discovery-group>
</discovery-groups>
<cluster-connections>
<cluster-connection name="my-cluster">
<connector-ref>artemis</connector-ref>
<message-load-balancing>ON_DEMAND</message-load-balancing>
<max-hops>0</max-hops>
<discovery-group-ref discovery-group-name="dg-group1"/>
</cluster-connection>
</cluster-connections>
slave 1 broker the cluster conf is the same with master (auto-configuration when creating a node through the console --clustered)
<ha-policy>
<replication>
<slave/>
</replication>
</ha-policy>
<connectors>
<connector name="artemis">tcp://localhost:61618</connector>
<connector name="netty-live-connector">tcp://localhost:61617</connector>
</connectors>
<acceptors>
<acceptor name="artemis">tcp://localhost:61618 </acceptor>
</acceptors>
slave 2 broker the cluster conf is the same with master (auto-configuration when creating a node through the console --clustered)
<ha-policy>
<replication>
<slave/>
</replication>
</ha-policy>
<connectors>
<connector name="artemis">tcp://localhost:61619</connector>
<connector name="netty-live-connector">tcp://localhost:61617</connector>
</connectors>
<acceptors>
<acceptor name="artemis">tcp://localhost:61619</acceptor>
</acceptors>
JNDI configuration in consumer :
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connectionFactory.ConnectionFactory=(tcp://localhost:61617?ha=true&retryInterval=1000&retryIntervalMultiplier=1.0&reconnectAttempts=10,tcp://localhost:61618?ha=true&retryInterval=1000&retryIntervalMultiplier=1.0&reconnectAttempts=10,tcp://localhost:61619?ha=true&retryInterval=1000&retryIntervalMultiplier=1.0&reconnectAttempts=10)
My configuration works, however I don`t sure if it is the right way it should be.
I've also found similar question which uses static connectors. What are they doing? I don't understand how they work. Or may be that is the right way of configuration that I am looking for?
The first thing to note is that using a single live/backup pair (or even live/backup/backup triplet) with network replication is dangerous due to the risk of "split-brain." I would recommend you use either 1 live/backup pair with shared-storage or 3 live/backup pairs with replication (which will allow the establishment of a proper quorum). Read the documentation about split brain for more details.
Aside from the risk of split-brain the broker configuration looks OK. Most (if not all) the configuration details are covered in the clustering and HA documentation. There is also a wealth of examples which ship with the broker many of which are specific to clustering and HA.
You could simplify your connection factory URL. Currently you have:
(tcp://localhost:61617?ha=true&retryInterval=1000&retryIntervalMultiplier=1.0&reconnectAttempts=10,tcp://localhost:61618?ha=true&retryInterval=1000&retryIntervalMultiplier=1.0&reconnectAttempts=10,tcp://localhost:61619?ha=true&retryInterval=1000&retryIntervalMultiplier=1.0&reconnectAttempts=10)
However, you could use:
(tcp://localhost:61617,tcp://localhost:61618,tcp://localhost:61619)?ha=true&retryInterval=1000&retryIntervalMultiplier=1.0&reconnectAttempts=10
Static connectors are typically used in environments which don't support UDP multicast. It allows manual configuration of the cluster members. If you are in an environment which supports UDP multicast I recommend you use the discovery/broadcast groups configuration rather than static discovery.
In general, if everything is working the way you want that indicates your configuration is fine.
Related
I have ActiveMQ Artemis 2.8.1 running and get the following error when I try to connect to it using a Spring Boot application over SSL.
ERROR [org.apache.activemq.artemis.core.server] AMQ224018: Failed to create session: java.lang.SecurityException: java.io.IOException: Configuration Error:
Line 11: expected [{], found [sufficient]
Additionally, I get this line in the logs that I've never seen before.
INFO [org.apache.activemq.artemis.core.server] AMQ221053: Disallowing use of vulnerable protocol 'SSLv2Hello' on acceptor 'netty-ssl-acceptor'. See http://www.oracle.com/technetwork/topics/security/poodlecve-2014-3566-2339408.html for more details.
I had ActiveMQ Artemis 2.18.0 running initially, and then changed ARTEMIS_HOME in artemis.profile to point to the directory containing 2.8.1 for compatibility reasons. I'm wondering if that change has anything to do with this.
How do I go about resolving this issue?
broker.xml:
<?xml version='1.0'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<configuration xmlns="urn:activemq"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xi="http://www.w3.org/2001/XInclude"
xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
<core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:activemq:core ">
<name>0.0.0.0</name>
<persistence-enabled>true</persistence-enabled>
<!-- this could be ASYNCIO, MAPPED, NIO
ASYNCIO: Linux Libaio
MAPPED: mmap files
NIO: Plain Java Files
-->
<journal-type>ASYNCIO</journal-type>
<paging-directory>data/paging</paging-directory>
<bindings-directory>data/bindings</bindings-directory>
<journal-directory>data/journal</journal-directory>
<large-messages-directory>data/large-messages</large-messages-directory>
<journal-datasync>true</journal-datasync>
<journal-min-files>2</journal-min-files>
<journal-pool-files>10</journal-pool-files>
<journal-file-size>10M</journal-file-size>
<!--
This value was determined through a calculation.
Your system could perform 125 writes per millisecond
on the current journal configuration.
That translates as a sync write every 8000 nanoseconds.
Note: If you specify 0 the system will perform writes directly to the disk.
We recommend this to be 0 if you are using journalType=MAPPED and journal-datasync=false.
-->
<journal-buffer-timeout>8000</journal-buffer-timeout>
<!--
When using ASYNCIO, this will determine the writing queue depth for libaio.
-->
<journal-max-io>4096</journal-max-io>
<!--
You can verify the network health of a particular NIC by specifying the <network-check-NIC> element.
<network-check-NIC>theNicName</network-check-NIC>
-->
<!--
Use this to use an HTTP server to validate the network
<network-check-URL-list>http://www.apache.org</network-check-URL-list> -->
<!-- <network-check-period>10000</network-check-period> -->
<!-- <network-check-timeout>1000</network-check-timeout> -->
<!-- this is a comma separated list, no spaces, just DNS or IPs
it should accept IPV6
Warning: Make sure you understand your network topology as this is meant to validate if your network is valid.
Using IPs that could eventually disappear or be partially visible may defeat the purpose.
You can use a list of multiple IPs, and if any successful ping will make the server OK to continue running -->
<!-- <network-check-list>10.0.0.1</network-check-list> -->
<!-- use this to customize the ping used for ipv4 addresses -->
<!-- <network-check-ping-command>ping -c 1 -t %d %s</network-check-ping-command> -->
<!-- use this to customize the ping used for ipv6 addresses -->
<!-- <network-check-ping6-command>ping6 -c 1 %2$s</network-check-ping6-command> -->
<!-- how often we are looking for how many bytes are being used on the disk in ms -->
<disk-scan-period>5000</disk-scan-period>
<!-- once the disk hits this limit the system will block, or close the connection in certain protocols
that won't support flow control. -->
<max-disk-usage>90</max-disk-usage>
<!-- should the broker detect dead locks and other issues -->
<critical-analyzer>true</critical-analyzer>
<critical-analyzer-timeout>120000</critical-analyzer-timeout>
<critical-analyzer-check-period>60000</critical-analyzer-check-period>
<critical-analyzer-policy>HALT</critical-analyzer-policy>
<!-- the system will enter into page mode once you hit this limit.
This is an estimate in bytes of how much the messages are using in memory
The system will use half of the available memory (-Xmx) by default for the global-max-size.
You may specify a different value here if you need to customize it to your needs.
<global-max-size>100Mb</global-max-size>
-->
<acceptors>
<!-- useEpoll means: it will use Netty epoll if you are on a system (Linux) that supports it -->
<!-- amqpCredits: The number of credits sent to AMQP producers -->
<!-- amqpLowCredits: The server will send the # credits specified at amqpCredits at this low mark -->
<!-- Note: If an acceptor needs to be compatible with HornetQ and/or Artemis 1.x clients add
"anycastPrefix=jms.queue.;multicastPrefix=jms.topic." to the acceptor url.
See https://issues.apache.org/jira/browse/ARTEMIS-1644 for more information. -->
<!-- Acceptor for every supported protocol -->
<acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300</acceptor>
<!-- AMQP Acceptor. Listens on default AMQP port for AMQP traffic.-->
<acceptor name="amqp">tcp://0.0.0.0:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpLowCredits=300</acceptor>
<!-- STOMP Acceptor. -->
<acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true</acceptor>
<!-- HornetQ Compatibility Acceptor. Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
<acceptor name="hornetq">tcp://0.0.0.0:5445?anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;protocols=HORNETQ,STOMP;useEpoll=true</acceptor>
<!-- MQTT Acceptor -->
<acceptor name="mqtt">tcp://0.0.0.0:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true</acceptor>
<!-- SSL Acceptor -->
<acceptor name="netty-ssl-acceptor">tcp://0.0.0.0:61617?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;verifyHost=false;anycastPrefix=jms.queue;multicastPrefix=jms.topic.;sslEnabled=true;keyStorePath=/opt/sprink-broker/etc/oceanBroker.jks;keyStorePassword=changeit;trustStorePath=/opt/sprink-broker/etc/oceanBroker.ts;trustStorePassword=changeit;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE</acceptor>
<acceptor name="mqtt-ssl-acceptor">tcp://0.0.0.0:8883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;anycastPrefix=jms.queue;multicastPrefix=jms.topic.;sslEnabled=true;keyStorePath=/opt/sprink-broker/etc/oceanBroker.jks;keyStorePassword=changeit;trustStorePath=/opt/sprink-broker/etc/oceanBroker.ts;trustStorePassword=changeit;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE</acceptor>
</acceptors>
<security-settings>
<security-setting match="#">
<permission type="createNonDurableQueue" roles="amq, users"/>
<permission type="deleteNonDurableQueue" roles="amq, users"/>
<permission type="createDurableQueue" roles="amq, users"/>
<permission type="deleteDurableQueue" roles="amq, users"/>
<permission type="createAddress" roles="amq, users"/>
<permission type="deleteAddress" roles="amq, users"/>
<permission type="consume" roles="amq, users"/>
<permission type="browse" roles="amq, users"/>
<permission type="send" roles="amq, users"/>
<!-- we need this otherwise ./artemis data imp wouldn't work -->
<permission type="manage" roles="amq"/>
</security-setting>
</security-settings>
<address-settings>
<!-- if you define auto-create on certain queues, management has to be auto-create -->
<address-setting match="activemq.management#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- with -1 only the global-max-size is in use for limiting -->
<max-size-bytes>-1</max-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
<auto-create-jms-queues>true</auto-create-jms-queues>
<auto-create-jms-topics>true</auto-create-jms-topics>
</address-setting>
<!--default for catch all-->
<address-setting match="#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- with -1 only the global-max-size is in use for limiting -->
<max-size-bytes>-1</max-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
<auto-create-jms-queues>true</auto-create-jms-queues>
<auto-create-jms-topics>true</auto-create-jms-topics>
</address-setting>
</address-settings>
<addresses>
<address name="DLQ">
<anycast>
<queue name="DLQ" />
</anycast>
</address>
<address name="ExpiryQueue">
<anycast>
<queue name="ExpiryQueue" />
</anycast>
</address>
</addresses>
<!-- Uncomment the following if you want to use the Standard LoggingActiveMQServerPlugin pluging to log in events
<broker-plugins>
<broker-plugin class-name="org.apache.activemq.artemis.core.server.plugin.impl.LoggingActiveMQServerPlugin">
<property key="LOG_ALL_EVENTS" value="true"/>
<property key="LOG_CONNECTION_EVENTS" value="true"/>
<property key="LOG_SESSION_EVENTS" value="true"/>
<property key="LOG_CONSUMER_EVENTS" value="true"/>
<property key="LOG_DELIVERING_EVENTS" value="true"/>
<property key="LOG_SENDING_EVENTS" value="true"/>
<property key="LOG_INTERNAL_EVENTS" value="true"/>
</broker-plugin>
</broker-plugins>
-->
</core>
</configuration>
Spring Boot config file used to connect to ActiveMQ Artemis:
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.core.JmsTemplate;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
#Configuration
#EnableJms
public class MQTTConfig {
#Value("${activemq.broker-url}")
private String brokerUrl;
#Value("${activemq.ssl-url}")
private String sslUrl;
#Value("${JMS_BROKER_TRUSTSTORE}")
private String pathToTrustStore;
#Value("${JMS_BROKER_KEYSTORE}")
private String pathToKeystore;
#Value("${JMS_BROKER_TRUSTSTORE_PASSWORD}")
private String truststorePassword;
#Value("${JMS_BROKER_KEYSTORE_PASSWORD}")
private String keystorePassword;
#Bean
public ActiveMQConnectionFactory artemisSSLConnectionFactory() {
ActiveMQConnectionFactory artemisConnectionFactory = new ActiveMQConnectionFactory("tcp://ip:port?&" + "sslEnabled=true&" +
"trustStorePath=" + pathToTrustStore + "&trustStorePassword=xxxxx");
artemisConnectionFactory.setUser("user");
artemisConnectionFactory.setPassword("xxxxx");
return artemisConnectionFactory;
}
/**
* Initialise {#link JmsTemplate} as required
*/
#Bean
public JmsTemplate jmsTemplate() throws JMSException {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(artemisSSLConnectionFactory());
//setting PuSubDomain to true configures JmsTemplate to work with topics instead of queues
jmsTemplate.setPubSubDomain(true);
return jmsTemplate;
}
/**
* Initialise {#link DefaultJmsListenerContainerFactory} as required
*/
#Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() throws JMSException {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(artemisSSLConnectionFactory());
//setting PuSubDomain to true configures the DefaultJmsListenerContainerFactory to work with topics instead of queues
factory.setPubSubDomain(true);
return factory;
}
}
artemis.roles-properties:
amq = admin
users=user
guests=guest
artemis-users.properties:
admin = xxxxx
system=xxxxx
user=xxxxx
guest=xxxxx
login.config:
activemq {
org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule required
debug=false
reload=true
org.apache.activemq.jaas.properties.user="artemis-users.properties"
org.apache.activemq.jaas.properties.role="artemis-roles.properties";
org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient
debug=false
org.apache.activemq.jaas.guest.user="guest"
org.apache.activemq.jaas.guest.role="guests";
};
There is definitely a problem with your configuration. The error message even says so:
ERROR [org.apache.activemq.artemis.core.server] AMQ224018: Failed to create session: java.lang.SecurityException: java.io.IOException: Configuration Error:
Line 11: expected [{], found [sufficient]
Given that it found the word sufficient when it was looking for { I conclude that the problem is in your etc/login.config since that's almost certainly the only place the word sufficient appears and because it's related to security.
The login.config you pasted looks fine to me so my guess is that you pasted the contents of a login.config that isn't actually being used by the broker.
Also, the AMQ221053 message has been in the code-base since the 1.0 release. See ARTEMIS-36.
Lastly, it's kind of odd for you to be specifying the keystore and truststore on both the client and the broker without also specifying needClientAuth=true or wantClientAuth=true on the broker. You would only specify a keystore on a client and a truststore on the broker if you wanted to do mutual SSL, but without needClientAuth=true or wantClientAuth=true that won't actually happen.
I am new to ActiveMQ Artemis and trying to configure master-slave setup. In my scenario, I am using one master and one slave.
Master's broker.xml looks like:
<configuration xmlns="...">
<core xmlns="...">
<name>10.168.100.41</name>
<persistence-enabled>true</persistence-enabled>
<journal-type>ASYNCIO</journal-type>
<paging-directory>data/paging</paging-directory>
<bindings-directory>data/bindings</bindings-directory>
<journal-directory>data/journal</journal-directory>
<large-messages-directory>data/large-messages</large-messages-directory>
<journal-datasync>true</journal-datasync>
<journal-min-files>2</journal-min-files>
<journal-pool-files>10</journal-pool-files>
<journal-device-block-size>4096</journal-device-block-size>
<journal-file-size>10M</journal-file-size>
<journal-buffer-timeout>28000</journal-buffer-timeout>
<!--
When using ASYNCIO, this will determine the writing queue depth for libaio.
-->
<journal-max-io>4096</journal-max-io>
<!--
You can verify the network health of a particular NIC by specifying the <network-check-NIC> element.
<network-check-NIC>theNicName</network-check-NIC>
-->
<connectors>
<!-- Connector used to be announced through cluster connections and notifications -->
<connector name="artemis">tcp://10.168.100.41:61616</connector>
</connectors>
<!-- how often we are looking for how many bytes are being used on the disk in ms -->
<disk-scan-period>5000</disk-scan-period>
<!-- once the disk hits this limit the system will block, or close the connection in certain protocols
that won't support flow control. -->
<max-disk-usage>90</max-disk-usage>
<!-- should the broker detect dead locks and other issues -->
<critical-analyzer>true</critical-analyzer>
<critical-analyzer-timeout>120000</critical-analyzer-timeout>
<critical-analyzer-check-period>60000</critical-analyzer-check-period>
<critical-analyzer-policy>HALT</critical-analyzer-policy>
<page-sync-timeout>356000</page-sync-timeout>
<!-- the system will enter into page mode once you hit this limit.
This is an estimate in bytes of how much the messages are using in memory
The system will use half of the available memory (-Xmx) by default for the global-max-size.
You may specify a different value here if you need to customize it to your needs.
<global-max-size>100Mb</global-max-size>
-->
<acceptors>
<!-- useEpoll means: it will use Netty epoll if you are on a system (Linux) that supports it -->
<!-- amqpCredits: The number of credits sent to AMQP producers -->
<!-- amqpLowCredits: The server will send the # credits specified at amqpCredits at this low mark -->
<!-- amqpDuplicateDetection: If you are not using duplicate detection, set this to false
as duplicate detection requires applicationProperties to be parsed on the server. -->
<!-- amqpMinLargeMessageSize: Determines how many bytes are considered large, so we start using files to hold their data.
default: 102400, -1 would mean to disable large mesasge control -->
<!-- Note: If an acceptor needs to be compatible with HornetQ and/or Artemis 1.x clients add
"anycastPrefix=jms.queue.;multicastPrefix=jms.topic." to the acceptor url.
See https://issues.apache.org/jira/browse/ARTEMIS-1644 for more information. -->
<!-- Acceptor for every supported protocol -->
<acceptor name="artemis">tcp://10.168.100.41:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true</acceptor>
<acceptor name="amqp">tcp://10.168.100.41:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpMinLargeMessageSize=102400;amqpDuplicateDetection=true</acceptor>
<!-- STOMP Acceptor. -->
<acceptor name="stomp">tcp://10.168.100.41:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true</acceptor>
<!-- HornetQ Compatibility Acceptor. Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
<acceptor name="hornetq">tcp://10.168.100.41:5445?anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;protocols=HORNETQ,STOMP;useEpoll=true</acceptor>
<!-- MQTT Acceptor -->
<acceptor name="mqtt">tcp://10.168.100.41:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true</acceptor>
</acceptors>
<cluster-user>username</cluster-user>
<cluster-password>password</cluster-password>
<broadcast-groups>
<broadcast-group name="bg-group1">
<group-address>231.7.7.7</group-address>
<group-port>9876</group-port>
<broadcast-period>5000</broadcast-period>
<connector-ref>artemis</connector-ref>
</broadcast-group>
</broadcast-groups>
<discovery-groups>
<discovery-group name="dg-group1">
<group-address>231.7.7.7</group-address>
<group-port>9876</group-port>
<refresh-timeout>10000</refresh-timeout>
</discovery-group>
</discovery-groups>
<cluster-connections>
<cluster-connection name="my-cluster">
<connector-ref>artemis</connector-ref>
<message-load-balancing>ON_DEMAND</message-load-balancing>
<max-hops>0</max-hops>
<discovery-group-ref discovery-group-name="dg-group1"/>
</cluster-connection>
</cluster-connections>
<ha-policy>
<replication>
<master>
<vote-on-replication-failure>true</vote-on-replication-failure>
</master>
</replication>
</ha-policy>
<security-settings>
<security-setting match="#">
<permission type="createNonDurableQueue" roles="amq"/>
<permission type="deleteNonDurableQueue" roles="amq"/>
<permission type="createDurableQueue" roles="amq"/>
<permission type="deleteDurableQueue" roles="amq"/>
<permission type="createAddress" roles="amq"/>
<permission type="deleteAddress" roles="amq"/>
<permission type="consume" roles="amq"/>
<permission type="browse" roles="amq"/>
<permission type="send" roles="amq"/>
<!-- we need this otherwise ./artemis data imp wouldn't work -->
<permission type="manage" roles="amq"/>
</security-setting>
</security-settings>
<address-settings>
<!-- if you define auto-create on certain queues, management has to be auto-create -->
<address-setting match="activemq.management#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- with -1 only the global-max-size is in use for limiting -->
<max-size-bytes>-1</max-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
<auto-create-jms-queues>true</auto-create-jms-queues>
<auto-create-jms-topics>true</auto-create-jms-topics>
</address-setting>
<!--default for catch all-->
<address-setting match="#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- with -1 only the global-max-size is in use for limiting -->
<max-size-bytes>-1</max-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
<auto-create-jms-queues>true</auto-create-jms-queues>
<auto-create-jms-topics>true</auto-create-jms-topics>
</address-setting>
</address-settings>
<addresses>
<address name="DLQ">
<anycast>
<queue name="DLQ" />
</anycast>
</address>
<address name="ExpiryQueue">
<anycast>
<queue name="ExpiryQueue" />
</anycast>
</address>
</addresses>
</core>
</configuration>
Slave's broker.xml looks like:
<?xml version='1.0'?>
<configuration xmlns="...">
<core xmlns="...">
<name>10.168.100.41</name>
<persistence-enabled>true</persistence-enabled>
<journal-type>ASYNCIO</journal-type>
<paging-directory>data/paging</paging-directory>
<bindings-directory>data/bindings</bindings-directory>
<journal-directory>data/journal</journal-directory>
<large-messages-directory>data/large-messages</large-messages-directory>
<journal-datasync>true</journal-datasync>
<journal-min-files>2</journal-min-files>
<journal-pool-files>10</journal-pool-files>
<journal-device-block-size>4096</journal-device-block-size>
<journal-file-size>10M</journal-file-size>
<journal-buffer-timeout>28000</journal-buffer-timeout>
<journal-max-io>4096</journal-max-io>
<connectors>
<!-- Connector used to be announced through cluster connections and notifications -->
<connector name="artemis">tcp://10.168.100.42:61616</connector>
<connector name="netty-live-connector">tcp://10.168.100.41:61616</connector>
</connectors>
<!-- how often we are looking for how many bytes are being used on the disk in ms -->
<disk-scan-period>5000</disk-scan-period>
<max-disk-usage>90</max-disk-usage>
<!-- should the broker detect dead locks and other issues -->
<critical-analyzer>true</critical-analyzer>
<critical-analyzer-timeout>120000</critical-analyzer-timeout>
<critical-analyzer-check-period>60000</critical-analyzer-check-period>
<critical-analyzer-policy>HALT</critical-analyzer-policy>
<page-sync-timeout>356000</page-sync-timeout>
<acceptors>
<acceptor name="artemis">tcp://10.168.100.42:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true</acceptor>
<acceptor name="amqp">tcp://10.168.100.41:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpMinLargeMessageSize=102400;amqpDuplicateDetection=true</acceptor>
<acceptor name="stomp">tcp://10.168.100.41:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true</acceptor>
<acceptor name="hornetq">tcp://10.168.100.41:5445?anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;protocols=HORNETQ,STOMP;useEpoll=true</acceptor>
<acceptor name="mqtt">tcp://10.168.100.41:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true</acceptor>
</acceptors>
<cluster-user>username</cluster-user>
<cluster-password>password</cluster-password>
<broadcast-groups>
<broadcast-group name="bg-group1">
<group-address>231.7.7.7</group-address>
<group-port>9876</group-port>
<broadcast-period>5000</broadcast-period>
<connector-ref>artemis</connector-ref>
</broadcast-group>
</broadcast-groups>
<discovery-groups>
<discovery-group name="dg-group1">
<group-address>231.7.7.7</group-address>
<group-port>9876</group-port>
<refresh-timeout>10000</refresh-timeout>
</discovery-group>
</discovery-groups>
<cluster-connections>
<cluster-connection name="my-cluster">
<connector-ref>artemis</connector-ref>
<message-load-balancing>ON_DEMAND</message-load-balancing>
<max-hops>0</max-hops>
<discovery-group-ref discovery-group-name="dg-group1"/>
</cluster-connection>
</cluster-connections>
<ha-policy>
<replication>
<slave/>
</replication>
</ha-policy>
<security-settings>
<security-setting match="#">
<permission type="createNonDurableQueue" roles="amq"/>
<permission type="deleteNonDurableQueue" roles="amq"/>
<permission type="createDurableQueue" roles="amq"/>
<permission type="deleteDurableQueue" roles="amq"/>
<permission type="createAddress" roles="amq"/>
<permission type="deleteAddress" roles="amq"/>
<permission type="consume" roles="amq"/>
<permission type="browse" roles="amq"/>
<permission type="send" roles="amq"/>
<!-- we need this otherwise ./artemis data imp wouldn't work -->
<permission type="manage" roles="amq"/>
</security-setting>
</security-settings>
<address-settings>
<!-- if you define auto-create on certain queues, management has to be auto-create -->
<address-setting match="activemq.management#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- with -1 only the global-max-size is in use for limiting -->
<max-size-bytes>-1</max-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
<auto-create-jms-queues>true</auto-create-jms-queues>
<auto-create-jms-topics>true</auto-create-jms-topics>
</address-setting>
<!--default for catch all-->
<address-setting match="#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- with -1 only the global-max-size is in use for limiting -->
<max-size-bytes>-1</max-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
<auto-create-jms-queues>true</auto-create-jms-queues>
<auto-create-jms-topics>true</auto-create-jms-topics>
</address-setting>
</address-settings>
<addresses>
<address name="DLQ">
<anycast>
<queue name="DLQ" />
</anycast>
</address>
<address name="ExpiryQueue">
<anycast>
<queue name="ExpiryQueue" />
</anycast>
</address>
</addresses>
</core>
</configuration>
When I start master and slave they are started without any issue, but master and slave are not in sync:
master.log is
INFO [org.apache.activemq.artemis.integration.bootstrap] AMQ101000: Starting ActiveMQ Artemis Server
INFO [org.apache.activemq.artemis.core.server] AMQ221000: live Message Broker is starting with configuration Broker Configuration (clustered=true,journalDirectory=data/journal,bindingsDirectory=data/bindings,largeMessagesDirectory=data/large-messages,pagingDirectory=data/paging)
INFO [org.apache.activemq.artemis.core.server] AMQ221012: Using AIO Journal
INFO [org.apache.activemq.artemis.core.server] AMQ221057: Global Max Size is being adjusted to 1/2 of the JVM max size (-Xmx). being defined as 1,073,741,824
INFO [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-server]. Adding protocol support for: CORE
INFO [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-amqp-protocol]. Adding protocol support for: AMQP
INFO [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-hornetq-protocol]. Adding protocol support for: HORNETQ
INFO [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-mqtt-protocol]. Adding protocol support for: MQTT
INFO [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-openwire-protocol]. Adding protocol support for: OPENWIRE
INFO [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-stomp-protocol]. Adding protocol support for: STOMP
INFO [org.apache.activemq.artemis.core.server] AMQ221080: Deploying address DLQ supporting [ANYCAST]
INFO [org.apache.activemq.artemis.core.server] AMQ221003: Deploying ANYCAST queue DLQ on address DLQ
INFO [org.apache.activemq.artemis.core.server] AMQ221080: Deploying address ExpiryQueue supporting [ANYCAST]
INFO [org.apache.activemq.artemis.core.server] AMQ221003: Deploying ANYCAST queue ExpiryQueue on address ExpiryQueue
INFO [org.apache.activemq.artemis.core.server] AMQ221020: Started EPOLL Acceptor at 10.168.100.41:61616 for protocols [CORE,MQTT,AMQP,STOMP,HORNETQ,OPENWIRE]
INFO [org.apache.activemq.artemis.core.server] AMQ221020: Started EPOLL Acceptor at 10.168.100.41:5445 for protocols [HORNETQ,STOMP]
INFO [org.apache.activemq.artemis.core.server] AMQ221020: Started EPOLL Acceptor at 10.168.100.41:5672 for protocols [AMQP]
INFO [org.apache.activemq.artemis.core.server] AMQ221020: Started EPOLL Acceptor at 10.168.100.41:1883 for protocols [MQTT]
INFO [org.apache.activemq.artemis.core.server] AMQ221020: Started EPOLL Acceptor at 10.168.100.41:61613 for protocols [STOMP]
INFO [org.apache.activemq.artemis.core.server] AMQ221007: Server is now live
INFO [org.apache.activemq.artemis.core.server] AMQ221001: Apache ActiveMQ Artemis Message Broker version 2.16.0 [10.168.100.41, nodeID=05cefba8-38e1-11eb-9570-024236bc469a]
INFO [org.apache.activemq.hawtio.branding.PluginContextListener] Initialized activemq-branding plugin
INFO [org.apache.activemq.hawtio.plugin.PluginContextListener] Initialized artemis-plugin plugin
INFO [io.hawt.HawtioContextListener] Initialising hawtio services
INFO [io.hawt.system.ConfigManager] Configuration will be discovered via system properties
INFO [io.hawt.jmx.JmxTreeWatcher] Welcome to Hawtio 2.11.0
INFO [io.hawt.web.auth.AuthenticationConfiguration] Starting hawtio authentication filter, JAAS realm: "activemq" authorized role(s): "amq" role principal classes: "org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal"
INFO [io.hawt.web.proxy.ProxyServlet] Proxy servlet is disabled
INFO [io.hawt.web.servlets.JolokiaConfiguredAgentServlet] Jolokia overridden property: [key=policyLocation, value=file:/gcdata/amq/data/etc/jolokia-access.xml]
INFO [org.apache.activemq.artemis] AMQ241001: HTTP Server started at http://localhost:8161
INFO [org.apache.activemq.artemis] AMQ241002: Artemis Jolokia REST API available at http://localhost:8161/console/jolokia
INFO [org.apache.activemq.artemis] AMQ241004: Artemis Console available at http://localhost:8161/console
INFO [io.hawt.web.auth.LoginServlet] Hawtio login is using 1800 sec. HttpSession timeout
INFO [io.hawt.web.auth.LoginServlet] Logging in user: user
INFO [io.hawt.web.auth.keycloak.KeycloakServlet] Keycloak integration is disabled
INFO [io.hawt.web.auth.SessionExpiryFilter] Expiring session due to inactivity
slave log :
INFO [org.apache.activemq.artemis.integration.bootstrap] AMQ101000: Starting ActiveMQ Artemis Server
INFO [org.apache.activemq.artemis.core.server] AMQ221000: backup Message Broker is starting with configuration Broker Configuration (clustered=true,journalDirectory=data/journal,bindingsDirectory=data/bindings,largeMessagesDirectory=data/large-messages,pagingDirectory=data/paging)
INFO [org.apache.activemq.artemis.core.server] AMQ221055: There were too many old replicated folders upon startup, removing /gcdata/amq/data/data/journal/oldreplica.4
INFO [org.apache.activemq.artemis.core.server] AMQ222162: Moving data directory /gcdata/amq/data/data/journal to /gcdata/amq/data/data/journal/oldreplica.6
INFO [org.apache.activemq.artemis.core.server] AMQ221012: Using AIO Journal
INFO [org.apache.activemq.artemis.core.server] AMQ221057: Global Max Size is being adjusted to 1/2 of the JVM max size (-Xmx). being defined as 1,073,741,824
INFO [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-server]. Adding protocol support for: CORE
INFO [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-amqp-protocol]. Adding protocol support for: AMQP
INFO [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-hornetq-protocol]. Adding protocol support for: HORNETQ
INFO [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-mqtt-protocol]. Adding protocol support for: MQTT
INFO [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-openwire-protocol]. Adding protocol support for: OPENWIRE
INFO [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-stomp-protocol]. Adding protocol support for: STOMP
INFO [org.apache.activemq.hawtio.branding.PluginContextListener] Initialized activemq-branding plugin
INFO [org.apache.activemq.hawtio.plugin.PluginContextListener] Initialized artemis-plugin plugin
INFO [io.hawt.HawtioContextListener] Initialising hawtio services
INFO [io.hawt.system.ConfigManager] Configuration will be discovered via system properties
INFO [io.hawt.jmx.JmxTreeWatcher] Welcome to Hawtio 2.11.0
INFO [io.hawt.web.auth.AuthenticationConfiguration] Starting hawtio authentication filter, JAAS realm: "activemq" authorized role(s): "amq" role principal classes: "org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal"
INFO [io.hawt.web.proxy.ProxyServlet] Proxy servlet is disabled
INFO [io.hawt.web.servlets.JolokiaConfiguredAgentServlet] Jolokia overridden property: [key=policyLocation, value=file:/gcdata/amq/data/etc/jolokia-access.xml]
INFO [org.apache.activemq.artemis] AMQ241001: HTTP Server started at http://localhost:8161
INFO [org.apache.activemq.artemis] AMQ241002: Artemis Jolokia REST API available at http://localhost:8161/console/jolokia
INFO [org.apache.activemq.artemis] AMQ241004: Artemis Console available at http://localhost:8161/console
I used iperf to test connectivity and result is:
~$ iperf -s -u -B 10.168.100.41 -i 1
------------------------------------------------------------
Server listening on UDP port 5001
Binding to local address 10.168.100.41
Receiving 1470 byte datagrams
UDP buffer size: 208 KByte (default)
------------------------------------------------------------
[ 3] local 10.168.100.41 port 5001 connected with 10.168.100.42 port 41425
[ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
[ 3] 0.0- 1.0 sec 129 KBytes 1.06 Mbits/sec 0.024 ms 0/ 90 (0%)
...
Am I doing something wrong here?
Try to specify the local-bind-address parameter in broadcast and discovery groups. If this property is not specified when having multiple network interfaces, then the socket will be bound to the wildcard address, an IP address chosen by the kernel.
Master:
<name>10.168.100.41</name>
<connectors>
<connector name="artemis">tcp://10.168.100.41:61616</connector>
</connectors>
<broadcast-groups>
<broadcast-group name="bg-group1">
<local-bind-address>10.168.100.41</local-bind-address>
<group-address>231.7.7.7</group-address>
<group-port>9876</group-port>
<broadcast-period>5000</broadcast-period>
<connector-ref>artemis</connector-ref>
</broadcast-group>
</broadcast-groups>
<discovery-groups>
<discovery-group name="dg-group1">
<local-bind-address>10.168.100.41</local-bind-address>
<group-address>231.7.7.7</group-address>
<group-port>9876</group-port>
<refresh-timeout>10000</refresh-timeout>
</discovery-group>
</discovery-groups>
Slave:
<name>10.168.100.42</name>
<connectors>
<connector name="artemis">tcp://10.168.100.42:61616</connector>
</connectors>
<broadcast-groups>
<broadcast-group name="bg-group1">
<local-bind-address>10.168.100.42</local-bind-address>
<group-address>231.7.7.7</group-address>
<group-port>9876</group-port>
<broadcast-period>5000</broadcast-period>
<connector-ref>artemis</connector-ref>
</broadcast-group>
</broadcast-groups>
<discovery-groups>
<discovery-group name="dg-group1">
<local-bind-address>10.168.100.42</local-bind-address>
<group-address>231.7.7.7</group-address>
<group-port>9876</group-port>
<refresh-timeout>10000</refresh-timeout>
</discovery-group>
</discovery-groups>
Given that replication is a shared-nothing architecture, having 3 master-slave nodes (6 brokers in total) will mitigate against the risk of split-brain thanks to the quorum voting mechanism. To enable this, you should have an odd number of live nodes greater than one (i.e. 3, 5, 7 and so on).
I have two deployed apps, one on my local machine and one on the server. Both apps are communicating through the same Artemis client, which is installed on the server. Artemis version is 1.5.5.
The problem occurs when I execute a simple test that sends 1000 messages divided into multiple groups, in this case 50 groups (numbers are not important, it happens no matter the number of messages or groups) from the server app. The local app consumer receives every group and almost all messages. It's because the server app consumer receives, for example, only one message from - let's say - group number 5. That behavior is repeated in multiple groups.
Why is this happening? Again, both consumers and producers are working on the same Artemis. Apps are written in Spring boot. The local app is deployed using Spring's bootRun task, while the server app is deployed in Wildfly-11.0.0.Final.
Here is my broker.xml file:
<configuration xmlns="urn:activemq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
<jms xmlns="urn:activemq:jms">
<queue name="DLQ"/>
<queue name="ExpiryQueue"/>
<queue name="AlarmsQueue"/>
</jms>
<core xmlns="urn:activemq:core">
<name>0.0.0.0</name>
<persistence-enabled>true</persistence-enabled>
<!-- this could be ASYNCIO or NIO
-->
<journal-type>ASYNCIO</journal-type>
<paging-directory>./data/paging</paging-directory>
<bindings-directory>./data/bindings</bindings-directory>
<journal-directory>./data/journal</journal-directory>
<large-messages-directory>./data/large-messages</large-messages-directory>
<journal-datasync>true</journal-datasync>
<journal-min-files>2</journal-min-files>
<journal-pool-files>-1</journal-pool-files>
<!--
This value was determined through a calculation.
Your system could perform 8.06 writes per millisecond
on the current journal configuration.
That translates as a sync write every 124000 nanoseconds
-->
<journal-buffer-timeout>124000</journal-buffer-timeout>
<!-- how often we are looking for how many bytes are being used on the disk in ms -->
<disk-scan-period>5000</disk-scan-period>
<!-- once the disk hits this limit the system will block, or close the connection in certain protocols
that won't support flow control. -->
<max-disk-usage>95</max-disk-usage>
<!-- the system will enter into page mode once you hit this limit.
This is an estimate in bytes of how much the messages are using in memory -->
<global-max-size>104857600</global-max-size>
<acceptors>
<!-- Default ActiveMQ Artemis Acceptor. Multi-protocol adapter. Currently supports ActiveMQ Artemis Core, OpenWire, STOMP, AMQP, MQTT, and HornetQ Core. -->
<!-- performance tests have shown that openWire performs best with these buffer sizes -->
<acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576</acceptor>
<!-- AMQP Acceptor. Listens on default AMQP port for AMQP traffic.-->
<acceptor name="amqp">tcp://0.0.0.0:5672?protocols=AMQP</acceptor>
<!-- STOMP Acceptor. -->
<acceptor name="stomp">tcp://0.0.0.0:61613?protocols=STOMP</acceptor>
<!-- HornetQ Compatibility Acceptor. Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
<acceptor name="hornetq">tcp://0.0.0.0:5445?protocols=HORNETQ,STOMP</acceptor>
<!-- MQTT Acceptor -->
<acceptor name="mqtt">tcp://0.0.0.0:1883?protocols=MQTT</acceptor>
</acceptors>
<security-settings>
<security-setting match="#">
<permission type="createNonDurableQueue" roles="guest"/>
<permission type="deleteNonDurableQueue" roles="guest"/>
<permission type="createDurableQueue" roles="guest"/>
<permission type="deleteDurableQueue" roles="guest"/>
<permission type="consume" roles="guest"/>
<permission type="browse" roles="guest"/>
<permission type="send" roles="guest"/>
<!-- we need this otherwise ./artemis data imp wouldn't work -->
<permission type="manage" roles="guest"/>
</security-setting>
</security-settings>
<address-settings>
<!--default for catch all-->
<address-setting match="#">
<dead-letter-address>jms.queue.DLQ</dead-letter-address>
<expiry-address>jms.queue.ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- with -1 only the global-max-size is in use for limiting -->
<max-size-bytes>-1</max-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
</address-setting>
</address-settings>
<connectors>
<connector name="netty-connector">tcp://<ip>:61616</connector>
</connectors>
<ha-policy/>
<broadcast-groups>
<broadcast-group name="my-broadcast-group">
<group-address>${udp-address:<ip>}</group-address>
<group-port>9876</group-port>
<broadcast-period>2000</broadcast-period>
<connector-ref>netty-connector</connector-ref>
</broadcast-group>
</broadcast-groups>
<discovery-groups>
<discovery-group name="my-discovery-group">
<group-address>${udp-address:<ip>}</group-address>
<group-port>9876</group-port>
<refresh-timeout>10000</refresh-timeout>
</discovery-group>
</discovery-groups>
<cluster-connections>
<cluster-connection name="my-cluster">
<address>jms</address>
<connector-ref>netty-connector</connector-ref>
<retry-interval>500</retry-interval>
<message-load-balancing>STRICT</message-load-balancing>
<max-hops>1</max-hops>
<discovery-group-ref discovery-group-name="my-discovery-group"/>
</cluster-connection>
</cluster-connections>
</core>
</configuration>
What is the connection factory to use for sending messages outside the VM?
I see in JBOSS/standalone/configuration/configuration_full.xml two factories: InVmConnectionFactory and RemoteConnectionFactory.
Are this the only available factories?
My actual configuration is:
SERVER standalone_full.xml
<subsystem xmlns="urn:jboss:domain:messaging:1.1">
<hornetq-server>
...
<subsystem xmlns="urn:jboss:domain:messaging:1.1">
<jms-connection-factories>
<connection-factory name="InVmConnectionFactory">
<connectors>
<connector-ref connector-name="in-vm"/>
</connectors>
<entries>
<entry name="java:/ConnectionFactory"/>
</entries>
</connection-factory>
<connection-factory name="RemoteConnectionFactory">
<connectors>
<connector-ref connector-name="netty"/>
</connectors>
<entries>
<entry name="RemoteConnectionFactory"/>
<entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
</entries>
</connection-factory>
<pooled-connection-factory name="hornetq-ra">
<transaction mode="xa"/>
<connectors>
<connector-ref connector-name="in-vm"/>
</connectors>
<entries>
<entry name="java:/JmsXA"/>
</entries>
</pooled-connection-factory>
</jms-connection-factories>
</subsystem xmlns="urn:jboss:domain:messaging:1.1">
</hornetq-server>
</subsystem xmlns="urn:jboss:domain:messaging:1.1">
REMOTE MASCINE standalone_full.xml
<subsystem xmlns="urn:jboss:domain:messaging:1.1">
<hornetq-server>
...
<subsystem xmlns="urn:jboss:domain:messaging:1.1">
<jms-connection-factories> same factories as SERVER </jms-connection-factories>
<jms-destinations>
<jms-queue name="remoteQueue">
<entry name="jms/remoteQueue"/>
<entry name="java:jboss/exported/jms/queue/remoteQueue"/>
</jms-queue>
</jms-destinations>
</subsystem xmlns="urn:jboss:domain:messaging:1.1">
</hornetq-server>
</subsystem xmlns="urn:jboss:domain:messaging:1.1">
Lookup from SERVER side, server-application.ear:
ConnectionFactory connectionFactory = (ConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
Destination destination = (Destination) ctx.lookup("jms/queue/remoteQueue");
Context build like:
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
properties.put(Context.PROVIDER_URL, "remote://" + messageConnection.getHost() + ":" + messageConnection.getPort());
properties.put(Context.SECURITY_PRINCIPAL, messageConnection.getUsername());
properties.put(Context.SECURITY_CREDENTIALS, messageConnection.getPassword());
Context ctx = new InitialContext(properties);
Error I get:
Caused by: java.io.NotSerializableException: org.hornetq.api.core.client.loadbalance.RoundRobinConnectionLoadBalancingPolicy
Caused by: an exception which occurred:
in field loadBalancingPolicy
in field serverLocator
in object org.hornetq.jms.client.HornetQJMSConnectionFactory#36cdb608
If I try to deploy both applications server-application.ear and remote-application.ear in the same jboss(same VM), the messaging in working fine.
This problem occur when I use two jbosses (in the same macchine).
Anyone has any idea?
Thank you in advance.
InVmConnectionFactory references an in-vm-connector and can be used to send and receive messages when both the client and server are running in the same JVM. RemoteConnectionFactory references an netty connector and can be used to send and receive messages when client and server are running in different JVMs. You can define your own connection factory based on connector.
Regarding error, could you post complete stack trace ?
This answer in the JBossDeveloper forum is the answer to the question:
Remote JMS queue in JBoss AS 7.1
Will not show a fully working example for Netty configuration making two nodes exchanging messages, but is very helpful to understand the concept.
Most app. servers provide a way of tuning the number of WebContainer worker-threads when it goes down to tuning. Is it possible to do that in JBoss AS 7.x?
Thanks.
you can tune the HTTP Conector of the AS7 web subsystem. The available attributes you can tune for the HTTP Connector are described here The Http Connector. To define the max-connections for this connector you need change it in $JBOSS_HOME/standalone/configuration/standalone.xml or $JBOSS_HOME/domain/configuration/domain.xml
See this piece of configuration:
<subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">
<connector name="http"
protocol="HTTP/1.1"
scheme="http"
socket-binding="http"
max-connections="250"/>
...
</subsystem>
To define a thread pool specific for the HTTP Connector you need to use the AS7 threads subsystem like this one:
<subsystem xmlns="urn:jboss:domain:threads:1.0">
<bounded-queue-thread-pool name="http-executor" blocking="true">
<core-threads count="10" per-cpu="20" />
<queue-length count="10" per-cpu="20" />
<max-threads count="10" per-cpu="20" />
<keepalive-time time="10" unit="seconds" />
</bounded-queue-thread-pool>
</subsystem>
and then you need to reference it in the executor attribute of the HTTP Connector. See this piece of config:
<subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">
<connector name="http"
protocol="HTTP/1.1"
scheme="http"
socket-binding="http"
max-connections="250"
executor="http-executor"/>
...
</subsystem>
For more details about tuning the AS7 see this post JBoss AS 7 Performance tuning - Tuning Web server thread pool on the masterjboss.com.