Merge pull request #879 from lwclover/master

[RIP-40]Apache Rocketmq Playbook
diff --git a/rocketmq-ansible/Rocketmq Ansible Playbook cn.md b/rocketmq-ansible/Rocketmq Ansible Playbook cn.md
new file mode 100644
index 0000000..3c43d1b
--- /dev/null
+++ b/rocketmq-ansible/Rocketmq Ansible Playbook cn.md
@@ -0,0 +1,133 @@
+Apache RocketMQ Playbook提供Apache RocketMQ集群部署和Apache RocketMQ Exporter部署功能。
+
+Apache RocketMQ Playbook集成了部署环境初始化、可运行包下载、os参数调优、broker最佳配置参数、Apache RocketMQ集群部署、Apache RocketMQ Exporter部署、Apache RocketMQ Exporter接入prometheus、添加开机自启动机制等任务编排到一起。
+
+Apache RocketMQ Playbook可以嵌入在CI/CD流程中或者编排到terraform流程中,这在自动化运维或者VDC一键部署(SDE)有非常重要的意义。
+
+## 使用说明
+## 先决条件
+
+安装Ansible。Ansible是一个自动化运维工具,可以进行配置管理和应用部署。实现了批量系统配置、批量程序部署、批量运行命令等功能。
+
+安装文档参考官网
+
+[https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html)
+
+## Playbook结构
+
+Apache RocketMQ Playbook入口文件为rocketmq.yml。rocketmq.yml包含namesrv.yml、broker.yml、exporter.yml 3个子playbook。
+rocketmq.yml可以单独执行部署一个完整的rocketmq集群或者3个子playbook单独执行。
+hosts文件配置了namesrv、broker、exporter部署的机器列表及变量,当使用terraform编排时hosts可以当做变量传递。
+
+rocketmq-ansible
+
+│
+
+│  broker.yml#部署broker
+
+│  exporter.yml#部署exporter
+
+│  hosts#部署机器列表及变量
+
+│  namesrv.yml#部署namesrv
+
+│  rocketmq.yml#playbook入口文件
+
+│  
+
+├─roles
+
+│  ├─broker
+
+│  │  ├─tasks
+
+│  │  │      main.yml   #部署broker流程
+
+│  │  │      
+
+│  │  ├─templates
+
+│  │  │      broker.conf.j2   #broker最佳配置模版
+
+│  │  │      logback_broker.xml.j2   #broker logback配置模版
+
+│  │  │      mqbroker.service    #broker开机自启动脚本模版
+
+│  │  │      
+
+│  │  └─vars
+
+│  │          main.yml   #broker.yml使用的变量
+
+│  │          
+
+│  ├─exporter
+
+│  │  ├─files
+
+│  │  │      mqexportershutdown.sh   #exporter停止脚本
+
+│  │  │      
+
+│  │  ├─tasks
+
+│  │  │      main.yml    #exporter部署流程
+
+│  │  │      
+
+│  │  ├─templates
+
+│  │  │      mqexporter.service   #exporter开机自动脚本模版
+
+│  │  │      mqexporter.sh.j2    #exporter启动脚本模版
+
+│  │  │      
+
+│  │  └─vars
+
+│  │          main.yml   #exporter.yml使用的变量
+
+│  │          
+
+│  └─namesrv
+
+│      ├─tasks
+
+│      │      main.yml   #namesrv部署流程
+
+│      │      
+
+│      ├─templates
+
+│      │      logback_namesrv.xml.j2   #namesrv logback配置模版
+
+│      │      mqnamesrv.service   #namesrv开机自启动脚本模版
+
+│      │      
+
+│      └─vars
+
+│              main.yml   #namesrv.yml使用的变量
+
+│              
+
+└─vars
+
+        main.yml   #rocketmq.yml使用的变量
+
+## Playbook执行
+
+ansible-playbook /path/rocketmq.yml -i /path/hosts
+
+## rocketmq.yml
+rocketmq.yml描述了使用linux root用户部署。在执行部署之前做一些环境初始化任务,创建应用文件目录和数据文件目录。
+
+## namesrv.yml
+namesrv.yml描述了部署namesrv的过程。包含了创建部署目录、下载可运行包、修改日志文件目录、添加开机自启动机制、启动进程等任务。
+
+## broker.yml
+broker.yml描述了部署broker的过程。包含了创建部署目录、下载可运行包、修改日志文件目录、优化os参数、优化broker配置、添加开机自启动机制、启动进程等任务。
+
+## exporter.yml
+exporter.yml描述了部署rocketmq exporter的过程。包含了创建部署目录、下载Apache RocketMQ Exporter可运行包、生成启动和停止脚本、添加开机自启动机制、启动进程等任务。
+
diff --git a/rocketmq-ansible/Rocketmq Ansible Playbook en.md b/rocketmq-ansible/Rocketmq Ansible Playbook en.md
new file mode 100644
index 0000000..dff4506
--- /dev/null
+++ b/rocketmq-ansible/Rocketmq Ansible Playbook en.md
@@ -0,0 +1,148 @@
+Apache RocketMQ Playbook provides the Apache RocketMQ cluster deployment and Apache RocketMQ Exporter deployment function.
+
+Apache RocketMQ Playbook integrates deployment environment initialization, runnable pack download, os parameter tuning, broker optimal configuration parameters, Apache RocketMQ cluster deployment, Apache RocketMQ Exporter deployment, Apache RocketMQ Exporter access to prometheus, and startup.
+
+The Apache RocketMQ Playbook can be embedded in CI/CD processes or choreographed into Terraform processes, making it important for automated operations or VDC one-click deployment (SDE).
+
+## instructions
+## prerequisite
+
+Install Ansible. 
+
+Ansible is an agentless automation tool for configuration management and application deployment. Realized batch system configuration, batch program deployment, batch running commands and other functions.
+
+Installation documents refer to the official website:
+
+[https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html)
+
+## Structure of playbook
+
+The Apache RocketMQ Playbook entry file is rocketmq.yml.
+
+Rocketmq.yml contains namesrv.yml, broker.yml, and exporter.
+
+Rocketmq.yml can be executed separately by deploying a full Apache RocketMQ cluster or three child Playbooks.
+
+The hosts file is configured with a list of machines and variables for Namesrv, Broker, and exporter deployment. 
+
+The hosts file can be used as a variable.
+
+
+rocketmq-ansible
+
+│
+
+│  broker.yml   #Deploy the broker
+
+│  exporter.yml   #Deploy the exporter
+
+│  hosts   #Deploy machine list and variables
+
+│  namesrv.yml   #Deploy the namesrv
+
+│  rocketmq.yml   #Playbook entry file
+
+│  
+
+├─roles
+
+│  ├─broker
+
+│  │  ├─tasks
+
+│  │  │      main.yml   #Deploy the Broker process
+
+│  │  │      
+
+│  │  ├─templates
+
+│  │  │      broker.conf.j2   #Broker best configuration template
+
+│  │  │      logback_broker.xml.j2   #Broker Logback configuration template
+
+│  │  │      mqbroker.service    #Self boot automatic script template
+
+│  │  │      
+
+│  │  └─vars
+
+│  │          main.yml   #The variable used by broker.yml
+
+│  │          
+
+│  ├─exporter
+
+│  │  ├─files
+
+│  │  │      mqexportershutdown.sh   #Exporter stop script
+
+│  │  │      
+
+│  │  ├─tasks
+
+│  │  │      main.yml    #Export Deployment Process
+
+│  │  │      
+
+│  │  ├─templates
+
+│  │  │      mqexporter.service   #Self boot automatic script template
+
+│  │  │      mqexporter.sh.j2    #Exporter startup script template
+
+│  │  │      
+
+│  │  └─vars
+
+│  │          main.yml   #A variable used by exporter.yml
+
+│  │          
+
+│  └─namesrv
+
+│      ├─tasks
+
+│      │      main.yml   #Namesrv deployment process
+
+│      │      
+
+│      ├─templates
+
+│      │      logback_namesrv.xml.j2   #Namesrv logback configuration template
+
+│      │      mqnamesrv.service   #Self boot automatic script template
+
+│      │      
+
+│      └─vars
+
+│              main.yml   #The variable used by namesrv.yml
+
+│              
+
+└─vars
+
+        main.yml   #The variable used by rocketmq.yml
+
+## Perform playbook
+
+ansible-playbook /path/rocketmq.yml -i /path/hosts
+
+## rocketmq.yml
+rocketmq.yml describes how to deploy as Linux root user, perform some deployment environment initialization tasks, and create application file directories and data file directories before executing three sub-Playbooks.
+
+## namesrv.yml
+namesrv.yml describes the process of deploying namesrv. 
+
+This includes creating a deployment directory, downloading Apache RocketMQ pack, modifying the log file directory, adding a startup mechanism, and starting processes.
+
+## broker.yml
+broker.yml describes the process of deploying the broker. 
+
+This includes creating a deployment directory, downloading Apache RocketMQ pack, modifying log file directories, optimizing os parameters, optimizing broker configuration, adding a startup mechanism, and starting processes.
+
+## exporter.yml
+exporter.yml describes the process of deploying Apache RocketMQ Exporter. 
+
+It contains tasks such as creating a deployment directory, downloading Apache RocketMQ Exporter pack, generating startup and stop scripts, adding a self-boot mechanism, and starting processes.
+
diff --git a/rocketmq-ansible/broker.yml b/rocketmq-ansible/broker.yml
new file mode 100644
index 0000000..8bd906d
--- /dev/null
+++ b/rocketmq-ansible/broker.yml
@@ -0,0 +1,19 @@
+# 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.

+

+# deploy Apache 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..6ad67d1
--- /dev/null
+++ b/rocketmq-ansible/exporter.yml
@@ -0,0 +1,19 @@
+# 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.

+

+# deploy Apache 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..bf11693
--- /dev/null
+++ b/rocketmq-ansible/hosts
@@ -0,0 +1,37 @@
+# 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.

+

+#hosts example, please change the value based on the actual situation

+#Apache Rocketmq namesrv

+[rocketmq_namesrv]

+127.0.0.1

+127.0.0.2

+

+#Apache Rocketmq broker 

+[rocketmq_broker]

+127.0.0.3 brokerName=broker-a brokerId=0 brokerRole=SYNC_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=/root/store

+

+#Apache 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..a698b4e
--- /dev/null
+++ b/rocketmq-ansible/namesrv.yml
@@ -0,0 +1,19 @@
+# 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.

+

+# deploy Apache 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..a189bb2
--- /dev/null
+++ b/rocketmq-ansible/rocketmq.yml
@@ -0,0 +1,40 @@
+# 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.

+

+# deploy Apache Rocketmq cluster

+- name: Apache 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 log path

+      file:

+        path: "{{ rocketmq_log_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..afcf546
--- /dev/null
+++ b/rocketmq-ansible/roles/broker/tasks/main.yml
@@ -0,0 +1,70 @@
+# 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.

+

+- name: check broker deploy directory

+  stat:

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

+  register: deploy_directory

+

+- debug:

+    msg: "{{ deploy_directory }}"

+

+- name: download Apache Rocketmq

+  unarchive:

+    src: "{{ rocketmq_download_url }}"

+    dest: "{{ rocketmq_deploy_path }}"

+    remote_src: yes

+    mode: 0750

+  when: deploy_directory.stat.exists == False

+

+- name: rename broker deploy directory

+  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: add broker boot mechanism

+  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..7e6f61f
--- /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_log_path }}/logs/rocketmqlogs/broker_default.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_log_path }}/logs/rocketmqlogs/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_log_path }}/logs/rocketmqlogs/broker.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_log_path }}/logs/rocketmqlogs/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_log_path }}/logs/rocketmqlogs/protection.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_log_path }}/logs/rocketmqlogs/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_log_path }}/logs/rocketmqlogs/watermark.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_log_path }}/logs/rocketmqlogs/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_log_path }}/logs/rocketmqlogs/store.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_log_path }}/logs/rocketmqlogs/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_log_path }}/logs/rocketmqlogs/remoting.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_log_path }}/logs/rocketmqlogs/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_log_path }}/logs/rocketmqlogs/storeerror.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_log_path }}/logs/rocketmqlogs/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_log_path }}/logs/rocketmqlogs/transaction.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_log_path }}/logs/rocketmqlogs/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_log_path }}/logs/rocketmqlogs/lock.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_log_path }}/logs/rocketmqlogs/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_log_path }}/logs/rocketmqlogs/filter.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_log_path }}/logs/rocketmqlogs/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_log_path }}/logs/rocketmqlogs/stats.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_log_path }}/logs/rocketmqlogs/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_log_path }}/logs/rocketmqlogs/commercial.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_log_path }}/logs/rocketmqlogs/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..e5e1a6d
--- /dev/null
+++ b/rocketmq-ansible/roles/broker/templates/mqbroker.service
@@ -0,0 +1,30 @@
+# 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.

+

+[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

diff --git a/rocketmq-ansible/roles/broker/vars/main.yml b/rocketmq-ansible/roles/broker/vars/main.yml
new file mode 100644
index 0000000..26d5bf0
--- /dev/null
+++ b/rocketmq-ansible/roles/broker/vars/main.yml
@@ -0,0 +1,19 @@
+# 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.

+

+# broker 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_log_path: ${user.home}
\ 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..c3b1e05
--- /dev/null
+++ b/rocketmq-ansible/roles/exporter/files/mqexportershutdown.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# 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.
+
+source /etc/profile
+pid=$(jps -lvVm | grep rocketmq-exporter | awk '{print $1}')
+
+if [ ! -z $pid ]; then
+  kill -9 $pid
+fi
diff --git a/rocketmq-ansible/roles/exporter/tasks/main.yml b/rocketmq-ansible/roles/exporter/tasks/main.yml
new file mode 100644
index 0000000..fbac2a9
--- /dev/null
+++ b/rocketmq-ansible/roles/exporter/tasks/main.yml
@@ -0,0 +1,60 @@
+# 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.

+

+- name: create exporter deploy directory

+  file:

+    path: "{{ rocketmq_exporter_deploy_directory }}"

+    state: directory

+    recurse: yes

+

+- name: download Apache Rocketmq exporter

+  get_url:

+    url: "{{ rocketmq_exporter_download_url }}"

+    dest: "{{ rocketmq_exporter_deploy_directory }}"

+    mode: 0750

+

+- name: copy exporter shutdown script

+  copy:

+    src: mqexportershutdown.sh

+    dest: "{{ rocketmq_exporter_deploy_directory }}"

+    mode: 0750

+

+- name: copy exporter start script

+  template:

+    src: mqexporter.sh.j2

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

+    mode: 0750

+

+- name: add exporter boot mechanism

+  template:

+    src: mqexporter.service

+    dest: /usr/lib/systemd/system

+    mode: 0750

+

+- name: check exporter status

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

+  register: status_result

+

+- debug:

+    msg: "{{ status_result }}"

+

+- name: start 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..dc436dd
--- /dev/null
+++ b/rocketmq-ansible/roles/exporter/templates/mqexporter.service
@@ -0,0 +1,30 @@
+# 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.
+
+[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
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..98e0ef9
--- /dev/null
+++ b/rocketmq-ansible/roles/exporter/templates/mqexporter.sh.j2
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# 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.
+
+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 &
diff --git a/rocketmq-ansible/roles/exporter/vars/main.yml b/rocketmq-ansible/roles/exporter/vars/main.yml
new file mode 100644
index 0000000..a1a78aa
--- /dev/null
+++ b/rocketmq-ansible/roles/exporter/vars/main.yml
@@ -0,0 +1,18 @@
+# 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.

+

+#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..ceff931
--- /dev/null
+++ b/rocketmq-ansible/roles/namesrv/tasks/main.yml
@@ -0,0 +1,60 @@
+# 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.

+

+- name: check namesrv deploy directory

+  stat:

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

+  register: deploy_directory

+

+- debug:

+    msg: "{{ deploy_directory }}"

+

+- name: download Apache Rocketmq

+  unarchive:

+    src: "{{ rocketmq_download_url }}"

+    dest: "{{ rocketmq_deploy_path }}"

+    remote_src: yes

+    mode: 0750

+  when: deploy_directory.stat.exists == False

+

+- name: rename namesrv deploy directory

+  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: add namesrv boot mechanism

+  template:

+    src: mqnamesrv.service

+    dest: /usr/lib/systemd/system

+    mode: 0750

+

+- name: check namesrv 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..868ad9e
--- /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_log_path }}/logs/rocketmqlogs/namesrv_default.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_log_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_log_path }}/logs/rocketmqlogs/namesrv.log</file>
+        <append>true</append>
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>{{ rocketmq_log_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..0c7c052
--- /dev/null
+++ b/rocketmq-ansible/roles/namesrv/templates/mqnamesrv.service
@@ -0,0 +1,30 @@
+# 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.

+

+[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

diff --git a/rocketmq-ansible/roles/namesrv/vars/main.yml b/rocketmq-ansible/roles/namesrv/vars/main.yml
new file mode 100644
index 0000000..4a0da29
--- /dev/null
+++ b/rocketmq-ansible/roles/namesrv/vars/main.yml
@@ -0,0 +1,19 @@
+# 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.

+

+# 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_log_path: ${user.home}

diff --git a/rocketmq-ansible/vars/main.yml b/rocketmq-ansible/vars/main.yml
new file mode 100644
index 0000000..86c4599
--- /dev/null
+++ b/rocketmq-ansible/vars/main.yml
@@ -0,0 +1,18 @@
+# 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.

+

+# The global variable

+rocketmq_deploy_path: /app

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