diff --git a/playbooks/activemq_cluster.yml b/playbooks/activemq_cluster.yml new file mode 100644 index 00000000..606a8351 --- /dev/null +++ b/playbooks/activemq_cluster.yml @@ -0,0 +1,29 @@ +--- +- name: Playbook for Red Hat AMQ Broker + hosts: all + vars: + amq_broker_ha_enabled: true + amq_broker_disable_hornetq_protocol: true + amq_broker_disable_mqtt_protocol: true + amq_broker_shared_storage: true + amq_broker_configure_firewalld: true + collections: + - middleware_automation.redhat_csp_download + - middleware_automation.amq + roles: + - amq_broker + pre_tasks: + - name: Create nfs shared directory + ansible.builtin.file: + state: directory + path: /opt/amq/amq-broker/data/shared + owner: root + group: root + mode: 0775 + - name: Create mount NFS volume + ansible.posix.mount: + src: 10.0.153.34:/nfs + path: /opt/amq/amq-broker/data/shared + opts: rw,sync,hard,intr + state: mounted + fstype: nfs diff --git a/roles/amq_broker/README.md b/roles/amq_broker/README.md index 666f6218..560afeb0 100644 --- a/roles/amq_broker/README.md +++ b/roles/amq_broker/README.md @@ -90,6 +90,7 @@ Role Defaults |`amq_broker_cluster_lb_policy`| Policy for cluster load balancing | `ON_DEMAND` | |`amq_broker_replicate`| Enables replication | `False` | |`amq_broker_replicated`| Designate instance as replicated node | `False` | +|`amq_broker_cluster_discovery` | Cluster discovery: [`jgroups` (shared file ping), `multicast` (UDP), `static` (node list)] | `static` | * TLS/SSL protocol @@ -108,6 +109,7 @@ Role Defaults |:---------|:------------|:--------| |`amq_broker_nio_enabled`| Enable Native IO using libaio | `False` | |`amq_broker_shared_storage`| Use shared filesystem directory for storage | `False` | +|`amq_broker_shared_storage_path`| Path of shared directory relative to activemq home directory | `data/shared` | |`amq_broker_disable_destination_autocreate`| Disable automatic creation of destination | `True` | |`amq_broker_queues`| Queue names comma separated | `queue.in,queue.out` | |`amq_broker_disable_amqp_protocol`| Whether to disable AMQP protocol | `False` | diff --git a/roles/amq_broker/defaults/main.yml b/roles/amq_broker/defaults/main.yml index e3db0770..22c753b4 100644 --- a/roles/amq_broker/defaults/main.yml +++ b/roles/amq_broker/defaults/main.yml @@ -49,6 +49,8 @@ amq_broker_cluster_maxhops: 1 amq_broker_cluster_lb_policy: ON_DEMAND amq_broker_replicate: False amq_broker_replicated: False +# cluster discovery: ['jgroups' for shared file ping, 'multicast' for UDP multicast, 'static' for static declaration] +amq_broker_cluster_discovery: static ### Enable database configuration for JDBC persistence amq_broker_db_enabled: False @@ -70,6 +72,7 @@ amq_broker_nio_enabled: False ## Shared Storage amq_broker_shared_storage: False +amq_broker_shared_storage_path: data/shared ## Ports amq_broker_ports_offset_enabled: False @@ -83,4 +86,4 @@ amq_broker_queues: queue.in,queue.out amq_broker_disable_amqp_protocol: False amq_broker_disable_hornetq_protocol: False amq_broker_disable_mqtt_protocol: False -amq_broker_disable_stomp_protocol: False \ No newline at end of file +amq_broker_disable_stomp_protocol: False diff --git a/roles/amq_broker/meta/argument_specs.yml b/roles/amq_broker/meta/argument_specs.yml index 81a0b2ed..7e7601b5 100644 --- a/roles/amq_broker/meta/argument_specs.yml +++ b/roles/amq_broker/meta/argument_specs.yml @@ -201,6 +201,10 @@ argument_specs: default: "ON_DEMAND" description: "Policy for cluster load balancing" type: "str" + amq_broker_cluster_discovery: + default: "static" + description: "Cluster discovery: ['jgroups' for shared file ping, 'multicast' for UDP multicast, 'static' for static declaration]" + type: "str" amq_broker_replicate: # line 50 of defaults/main.yml default: false @@ -261,6 +265,10 @@ argument_specs: default: false description: "Use shared filesystem directory for storage" type: "bool" + amq_broker_shared_storage_path: + default: "data/shared" + description: "Path of shared directory relative to activemq home directory" + type: "str" amq_broker_ports_offset_enabled: # line 75 of defaults/main.yml default: false diff --git a/roles/amq_broker/tasks/configure.yml b/roles/amq_broker/tasks/configure.yml index e54c7e56..344bf740 100644 --- a/roles/amq_broker/tasks/configure.yml +++ b/roles/amq_broker/tasks/configure.yml @@ -7,7 +7,7 @@ "name": amq_broker.instance_name, "address": item, "inventory_host": item, - "value": "tcp://" + item + ":" + (((61616|int + amq_broker_ports_offset|int)|abs)|string) + "value": "tcp://" + item + ":" + (((amq_broker_port|int + amq_broker_ports_offset|int)|abs)|string) } ] }} loop: "{{ ansible_play_batch }}" @@ -25,10 +25,19 @@ - "--cluster-user {{ amq_broker_cluster_user }}" - "--cluster-password {{ amq_broker_cluster_pass }}" - "--max-hops {{ amq_broker_cluster_maxhops }}" - - "--message-load-balancing {{ amq_broker_cluster_load_balancing_policy }}" + - "--message-load-balancing {{ amq_broker_cluster_lb_policy }}" - "--failover-on-shutdown" when: amq_broker_ha_enabled +- name: Enable static clustering + ansible.builtin.set_fact: + amq_broker_options: + - "{{ amq_broker_options | join(' ') }}" + - "--staticCluster {{ amq_broker_cluster_nodes | map(attribute='value') | join(',') }}" + when: + - amq_broker_ha_enabled + - amq_broker_cluster_discovery == "static" + - name: Enable security ansible.builtin.set_fact: amq_broker_options: @@ -48,7 +57,7 @@ ansible.builtin.set_fact: amq_broker_options: - "{{ amq_broker_options | join(' ') }}" - - "--http-host {{ amq_broker_host }}" + - "--http-host {{ amq_broker_bind_address }}" - name: Disable automatic creation of queues ansible.builtin.set_fact: @@ -89,7 +98,7 @@ amq_broker_options: - "{{ amq_broker_options | join(' ') }}" - "--shared-store" - - "--data {{ amq_broker.home }}/data" + - "--data {{ amq_broker.instance_home }}/{{ amq_broker_shared_storage_path }}" when: amq_broker_shared_storage - name: Set up port offset diff --git a/roles/amq_broker/tasks/jgroups.yml b/roles/amq_broker/tasks/jgroups.yml new file mode 100644 index 00000000..f8f9113b --- /dev/null +++ b/roles/amq_broker/tasks/jgroups.yml @@ -0,0 +1,9 @@ +--- +- name: configure - clustering - remove discovery groups + xml: + path: "{{ amq_broker.home }}/etc/broker.xml" + xpath: /conf:configuration/core:core/core:discovery-groups + state: absent + namespaces: + conf: urn:activemq + core: urn:activemq:core diff --git a/roles/amq_broker/tasks/systemd.yml b/roles/amq_broker/tasks/systemd.yml index b9b80b1f..de2bc6f6 100644 --- a/roles/amq_broker/tasks/systemd.yml +++ b/roles/amq_broker/tasks/systemd.yml @@ -35,15 +35,21 @@ - name: "Check instance directory: {{ amq_broker_dest }}/{{ amq_broker.instance_name }}" ansible.builtin.stat: - path: "{{ amq_broker_dest }}/{{ amq_broker.instance_name }}" + path: "{{ amq_broker_dest }}/{{ amq_broker.instance_name }}/bin" register: instance_directory become: yes -- name: "Generate configuration for: {{ amq_broker_dest }}/{{ amq_broker.instance_name }}" +- name: "Generate artemis configuration for: {{ amq_broker_dest }}/{{ amq_broker.instance_name }}" ansible.builtin.include_tasks: configure.yml when: - not instance_directory.stat.exists +- name: "Setup clustering with jgroups" + ansible.builtin.include_tasks: jgroups.yml + when: + - amq_broker_ha_enabled + - amq_broker_cluster_discovery == 'jgroups' + - name: "Create instance {{ amq_broker.instance_name }} of {{ amq_broker.service_name }}" ansible.builtin.command: cmd: "{{ amq_broker.home }}/bin/artemis create {{ amq_broker.instance_home }} {{ amq_broker_options }}" @@ -71,6 +77,8 @@ ansible.builtin.command: "systemctl status {{ amq_broker.instance_name }}" register: amq_broker_service_status changed_when: False + retries: 6 + delay: 5 - name: Verify service status ansible.builtin.assert: diff --git a/roles/amq_broker/templates/jgroups_ping.xml.j2 b/roles/amq_broker/templates/jgroups_ping.xml.j2 new file mode 100644 index 00000000..4a72c11b --- /dev/null +++ b/roles/amq_broker/templates/jgroups_ping.xml.j2 @@ -0,0 +1,56 @@ +<!-- (( ansible_managed )) --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="urn:org:jgroups" + xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/jgroups.xsd"> + + <TCP loopback="false" + bind_addr="{{ broker_private_ip }}" + bind_port="7800" + use_send_queues="true" + recv_buf_size="${tcp.recv_buf_size:5M}" + send_buf_size="${tcp.send_buf_size:5M}" + max_bundle_size="64K" + max_bundle_timeout="30" + sock_conn_timeout="300" + + timer_type="new3" + timer.min_threads="4" + timer.max_threads="10" + timer.keep_alive_time="3000" + timer.queue_max_size="500" + + thread_pool.enabled="true" + thread_pool.min_threads="2" + thread_pool.max_threads="8" + thread_pool.keep_alive_time="5000" + thread_pool.queue_enabled="true" + thread_pool.queue_max_size="10000" + thread_pool.rejection_policy="discard" + + oob_thread_pool.enabled="true" + oob_thread_pool.min_threads="1" + oob_thread_pool.max_threads="8" + oob_thread_pool.keep_alive_time="5000" + oob_thread_pool.queue_enabled="false" + oob_thread_pool.queue_max_size="100" + oob_thread_pool.rejection_policy="discard" /> + + <FILE_PING location="{{ amq_broker.home }}/{{ amq_broker_shared_storage_path }}/file-ping" /> + <MERGE3 min_interval="10000" + max_interval="30000"/> + <FD_SOCK/> + <FD timeout="3000" max_tries="3"/> + <VERIFY_SUSPECT timeout="1500"/> + <BARRIER/> + <pbcast.NAKACK2 use_mcast_xmit="false" + discard_delivered_msgs="true"/> + <UNICAST3/> + <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000" + max_bytes="4M"/> + <pbcast.GMS print_local_addr="true" join_timeout="2000" + view_bundling="true"/> + <MFC max_credits="2M" + min_threshold="0.4"/> + <FRAG2 frag_size="60K"/> + <pbcast.STATE_TRANSFER/> +</config> \ No newline at end of file