rocketmq ansible playbook
diff --git a/rocketmq-ansible/broker.yml b/rocketmq-ansible/broker.yml
new file mode 100644
index 0000000..86ff72a
--- /dev/null
+++ b/rocketmq-ansible/broker.yml
@@ -0,0 +1,5 @@
+---

+# deploy rocketmq broker

+- hosts: rocketmq_broker

+  roles:

+    - broker
\ No newline at end of file
diff --git a/rocketmq-ansible/exporter.yml b/rocketmq-ansible/exporter.yml
new file mode 100644
index 0000000..26b3bc7
--- /dev/null
+++ b/rocketmq-ansible/exporter.yml
@@ -0,0 +1,5 @@
+---

+# deploy rocketmq exporter

+- hosts: rocketmq_exporter

+  roles:

+    - exporter
\ No newline at end of file
diff --git a/rocketmq-ansible/hosts b/rocketmq-ansible/hosts
new file mode 100644
index 0000000..821e1e1
--- /dev/null
+++ b/rocketmq-ansible/hosts
@@ -0,0 +1,22 @@
+#used by terraform api

+#rocketmq namesrv

+[rocketmq_namesrv]

+127.0.0.1

+127.0.0.2

+

+#rocketmq broker 

+[rocketmq_broker]

+127.0.0.3 brokerName=broker-a brokerId=0 brokerRole=ASYNC_MASTER

+127.0.0.4 brokerName=broker-a brokerId=1 brokerRole=SLAVE

+[rocketmq_broker:vars]

+brokerClusterName=DefaultCluster

+namesrvAddr=127.0.0.1:9876;127.0.0.2:9876

+storePathRootDir=/chj/data/rocketmq/store

+

+#rocketmq exporter

+[rocketmq_exporter]

+127.0.0.5

+[rocketmq_exporter:vars]

+namesrvAddr=127.0.0.1:9876;127.0.0.2:9876

+webTelemetryPath=/metrics

+rocketmqVersion=V4_7_1
\ No newline at end of file
diff --git a/rocketmq-ansible/namesrv.yml b/rocketmq-ansible/namesrv.yml
new file mode 100644
index 0000000..9db3f61
--- /dev/null
+++ b/rocketmq-ansible/namesrv.yml
@@ -0,0 +1,5 @@
+---

+# deploy rocketmq namesrv

+- hosts: rocketmq_namesrv

+  roles:

+    - namesrv
\ No newline at end of file
diff --git a/rocketmq-ansible/rocketmq.yml b/rocketmq-ansible/rocketmq.yml
new file mode 100644
index 0000000..38c8e20
--- /dev/null
+++ b/rocketmq-ansible/rocketmq.yml
@@ -0,0 +1,26 @@
+---

+# deploy rocketmq cluster

+- name: RocketMQ

+  hosts: all

+  become: yes

+  become_user: root

+  become_method: sudo

+  gather_facts: False

+  vars_files:

+    - vars/main.yml

+

+  pre_tasks:

+    - name: create rocketmq deploy path

+      file:

+        path: "{{ rocketmq_deploy_path }}"

+        state: directory

+        recurse: yes

+    - name: create rocketmq data path

+      file:

+        path: "{{ rocketmq_data_path }}"

+        state: directory

+        recurse: yes

+

+- include: namesrv.yml

+- include: broker.yml

+- include: exporter.yml
\ No newline at end of file
diff --git a/rocketmq-ansible/roles/broker/tasks/main.yml b/rocketmq-ansible/roles/broker/tasks/main.yml
new file mode 100644
index 0000000..b59c9e8
--- /dev/null
+++ b/rocketmq-ansible/roles/broker/tasks/main.yml
@@ -0,0 +1,54 @@
+- name: check broker deploy directory

+  stat:

+    path: "{{ rocketmq_deploy_path }}/rocketmq"

+  register: deploy_directory

+

+- debug:

+    msg: "{{ deploy_directory }}"

+

+- name: download rocketmq

+  unarchive:

+    src: "{{ rocketmq_download_url }}"

+    dest: "{{ rocketmq_deploy_path }}"

+    remote_src: yes

+    mode: 0750

+  when: deploy_directory.stat.exists == False

+

+- name: rename rocketmq dir name

+  shell: cd {{ rocketmq_deploy_path }}; if [ ! -d "rocketmq" ]; then mv rocketmq-* rocketmq; fi

+

+- name: modify broker log path

+  template:

+    src: logback_broker.xml.j2

+    dest: "{{ rocketmq_deploy_path }}/rocketmq/conf/logback_broker.xml"

+

+- name: modify broker config

+  template:

+    src: broker.conf.j2

+    dest: "{{ rocketmq_deploy_path }}/rocketmq/conf/broker.conf"

+

+- name: copy broker service script

+  template:

+    src: mqbroker.service

+    dest: /usr/lib/systemd/system

+    mode: 0750

+

+- name: check broker process

+  shell: source /etc/profile && jps | grep BrokerStartup | wc -l

+  register: check_status

+

+- debug:

+    msg: "{{ check_status }}"

+

+- name: optimize os

+  shell: source /etc/profile && sh {{ rocketmq_deploy_path }}/rocketmq/bin/os.sh

+  when: deploy_directory.stat.exists == False

+

+- name: start broker

+  shell: |

+    source /etc/profile

+    systemctl disable mqbroker

+    systemctl enable mqbroker

+    systemctl stop mqbroker

+    systemctl start mqbroker

+  when: check_status.stdout|int == 0
\ No newline at end of file
diff --git a/rocketmq-ansible/roles/broker/templates/broker.conf.j2 b/rocketmq-ansible/roles/broker/templates/broker.conf.j2
new file mode 100644
index 0000000..6a4c335
--- /dev/null
+++ b/rocketmq-ansible/roles/broker/templates/broker.conf.j2
@@ -0,0 +1,35 @@
+# 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.
+
+brokerClusterName={{ brokerClusterName }}
+brokerName={{ brokerName }}
+brokerId={{ brokerId }}
+namesrvAddr={{ namesrvAddr }}
+autoCreateTopicEnable=false
+sendMessageThreadPoolNums=4
+waitTimeMillsInSendQueue=1000
+sendThreadPoolQueueCapacity=20000
+
+
+brokerRole={{ brokerRole }}
+flushDiskType=ASYNC_FLUSH
+storePathRootDir={{ storePathRootDir }}
+storePathCommitLog={{ storePathRootDir }}/commitlog
+#maxMessageSize=1048576
+messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
+osPageCacheBusyTimeOutMills=1500
+#transientStorePoolEnable=true
+diskMaxUsedSpaceRatio=88
+fileReservedTime=168
diff --git a/rocketmq-ansible/roles/broker/templates/logback_broker.xml.j2 b/rocketmq-ansible/roles/broker/templates/logback_broker.xml.j2
new file mode 100644
index 0000000..edae025
--- /dev/null
+++ b/rocketmq-ansible/roles/broker/templates/logback_broker.xml.j2
@@ -0,0 +1,337 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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>
+    <appender name="DefaultAppender"
+              class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>{{ rocketmq_data_path }}/log/db-rocketmq/broker_default.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_data_path }}/log/db-rocketmq/otherdays/broker_default.%i.log.gz</fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>10</maxIndex>
+        </rollingPolicy>
+        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>100MB</maxFileSize>
+        </triggeringPolicy>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH:mm:ss,GMT+8} %p %t - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+
+    <appender name="RocketmqBrokerAppender_inner"
+              class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>{{ rocketmq_data_path }}/log/db-rocketmq/broker.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_data_path }}/log/db-rocketmq/otherdays/broker.%i.log.gz</fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>20</maxIndex>
+        </rollingPolicy>
+        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>128MB</maxFileSize>
+        </triggeringPolicy>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH:mm:ss,GMT+8} %p %t - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="RocketmqBrokerAppender" class="ch.qos.logback.classic.AsyncAppender">
+        <appender-ref ref="RocketmqBrokerAppender_inner"/>
+    </appender>
+
+    <appender name="RocketmqProtectionAppender_inner"
+              class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>{{ rocketmq_data_path }}/log/db-rocketmq/protection.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_data_path }}/log/db-rocketmq/otherdays/protection.%i.log.gz</fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>10</maxIndex>
+        </rollingPolicy>
+        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>100MB</maxFileSize>
+        </triggeringPolicy>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH:mm:ss,GMT+8} - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="RocketmqProtectionAppender" class="ch.qos.logback.classic.AsyncAppender">
+        <appender-ref ref="RocketmqProtectionAppender_inner"/>
+    </appender>
+
+    <appender name="RocketmqWaterMarkAppender_inner"
+              class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>{{ rocketmq_data_path }}/log/db-rocketmq/watermark.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_data_path }}/log/db-rocketmq/otherdays/watermark.%i.log.gz</fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>10</maxIndex>
+        </rollingPolicy>
+        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>100MB</maxFileSize>
+        </triggeringPolicy>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH:mm:ss,GMT+8} - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="RocketmqWaterMarkAppender" class="ch.qos.logback.classic.AsyncAppender">
+        <appender-ref ref="RocketmqWaterMarkAppender_inner"/>
+    </appender>
+
+    <appender name="RocketmqStoreAppender_inner"
+              class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>{{ rocketmq_data_path }}/log/db-rocketmq/store.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_data_path }}/log/db-rocketmq/otherdays/store.%i.log.gz</fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>10</maxIndex>
+        </rollingPolicy>
+        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>128MB</maxFileSize>
+        </triggeringPolicy>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH:mm:ss,GMT+8} %p %t - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="RocketmqStoreAppender" class="ch.qos.logback.classic.AsyncAppender">
+        <appender-ref ref="RocketmqStoreAppender_inner"/>
+    </appender>
+
+    <appender name="RocketmqRemotingAppender_inner"
+              class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>{{ rocketmq_data_path }}/log/db-rocketmq/remoting.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_data_path }}/log/db-rocketmq/otherdays/remoting.%i.log.gz</fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>10</maxIndex>
+        </rollingPolicy>
+        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>100MB</maxFileSize>
+        </triggeringPolicy>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH:mm:ss,GMT+8} %p %t - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="RocketmqRemotingAppender" class="ch.qos.logback.classic.AsyncAppender">
+        <appender-ref ref="RocketmqRemotingAppender_inner"/>
+    </appender>
+
+    <appender name="RocketmqStoreErrorAppender_inner"
+              class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>{{ rocketmq_data_path }}/log/db-rocketmq/storeerror.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_data_path }}/log/db-rocketmq/otherdays/storeerror.%i.log.gz</fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>10</maxIndex>
+        </rollingPolicy>
+        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>100MB</maxFileSize>
+        </triggeringPolicy>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH:mm:ss,GMT+8} %p %t - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="RocketmqStoreErrorAppender" class="ch.qos.logback.classic.AsyncAppender">
+        <appender-ref ref="RocketmqStoreErrorAppender_inner"/>
+    </appender>
+
+
+    <appender name="RocketmqTransactionAppender_inner"
+              class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>{{ rocketmq_data_path }}/log/db-rocketmq/transaction.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_data_path }}/log/db-rocketmq/otherdays/transaction.%i.log.gz</fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>10</maxIndex>
+        </rollingPolicy>
+        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>100MB</maxFileSize>
+        </triggeringPolicy>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH:mm:ss,GMT+8} %p %t - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="RocketmqTransactionAppender" class="ch.qos.logback.classic.AsyncAppender">
+        <appender-ref ref="RocketmqTransactionAppender_inner"/>
+    </appender>
+
+    <appender name="RocketmqRebalanceLockAppender_inner"
+              class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>{{ rocketmq_data_path }}/log/db-rocketmq/lock.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_data_path }}/log/db-rocketmq/otherdays/lock.%i.log.gz</fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>5</maxIndex>
+        </rollingPolicy>
+        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>100MB</maxFileSize>
+        </triggeringPolicy>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH:mm:ss,GMT+8} %p %t - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="RocketmqRebalanceLockAppender" class="ch.qos.logback.classic.AsyncAppender">
+        <appender-ref ref="RocketmqRebalanceLockAppender_inner"/>
+    </appender>
+
+    <appender name="RocketmqFilterAppender_inner"
+              class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>{{ rocketmq_data_path }}/log/db-rocketmq/filter.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_data_path }}/log/db-rocketmq/otherdays/filter.%i.log.gz</fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>10</maxIndex>
+        </rollingPolicy>
+        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>100MB</maxFileSize>
+        </triggeringPolicy>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH:mm:ss,GMT+8} %p %t - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="RocketmqFilterAppender" class="ch.qos.logback.classic.AsyncAppender">
+        <appender-ref ref="RocketmqFilterAppender_inner"/>
+    </appender>
+
+    <appender name="RocketmqStatsAppender"
+              class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>{{ rocketmq_data_path }}/log/db-rocketmq/stats.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_data_path }}/log/db-rocketmq/otherdays/stats.%i.log.gz</fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>5</maxIndex>
+        </rollingPolicy>
+        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>100MB</maxFileSize>
+        </triggeringPolicy>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH:mm:ss,GMT+8} %p - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+
+    <appender name="RocketmqCommercialAppender"
+              class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>{{ rocketmq_data_path }}/log/db-rocketmq/commercial.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_data_path }}/log/db-rocketmq/otherdays/commercial.%i.log.gz</fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>10</maxIndex>
+        </rollingPolicy>
+        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>500MB</maxFileSize>
+        </triggeringPolicy>
+    </appender>
+
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <append>true</append>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH\:mm\:ss,GMT+8} %p %t - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+
+    <logger name="RocketmqBroker" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqBrokerAppender"/>
+    </logger>
+
+    <logger name="RocketmqProtection" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqProtectionAppender"/>
+    </logger>
+
+    <logger name="RocketmqWaterMark" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqWaterMarkAppender"/>
+    </logger>
+
+    <logger name="RocketmqCommon" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqBrokerAppender"/>
+    </logger>
+
+    <logger name="RocketmqStore" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqStoreAppender"/>
+    </logger>
+
+    <logger name="RocketmqStoreError" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqStoreErrorAppender"/>
+    </logger>
+
+    <logger name="RocketmqTransaction" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqTransactionAppender"/>
+    </logger>
+
+    <logger name="RocketmqRebalanceLock" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqRebalanceLockAppender"/>
+    </logger>
+
+    <logger name="RocketmqRemoting" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqRemotingAppender"/>
+    </logger>
+
+    <logger name="RocketmqStats" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqStatsAppender"/>
+    </logger>
+
+    <logger name="RocketmqCommercial" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqCommercialAppender"/>
+    </logger>
+
+    <logger name="RocketmqFilter" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqFilterAppender"/>
+    </logger>
+
+    <logger name="RocketmqConsole" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="STDOUT"/>
+    </logger>
+
+    <root>
+        <level value="INFO"/>
+        <appender-ref ref="DefaultAppender"/>
+    </root>
+</configuration>
diff --git a/rocketmq-ansible/roles/broker/templates/mqbroker.service b/rocketmq-ansible/roles/broker/templates/mqbroker.service
new file mode 100644
index 0000000..47aa0bb
--- /dev/null
+++ b/rocketmq-ansible/roles/broker/templates/mqbroker.service
@@ -0,0 +1,15 @@
+[Unit]

+Description=rocketmq namesrv service

+After=network.target

+

+[Service]

+Type=simple

+

+ExecStart=/bin/bash -c 'source /etc/profile && {{ rocketmq_deploy_path }}/rocketmq/bin/mqbroker -c {{ rocketmq_deploy_path }}/rocketmq/conf/broker.conf'

+ExecStop=/bin/bash -c 'source /etc/profile && {{ rocketmq_deploy_path }}/rocketmq/bin/mqshutdown broker'

+RemainAfterExit=yes

+

+Restart=always

+RestartSec=5s

+[Install]

+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/rocketmq-ansible/roles/broker/vars/main.yml b/rocketmq-ansible/roles/broker/vars/main.yml
new file mode 100644
index 0000000..68db6ce
--- /dev/null
+++ b/rocketmq-ansible/roles/broker/vars/main.yml
@@ -0,0 +1,4 @@
+# namesrv variable

+rocketmq_download_url: https://dlcdn.apache.org/rocketmq/4.9.3/rocketmq-all-4.9.3-bin-release.zip

+rocketmq_deploy_path: /app

+rocketmq_data_path: /data
\ No newline at end of file
diff --git a/rocketmq-ansible/roles/exporter/files/mqexportershutdown.sh b/rocketmq-ansible/roles/exporter/files/mqexportershutdown.sh
new file mode 100644
index 0000000..9465346
--- /dev/null
+++ b/rocketmq-ansible/roles/exporter/files/mqexportershutdown.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+source /etc/profile
+pid=$(jps -lvVm | grep rocketmq-exporter | awk '{print $1}')
+
+if [ ! -z $pid ]; then
+  kill -9 $pid
+fi
\ No newline at end of file
diff --git a/rocketmq-ansible/roles/exporter/tasks/main.yml b/rocketmq-ansible/roles/exporter/tasks/main.yml
new file mode 100644
index 0000000..7a21e83
--- /dev/null
+++ b/rocketmq-ansible/roles/exporter/tasks/main.yml
@@ -0,0 +1,45 @@
+- name: create rocketmq exporter deploy directory

+  file:

+    path: "{{ rocketmq_exporter_deploy_directory }}"

+    state: directory

+    recurse: yes

+

+- name: download rocketmq exporter

+  get_url:

+    url: "{{ rocketmq_exporter_download_url }}"

+    dest: "{{ rocketmq_exporter_deploy_directory }}"

+    mode: 0750

+

+- name: copy mqexportershutdown script

+  copy:

+    src: mqexportershutdown.sh

+    dest: "{{ rocketmq_exporter_deploy_directory }}"

+    mode: 0750

+

+- name: copy mqexporter service script

+  template:

+    src: mqexporter.service

+    dest: /usr/lib/systemd/system

+    mode: 0750

+

+- name: replace and copy mqexporter script

+  template:

+    src: mqexporter.sh.j2

+    dest: "{{rocketmq_exporter_deploy_directory}}/mqexporter.sh"

+    mode: 0750

+

+- name: check rocketmq exporter status

+  shell: source /etc/profile && jps -lvVm | grep rocketmq-exporter | wc -l

+  register: status_result

+

+- debug:

+    msg: "{{ status_result }}"

+

+- name: start rocketmq exporter

+  shell: |

+    source /etc/profile

+    systemctl disable mqexporter

+    systemctl enable mqexporter

+    systemctl stop mqexporter

+    systemctl start mqexporter

+  when: status_result.stdout|int == 0
\ No newline at end of file
diff --git a/rocketmq-ansible/roles/exporter/templates/mqexporter.service b/rocketmq-ansible/roles/exporter/templates/mqexporter.service
new file mode 100644
index 0000000..cba3963
--- /dev/null
+++ b/rocketmq-ansible/roles/exporter/templates/mqexporter.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=rocketmq exporter service
+After=network.target
+
+[Service]
+Type=simple
+
+ExecStart=/bin/bash -c 'source /etc/profile && {{ rocketmq_exporter_deploy_directory }}/mqexporter.sh'
+ExecStop=/bin/bash -c 'source /etc/profile && {{ rocketmq_exporter_deploy_directory }}/mqexportershutdown.sh'
+RemainAfterExit=yes
+
+Restart=always
+RestartSec=5s
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/rocketmq-ansible/roles/exporter/templates/mqexporter.sh.j2 b/rocketmq-ansible/roles/exporter/templates/mqexporter.sh.j2
new file mode 100644
index 0000000..70bf8cc
--- /dev/null
+++ b/rocketmq-ansible/roles/exporter/templates/mqexporter.sh.j2
@@ -0,0 +1,6 @@
+#!/bin/sh
+source /etc/profile
+nohup java -Drocketmq.namesrv.addr="{{ namesrvAddr }}" \
+    -Drocketmq.config.webTelemetryPath={{ webTelemetryPath }} \
+    -Drocketmq.config.rocketmqVersion={{ rocketmqVersion }} \
+    -jar {{ rocketmq_exporter_deploy_directory }}/rocketmq-exporter-0.0.2-SNAPSHOT.jar &
\ No newline at end of file
diff --git a/rocketmq-ansible/roles/exporter/vars/main.yml b/rocketmq-ansible/roles/exporter/vars/main.yml
new file mode 100644
index 0000000..de9e46f
--- /dev/null
+++ b/rocketmq-ansible/roles/exporter/vars/main.yml
@@ -0,0 +1,4 @@
+#exporter variable

+#exporter need build by yourself

+rocketmq_exporter_download_url: http://rocketmq.exporter/rocketmq-exporter-0.0.2-SNAPSHOT.jar

+rocketmq_exporter_deploy_directory: /app/exporter
\ No newline at end of file
diff --git a/rocketmq-ansible/roles/namesrv/tasks/main.yml b/rocketmq-ansible/roles/namesrv/tasks/main.yml
new file mode 100644
index 0000000..400e680
--- /dev/null
+++ b/rocketmq-ansible/roles/namesrv/tasks/main.yml
@@ -0,0 +1,45 @@
+- name: check namesrv deploy directory

+  stat:

+    path: "{{ rocketmq_deploy_path }}/rocketmq"

+  register: deploy_directory

+

+- debug:

+    msg: "{{ deploy_directory }}"

+

+- name: download rocketmq

+  unarchive:

+    src: "{{ rocketmq_download_url }}"

+    dest: "{{ rocketmq_deploy_path }}"

+    remote_src: yes

+    mode: 0750

+  when: deploy_directory.stat.exists == False

+

+- name: rename rocketmq directory name

+  shell: cd {{ rocketmq_deploy_path }}; if [ ! -d "rocketmq" ]; then mv rocketmq-* rocketmq; fi

+

+- name: modify namesrv log path

+  template:

+    src: logback_namesrv.xml.j2

+    dest: "{{ rocketmq_deploy_path }}/rocketmq/conf/logback_namesrv.xml"

+

+- name: copy namesrv service script

+  template:

+    src: mqnamesrv.service

+    dest: /usr/lib/systemd/system

+    mode: 0750

+

+- name: check namesrv process status

+  shell: source /etc/profile && jps | grep NamesrvStartup | wc -l

+  register: check_status

+

+- debug:

+    msg: "{{ check_status }}"

+

+- name: start namesrv

+  shell: |

+    source /etc/profile

+    systemctl disable mqnamesrv

+    systemctl enable mqnamesrv

+    systemctl stop mqnamesrv

+    systemctl start mqnamesrv

+  when: check_status.stdout|int == 0
\ No newline at end of file
diff --git a/rocketmq-ansible/roles/namesrv/templates/logback_namesrv.xml.j2 b/rocketmq-ansible/roles/namesrv/templates/logback_namesrv.xml.j2
new file mode 100644
index 0000000..a252117
--- /dev/null
+++ b/rocketmq-ansible/roles/namesrv/templates/logback_namesrv.xml.j2
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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>
+    <appender name="DefaultAppender"
+              class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>{{ rocketmq_data_path }}/logs/rocketmqlogs/namesrv_default.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_data_path }}/logs/rocketmqlogs/otherdays/namesrv_default.%i.log.gz</fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>5</maxIndex>
+        </rollingPolicy>
+        <triggeringPolicy
+            class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>100MB</maxFileSize>
+        </triggeringPolicy>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH:mm:ss,GMT+8} %p %t - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+
+    <appender name="RocketmqNamesrvAppender_inner"
+              class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>{{ rocketmq_data_path }}/logs/rocketmqlogs/namesrv.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_data_path }}/logs/rocketmqlogs/otherdays/namesrv.%i.log.gz</fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>5</maxIndex>
+        </rollingPolicy>
+        <triggeringPolicy
+            class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>100MB</maxFileSize>
+        </triggeringPolicy>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH:mm:ss,GMT+8} %p %t - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="RocketmqNamesrvAppender" class="ch.qos.logback.classic.AsyncAppender">
+        <appender-ref ref="RocketmqNamesrvAppender_inner"/>
+        <discardingThreshold>0</discardingThreshold>
+    </appender>
+
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <append>true</append>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH\:mm\:ss,SSS} %p %t - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+
+    <logger name="RocketmqNamesrv" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqNamesrvAppender"/>
+    </logger>
+
+    <logger name="RocketmqCommon" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqNamesrvAppender"/>
+    </logger>
+
+    <logger name="RocketmqRemoting" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="RocketmqNamesrvAppender"/>
+    </logger>
+
+    <logger name="RocketmqNamesrvConsole" additivity="false">
+        <level value="INFO"/>
+        <appender-ref ref="STDOUT"/>
+    </logger>
+
+    <root>
+        <level value="INFO"/>
+        <appender-ref ref="DefaultAppender"/>
+    </root>
+</configuration>
diff --git a/rocketmq-ansible/roles/namesrv/templates/mqnamesrv.service b/rocketmq-ansible/roles/namesrv/templates/mqnamesrv.service
new file mode 100644
index 0000000..5e99171
--- /dev/null
+++ b/rocketmq-ansible/roles/namesrv/templates/mqnamesrv.service
@@ -0,0 +1,15 @@
+[Unit]

+Description=rocketmq namesrv service

+After=network.target

+

+[Service]

+Type=simple

+

+ExecStart=/bin/bash -c 'source /etc/profile && {{ rocketmq_deploy_path }}/rocketmq/bin/mqnamesrv'

+ExecStop=/bin/bash -c 'source /etc/profile && {{ rocketmq_deploy_path }}/rocketmq/bin/mqshutdown namesrv'

+RemainAfterExit=yes

+

+Restart=always

+RestartSec=5s

+[Install]

+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/rocketmq-ansible/roles/namesrv/vars/main.yml b/rocketmq-ansible/roles/namesrv/vars/main.yml
new file mode 100644
index 0000000..8338b81
--- /dev/null
+++ b/rocketmq-ansible/roles/namesrv/vars/main.yml
@@ -0,0 +1,4 @@
+# namesrv variable

+rocketmq_download_url: https://dlcdn.apache.org/rocketmq/4.9.3/rocketmq-all-4.9.3-bin-release.zip

+rocketmq_deploy_path: /app

+rocketmq_data_path: /data

diff --git a/rocketmq-ansible/vars/main.yml b/rocketmq-ansible/vars/main.yml
new file mode 100644
index 0000000..3049405
--- /dev/null
+++ b/rocketmq-ansible/vars/main.yml
@@ -0,0 +1,3 @@
+# The global variable

+rocketmq_deploy_path: /app

+rocketmq_data_path: /data
\ No newline at end of file