You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by gi...@apache.org on 2022/04/14 05:05:14 UTC

[dolphinscheduler-website] branch asf-site updated: Automated deployment: 1691d6f4d4257225b17b8177c4fdda06651a4b1c

This is an automated email from the ASF dual-hosted git repository.

github-bot pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler-website.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new b53b5181a Automated deployment: 1691d6f4d4257225b17b8177c4fdda06651a4b1c
b53b5181a is described below

commit b53b5181a595447a1769488f342fd97e33f3ecd2
Author: github-actions[bot] <gi...@users.noreply.github.com>
AuthorDate: Thu Apr 14 05:05:09 2022 +0000

    Automated deployment: 1691d6f4d4257225b17b8177c4fdda06651a4b1c
---
 en-us/community/join/review.html                   |   2 +
 en-us/community/join/review.json                   |   2 +-
 en-us/development/architecture-design.html         |  22 +-
 en-us/development/architecture-design.json         |   2 +-
 en-us/development/e2e-test.html                    |   8 +-
 en-us/development/e2e-test.json                    |   2 +-
 .../dev/user_doc/development/api-standard.html     | 124 -----
 .../dev/user_doc/development/api-standard.json     |   6 -
 .../user_doc/development/architecture-design.html  | 314 ------------
 .../user_doc/development/architecture-design.json  |   6 -
 .../backend/mechanism/global-parameter.html        |  84 ----
 .../backend/mechanism/global-parameter.json        |   6 -
 .../development/backend/mechanism/overview.html    |  44 --
 .../development/backend/mechanism/overview.json    |   6 -
 .../development/backend/mechanism/task/switch.html |  46 --
 .../development/backend/mechanism/task/switch.json |   6 -
 .../user_doc/development/backend/spi/alert.html    |  97 ----
 .../user_doc/development/backend/spi/alert.json    |   6 -
 .../development/backend/spi/datasource.html        |  57 ---
 .../development/backend/spi/datasource.json        |   6 -
 .../user_doc/development/backend/spi/registry.html |  56 ---
 .../user_doc/development/backend/spi/registry.json |   6 -
 .../dev/user_doc/development/backend/spi/task.html |  46 --
 .../dev/user_doc/development/backend/spi/task.json |   6 -
 .../development/development-environment-setup.html | 173 -------
 .../development/development-environment-setup.json |   6 -
 en-us/docs/dev/user_doc/development/e2e-test.html  | 190 --------
 en-us/docs/dev/user_doc/development/e2e-test.json  |   6 -
 .../user_doc/development/frontend-development.html | 538 ---------------------
 .../user_doc/development/frontend-development.json |   6 -
 .../dev/user_doc/development/have-questions.html   |  97 ----
 .../dev/user_doc/development/have-questions.json   |   6 -
 .../user_doc/guide/alert/enterprise-wechat.html    |  39 +-
 .../user_doc/guide/alert/enterprise-wechat.json    |   2 +-
 img/alert/enterprise-wechat-app-msg-md.png         | Bin 0 -> 54994 bytes
 img/alert/enterprise-wechat-app-msg.png            | Bin 0 -> 18009 bytes
 img/alert/enterprise-wechat-create-group.png       | Bin 0 -> 32570 bytes
 img/alert/enterprise-wechat-group-msg-md.png       | Bin 0 -> 52086 bytes
 img/alert/enterprise-wechat-group-msg.png          | Bin 0 -> 43359 bytes
 img/alert/enterprise-wechat-query-userid.png       | Bin 0 -> 18747 bytes
 img/alert/wechat-app-form-example.png              | Bin 0 -> 22056 bytes
 img/alert/wechat-group-form-example.png            | Bin 0 -> 23285 bytes
 img/architecture-design/dag_examples_ch_zn.png     | Bin 89203 -> 0 bytes
 img/architecture-design/dag_examples_en_us.png     | Bin 89184 -> 0 bytes
 img/architecture-design/distributed_lock_ch_zn.png | Bin 179233 -> 0 bytes
 img/architecture-design/distributed_lock_en_us.png | Bin 188964 -> 0 bytes
 .../distributed_lock_procss_ch_zn.png              | Bin 345394 -> 0 bytes
 .../distributed_lock_procss_en_us.png              | Bin 363294 -> 0 bytes
 img/architecture-design/fault-tolerant_ch_zn.png   | Bin 177202 -> 0 bytes
 img/architecture-design/fault-tolerant_en_us.png   | Bin 193511 -> 0 bytes
 .../fault-tolerant_master_ch_zn.png                | Bin 156134 -> 0 bytes
 .../fault-tolerant_master_en_us.png                | Bin 169131 -> 0 bytes
 .../fault-tolerant_worker_ch_zn.png                | Bin 156743 -> 0 bytes
 .../fault-tolerant_worker_en_us.png                | Bin 164622 -> 0 bytes
 img/architecture-design/grpc_en_us.png             | Bin 68933 -> 0 bytes
 img/architecture-design/lack_thread_ch_zn.png      | Bin 173229 -> 0 bytes
 img/architecture-design/lack_thread_en_us.png      | Bin 195509 -> 0 bytes
 img/architecture-design/process_priority_en_us.png | Bin 49112 -> 0 bytes
 img/architecture-design/task_priority_en_us.png    | Bin 30544 -> 0 bytes
 img/architecture-en.jpg                            | Bin 245445 -> 0 bytes
 img/tasks/demo/shell.jpg                           | Bin 632738 -> 436873 bytes
 img/tasks/demo/shell_custom_param.jpg              | Bin 556773 -> 404207 bytes
 zh-cn/community/join/review.html                   |   2 +
 zh-cn/community/join/review.json                   |   2 +-
 zh-cn/development/architecture-design.html         |  14 +-
 zh-cn/development/architecture-design.json         |   2 +-
 zh-cn/development/e2e-test.html                    |  10 +-
 zh-cn/development/e2e-test.json                    |   2 +-
 .../dev/user_doc/development/api-standard.html     | 123 -----
 .../dev/user_doc/development/api-standard.json     |   6 -
 .../user_doc/development/architecture-design.html  | 322 ------------
 .../user_doc/development/architecture-design.json  |   6 -
 .../backend/mechanism/global-parameter.html        |  83 ----
 .../backend/mechanism/global-parameter.json        |   6 -
 .../development/backend/mechanism/overview.html    |  44 --
 .../development/backend/mechanism/overview.json    |   6 -
 .../development/backend/mechanism/task/switch.html |  46 --
 .../development/backend/mechanism/task/switch.json |   6 -
 .../user_doc/development/backend/spi/alert.html    |  93 ----
 .../user_doc/development/backend/spi/alert.json    |   6 -
 .../development/backend/spi/datasource.html        |  53 --
 .../development/backend/spi/datasource.json        |   6 -
 .../user_doc/development/backend/spi/registry.html |  56 ---
 .../user_doc/development/backend/spi/registry.json |   6 -
 .../dev/user_doc/development/backend/spi/task.html |  46 --
 .../dev/user_doc/development/backend/spi/task.json |   6 -
 .../development/development-environment-setup.html | 168 -------
 .../development/development-environment-setup.json |   6 -
 zh-cn/docs/dev/user_doc/development/e2e-test.html  | 188 -------
 zh-cn/docs/dev/user_doc/development/e2e-test.json  |   6 -
 .../user_doc/development/frontend-development.html | 538 ---------------------
 .../user_doc/development/frontend-development.json |   6 -
 .../dev/user_doc/development/have-questions.html   |  98 ----
 .../dev/user_doc/development/have-questions.json   |   6 -
 .../user_doc/guide/alert/enterprise-wechat.html    |  37 +-
 .../user_doc/guide/alert/enterprise-wechat.json    |   2 +-
 96 files changed, 108 insertions(+), 3922 deletions(-)

diff --git a/en-us/community/join/review.html b/en-us/community/join/review.html
index 54b6c416e..93992531f 100644
--- a/en-us/community/join/review.html
+++ b/en-us/community/join/review.html
@@ -191,6 +191,7 @@ you can <code>@</code>  members to do that. But as long as you have a GitHub acc
 We encourage everyone in the community to comment and answer issues</p>
 </blockquote>
 <h3>Pull Requests</h3>
+<!-- markdown-link-check-disable -->
 <p>Review Pull mean discussing in <a href="https://github.com/apache/dolphinscheduler/pulls">Pull Requests</a> in GitHub and giving suggestions to it. DolphinScheduler's
 Pull Requests reviewing are the same as <a href="https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/about-pull-request-reviews">GitHub's reviewing changes in pull requests</a>. You can give your
 suggestions in Pull Requests</p>
@@ -202,6 +203,7 @@ in <a href="https://docs.github.com/en/pull-requests/collaborating-with-pull-req
 merged, please follow &quot;Request changes&quot; in <a href="https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/about-pull-request-reviews">GitHub's reviewing changes in pull requests</a> to ask contributors
 modify it.</li>
 </ul>
+<!-- markdown-link-check-enable -->
 <p>Labeled Pull Requests is an important part. Reasonable classification can save a lot of time for reviewers. The good news
 is that the label's name and usage of Pull Requests are the same in <a href="#issues">Issues</a>, which can reduce the memory. For
 example, if there is a Pull Request is related to docker and block deployment. We can label it with <a href="https://github.com/apache/dolphinscheduler/labels/docker">docker</a>
diff --git a/en-us/community/join/review.json b/en-us/community/join/review.json
index f96a3ba13..8aa0f428f 100644
--- a/en-us/community/join/review.json
+++ b/en-us/community/join/review.json
@@ -1,6 +1,6 @@
 {
   "filename": "review.md",
-  "__html": "<h1>Community Review</h1>\n<p>Beside submit Issues and pull requests to the GitHub repository mentioned in <a href=\"../team.md\">team</a>, another important way to\ncontribute to DolphinScheduler is reviewing GitHub Issues or Pull Requests. You can not only know the latest new and\ndirection of the community, but also understand the good design in others during you reviewing. At the same time, you can\nincrease your exposure in the community and accumulate your honor.</p>\n [...]
+  "__html": "<h1>Community Review</h1>\n<p>Beside submit Issues and pull requests to the GitHub repository mentioned in <a href=\"../team.md\">team</a>, another important way to\ncontribute to DolphinScheduler is reviewing GitHub Issues or Pull Requests. You can not only know the latest new and\ndirection of the community, but also understand the good design in others during you reviewing. At the same time, you can\nincrease your exposure in the community and accumulate your honor.</p>\n [...]
   "link": "/dist/en-us/community/join/review.html",
   "meta": {}
 }
\ No newline at end of file
diff --git a/en-us/development/architecture-design.html b/en-us/development/architecture-design.html
index 233653b71..c114e0658 100644
--- a/en-us/development/architecture-design.html
+++ b/en-us/development/architecture-design.html
@@ -15,7 +15,7 @@
 <h3>1.Noun Interpretation</h3>
 <p><strong>DAG:</strong> Full name Directed Acyclic Graph,referred to as DAG。Tasks in the workflow are assembled in the form of directed acyclic graphs, which are topologically traversed from nodes with zero indegrees of ingress until there are no successor nodes. For example, the following picture:</p>
 <p align="center">
-  <img src="/img/architecture-design/dag_examples_en_us.png" alt="dag示例"  width="80%" />
+  <img src="/img/architecture-design/dag_examples.png" alt="dag示例"  width="80%" />
   <p align="center">
         <em>dag example</em>
   </p>
@@ -34,7 +34,7 @@
 <h3>2.System architecture</h3>
 <h4>2.1 System Architecture Diagram</h4>
 <p align="center">
-  <img src="/img/architecture-en.jpg" alt="System Architecture Diagram"  />
+  <img src="/img/architecture.jpg" alt="System Architecture Diagram"  />
   <p align="center">
         <em>System Architecture Diagram</em>
   </p>
@@ -136,13 +136,13 @@ Interfaces include workflow creation, definition, query, modification, release,
 <li>The core process algorithm for obtaining distributed locks is as follows</li>
 </ol>
  <p align="center">
-   <img src="/img/architecture-design/distributed_lock_en_us.png" alt="Get Distributed Lock Process" width="70%" />
+   <img src="/img/architecture-design/distributed_lock.png" alt="Get Distributed Lock Process" width="70%" />
  </p>
 <ol start="2">
 <li>Scheduler thread distributed lock implementation flow chart in DolphinScheduler:</li>
 </ol>
  <p align="center">
-   <img src="/img/architecture-design/distributed_lock_procss_en_us.png" alt="Get Distributed Lock Process" />
+   <img src="/img/architecture-design/distributed_lock_procss.png" alt="Get Distributed Lock Process" />
  </p>
 <h5>Third, the thread is insufficient loop waiting problem</h5>
 <ul>
@@ -150,7 +150,7 @@ Interfaces include workflow creation, definition, query, modification, release,
 <li>If a large number of sub-processes are nested in a large DAG, the following figure will result in a &quot;dead&quot; state:</li>
 </ul>
  <p align="center">
-   <img src="/img/architecture-design/lack_thread_en_us.png" alt="Thread is not enough to wait for loop" width="70%" />
+   <img src="/img/architecture-design/lack_thread.png" alt="Thread is not enough to wait for loop" width="70%" />
  </p>
 <p>In the above figure, MainFlowThread waits for SubFlowThread1 to end, SubFlowThread1 waits for SubFlowThread2 to end, SubFlowThread2 waits for SubFlowThread3 to end, and SubFlowThread3 waits for a new thread in the thread pool, then the entire DAG process cannot end, and thus the thread cannot be released. This forms the state of the child parent process loop waiting. At this point, the scheduling cluster will no longer be available unless a new Master is started to add threads to brea [...]
 <p>It seems a bit unsatisfactory to start a new Master to break the deadlock, so we proposed the following three options to reduce this risk:</p>
@@ -166,21 +166,21 @@ Interfaces include workflow creation, definition, query, modification, release,
 <h6>1. Downtime fault tolerance</h6>
 <p>Service fault tolerance design relies on ZooKeeper's Watcher mechanism. The implementation principle is as follows:</p>
  <p align="center">
-   <img src="/img/architecture-design/fault-tolerant_en_us.png" alt="DolphinScheduler Fault Tolerant Design" width="70%" />
+   <img src="/img/architecture-design/fault-tolerant.png" alt="DolphinScheduler Fault Tolerant Design" width="70%" />
  </p>
 <p>The Master monitors the directories of other Masters and Workers. If the remove event is detected, the process instance is fault-tolerant or the task instance is fault-tolerant according to the specific business logic.</p>
 <ul>
 <li>Master fault tolerance flow chart:</li>
 </ul>
  <p align="center">
-   <img src="/img/architecture-design/fault-tolerant_master_en_us.png" alt="Master Fault Tolerance Flowchart" width="70%" />
+   <img src="/img/architecture-design/fault-tolerant_master.png" alt="Master Fault Tolerance Flowchart" width="70%" />
  </p>
 <p>After the ZooKeeper Master is fault-tolerant, it is rescheduled by the Scheduler thread in DolphinScheduler. It traverses the DAG to find the &quot;Running&quot; and &quot;Submit Successful&quot; tasks, and monitors the status of its task instance for the &quot;Running&quot; task. You need to determine whether the Task Queue already exists. If it exists, monitor the status of the task instance. If it does not exist, resubmit the task instance.</p>
 <ul>
 <li>Worker fault tolerance flow chart:</li>
 </ul>
  <p align="center">
-   <img src="/img/architecture-design/fault-tolerant_worker_en_us.png" alt="Worker Fault Tolerance Flowchart" width="70%" />
+   <img src="/img/architecture-design/fault-tolerant_worker.png" alt="Worker Fault Tolerance Flowchart" width="70%" />
  </p>
 <p>Once the Master Scheduler thread finds the task instance as &quot;need to be fault tolerant&quot;, it takes over the task and resubmits.</p>
 <p>Note: Because the &quot;network jitter&quot; may cause the node to lose the heartbeat of ZooKeeper in a short time, the node's remove event occurs. In this case, we use the easiest way, that is, once the node has timeout connection with ZooKeeper, it will directly stop the Master or Worker service.</p>
@@ -210,13 +210,13 @@ Interfaces include workflow creation, definition, query, modification, release,
 <li>
 <p>The priority of the process definition is that some processes need to be processed before other processes. This can be configured at the start of the process or at the time of scheduled start. There are 5 levels, followed by HIGHEST, HIGH, MEDIUM, LOW, and LOWEST. As shown below</p>
 <p align="center">
-   <img src="/img/architecture-design/process_priority_en_us.png" alt="Process Priority Configuration" width="40%" />
+   <img src="/img/architecture-design/process_priority.png" alt="Process Priority Configuration" width="40%" />
  </p>
 </li>
 <li>
 <p>The priority of the task is also divided into 5 levels, followed by HIGHEST, HIGH, MEDIUM, LOW, and LOWEST. As shown below</p>
 <p align="center">`
-   <img src="/img/architecture-design/task_priority_en_us.png" alt="task priority configuration" width="35%" />
+   <img src="/img/architecture-design/task_priority.png" alt="task priority configuration" width="35%" />
  </p>
 </li>
 </ul>
@@ -235,7 +235,7 @@ Interfaces include workflow creation, definition, query, modification, release,
 <li>Considering the lightweightness of DolphinScheduler as much as possible, gRPC was chosen to implement remote access log information.</li>
 </ul>
  <p align="center">
-   <img src="/img/architecture-design/grpc_en_us.png" alt="grpc remote access" width="50%" />
+   <img src="/img/architecture-design/grpc.png" alt="grpc remote access" width="50%" />
  </p>
 <ul>
 <li>We use a custom Logback FileAppender and Filter function to generate a log file for each task instance.</li>
diff --git a/en-us/development/architecture-design.json b/en-us/development/architecture-design.json
index 034348430..6f27fe0af 100644
--- a/en-us/development/architecture-design.json
+++ b/en-us/development/architecture-design.json
@@ -1,6 +1,6 @@
 {
   "filename": "architecture-design.md",
-  "__html": "<h2>Architecture Design</h2>\n<p>Before explaining the architecture of the schedule system, let us first understand the common nouns of the schedule system.</p>\n<h3>1.Noun Interpretation</h3>\n<p><strong>DAG:</strong> Full name Directed Acyclic Graph,referred to as DAG。Tasks in the workflow are assembled in the form of directed acyclic graphs, which are topologically traversed from nodes with zero indegrees of ingress until there are no successor nodes. For example, the fol [...]
+  "__html": "<h2>Architecture Design</h2>\n<p>Before explaining the architecture of the schedule system, let us first understand the common nouns of the schedule system.</p>\n<h3>1.Noun Interpretation</h3>\n<p><strong>DAG:</strong> Full name Directed Acyclic Graph,referred to as DAG。Tasks in the workflow are assembled in the form of directed acyclic graphs, which are topologically traversed from nodes with zero indegrees of ingress until there are no successor nodes. For example, the fol [...]
   "link": "/dist/en-us/development/architecture-design.html",
   "meta": {}
 }
\ No newline at end of file
diff --git a/en-us/development/e2e-test.html b/en-us/development/e2e-test.html
index 523190d85..3df95dcd7 100644
--- a/en-us/development/e2e-test.html
+++ b/en-us/development/e2e-test.html
@@ -124,7 +124,7 @@
 </code></pre>
 <h3>E2E-Cases</h3>
 <p>Current E2E test cases supported include: File Management, Project Management, Queue Management, Tenant Management, User Management, Worker Group Management and Workflow Test.</p>
-<p><img src="../../img/e2e-test/E2E_Cases.png" alt="E2E_Cases"></p>
+<p><img src="/img/e2e-test/E2E_Cases.png" alt="E2E_Cases"></p>
 <p>The following is an example of a tenant management test. As explained earlier, we use docker-compose for deployment, so for each test case, we need to import the corresponding file in the form of an annotation.</p>
 <p>The browser is loaded using the RemoteWebDriver provided with Selenium. Before each test case is started there is some preparation work that needs to be done. For example: logging in the user, jumping to the corresponding page (depending on the specific test case).</p>
 <pre><code class="language-java">    <span class="hljs-meta">@BeforeAll</span>
@@ -157,11 +157,11 @@
 <p>When running E2E tests locally, the <code>-Dlocal=true</code> parameter can be configured to connect locally and facilitate changes to the UI.</p>
 <p>When running E2E tests with <code>M1</code> chip, you can use <code>-Dm1_chip=true</code> parameter to configure containers supported by
 <code>ARM64</code>.</p>
-<p><img src="../../img/e2e-test/Dlocal.png" alt="Dlocal"></p>
+<p><img src="/img/e2e-test/Dlocal.png" alt="Dlocal"></p>
 <p>If a connection timeout occurs during a local run, increase the load time to a recommended 30 and above.</p>
-<p><img src="../../img/e2e-test/timeout.png" alt="timeout"></p>
+<p><img src="/img/e2e-test/timeout.png" alt="timeout"></p>
 <p>The test run will be available as an MP4 file.</p>
-<p><img src="../../img/e2e-test/MP4.png" alt="MP4"></p>
+<p><img src="/img/e2e-test/MP4.png" alt="MP4"></p>
 </div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
   <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
   <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
diff --git a/en-us/development/e2e-test.json b/en-us/development/e2e-test.json
index 8adfdd15d..a63a91760 100644
--- a/en-us/development/e2e-test.json
+++ b/en-us/development/e2e-test.json
@@ -1,6 +1,6 @@
 {
   "filename": "e2e-test.md",
-  "__html": "<h1>DolphinScheduler E2E Automation Test</h1>\n<h2>I. Preparatory knowledge</h2>\n<h3>1. The difference between E2E Test and Unit Test</h3>\n<p>E2E, which stands for &quot;End to End&quot;, can be translated as &quot;end-to-end&quot; testing. It imitates the user, starting from a certain entry point and progressively performing actions until a certain job is completed. And unit tests are different, the latter usually requires testing parameters, types and parameter values, t [...]
+  "__html": "<h1>DolphinScheduler E2E Automation Test</h1>\n<h2>I. Preparatory knowledge</h2>\n<h3>1. The difference between E2E Test and Unit Test</h3>\n<p>E2E, which stands for &quot;End to End&quot;, can be translated as &quot;end-to-end&quot; testing. It imitates the user, starting from a certain entry point and progressively performing actions until a certain job is completed. And unit tests are different, the latter usually requires testing parameters, types and parameter values, t [...]
   "link": "/dist/en-us/development/e2e-test.html",
   "meta": {}
 }
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/api-standard.html b/en-us/docs/dev/user_doc/development/api-standard.html
deleted file mode 100644
index 8baecae55..000000000
--- a/en-us/docs/dev/user_doc/development/api-standard.html
+++ /dev/null
@@ -1,124 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="api-standard">
-  <meta name="description" content="api-standard">
-  <title>api-standard</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 Have queries regarding Apache DolphinScheduler, Join Slack channel to disscuss them <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span> [...]
-<p>A standardized and unified API is the cornerstone of project design.The API of DolphinScheduler follows the REST ful standard. REST ful is currently the most popular Internet software architecture. It has a clear structure, conforms to standards, is easy to understand and extend.</p>
-<p>This article uses the DolphinScheduler API as an example to explain how to construct a Restful API.</p>
-<h2>1. URI design</h2>
-<p>REST is &quot;Representational State Transfer&quot;.The design of Restful URI is based on resources.The resource corresponds to an entity on the network, for example: a piece of text, a picture, and a service. And each resource corresponds to a URI.</p>
-<ul>
-<li>One Kind of Resource: expressed in the plural, such as <code>task-instances</code>、<code>groups</code> ;</li>
-<li>A Resource: expressed in the singular, or use the ID to represent the corresponding resource, such as <code>group</code>、<code>groups/{groupId}</code>;</li>
-<li>Sub Resources: Resources under a certain resource, such as <code>/instances/{instanceId}/tasks</code>;</li>
-<li>A Sub Resource:<code>/instances/{instanceId}/tasks/{taskId}</code>;</li>
-</ul>
-<h2>2. Method design</h2>
-<p>We need to locate a certain resource by URI, and then use Method or declare actions in the path suffix to reflect the operation of the resource.</p>
-<h3>① Query - GET</h3>
-<p>Use URI to locate the resource, and use GET to indicate query.</p>
-<ul>
-<li>When the URI is a type of resource, it means to query a type of resource. For example, the following example indicates paging query <code>alter-groups</code>.</li>
-</ul>
-<pre><code>Method: GET
-/api/dolphinscheduler/alert-groups
-</code></pre>
-<ul>
-<li>When the URI is a single resource, it means to query this resource. For example, the following example means to query the specified <code>alter-group</code>.</li>
-</ul>
-<pre><code>Method: GET
-/api/dolphinscheduler/alter-groups/{id}
-</code></pre>
-<ul>
-<li>In addition, we can also express query sub-resources based on URI, as follows:</li>
-</ul>
-<pre><code>Method: GET
-/api/dolphinscheduler/projects/{projectId}/tasks
-</code></pre>
-<p><strong>The above examples all represent paging query. If we need to query all data, we need to add <code>/list</code> after the URI to distinguish. Do not mix the same API for both paged query and query.</strong></p>
-<pre><code>Method: GET
-/api/dolphinscheduler/alert-groups/list
-</code></pre>
-<h3>② Create - POST</h3>
-<p>Use URI to locate the resource, use POST to indicate create, and then return the created id to requester.</p>
-<ul>
-<li>create an <code>alter-group</code>:</li>
-</ul>
-<pre><code>Method: POST
-/api/dolphinscheduler/alter-groups
-</code></pre>
-<ul>
-<li>create sub-resources is also the same as above.</li>
-</ul>
-<pre><code>Method: POST
-/api/dolphinscheduler/alter-groups/{alterGroupId}/tasks
-</code></pre>
-<h3>③ Modify - PUT</h3>
-<p>Use URI to locate the resource, use PUT to indicate modify.</p>
-<ul>
-<li>modify an <code>alert-group</code></li>
-</ul>
-<pre><code>Method: PUT
-/api/dolphinscheduler/alter-groups/{alterGroupId}
-</code></pre>
-<h3>④ Delete -DELETE</h3>
-<p>Use URI to locate the resource, use DELETE to indicate delete.</p>
-<ul>
-<li>delete an <code>alert-group</code></li>
-</ul>
-<pre><code>Method: DELETE
-/api/dolphinscheduler/alter-groups/{alterGroupId}
-</code></pre>
-<ul>
-<li>batch deletion: batch delete the id array,we should use POST. <strong>(Do not use the DELETE method, because the body of the DELETE request has no semantic meaning, and it is possible that some gateways, proxies, and firewalls will directly strip off the request body after receiving the DELETE request.)</strong></li>
-</ul>
-<pre><code>Method: POST
-/api/dolphinscheduler/alter-groups/batch-delete
-</code></pre>
-<h3>⑤ Others</h3>
-<p>In addition to creating, deleting, modifying and quering, we also locate the corresponding resource through url, and then append operations to it after the path, such as:</p>
-<pre><code>/api/dolphinscheduler/alert-groups/verify-name
-/api/dolphinscheduler/projects/{projectCode}/process-instances/{code}/view-gantt
-</code></pre>
-<h2>3. Parameter design</h2>
-<p>There are two types of parameters, one is request parameter and the other is path parameter. And the parameter must use small hump.</p>
-<p>In the case of paging, if the parameter entered by the user is less than 1, the front end needs to automatically turn to 1, indicating that the first page is requested; When the backend finds that the parameter entered by the user is greater than the total number of pages, it should directly return to the last page.</p>
-<h2>4. Others design</h2>
-<h3>base URL</h3>
-<p>The URI of the project needs to use <code>/api/&lt;project_name&gt;</code> as the base path, so as to identify that these APIs are under this project.</p>
-<pre><code>/api/dolphinscheduler
-</code></pre>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/api-standard.json b/en-us/docs/dev/user_doc/development/api-standard.json
deleted file mode 100644
index e47b6e7ea..000000000
--- a/en-us/docs/dev/user_doc/development/api-standard.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "api-standard.md",
-  "__html": "<h1>API design standard</h1>\n<p>A standardized and unified API is the cornerstone of project design.The API of DolphinScheduler follows the REST ful standard. REST ful is currently the most popular Internet software architecture. It has a clear structure, conforms to standards, is easy to understand and extend.</p>\n<p>This article uses the DolphinScheduler API as an example to explain how to construct a Restful API.</p>\n<h2>1. URI design</h2>\n<p>REST is &quot;Representat [...]
-  "link": "/dist/en-us/docs/dev/user_doc/development/api-standard.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/architecture-design.html b/en-us/docs/dev/user_doc/development/architecture-design.html
deleted file mode 100644
index 2d587abe6..000000000
--- a/en-us/docs/dev/user_doc/development/architecture-design.html
+++ /dev/null
@@ -1,314 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="architecture-design">
-  <meta name="description" content="architecture-design">
-  <title>architecture-design</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 Have queries regarding Apache DolphinScheduler, Join Slack channel to disscuss them <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span> [...]
-<p>Before explaining the architecture of the schedule system, let us first understand the common nouns of the schedule system.</p>
-<h3>1.Noun Interpretation</h3>
-<p><strong>DAG:</strong> Full name Directed Acyclic Graph,referred to as DAG。Tasks in the workflow are assembled in the form of directed acyclic graphs, which are topologically traversed from nodes with zero indegrees of ingress until there are no successor nodes. For example, the following picture:</p>
-<p align="center">
-  <img src="/img/architecture-design/dag_examples.png" alt="dag示例"  width="80%" />
-  <p align="center">
-        <em>dag example</em>
-  </p>
-</p>
-<p><strong>Process definition</strong>: Visualization <strong>DAG</strong> by dragging task nodes and establishing associations of task nodes</p>
-<p><strong>Process instance</strong>: A process instance is an instantiation of a process definition, which can be generated by manual startup or  scheduling. The process definition runs once, a new process instance is generated</p>
-<p><strong>Task instance</strong>: A task instance is the instantiation of a specific task node when a process instance runs, which indicates the specific task execution status</p>
-<p><strong>Task type</strong>: Currently supports SHELL, SQL, SUB_PROCESS (sub-process), PROCEDURE, MR, SPARK, PYTHON, DEPENDENT (dependency), and plans to support dynamic plug-in extension, note: the sub-<strong>SUB_PROCESS</strong> is also A separate process definition that can be launched separately</p>
-<p><strong>Schedule mode</strong> :  The system supports timing schedule and manual schedule based on cron expressions. Command type support: start workflow, start execution from current node, resume fault-tolerant workflow, resume pause process, start execution from failed node, complement, timer, rerun, pause, stop, resume waiting thread. Where <strong>recovers the fault-tolerant workflow</strong> and <strong>restores the waiting thread</strong> The two command types are used by the sc [...]
-<p><strong>Timed schedule</strong>: The system uses <strong>quartz</strong> distributed scheduler and supports the generation of cron expression visualization</p>
-<p><strong>Dependency</strong>: The system does not only support <strong>DAG</strong> Simple dependencies between predecessors and successor nodes, but also provides <strong>task dependencies</strong> nodes, support for <strong>custom task dependencies between processes</strong></p>
-<p><strong>Priority</strong>: Supports the priority of process instances and task instances. If the process instance and task instance priority are not set, the default is first in, first out.</p>
-<p><strong>Mail Alert</strong>: Support <strong>SQL Task</strong> Query Result Email Send, Process Instance Run Result Email Alert and Fault Tolerant Alert Notification</p>
-<p><strong>Failure policy</strong>: For tasks running in parallel, if there are tasks that fail, two failure policy processing methods are provided. <strong>Continue</strong> means that the status of the task is run in parallel until the end of the process failure. <strong>End</strong> means that once a failed task is found, Kill also drops the running parallel task and the process ends.</p>
-<p><strong>Complement</strong>: Complement historical data, support <strong>interval parallel and serial</strong> two complement methods</p>
-<h3>2.System architecture</h3>
-<h4>2.1 System Architecture Diagram</h4>
-<p align="center">
-  <img src="/img/architecture.jpg" alt="System Architecture Diagram"  />
-  <p align="center">
-        <em>System Architecture Diagram</em>
-  </p>
-</p>
-<h4>2.2 Architectural description</h4>
-<ul>
-<li>
-<p><strong>MasterServer</strong></p>
-<p>MasterServer adopts the distributed non-central design concept. MasterServer is mainly responsible for DAG task split, task submission monitoring, and monitoring the health status of other MasterServer and WorkerServer.
-When the MasterServer service starts, it registers a temporary node with Zookeeper, and listens to the Zookeeper temporary node state change for fault tolerance processing.</p>
-<h5>The service mainly contains:</h5>
-<ul>
-<li>
-<p><strong>Distributed Quartz</strong> distributed scheduling component, mainly responsible for the start and stop operation of the scheduled task. When the quartz picks up the task, the master internally has a thread pool to be responsible for the subsequent operations of the task.</p>
-</li>
-<li>
-<p><strong>MasterSchedulerThread</strong> is a scan thread that periodically scans the <strong>command</strong> table in the database for different business operations based on different <strong>command types</strong></p>
-</li>
-<li>
-<p><strong>MasterExecThread</strong> is mainly responsible for DAG task segmentation, task submission monitoring, logic processing of various command types</p>
-</li>
-<li>
-<p><strong>MasterTaskExecThread</strong> is mainly responsible for task persistence</p>
-</li>
-</ul>
-</li>
-<li>
-<p><strong>WorkerServer</strong></p>
-<ul>
-<li>
-<p>WorkerServer also adopts a distributed, non-central design concept. WorkerServer is mainly responsible for task execution and providing log services. When the WorkerServer service starts, it registers the temporary node with Zookeeper and maintains the heartbeat.</p>
-<h5>This service contains:</h5>
-<ul>
-<li><strong>FetchTaskThread</strong> is mainly responsible for continuously receiving tasks from <strong>Task Queue</strong> and calling <strong>TaskScheduleThread</strong> corresponding executors according to different task types.</li>
-</ul>
-</li>
-<li>
-<p><strong>ZooKeeper</strong></p>
-<p>The ZooKeeper service, the MasterServer and the WorkerServer nodes in the system all use the ZooKeeper for cluster management and fault tolerance. In addition, the system also performs event monitoring and distributed locking based on ZooKeeper.
-We have also implemented queues based on Redis, but we hope that DolphinScheduler relies on as few components as possible, so we finally removed the Redis implementation.</p>
-</li>
-<li>
-<p><strong>Task Queue</strong></p>
-<p>The task queue operation is provided. Currently, the queue is also implemented based on Zookeeper. Since there is less information stored in the queue, there is no need to worry about too much data in the queue. In fact, we have over-measured a million-level data storage queue, which has no effect on system stability and performance.</p>
-</li>
-<li>
-<p><strong>Alert</strong></p>
-<p>Provides alarm-related interfaces. The interfaces mainly include <strong>Alarms</strong>. The storage, query, and notification functions of the two types of alarm data. The notification function has two types: <strong>mail notification</strong> and <strong>SNMP (not yet implemented)</strong>.</p>
-</li>
-<li>
-<p><strong>API</strong></p>
-<p>The API interface layer is mainly responsible for processing requests from the front-end UI layer. The service provides a RESTful api to provide request services externally.
-Interfaces include workflow creation, definition, query, modification, release, offline, manual start, stop, pause, resume, start execution from this node, and more.</p>
-</li>
-<li>
-<p><strong>UI</strong></p>
-<p>The front-end page of the system provides various visual operation interfaces of the system. For details, see the <a href="https://dolphinscheduler.apache.org/en-us/docs/latest/user_doc/guide/quick-start.html">quick start</a> section.</p>
-</li>
-</ul>
-</li>
-</ul>
-<h4>2.3 Architectural Design Ideas</h4>
-<h5>I. Decentralized vs centralization</h5>
-<h6>Centralization Thought</h6>
-<p>The centralized design concept is relatively simple. The nodes in the distributed cluster are divided into two roles according to their roles:</p>
-<p align="center">
-   <img src="https://analysys.github.io/easyscheduler_docs_cn/images/master_slave.png" alt="master-slave role" width="50%" />
- </p>
-<ul>
-<li>The role of Master is mainly responsible for task distribution and supervising the health status of Slave. It can dynamically balance the task to Slave, so that the Slave node will not be &quot;busy&quot; or &quot;free&quot;.</li>
-<li>The role of the Worker is mainly responsible for the execution of the task and maintains the heartbeat with the Master so that the Master can assign tasks to the Slave.</li>
-</ul>
-<p>Problems in the design of centralized :</p>
-<ul>
-<li>Once the Master has a problem, the group has no leader and the entire cluster will crash. In order to solve this problem, most Master/Slave architecture modes adopt the design scheme of the master and backup masters, which can be hot standby or cold standby, automatic switching or manual switching, and more and more new systems are available. Automatically elects the ability to switch masters to improve system availability.</li>
-<li>Another problem is that if the Scheduler is on the Master, although it can support different tasks in one DAG running on different machines, it will generate overload of the Master. If the Scheduler is on the Slave, all tasks in a DAG can only be submitted on one machine. If there are more parallel tasks, the pressure on the Slave may be larger.</li>
-</ul>
-<h6>Decentralization</h6>
- <p align="center"
-   <img src="https://analysys.github.io/easyscheduler_docs_cn/images/decentralization.png" alt="decentralized" width="50%" />
- </p>
-<ul>
-<li>
-<p>In the decentralized design, there is usually no Master/Slave concept, all roles are the same, the status is equal, the global Internet is a typical decentralized distributed system, networked arbitrary node equipment down machine , all will only affect a small range of features.</p>
-</li>
-<li>
-<p>The core design of decentralized design is that there is no &quot;manager&quot; that is different from other nodes in the entire distributed system, so there is no single point of failure problem. However, since there is no &quot;manager&quot; node, each node needs to communicate with other nodes to get the necessary machine information, and the unreliable line of distributed system communication greatly increases the difficulty of implementing the above functions.</p>
-</li>
-<li>
-<p>In fact, truly decentralized distributed systems are rare. Instead, dynamic centralized distributed systems are constantly emerging. Under this architecture, the managers in the cluster are dynamically selected, rather than preset, and when the cluster fails, the nodes of the cluster will spontaneously hold &quot;meetings&quot; to elect new &quot;managers&quot;. Go to preside over the work. The most typical case is the Etcd implemented in ZooKeeper and Go.</p>
-</li>
-<li>
-<p>Decentralization of DolphinScheduler is the registration of Master/Worker to ZooKeeper. The Master Cluster and the Worker Cluster are not centered, and the Zookeeper distributed lock is used to elect one Master or Worker as the “manager” to perform the task.</p>
-</li>
-</ul>
-<h5>二、Distributed lock practice</h5>
-<p>DolphinScheduler uses ZooKeeper distributed locks to implement only one Master to execute the Scheduler at the same time, or only one Worker to perform task submission.</p>
-<ol>
-<li>The core process algorithm for obtaining distributed locks is as follows</li>
-</ol>
- <p align="center">
-   <img src="/img/architecture-design/distributed_lock.png" alt="Get Distributed Lock Process" width="70%" />
- </p>
-<ol start="2">
-<li>Scheduler thread distributed lock implementation flow chart in DolphinScheduler:</li>
-</ol>
- <p align="center">
-   <img src="/img/architecture-design/distributed_lock_procss.png" alt="Get Distributed Lock Process" />
- </p>
-<h5>Third, the thread is insufficient loop waiting problem</h5>
-<ul>
-<li>If there is no subprocess in a DAG, if the number of data in the Command is greater than the threshold set by the thread pool, the direct process waits or fails.</li>
-<li>If a large number of sub-processes are nested in a large DAG, the following figure will result in a &quot;dead&quot; state:</li>
-</ul>
- <p align="center">
-   <img src="/img/architecture-design/lack_thread.png" alt="Thread is not enough to wait for loop" width="70%" />
- </p>
-<p>In the above figure, MainFlowThread waits for SubFlowThread1 to end, SubFlowThread1 waits for SubFlowThread2 to end, SubFlowThread2 waits for SubFlowThread3 to end, and SubFlowThread3 waits for a new thread in the thread pool, then the entire DAG process cannot end, and thus the thread cannot be released. This forms the state of the child parent process loop waiting. At this point, the scheduling cluster will no longer be available unless a new Master is started to add threads to brea [...]
-<p>It seems a bit unsatisfactory to start a new Master to break the deadlock, so we proposed the following three options to reduce this risk:</p>
-<ol>
-<li>Calculate the sum of the threads of all Masters, and then calculate the number of threads required for each DAG, that is, pre-calculate before the DAG process is executed. Because it is a multi-master thread pool, the total number of threads is unlikely to be obtained in real time.</li>
-<li>Judge the single master thread pool. If the thread pool is full, let the thread fail directly.</li>
-<li>Add a Command type with insufficient resources. If the thread pool is insufficient, the main process will be suspended. This way, the thread pool has a new thread, which can make the process with insufficient resources hang up and wake up again.</li>
-</ol>
-<p>Note: The Master Scheduler thread is FIFO-enabled when it gets the Command.</p>
-<p>So we chose the third way to solve the problem of insufficient threads.</p>
-<h5>IV. Fault Tolerant Design</h5>
-<p>Fault tolerance is divided into service fault tolerance and task retry. Service fault tolerance is divided into two types: Master Fault Tolerance and Worker Fault Tolerance.</p>
-<h6>1. Downtime fault tolerance</h6>
-<p>Service fault tolerance design relies on ZooKeeper's Watcher mechanism. The implementation principle is as follows:</p>
- <p align="center">
-   <img src="/img/architecture-design/fault-tolerant.png" alt="DolphinScheduler Fault Tolerant Design" width="70%" />
- </p>
-<p>The Master monitors the directories of other Masters and Workers. If the remove event is detected, the process instance is fault-tolerant or the task instance is fault-tolerant according to the specific business logic.</p>
-<ul>
-<li>Master fault tolerance flow chart:</li>
-</ul>
- <p align="center">
-   <img src="/img/architecture-design/fault-tolerant_master.png" alt="Master Fault Tolerance Flowchart" width="70%" />
- </p>
-<p>After the ZooKeeper Master is fault-tolerant, it is rescheduled by the Scheduler thread in DolphinScheduler. It traverses the DAG to find the &quot;Running&quot; and &quot;Submit Successful&quot; tasks, and monitors the status of its task instance for the &quot;Running&quot; task. You need to determine whether the Task Queue already exists. If it exists, monitor the status of the task instance. If it does not exist, resubmit the task instance.</p>
-<ul>
-<li>Worker fault tolerance flow chart:</li>
-</ul>
- <p align="center">
-   <img src="/img/architecture-design/fault-tolerant_worker.png" alt="Worker Fault Tolerance Flowchart" width="70%" />
- </p>
-<p>Once the Master Scheduler thread finds the task instance as &quot;need to be fault tolerant&quot;, it takes over the task and resubmits.</p>
-<p>Note: Because the &quot;network jitter&quot; may cause the node to lose the heartbeat of ZooKeeper in a short time, the node's remove event occurs. In this case, we use the easiest way, that is, once the node has timeout connection with ZooKeeper, it will directly stop the Master or Worker service.</p>
-<h6>2. Task failure retry</h6>
-<p>Here we must first distinguish between the concept of task failure retry, process failure recovery, and process failure rerun:</p>
-<ul>
-<li>Task failure Retry is task level, which is automatically performed by the scheduling system. For example, if a shell task sets the number of retries to 3 times, then the shell task will try to run up to 3 times after failing to run.</li>
-<li>Process failure recovery is process level, is done manually, recovery can only be performed <strong>from the failed node</strong> or <strong>from the current node</strong></li>
-<li>Process failure rerun is also process level, is done manually, rerun is from the start node</li>
-</ul>
-<p>Next, let's talk about the topic, we divided the task nodes in the workflow into two types.</p>
-<ul>
-<li>One is a business node, which corresponds to an actual script or processing statement, such as a Shell node, an MR node, a Spark node, a dependent node, and so on.</li>
-<li>There is also a logical node, which does not do the actual script or statement processing, but the logical processing of the entire process flow, such as sub-flow sections.</li>
-</ul>
-<p>Each <strong>service node</strong> can configure the number of failed retries. When the task node fails, it will automatically retry until it succeeds or exceeds the configured number of retries. <strong>Logical node</strong> does not support failed retry. But the tasks in the logical nodes support retry.</p>
-<p>If there is a task failure in the workflow that reaches the maximum number of retries, the workflow will fail to stop, and the failed workflow can be manually rerun or process resumed.</p>
-<h5>V. Task priority design</h5>
-<p>In the early scheduling design, if there is no priority design and fair scheduling design, it will encounter the situation that the task submitted first may be completed simultaneously with the task submitted subsequently, but the priority of the process or task cannot be set. We have redesigned this, and we are currently designing it as follows:</p>
-<ul>
-<li>
-<p>According to <strong>different process instance priority</strong> prioritizes <strong>same process instance priority</strong> prioritizes <strong>task priority within the same process</strong> takes precedence over <strong>same process</strong> commit order from high Go to low for task processing.</p>
-<ul>
-<li>
-<p>The specific implementation is to resolve the priority according to the json of the task instance, and then save the <strong>process instance priority _ process instance id_task priority _ task id</strong> information in the ZooKeeper task queue, when obtained from the task queue, Through string comparison, you can get the task that needs to be executed first.</p>
-<ul>
-<li>
-<p>The priority of the process definition is that some processes need to be processed before other processes. This can be configured at the start of the process or at the time of scheduled start. There are 5 levels, followed by HIGHEST, HIGH, MEDIUM, LOW, and LOWEST. As shown below</p>
-<p align="center">
-   <img src="/img/architecture-design/process_priority.png" alt="Process Priority Configuration" width="40%" />
- </p>
-</li>
-<li>
-<p>The priority of the task is also divided into 5 levels, followed by HIGHEST, HIGH, MEDIUM, LOW, and LOWEST. As shown below</p>
-<p align="center">`
-   <img src="/img/architecture-design/task_priority.png" alt="task priority configuration" width="35%" />
- </p>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-<h5>VI. Logback and gRPC implement log access</h5>
-<ul>
-<li>Since the Web (UI) and Worker are not necessarily on the same machine, viewing the log is not as it is for querying local files. There are two options:
-<ul>
-<li>Put the logs on the ES search engine</li>
-<li>Obtain remote log information through gRPC communication</li>
-</ul>
-</li>
-<li>Considering the lightweightness of DolphinScheduler as much as possible, gRPC was chosen to implement remote access log information.</li>
-</ul>
- <p align="center">
-   <img src="/img/architecture-design/grpc.png" alt="grpc remote access" width="50%" />
- </p>
-<ul>
-<li>We use a custom Logback FileAppender and Filter function to generate a log file for each task instance.</li>
-<li>The main implementation of FileAppender is as follows:</li>
-</ul>
-<pre><code class="language-java"> <span class="hljs-comment">/**
-  * task log appender
-  */</span>
- Public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TaskLogAppender</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">FileAppender</span>&lt;<span class="hljs-title">ILoggingEvent</span>&gt; </span>{
- 
-     ...
-
-    <span class="hljs-meta">@Override</span>
-    <span class="hljs-function">Protected <span class="hljs-keyword">void</span> <span class="hljs-title">append</span><span class="hljs-params">(ILoggingEvent event)</span> </span>{
-
-        If (currentlyActiveFile == <span class="hljs-keyword">null</span>){
-            currentlyActiveFile = getFile();
-        }
-        String activeFile = currentlyActiveFile;
-        <span class="hljs-comment">// thread name: taskThreadName-processDefineId_processInstanceId_taskInstanceId</span>
-        String threadName = event.getThreadName();
-        String[] threadNameArr = threadName.split(<span class="hljs-string">&quot;-&quot;</span>);
-        <span class="hljs-comment">// logId = processDefineId_processInstanceId_taskInstanceId</span>
-        String logId = threadNameArr[<span class="hljs-number">1</span>];
-        ...
-        <span class="hljs-keyword">super</span>.subAppend(event);
-    }
-}
-</code></pre>
-<p>Generate a log in the form of /process definition id/process instance id/task instance id.log</p>
-<ul>
-<li>Filter matches the thread name starting with TaskLogInfo:</li>
-<li>TaskLogFilter is implemented as follows:</li>
-</ul>
-<pre><code class="language-java"> <span class="hljs-comment">/**
- * task log filter
- */</span>
-Public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TaskLogFilter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Filter</span>&lt;<span class="hljs-title">ILoggingEvent</span>&gt; </span>{
-
-    <span class="hljs-meta">@Override</span>
-    <span class="hljs-function">Public FilterReply <span class="hljs-title">decide</span><span class="hljs-params">(ILoggingEvent event)</span> </span>{
-        If (event.getThreadName().startsWith(<span class="hljs-string">&quot;TaskLogInfo-&quot;</span>)){
-            Return FilterReply.ACCEPT;
-        }
-        Return FilterReply.DENY;
-    }
-}
-</code></pre>
-<h3>summary</h3>
-<p>Starting from the scheduling, this paper introduces the architecture principle and implementation ideas of the big data distributed workflow scheduling system-DolphinScheduler. To be continued</p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/architecture-design.json b/en-us/docs/dev/user_doc/development/architecture-design.json
deleted file mode 100644
index ff01c84c7..000000000
--- a/en-us/docs/dev/user_doc/development/architecture-design.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "architecture-design.md",
-  "__html": "<h2>Architecture Design</h2>\n<p>Before explaining the architecture of the schedule system, let us first understand the common nouns of the schedule system.</p>\n<h3>1.Noun Interpretation</h3>\n<p><strong>DAG:</strong> Full name Directed Acyclic Graph,referred to as DAG。Tasks in the workflow are assembled in the form of directed acyclic graphs, which are topologically traversed from nodes with zero indegrees of ingress until there are no successor nodes. For example, the fol [...]
-  "link": "/dist/en-us/docs/dev/user_doc/development/architecture-design.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/backend/mechanism/global-parameter.html b/en-us/docs/dev/user_doc/development/backend/mechanism/global-parameter.html
deleted file mode 100644
index 80c4e8540..000000000
--- a/en-us/docs/dev/user_doc/development/backend/mechanism/global-parameter.html
+++ /dev/null
@@ -1,84 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="global-parameter">
-  <meta name="description" content="global-parameter">
-  <title>global-parameter</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 Have queries regarding Apache DolphinScheduler, Join Slack channel to disscuss them <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span> [...]
-<p>After the user defines the parameter with the direction OUT, it is saved in the localParam of the task.</p>
-<h2>Usage of parameters</h2>
-<p>Getting the direct predecessor node <code>preTasks</code> of the current <code>taskInstance</code> to be created from the DAG, get the <code>varPool</code> of <code>preTasks</code>, merge this varPool (List) into one <code>varPool</code>, and in the merging process, if parameters with the same parameter name are found, they will be handled according to the following logics:</p>
-<ul>
-<li>If all the values are null, the merged value is null</li>
-<li>If one and only one value is non-null, then the merged value is the non-null value</li>
-<li>If all the values are not null, it would be the earliest value of the endtime of taskInstance taken by VarPool.</li>
-</ul>
-<p>The direction of all the merged properties is updated to IN during the merge process.</p>
-<p>The result of the merge is saved in taskInstance.varPool.</p>
-<p>The worker receives and parses the varPool into the format of <code>Map&lt;String,Property&gt;</code>, where the key of the map is property.prop, which is the parameter name.</p>
-<p>When the processor processes the parameters, it will merge the varPool and localParam and globalParam parameters, and if there are parameters with duplicate names during the merging process, they will be replaced according to the following priorities, with the higher priority being retained and the lower priority being replaced:</p>
-<ul>
-<li>globalParam: high</li>
-<li>varPool: middle</li>
-<li>localParam: low</li>
-</ul>
-<p>The parameters are replaced with the corresponding values using regular expressions compared to ${parameter name} before the node content is executed.</p>
-<h2>Parameter setting</h2>
-<p>Currently, only SQL and SHELL nodes are supported to get parameters.</p>
-<p>Get the parameter with direction OUT from localParam, and do the following way according to the type of different nodes.</p>
-<h3>SQL node</h3>
-<p>The structure returned by the parameter is List&lt;Map&lt;String,String&gt;&gt;, where the elements of List are each row of data, the key of Map is the column name, and the value is the value corresponding to the column.</p>
-<ul>
-<li>If the SQL statement returns one row of data, match the OUT parameter name based on the OUT parameter name defined by the user when defining the task, or discard it if it does not match.</li>
-<li>If the SQL statement returns multiple rows of data, the column names are matched based on the OUT parameter names defined by the user when defining the task of type LIST. All rows of the corresponding column are converted to <code>List&lt;String&gt;</code> as the value of this parameter. If there is no match, it is discarded.</li>
-</ul>
-<h3>SHELL node</h3>
-<p>The result of the processor execution is returned as <code>Map&lt;String,String&gt;</code>.</p>
-<p>The user needs to define <code>${setValue(key=value)}</code> in the output when defining the shell script.</p>
-<p>Remove <code>${setValue()}</code> when processing parameters, split by &quot;=&quot;, with the 0th being the key and the 1st being the value.</p>
-<p>Similarly match the OUT parameter name and key defined by the user when defining the task, and use value as the value of that parameter.</p>
-<p>Return parameter processing</p>
-<ul>
-<li>The result of acquired Processor is String.</li>
-<li>Determine whether the processor is empty or not, and exit if it is empty.</li>
-<li>Determine whether the localParam is empty or not, and exit if it is empty.</li>
-<li>Get the parameter of localParam which is OUT, and exit if it is empty.</li>
-<li>Format String as per appeal format (<code>List&lt;Map&lt;String,String&gt;&gt;</code> for SQL, <code>Map&lt;String,String&gt;&gt;</code> for shell).</li>
-</ul>
-<p>Assign the parameters with matching values to varPool (List, which contains the original IN's parameters)</p>
-<ul>
-<li>Format the varPool as json and pass it to master.</li>
-<li>The parameters that are OUT would be written into the localParam after the master has received the varPool.</li>
-</ul>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/backend/mechanism/global-parameter.json b/en-us/docs/dev/user_doc/development/backend/mechanism/global-parameter.json
deleted file mode 100644
index 253ae6a4c..000000000
--- a/en-us/docs/dev/user_doc/development/backend/mechanism/global-parameter.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "global-parameter.md",
-  "__html": "<h1>Global Parameter development document</h1>\n<p>After the user defines the parameter with the direction OUT, it is saved in the localParam of the task.</p>\n<h2>Usage of parameters</h2>\n<p>Getting the direct predecessor node <code>preTasks</code> of the current <code>taskInstance</code> to be created from the DAG, get the <code>varPool</code> of <code>preTasks</code>, merge this varPool (List) into one <code>varPool</code>, and in the merging process, if parameters with  [...]
-  "link": "/dist/en-us/docs/dev/user_doc/development/backend/mechanism/global-parameter.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/backend/mechanism/overview.html b/en-us/docs/dev/user_doc/development/backend/mechanism/overview.html
deleted file mode 100644
index 2ea50197b..000000000
--- a/en-us/docs/dev/user_doc/development/backend/mechanism/overview.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="overview">
-  <meta name="description" content="overview">
-  <title>overview</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 Have queries regarding Apache DolphinScheduler, Join Slack channel to disscuss them <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span> [...]
-<!-- TODO Since the side menu does not support multiple levels, add new page to keep all sub page here -->
-<ul>
-<li><a href="global-parameter.md">Global Parameter</a></li>
-<li><a href="task/switch.md">Switch Task type</a></li>
-</ul>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/backend/mechanism/overview.json b/en-us/docs/dev/user_doc/development/backend/mechanism/overview.json
deleted file mode 100644
index 1ab5f79ec..000000000
--- a/en-us/docs/dev/user_doc/development/backend/mechanism/overview.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "overview.md",
-  "__html": "<h1>Overview</h1>\n<!-- TODO Since the side menu does not support multiple levels, add new page to keep all sub page here -->\n<ul>\n<li><a href=\"global-parameter.md\">Global Parameter</a></li>\n<li><a href=\"task/switch.md\">Switch Task type</a></li>\n</ul>\n",
-  "link": "/dist/en-us/docs/dev/user_doc/development/backend/mechanism/overview.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/backend/mechanism/task/switch.html b/en-us/docs/dev/user_doc/development/backend/mechanism/task/switch.html
deleted file mode 100644
index 91a7d63db..000000000
--- a/en-us/docs/dev/user_doc/development/backend/mechanism/task/switch.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="switch">
-  <meta name="description" content="switch">
-  <title>switch</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 Have queries regarding Apache DolphinScheduler, Join Slack channel to disscuss them <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span> [...]
-<p>Switch task workflow step as follows</p>
-<ul>
-<li>User-defined expressions and branch information are stored in <code>taskParams</code> in <code>taskdefinition</code>. When the switch is executed, it will be formatted as <code>SwitchParameters</code></li>
-<li><code>SwitchTaskExecThread</code> processes the expressions defined in <code>switch</code> from top to bottom, obtains the value of the variable from <code>varPool</code>, and parses the expression through <code>javascript</code>. If the expression returns true, stop checking and record The order of the expression, here we record as resultConditionLocation. The task of SwitchTaskExecThread is over</li>
-<li>After the <code>switch</code> task runs, if there is no error (more commonly, the user-defined expression is out of specification or there is a problem with the parameter name), then <code>MasterExecThread.submitPostNode</code> will obtain the downstream node of the <code>DAG</code> to continue execution.</li>
-<li>If it is found in <code>DagHelper.parsePostNodes</code> that the current node (the node that has just completed the work) is a <code>switch</code> node, the <code>resultConditionLocation</code> will be obtained, and all branches except <code>resultConditionLocation</code> in the SwitchParameters will be skipped. In this way, only the branches that need to be executed are left</li>
-</ul>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/backend/mechanism/task/switch.json b/en-us/docs/dev/user_doc/development/backend/mechanism/task/switch.json
deleted file mode 100644
index 09be3055b..000000000
--- a/en-us/docs/dev/user_doc/development/backend/mechanism/task/switch.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "switch.md",
-  "__html": "<h1>SWITCH Task development</h1>\n<p>Switch task workflow step as follows</p>\n<ul>\n<li>User-defined expressions and branch information are stored in <code>taskParams</code> in <code>taskdefinition</code>. When the switch is executed, it will be formatted as <code>SwitchParameters</code></li>\n<li><code>SwitchTaskExecThread</code> processes the expressions defined in <code>switch</code> from top to bottom, obtains the value of the variable from <code>varPool</code>, and par [...]
-  "link": "/dist/en-us/docs/dev/user_doc/development/backend/mechanism/task/switch.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/backend/spi/alert.html b/en-us/docs/dev/user_doc/development/backend/spi/alert.html
deleted file mode 100644
index d221ede1c..000000000
--- a/en-us/docs/dev/user_doc/development/backend/spi/alert.html
+++ /dev/null
@@ -1,97 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="alert">
-  <meta name="description" content="alert">
-  <title>alert</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 Have queries regarding Apache DolphinScheduler, Join Slack channel to disscuss them <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span> [...]
-<h4>DolphinScheduler SPI Design</h4>
-<p>DolphinScheduler is undergoing a microkernel + plug-in architecture change. All core capabilities such as tasks, resource storage, registration centers, etc. will be designed as extension points. We hope to use SPI to improve DolphinScheduler’s own flexibility and friendliness (extended sex).</p>
-<p>For alarm-related codes, please refer to the <code>dolphinscheduler-alert-api</code> module. This module defines the extension interface of the alarm plug-in and some basic codes. When we need to realize the plug-inization of related functions, it is recommended to read the code of this block first. Of course, it is recommended that you read the document. This will reduce a lot of time, but the document There is a certain degree of lag. When the document is missing, it is recommended  [...]
-<p>We use the native JAVA-SPI, when you need to extend, in fact, you only need to pay attention to the extension of the <code>org.apache.dolphinscheduler.alert.api.AlertChannelFactory</code> interface, the underlying logic such as plug-in loading, and other kernels have been implemented, Which makes our development more focused and simple.</p>
-<p>By the way, we have adopted an excellent front-end component form-create, which supports the generation of front-end UI components based on JSON. If plug-in development involves the front-end, we will use JSON to generate related front-end UI components, org.apache.dolphinscheduler. The parameters of the plug-in are encapsulated in spi.params, which will convert all the relevant parameters into the corresponding JSON, which means that you can complete the drawing of the front-end comp [...]
-<p>This article mainly focuses on the design and development of Alert.</p>
-<h4>Main Modules</h4>
-<p>If you don't care about its internal design, but simply want to know how to develop your own alarm plug-in, you can skip this content.</p>
-<ul>
-<li>
-<p>dolphinscheduler-alert-api</p>
-<p>This module is the core module of ALERT SPI. This module defines the interface of the alarm plug-in extension and some basic codes. The extension plug-in must implement the interface defined by this module: <code>org.apache.dolphinscheduler.alert.api.AlertChannelFactory</code></p>
-</li>
-<li>
-<p>dolphinscheduler-alert-plugins</p>
-<p>This module is currently a plug-in provided by us, such as Email, DingTalk, Script, etc.</p>
-</li>
-</ul>
-<h4>Alert SPI Main class information.</h4>
-<p>AlertChannelFactory
-Alarm plug-in factory interface. All alarm plug-ins need to implement this interface. This interface is used to define the name of the alarm plug-in and the required parameters. The create method is used to create a specific alarm plug-in instance.</p>
-<p>AlertChannel
-The interface of the alert plug-in. The alert plug-in needs to implement this interface. There is only one method process in this interface. The upper-level alert system will call this method and obtain the return information of the alert through the AlertResult returned by this method.</p>
-<p>AlertData
-Alarm content information, including id, title, content, log.</p>
-<p>AlertInfo
-For alarm-related information, when the upper-level system calls an instance of the alarm plug-in, the instance of this class is passed to the specific alarm plug-in through the process method. It contains the alert content AlertData and the parameter information filled in by the front end of the called alert plug-in instance.</p>
-<p>AlertResult
-The alarm plug-in sends alarm return information.</p>
-<p>org.apache.dolphinscheduler.spi.params
-This package is a plug-in parameter definition. Our front-end uses the from-create front-end library <a href="http://www.form-create.com">http://www.form-create.com</a>, which can dynamically generate the front-end UI based on the parameter list json returned by the plug-in definition, so We don't need to care about the front end when we are doing SPI plug-in development.</p>
-<p>Under this package, we currently only encapsulate RadioParam, TextParam, and PasswordParam, which are used to define text type parameters, radio parameters and password type parameters, respectively.</p>
-<p>AbsPluginParams This class is the base class of all parameters, RadioParam these classes all inherit this class. Each DS alert plug-in will return a list of AbsPluginParams in the implementation of AlertChannelFactory.</p>
-<p>The specific design of alert_spi can be seen in the issue: <a href="https://github.com/apache/incubator-dolphinscheduler/issues/3049">Alert Plugin Design</a></p>
-<h4>Alert SPI built-in implementation</h4>
-<ul>
-<li>
-<p>Email</p>
-<p>Email alert notification</p>
-</li>
-<li>
-<p>DingTalk</p>
-<p>Alert for DingTalk group chat bots</p>
-</li>
-<li>
-<p>EnterpriseWeChat</p>
-<p>EnterpriseWeChat alert notifications</p>
-<p>Related parameter configuration can refer to the EnterpriseWeChat robot document.</p>
-</li>
-<li>
-<p>Script</p>
-<p>We have implemented a shell script for alerting. We will pass the relevant alert parameters to the script and you can implement your alert logic in the shell. This is a good way to interface with internal alerting applications.</p>
-</li>
-<li>
-<p>SMS</p>
-<p>SMS alerts</p>
-</li>
-</ul>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/backend/spi/alert.json b/en-us/docs/dev/user_doc/development/backend/spi/alert.json
deleted file mode 100644
index f1ab421cb..000000000
--- a/en-us/docs/dev/user_doc/development/backend/spi/alert.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "alert.md",
-  "__html": "<h3>DolphinScheduler Alert SPI main design</h3>\n<h4>DolphinScheduler SPI Design</h4>\n<p>DolphinScheduler is undergoing a microkernel + plug-in architecture change. All core capabilities such as tasks, resource storage, registration centers, etc. will be designed as extension points. We hope to use SPI to improve DolphinScheduler’s own flexibility and friendliness (extended sex).</p>\n<p>For alarm-related codes, please refer to the <code>dolphinscheduler-alert-api</code> mo [...]
-  "link": "/dist/en-us/docs/dev/user_doc/development/backend/spi/alert.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/backend/spi/datasource.html b/en-us/docs/dev/user_doc/development/backend/spi/datasource.html
deleted file mode 100644
index 86fd94aa4..000000000
--- a/en-us/docs/dev/user_doc/development/backend/spi/datasource.html
+++ /dev/null
@@ -1,57 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="datasource">
-  <meta name="description" content="datasource">
-  <title>datasource</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 Have queries regarding Apache DolphinScheduler, Join Slack channel to disscuss them <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span> [...]
-<h4>How do I use data sources?</h4>
-<p>The data source center supports POSTGRESQL, HIVE/IMPALA, SPARK, CLICKHOUSE, SQLSERVER data sources by default.</p>
-<p>If you are using MySQL or ORACLE data source, you need to place the corresponding driver package in the lib directory</p>
-<h4>How to do Datasource plugin development?</h4>
-<p>org.apache.dolphinscheduler.spi.datasource.DataSourceChannel
-org.apache.dolphinscheduler.spi.datasource.DataSourceChannelFactory
-org.apache.dolphinscheduler.plugin.datasource.api.client.CommonDataSourceClient</p>
-<ol>
-<li>
-<p>In the first step, the data source plug-in can implement the above interfaces and inherit the general client. For details, refer to the implementation of data source plug-ins such as sqlserver and mysql. The addition methods of all RDBMS plug-ins are the same.</p>
-</li>
-<li>
-<p>Add the driver configuration in the data source plug-in pom.xml</p>
-</li>
-</ol>
-<p>We provide APIs for external access of all data sources in the dolphin scheduler data source API module</p>
-<h4><strong>Future plan</strong></h4>
-<p>Support data sources such as kafka, http, files, sparkSQL, FlinkSQL, etc.</p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/backend/spi/datasource.json b/en-us/docs/dev/user_doc/development/backend/spi/datasource.json
deleted file mode 100644
index 26103a9c4..000000000
--- a/en-us/docs/dev/user_doc/development/backend/spi/datasource.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "datasource.md",
-  "__html": "<h2>DolphinScheduler Datasource SPI main design</h2>\n<h4>How do I use data sources?</h4>\n<p>The data source center supports POSTGRESQL, HIVE/IMPALA, SPARK, CLICKHOUSE, SQLSERVER data sources by default.</p>\n<p>If you are using MySQL or ORACLE data source, you need to place the corresponding driver package in the lib directory</p>\n<h4>How to do Datasource plugin development?</h4>\n<p>org.apache.dolphinscheduler.spi.datasource.DataSourceChannel\norg.apache.dolphinscheduler [...]
-  "link": "/dist/en-us/docs/dev/user_doc/development/backend/spi/datasource.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/backend/spi/registry.html b/en-us/docs/dev/user_doc/development/backend/spi/registry.html
deleted file mode 100644
index 49bd1224b..000000000
--- a/en-us/docs/dev/user_doc/development/backend/spi/registry.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="registry">
-  <meta name="description" content="registry">
-  <title>registry</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 Have queries regarding Apache DolphinScheduler, Join Slack channel to disscuss them <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span> [...]
-<h4>how to use?</h4>
-<p>Make the following configuration (take zookeeper as an example)</p>
-<ul>
-<li>Registry plug-in configuration, take Zookeeper as an example (registry.properties)
-dolphinscheduler-service/src/main/resources/registry.properties<pre><code class="language-registry.properties"> registry.plugin.name=zookeeper
- registry.servers=127.0.0.1:2181
-</code></pre>
-</li>
-</ul>
-<p>For specific configuration information, please refer to the parameter information provided by the specific plug-in, for example zk: <code>org/apache/dolphinscheduler/plugin/registry/zookeeper/ZookeeperConfiguration.java</code>
-All configuration information prefixes need to be +registry, such as <a href="http://base.sleep.time.ms">base.sleep.time.ms</a>, which should be configured in the registry as follows: registry.base.sleep.time.ms=100</p>
-<h4>How to expand</h4>
-<p><code>dolphinscheduler-registry-api</code> defines the standard for implementing plugins. When you need to extend plugins, you only need to implement <code>org.apache.dolphinscheduler.registry.api.RegistryFactory</code>.</p>
-<p>Under the <code>dolphinscheduler-registry-plugin</code> module is the registry plugin we currently provide.</p>
-<h4>FAQ</h4>
-<p>1: registry connect timeout</p>
-<p>You can increase the relevant timeout parameters.</p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/backend/spi/registry.json b/en-us/docs/dev/user_doc/development/backend/spi/registry.json
deleted file mode 100644
index c02f6af51..000000000
--- a/en-us/docs/dev/user_doc/development/backend/spi/registry.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "registry.md",
-  "__html": "<h3>DolphinScheduler Registry SPI Extension</h3>\n<h4>how to use?</h4>\n<p>Make the following configuration (take zookeeper as an example)</p>\n<ul>\n<li>Registry plug-in configuration, take Zookeeper as an example (registry.properties)\ndolphinscheduler-service/src/main/resources/registry.properties<pre><code class=\"language-registry.properties\"> registry.plugin.name=zookeeper\n registry.servers=127.0.0.1:2181\n</code></pre>\n</li>\n</ul>\n<p>For specific configuration in [...]
-  "link": "/dist/en-us/docs/dev/user_doc/development/backend/spi/registry.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/backend/spi/task.html b/en-us/docs/dev/user_doc/development/backend/spi/task.html
deleted file mode 100644
index 9f4eb6466..000000000
--- a/en-us/docs/dev/user_doc/development/backend/spi/task.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="task">
-  <meta name="description" content="task">
-  <title>task</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 Have queries regarding Apache DolphinScheduler, Join Slack channel to disscuss them <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span> [...]
-<h4>How to develop task plugins?</h4>
-<p>org.apache.dolphinscheduler.spi.task.TaskChannel</p>
-<p>The plug-in can implement the above interface. It mainly includes creating tasks (task initialization, task running, etc.) and task cancellation. If it is a yarn task, you need to implement org.apache.dolphinscheduler.plugin.task.api.AbstractYarnTask.</p>
-<p>We provide APIs for external access to all tasks in the dolphinscheduler-task-api module, while the dolphinscheduler-spi module is the spi general code library, which defines all the plug-in modules, such as the alarm module, the registry module, etc., you can read and view in detail .</p>
-<p><em>NOTICE</em></p>
-<p>Since the task plug-in involves the front-end page, the front-end SPI has not yet been implemented, so you need to implement the front-end page corresponding to the plug-in separately.</p>
-<p>If there is a class conflict in the task plugin, you can use <a href="https://maven.apache.org/plugins/maven-shade-plugin/">Shade-Relocating Classes</a> to solve this problem.</p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/backend/spi/task.json b/en-us/docs/dev/user_doc/development/backend/spi/task.json
deleted file mode 100644
index 72fc15c2a..000000000
--- a/en-us/docs/dev/user_doc/development/backend/spi/task.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "task.md",
-  "__html": "<h2>DolphinScheduler Task SPI extension</h2>\n<h4>How to develop task plugins?</h4>\n<p>org.apache.dolphinscheduler.spi.task.TaskChannel</p>\n<p>The plug-in can implement the above interface. It mainly includes creating tasks (task initialization, task running, etc.) and task cancellation. If it is a yarn task, you need to implement org.apache.dolphinscheduler.plugin.task.api.AbstractYarnTask.</p>\n<p>We provide APIs for external access to all tasks in the dolphinscheduler-t [...]
-  "link": "/dist/en-us/docs/dev/user_doc/development/backend/spi/task.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/development-environment-setup.html b/en-us/docs/dev/user_doc/development/development-environment-setup.html
deleted file mode 100644
index 0c61cd9b0..000000000
--- a/en-us/docs/dev/user_doc/development/development-environment-setup.html
+++ /dev/null
@@ -1,173 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="development-environment-setup">
-  <meta name="description" content="development-environment-setup">
-  <title>development-environment-setup</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 Have queries regarding Apache DolphinScheduler, Join Slack channel to disscuss them <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span> [...]
-<h2>Software Requests</h2>
-<p>Before setting up the DolphinScheduler development environment, please make sure you have installed the software as below:</p>
-<ul>
-<li><a href="https://git-scm.com/downloads">Git</a>: DolphinScheduler version control system</li>
-<li><a href="https://www.oracle.com/technetwork/java/javase/downloads/index.html">JDK</a>: DolphinScheduler backend language</li>
-<li><a href="http://maven.apache.org/download.cgi">Maven</a>: Java Package Management System</li>
-<li><a href="https://nodejs.org/en/download">Node</a>: DolphinScheduler frontend
-language</li>
-</ul>
-<h3>Clone Git Repository</h3>
-<p>Download the git repository through your git management tool, here we use git-core as an example</p>
-<pre><code class="language-shell">mkdir dolphinscheduler
-cd dolphinscheduler
-git clone git@github.com:apache/dolphinscheduler.git
-</code></pre>
-<h3>compile source code</h3>
-<p>i. If you use MySQL database, pay attention to modify pom.xml in the root project, and change the scope of the mysql-connector-java dependency to compile.</p>
-<p>ii. Run <code>mvn clean install -Prelease -Dmaven.test.skip=true</code></p>
-<h2>Notice</h2>
-<p>There are two ways to configure the DolphinScheduler development environment, standalone mode and normal mode</p>
-<ul>
-<li><a href="#dolphinscheduler-standalone-quick-start">Standalone mode</a>: <strong>Recommended</strong>,more convenient to build development environment, it can cover most scenes.</li>
-<li><a href="#dolphinscheduler-normal-mode">Normal mode</a>: Separate server master, worker, api, which can cover more test environments than standalone, and it is more like production environment in real life.</li>
-</ul>
-<h2>DolphinScheduler Standalone Quick Start</h2>
-<blockquote>
-<p><strong><em>Note:</em></strong> Standalone server only for development and debugging, cause it use H2 Database, Zookeeper Testing Server which may not stable in production
-Standalone is only supported in DolphinScheduler 1.3.9 and later versions</p>
-</blockquote>
-<h3>Git Branch Choose</h3>
-<p>Use different Git branch to develop different codes</p>
-<ul>
-<li>If you want to develop based on a binary package, switch git branch to specific release branch, for example, if you want to develop base on 1.3.9, you should choose branch <code>1.3.9-release</code>.</li>
-<li>If you want to develop the latest code, choose branch branch <code>dev</code>.</li>
-</ul>
-<h3>Start backend server</h3>
-<p>Find the class <code>org.apache.dolphinscheduler.server.StandaloneServer</code> in Intellij IDEA and clikc run main function to startup.</p>
-<h3>Start frontend server</h3>
-<p>Install frontend dependencies and run it</p>
-<pre><code class="language-shell">cd dolphinscheduler-ui
-npm install
-npm run start
-</code></pre>
-<p>The browser access address <a href="http://localhost:12345/dolphinscheduler">http://localhost:12345/dolphinscheduler</a> can login DolphinScheduler UI. The default username and password are <strong>admin/dolphinscheduler123</strong></p>
-<h2>DolphinScheduler Normal Mode</h2>
-<h3>Prepare</h3>
-<h4>zookeeper</h4>
-<p>Download <a href="https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.6.3">ZooKeeper</a>, and extract it.</p>
-<ul>
-<li>
-<p>Create directory <code>zkData</code> and <code>zkLog</code></p>
-</li>
-<li>
-<p>Go to the zookeeper installation directory, copy configure file <code>zoo_sample.cfg</code> to <code>conf/zoo.cfg</code>, and change value of dataDir in conf/zoo.cfg to dataDir=./tmp/zookeeper</p>
-<pre><code class="language-shell"><span class="hljs-meta">#</span><span class="bash"> We use path /data/zookeeper/data and /data/zookeeper/datalog here as example</span>
-dataDir=/data/zookeeper/data
-dataLogDir=/data/zookeeper/datalog
-</code></pre>
-</li>
-<li>
-<p>Run <code>./bin/zkServer.sh</code> in terminal by command <code>./bin/zkServer.sh start</code>.</p>
-</li>
-</ul>
-<h4>Database</h4>
-<p>The DolphinScheduler's metadata is stored in relational database. Currently supported MySQL and Postgresql. We use MySQL as an example. Start the database and create a new database named dolphinscheduler as DolphinScheduler metabase</p>
-<p>After creating the new database, run the sql file under <code>dolphinscheduler/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_mysql.sql</code> directly in MySQL to complete the database initialization</p>
-<h4>Start Backend Server</h4>
-<p>Following steps will guide how to start the DolphinScheduler backend service</p>
-<h5>Backend Start Prepare</h5>
-<ul>
-<li>
-<p>Open project: Use IDE open the project, here we use Intellij IDEA as an example, after opening it will take a while for Intellij IDEA to complete the dependent download</p>
-</li>
-<li>
-<p>Plugin installation(<strong>Only required for 2.0 or later</strong>)</p>
-</li>
-<li>
-<p>Registry plug-in configuration, take Zookeeper as an example (registry.properties)
-dolphinscheduler-service/src/main/resources/registry.properties</p>
-</li>
-</ul>
-<pre><code class="language-registry.properties"> registry.plugin.name=zookeeper
- registry.servers=127.0.0.1:2181
-</code></pre>
-<ul>
-<li>
-<p>File change</p>
-<ul>
-<li>If you use MySQL as your metadata database, you need to modify <code>dolphinscheduler/pom.xml</code> and change the <code>scope</code> of the <code>mysql-connector-java</code> dependency to <code>compile</code>. This step is not necessary to use PostgreSQL</li>
-<li>Modify database configuration, modify the database configuration in the <code>dolphinscheduler-dao/src/main/resources/application-mysql.yaml</code></li>
-</ul>
-<p>We here use MySQL with database, username, password named dolphinscheduler as an example</p>
-<pre><code class="language-application-mysql.yaml"> spring:
-   datasource:
-     driver-class-name: com.mysql.jdbc.Driver
-     url: jdbc:mysql://127.0.0.1:3306/dolphinscheduler?useUnicode=true&amp;characterEncoding=UTF-8
-     username: ds_user
-     password: dolphinscheduler
-</code></pre>
-</li>
-<li>
-<p>Log level: add a line <code>&lt;appender-ref ref=&quot;STDOUT&quot;/&gt;</code> to the following configuration to enable the log to be displayed on the command line</p>
-<p><code>dolphinscheduler-server/src/main/resources/logback-worker.xml</code></p>
-<p><code>dolphinscheduler-server/src/main/resources/logback-master.xml</code></p>
-<p><code>dolphinscheduler-api/src/main/resources/logback-api.xml</code></p>
-<p>here we add the result after modify as below:</p>
-<pre><code class="language-diff">&lt;root level=&quot;INFO&quot;&gt;
-<span class="hljs-addition">+  &lt;appender-ref ref=&quot;STDOUT&quot;/&gt;</span>
-  &lt;appender-ref ref=&quot;APILOGFILE&quot;/&gt;
-  &lt;appender-ref ref=&quot;SKYWALKING-LOG&quot;/&gt;
-&lt;/root&gt;
-</code></pre>
-</li>
-</ul>
-<blockquote>
-<p><strong><em>Note:</em></strong> Only DolphinScheduler 2.0 and later versions need to inatall plugin before start server. It not need before version 2.0.</p>
-</blockquote>
-<h5>Server start</h5>
-<p>There are three services that need to be started, including MasterServer, WorkerServer, ApiApplicationServer.</p>
-<ul>
-<li>MasterServer:Execute function <code>main</code> in the class <code>org.apache.dolphinscheduler.server.master.MasterServer</code> by Intellij IDEA, with the configuration <em>VM Options</em> <code>-Dlogging.config=classpath:logback-master.xml -Ddruid.mysql.usePingMethod=false -Dspring.profiles.active=mysql</code></li>
-<li>WorkerServer:Execute function <code>main</code> in the class <code>org.apache.dolphinscheduler.server.worker.WorkerServer</code> by Intellij IDEA, with the configuration <em>VM Options</em> <code>-Dlogging.config=classpath:logback-worker.xml -Ddruid.mysql.usePingMethod=false -Dspring.profiles.active=mysql</code></li>
-<li>ApiApplicationServer:Execute function <code>main</code> in the class <code>org.apache.dolphinscheduler.api.ApiApplicationServer</code> by Intellij IDEA, with the configuration <em>VM Options</em> <code>-Dlogging.config=classpath:logback-api.xml -Dspring.profiles.active=api,mysql</code>. After it started, you could find Open API documentation in <a href="http://localhost:12345/dolphinscheduler/doc.html">http://localhost:12345/dolphinscheduler/doc.html</a></li>
-</ul>
-<blockquote>
-<p>The <code>mysql</code> in the VM Options <code>-Dspring.profiles.active=mysql</code> means specified configuration file</p>
-</blockquote>
-<h3>Start Frontend Server</h3>
-<p>Install frontend dependencies and run it</p>
-<pre><code class="language-shell">cd dolphinscheduler-ui
-npm install
-npm run start
-</code></pre>
-<p>The browser access address <a href="http://localhost:12345/dolphinscheduler">http://localhost:12345/dolphinscheduler</a> can login DolphinScheduler UI. The default username and password are <strong>admin/dolphinscheduler123</strong></p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/development-environment-setup.json b/en-us/docs/dev/user_doc/development/development-environment-setup.json
deleted file mode 100644
index b4e187a8c..000000000
--- a/en-us/docs/dev/user_doc/development/development-environment-setup.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "development-environment-setup.md",
-  "__html": "<h1>DolphinScheduler development</h1>\n<h2>Software Requests</h2>\n<p>Before setting up the DolphinScheduler development environment, please make sure you have installed the software as below:</p>\n<ul>\n<li><a href=\"https://git-scm.com/downloads\">Git</a>: DolphinScheduler version control system</li>\n<li><a href=\"https://www.oracle.com/technetwork/java/javase/downloads/index.html\">JDK</a>: DolphinScheduler backend language</li>\n<li><a href=\"http://maven.apache.org/dow [...]
-  "link": "/dist/en-us/docs/dev/user_doc/development/development-environment-setup.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/e2e-test.html b/en-us/docs/dev/user_doc/development/e2e-test.html
deleted file mode 100644
index 279183136..000000000
--- a/en-us/docs/dev/user_doc/development/e2e-test.html
+++ /dev/null
@@ -1,190 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="e2e-test">
-  <meta name="description" content="e2e-test">
-  <title>e2e-test</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 Have queries regarding Apache DolphinScheduler, Join Slack channel to disscuss them <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span> [...]
-<h2>I. Preparatory knowledge</h2>
-<h3>1. The difference between E2E Test and Unit Test</h3>
-<p>E2E, which stands for &quot;End to End&quot;, can be translated as &quot;end-to-end&quot; testing. It imitates the user, starting from a certain entry point and progressively performing actions until a certain job is completed. And unit tests are different, the latter usually requires testing parameters, types and parameter values, the number of arguments, the return value, throw an error, and so on, the purpose is to ensure that a specific function to finishing the work is stable and [...]
-<p>In contrast, E2E test does not emphasize so much the need to cover all usage scenarios, it focuses on whether a complete chain of operations can be completed. For the web front-end, it is also concerned with the layout of the interface and whether the content information meets expectations.</p>
-<p>For example, E2E test of the login page is concerned with whether the user is able to enter and log in normally, and whether the error message is correctly displayed if the login fails. It is not a major concern whether input that is not legal is processed.</p>
-<h3>2. Selenium test framework</h3>
-<p><a href="https://www.selenium.dev">Selenium</a> is an open source testing tool for executing automated tests on a web browser. The framework uses WebDriver to transform Web Service commands into browser native calls through the browser's native components to complete operations. In simple words, it simulates the browser and makes selection operations on the elements of the page.</p>
-<p>A WebDriver is an API and protocol which defines a language-neutral interface for controlling the behavior of a web browser.  Every browser has a specific WebDriver implementation, called a driver. The driver is the component responsible for delegating to the browser and handling the communication with Selenium and the browser.</p>
-<p>The Selenium framework links all these components together through a user-facing interface that allows transparent work with different browser backends, enabling cross-browser and cross-platform automation.</p>
-<h2>II. E2E Test</h2>
-<h3>1. E2E-Pages</h3>
-<p>DolphinScheduler's E2E tests are deployed using docker-compose. The current tests are in standalone mode and are mainly used to check some basic functions such as &quot;add, delete, change and check&quot;. For further cluster validation, such as collaboration between services or communication mechanisms between services, refer to <code>deploy/docker/docker-compose.yml</code> for configuration.</p>
-<p>For E2E test (the front-end part),  the <a href="https://www.selenium.dev/documentation/guidelines/page_object_models/">page model</a> form is used, mainly to create a corresponding model for each page. The following is an example of a login page.</p>
-<pre><code class="language-java"><span class="hljs-keyword">package</span> org.apache.dolphinscheduler.e2e.pages;
-
-<span class="hljs-keyword">import</span> org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
-<span class="hljs-keyword">import</span> org.apache.dolphinscheduler.e2e.pages.security.TenantPage;
-
-<span class="hljs-keyword">import</span> org.openqa.selenium.WebElement;
-<span class="hljs-keyword">import</span> org.openqa.selenium.remote.RemoteWebDriver;
-<span class="hljs-keyword">import</span> org.openqa.selenium.support.FindBy;
-<span class="hljs-keyword">import</span> org.openqa.selenium.support.ui.ExpectedConditions;
-<span class="hljs-keyword">import</span> org.openqa.selenium.support.ui.WebDriverWait;
-
-<span class="hljs-keyword">import</span> lombok.Getter;
-<span class="hljs-keyword">import</span> lombok.SneakyThrows;
-
-<span class="hljs-meta">@Getter</span>
-<span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LoginPage</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">NavBarPage</span> </span>{
-    <span class="hljs-meta">@FindBy(id = &quot;inputUsername&quot;)</span>
-    <span class="hljs-keyword">private</span> WebElement inputUsername;
-
-    <span class="hljs-meta">@FindBy(id = &quot;inputPassword&quot;)</span>
-    <span class="hljs-keyword">private</span> WebElement inputPassword;
-
-    <span class="hljs-meta">@FindBy(id = &quot;btnLogin&quot;)</span>
-    <span class="hljs-keyword">private</span> WebElement buttonLogin;
-
-    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">LoginPage</span><span class="hljs-params">(RemoteWebDriver driver)</span> </span>{
-        <span class="hljs-keyword">super</span>(driver);
-    }
-
-    <span class="hljs-meta">@SneakyThrows</span>
-    <span class="hljs-function"><span class="hljs-keyword">public</span> TenantPage <span class="hljs-title">login</span><span class="hljs-params">(String username, String password)</span> </span>{
-        inputUsername().sendKeys(username);
-        inputPassword().sendKeys(password);
-        buttonLogin().click();
-
-        <span class="hljs-keyword">new</span> WebDriverWait(driver, <span class="hljs-number">10</span>)
-            .until(ExpectedConditions.urlContains(<span class="hljs-string">&quot;/#/security&quot;</span>));
-
-        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> TenantPage(driver);
-    }
-}
-</code></pre>
-<p>During the test process, we only test the elements we need to focus on, not all elements of the page. So on the login page only the username, password and login button elements are declared. The FindBy interface is provided by the Selenium test framework to find the corresponding id or class in a Vue file.</p>
-<p>In addition, during the testing process, the elements are not manipulated directly. The general choice is to package the corresponding methods to achieve the effect of reuse. For example, if you want to log in, you input your username and password through the <code>public TenantPage login()</code> method to manipulate the elements you pass in to achieve the effect of logging in. That is, when the user finishes logging in, he or she jumps to the Security Centre (which goes to the Tenan [...]
-<p>The goToTab method is provided in SecurityPage to test the corresponding sidebar jumps, which include TenantPage, UserPage and WorkerGroupPge and QueuePage. These pages are implemented in the same way, to test that the form's input, add and delete buttons return the corresponding pages.</p>
-<pre><code class="language-java"> <span class="hljs-keyword">public</span> &lt;T extends SecurityPage.Tab&gt; <span class="hljs-function">T <span class="hljs-title">goToTab</span><span class="hljs-params">(Class&lt;T&gt; tab)</span> </span>{
-        <span class="hljs-keyword">if</span> (tab == TenantPage.class) {
-            WebElement menuTenantManageElement = <span class="hljs-keyword">new</span> WebDriverWait(driver, <span class="hljs-number">60</span>)
-                    .until(ExpectedConditions.elementToBeClickable(menuTenantManage));
-            ((JavascriptExecutor)driver).executeScript(<span class="hljs-string">&quot;arguments[0].click();&quot;</span>, menuTenantManageElement);
-            <span class="hljs-keyword">return</span> tab.cast(<span class="hljs-keyword">new</span> TenantPage(driver));
-        }
-        <span class="hljs-keyword">if</span> (tab == UserPage.class) {
-            WebElement menUserManageElement = <span class="hljs-keyword">new</span> WebDriverWait(driver, <span class="hljs-number">60</span>)
-                    .until(ExpectedConditions.elementToBeClickable(menUserManage));
-            ((JavascriptExecutor)driver).executeScript(<span class="hljs-string">&quot;arguments[0].click();&quot;</span>, menUserManageElement);
-            <span class="hljs-keyword">return</span> tab.cast(<span class="hljs-keyword">new</span> UserPage(driver));
-        }
-        <span class="hljs-keyword">if</span> (tab == WorkerGroupPage.class) {
-            WebElement menWorkerGroupManageElement = <span class="hljs-keyword">new</span> WebDriverWait(driver, <span class="hljs-number">60</span>)
-                    .until(ExpectedConditions.elementToBeClickable(menWorkerGroupManage));
-            ((JavascriptExecutor)driver).executeScript(<span class="hljs-string">&quot;arguments[0].click();&quot;</span>, menWorkerGroupManageElement);
-            <span class="hljs-keyword">return</span> tab.cast(<span class="hljs-keyword">new</span> WorkerGroupPage(driver));
-        }
-        <span class="hljs-keyword">if</span> (tab == QueuePage.class) {
-            menuQueueManage().click();
-            <span class="hljs-keyword">return</span> tab.cast(<span class="hljs-keyword">new</span> QueuePage(driver));
-        }
-        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> UnsupportedOperationException(<span class="hljs-string">&quot;Unknown tab: &quot;</span> + tab.getName());
-    }
-</code></pre>
-<p><img src="/img/e2e-test/SecurityPage.png" alt="SecurityPage"></p>
-<p>For navigation bar options jumping, the goToNav method is provided in <code>org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java</code>. The currently supported pages are: ProjectPage, SecurityPage and ResourcePage.</p>
-<pre><code class="language-java">    <span class="hljs-keyword">public</span> &lt;T extends NavBarItem&gt; <span class="hljs-function">T <span class="hljs-title">goToNav</span><span class="hljs-params">(Class&lt;T&gt; nav)</span> </span>{
-        <span class="hljs-keyword">if</span> (nav == ProjectPage.class) {
-            WebElement projectTabElement = <span class="hljs-keyword">new</span> WebDriverWait(driver, <span class="hljs-number">60</span>)
-                .until(ExpectedConditions.elementToBeClickable(projectTab));
-            ((JavascriptExecutor)driver).executeScript(<span class="hljs-string">&quot;arguments[0].click();&quot;</span>, projectTabElement);
-            <span class="hljs-keyword">return</span> nav.cast(<span class="hljs-keyword">new</span> ProjectPage(driver));
-        }
-
-        <span class="hljs-keyword">if</span> (nav == SecurityPage.class) {
-            WebElement securityTabElement = <span class="hljs-keyword">new</span> WebDriverWait(driver, <span class="hljs-number">60</span>)
-                .until(ExpectedConditions.elementToBeClickable(securityTab));
-            ((JavascriptExecutor)driver).executeScript(<span class="hljs-string">&quot;arguments[0].click();&quot;</span>, securityTabElement);
-            <span class="hljs-keyword">return</span> nav.cast(<span class="hljs-keyword">new</span> SecurityPage(driver));
-        }
-
-        <span class="hljs-keyword">if</span> (nav == ResourcePage.class) {
-            WebElement resourceTabElement = <span class="hljs-keyword">new</span> WebDriverWait(driver, <span class="hljs-number">60</span>)
-                .until(ExpectedConditions.elementToBeClickable(resourceTab));
-            ((JavascriptExecutor)driver).executeScript(<span class="hljs-string">&quot;arguments[0].click();&quot;</span>, resourceTabElement);
-            <span class="hljs-keyword">return</span> nav.cast(<span class="hljs-keyword">new</span> ResourcePage(driver));
-        }
-
-        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> UnsupportedOperationException(<span class="hljs-string">&quot;Unknown nav bar&quot;</span>);
-    }
-</code></pre>
-<h3>E2E-Cases</h3>
-<p>Current E2E test cases supported include: File Management, Project Management, Queue Management, Tenant Management, User Management, Worker Group Management and Workflow Test.</p>
-<p><img src="/img/e2e-test/E2E_Cases.png" alt="E2E_Cases"></p>
-<p>The following is an example of a tenant management test. As explained earlier, we use docker-compose for deployment, so for each test case, we need to import the corresponding file in the form of an annotation.</p>
-<p>The browser is loaded using the RemoteWebDriver provided with Selenium. Before each test case is started there is some preparation work that needs to be done. For example: logging in the user, jumping to the corresponding page (depending on the specific test case).</p>
-<pre><code class="language-java">    <span class="hljs-meta">@BeforeAll</span>
-    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setup</span><span class="hljs-params">()</span> </span>{
-        <span class="hljs-keyword">new</span> LoginPage(browser)
-                .login(<span class="hljs-string">&quot;admin&quot;</span>, <span class="hljs-string">&quot;dolphinscheduler123&quot;</span>) 
-                .goToNav(SecurityPage.class) 
-                .goToTab(TenantPage.class)
-        ;
-    }
-</code></pre>
-<p>When the preparation is complete, it is time for the formal test case writing. We use a form of @Order() annotation for modularity, to confirm the order of the tests. After the tests have been run, assertions are used to determine if the tests were successful, and if the assertion returns true, the tenant creation was successful. The following code can be used as a reference:</p>
-<pre><code class="language-java">    <span class="hljs-meta">@Test</span>
-    <span class="hljs-meta">@Order(10)</span>
-    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">testCreateTenant</span><span class="hljs-params">()</span> </span>{
-        <span class="hljs-keyword">final</span> TenantPage page = <span class="hljs-keyword">new</span> TenantPage(browser);
-        page.create(tenant);
-
-        await().untilAsserted(() -&gt; assertThat(page.tenantList())
-                .as(<span class="hljs-string">&quot;Tenant list should contain newly-created tenant&quot;</span>)
-                .extracting(WebElement::getText)
-                .anyMatch(it -&gt; it.contains(tenant)));
-    }
-</code></pre>
-<p>The rest are similar cases and can be understood by referring to the specific source code.</p>
-<p><a href="https://github.com/apache/dolphinscheduler/tree/dev/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases">https://github.com/apache/dolphinscheduler/tree/dev/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases</a></p>
-<h2>III. Supplements</h2>
-<p>When running E2E tests locally, First, you need to start the local service, you can refer to this page:
-<a href="https://dolphinscheduler.apache.org/en-us/development/development-environment-setup.html">development-environment-setup</a></p>
-<p>When running E2E tests locally, the <code>-Dlocal=true</code> parameter can be configured to connect locally and facilitate changes to the UI.</p>
-<p>When running E2E tests with <code>M1</code> chip, you can use <code>-Dm1_chip=true</code> parameter to configure containers supported by
-<code>ARM64</code>.</p>
-<p><img src="/img/e2e-test/Dlocal.png" alt="Dlocal"></p>
-<p>If a connection timeout occurs during a local run, increase the load time to a recommended 30 and above.</p>
-<p><img src="/img/e2e-test/timeout.png" alt="timeout"></p>
-<p>The test run will be available as an MP4 file.</p>
-<p><img src="/img/e2e-test/MP4.png" alt="MP4"></p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/e2e-test.json b/en-us/docs/dev/user_doc/development/e2e-test.json
deleted file mode 100644
index e0356c5e7..000000000
--- a/en-us/docs/dev/user_doc/development/e2e-test.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "e2e-test.md",
-  "__html": "<h1>DolphinScheduler E2E Automation Test</h1>\n<h2>I. Preparatory knowledge</h2>\n<h3>1. The difference between E2E Test and Unit Test</h3>\n<p>E2E, which stands for &quot;End to End&quot;, can be translated as &quot;end-to-end&quot; testing. It imitates the user, starting from a certain entry point and progressively performing actions until a certain job is completed. And unit tests are different, the latter usually requires testing parameters, types and parameter values, t [...]
-  "link": "/dist/en-us/docs/dev/user_doc/development/e2e-test.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/frontend-development.html b/en-us/docs/dev/user_doc/development/frontend-development.html
deleted file mode 100644
index 6db1b2632..000000000
--- a/en-us/docs/dev/user_doc/development/frontend-development.html
+++ /dev/null
@@ -1,538 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="frontend-development">
-  <meta name="description" content="frontend-development">
-  <title>frontend-development</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 Have queries regarding Apache DolphinScheduler, Join Slack channel to disscuss them <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span> [...]
-<h3>Technical selection</h3>
-<pre><code>Vue mvvm framework
-
-Es6 ECMAScript 6.0
-
-Ans-ui Analysys-ui
-
-D3  Visual Library Chart Library
-
-Jsplumb connection plugin library
-
-Lodash high performance JavaScript utility library
-</code></pre>
-<h3>Development environment</h3>
-<ul>
-<li>
-<h4>Node installation</h4>
-</li>
-</ul>
-<p>Node package download (note version v12.20.2) <code>https://nodejs.org/download/release/v12.20.2/</code></p>
-<ul>
-<li>
-<h4>Front-end project construction</h4>
-</li>
-</ul>
-<p>Use the command line mode <code>cd</code>  enter the <code>dolphinscheduler-ui</code> project directory and execute <code>npm install</code> to pull the project dependency package.</p>
-<blockquote>
-<p>If <code>npm install</code> is very slow, you can set the taobao mirror</p>
-</blockquote>
-<pre><code>npm config set registry http://registry.npm.taobao.org/
-</code></pre>
-<ul>
-<li>Modify <code>API_BASE</code> in the file <code>dolphinscheduler-ui/.env</code> to interact with the backend:</li>
-</ul>
-<pre><code># back end interface address
-API_BASE = http://127.0.0.1:12345
-</code></pre>
-<blockquote>
-<h5>! ! ! Special attention here. If the project reports a &quot;node-sass error&quot; error while pulling the dependency package, execute the following command again after execution.</h5>
-</blockquote>
-<pre><code class="language-bash">npm install node-sass --unsafe-perm <span class="hljs-comment">#Install node-sass dependency separately</span>
-</code></pre>
-<ul>
-<li>
-<h4>Development environment operation</h4>
-</li>
-<li><code>npm start</code> project development environment (after startup address <a href="http://localhost:8888">http://localhost:8888</a>)</li>
-</ul>
-<h4>Front-end project release</h4>
-<ul>
-<li><code>npm run build</code> project packaging (after packaging, the root directory will create a folder called dist for publishing Nginx online)</li>
-</ul>
-<p>Run the <code>npm run build</code> command to generate a package file (dist) package</p>
-<p>Copy it to the corresponding directory of the server (front-end service static page storage directory)</p>
-<p>Visit address<code>http://localhost:8888</code></p>
-<h4>Start with node and daemon under Linux</h4>
-<p>Install pm2 <code>npm install -g pm2</code></p>
-<p>Execute <code>pm2 start npm -- run dev</code> to start the project in the project <code>dolphinscheduler-ui</code>root directory</p>
-<h4>command</h4>
-<ul>
-<li>
-<p>Start <code>pm2 start npm -- run dev</code></p>
-</li>
-<li>
-<p>Stop <code>pm2 stop npm</code></p>
-</li>
-<li>
-<p>delete <code>pm2 delete npm</code></p>
-</li>
-<li>
-<p>Status  <code>pm2 list</code></p>
-</li>
-</ul>
-<pre><code>
-[root@localhost dolphinscheduler-ui]# pm2 start npm -- run dev
-[PM2] Applying action restartProcessId on app [npm](ids: 0)
-[PM2] [npm](0) ✓
-[PM2] Process successfully started
-┌──────────┬────┬─────────┬──────┬──────┬────────┬─────────┬────────┬─────┬──────────┬──────┬──────────┐
-│ App name │ id │ version │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem      │ user │ watching │
-├──────────┼────┼─────────┼──────┼──────┼────────┼─────────┼────────┼─────┼──────────┼──────┼──────────┤
-│ npm      │ 0  │ N/A     │ fork │ 6168 │ online │ 31      │ 0s     │ 0%  │ 5.6 MB   │ root │ disabled │
-└──────────┴────┴─────────┴──────┴──────┴────────┴─────────┴────────┴─────┴──────────┴──────┴──────────┘
- Use `pm2 show &lt;id|name&gt;` to get more details about an app
-
-</code></pre>
-<h3>Project directory structure</h3>
-<p><code>build</code> some webpack configurations for packaging and development environment projects</p>
-<p><code>node_modules</code> development environment node dependency package</p>
-<p><code>src</code> project required documents</p>
-<p><code>src =&gt; combo</code> project third-party resource localization <code>npm run combo</code> specific view <code>build/combo.js</code></p>
-<p><code>src =&gt; font</code> Font icon library can be added by visiting <a href="https://www.iconfont.cn">https://www.iconfont.cn</a> Note: The font library uses its own secondary development to reintroduce its own library <code>src/sass/common/_font.scss</code></p>
-<p><code>src =&gt; images</code> public image storage</p>
-<p><code>src =&gt; js</code> js/vue</p>
-<p><code>src =&gt; lib</code> internal components of the company (company component library can be deleted after open source)</p>
-<p><code>src =&gt; sass</code> sass file One page corresponds to a sass file</p>
-<p><code>src =&gt; view</code> page file One page corresponds to an html file</p>
-<pre><code>&gt; Projects are developed using vue single page application (SPA)
-- All page entry files are in the `src/js/conf/${ corresponding page filename =&gt; home} index.js` entry file
-- The corresponding sass file is in `src/sass/conf/${corresponding page filename =&gt; home}/index.scss`
-- The corresponding html file is in `src/view/${corresponding page filename =&gt; home}/index.html`
-</code></pre>
-<p>Public module and utill <code>src/js/module</code></p>
-<p><code>components</code> =&gt; internal project common components</p>
-<p><code>download</code> =&gt; download component</p>
-<p><code>echarts</code> =&gt; chart component</p>
-<p><code>filter</code> =&gt; filter and vue pipeline</p>
-<p><code>i18n</code> =&gt; internationalization</p>
-<p><code>io</code> =&gt; io request encapsulation based on axios</p>
-<p><code>mixin</code> =&gt; vue mixin public part for disabled operation</p>
-<p><code>permissions</code> =&gt; permission operation</p>
-<p><code>util</code> =&gt; tool</p>
-<h3>System function module</h3>
-<p>Home  =&gt; <code>http://localhost:8888/#/home</code></p>
-<p>Project Management =&gt; <code>http://localhost:8888/#/projects/list</code></p>
-<pre><code>| Project Home
-| Workflow
-  - Workflow definition
-  - Workflow instance
-  - Task instance
-</code></pre>
-<p>Resource Management =&gt; <code>http://localhost:8888/#/resource/file</code></p>
-<pre><code>| File Management
-| udf Management
-  - Resource Management
-  - Function management
-</code></pre>
-<p>Data Source Management =&gt; <code>http://localhost:8888/#/datasource/list</code></p>
-<p>Security Center =&gt; <code>http://localhost:8888/#/security/tenant</code></p>
-<pre><code>| Tenant Management
-| User Management
-| Alarm Group Management
-  - master
-  - worker
-</code></pre>
-<p>User Center =&gt; <code>http://localhost:8888/#/user/account</code></p>
-<h2>Routing and state management</h2>
-<p>The project <code>src/js/conf/home</code> is divided into</p>
-<p><code>pages</code> =&gt; route to page directory</p>
-<pre><code> The page file corresponding to the routing address
-</code></pre>
-<p><code>router</code> =&gt; route management</p>
-<pre><code>vue router, the entry file index.js in each page will be registered. Specific operations: https://router.vuejs.org/zh/
-</code></pre>
-<p><code>store</code> =&gt; status management</p>
-<pre><code>The page corresponding to each route has a state management file divided into:
-
-actions =&gt; mapActions =&gt; Details:https://vuex.vuejs.org/zh/guide/actions.html
-
-getters =&gt; mapGetters =&gt; Details:https://vuex.vuejs.org/zh/guide/getters.html
-
-index =&gt; entrance
-
-mutations =&gt; mapMutations =&gt; Details:https://vuex.vuejs.org/zh/guide/mutations.html
-
-state =&gt; mapState =&gt; Details:https://vuex.vuejs.org/zh/guide/state.html
-
-Specific action:https://vuex.vuejs.org/zh/
-</code></pre>
-<h2>specification</h2>
-<h2>Vue specification</h2>
-<h5>1.Component name</h5>
-<p>The component is named multiple words and is connected with a wire (-) to avoid conflicts with HTML tags and a clearer structure.</p>
-<pre><code>// positive example
-export default {
-    name: 'page-article-item'
-}
-</code></pre>
-<h5>2.Component files</h5>
-<p>The internal common component of the <code>src/js/module/components</code> project writes the folder name with the same name as the file name. The subcomponents and util tools that are split inside the common component are placed in the internal <code>_source</code> folder of the component.</p>
-<pre><code>└── components
-    ├── header
-        ├── header.vue
-        └── _source
-            └── nav.vue
-            └── util.js
-    ├── conditions
-        ├── conditions.vue
-        └── _source
-            └── search.vue
-            └── util.js
-</code></pre>
-<h5>3.Prop</h5>
-<p>When you define Prop, you should always name it in camel format (camelCase) and use the connection line (-) when assigning values to the parent component.
-This follows the characteristics of each language, because it is case-insensitive in HTML tags, and the use of links is more friendly; in JavaScript, the more natural is the hump name.</p>
-<pre><code>// Vue
-props: {
-    articleStatus: Boolean
-}
-// HTML
-&lt;article-item :article-status=&quot;true&quot;&gt;&lt;/article-item&gt;
-</code></pre>
-<p>The definition of Prop should specify its type, defaults, and validation as much as possible.</p>
-<p>Example:</p>
-<pre><code>props: {
-    attrM: Number,
-    attrA: {
-        type: String,
-        required: true
-    },
-    attrZ: {
-        type: Object,
-        //  The default value of the array/object should be returned by a factory function
-        default: function () {
-            return {
-                msg: 'achieve you and me'
-            }
-        }
-    },
-    attrE: {
-        type: String,
-        validator: function (v) {
-            return !(['success', 'fail'].indexOf(v) === -1) 
-        }
-    }
-}
-</code></pre>
-<h5>4.v-for</h5>
-<p>When performing v-for traversal, you should always bring a key value to make rendering more efficient when updating the DOM.</p>
-<pre><code>&lt;ul&gt;
-    &lt;li v-for=&quot;item in list&quot; :key=&quot;item.id&quot;&gt;
-        {{ item.title }}
-    &lt;/li&gt;
-&lt;/ul&gt;
-</code></pre>
-<p>v-for should be avoided on the same element as v-if (<code>for example: &lt;li&gt;</code>) because v-for has a higher priority than v-if. To avoid invalid calculations and rendering, you should try to use v-if Put it on top of the container's parent element.</p>
-<pre><code>&lt;ul v-if=&quot;showList&quot;&gt;
-    &lt;li v-for=&quot;item in list&quot; :key=&quot;item.id&quot;&gt;
-        {{ item.title }}
-    &lt;/li&gt;
-&lt;/ul&gt;
-</code></pre>
-<h5>5.v-if / v-else-if / v-else</h5>
-<p>If the elements in the same set of v-if logic control are logically identical, Vue reuses the same part for more efficient element switching, <code>such as: value</code>. In order to avoid the unreasonable effect of multiplexing, you should add key to the same element for identification.</p>
-<pre><code>&lt;div v-if=&quot;hasData&quot; key=&quot;mazey-data&quot;&gt;
-    &lt;span&gt;{{ mazeyData }}&lt;/span&gt;
-&lt;/div&gt;
-&lt;div v-else key=&quot;mazey-none&quot;&gt;
-    &lt;span&gt;no data&lt;/span&gt;
-&lt;/div&gt;
-</code></pre>
-<h5>6.Instruction abbreviation</h5>
-<p>In order to unify the specification, the instruction abbreviation is always used. Using <code>v-bind</code>, <code>v-on</code> is not bad. Here is only a unified specification.</p>
-<pre><code>&lt;input :value=&quot;mazeyUser&quot; @click=&quot;verifyUser&quot;&gt;
-</code></pre>
-<h5>7.Top-level element order of single file components</h5>
-<p>Styles are packaged in a file, all the styles defined in a single vue file, the same name in other files will also take effect. All will have a top class name before creating a component.
-Note: The sass plugin has been added to the project, and the sas syntax can be written directly in a single vue file.
-For uniformity and ease of reading, they should be placed in the order of  <code>&lt;template&gt;</code>、<code>&lt;script&gt;</code>、<code>&lt;style&gt;</code>.</p>
-<pre><code>&lt;template&gt;
-  &lt;div class=&quot;test-model&quot;&gt;
-    test
-  &lt;/div&gt;
-&lt;/template&gt;
-&lt;script&gt;
-  export default {
-    name: &quot;test&quot;,
-    data() {
-      return {}
-    },
-    props: {},
-    methods: {},
-    watch: {},
-    beforeCreate() {
-    },
-    created() {
-    },
-    beforeMount() {
-    },
-    mounted() {
-    },
-    beforeUpdate() {
-    },
-    updated() {
-    },
-    beforeDestroy() {
-    },
-    destroyed() {
-    },
-    computed: {},
-    components: {},
-  }
-&lt;/script&gt;
-
-&lt;style lang=&quot;scss&quot; rel=&quot;stylesheet/scss&quot;&gt;
-  .test-model {
-
-  }
-&lt;/style&gt;
-
-</code></pre>
-<h2>JavaScript specification</h2>
-<h5>1.var / let / const</h5>
-<p>It is recommended to no longer use var, but use let / const, prefer const. The use of any variable must be declared in advance, except that the function defined by function can be placed anywhere.</p>
-<h5>2.quotes</h5>
-<pre><code>const foo = 'after division'
-const bar = `${foo},ront-end engineer`
-</code></pre>
-<h5>3.function</h5>
-<p>Anonymous functions use the arrow function uniformly. When multiple parameters/return values are used, the object's structure assignment is used first.</p>
-<pre><code>function getPersonInfo ({name, sex}) {
-    // ...
-    return {name, gender}
-}
-</code></pre>
-<p>The function name is uniformly named with a camel name. The beginning of the capital letter is a constructor. The lowercase letters start with ordinary functions, and the new operator should not be used to operate ordinary functions.</p>
-<h5>4.object</h5>
-<pre><code>const foo = {a: 0, b: 1}
-const bar = JSON.parse(JSON.stringify(foo))
-
-const foo = {a: 0, b: 1}
-const bar = {...foo, c: 2}
-
-const foo = {a: 3}
-Object.assign(foo, {b: 4})
-
-const myMap = new Map([])
-for (let [key, value] of myMap.entries()) {
-    // ...
-}
-</code></pre>
-<h5>5.module</h5>
-<p>Unified management of project modules using import / export.</p>
-<pre><code>// lib.js
-export default {}
-
-// app.js
-import app from './lib'
-</code></pre>
-<p>Import is placed at the top of the file.</p>
-<p>If the module has only one output value, use <code>export default</code>,otherwise no.</p>
-<h2>HTML / CSS</h2>
-<h5>1.Label</h5>
-<p>Do not write the type attribute when referencing external CSS or JavaScript. The HTML5 default type is the text/css and text/javascript properties, so there is no need to specify them.</p>
-<pre><code>&lt;link rel=&quot;stylesheet&quot; href=&quot;//www.test.com/css/test.css&quot;&gt;
-&lt;script src=&quot;//www.test.com/js/test.js&quot;&gt;&lt;/script&gt;
-</code></pre>
-<h5>2.Naming</h5>
-<p>The naming of Class and ID should be semantic, and you can see what you are doing by looking at the name; multiple words are connected by a link.</p>
-<pre><code>// positive example
-.test-header{
-    font-size: 20px;
-}
-</code></pre>
-<h5>3.Attribute abbreviation</h5>
-<p>CSS attributes use abbreviations as much as possible to improve the efficiency and ease of understanding of the code.</p>
-<pre><code>// counter example
-border-width: 1px;
-border-style: solid;
-border-color: #ccc;
-
-// positive example
-border: 1px solid #ccc;
-</code></pre>
-<h5>4.Document type</h5>
-<p>The HTML5 standard should always be used.</p>
-<pre><code>&lt;!DOCTYPE html&gt;
-</code></pre>
-<h5>5.Notes</h5>
-<p>A block comment should be written to a module file.</p>
-<pre><code>/**
-* @module mazey/api
-* @author Mazey &lt;mazey@mazey.net&gt;
-* @description test.
-* */
-</code></pre>
-<h2>interface</h2>
-<h5>All interfaces are returned as Promise</h5>
-<p>Note that non-zero is wrong for catching catch</p>
-<pre><code>const test = () =&gt; {
-  return new Promise((resolve, reject) =&gt; {
-    resolve({
-      a:1
-    })
-  })
-}
-
-// transfer
-test.then(res =&gt; {
-  console.log(res)
-  // {a:1}
-})
-</code></pre>
-<p>Normal return</p>
-<pre><code>{
-  code:0,
-  data:{}
-  msg:'success'
-}
-</code></pre>
-<p>Error return</p>
-<pre><code>{
-  code:10000, 
-  data:{}
-  msg:'failed'
-}
-</code></pre>
-<p>If the interface is a post request, the Content-Type defaults to application/x-www-form-urlencoded; if the Content-Type is changed to application/json,
-Interface parameter transfer needs to be changed to the following way</p>
-<pre><code>io.post('url', payload, null, null, { emulateJSON: false } res =&gt; {
-  resolve(res)
-}).catch(e =&gt; {
-  reject(e)
-})
-</code></pre>
-<h5>Related interface path</h5>
-<p>dag related interface <code>src/js/conf/home/store/dag/actions.js</code></p>
-<p>Data Source Center Related Interfaces  <code>src/js/conf/home/store/datasource/actions.js</code></p>
-<p>Project Management Related Interfaces <code>src/js/conf/home/store/projects/actions.js</code></p>
-<p>Resource Center Related Interfaces <code>src/js/conf/home/store/resource/actions.js</code></p>
-<p>Security Center Related Interfaces <code>src/js/conf/home/store/security/actions.js</code></p>
-<p>User Center Related Interfaces <code>src/js/conf/home/store/user/actions.js</code></p>
-<h2>Extended development</h2>
-<h5>1.Add node</h5>
-<p>(1) First place the icon icon of the node in the <code>src/js/conf/home/pages/dag/img</code>folder, and note the English name of the node defined by the <code>toolbar_${in the background. For example: SHELL}.png</code></p>
-<p>(2)  Find the <code>tasksType</code> object in <code>src/js/conf/home/pages/dag/_source/config.js</code> and add it to it.</p>
-<pre><code>'DEPENDENT': {  //  The background definition node type English name is used as the key value
-  desc: 'DEPENDENT',  // tooltip desc
-  color: '#2FBFD8'  // The color represented is mainly used for tree and gantt
-}
-</code></pre>
-<p>(3)  Add a <code>${node type (lowercase)}</code>.vue file in <code>src/js/conf/home/pages/dag/_source/formModel/tasks</code>. The contents of the components related to the current node are written here. Must belong to a node component must have a function _verification () After the verification is successful, the relevant data of the current component is thrown to the parent component.</p>
-<pre><code>/**
- * Verification
-*/
-  _verification () {
-    // datasource subcomponent verification
-    if (!this.$refs.refDs._verifDatasource()) {
-      return false
-    }
-
-    // verification function
-    if (!this.method) {
-      this.$message.warning(`${i18n.$t('Please enter method')}`)
-      return false
-    }
-
-    // localParams subcomponent validation
-    if (!this.$refs.refLocalParams._verifProp()) {
-      return false
-    }
-    // store
-    this.$emit('on-params', {
-      type: this.type,
-      datasource: this.datasource,
-      method: this.method,
-      localParams: this.localParams
-    })
-    return true
-  }
-</code></pre>
-<p>(4) Common components used inside the node component are under<code>_source</code>, and <code>commcon.js</code> is used to configure public data.</p>
-<h5>2.Increase the status type</h5>
-<p>(1) Find the <code>tasksState</code> object in <code>src/js/conf/home/pages/dag/_source/config.js</code> and add it to it.</p>
-<pre><code> 'WAITTING_DEPEND': {  // 'WAITTING_DEPEND': {  //Backend defines state type, frontend is used as key value
-  id: 11,  // front-end definition id is used as a sort
-  desc: `${i18n.$t('waiting for dependency')}`,  // tooltip desc
-  color: '#5101be',  // The color represented is mainly used for tree and gantt
-  icoUnicode: '&amp;#xe68c;',  // font icon
-  isSpin: false  // whether to rotate (requires code judgment)
-}
-</code></pre>
-<h5>3.Add the action bar tool</h5>
-<p>(1)  Find the <code>toolOper</code> object in <code>src/js/conf/home/pages/dag/_source/config.js</code> and add it to it.</p>
-<pre><code>{
-  code: 'pointer',  // tool identifier
-  icon: '&amp;#xe781;',  // tool icon
-  disable: disable,  // disable
-  desc: `${i18n.$t('Drag node and selected item')}`  // tooltip desc
-}
-</code></pre>
-<p>(2) Tool classes are returned as a constructor  <code>src/js/conf/home/pages/dag/_source/plugIn</code></p>
-<p><code>downChart.js</code>  =&gt;  dag image download processing</p>
-<p><code>dragZoom.js</code>  =&gt;  mouse zoom effect processing</p>
-<p><code>jsPlumbHandle.js</code>  =&gt;  drag and drop line processing</p>
-<p><code>util.js</code>  =&gt;   belongs to the <code>plugIn</code> tool class</p>
-<p>The operation is handled in the <code>src/js/conf/home/pages/dag/_source/dag.js</code> =&gt; <code>toolbarEvent</code> event.</p>
-<h5>3.Add a routing page</h5>
-<p>(1) First add a routing address<code>src/js/conf/home/router/index.js</code> in route management</p>
-<pre><code>routing address{
-  path: '/test',  // routing address
-  name: 'test',  // alias
-  component: resolve =&gt; require(['../pages/test/index'], resolve),  // route corresponding component entry file
-  meta: {
-    title: `${i18n.$t('test')} - EasyScheduler`  // title display
-  }
-},
-</code></pre>
-<p>(2)Create a <code>test</code> folder in <code>src/js/conf/home/pages</code> and create an <code>index.vue</code>entry file in the folder.</p>
-<pre><code>This will give you direct access to`http://localhost:8888/#/test`
-</code></pre>
-<h5>4.Increase the preset mailbox</h5>
-<p>Find the <code>src/lib/localData/email.js</code> startup and timed email address input to automatically pull down the match.</p>
-<pre><code>export default [&quot;test@analysys.com.cn&quot;,&quot;test1@analysys.com.cn&quot;,&quot;test3@analysys.com.cn&quot;]
-</code></pre>
-<h5>5.Authority management and disabled state processing</h5>
-<p>The permission gives the userType according to the backUser interface <code>getUserInfo</code> interface: <code>&quot;ADMIN_USER/GENERAL_USER&quot;</code>permission to control whether the page operation button is <code>disabled</code>.</p>
-<p>specific operation:<code>src/js/module/permissions/index.js</code></p>
-<p>disabled processing:<code>src/js/module/mixin/disabledState.js</code></p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/frontend-development.json b/en-us/docs/dev/user_doc/development/frontend-development.json
deleted file mode 100644
index f1781cb18..000000000
--- a/en-us/docs/dev/user_doc/development/frontend-development.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "frontend-development.md",
-  "__html": "<h1>Front-end development documentation</h1>\n<h3>Technical selection</h3>\n<pre><code>Vue mvvm framework\n\nEs6 ECMAScript 6.0\n\nAns-ui Analysys-ui\n\nD3  Visual Library Chart Library\n\nJsplumb connection plugin library\n\nLodash high performance JavaScript utility library\n</code></pre>\n<h3>Development environment</h3>\n<ul>\n<li>\n<h4>Node installation</h4>\n</li>\n</ul>\n<p>Node package download (note version v12.20.2) <code>https://nodejs.org/download/release/v12.20. [...]
-  "link": "/dist/en-us/docs/dev/user_doc/development/frontend-development.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/have-questions.html b/en-us/docs/dev/user_doc/development/have-questions.html
deleted file mode 100644
index 3eb7cc4d7..000000000
--- a/en-us/docs/dev/user_doc/development/have-questions.html
+++ /dev/null
@@ -1,97 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="have-questions">
-  <meta name="description" content="have-questions">
-  <title>have-questions</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 Have queries regarding Apache DolphinScheduler, Join Slack channel to disscuss them <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span> [...]
-<h2>StackOverflow</h2>
-<p>For usage questions, it is recommended you use the StackOverflow tag <a href="https://stackoverflow.com/questions/tagged/apache-dolphinscheduler">apache-dolphinscheduler</a> as it is an active forum for DolphinScheduler users’ questions and answers.</p>
-<p>Some quick tips when using StackOverflow:</p>
-<ul>
-<li>Prior to asking submitting questions, please:
-<ul>
-<li>Search StackOverflow’s <a href="https://stackoverflow.com/questions/tagged/apache-dolphinscheduler">apache-dolphinscheduler</a> tag to see if your question has already been answered</li>
-</ul>
-</li>
-<li>Please follow the StackOverflow <a href="https://stackoverflow.com/help/how-to-ask">code of conduct</a></li>
-<li>Always use the apache-dolphinscheduler tag when asking questions</li>
-<li>Please do not cross-post between <a href="https://stackoverflow.com/questions/tagged/apache-dolphinscheduler">StackOverflow</a> and <a href="https://github.com/apache/dolphinscheduler/issues/new/choose">GitHub issues</a></li>
-</ul>
-<p>Question template:</p>
-<blockquote>
-<p><strong>Describe the question</strong></p>
-<p>A clear and concise description of what the question is.</p>
-<p><strong>Which version of DolphinScheduler:</strong></p>
-<p>-[1.3.0-preview]</p>
-<p><strong>Additional context</strong></p>
-<p>Add any other context about the problem here.</p>
-<p><strong>Requirement or improvement</strong></p>
-<p>- Please describe about your requirements or improvement suggestions.</p>
-</blockquote>
-<p>For broad, opinion based, ask for external resources, debug issues, bugs, contributing to the project, and scenarios, it is recommended you use the<a href="https://github.com/apache/dolphinscheduler/issues/new/choose"> GitHub issues </a>or <a href="mailto:dev@dolphinscheduler.apache.org">dev@dolphinscheduler.apache.org</a> mailing list.</p>
-<h2>Mailing Lists</h2>
-<ul>
-<li><a href="https://lists.apache.org/list.html?dev@dolphinscheduler.apache.org">dev@dolphinscheduler.apache.org</a> is for people who want to contribute code to DolphinScheduler. <a href="mailto:dev-subscribe@dolphinscheduler.apache.org?subject=(send%20this%20email%20to%20subscribe)">(subscribe)</a> <a href="mailto:dev-unsubscribe@dolphinscheduler.apache.org?subject=(send%20this%20email%20to%20unsubscribe)">(unsubscribe)</a> <a href="http://lists.apache.org/list.html?dev@dolphinschedule [...]
-</ul>
-<p>Some quick tips when using email:</p>
-<ul>
-<li>
-<p>Prior to asking submitting questions, please:</p>
-<ul>
-<li>Search StackOverflow at <a href="https://stackoverflow.com/questions/tagged/apache-dolphinscheduler">apache-dolphinscheduler</a> to see if your question has already been answered</li>
-</ul>
-</li>
-<li>
-<p>Tagging the subject line of your email will help you get a faster response, e.g. [api-server]: How to get open api interface?</p>
-</li>
-<li>
-<p>Tags may help identify a topic by:</p>
-<ul>
-<li>Component: MasterServer,ApiServer,WorkerServer,AlertServer, etc</li>
-<li>Level: Beginner, Intermediate, Advanced</li>
-<li>Scenario: Debug, How-to</li>
-</ul>
-</li>
-<li>
-<p>For error logs or long code examples, please use <a href="https://gist.github.com/">GitHub gist</a> and include only a few lines of the pertinent code / log within the email.</p>
-</li>
-</ul>
-<h2>Chat Rooms</h2>
-<p>Chat rooms are great for quick questions or discussions on specialized topics.</p>
-<p>The following chat rooms are officially part of Apache DolphinScheduler:</p>
-<p>​	The Slack workspace URL: <a href="http://asf-dolphinscheduler.slack.com/">http://asf-dolphinscheduler.slack.com/</a>.</p>
-<p>​	You can join through invitation url: <a href="https://s.apache.org/dolphinscheduler-slack">https://s.apache.org/dolphinscheduler-slack</a>.</p>
-<p>This chat room is used for questions and discussions related to using DolphinScheduler.</p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/development/have-questions.json b/en-us/docs/dev/user_doc/development/have-questions.json
deleted file mode 100644
index 07f1c2612..000000000
--- a/en-us/docs/dev/user_doc/development/have-questions.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "have-questions.md",
-  "__html": "<h1>Have Questions?</h1>\n<h2>StackOverflow</h2>\n<p>For usage questions, it is recommended you use the StackOverflow tag <a href=\"https://stackoverflow.com/questions/tagged/apache-dolphinscheduler\">apache-dolphinscheduler</a> as it is an active forum for DolphinScheduler users’ questions and answers.</p>\n<p>Some quick tips when using StackOverflow:</p>\n<ul>\n<li>Prior to asking submitting questions, please:\n<ul>\n<li>Search StackOverflow’s <a href=\"https://stackoverfl [...]
-  "link": "/dist/en-us/docs/dev/user_doc/development/have-questions.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/en-us/docs/dev/user_doc/guide/alert/enterprise-wechat.html b/en-us/docs/dev/user_doc/guide/alert/enterprise-wechat.html
index 87d8c2e48..1db57ae7a 100644
--- a/en-us/docs/dev/user_doc/guide/alert/enterprise-wechat.html
+++ b/en-us/docs/dev/user_doc/guide/alert/enterprise-wechat.html
@@ -11,13 +11,44 @@
 </head>
 <body>
   <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 Have queries regarding Apache DolphinScheduler, Join Slack channel to disscuss them <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span> [...]
-<p>If you need to use <code>Enterprise WeChat</code> to alert, create an alert instance in the alert instance management, and choose the WeChat plugin.
+<p>If you need to use <code>Enterprise WeChat</code> to alert, create an alert instance in the alert instance management, and choose the <code>WeChat</code> plugin.
 The following is the <code>WeChat</code> configuration example:</p>
 <p><img src="/img/alert/enterprise-wechat-plugin.png" alt="enterprise-wechat-plugin"></p>
-<p>The parameter <code>send.type</code> corresponds to app and group chat respectively:</p>
+<h2>Send Type</h2>
+<p>The parameter <code>send.type</code> corresponds to sending messages to Enterprise WeChat customized APP and group chat created by API respectively.</p>
+<h3>APP</h3>
+<p>The APP sends type means to notify the alert results via Enterprise WeChat customized APPs, supports sending messages to both specified users and all members. Currently, send to specified enterprise department and tags are not supported, a new PR to contribute is welcomed.
+The following is the <code>APP</code> alert config example:</p>
+<p><img src="/img/alert/wechat-app-form-example.png" alt="enterprise-wechat-app-msg-config"></p>
+<p>The following is the <code>APP</code> <code>MARKDOWN</code> alert message example:</p>
+<p><img src="/img/alert/enterprise-wechat-app-msg-md.png" alt="enterprise-wechat-app-msg-markdown"></p>
+<p>The following is the <code>APP</code> <code>TEXT</code> alert message example:</p>
+<p><img src="/img/alert/enterprise-wechat-app-msg.png" alt="enterprise-wechat-app-msg-text"></p>
+<h4>Prerequisites</h4>
+<p>Need to create a new customized APP in Enterprise WeChat before sending messages to APP, create at the <a href="https://work.weixin.qq.com/wework_admin/frame#apps">APP Page</a> and acquire the APP <code>AgentId</code> and set its visible scope to the root of the hierarchy.</p>
+<h4>Send Messages to Specified Users</h4>
+<p>The Enterprise WeChat APPs support sending messages to both specified users and all members, using <code>|</code> to separate multiple <code>userIds</code> and using <code>@all</code> to send messages to everyone.
+To acquire user <code>userId</code> refer to <a href="https://developer.work.weixin.qq.com/document/path/95402">Official Doc</a>, acquire <code>userId</code> by user phone number.
+The following is the <code>query userId</code> API example:</p>
+<p><img src="/img/alert/enterprise-wechat-query-userid.png" alt="enterprise-wechat-create-group"></p>
+<h4>References</h4>
 <p>APP: <a href="https://work.weixin.qq.com/api/doc/90000/90135/90236">https://work.weixin.qq.com/api/doc/90000/90135/90236</a></p>
-<p>Group Chat: <a href="https://work.weixin.qq.com/api/doc/90000/90135/90248">https://work.weixin.qq.com/api/doc/90000/90135/90248</a></p>
-<p>The parameter <code>user.send.msg</code> corresponds to the <code>content</code> in the document, and the corresponding variable is <code>{msg}</code>.</p>
+<h3>Group Chat</h3>
+<p>The Group Chat send type means to notify the alert results via group chat created by Enterprise WeChat API, sending messages to all members of the group and specified users are not supported.
+The following is the <code>Group Chat</code> alert config example:</p>
+<p><img src="/img/alert/wechat-group-form-example.png" alt="enterprise-wechat-app-msg-config"></p>
+<p>The following is the <code>APP</code> <code>MARKDOWN</code> alert message example:</p>
+<p><img src="/img/alert/enterprise-wechat-group-msg-md.png" alt="enterprise-wechat-group-msg-markdown"></p>
+<p>The following is the <code>Group Chat</code> <code>TEXT</code> alert message example:</p>
+<p><img src="/img/alert/enterprise-wechat-group-msg.png" alt="enterprise-wechat-group-msg-text"></p>
+<h4>Prerequisites</h4>
+<p>Before sending messages to group chat, create a new group chat by Enterprise WeChat API, refer to <a href="https://developer.work.weixin.qq.com/document/path/90245">Official Doc</a> to create a new one and acquire <code>chatid</code>.
+To acquire user <code>userId</code> refer to <a href="https://developer.work.weixin.qq.com/document/path/95402">Official Doc</a>, acquire <code>userId</code> by user phone number.
+The following is the <code>create new group chat</code> API and <code>query userId</code> API example:</p>
+<p><img src="/img/alert/enterprise-wechat-create-group.png" alt="enterprise-wechat-create-group"></p>
+<p><img src="/img/alert/enterprise-wechat-query-userid.png" alt="enterprise-wechat-create-group"></p>
+<h4>References</h4>
+<p>Group Chat:<a href="https://work.weixin.qq.com/api/doc/90000/90135/90248">https://work.weixin.qq.com/api/doc/90000/90135/90248</a></p>
 </div></section><footer class="footer-container"><div class="footer-body"><div><h3>About us</h3><h4>Do you need feedback? Please contact us through the following ways.</h4></div><div class="contact-container"><ul><li><a href="/en-us/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>Email List</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png [...]
   <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
   <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
diff --git a/en-us/docs/dev/user_doc/guide/alert/enterprise-wechat.json b/en-us/docs/dev/user_doc/guide/alert/enterprise-wechat.json
index f03a25505..029ebed8d 100644
--- a/en-us/docs/dev/user_doc/guide/alert/enterprise-wechat.json
+++ b/en-us/docs/dev/user_doc/guide/alert/enterprise-wechat.json
@@ -1,6 +1,6 @@
 {
   "filename": "enterprise-wechat.md",
-  "__html": "<h1>Enterprise WeChat</h1>\n<p>If you need to use <code>Enterprise WeChat</code> to alert, create an alert instance in the alert instance management, and choose the WeChat plugin.\nThe following is the <code>WeChat</code> configuration example:</p>\n<p><img src=\"/img/alert/enterprise-wechat-plugin.png\" alt=\"enterprise-wechat-plugin\"></p>\n<p>The parameter <code>send.type</code> corresponds to app and group chat respectively:</p>\n<p>APP: <a href=\"https://work.weixin.qq. [...]
+  "__html": "<h1>Enterprise WeChat</h1>\n<p>If you need to use <code>Enterprise WeChat</code> to alert, create an alert instance in the alert instance management, and choose the <code>WeChat</code> plugin.\nThe following is the <code>WeChat</code> configuration example:</p>\n<p><img src=\"/img/alert/enterprise-wechat-plugin.png\" alt=\"enterprise-wechat-plugin\"></p>\n<h2>Send Type</h2>\n<p>The parameter <code>send.type</code> corresponds to sending messages to Enterprise WeChat customiz [...]
   "link": "/dist/en-us/docs/dev/user_doc/guide/alert/enterprise-wechat.html",
   "meta": {}
 }
\ No newline at end of file
diff --git a/img/alert/enterprise-wechat-app-msg-md.png b/img/alert/enterprise-wechat-app-msg-md.png
new file mode 100644
index 000000000..6503e0eb8
Binary files /dev/null and b/img/alert/enterprise-wechat-app-msg-md.png differ
diff --git a/img/alert/enterprise-wechat-app-msg.png b/img/alert/enterprise-wechat-app-msg.png
new file mode 100644
index 000000000..d43917134
Binary files /dev/null and b/img/alert/enterprise-wechat-app-msg.png differ
diff --git a/img/alert/enterprise-wechat-create-group.png b/img/alert/enterprise-wechat-create-group.png
new file mode 100644
index 000000000..3e7d304f3
Binary files /dev/null and b/img/alert/enterprise-wechat-create-group.png differ
diff --git a/img/alert/enterprise-wechat-group-msg-md.png b/img/alert/enterprise-wechat-group-msg-md.png
new file mode 100644
index 000000000..3fb5da33c
Binary files /dev/null and b/img/alert/enterprise-wechat-group-msg-md.png differ
diff --git a/img/alert/enterprise-wechat-group-msg.png b/img/alert/enterprise-wechat-group-msg.png
new file mode 100644
index 000000000..39830bd31
Binary files /dev/null and b/img/alert/enterprise-wechat-group-msg.png differ
diff --git a/img/alert/enterprise-wechat-query-userid.png b/img/alert/enterprise-wechat-query-userid.png
new file mode 100644
index 000000000..a7fb3b50b
Binary files /dev/null and b/img/alert/enterprise-wechat-query-userid.png differ
diff --git a/img/alert/wechat-app-form-example.png b/img/alert/wechat-app-form-example.png
new file mode 100644
index 000000000..d425da784
Binary files /dev/null and b/img/alert/wechat-app-form-example.png differ
diff --git a/img/alert/wechat-group-form-example.png b/img/alert/wechat-group-form-example.png
new file mode 100644
index 000000000..c289ebc95
Binary files /dev/null and b/img/alert/wechat-group-form-example.png differ
diff --git a/img/architecture-design/dag_examples_ch_zn.png b/img/architecture-design/dag_examples_ch_zn.png
deleted file mode 100644
index 95134b33c..000000000
Binary files a/img/architecture-design/dag_examples_ch_zn.png and /dev/null differ
diff --git a/img/architecture-design/dag_examples_en_us.png b/img/architecture-design/dag_examples_en_us.png
deleted file mode 100644
index 15848da71..000000000
Binary files a/img/architecture-design/dag_examples_en_us.png and /dev/null differ
diff --git a/img/architecture-design/distributed_lock_ch_zn.png b/img/architecture-design/distributed_lock_ch_zn.png
deleted file mode 100644
index f2e233728..000000000
Binary files a/img/architecture-design/distributed_lock_ch_zn.png and /dev/null differ
diff --git a/img/architecture-design/distributed_lock_en_us.png b/img/architecture-design/distributed_lock_en_us.png
deleted file mode 100644
index 5c34fc429..000000000
Binary files a/img/architecture-design/distributed_lock_en_us.png and /dev/null differ
diff --git a/img/architecture-design/distributed_lock_procss_ch_zn.png b/img/architecture-design/distributed_lock_procss_ch_zn.png
deleted file mode 100644
index 78b87dfc8..000000000
Binary files a/img/architecture-design/distributed_lock_procss_ch_zn.png and /dev/null differ
diff --git a/img/architecture-design/distributed_lock_procss_en_us.png b/img/architecture-design/distributed_lock_procss_en_us.png
deleted file mode 100644
index 469128bc1..000000000
Binary files a/img/architecture-design/distributed_lock_procss_en_us.png and /dev/null differ
diff --git a/img/architecture-design/fault-tolerant_ch_zn.png b/img/architecture-design/fault-tolerant_ch_zn.png
deleted file mode 100644
index 5da473c9b..000000000
Binary files a/img/architecture-design/fault-tolerant_ch_zn.png and /dev/null differ
diff --git a/img/architecture-design/fault-tolerant_en_us.png b/img/architecture-design/fault-tolerant_en_us.png
deleted file mode 100644
index 45dadf76e..000000000
Binary files a/img/architecture-design/fault-tolerant_en_us.png and /dev/null differ
diff --git a/img/architecture-design/fault-tolerant_master_ch_zn.png b/img/architecture-design/fault-tolerant_master_ch_zn.png
deleted file mode 100644
index 56c350062..000000000
Binary files a/img/architecture-design/fault-tolerant_master_ch_zn.png and /dev/null differ
diff --git a/img/architecture-design/fault-tolerant_master_en_us.png b/img/architecture-design/fault-tolerant_master_en_us.png
deleted file mode 100644
index a9901ce73..000000000
Binary files a/img/architecture-design/fault-tolerant_master_en_us.png and /dev/null differ
diff --git a/img/architecture-design/fault-tolerant_worker_ch_zn.png b/img/architecture-design/fault-tolerant_worker_ch_zn.png
deleted file mode 100644
index c8b5cd543..000000000
Binary files a/img/architecture-design/fault-tolerant_worker_ch_zn.png and /dev/null differ
diff --git a/img/architecture-design/fault-tolerant_worker_en_us.png b/img/architecture-design/fault-tolerant_worker_en_us.png
deleted file mode 100644
index e7f379d1f..000000000
Binary files a/img/architecture-design/fault-tolerant_worker_en_us.png and /dev/null differ
diff --git a/img/architecture-design/grpc_en_us.png b/img/architecture-design/grpc_en_us.png
deleted file mode 100644
index 633b83756..000000000
Binary files a/img/architecture-design/grpc_en_us.png and /dev/null differ
diff --git a/img/architecture-design/lack_thread_ch_zn.png b/img/architecture-design/lack_thread_ch_zn.png
deleted file mode 100644
index 31263cd27..000000000
Binary files a/img/architecture-design/lack_thread_ch_zn.png and /dev/null differ
diff --git a/img/architecture-design/lack_thread_en_us.png b/img/architecture-design/lack_thread_en_us.png
deleted file mode 100644
index 0dc5a7b13..000000000
Binary files a/img/architecture-design/lack_thread_en_us.png and /dev/null differ
diff --git a/img/architecture-design/process_priority_en_us.png b/img/architecture-design/process_priority_en_us.png
deleted file mode 100644
index c6cd6001a..000000000
Binary files a/img/architecture-design/process_priority_en_us.png and /dev/null differ
diff --git a/img/architecture-design/task_priority_en_us.png b/img/architecture-design/task_priority_en_us.png
deleted file mode 100644
index 347026071..000000000
Binary files a/img/architecture-design/task_priority_en_us.png and /dev/null differ
diff --git a/img/architecture-en.jpg b/img/architecture-en.jpg
deleted file mode 100644
index cbefda24a..000000000
Binary files a/img/architecture-en.jpg and /dev/null differ
diff --git a/img/tasks/demo/shell.jpg b/img/tasks/demo/shell.jpg
index 3a0118469..1c5e2f5e1 100644
Binary files a/img/tasks/demo/shell.jpg and b/img/tasks/demo/shell.jpg differ
diff --git a/img/tasks/demo/shell_custom_param.jpg b/img/tasks/demo/shell_custom_param.jpg
index c52b0d14f..6dd45a638 100644
Binary files a/img/tasks/demo/shell_custom_param.jpg and b/img/tasks/demo/shell_custom_param.jpg differ
diff --git a/zh-cn/community/join/review.html b/zh-cn/community/join/review.html
index 936e91be3..41010dabd 100644
--- a/zh-cn/community/join/review.html
+++ b/zh-cn/community/join/review.html
@@ -183,6 +183,7 @@ review 社区的 Issues 或者 Pull Requests。通过别人 Issues 和 Pull Requ
 但只要你有 GitHub 账号就能评论 Issue,并给出建议。我们鼓励社区每人都去评论并为 Issue 给出解答</p>
 </blockquote>
 <h3>Pull Requests</h3>
+<!-- markdown-link-check-disable -->
 <p>Review Pull 是指在 GitHub 中参与 <a href="https://github.com/apache/dolphinscheduler/pulls">Pull Requests</a> 的讨论,并在对应的 Pull Requests 给出建议。DolphinScheduler review
 Pull Requests 与 <a href="https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/about-pull-request-reviews">GitHub 的 reviewing changes in pull requests</a> 一样。你可以为 Pull Requests 提出自己的看法,</p>
 <ul>
@@ -192,6 +193,7 @@ approve 流程同意这个 Pull Requests。</li>
 流程评论这个 Pull Requests。当你认为存在一定要先修复才能合并的问题,请参照 <a href="https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/about-pull-request-reviews">GitHub 的 reviewing changes in pull requests</a>
 的 Request changes 流程要求贡献者修改 Pull Requests 的内容。</li>
 </ul>
+<!-- markdown-link-check-enable -->
 <p>为 Pull Requests 打上标签也是非常重要的一个环节,合理的分类能为后来的 reviewer 节省大量的时间。值得高兴的是,Pull Requests 的标签和 <a href="#issues">Issues</a>
 中提及的标签和用法是一致的,这能减少 reviewer 对标签的记忆。例如这个 Pull Requests 是和 docker 并且直接影响到用户部署的,我们可以为他
 打上 <a href="https://github.com/apache/dolphinscheduler/labels/docker">docker</a> 和 <a href="https://github.com/apache/dolphinscheduler/labels/priority%3Ahigh">priority:high</a> 的标签。</p>
diff --git a/zh-cn/community/join/review.json b/zh-cn/community/join/review.json
index 3ae98028b..f517c751f 100644
--- a/zh-cn/community/join/review.json
+++ b/zh-cn/community/join/review.json
@@ -1,6 +1,6 @@
 {
   "filename": "review.md",
-  "__html": "<h1>参与社区 review</h1>\n<p>贡献 DolphinScheduler 的方式,除了向 <a href=\"../team.md\">团队</a> 中提到的 GitHub 仓库提交 Issues 和 pull requests 外,另一非常重要的方式是\nreview 社区的 Issues 或者 Pull Requests。通过别人 Issues 和 Pull Requests,你不仅能知道社区的最新进展和发展方向,还能了解别人代码的设\n计思想,同时可以增加自己在社区的曝光、积累自己在社区的荣誉值。</p>\n<p>任何人都被鼓励去 review 社区的  Issues 和 Pull Requests。我们还曾经发起过一个 Help Wanted 的邮件讨论,向社区征求贡献者协助 review Issues\n以及 Pull Requests,详见 <a href=\"https://lists.apache.org/thread/9flwlzrp69xjn6v8tdkbytq8glqp2k51\">邮件</a>,并将其结果 [...]
+  "__html": "<h1>参与社区 review</h1>\n<p>贡献 DolphinScheduler 的方式,除了向 <a href=\"../team.md\">团队</a> 中提到的 GitHub 仓库提交 Issues 和 pull requests 外,另一非常重要的方式是\nreview 社区的 Issues 或者 Pull Requests。通过别人 Issues 和 Pull Requests,你不仅能知道社区的最新进展和发展方向,还能了解别人代码的设\n计思想,同时可以增加自己在社区的曝光、积累自己在社区的荣誉值。</p>\n<p>任何人都被鼓励去 review 社区的  Issues 和 Pull Requests。我们还曾经发起过一个 Help Wanted 的邮件讨论,向社区征求贡献者协助 review Issues\n以及 Pull Requests,详见 <a href=\"https://lists.apache.org/thread/9flwlzrp69xjn6v8tdkbytq8glqp2k51\">邮件</a>,并将其结果 [...]
   "link": "/dist/zh-cn/community/join/review.html",
   "meta": {}
 }
\ No newline at end of file
diff --git a/zh-cn/development/architecture-design.html b/zh-cn/development/architecture-design.html
index 0a853d3b2..0b8323a0a 100644
--- a/zh-cn/development/architecture-design.html
+++ b/zh-cn/development/architecture-design.html
@@ -15,7 +15,7 @@
 <h3>1.名词解释</h3>
 <p><strong>DAG:</strong> 全称Directed Acyclic Graph,简称DAG。工作流中的Task任务以有向无环图的形式组装起来,从入度为零的节点进行拓扑遍历,直到无后继节点为止。举例如下图:</p>
 <p align="center">
-  <img src="/img/architecture-design/dag_examples_ch_zn.png" alt="dag示例"  width="80%" />
+  <img src="/img/architecture-design/dag_examples.png" alt="dag示例"  width="80%" />
   <p align="center">
         <em>dag示例</em>
   </p>
@@ -132,13 +132,13 @@ MasterServer服务启动时向Zookeeper注册临时节点,通过监听Zookeepe
 <li>获取分布式锁的核心流程算法如下</li>
 </ol>
  <p align="center">
-   <img src="/img/architecture-design/distributed_lock_ch_zn.png" alt="获取分布式锁流程"  width="70%" />
+   <img src="/img/architecture-design/distributed_lock.png" alt="获取分布式锁流程"  width="70%" />
  </p>
 <ol start="2">
 <li>DolphinScheduler中Scheduler线程分布式锁实现流程图:</li>
 </ol>
  <p align="center">
-   <img src="/img/architecture-design/distributed_lock_procss_ch_zn.png" alt="获取分布式锁流程" />
+   <img src="/img/architecture-design/distributed_lock_procss.png" alt="获取分布式锁流程" />
  </p>
 <h5>三、线程不足循环等待问题</h5>
 <ul>
@@ -146,7 +146,7 @@ MasterServer服务启动时向Zookeeper注册临时节点,通过监听Zookeepe
 <li>如果一个大的DAG中嵌套了很多子流程,如下图则会产生“死等”状态:</li>
 </ul>
  <p align="center">
-   <img src="/img/architecture-design/lack_thread_ch_zn.png" alt="线程不足循环等待问题"  width="70%" />
+   <img src="/img/architecture-design/lack_thread.png" alt="线程不足循环等待问题"  width="70%" />
  </p>
 上图中MainFlowThread等待SubFlowThread1结束,SubFlowThread1等待SubFlowThread2结束, SubFlowThread2等待SubFlowThread3结束,而SubFlowThread3等待线程池有新线程,则整个DAG流程不能结束,从而其中的线程也不能释放。这样就形成的子父流程循环等待的状态。此时除非启动新的Master来增加线程来打破这样的”僵局”,否则调度集群将不能再使用。
 <p>对于启动新Master来打破僵局,似乎有点差强人意,于是我们提出了以下三种方案来降低这种风险:</p>
@@ -162,21 +162,21 @@ MasterServer服务启动时向Zookeeper注册临时节点,通过监听Zookeepe
 <h6>1. 宕机容错</h6>
 <p>服务容错设计依赖于ZooKeeper的Watcher机制,实现原理如图:</p>
  <p align="center">
-   <img src="/img/architecture-design/fault-tolerant_ch_zn.png" alt="DolphinScheduler容错设计"  width="70%" />
+   <img src="/img/architecture-design/fault-tolerant.png" alt="DolphinScheduler容错设计"  width="70%" />
  </p>
 其中Master监控其他Master和Worker的目录,如果监听到remove事件,则会根据具体的业务逻辑进行流程实例容错或者任务实例容错。
 <ul>
 <li>Master容错流程图:</li>
 </ul>
  <p align="center">
-   <img src="/img/architecture-design/fault-tolerant_master_ch_zn.png" alt="Master容错流程图"  width="70%" />
+   <img src="/img/architecture-design/fault-tolerant_master.png" alt="Master容错流程图"  width="70%" />
  </p>
 ZooKeeper Master容错完成之后则重新由DolphinScheduler中Scheduler线程调度,遍历 DAG 找到”正在运行”和“提交成功”的任务,对”正在运行”的任务监控其任务实例的状态,对”提交成功”的任务需要判断Task Queue中是否已经存在,如果存在则同样监控任务实例的状态,如果不存在则重新提交任务实例。
 <ul>
 <li>Worker容错流程图:</li>
 </ul>
  <p align="center">
-   <img src="/img/architecture-design/fault-tolerant_worker_ch_zn.png" alt="Worker容错流程图"  width="70%" />
+   <img src="/img/architecture-design/fault-tolerant_worker.png" alt="Worker容错流程图"  width="70%" />
  </p>
 <p>Master Scheduler线程一旦发现任务实例为” 需要容错”状态,则接管任务并进行重新提交。</p>
 <p>注意:由于” 网络抖动”可能会使得节点短时间内失去和ZooKeeper的心跳,从而发生节点的remove事件。对于这种情况,我们使用最简单的方式,那就是节点一旦和ZooKeeper发生超时连接,则直接将Master或Worker服务停掉。</p>
diff --git a/zh-cn/development/architecture-design.json b/zh-cn/development/architecture-design.json
index b4b4e7c76..56431a5bb 100644
--- a/zh-cn/development/architecture-design.json
+++ b/zh-cn/development/architecture-design.json
@@ -1,6 +1,6 @@
 {
   "filename": "architecture-design.md",
-  "__html": "<h2>系统架构设计</h2>\n<p>在对调度系统架构说明之前,我们先来认识一下调度系统常用的名词</p>\n<h3>1.名词解释</h3>\n<p><strong>DAG:</strong> 全称Directed Acyclic Graph,简称DAG。工作流中的Task任务以有向无环图的形式组装起来,从入度为零的节点进行拓扑遍历,直到无后继节点为止。举例如下图:</p>\n<p align=\"center\">\n  <img src=\"/img/architecture-design/dag_examples_ch_zn.png\" alt=\"dag示例\"  width=\"80%\" />\n  <p align=\"center\">\n        <em>dag示例</em>\n  </p>\n</p>\n<p><strong>流程定义</strong>:通过拖拽任务节点并建立任务节点的关联所形成的可视化<strong>DAG</strong></p>\n<p><strong>流程实例</strong>:流程实例是流程 [...]
+  "__html": "<h2>系统架构设计</h2>\n<p>在对调度系统架构说明之前,我们先来认识一下调度系统常用的名词</p>\n<h3>1.名词解释</h3>\n<p><strong>DAG:</strong> 全称Directed Acyclic Graph,简称DAG。工作流中的Task任务以有向无环图的形式组装起来,从入度为零的节点进行拓扑遍历,直到无后继节点为止。举例如下图:</p>\n<p align=\"center\">\n  <img src=\"/img/architecture-design/dag_examples.png\" alt=\"dag示例\"  width=\"80%\" />\n  <p align=\"center\">\n        <em>dag示例</em>\n  </p>\n</p>\n<p><strong>流程定义</strong>:通过拖拽任务节点并建立任务节点的关联所形成的可视化<strong>DAG</strong></p>\n<p><strong>流程实例</strong>:流程实例是流程定义的实例化 [...]
   "link": "/dist/zh-cn/development/architecture-design.html",
   "meta": {}
 }
\ No newline at end of file
diff --git a/zh-cn/development/e2e-test.html b/zh-cn/development/e2e-test.html
index 93cc0e3e3..e4b87b298 100644
--- a/zh-cn/development/e2e-test.html
+++ b/zh-cn/development/e2e-test.html
@@ -95,7 +95,7 @@
         <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> UnsupportedOperationException(<span class="hljs-string">&quot;Unknown tab: &quot;</span> + tab.getName());
     }
 </code></pre>
-<p><img src="../../img/e2e-test/SecurityPage.png" alt="SecurityPage"></p>
+<p><img src="/img/e2e-test/SecurityPage.png" alt="SecurityPage"></p>
 <p>对于导航栏选项的跳转,在<code>org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java</code> 中提供了 goToNav 的方法。当前支持的页面为:项目管理(ProjectPage)、安全中心(SecurityPage)和资源中心(ResourcePage)。</p>
 <pre><code class="language-java">    <span class="hljs-keyword">public</span> &lt;T extends NavBarItem&gt; <span class="hljs-function">T <span class="hljs-title">goToNav</span><span class="hljs-params">(Class&lt;T&gt; nav)</span> </span>{
         <span class="hljs-keyword">if</span> (nav == ProjectPage.class) {
@@ -124,7 +124,7 @@
 </code></pre>
 <h3>2、E2E-Cases</h3>
 <p>当前所支持的 E2E 测试案例,主要包括:文件管理、项目管理、队列管理、租户管理、用户管理、Worker 分组管理和工作流测试。</p>
-<p><img src="../../img/e2e-test/E2E_Cases.png" alt="E2E_Cases"></p>
+<p><img src="/img/e2e-test/E2E_Cases.png" alt="E2E_Cases"></p>
 <p>下面以租户管理测试为例,前文已经说明,我们使用 docker-compose 进行部署,所以每个测试案例,都需要以注解的形式引入对应的文件。</p>
 <p>使用 Selenium 所提供的 RemoteWebDriver 来加载浏览器。在每个测试案例开始之前都需要进行一些准备工作。比如:登录用户、跳转到对应的页面(根据具体的测试案例而定)。</p>
 <pre><code class="language-java">    <span class="hljs-meta">@BeforeAll</span>
@@ -155,11 +155,11 @@
 <p>在本地运行的时候,首先需要启动相应的本地服务,可以参考该页面: <a href="https://dolphinscheduler.apache.org/zh-cn/development/development-environment-setup.html">环境搭建</a></p>
 <p>在本地运行 E2E 测试的时候,可以配置 <code>-Dlocal=true</code> 参数,用于连接本地,方便对于 UI 界面的更改。</p>
 <p>如果是<code>M1</code>芯片的机器,可以使用<code>-Dm1_chip=true</code> 参数,用于配置使用<code>ARM64</code>支持的容器。</p>
-<p><img src="../../img/e2e-test/Dlocal.png" alt="Dlocal"></p>
+<p><img src="/img/e2e-test/Dlocal.png" alt="Dlocal"></p>
 <p>在本地运行过程中,如果出现连接超时,可增大加载时间,建议 30 及其以上。</p>
-<p><img src="../../img/e2e-test/timeout.png" alt="timeout"></p>
+<p><img src="/img/e2e-test/timeout.png" alt="timeout"></p>
 <p>测试的运行过程将会以 MP4 的文件格式存在。</p>
-<p><img src="../../img/e2e-test/MP4.png" alt="MP4"></p>
+<p><img src="/img/e2e-test/MP4.png" alt="MP4"></p>
 </div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
   <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
   <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
diff --git a/zh-cn/development/e2e-test.json b/zh-cn/development/e2e-test.json
index 6d81f58bb..48c9f6d20 100644
--- a/zh-cn/development/e2e-test.json
+++ b/zh-cn/development/e2e-test.json
@@ -1,6 +1,6 @@
 {
   "filename": "e2e-test.md",
-  "__html": "<h1>DolphinScheduler — E2E 自动化测试</h1>\n<h2>一、前置知识:</h2>\n<h3>1、E2E 测试与单元测试的区别</h3>\n<p>E2E,是“End to End”的缩写,可以翻译成“端到端”测试。它模仿用户,从某个入口开始,逐步执行操作,直到完成某项工作。与单元测试不同,后者通常需要测试参数、参数类型、参数值、参数数量、返回值、抛出错误等,目的在于保证特定函数能够在任何情况下都稳定可靠完成工作。单元测试假定只要所有函数都正常工作,那么整个产品就能正常工作。</p>\n<p>相对来说,E2E 测试并没有那么强调要覆盖全部使用场景,它关注的<strong>一个完整的操作链是否能够完成</strong>。对于 Web 前端来说,还关注<strong>界面布局、内容信息是否符合预期</strong>。</p>\n<p>比如,登陆界面的 E2E 测试,关注用户是否能够正常输入,正常登录;登陆失败的�
 �,是否能够正确显示错误信息。至于输入不合法的内容是否处理,并不是所关注的重点。</p>\n<h3>2、Selen [...]
+  "__html": "<h1>DolphinScheduler — E2E 自动化测试</h1>\n<h2>一、前置知识:</h2>\n<h3>1、E2E 测试与单元测试的区别</h3>\n<p>E2E,是“End to End”的缩写,可以翻译成“端到端”测试。它模仿用户,从某个入口开始,逐步执行操作,直到完成某项工作。与单元测试不同,后者通常需要测试参数、参数类型、参数值、参数数量、返回值、抛出错误等,目的在于保证特定函数能够在任何情况下都稳定可靠完成工作。单元测试假定只要所有函数都正常工作,那么整个产品就能正常工作。</p>\n<p>相对来说,E2E 测试并没有那么强调要覆盖全部使用场景,它关注的<strong>一个完整的操作链是否能够完成</strong>。对于 Web 前端来说,还关注<strong>界面布局、内容信息是否符合预期</strong>。</p>\n<p>比如,登陆界面的 E2E 测试,关注用户是否能够正常输入,正常登录;登陆失败的�
 �,是否能够正确显示错误信息。至于输入不合法的内容是否处理,并不是所关注的重点。</p>\n<h3>2、Selen [...]
   "link": "/dist/zh-cn/development/e2e-test.html",
   "meta": {}
 }
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/api-standard.html b/zh-cn/docs/dev/user_doc/development/api-standard.html
deleted file mode 100644
index 28c174d6e..000000000
--- a/zh-cn/docs/dev/user_doc/development/api-standard.html
+++ /dev/null
@@ -1,123 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="api-standard">
-  <meta name="description" content="api-standard">
-  <title>api-standard</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 有关于 Apache DolphinScheduler 的疑问,加入 Slack 频道来讨论他们 <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span><a href="/zh-cn/index.html"><img cl [...]
-<p>规范统一的 API 是项目设计的基石。DolphinScheduler 的 API 遵循 REST ful 标准,REST ful 是目前最流行的一种互联网软件架构,它结构清晰,符合标准,易于理解,扩展方便。</p>
-<p>本文以 DolphinScheduler 项目的接口为样例,讲解如何构造具有 Restful 风格的 API。</p>
-<h2>1. URI 设计</h2>
-<p>REST 即为 Representational State Transfer 的缩写,即“表现层状态转化”。</p>
-<p>“表现层”指的就是“资源”。资源对应网络上的一种实体,例如:一段文本,一张图片,一种服务。且每种资源都对应一个特定的 URI。</p>
-<p>Restful URI 的设计基于资源:</p>
-<ul>
-<li>一类资源:用复数表示,如 <code>task-instances</code>、<code>groups</code> 等;</li>
-<li>单个资源:用单数,或是用 id 值表示某类资源下的一个,如 <code>group</code>、<code>groups/{groupId}</code>;</li>
-<li>子资源:某个资源下的资源:<code>/instances/{instanceId}/tasks</code>;</li>
-<li>子资源下的单个资源:<code>/instances/{instanceId}/tasks/{taskId}</code>;</li>
-</ul>
-<h2>2. Method 设计</h2>
-<p>我们需要通过 URI 来定位某种资源,再通过 Method,或者在路径后缀声明动作来体现对资源的操作。</p>
-<h3>① 查询操作 - GET</h3>
-<p>通过 URI 来定位要资源,通过 GET 表示查询。</p>
-<ul>
-<li>当 URI 为一类资源时表示查询一类资源,例如下面样例表示分页查询 <code>alter-groups</code>。</li>
-</ul>
-<pre><code>Method: GET
-/api/dolphinscheduler/alert-groups
-</code></pre>
-<ul>
-<li>当 URI 为单个资源时表示查询此资源,例如下面样例表示查询对应的 <code>alter-group</code>。</li>
-</ul>
-<pre><code>Method: GET
-/api/dolphinscheduler/alter-groups/{id}
-</code></pre>
-<ul>
-<li>此外,我们还可以根据 URI 来表示查询子资源,如下:</li>
-</ul>
-<pre><code>Method: GET
-/api/dolphinscheduler/projects/{projectId}/tasks
-</code></pre>
-<p><strong>上述的关于查询的方式都表示分页查询,如果我们需要查询全部数据的话,则需在 URI 的后面加 <code>/list</code> 来区分。分页查询和查询全部不要混用一个 API。</strong></p>
-<pre><code>Method: GET
-/api/dolphinscheduler/alert-groups/list
-</code></pre>
-<h3>② 创建操作 - POST</h3>
-<p>通过 URI 来定位要创建的资源类型,通过 POST 表示创建动作,并且将创建后的 <code>id</code> 返回给请求者。</p>
-<ul>
-<li>下面样例表示创建一个 <code>alter-group</code>:</li>
-</ul>
-<pre><code>Method: POST
-/api/dolphinscheduler/alter-groups
-</code></pre>
-<ul>
-<li>创建子资源也是类似的操作:</li>
-</ul>
-<pre><code>Method: POST
-/api/dolphinscheduler/alter-groups/{alterGroupId}/tasks
-</code></pre>
-<h3>③ 修改操作 - PUT</h3>
-<p>通过 URI 来定位某一资源,通过 PUT 指定对其修改。</p>
-<pre><code>Method: PUT
-/api/dolphinscheduler/alter-groups/{alterGroupId}
-</code></pre>
-<h3>④ 删除操作 -DELETE</h3>
-<p>通过 URI 来定位某一资源,通过 DELETE 指定对其删除。</p>
-<ul>
-<li>下面例子表示删除 <code>alterGroupId</code> 对应的资源:</li>
-</ul>
-<pre><code>Method: DELETE
-/api/dolphinscheduler/alter-groups/{alterGroupId}
-</code></pre>
-<ul>
-<li>批量删除:对传入的 id 数组进行批量删除,使用 POST 方法。<strong>(这里不要用 DELETE 方法,因为 DELETE 请求的 body 在语义上没有任何意义,而且有可能一些网关,代理,防火墙在收到 DELETE 请求后会把请求的 body 直接剥离掉。)</strong></li>
-</ul>
-<pre><code>Method: POST
-/api/dolphinscheduler/alter-groups/batch-delete
-</code></pre>
-<h3>⑤ 其他操作</h3>
-<p>除增删改查外的操作,我们同样也通过 <code>url</code> 定位到对应的资源,然后再在路径后面追加对其进行的操作。例如:</p>
-<pre><code>/api/dolphinscheduler/alert-groups/verify-name
-/api/dolphinscheduler/projects/{projectCode}/process-instances/{code}/view-gantt
-</code></pre>
-<h2>3. 参数设计</h2>
-<p>参数分为两种,一种是请求参数(Request Param 或 Request Body),另一种是路径参数(Path Param)。</p>
-<p>参数变量必须用小驼峰表示,并且在分页场景中,用户输入的参数小于 1,则前端需要返给后端 1 表示请求第一页;当后端发现用户输入的参数大于总页数时,直接返回最后一页。</p>
-<h2>4. 其他设计</h2>
-<h3>基础路径</h3>
-<p>整个项目的 URI 需要以 <code>/api/&lt;project_name&gt;</code> 作为基础路径,从而标识这类 API 都是项目下的,即:</p>
-<pre><code>/api/dolphinscheduler
-</code></pre>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/api-standard.json b/zh-cn/docs/dev/user_doc/development/api-standard.json
deleted file mode 100644
index 1befd8929..000000000
--- a/zh-cn/docs/dev/user_doc/development/api-standard.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "api-standard.md",
-  "__html": "<h1>API 设计规范</h1>\n<p>规范统一的 API 是项目设计的基石。DolphinScheduler 的 API 遵循 REST ful 标准,REST ful 是目前最流行的一种互联网软件架构,它结构清晰,符合标准,易于理解,扩展方便。</p>\n<p>本文以 DolphinScheduler 项目的接口为样例,讲解如何构造具有 Restful 风格的 API。</p>\n<h2>1. URI 设计</h2>\n<p>REST 即为 Representational State Transfer 的缩写,即“表现层状态转化”。</p>\n<p>“表现层”指的就是“资源”。资源对应网络上的一种实体,例如:一段文本,一张图片,一种服务。且每种资源都对应一个特定的 URI。</p>\n<p>Restful URI 的设计基于资源:</p>\n<ul>\n<li>一类资源:用复数表示,如 <code>task-instances</code>、<code>groups</code> 等;</li>\n<li>单个资源:用单数,或是用 i [...]
-  "link": "/dist/zh-cn/docs/dev/user_doc/development/api-standard.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/architecture-design.html b/zh-cn/docs/dev/user_doc/development/architecture-design.html
deleted file mode 100644
index 8229a9531..000000000
--- a/zh-cn/docs/dev/user_doc/development/architecture-design.html
+++ /dev/null
@@ -1,322 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="architecture-design">
-  <meta name="description" content="architecture-design">
-  <title>architecture-design</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 有关于 Apache DolphinScheduler 的疑问,加入 Slack 频道来讨论他们 <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span><a href="/zh-cn/index.html"><img cl [...]
-<p>在对调度系统架构说明之前,我们先来认识一下调度系统常用的名词</p>
-<h3>1.名词解释</h3>
-<p><strong>DAG:</strong> 全称Directed Acyclic Graph,简称DAG。工作流中的Task任务以有向无环图的形式组装起来,从入度为零的节点进行拓扑遍历,直到无后继节点为止。举例如下图:</p>
-<p align="center">
-  <img src="/img/architecture-design/dag_examples.png" alt="dag示例"  width="80%" />
-  <p align="center">
-        <em>dag示例</em>
-  </p>
-</p>
-<p><strong>流程定义</strong>:通过拖拽任务节点并建立任务节点的关联所形成的可视化<strong>DAG</strong></p>
-<p><strong>流程实例</strong>:流程实例是流程定义的实例化,可以通过手动启动或定时调度生成,流程定义每运行一次,产生一个流程实例</p>
-<p><strong>任务实例</strong>:任务实例是流程定义中任务节点的实例化,标识着具体的任务执行状态</p>
-<p><strong>任务类型</strong>: 目前支持有SHELL、SQL、SUB_PROCESS(子流程)、PROCEDURE、MR、SPARK、PYTHON、DEPENDENT(依赖),同时计划支持动态插件扩展,注意:其中子 <strong>SUB_PROCESS</strong>  也是一个单独的流程定义,是可以单独启动执行的</p>
-<p><strong>调度方式:</strong> 系统支持基于cron表达式的定时调度和手动调度。命令类型支持:启动工作流、从当前节点开始执行、恢复被容错的工作流、恢复暂停流程、从失败节点开始执行、补数、定时、重跑、暂停、停止、恢复等待线程。其中 <strong>恢复被容错的工作流</strong> 和 <strong>恢复等待线程</strong> 两种命令类型是由调度内部控制使用,外部无法调用</p>
-<p><strong>定时调度</strong>:系统采用 <strong>quartz</strong> 分布式调度器,并同时支持cron表达式可视化的生成</p>
-<p><strong>依赖</strong>:系统不单单支持 <strong>DAG</strong> 简单的前驱和后继节点之间的依赖,同时还提供<strong>任务依赖</strong>节点,支持<strong>流程间的自定义任务依赖</strong></p>
-<p><strong>优先级</strong> :支持流程实例和任务实例的优先级,如果流程实例和任务实例的优先级不设置,则默认是先进先出</p>
-<p><strong>邮件告警</strong>:支持 <strong>SQL任务</strong> 查询结果邮件发送,流程实例运行结果邮件告警及容错告警通知</p>
-<p><strong>失败策略</strong>:对于并行运行的任务,如果有任务失败,提供两种失败策略处理方式,<strong>继续</strong>是指不管并行运行任务的状态,直到流程失败结束。<strong>结束</strong>是指一旦发现失败任务,则同时Kill掉正在运行的并行任务,流程失败结束</p>
-<p><strong>补数</strong>:补历史数据,支持<strong>区间并行和串行</strong>两种补数方式</p>
-<h3>2.系统架构</h3>
-<h4>2.1 系统架构图</h4>
-<p align="center">
-  <img src="/img/architecture.jpg" alt="系统架构图"  />
-  <p align="center">
-        <em>系统架构图</em>
-  </p>
-</p>
-<h4>2.2 架构说明</h4>
-<ul>
-<li>
-<p><strong>MasterServer</strong></p>
-<p>MasterServer采用分布式无中心设计理念,MasterServer主要负责 DAG 任务切分、任务提交监控,并同时监听其它MasterServer和WorkerServer的健康状态。
-MasterServer服务启动时向Zookeeper注册临时节点,通过监听Zookeeper临时节点变化来进行容错处理。</p>
-<h5>该服务内主要包含:</h5>
-<ul>
-<li>
-<p><strong>Distributed Quartz</strong>分布式调度组件,主要负责定时任务的启停操作,当quartz调起任务后,Master内部会有线程池具体负责处理任务的后续操作</p>
-</li>
-<li>
-<p><strong>MasterSchedulerThread</strong>是一个扫描线程,定时扫描数据库中的 <strong>command</strong> 表,根据不同的<strong>命令类型</strong>进行不同的业务操作</p>
-</li>
-<li>
-<p><strong>MasterExecThread</strong>主要是负责DAG任务切分、任务提交监控、各种不同命令类型的逻辑处理</p>
-</li>
-<li>
-<p><strong>MasterTaskExecThread</strong>主要负责任务的持久化</p>
-</li>
-</ul>
-</li>
-<li>
-<p><strong>WorkerServer</strong></p>
-<p>WorkerServer也采用分布式无中心设计理念,WorkerServer主要负责任务的执行和提供日志服务。WorkerServer服务启动时向Zookeeper注册临时节点,并维持心跳。</p>
-<h5>该服务包含:</h5>
-<ul>
-<li><strong>FetchTaskThread</strong>主要负责不断从<strong>Task Queue</strong>中领取任务,并根据不同任务类型调用<strong>TaskScheduleThread</strong>对应执行器。</li>
-</ul>
-</li>
-<li>
-<p><strong>ZooKeeper</strong></p>
-<p>ZooKeeper服务,系统中的MasterServer和WorkerServer节点都通过ZooKeeper来进行集群管理和容错。另外系统还基于ZooKeeper进行事件监听和分布式锁。
-我们也曾经基于Redis实现过队列,不过我们希望DolphinScheduler依赖到的组件尽量地少,所以最后还是去掉了Redis实现。</p>
-</li>
-<li>
-<p><strong>Task Queue</strong></p>
-<p>提供任务队列的操作,目前队列也是基于Zookeeper来实现。由于队列中存的信息较少,不必担心队列里数据过多的情况,实际上我们压测过百万级数据存队列,对系统稳定性和性能没影响。</p>
-</li>
-<li>
-<p><strong>Alert</strong></p>
-<p>提供告警相关接口,接口主要包括两种类型的告警数据的存储、查询和通知功能。其中通知功能又有<strong>邮件通知</strong>和**SNMP(暂未实现)**两种。</p>
-</li>
-<li>
-<p><strong>API</strong></p>
-<p>API接口层,主要负责处理前端UI层的请求。该服务统一提供RESTful api向外部提供请求服务。
-接口包括工作流的创建、定义、查询、修改、发布、下线、手工启动、停止、暂停、恢复、从该节点开始执行等等。</p>
-</li>
-<li>
-<p><strong>UI</strong></p>
-<p>系统的前端页面,提供系统的各种可视化操作界面,详见 <a href="https://dolphinscheduler.apache.org/zh-cn/docs/latest/user_doc/guide/quick-start.html">快速开始</a> 部分。</p>
-</li>
-</ul>
-<h4>2.3 架构设计思想</h4>
-<h5>一、去中心化vs中心化</h5>
-<h6>中心化思想</h6>
-<p>中心化的设计理念比较简单,分布式集群中的节点按照角色分工,大体上分为两种角色:</p>
-<p align="center">
-   <img src="https://analysys.github.io/easyscheduler_docs_cn/images/master_slave.png" alt="master-slave角色"  width="50%" />
- </p>
-<ul>
-<li>Master的角色主要负责任务分发并监督Slave的健康状态,可以动态的将任务均衡到Slave上,以致Slave节点不至于“忙死”或”闲死”的状态。</li>
-<li>Worker的角色主要负责任务的执行工作并维护和Master的心跳,以便Master可以分配任务给Slave。</li>
-</ul>
-<p>中心化思想设计存在的问题:</p>
-<ul>
-<li>一旦Master出现了问题,则群龙无首,整个集群就会崩溃。为了解决这个问题,大多数Master/Slave架构模式都采用了主备Master的设计方案,可以是热备或者冷备,也可以是自动切换或手动切换,而且越来越多的新系统都开始具备自动选举切换Master的能力,以提升系统的可用性。</li>
-<li>另外一个问题是如果Scheduler在Master上,虽然可以支持一个DAG中不同的任务运行在不同的机器上,但是会产生Master的过负载。如果Scheduler在Slave上,则一个DAG中所有的任务都只能在某一台机器上进行作业提交,则并行任务比较多的时候,Slave的压力可能会比较大。</li>
-</ul>
-<h6>去中心化</h6>
- <p align="center"
-   <img src="https://analysys.github.io/easyscheduler_docs_cn/images/decentralization.png" alt="去中心化"  width="50%" />
- </p>
-<ul>
-<li>
-<p>在去中心化设计里,通常没有Master/Slave的概念,所有的角色都是一样的,地位是平等的,全球互联网就是一个典型的去中心化的分布式系统,联网的任意节点设备down机,都只会影响很小范围的功能。</p>
-</li>
-<li>
-<p>去中心化设计的核心设计在于整个分布式系统中不存在一个区别于其他节点的”管理者”,因此不存在单点故障问题。但由于不存在” 管理者”节点所以每个节点都需要跟其他节点通信才得到必须要的机器信息,而分布式系统通信的不可靠性,则大大增加了上述功能的实现难度。</p>
-</li>
-<li>
-<p>实际上,真正去中心化的分布式系统并不多见。反而动态中心化分布式系统正在不断涌出。在这种架构下,集群中的管理者是被动态选择出来的,而不是预置的,并且集群在发生故障的时候,集群的节点会自发的举行&quot;会议&quot;来选举新的&quot;管理者&quot;去主持工作。最典型的案例就是ZooKeeper及Go语言实现的Etcd。</p>
-</li>
-<li>
-<p>DolphinScheduler的去中心化是Master/Worker注册到Zookeeper中,实现Master集群和Worker集群无中心,并使用Zookeeper分布式锁来选举其中的一台Master或Worker为“管理者”来执行任务。</p>
-</li>
-</ul>
-<h5>二、分布式锁实践</h5>
-<p>DolphinScheduler使用ZooKeeper分布式锁来实现同一时刻只有一台Master执行Scheduler,或者只有一台Worker执行任务的提交。</p>
-<ol>
-<li>获取分布式锁的核心流程算法如下</li>
-</ol>
- <p align="center">
-   <img src="/img/architecture-design/distributed_lock.png" alt="获取分布式锁流程"  width="70%" />
- </p>
-<ol start="2">
-<li>DolphinScheduler中Scheduler线程分布式锁实现流程图:</li>
-</ol>
- <p align="center">
-   <img src="/img/architecture-design/distributed_lock_procss.png" alt="获取分布式锁流程" />
- </p>
-<h5>三、线程不足循环等待问题</h5>
-<ul>
-<li>如果一个DAG中没有子流程,则如果Command中的数据条数大于线程池设置的阈值,则直接流程等待或失败。</li>
-<li>如果一个大的DAG中嵌套了很多子流程,如下图则会产生“死等”状态:</li>
-</ul>
- <p align="center">
-   <img src="/img/architecture-design/lack_thread.png" alt="线程不足循环等待问题"  width="70%" />
- </p>
-上图中MainFlowThread等待SubFlowThread1结束,SubFlowThread1等待SubFlowThread2结束, SubFlowThread2等待SubFlowThread3结束,而SubFlowThread3等待线程池有新线程,则整个DAG流程不能结束,从而其中的线程也不能释放。这样就形成的子父流程循环等待的状态。此时除非启动新的Master来增加线程来打破这样的”僵局”,否则调度集群将不能再使用。
-<p>对于启动新Master来打破僵局,似乎有点差强人意,于是我们提出了以下三种方案来降低这种风险:</p>
-<ol>
-<li>计算所有Master的线程总和,然后对每一个DAG需要计算其需要的线程数,也就是在DAG流程执行之前做预计算。因为是多Master线程池,所以总线程数不太可能实时获取。</li>
-<li>对单Master线程池进行判断,如果线程池已经满了,则让线程直接失败。</li>
-<li>增加一种资源不足的Command类型,如果线程池不足,则将主流程挂起。这样线程池就有了新的线程,可以让资源不足挂起的流程重新唤醒执行。</li>
-</ol>
-<p>注意:Master Scheduler线程在获取Command的时候是FIFO的方式执行的。</p>
-<p>于是我们选择了第三种方式来解决线程不足的问题。</p>
-<h5>四、容错设计</h5>
-<p>容错分为服务宕机容错和任务重试,服务宕机容错又分为Master容错和Worker容错两种情况</p>
-<h6>1. 宕机容错</h6>
-<p>服务容错设计依赖于ZooKeeper的Watcher机制,实现原理如图:</p>
- <p align="center">
-   <img src="/img/architecture-design/fault-tolerant.png" alt="DolphinScheduler容错设计"  width="70%" />
- </p>
-其中Master监控其他Master和Worker的目录,如果监听到remove事件,则会根据具体的业务逻辑进行流程实例容错或者任务实例容错。
-<ul>
-<li>Master容错流程图:</li>
-</ul>
- <p align="center">
-   <img src="/img/architecture-design/fault-tolerant_master.png" alt="Master容错流程图"  width="70%" />
- </p>
-ZooKeeper Master容错完成之后则重新由DolphinScheduler中Scheduler线程调度,遍历 DAG 找到”正在运行”和“提交成功”的任务,对”正在运行”的任务监控其任务实例的状态,对”提交成功”的任务需要判断Task Queue中是否已经存在,如果存在则同样监控任务实例的状态,如果不存在则重新提交任务实例。
-<ul>
-<li>Worker容错流程图:</li>
-</ul>
- <p align="center">
-   <img src="/img/architecture-design/fault-tolerant_worker.png" alt="Worker容错流程图"  width="70%" />
- </p>
-<p>Master Scheduler线程一旦发现任务实例为” 需要容错”状态,则接管任务并进行重新提交。</p>
-<p>注意:由于” 网络抖动”可能会使得节点短时间内失去和ZooKeeper的心跳,从而发生节点的remove事件。对于这种情况,我们使用最简单的方式,那就是节点一旦和ZooKeeper发生超时连接,则直接将Master或Worker服务停掉。</p>
-<h6>2.任务失败重试</h6>
-<p>这里首先要区分任务失败重试、流程失败恢复、流程失败重跑的概念:</p>
-<ul>
-<li>任务失败重试是任务级别的,是调度系统自动进行的,比如一个Shell任务设置重试次数为3次,那么在Shell任务运行失败后会自己再最多尝试运行3次</li>
-<li>流程失败恢复是流程级别的,是手动进行的,恢复是从只能<strong>从失败的节点开始执行</strong>或<strong>从当前节点开始执行</strong></li>
-<li>流程失败重跑也是流程级别的,是手动进行的,重跑是从开始节点进行</li>
-</ul>
-<p>接下来说正题,我们将工作流中的任务节点分了两种类型。</p>
-<ul>
-<li>
-<p>一种是业务节点,这种节点都对应一个实际的脚本或者处理语句,比如Shell节点,MR节点、Spark节点、依赖节点等。</p>
-</li>
-<li>
-<p>还有一种是逻辑节点,这种节点不做实际的脚本或语句处理,只是整个流程流转的逻辑处理,比如子流程节等。</p>
-</li>
-</ul>
-<p>每一个<strong>业务节点</strong>都可以配置失败重试的次数,当该任务节点失败,会自动重试,直到成功或者超过配置的重试次数。<strong>逻辑节点</strong>不支持失败重试。但是逻辑节点里的任务支持重试。</p>
-<p>如果工作流中有任务失败达到最大重试次数,工作流就会失败停止,失败的工作流可以手动进行重跑操作或者流程恢复操作</p>
-<h5>五、任务优先级设计</h5>
-<p>在早期调度设计中,如果没有优先级设计,采用公平调度设计的话,会遇到先行提交的任务可能会和后继提交的任务同时完成的情况,而不能做到设置流程或者任务的优先级,因此我们对此进行了重新设计,目前我们设计如下:</p>
-<ul>
-<li>按照<strong>不同流程实例优先级</strong>优先于<strong>同一个流程实例优先级</strong>优先于<strong>同一流程内任务优先级</strong>优先于<strong>同一流程内任务</strong>提交顺序依次从高到低进行任务处理。
-<ul>
-<li>
-<p>具体实现是根据任务实例的json解析优先级,然后把<strong>流程实例优先级_流程实例id_任务优先级_任务id</strong>信息保存在ZooKeeper任务队列中,当从任务队列获取的时候,通过字符串比较即可得出最需要优先执行的任务</p>
-<ul>
-<li>
-<p>其中流程定义的优先级是考虑到有些流程需要先于其他流程进行处理,这个可以在流程启动或者定时启动时配置,共有5级,依次为HIGHEST、HIGH、MEDIUM、LOW、LOWEST。如下图</p>
-  <p align="center">
-     <img src="https://analysys.github.io/easyscheduler_docs_cn/images/process_priority.png" alt="流程优先级配置"  width="40%" />
-   </p>
-</li>
-<li>
-<p>任务的优先级也分为5级,依次为HIGHEST、HIGH、MEDIUM、LOW、LOWEST。如下图</p>
-  <p align="center">
-     <img src="https://analysys.github.io/easyscheduler_docs_cn/images/task_priority.png" alt="任务优先级配置"  width="35%" />
-   </p>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-<h5>六、Logback和gRPC实现日志访问</h5>
-<ul>
-<li>
-<p>由于Web(UI)和Worker不一定在同一台机器上,所以查看日志不能像查询本地文件那样。有两种方案:</p>
-</li>
-<li>
-<p>将日志放到ES搜索引擎上</p>
-</li>
-<li>
-<p>通过gRPC通信获取远程日志信息</p>
-</li>
-<li>
-<p>介于考虑到尽可能的DolphinScheduler的轻量级性,所以选择了gRPC实现远程访问日志信息。</p>
-</li>
-</ul>
- <p align="center">
-   <img src="https://analysys.github.io/easyscheduler_docs_cn/images/grpc.png" alt="grpc远程访问"  width="60%" />
- </p>
-<ul>
-<li>我们使用自定义Logback的FileAppender和Filter功能,实现每个任务实例生成一个日志文件。</li>
-<li>FileAppender主要实现如下:</li>
-</ul>
-<pre><code class="language-java"><span class="hljs-comment">/**
- * task log appender
- */</span>
-<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TaskLogAppender</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">FileAppender</span>&lt;<span class="hljs-title">ILoggingEvent</span>&gt; </span>{
-
-    ...
-
-   <span class="hljs-meta">@Override</span>
-   <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">append</span><span class="hljs-params">(ILoggingEvent event)</span> </span>{
-
-       <span class="hljs-keyword">if</span> (currentlyActiveFile == <span class="hljs-keyword">null</span>){
-           currentlyActiveFile = getFile();
-       }
-       String activeFile = currentlyActiveFile;
-       <span class="hljs-comment">// thread name: taskThreadName-processDefineId_processInstanceId_taskInstanceId</span>
-       String threadName = event.getThreadName();
-       String[] threadNameArr = threadName.split(<span class="hljs-string">&quot;-&quot;</span>);
-       <span class="hljs-comment">// logId = processDefineId_processInstanceId_taskInstanceId</span>
-       String logId = threadNameArr[<span class="hljs-number">1</span>];
-       ...
-       <span class="hljs-keyword">super</span>.subAppend(event);
-   }
-}
-</code></pre>
-<p>以/流程定义id/流程实例id/任务实例id.log的形式生成日志</p>
-<ul>
-<li>
-<p>过滤匹配以TaskLogInfo开始的线程名称:</p>
-</li>
-<li>
-<p>TaskLogFilter实现如下:</p>
-</li>
-</ul>
-<pre><code class="language-java"><span class="hljs-comment">/**
-*  task log filter
-*/</span>
-<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TaskLogFilter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Filter</span>&lt;<span class="hljs-title">ILoggingEvent</span>&gt; </span>{
-
-   <span class="hljs-meta">@Override</span>
-   <span class="hljs-function"><span class="hljs-keyword">public</span> FilterReply <span class="hljs-title">decide</span><span class="hljs-params">(ILoggingEvent event)</span> </span>{
-       <span class="hljs-keyword">if</span> (event.getThreadName().startsWith(<span class="hljs-string">&quot;TaskLogInfo-&quot;</span>)){
-           <span class="hljs-keyword">return</span> FilterReply.ACCEPT;
-       }
-       <span class="hljs-keyword">return</span> FilterReply.DENY;
-   }
-}
-</code></pre>
-<h3>总结</h3>
-<p>本文从调度出发,初步介绍了大数据分布式工作流调度系统--DolphinScheduler的架构原理及实现思路。未完待续</p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/architecture-design.json b/zh-cn/docs/dev/user_doc/development/architecture-design.json
deleted file mode 100644
index 3fb0816a2..000000000
--- a/zh-cn/docs/dev/user_doc/development/architecture-design.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "architecture-design.md",
-  "__html": "<h2>系统架构设计</h2>\n<p>在对调度系统架构说明之前,我们先来认识一下调度系统常用的名词</p>\n<h3>1.名词解释</h3>\n<p><strong>DAG:</strong> 全称Directed Acyclic Graph,简称DAG。工作流中的Task任务以有向无环图的形式组装起来,从入度为零的节点进行拓扑遍历,直到无后继节点为止。举例如下图:</p>\n<p align=\"center\">\n  <img src=\"/img/architecture-design/dag_examples.png\" alt=\"dag示例\"  width=\"80%\" />\n  <p align=\"center\">\n        <em>dag示例</em>\n  </p>\n</p>\n<p><strong>流程定义</strong>:通过拖拽任务节点并建立任务节点的关联所形成的可视化<strong>DAG</strong></p>\n<p><strong>流程实例</strong>:流程实例是流程定义的实例化 [...]
-  "link": "/dist/zh-cn/docs/dev/user_doc/development/architecture-design.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/backend/mechanism/global-parameter.html b/zh-cn/docs/dev/user_doc/development/backend/mechanism/global-parameter.html
deleted file mode 100644
index 6ee5fba69..000000000
--- a/zh-cn/docs/dev/user_doc/development/backend/mechanism/global-parameter.html
+++ /dev/null
@@ -1,83 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="global-parameter">
-  <meta name="description" content="global-parameter">
-  <title>global-parameter</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 有关于 Apache DolphinScheduler 的疑问,加入 Slack 频道来讨论他们 <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span><a href="/zh-cn/index.html"><img cl [...]
-<p>用户在定义方向为 OUT 的参数后,会保存在 task 的 localParam 中。</p>
-<h2>参数的使用</h2>
-<p>从 DAG 中获取当前需要创建的 taskInstance 的直接前置节点 preTasks,获取 preTasks 的 varPool,将该 <code>varPool(List&lt;Property&gt;)</code>合并为一个 varPool,在合并过程中,如果发现有相同的变量名的变量,按照以下逻辑处理</p>
-<ul>
-<li>若所有的值都是 null,则合并后的值为 null</li>
-<li>若有且只有一个值为非 null,则合并后的值为该非 null 值</li>
-<li>若所有的值都不是 null,则根据取 varPool 的 taskInstance 的 endtime 最早的一个</li>
-</ul>
-<p>在合并过程中将所有的合并过来的 Property 的方向更新为 IN</p>
-<p>合并后的结果保存在 taskInstance.varPool 中。</p>
-<p>Worker 收到后将 varPool 解析为 Map&lt;String,Property&gt; 的格式,其中 map 的 key 为 property.prop 也就是变量名。</p>
-<p>在 processor 处理参数时,会将 varPool 和 localParam 和 globalParam 三个变量池参数合并,合并过程中若有参数名重复的参数,按照以下优先级进行替换,高优先级保留,低优先级被替换:</p>
-<ul>
-<li><code>globalParam</code> :高</li>
-<li><code>varPool</code> :中</li>
-<li><code>localParam</code> :低</li>
-</ul>
-<p>参数会在节点内容执行之前利用正则表达式比配到 ${变量名},替换为对应的值。</p>
-<h2>参数的设置</h2>
-<p>目前仅支持 SQL 和 SHELL 节点的参数获取。
-从 localParam 中获取方向为 OUT 的参数,根据不同节点的类型做以下方式处理。</p>
-<h3>SQL 节点</h3>
-<p>参数返回的结构为 List&lt;Map&lt;String,String&gt;&gt;</p>
-<p>其中,List 的元素为每行数据,Map 的 key 为列名,value 为该列对应的值</p>
-<ul>
-<li>若 SQL 语句返回为有一行数据,则根据用户在定义 task 时定义的 OUT 参数名匹配列名,若没有匹配到则放弃。</li>
-<li>若 SQL 语句返回多行,按照根据用户在定义 task 时定义的类型为 LIST 的 OUT 参数名匹配列名,将对应列的所有行数据转换为 <code>List&lt;String&gt;</code>,作为该参数的值。若没有匹配到则放弃。</li>
-</ul>
-<h3>SHELL 节点</h3>
-<p>processor 执行后的结果返回为 <code>Map&lt;String,String&gt;</code></p>
-<p>用户在定义 shell 脚本时需要在输出中定义 <code>${setValue(key=value)}</code></p>
-<p>在参数处理时去掉 ${setValue()},按照 “=” 进行拆分,第 0 个为 key,第 1 个为 value。</p>
-<p>同样匹配用户定义 task 时定义的 OUT 参数名与 key,将 value 作为该参数的值。</p>
-<p>返回参数处理</p>
-<ul>
-<li>获取到的 processor 的结果为 String</li>
-<li>判断 processor 是否为空,为空退出</li>
-<li>判断 localParam 是否为空,为空退出</li>
-<li>获取 localParam 中为 OUT 的参数,为空退出</li>
-<li>将String按照上诉格式格式化(SQL为List&lt;Map&lt;String,String&gt;&gt;,shell为Map&lt;String,String&gt;)</li>
-<li>将匹配好值的参数赋值给 varPool(List<Property>,其中包含原有 IN 的参数)</li>
-</ul>
-<p>varPool 格式化为 json,传递给 master。
-Master 接收到 varPool 后,将其中为 OUT 的参数回写到 localParam 中。</p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/backend/mechanism/global-parameter.json b/zh-cn/docs/dev/user_doc/development/backend/mechanism/global-parameter.json
deleted file mode 100644
index a6234a72d..000000000
--- a/zh-cn/docs/dev/user_doc/development/backend/mechanism/global-parameter.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "global-parameter.md",
-  "__html": "<h1>全局参数开发文档</h1>\n<p>用户在定义方向为 OUT 的参数后,会保存在 task 的 localParam 中。</p>\n<h2>参数的使用</h2>\n<p>从 DAG 中获取当前需要创建的 taskInstance 的直接前置节点 preTasks,获取 preTasks 的 varPool,将该 <code>varPool(List&lt;Property&gt;)</code>合并为一个 varPool,在合并过程中,如果发现有相同的变量名的变量,按照以下逻辑处理</p>\n<ul>\n<li>若所有的值都是 null,则合并后的值为 null</li>\n<li>若有且只有一个值为非 null,则合并后的值为该非 null 值</li>\n<li>若所有的值都不是 null,则根据取 varPool 的 taskInstance 的 endtime 最早的一个</li>\n</ul>\n<p>在合并过程中将所有的合并过来的 Property 的方向更新为 IN</p>\n<p>合并后的结果保存在 taskInsta [...]
-  "link": "/dist/zh-cn/docs/dev/user_doc/development/backend/mechanism/global-parameter.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/backend/mechanism/overview.html b/zh-cn/docs/dev/user_doc/development/backend/mechanism/overview.html
deleted file mode 100644
index 307ce53eb..000000000
--- a/zh-cn/docs/dev/user_doc/development/backend/mechanism/overview.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="overview">
-  <meta name="description" content="overview">
-  <title>overview</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 有关于 Apache DolphinScheduler 的疑问,加入 Slack 频道来讨论他们 <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span><a href="/zh-cn/index.html"><img cl [...]
-<!-- TODO 由于 side menu 不支持多个等级,所以新建了一个leading page存放 -->
-<ul>
-<li><a href="global-parameter.md">全局参数</a></li>
-<li><a href="task/switch.md">switch任务类型</a></li>
-</ul>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/backend/mechanism/overview.json b/zh-cn/docs/dev/user_doc/development/backend/mechanism/overview.json
deleted file mode 100644
index 4aa360746..000000000
--- a/zh-cn/docs/dev/user_doc/development/backend/mechanism/overview.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "overview.md",
-  "__html": "<h1>综述</h1>\n<!-- TODO 由于 side menu 不支持多个等级,所以新建了一个leading page存放 -->\n<ul>\n<li><a href=\"global-parameter.md\">全局参数</a></li>\n<li><a href=\"task/switch.md\">switch任务类型</a></li>\n</ul>\n",
-  "link": "/dist/zh-cn/docs/dev/user_doc/development/backend/mechanism/overview.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/backend/mechanism/task/switch.html b/zh-cn/docs/dev/user_doc/development/backend/mechanism/task/switch.html
deleted file mode 100644
index b6f786f32..000000000
--- a/zh-cn/docs/dev/user_doc/development/backend/mechanism/task/switch.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="switch">
-  <meta name="description" content="switch">
-  <title>switch</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 有关于 Apache DolphinScheduler 的疑问,加入 Slack 频道来讨论他们 <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span><a href="/zh-cn/index.html"><img cl [...]
-<p>Switch任务类型的工作流程如下</p>
-<ul>
-<li>用户定义的表达式和分支流转的信息存在了taskdefinition中的taskParams中,当switch被执行到时,会被格式化为SwitchParameters。</li>
-<li>SwitchTaskExecThread从上到下(用户在页面上定义的表达式顺序)处理switch中定义的表达式,从varPool中获取变量的值,通过js解析表达式,如果表达式返回true,则停止检查,并且记录该表达式的顺序,这里我们记录为resultConditionLocation。SwitchTaskExecThread的任务便结束了。</li>
-<li>当switch节点运行结束之后,如果没有发生错误(较为常见的是用户定义的表达式不合规范或参数名有问题),这个时候MasterExecThread.submitPostNode会获取DAG的下游节点继续执行。</li>
-<li>DagHelper.parsePostNodes中如果发现当前节点(刚刚运行完成功的节点)是switch节点的话,会获取resultConditionLocation,将SwitchParameters中除了resultConditionLocation以外的其他分支全部skip掉。这样留下来的就只有需要执行的分支了。</li>
-</ul>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/backend/mechanism/task/switch.json b/zh-cn/docs/dev/user_doc/development/backend/mechanism/task/switch.json
deleted file mode 100644
index 0af081490..000000000
--- a/zh-cn/docs/dev/user_doc/development/backend/mechanism/task/switch.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "switch.md",
-  "__html": "<h1>SWITCH 任务类型开发文档</h1>\n<p>Switch任务类型的工作流程如下</p>\n<ul>\n<li>用户定义的表达式和分支流转的信息存在了taskdefinition中的taskParams中,当switch被执行到时,会被格式化为SwitchParameters。</li>\n<li>SwitchTaskExecThread从上到下(用户在页面上定义的表达式顺序)处理switch中定义的表达式,从varPool中获取变量的值,通过js解析表达式,如果表达式返回true,则停止检查,并且记录该表达式的顺序,这里我们记录为resultConditionLocation。SwitchTaskExecThread的任务便结束了。</li>\n<li>当switch节点运行结束之后,如果没有发生错误(较为常见的是用户定义的表达式不合规范或参数名有问题),这个时候MasterExecThread.submitPostNode会获取DAG的下游节点继续执行。</li>\n<li>DagHelper.parsePostNodes中如果 [...]
-  "link": "/dist/zh-cn/docs/dev/user_doc/development/backend/mechanism/task/switch.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/backend/spi/alert.html b/zh-cn/docs/dev/user_doc/development/backend/spi/alert.html
deleted file mode 100644
index 4d4e1f0fd..000000000
--- a/zh-cn/docs/dev/user_doc/development/backend/spi/alert.html
+++ /dev/null
@@ -1,93 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="alert">
-  <meta name="description" content="alert">
-  <title>alert</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 有关于 Apache DolphinScheduler 的疑问,加入 Slack 频道来讨论他们 <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span><a href="/zh-cn/index.html"><img cl [...]
-<h4>DolphinScheduler SPI 设计</h4>
-<p>DolphinScheduler 正在处于微内核 + 插件化的架构更改之中,所有核心能力如任务、资源存储、注册中心等都将被设计为扩展点,我们希望通过 SPI 来提高 DolphinScheduler 本身的灵活性以及友好性(扩展性)。</p>
-<p>告警相关代码可以参考 <code>dolphinscheduler-alert-api</code> 模块。该模块定义了告警插件扩展的接口以及一些基础代码,当我们需要实现相关功能的插件化的时候,建议先阅读此块的代码,当然,更建议你阅读文档,这会减少很多时间,不过文档有一定的后滞性,当文档缺失的时候,建议以源码为准(如果有兴趣,我们也欢迎你来提交相关文档),此外,我们几乎不会对扩展接口做变更(不包括新增),除非重大架构调整,出现不兼容升级版本,因此,现有文档一般都能够满足。</p>
-<p>我们采用了原生的 JAVA-SPI,当你需要扩展的时候,事实上你只需要关注扩展<code>org.apache.dolphinscheduler.alert.api.AlertChannelFactory</code>接口即可,底层相关逻辑如插件加载等内核已经实现,这让我们的开发更加专注且简单。</p>
-<p>顺便提一句,我们采用了一款优秀的前端组件 form-create,它支持基于 json 生成前端 ui 组件,如果插件开发牵扯到前端,我们会通过 json 来生成相关前端 UI 组件,org.apache.dolphinscheduler.spi.params 里面对插件的参数做了封装,它会将相关参数全部全部转化为对应的 json,这意味这你完全可以通过 Java 代码的方式完成前端组件的绘制(这里主要是表单,我们只关心前后端交互的数据)。</p>
-<p>本文主要着重讲解 Alert 告警相关设计以及开发。</p>
-<h4>主要模块</h4>
-<p>如果你并不关心它的内部设计,只是想单纯的了解如何开发自己的告警插件,可以略过该内容。</p>
-<ul>
-<li>
-<p>dolphinscheduler-alert-api</p>
-<p>该模块是 ALERT SPI 的核心模块,该模块定义了告警插件扩展的接口以及一些基础代码,扩展插件必须实现此模块所定义的接口:<code>org.apache.dolphinscheduler.alert.api.AlertChannelFactory</code></p>
-</li>
-<li>
-<p>dolphinscheduler-alert-plugins</p>
-<p>该模块是目前我们提供的插件,如 Email、DingTalk、Script等。</p>
-</li>
-</ul>
-<h4>Alert SPI 主要类信息:</h4>
-<p>AlertChannelFactory
-告警插件工厂接口,所有告警插件需要实现该接口,该接口用来定义告警插件的名称,需要的参数,create 方法用来创建具体的告警插件实例。</p>
-<p>AlertChannel
-告警插件的接口,告警插件需要实现该接口,该接口中只有一个方法 process ,上层告警系统会调用该方法并通过该方法返回的 AlertResult 来获取告警的返回信息。</p>
-<p>AlertData
-告警内容信息,包括 id,标题,内容,日志。</p>
-<p>AlertInfo
-告警相关信息,上层系统调用告警插件实例时,将该类的实例通过 process 方法传入具体的告警插件。内部包含告警内容 AlertData 和调用的告警插件实例的前端填写的参数信息。</p>
-<p>AlertResult
-告警插件发送告警返回信息。</p>
-<p>org.apache.dolphinscheduler.spi.params
-该包下是插件化的参数定义,我们前端使用 from-create 这个前端库,该库可以基于插件定义返回的参数列表 json 来动态生成前端的 ui,因此我们在做 SPI 插件开发的时候无需关心前端。</p>
-<p>该 package 下我们目前只封装了 RadioParam,TextParam,PasswordParam,分别用来定义 text 类型的参数,radio 参数和 password 类型的参数。</p>
-<p>AbsPluginParams 该类是所有参数的基类,RadioParam 这些类都继承了该类。每个 DS 的告警插件都会在 AlertChannelFactory 的实现中返回一个 AbsPluginParams 的 list。</p>
-<p>alert_spi 具体设计可见 issue:<a href="https://github.com/apache/incubator-dolphinscheduler/issues/3049">Alert Plugin Design</a></p>
-<h4>Alert SPI 内置实现</h4>
-<ul>
-<li>
-<p>Email</p>
-<p>电子邮件告警通知</p>
-</li>
-<li>
-<p>DingTalk</p>
-<p>钉钉群聊机器人告警</p>
-</li>
-<li>
-<p>EnterpriseWeChat</p>
-<p>企业微信告警通知</p>
-<p>相关参数配置可以参考企业微信机器人文档。</p>
-</li>
-<li>
-<p>Script</p>
-<p>我们实现了 Shell 脚本告警,我们会将相关告警参数透传给脚本,你可以在 Shell 中实现你的相关告警逻辑,如果你需要对接内部告警应用,这是一种不错的方法。</p>
-</li>
-</ul>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/backend/spi/alert.json b/zh-cn/docs/dev/user_doc/development/backend/spi/alert.json
deleted file mode 100644
index 2417b4f9a..000000000
--- a/zh-cn/docs/dev/user_doc/development/backend/spi/alert.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "alert.md",
-  "__html": "<h3>DolphinScheduler Alert SPI 主要设计</h3>\n<h4>DolphinScheduler SPI 设计</h4>\n<p>DolphinScheduler 正在处于微内核 + 插件化的架构更改之中,所有核心能力如任务、资源存储、注册中心等都将被设计为扩展点,我们希望通过 SPI 来提高 DolphinScheduler 本身的灵活性以及友好性(扩展性)。</p>\n<p>告警相关代码可以参考 <code>dolphinscheduler-alert-api</code> 模块。该模块定义了告警插件扩展的接口以及一些基础代码,当我们需要实现相关功能的插件化的时候,建议先阅读此块的代码,当然,更建议你阅读文档,这会减少很多时间,不过文档有一定的后滞性,当文档缺失的时候,建议以源码为准(如果有兴趣,我们也欢迎你来提交相关文档),此外,我们几乎不会对扩展接口做变更(不包括新增),除非重大架构调整,出现不兼容升级版本,因此,现有文档一般都�
 �够满足。</p>\n<p>我们采用了原生的 JAVA-SPI,当你需要扩展的时候 [...]
-  "link": "/dist/zh-cn/docs/dev/user_doc/development/backend/spi/alert.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/backend/spi/datasource.html b/zh-cn/docs/dev/user_doc/development/backend/spi/datasource.html
deleted file mode 100644
index f9961011c..000000000
--- a/zh-cn/docs/dev/user_doc/development/backend/spi/datasource.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="datasource">
-  <meta name="description" content="datasource">
-  <title>datasource</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 有关于 Apache DolphinScheduler 的疑问,加入 Slack 频道来讨论他们 <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span><a href="/zh-cn/index.html"><img cl [...]
-<h4>如何使用数据源?</h4>
-<p>数据源中心默认支持POSTGRESQL、HIVE/IMPALA、SPARK、CLICKHOUSE、SQLSERVER数据源。</p>
-<p>如果使用的是MySQL、ORACLE数据源则需要、把对应的驱动包放置lib目录下</p>
-<h4>如何进行数据源插件开发?</h4>
-<p>org.apache.dolphinscheduler.spi.datasource.DataSourceChannel
-org.apache.dolphinscheduler.spi.datasource.DataSourceChannelFactory
-org.apache.dolphinscheduler.plugin.datasource.api.client.CommonDataSourceClient</p>
-<ol>
-<li>第一步数据源插件实现以上接口和继承通用client即可,具体可以参考sqlserver、mysql等数据源插件实现,所有RDBMS插件的添加方式都是一样的。</li>
-<li>在数据源插件pom.xml添加驱动配置</li>
-</ol>
-<p>我们在 dolphinscheduler-datasource-api 模块提供了所有数据源对外访问的 API</p>
-<h4><strong>未来计划</strong></h4>
-<p>支持kafka、http、文件、sparkSQL、FlinkSQL等数据源</p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/backend/spi/datasource.json b/zh-cn/docs/dev/user_doc/development/backend/spi/datasource.json
deleted file mode 100644
index 9858884be..000000000
--- a/zh-cn/docs/dev/user_doc/development/backend/spi/datasource.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "datasource.md",
-  "__html": "<h2>DolphinScheduler Datasource SPI 主要设计</h2>\n<h4>如何使用数据源?</h4>\n<p>数据源中心默认支持POSTGRESQL、HIVE/IMPALA、SPARK、CLICKHOUSE、SQLSERVER数据源。</p>\n<p>如果使用的是MySQL、ORACLE数据源则需要、把对应的驱动包放置lib目录下</p>\n<h4>如何进行数据源插件开发?</h4>\n<p>org.apache.dolphinscheduler.spi.datasource.DataSourceChannel\norg.apache.dolphinscheduler.spi.datasource.DataSourceChannelFactory\norg.apache.dolphinscheduler.plugin.datasource.api.client.CommonDataSourceClient</p>\n<ol>\n<li>第一步数据源插件实现以上接口和继承通用client即可,具体可以参考sqlserv [...]
-  "link": "/dist/zh-cn/docs/dev/user_doc/development/backend/spi/datasource.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/backend/spi/registry.html b/zh-cn/docs/dev/user_doc/development/backend/spi/registry.html
deleted file mode 100644
index 59a8e01f4..000000000
--- a/zh-cn/docs/dev/user_doc/development/backend/spi/registry.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="registry">
-  <meta name="description" content="registry">
-  <title>registry</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 有关于 Apache DolphinScheduler 的疑问,加入 Slack 频道来讨论他们 <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span><a href="/zh-cn/index.html"><img cl [...]
-<h4>如何使用?</h4>
-<p>进行以下配置(以 zookeeper 为例)</p>
-<ul>
-<li>注册中心插件配置, 以Zookeeper 为例 (registry.properties)
-dolphinscheduler-service/src/main/resources/registry.properties<pre><code class="language-registry.properties"> registry.plugin.name=zookeeper
- registry.servers=127.0.0.1:2181
-</code></pre>
-</li>
-</ul>
-<p>具体配置信息请参考具体插件提供的参数信息,例如 zk:<code>org/apache/dolphinscheduler/plugin/registry/zookeeper/ZookeeperConfiguration.java</code>
-所有配置信息前缀需要 +registry,如 <a href="http://base.sleep.time.ms">base.sleep.time.ms</a>,在 registry 中应该这样配置:registry.base.sleep.time.ms=100</p>
-<h4>如何扩展</h4>
-<p><code>dolphinscheduler-registry-api</code> 定义了实现插件的标准,当你需要扩展插件的时候只需要实现 <code>org.apache.dolphinscheduler.registry.api.RegistryFactory</code> 即可。</p>
-<p><code>dolphinscheduler-registry-plugin</code> 模块下是我们目前所提供的注册中心插件。</p>
-<h4>FAQ</h4>
-<p>1:registry connect timeout</p>
-<p>可以增加相关超时参数。</p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/backend/spi/registry.json b/zh-cn/docs/dev/user_doc/development/backend/spi/registry.json
deleted file mode 100644
index 96e859c0a..000000000
--- a/zh-cn/docs/dev/user_doc/development/backend/spi/registry.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "registry.md",
-  "__html": "<h3>DolphinScheduler Registry SPI 扩展</h3>\n<h4>如何使用?</h4>\n<p>进行以下配置(以 zookeeper 为例)</p>\n<ul>\n<li>注册中心插件配置, 以Zookeeper 为例 (registry.properties)\ndolphinscheduler-service/src/main/resources/registry.properties<pre><code class=\"language-registry.properties\"> registry.plugin.name=zookeeper\n registry.servers=127.0.0.1:2181\n</code></pre>\n</li>\n</ul>\n<p>具体配置信息请参考具体插件提供的参数信息,例如 zk:<code>org/apache/dolphinscheduler/plugin/registry/zookeeper/ZookeeperConfiguration.java</code [...]
-  "link": "/dist/zh-cn/docs/dev/user_doc/development/backend/spi/registry.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/backend/spi/task.html b/zh-cn/docs/dev/user_doc/development/backend/spi/task.html
deleted file mode 100644
index 5d47e166c..000000000
--- a/zh-cn/docs/dev/user_doc/development/backend/spi/task.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="task">
-  <meta name="description" content="task">
-  <title>task</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 有关于 Apache DolphinScheduler 的疑问,加入 Slack 频道来讨论他们 <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span><a href="/zh-cn/index.html"><img cl [...]
-<h4>如何进行任务插件开发?</h4>
-<p>org.apache.dolphinscheduler.spi.task.TaskChannel</p>
-<p>插件实现以上接口即可。主要包含创建任务(任务初始化,任务运行等方法)、任务取消,如果是 yarn 任务,则需要实现 org.apache.dolphinscheduler.plugin.task.api.AbstractYarnTask。</p>
-<p>我们在 dolphinscheduler-task-api 模块提供了所有任务对外访问的 API,而 dolphinscheduler-spi 模块则是 spi 通用代码库,定义了所有的插件模块,比如告警模块,注册中心模块等,你可以详细阅读查看。</p>
-<p><em>NOTICE</em></p>
-<p>由于任务插件涉及到前端页面,目前前端的SPI还没有实现,因此你需要单独实现插件对应的前端页面。</p>
-<p>如果任务插件存在类冲突,你可以采用 <a href="https://maven.apache.org/plugins/maven-shade-plugin/">Shade-Relocating Classes</a> 来解决这种问题。</p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/backend/spi/task.json b/zh-cn/docs/dev/user_doc/development/backend/spi/task.json
deleted file mode 100644
index 8010d032f..000000000
--- a/zh-cn/docs/dev/user_doc/development/backend/spi/task.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "task.md",
-  "__html": "<h2>DolphinScheduler Task SPI 扩展</h2>\n<h4>如何进行任务插件开发?</h4>\n<p>org.apache.dolphinscheduler.spi.task.TaskChannel</p>\n<p>插件实现以上接口即可。主要包含创建任务(任务初始化,任务运行等方法)、任务取消,如果是 yarn 任务,则需要实现 org.apache.dolphinscheduler.plugin.task.api.AbstractYarnTask。</p>\n<p>我们在 dolphinscheduler-task-api 模块提供了所有任务对外访问的 API,而 dolphinscheduler-spi 模块则是 spi 通用代码库,定义了所有的插件模块,比如告警模块,注册中心模块等,你可以详细阅读查看。</p>\n<p><em>NOTICE</em></p>\n<p>由于任务插件涉及到前端页面,目前前端的SPI还没有实现,因此你需要单独实现插件对应的前端页面。</p>\n<p>如果任务插件存在类冲突,你可以采用  [...]
-  "link": "/dist/zh-cn/docs/dev/user_doc/development/backend/spi/task.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/development-environment-setup.html b/zh-cn/docs/dev/user_doc/development/development-environment-setup.html
deleted file mode 100644
index 0c712b399..000000000
--- a/zh-cn/docs/dev/user_doc/development/development-environment-setup.html
+++ /dev/null
@@ -1,168 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="development-environment-setup">
-  <meta name="description" content="development-environment-setup">
-  <title>development-environment-setup</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 有关于 Apache DolphinScheduler 的疑问,加入 Slack 频道来讨论他们 <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span><a href="/zh-cn/index.html"><img cl [...]
-<h2>前置条件</h2>
-<p>在搭建 DolphinScheduler 开发环境之前请确保你已经安装一下软件</p>
-<ul>
-<li><a href="https://git-scm.com/downloads">Git</a>: 版本控制系统</li>
-<li><a href="https://www.oracle.com/technetwork/java/javase/downloads/index.html">JDK</a>: 后端开发</li>
-<li><a href="http://maven.apache.org/download.cgi">Maven</a>: Java包管理系统</li>
-<li><a href="https://nodejs.org/en/download">Node</a>: 前端开发</li>
-</ul>
-<h3>克隆代码库</h3>
-<p>通过你 git 管理工具下载 git 代码,下面以 git-core 为例</p>
-<pre><code class="language-shell">mkdir dolphinscheduler
-cd dolphinscheduler
-git clone git@github.com:apache/dolphinscheduler.git
-</code></pre>
-<h3>编译源码</h3>
-<ul>
-<li>如果使用MySQL数据库,请注意修改pom.xml, 添加 <code>mysql-connector-java</code> 依赖。</li>
-<li>运行 <code>mvn clean install -Prelease -Dmaven.test.skip=true</code></li>
-</ul>
-<h2>开发者须知</h2>
-<p>DolphinScheduler 开发环境配置有两个方式,分别是standalone模式,以及普通模式</p>
-<ul>
-<li><a href="#dolphinscheduler-standalone%E5%BF%AB%E9%80%9F%E5%BC%80%E5%8F%91%E6%A8%A1%E5%BC%8F">standalone模式</a>:<strong>推荐使用,但仅支持 1.3.9 及以后的版本</strong>,方便快速的开发环境搭建,能解决大部分场景的开发</li>
-<li><a href="#dolphinscheduler-%E6%99%AE%E9%80%9A%E5%BC%80%E5%8F%91%E6%A8%A1%E5%BC%8F">普通模式</a>:master、worker、api等单独启动,能更好的的模拟真实生产环境,可以覆盖的测试环境更多</li>
-</ul>
-<h2>DolphinScheduler Standalone快速开发模式</h2>
-<blockquote>
-<p><strong><em>注意:</em></strong> 仅供单机开发调试使用,默认使用 H2 Database,Zookeeper Testing Server
-Standalone 仅在 DolphinScheduler 1.3.9 及以后的版本支持</p>
-</blockquote>
-<h3>分支选择</h3>
-<p>开发不同的代码需要基于不同的分支</p>
-<ul>
-<li>如果想基于二进制包开发,切换到对应版本的代码,如 1.3.9 则是 <code>1.3.9-release</code></li>
-<li>如果想要开发最新代码,切换到 <code>dev</code> 分支</li>
-</ul>
-<h3>启动后端</h3>
-<p>在 Intellij IDEA 找到并启动类 <code>org.apache.dolphinscheduler.server.StandaloneServer</code> 即可完成后端启动</p>
-<h3>启动前端</h3>
-<p>安装前端依赖并运行前端组件</p>
-<pre><code class="language-shell">cd dolphinscheduler-ui
-npm install
-npm run start
-</code></pre>
-<p>截止目前,前后端已成功运行起来,浏览器访问<a href="http://localhost:8888">http://localhost:8888</a>,并使用默认账户密码 <strong>admin/dolphinscheduler123</strong> 即可完成登录</p>
-<h2>DolphinScheduler 普通开发模式</h2>
-<h3>必要软件安装</h3>
-<h4>zookeeper</h4>
-<p>下载 <a href="https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.6.3">ZooKeeper</a>,解压</p>
-<ul>
-<li>
-<p>在 ZooKeeper 的目录下新建 zkData、zkLog文件夹</p>
-</li>
-<li>
-<p>将 conf 目录下的 <code>zoo_sample.cfg</code> 文件,复制一份,重命名为 <code>zoo.cfg</code>,修改其中数据和日志的配置,如:</p>
-<pre><code class="language-shell">dataDir=/data/zookeeper/data ## 此处使用绝对路径
-dataLogDir=/data/zookeeper/datalog
-</code></pre>
-</li>
-<li>
-<p>运行 <code>./bin/zkServer.sh</code></p>
-</li>
-</ul>
-<h4>数据库</h4>
-<p>DolphinScheduler 的元数据存储在关系型数据库中,目前支持的关系型数据库包括 MySQL 以及 PostgreSQL。下面以MySQL为例,启动数据库并创建新 database 作为 DolphinScheduler 元数据库,这里以数据库名 dolphinscheduler 为例</p>
-<p>创建完新数据库后,将 <code>dolphinscheduler/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_mysql.sql</code> 下的 sql 文件直接在 MySQL 中运行,完成数据库初始化</p>
-<h4>启动后端</h4>
-<p>下面步骤将引导如何启动 DolphinScheduler 后端服务</p>
-<h5>必要的准备工作</h5>
-<ul>
-<li>
-<p>打开项目:使用开发工具打开项目,这里以 Intellij IDEA 为例,打开后需要一段时间,让 Intellij IDEA 完成以依赖的下载</p>
-</li>
-<li>
-<p>插件的配置(<strong>仅 2.0 及以后的版本需要</strong>):</p>
-<ul>
-<li>注册中心插件配置, 以Zookeeper 为例 (registry.properties)
-dolphinscheduler-service/src/main/resources/registry.properties</li>
-</ul>
-<pre><code class="language-registry.properties"> registry.plugin.name=zookeeper
- registry.servers=127.0.0.1:2181
-</code></pre>
-</li>
-<li>
-<p>必要的修改</p>
-<ul>
-<li>如果使用 MySQL 作为元数据库,需要先修改 <code>dolphinscheduler/pom.xml</code>,将 <code>mysql-connector-java</code> 依赖的 <code>scope</code> 改为 <code>compile</code>,使用 PostgreSQL 则不需要</li>
-<li>修改数据库配置,修改 <code>dolphinscheduler-dao/src/main/resources/application-mysql.yaml</code> 文件中的数据库配置</li>
-</ul>
-<p>本样例以 MySQL 为例,其中数据库名为 dolphinscheduler,账户名密码均为 dolphinscheduler</p>
-<pre><code class="language-application-mysql.yaml"> spring:
-   datasource:
-     driver-class-name: com.mysql.jdbc.Driver
-     url: jdbc:mysql://127.0.0.1:3306/dolphinscheduler?useUnicode=true&amp;characterEncoding=UTF-8
-     username: ds_user
-     password: dolphinscheduler
-</code></pre>
-</li>
-<li>
-<p>修改日志级别:为以下配置增加一行内容 <code>&lt;appender-ref ref=&quot;STDOUT&quot;/&gt;</code> 使日志能在命令行中显示</p>
-<p><code>dolphinscheduler-server/src/main/resources/logback-worker.xml</code></p>
-<p><code>dolphinscheduler-server/src/main/resources/logback-master.xml</code></p>
-<p><code>dolphinscheduler-api/src/main/resources/logback-api.xml</code></p>
-<p>修改后的结果如下:</p>
-<pre><code class="language-diff">&lt;root level=&quot;INFO&quot;&gt;
-<span class="hljs-addition">+  &lt;appender-ref ref=&quot;STDOUT&quot;/&gt;</span>
-  &lt;appender-ref ref=&quot;APILOGFILE&quot;/&gt;
-  &lt;appender-ref ref=&quot;SKYWALKING-LOG&quot;/&gt;
-&lt;/root&gt;
-</code></pre>
-</li>
-</ul>
-<h5>启动服务</h5>
-<p>我们需要启动三个服务,包括 MasterServer,WorkerServer,ApiApplicationServer</p>
-<ul>
-<li>MasterServer:在 Intellij IDEA 中执行 <code>org.apache.dolphinscheduler.server.master.MasterServer</code> 中的 <code>main</code> 方法,并配置 <em>VM Options</em> <code>-Dlogging.config=classpath:logback-master.xml -Ddruid.mysql.usePingMethod=false -Dspring.profiles.active=mysql</code></li>
-<li>WorkerServer:在 Intellij IDEA 中执行 <code>org.apache.dolphinscheduler.server.worker.WorkerServer</code> 中的 <code>main</code> 方法,并配置 <em>VM Options</em> <code>-Dlogging.config=classpath:logback-worker.xml -Ddruid.mysql.usePingMethod=false -Dspring.profiles.active=mysql</code></li>
-<li>ApiApplicationServer:在 Intellij IDEA 中执行 <code>org.apache.dolphinscheduler.api.ApiApplicationServer</code> 中的 <code>main</code> 方法,并配置 <em>VM Options</em> <code>-Dlogging.config=classpath:logback-api.xml -Dspring.profiles.active=api,mysql</code>。启动完成可以浏览 Open API 文档,地址为 <a href="http://localhost:12345/dolphinscheduler/doc.html">http://localhost:12345/dolphinscheduler/doc.html</a></li>
-</ul>
-<blockquote>
-<p>VM Options <code>-Dspring.profiles.active=mysql</code> 中 <code>mysql</code> 表示指定的配置文件</p>
-</blockquote>
-<h3>启动前端</h3>
-<p>安装前端依赖并运行前端组件</p>
-<pre><code class="language-shell">cd dolphinscheduler-ui
-npm install
-npm run start
-</code></pre>
-<p>截止目前,前后端已成功运行起来,浏览器访问<a href="http://localhost:8888">http://localhost:8888</a>,并使用默认账户密码 <strong>admin/dolphinscheduler123</strong> 即可完成登录</p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/development-environment-setup.json b/zh-cn/docs/dev/user_doc/development/development-environment-setup.json
deleted file mode 100644
index df05b4f70..000000000
--- a/zh-cn/docs/dev/user_doc/development/development-environment-setup.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "development-environment-setup.md",
-  "__html": "<h1>DolphinScheduler 开发手册</h1>\n<h2>前置条件</h2>\n<p>在搭建 DolphinScheduler 开发环境之前请确保你已经安装一下软件</p>\n<ul>\n<li><a href=\"https://git-scm.com/downloads\">Git</a>: 版本控制系统</li>\n<li><a href=\"https://www.oracle.com/technetwork/java/javase/downloads/index.html\">JDK</a>: 后端开发</li>\n<li><a href=\"http://maven.apache.org/download.cgi\">Maven</a>: Java包管理系统</li>\n<li><a href=\"https://nodejs.org/en/download\">Node</a>: 前端开发</li>\n</ul>\n<h3>克隆代码库</h3>\n<p>通过你 git 管理工具下载 git 代码,下面以 git-co [...]
-  "link": "/dist/zh-cn/docs/dev/user_doc/development/development-environment-setup.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/e2e-test.html b/zh-cn/docs/dev/user_doc/development/e2e-test.html
deleted file mode 100644
index c57a92a55..000000000
--- a/zh-cn/docs/dev/user_doc/development/e2e-test.html
+++ /dev/null
@@ -1,188 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="e2e-test">
-  <meta name="description" content="e2e-test">
-  <title>e2e-test</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 有关于 Apache DolphinScheduler 的疑问,加入 Slack 频道来讨论他们 <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span><a href="/zh-cn/index.html"><img cl [...]
-<h2>一、前置知识:</h2>
-<h3>1、E2E 测试与单元测试的区别</h3>
-<p>E2E,是“End to End”的缩写,可以翻译成“端到端”测试。它模仿用户,从某个入口开始,逐步执行操作,直到完成某项工作。与单元测试不同,后者通常需要测试参数、参数类型、参数值、参数数量、返回值、抛出错误等,目的在于保证特定函数能够在任何情况下都稳定可靠完成工作。单元测试假定只要所有函数都正常工作,那么整个产品就能正常工作。</p>
-<p>相对来说,E2E 测试并没有那么强调要覆盖全部使用场景,它关注的<strong>一个完整的操作链是否能够完成</strong>。对于 Web 前端来说,还关注<strong>界面布局、内容信息是否符合预期</strong>。</p>
-<p>比如,登陆界面的 E2E 测试,关注用户是否能够正常输入,正常登录;登陆失败的话,是否能够正确显示错误信息。至于输入不合法的内容是否处理,并不是所关注的重点。</p>
-<h3>2、Selenium 测试框架</h3>
-<p><a href="https://www.selenium.dev">Selenium</a> 是一种开源测试工具,用于在 Web 浏览器上执行自动化测试。该框架使用 WebDriver 通过浏览器的原生组件,转化 Web Service 的命令为浏览器 native 的调用来完成操作。简单来说,就是模拟浏览器,对于页面的元素进行选择操作。</p>
-<p>WebDriver 是一个 API 和协议,它定义了一个语言中立的接口,用于控制 web 浏览器的行为。 每个浏览器都有一个特定的 WebDriver 实现,称为驱动程序。驱动程序是负责委派给浏览器的组件,并处理与 Selenium 和浏览器之间的通信。</p>
-<p>Selenium 框架通过一个面向用户的界面将所有这些部分连接在一起, 该界面允许透明地使用不同的浏览器后端, 从而实现跨浏览器和跨平台自动化。</p>
-<h2>二、E2E 测试</h2>
-<h3>1、E2E-Pages</h3>
-<p>DolphinScheduler 的 E2E 测试使用 docker-compose 部署,当前测试的为单机模式,主要用于检验一些例如“增删改查”基本功能,后期如需做集群验证,例如不同服务之间的协作,或者各个服务之间的通讯机制,可参考 <code>deploy/docker/docker-compose.yml</code>来配置。</p>
-<p>对于 E2E 测试(前端这一块),使用 <a href="https://www.selenium.dev/documentation/guidelines/page_object_models/">页面模型</a> 的形式,主要为每一个页面建立一个对应的模型。下面以登录页为例:</p>
-<pre><code class="language-java"><span class="hljs-keyword">package</span> org.apache.dolphinscheduler.e2e.pages;
-
-<span class="hljs-keyword">import</span> org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
-<span class="hljs-keyword">import</span> org.apache.dolphinscheduler.e2e.pages.security.TenantPage;
-
-<span class="hljs-keyword">import</span> org.openqa.selenium.WebElement;
-<span class="hljs-keyword">import</span> org.openqa.selenium.remote.RemoteWebDriver;
-<span class="hljs-keyword">import</span> org.openqa.selenium.support.FindBy;
-<span class="hljs-keyword">import</span> org.openqa.selenium.support.ui.ExpectedConditions;
-<span class="hljs-keyword">import</span> org.openqa.selenium.support.ui.WebDriverWait;
-
-<span class="hljs-keyword">import</span> lombok.Getter;
-<span class="hljs-keyword">import</span> lombok.SneakyThrows;
-
-<span class="hljs-meta">@Getter</span>
-<span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LoginPage</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">NavBarPage</span> </span>{
-    <span class="hljs-meta">@FindBy(id = &quot;inputUsername&quot;)</span>
-    <span class="hljs-keyword">private</span> WebElement inputUsername;
-
-    <span class="hljs-meta">@FindBy(id = &quot;inputPassword&quot;)</span>
-    <span class="hljs-keyword">private</span> WebElement inputPassword;
-
-    <span class="hljs-meta">@FindBy(id = &quot;btnLogin&quot;)</span>
-    <span class="hljs-keyword">private</span> WebElement buttonLogin;
-
-    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">LoginPage</span><span class="hljs-params">(RemoteWebDriver driver)</span> </span>{
-        <span class="hljs-keyword">super</span>(driver);
-    }
-
-    <span class="hljs-meta">@SneakyThrows</span>
-    <span class="hljs-function"><span class="hljs-keyword">public</span> TenantPage <span class="hljs-title">login</span><span class="hljs-params">(String username, String password)</span> </span>{
-        inputUsername().sendKeys(username);
-        inputPassword().sendKeys(password);
-        buttonLogin().click();
-
-        <span class="hljs-keyword">new</span> WebDriverWait(driver, <span class="hljs-number">10</span>)
-            .until(ExpectedConditions.urlContains(<span class="hljs-string">&quot;/#/security&quot;</span>));
-
-        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> TenantPage(driver);
-    }
-}
-</code></pre>
-<p>在测试过程中,我们只针对所需要关注的元素进行测试,而非页面中的所有元素,所以在登陆页面只对用户名、密码和登录按钮这些元素进行声明。通过 Selenium 测试框架所提供的 FindBy 接口来查找 Vue 文件中对应的 id 或 class。</p>
-<p>此外,在测试过程中,并不会直接去操作元素,一般选择封装对应的方法,以达到复用的效果。例如想要登录的话,直接传入用户名和密码,通过 <code>public TenantPage login()</code> 方法去操作所传入的元素,从而达到实现登录的效果,即当用户完成登录之后,跳转到安全中心(默认进入到租户管理页面)。</p>
-<p>在安全中心页面(SecurityPage)提供了 goToTab 方法,用于测试对应侧栏的跳转,主要包括:租户管理(TenantPage)、用户管理(UserPage)、工作组管理(WorkerGroupPge)和队列管理(QueuePage)。这些页面的实现方式同理,主要测试表单的输入、增加和删除按钮是否能够返回出对应的页面。</p>
-<pre><code class="language-java"> <span class="hljs-keyword">public</span> &lt;T extends SecurityPage.Tab&gt; <span class="hljs-function">T <span class="hljs-title">goToTab</span><span class="hljs-params">(Class&lt;T&gt; tab)</span> </span>{
-        <span class="hljs-keyword">if</span> (tab == TenantPage.class) {
-            WebElement menuTenantManageElement = <span class="hljs-keyword">new</span> WebDriverWait(driver, <span class="hljs-number">60</span>)
-                    .until(ExpectedConditions.elementToBeClickable(menuTenantManage));
-            ((JavascriptExecutor)driver).executeScript(<span class="hljs-string">&quot;arguments[0].click();&quot;</span>, menuTenantManageElement);
-            <span class="hljs-keyword">return</span> tab.cast(<span class="hljs-keyword">new</span> TenantPage(driver));
-        }
-        <span class="hljs-keyword">if</span> (tab == UserPage.class) {
-            WebElement menUserManageElement = <span class="hljs-keyword">new</span> WebDriverWait(driver, <span class="hljs-number">60</span>)
-                    .until(ExpectedConditions.elementToBeClickable(menUserManage));
-            ((JavascriptExecutor)driver).executeScript(<span class="hljs-string">&quot;arguments[0].click();&quot;</span>, menUserManageElement);
-            <span class="hljs-keyword">return</span> tab.cast(<span class="hljs-keyword">new</span> UserPage(driver));
-        }
-        <span class="hljs-keyword">if</span> (tab == WorkerGroupPage.class) {
-            WebElement menWorkerGroupManageElement = <span class="hljs-keyword">new</span> WebDriverWait(driver, <span class="hljs-number">60</span>)
-                    .until(ExpectedConditions.elementToBeClickable(menWorkerGroupManage));
-            ((JavascriptExecutor)driver).executeScript(<span class="hljs-string">&quot;arguments[0].click();&quot;</span>, menWorkerGroupManageElement);
-            <span class="hljs-keyword">return</span> tab.cast(<span class="hljs-keyword">new</span> WorkerGroupPage(driver));
-        }
-        <span class="hljs-keyword">if</span> (tab == QueuePage.class) {
-            menuQueueManage().click();
-            <span class="hljs-keyword">return</span> tab.cast(<span class="hljs-keyword">new</span> QueuePage(driver));
-        }
-        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> UnsupportedOperationException(<span class="hljs-string">&quot;Unknown tab: &quot;</span> + tab.getName());
-    }
-</code></pre>
-<p><img src="/img/e2e-test/SecurityPage.png" alt="SecurityPage"></p>
-<p>对于导航栏选项的跳转,在<code>org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java</code> 中提供了 goToNav 的方法。当前支持的页面为:项目管理(ProjectPage)、安全中心(SecurityPage)和资源中心(ResourcePage)。</p>
-<pre><code class="language-java">    <span class="hljs-keyword">public</span> &lt;T extends NavBarItem&gt; <span class="hljs-function">T <span class="hljs-title">goToNav</span><span class="hljs-params">(Class&lt;T&gt; nav)</span> </span>{
-        <span class="hljs-keyword">if</span> (nav == ProjectPage.class) {
-            WebElement projectTabElement = <span class="hljs-keyword">new</span> WebDriverWait(driver, <span class="hljs-number">60</span>)
-                .until(ExpectedConditions.elementToBeClickable(projectTab));
-            ((JavascriptExecutor)driver).executeScript(<span class="hljs-string">&quot;arguments[0].click();&quot;</span>, projectTabElement);
-            <span class="hljs-keyword">return</span> nav.cast(<span class="hljs-keyword">new</span> ProjectPage(driver));
-        }
-
-        <span class="hljs-keyword">if</span> (nav == SecurityPage.class) {
-            WebElement securityTabElement = <span class="hljs-keyword">new</span> WebDriverWait(driver, <span class="hljs-number">60</span>)
-                .until(ExpectedConditions.elementToBeClickable(securityTab));
-            ((JavascriptExecutor)driver).executeScript(<span class="hljs-string">&quot;arguments[0].click();&quot;</span>, securityTabElement);
-            <span class="hljs-keyword">return</span> nav.cast(<span class="hljs-keyword">new</span> SecurityPage(driver));
-        }
-
-        <span class="hljs-keyword">if</span> (nav == ResourcePage.class) {
-            WebElement resourceTabElement = <span class="hljs-keyword">new</span> WebDriverWait(driver, <span class="hljs-number">60</span>)
-                .until(ExpectedConditions.elementToBeClickable(resourceTab));
-            ((JavascriptExecutor)driver).executeScript(<span class="hljs-string">&quot;arguments[0].click();&quot;</span>, resourceTabElement);
-            <span class="hljs-keyword">return</span> nav.cast(<span class="hljs-keyword">new</span> ResourcePage(driver));
-        }
-
-        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> UnsupportedOperationException(<span class="hljs-string">&quot;Unknown nav bar&quot;</span>);
-    }
-</code></pre>
-<h3>2、E2E-Cases</h3>
-<p>当前所支持的 E2E 测试案例,主要包括:文件管理、项目管理、队列管理、租户管理、用户管理、Worker 分组管理和工作流测试。</p>
-<p><img src="/img/e2e-test/E2E_Cases.png" alt="E2E_Cases"></p>
-<p>下面以租户管理测试为例,前文已经说明,我们使用 docker-compose 进行部署,所以每个测试案例,都需要以注解的形式引入对应的文件。</p>
-<p>使用 Selenium 所提供的 RemoteWebDriver 来加载浏览器。在每个测试案例开始之前都需要进行一些准备工作。比如:登录用户、跳转到对应的页面(根据具体的测试案例而定)。</p>
-<pre><code class="language-java">    <span class="hljs-meta">@BeforeAll</span>
-    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setup</span><span class="hljs-params">()</span> </span>{
-        <span class="hljs-keyword">new</span> LoginPage(browser)
-                .login(<span class="hljs-string">&quot;admin&quot;</span>, <span class="hljs-string">&quot;dolphinscheduler123&quot;</span>) <span class="hljs-comment">// 登录进入租户界面</span>
-                .goToNav(SecurityPage.class) <span class="hljs-comment">// 安全中心</span>
-                .goToTab(TenantPage.class)
-        ;
-    }
-</code></pre>
-<p>在完成准备工作之后,就是正式的测试案例编写。我们使用 @Order() 注解的形式,用于模块化,确认测试顺序。在进行测试之后,使用断言来判断测试是否成功,如果断言返回 true,则表示创建租户成功。可参考创建租户的测试代码:</p>
-<pre><code class="language-java">    <span class="hljs-meta">@Test</span>
-    <span class="hljs-meta">@Order(10)</span>
-    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">testCreateTenant</span><span class="hljs-params">()</span> </span>{
-        <span class="hljs-keyword">final</span> TenantPage page = <span class="hljs-keyword">new</span> TenantPage(browser);
-        page.create(tenant);
-
-        await().untilAsserted(() -&gt; assertThat(page.tenantList())
-                .as(<span class="hljs-string">&quot;Tenant list should contain newly-created tenant&quot;</span>)
-                .extracting(WebElement::getText)
-                .anyMatch(it -&gt; it.contains(tenant)));
-    }
-</code></pre>
-<p>其余的都是类似的情况,可参考具体的源码来理解。</p>
-<p><a href="https://github.com/apache/dolphinscheduler/tree/dev/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases">https://github.com/apache/dolphinscheduler/tree/dev/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases</a></p>
-<h2>三、补充</h2>
-<p>在本地运行的时候,首先需要启动相应的本地服务,可以参考该页面: <a href="https://dolphinscheduler.apache.org/zh-cn/development/development-environment-setup.html">环境搭建</a></p>
-<p>在本地运行 E2E 测试的时候,可以配置 <code>-Dlocal=true</code> 参数,用于连接本地,方便对于 UI 界面的更改。</p>
-<p>如果是<code>M1</code>芯片的机器,可以使用<code>-Dm1_chip=true</code> 参数,用于配置使用<code>ARM64</code>支持的容器。</p>
-<p><img src="/img/e2e-test/Dlocal.png" alt="Dlocal"></p>
-<p>在本地运行过程中,如果出现连接超时,可增大加载时间,建议 30 及其以上。</p>
-<p><img src="/img/e2e-test/timeout.png" alt="timeout"></p>
-<p>测试的运行过程将会以 MP4 的文件格式存在。</p>
-<p><img src="/img/e2e-test/MP4.png" alt="MP4"></p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/e2e-test.json b/zh-cn/docs/dev/user_doc/development/e2e-test.json
deleted file mode 100644
index fa2e13c89..000000000
--- a/zh-cn/docs/dev/user_doc/development/e2e-test.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "e2e-test.md",
-  "__html": "<h1>DolphinScheduler — E2E 自动化测试</h1>\n<h2>一、前置知识:</h2>\n<h3>1、E2E 测试与单元测试的区别</h3>\n<p>E2E,是“End to End”的缩写,可以翻译成“端到端”测试。它模仿用户,从某个入口开始,逐步执行操作,直到完成某项工作。与单元测试不同,后者通常需要测试参数、参数类型、参数值、参数数量、返回值、抛出错误等,目的在于保证特定函数能够在任何情况下都稳定可靠完成工作。单元测试假定只要所有函数都正常工作,那么整个产品就能正常工作。</p>\n<p>相对来说,E2E 测试并没有那么强调要覆盖全部使用场景,它关注的<strong>一个完整的操作链是否能够完成</strong>。对于 Web 前端来说,还关注<strong>界面布局、内容信息是否符合预期</strong>。</p>\n<p>比如,登陆界面的 E2E 测试,关注用户是否能够正常输入,正常登录;登陆失败的�
 �,是否能够正确显示错误信息。至于输入不合法的内容是否处理,并不是所关注的重点。</p>\n<h3>2、Selen [...]
-  "link": "/dist/zh-cn/docs/dev/user_doc/development/e2e-test.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/frontend-development.html b/zh-cn/docs/dev/user_doc/development/frontend-development.html
deleted file mode 100644
index b7f6bdd1a..000000000
--- a/zh-cn/docs/dev/user_doc/development/frontend-development.html
+++ /dev/null
@@ -1,538 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="frontend-development">
-  <meta name="description" content="frontend-development">
-  <title>frontend-development</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 有关于 Apache DolphinScheduler 的疑问,加入 Slack 频道来讨论他们 <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span><a href="/zh-cn/index.html"><img cl [...]
-<h3>技术选型</h3>
-<pre><code>Vue mvvm 框架
-
-Es6 ECMAScript 6.0
-
-Ans-ui Analysys-ui
-
-D3 可视化库图表库
-
-Jsplumb 连线插件库
-
-Lodash 高性能的 JavaScript 实用工具库
-</code></pre>
-<h3>开发环境搭建</h3>
-<ul>
-<li>
-<h4>Node安装</h4>
-</li>
-</ul>
-<p>Node包下载 (注意版本 v12.20.2) <code>https://nodejs.org/download/release/v12.20.2/</code></p>
-<ul>
-<li>
-<h4>前端项目构建</h4>
-</li>
-</ul>
-<p>用命令行模式 <code>cd</code>  进入 <code>dolphinscheduler-ui</code>项目目录并执行 <code>npm install</code> 拉取项目依赖包</p>
-<blockquote>
-<p>如果 <code>npm install</code> 速度非常慢,你可以设置淘宝镜像</p>
-</blockquote>
-<pre><code>npm config set registry http://registry.npm.taobao.org/
-</code></pre>
-<ul>
-<li>修改 <code>dolphinscheduler-ui/.env</code> 文件中的 <code>API_BASE</code>,用于跟后端交互:</li>
-</ul>
-<pre><code># 代理的接口地址(自行修改)
-API_BASE = http://127.0.0.1:12345
-</code></pre>
-<blockquote>
-<h5>!!!这里特别注意 项目如果在拉取依赖包的过程中报 &quot; node-sass error &quot; 错误,请在执行完后再次执行以下命令</h5>
-</blockquote>
-<pre><code class="language-bash">npm install node-sass --unsafe-perm <span class="hljs-comment">#单独安装node-sass依赖</span>
-</code></pre>
-<ul>
-<li>
-<h4>开发环境运行</h4>
-</li>
-<li><code>npm start</code> 项目开发环境 (启动后访问地址 <a href="http://localhost:8888">http://localhost:8888</a>)</li>
-</ul>
-<h4>前端项目发布</h4>
-<ul>
-<li><code>npm run build</code> 项目打包 (打包后根目录会创建一个名为dist文件夹,用于发布线上Nginx)</li>
-</ul>
-<p>运行 <code>npm run build</code> 命令,生成打包文件(dist)包</p>
-<p>再拷贝到服务器对应的目录下(前端服务静态页面存放目录)</p>
-<p>访问地址 <code>http://localhost:8888</code></p>
-<h4>Linux下使用node启动并且守护进程</h4>
-<p>安装pm2 <code>npm install -g pm2</code></p>
-<p>在项目<code>dolphinscheduler-ui</code>根目录执行 <code>pm2 start npm -- run dev</code> 启动项目</p>
-<h4>命令</h4>
-<ul>
-<li>
-<p>启用 <code>pm2 start npm -- run dev</code></p>
-</li>
-<li>
-<p>停止 <code>pm2 stop npm</code></p>
-</li>
-<li>
-<p>删除 <code>pm2 delete npm</code></p>
-</li>
-<li>
-<p>状态 <code>pm2 list</code></p>
-</li>
-</ul>
-<pre><code>
-[root@localhost dolphinscheduler-ui]# pm2 start npm -- run dev
-[PM2] Applying action restartProcessId on app [npm](ids: 0)
-[PM2] [npm](0) ✓
-[PM2] Process successfully started
-┌──────────┬────┬─────────┬──────┬──────┬────────┬─────────┬────────┬─────┬──────────┬──────┬──────────┐
-│ App name │ id │ version │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem      │ user │ watching │
-├──────────┼────┼─────────┼──────┼──────┼────────┼─────────┼────────┼─────┼──────────┼──────┼──────────┤
-│ npm      │ 0  │ N/A     │ fork │ 6168 │ online │ 31      │ 0s     │ 0%  │ 5.6 MB   │ root │ disabled │
-└──────────┴────┴─────────┴──────┴──────┴────────┴─────────┴────────┴─────┴──────────┴──────┴──────────┘
- Use `pm2 show &lt;id|name&gt;` to get more details about an app
-
-</code></pre>
-<h3>项目目录结构</h3>
-<p><code>build</code> 打包及开发环境项目的一些webpack配置</p>
-<p><code>node_modules</code> 开发环境node依赖包</p>
-<p><code>src</code> 项目所需文件</p>
-<p><code>src =&gt; combo</code> 项目第三方资源本地化 <code>npm run combo</code>具体查看<code>build/combo.js</code></p>
-<p><code>src =&gt; font</code> 字体图标库可访问 <code>https://www.iconfont.cn</code> 进行添加 注意:字体库用的自己的 二次开发需要重新引入自己的库 <code>src/sass/common/_font.scss</code></p>
-<p><code>src =&gt; images</code> 公共图片存放</p>
-<p><code>src =&gt; js</code> js/vue</p>
-<p><code>src =&gt; lib</code> 公司内部组件(公司组件库开源后可删掉)</p>
-<p><code>src =&gt; sass</code> sass文件 一个页面对应一个sass文件</p>
-<p><code>src =&gt; view</code> 页面文件 一个页面对应一个html文件</p>
-<pre><code>&gt; 项目采用vue单页面应用(SPA)开发
-- 所有页面入口文件在 `src/js/conf/${对应页面文件名 =&gt; home}` 的 `index.js` 入口文件
-- 对应的sass文件则在 `src/sass/conf/${对应页面文件名 =&gt; home}/index.scss`
-- 对应的html文件则在 `src/view/${对应页面文件名 =&gt; home}/index.html`
-</code></pre>
-<p>公共模块及util <code>src/js/module</code></p>
-<p><code>components</code> =&gt; 内部项目公共组件</p>
-<p><code>download</code> =&gt; 下载组件</p>
-<p><code>echarts</code> =&gt; 图表组件</p>
-<p><code>filter</code> =&gt; 过滤器和vue管道</p>
-<p><code>i18n</code> =&gt; 国际化</p>
-<p><code>io</code> =&gt; io请求封装 基于axios</p>
-<p><code>mixin</code> =&gt; vue mixin 公共部分 用于disabled操作</p>
-<p><code>permissions</code> =&gt; 权限操作</p>
-<p><code>util</code> =&gt; 工具</p>
-<h3>系统功能模块</h3>
-<p>首页 =&gt; <code>http://localhost:8888/#/home</code></p>
-<p>项目管理 =&gt; <code>http://localhost:8888/#/projects/list</code></p>
-<pre><code>| 项目首页
-| 工作流
-  - 工作流定义
-  - 工作流实例
-  - 任务实例
-</code></pre>
-<p>资源管理 =&gt; <code>http://localhost:8888/#/resource/file</code></p>
-<pre><code>| 文件管理
-| UDF管理
-  - 资源管理
-  - 函数管理
-</code></pre>
-<p>数据源管理 =&gt; <code>http://localhost:8888/#/datasource/list</code></p>
-<p>安全中心 =&gt; <code>http://localhost:8888/#/security/tenant</code></p>
-<pre><code>| 租户管理
-| 用户管理
-| 告警组管理
-  - master
-  - worker
-</code></pre>
-<p>用户中心 =&gt; <code>http://localhost:8888/#/user/account</code></p>
-<h2>路由和状态管理</h2>
-<p>项目 <code>src/js/conf/home</code> 下分为</p>
-<p><code>pages</code> =&gt; 路由指向页面目录</p>
-<pre><code> 路由地址对应的页面文件
-</code></pre>
-<p><code>router</code> =&gt; 路由管理</p>
-<pre><code>vue的路由器,在每个页面的入口文件index.js 都会注册进来 具体操作:https://router.vuejs.org/zh/
-</code></pre>
-<p><code>store</code> =&gt; 状态管理</p>
-<pre><code>每个路由对应的页面都有一个状态管理的文件 分为:
-
-actions =&gt; mapActions =&gt; 详情:https://vuex.vuejs.org/zh/guide/actions.html
-
-getters =&gt; mapGetters =&gt; 详情:https://vuex.vuejs.org/zh/guide/getters.html
-
-index =&gt; 入口
-
-mutations =&gt; mapMutations =&gt; 详情:https://vuex.vuejs.org/zh/guide/mutations.html
-
-state =&gt; mapState =&gt; 详情:https://vuex.vuejs.org/zh/guide/state.html
-
-具体操作:https://vuex.vuejs.org/zh/
-</code></pre>
-<h2>规范</h2>
-<h2>Vue规范</h2>
-<h5>1.组件名</h5>
-<p>组件名为多个单词,并且用连接线(-)连接,避免与 HTML 标签冲突,并且结构更加清晰。</p>
-<pre><code>// 正例
-export default {
-    name: 'page-article-item'
-}
-</code></pre>
-<h5>2.组件文件</h5>
-<p><code>src/js/module/components</code>项目内部公共组件书写文件夹名与文件名同名,公共组件内部所拆分的子组件与util工具都放置组件内部 <code>_source</code>文件夹里。</p>
-<pre><code>└── components
-    ├── header
-        ├── header.vue
-        └── _source
-            └── nav.vue
-            └── util.js
-    ├── conditions
-        ├── conditions.vue
-        └── _source
-            └── search.vue
-            └── util.js
-</code></pre>
-<h5>3.Prop</h5>
-<p>定义 Prop 的时候应该始终以驼峰格式(camelCase)命名,在父组件赋值的时候使用连接线(-)。
-这里遵循每个语言的特性,因为在 HTML 标记中对大小写是不敏感的,使用连接线更加友好;而在 JavaScript 中更自然的是驼峰命名。</p>
-<pre><code>// Vue
-props: {
-    articleStatus: Boolean
-}
-// HTML
-&lt;article-item :article-status=&quot;true&quot;&gt;&lt;/article-item&gt;
-</code></pre>
-<p>Prop 的定义应该尽量详细的指定其类型、默认值和验证。</p>
-<p>示例:</p>
-<pre><code>props: {
-    attrM: Number,
-    attrA: {
-        type: String,
-        required: true
-    },
-    attrZ: {
-        type: Object,
-        // 数组/对象的默认值应该由一个工厂函数返回
-        default: function () {
-            return {
-                msg: '成就你我'
-            }
-        }
-    },
-    attrE: {
-        type: String,
-        validator: function (v) {
-            return !(['success', 'fail'].indexOf(v) === -1) 
-        }
-    }
-}
-</code></pre>
-<h5>4.v-for</h5>
-<p>在执行 v-for 遍历的时候,总是应该带上 key 值使更新 DOM 时渲染效率更高。</p>
-<pre><code>&lt;ul&gt;
-    &lt;li v-for=&quot;item in list&quot; :key=&quot;item.id&quot;&gt;
-        {{ item.title }}
-    &lt;/li&gt;
-&lt;/ul&gt;
-</code></pre>
-<p>v-for 应该避免与 v-if 在同一个元素(<code>例如:&lt;li&gt;</code>)上使用,因为 v-for 的优先级比 v-if 更高,为了避免无效计算和渲染,应该尽量将 v-if 放到容器的父元素之上。</p>
-<pre><code>&lt;ul v-if=&quot;showList&quot;&gt;
-    &lt;li v-for=&quot;item in list&quot; :key=&quot;item.id&quot;&gt;
-        {{ item.title }}
-    &lt;/li&gt;
-&lt;/ul&gt;
-</code></pre>
-<h5>5.v-if / v-else-if / v-else</h5>
-<p>若同一组 v-if 逻辑控制中的元素逻辑相同,Vue 为了更高效的元素切换,会复用相同的部分,<code>例如:value</code>。为了避免复用带来的不合理效果,应该在同种元素上加上 key 做标识。</p>
-<pre><code>&lt;div v-if=&quot;hasData&quot; key=&quot;mazey-data&quot;&gt;
-    &lt;span&gt;{{ mazeyData }}&lt;/span&gt;
-&lt;/div&gt;
-&lt;div v-else key=&quot;mazey-none&quot;&gt;
-    &lt;span&gt;无数据&lt;/span&gt;
-&lt;/div&gt;
-</code></pre>
-<h5>6.指令缩写</h5>
-<p>为了统一规范始终使用指令缩写,使用<code>v-bind</code>,<code>v-on</code>并没有什么不好,这里仅为了统一规范。</p>
-<pre><code>&lt;input :value=&quot;mazeyUser&quot; @click=&quot;verifyUser&quot;&gt;
-</code></pre>
-<h5>7.单文件组件的顶级元素顺序</h5>
-<p>样式后续都是打包在一个文件里,所有在单个vue文件中定义的样式,在别的文件里同类名的样式也是会生效的所有在创建一个组件前都会有个顶级类名
-注意:项目内已经增加了sass插件,单个vue文件里可以直接书写sass语法
-为了统一和便于阅读,应该按 <code>&lt;template&gt;</code>、<code>&lt;script&gt;</code>、<code>&lt;style&gt;</code>的顺序放置。</p>
-<pre><code>&lt;template&gt;
-  &lt;div class=&quot;test-model&quot;&gt;
-    test
-  &lt;/div&gt;
-&lt;/template&gt;
-&lt;script&gt;
-  export default {
-    name: &quot;test&quot;,
-    data() {
-      return {}
-    },
-    props: {},
-    methods: {},
-    watch: {},
-    beforeCreate() {
-    },
-    created() {
-    },
-    beforeMount() {
-    },
-    mounted() {
-    },
-    beforeUpdate() {
-    },
-    updated() {
-    },
-    beforeDestroy() {
-    },
-    destroyed() {
-    },
-    computed: {},
-    components: {},
-  }
-&lt;/script&gt;
-
-&lt;style lang=&quot;scss&quot; rel=&quot;stylesheet/scss&quot;&gt;
-  .test-model {
-
-  }
-&lt;/style&gt;
-
-</code></pre>
-<h2>JavaScript规范</h2>
-<h5>1.var / let / const</h5>
-<p>建议不再使用 var,而使用 let / const,优先使用 const。任何一个变量的使用都要提前申明,除了 function 定义的函数可以随便放在任何位置。</p>
-<h5>2.引号</h5>
-<pre><code>const foo = '后除'
-const bar = `${foo},前端工程师`
-</code></pre>
-<h5>3.函数</h5>
-<p>匿名函数统一使用箭头函数,多个参数/返回值时优先使用对象的结构赋值。</p>
-<pre><code>function getPersonInfo ({name, sex}) {
-    // ...
-    return {name, gender}
-}
-</code></pre>
-<p>函数名统一使用驼峰命名,以大写字母开头申明的都是构造函数,使用小写字母开头的都是普通函数,也不该使用 new 操作符去操作普通函数。</p>
-<h5>4.对象</h5>
-<pre><code>const foo = {a: 0, b: 1}
-const bar = JSON.parse(JSON.stringify(foo))
-
-const foo = {a: 0, b: 1}
-const bar = {...foo, c: 2}
-
-const foo = {a: 3}
-Object.assign(foo, {b: 4})
-
-const myMap = new Map([])
-for (let [key, value] of myMap.entries()) {
-    // ...
-}
-</code></pre>
-<h5>5.模块</h5>
-<p>统一使用 import / export 的方式管理项目的模块。</p>
-<pre><code>// lib.js
-export default {}
-
-// app.js
-import app from './lib'
-</code></pre>
-<p>import 统一放在文件顶部。</p>
-<p>如果模块只有一个输出值,使用 <code>export default</code>,否则不用。</p>
-<h2>HTML / CSS</h2>
-<h6>1.标签</h6>
-<p>在引用外部 CSS 或 JavaScript 时不写 type 属性。HTML5 默认 type 为 <code>text/css</code> 和 <code>text/javascript</code> 属性,所以没必要指定。</p>
-<pre><code>&lt;link rel=&quot;stylesheet&quot; href=&quot;//www.test.com/css/test.css&quot;&gt;
-&lt;script src=&quot;//www.test.com/js/test.js&quot;&gt;&lt;/script&gt;
-</code></pre>
-<h5>2.命名</h5>
-<p>Class 和 ID 的命名应该语义化,通过看名字就知道是干嘛的;多个单词用连接线 - 连接。</p>
-<pre><code>// 正例
-.test-header{
-    font-size: 20px;
-}
-</code></pre>
-<h5>3.属性缩写</h5>
-<p>CSS 属性尽量使用缩写,提高代码的效率和方便理解。</p>
-<pre><code>// 反例
-border-width: 1px;
-border-style: solid;
-border-color: #ccc;
-
-// 正例
-border: 1px solid #ccc;
-</code></pre>
-<h5>4.文档类型</h5>
-<p>应该总是使用 HTML5 标准。</p>
-<pre><code>&lt;!DOCTYPE html&gt;
-</code></pre>
-<h5>5.注释</h5>
-<p>应该给一个模块文件写一个区块注释。</p>
-<pre><code>/**
-* @module mazey/api
-* @author Mazey &lt;mazey@mazey.net&gt;
-* @description test.
-* */
-</code></pre>
-<h2>接口</h2>
-<h5>所有的接口都以 Promise 形式返回</h5>
-<p>注意非0都为错误走catch</p>
-<pre><code>const test = () =&gt; {
-  return new Promise((resolve, reject) =&gt; {
-    resolve({
-      a:1
-    })
-  })
-}
-
-// 调用
-test.then(res =&gt; {
-  console.log(res)
-  // {a:1}
-})
-</code></pre>
-<p>正常返回</p>
-<pre><code>{
-  code:0,
-  data:{}
-  msg:'成功'
-}
-</code></pre>
-<p>错误返回</p>
-<pre><code>{
-  code:10000, 
-  data:{}
-  msg:'失败'
-}
-</code></pre>
-<p>接口如果是post请求,Content-Type默认为application/x-www-form-urlencoded;如果Content-Type改成application/json,
-接口传参需要改成下面的方式</p>
-<pre><code>io.post('url', payload, null, null, { emulateJSON: false } res =&gt; {
-  resolve(res)
-}).catch(e =&gt; {
-  reject(e)
-})
-</code></pre>
-<h5>相关接口路径</h5>
-<p>dag 相关接口 <code>src/js/conf/home/store/dag/actions.js</code></p>
-<p>数据源中心 相关接口 <code>src/js/conf/home/store/datasource/actions.js</code></p>
-<p>项目管理 相关接口 <code>src/js/conf/home/store/projects/actions.js</code></p>
-<p>资源中心 相关接口 <code>src/js/conf/home/store/resource/actions.js</code></p>
-<p>安全中心 相关接口 <code>src/js/conf/home/store/security/actions.js</code></p>
-<p>用户中心 相关接口 <code>src/js/conf/home/store/user/actions.js</code></p>
-<h2>扩展开发</h2>
-<h5>1.增加节点</h5>
-<p>(1) 先将节点的icon小图标放置<code>src/js/conf/home/pages/dag/img</code>文件夹内,注意 <code>toolbar_${后台定义的节点的英文名称 例如:SHELL}.png</code></p>
-<p>(2) 找到 <code>src/js/conf/home/pages/dag/_source/config.js</code> 里的 <code>tasksType</code> 对象,往里增加</p>
-<pre><code>'DEPENDENT': {  // 后台定义节点类型英文名称用作key值
-  desc: 'DEPENDENT',  // tooltip desc
-  color: '#2FBFD8'  // 代表的颜色主要用于 tree和gantt 两张图
-}
-</code></pre>
-<p>(3) 在 <code>src/js/conf/home/pages/dag/_source/formModel/tasks</code> 增加一个 <code>${节点类型(小写)}</code>.vue 文件,跟当前节点相关的组件内容都在这里写。 属于节点组件内的必须拥有一个函数 <code>_verification()</code> 验证成功后将当前组件的相关数据往父组件抛。</p>
-<pre><code>/**
- * 验证
-*/
-  _verification () {
-    // datasource 子组件验证
-    if (!this.$refs.refDs._verifDatasource()) {
-      return false
-    }
-
-    // 验证函数
-    if (!this.method) {
-      this.$message.warning(`${i18n.$t('请输入方法')}`)
-      return false
-    }
-
-    // localParams 子组件验证
-    if (!this.$refs.refLocalParams._verifProp()) {
-      return false
-    }
-    // 存储
-    this.$emit('on-params', {
-      type: this.type,
-      datasource: this.datasource,
-      method: this.method,
-      localParams: this.localParams
-    })
-    return true
-  }
-</code></pre>
-<p>(4) 节点组件内部所用到公共的组件都在<code>_source</code>下,<code>commcon.js</code>用于配置公共数据</p>
-<h5>2.增加状态类型</h5>
-<p>(1) 找到 <code>src/js/conf/home/pages/dag/_source/config.js</code> 里的 <code>tasksState</code> 对象,往里增加</p>
-<pre><code>'WAITTING_DEPEND': {  //后端定义状态类型 前端用作key值
-  id: 11,  // 前端定义id 后续用作排序
-  desc: `${i18n.$t('等待依赖')}`,  // tooltip desc
-  color: '#5101be',  // 代表的颜色主要用于 tree和gantt 两张图
-  icoUnicode: '&amp;#xe68c;',  // 字体图标 
-  isSpin: false  // 是否旋转(需代码判断)
-}
-</code></pre>
-<h5>3.增加操作栏工具</h5>
-<p>(1) 找到 <code>src/js/conf/home/pages/dag/_source/config.js</code> 里的 <code>toolOper</code> 对象,往里增加</p>
-<pre><code>{
-  code: 'pointer',  // 工具标识
-  icon: '&amp;#xe781;',  // 工具图标 
-  disable: disable,  // 是否禁用
-  desc: `${i18n.$t('拖动节点和选中项')}`  // tooltip desc
-}
-</code></pre>
-<p>(2) 工具类都以一个构造函数返回 <code>src/js/conf/home/pages/dag/_source/plugIn</code></p>
-<p><code>downChart.js</code>  =&gt;  dag 图片下载处理</p>
-<p><code>dragZoom.js</code>  =&gt;  鼠标缩放效果处理</p>
-<p><code>jsPlumbHandle.js</code>  =&gt;  拖拽线条处理</p>
-<p><code>util.js</code>  =&gt;   属于 <code>plugIn</code> 工具类</p>
-<p>操作则在 <code>src/js/conf/home/pages/dag/_source/dag.js</code> =&gt; <code>toolbarEvent</code> 事件中处理。</p>
-<h5>3.增加一个路由页面</h5>
-<p>(1) 首先在路由管理增加一个路由地址<code>src/js/conf/home/router/index.js</code></p>
-<pre><code>{
-  path: '/test',  // 路由地址 
-  name: 'test',  // 别名
-  component: resolve =&gt; require(['../pages/test/index'], resolve),  // 路由对应组件入口文件
-  meta: {
-    title: `${i18n.$t('test')} - DolphinScheduler`  // title 显示
-  }
-},
-</code></pre>
-<p>(2) 在<code>src/js/conf/home/pages</code> 建一个 <code>test</code> 文件夹,在文件夹里建一个<code>index.vue</code>入口文件。</p>
-<pre><code>这样就可以直接访问 `http://localhost:8888/#/test`
-</code></pre>
-<h5>4.增加预置邮箱</h5>
-<p>找到<code>src/lib/localData/email.js</code>启动和定时邮箱地址输入可以自动下拉匹配。</p>
-<pre><code>export default [&quot;test@analysys.com.cn&quot;,&quot;test1@analysys.com.cn&quot;,&quot;test3@analysys.com.cn&quot;]
-</code></pre>
-<h5>5.权限管理及disabled状态处理</h5>
-<p>权限根据后端接口<code>getUserInfo</code>接口给出<code>userType: &quot;ADMIN_USER/GENERAL_USER&quot;</code>权限控制页面操作按钮是否<code>disabled</code></p>
-<p>具体操作:<code>src/js/module/permissions/index.js</code></p>
-<p>disabled处理:<code>src/js/module/mixin/disabledState.js</code></p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/frontend-development.json b/zh-cn/docs/dev/user_doc/development/frontend-development.json
deleted file mode 100644
index e04e531f2..000000000
--- a/zh-cn/docs/dev/user_doc/development/frontend-development.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "frontend-development.md",
-  "__html": "<h1>前端开发文档</h1>\n<h3>技术选型</h3>\n<pre><code>Vue mvvm 框架\n\nEs6 ECMAScript 6.0\n\nAns-ui Analysys-ui\n\nD3 可视化库图表库\n\nJsplumb 连线插件库\n\nLodash 高性能的 JavaScript 实用工具库\n</code></pre>\n<h3>开发环境搭建</h3>\n<ul>\n<li>\n<h4>Node安装</h4>\n</li>\n</ul>\n<p>Node包下载 (注意版本 v12.20.2) <code>https://nodejs.org/download/release/v12.20.2/</code></p>\n<ul>\n<li>\n<h4>前端项目构建</h4>\n</li>\n</ul>\n<p>用命令行模式 <code>cd</code>  进入 <code>dolphinscheduler-ui</code>项目目录并执行 <code>npm install</code> 拉取项目依赖包</p>\ [...]
-  "link": "/dist/zh-cn/docs/dev/user_doc/development/frontend-development.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/have-questions.html b/zh-cn/docs/dev/user_doc/development/have-questions.html
deleted file mode 100644
index 4cb9c2721..000000000
--- a/zh-cn/docs/dev/user_doc/development/have-questions.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="keywords" content="have-questions">
-  <meta name="description" content="have-questions">
-  <title>have-questions</title>
-  <link rel="shortcut icon" href="/img/favicon.ico">
-  <link rel="stylesheet" href="/build/vendor.eeae4ed.css">
-</head>
-<body>
-  <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 有关于 Apache DolphinScheduler 的疑问,加入 Slack 频道来讨论他们 <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span><a href="/zh-cn/index.html"><img cl [...]
-<h2>StackOverflow</h2>
-<p>如果在使用上有疑问,建议你使用StackOverflow标签 <a href="https://stackoverflow.com/questions/tagged/apache-dolphinscheduler">apache-dolphinscheduler</a>,这是一个DolphinScheduler用户问答的活跃论坛。</p>
-<p>使用StackOverflow时的快速提示:</p>
-<ul>
-<li>
-<p>在提交问题之前:</p>
-<ul>
-<li>在StackOverflow的 <a href="https://stackoverflow.com/questions/tagged/apache-dolphinscheduler">apache-dolphinscheduler</a> 标签下进行搜索,看看你的问题是否已经被回答。</li>
-</ul>
-</li>
-<li>
-<p>请遵守StackOverflow的<a href="https://stackoverflow.com/help/how-to-ask">行为准则</a></p>
-</li>
-<li>
-<p>提出问题时,请务必使用apache-dolphinscheduler标签。</p>
-</li>
-<li>
-<p>请不要在 <a href="https://stackoverflow.com/questions/tagged/apache-dolphinscheduler">StackOverflow</a> 和 <a href="https://github.com/apache/dolphinscheduler/issues/new/choose">GitHub issues</a>之间交叉发帖。</p>
-</li>
-</ul>
-<p>提问模板:</p>
-<blockquote>
-<p><strong>Describe the question</strong></p>
-<p>对问题的内容进行清晰、简明的描述。</p>
-<p><strong>Which version of DolphinScheduler:</strong></p>
-<p>-[1.3.0-preview]</p>
-<p><strong>Additional context</strong></p>
-<p>在此添加关于该问题的其他背景。</p>
-<p><strong>Requirement or improvement</strong></p>
-<p>在此描述您的要求或改进建议。</p>
-</blockquote>
-<p>如果你的问题较为宽泛、有意见或建议、期望请求外部资源,或是有项目调试、bug提交等相关问题,或者想要对项目做出贡献、对场景进行讨论,建议你提交<a href="https://github.com/apache/dolphinscheduler/issues/new/choose"> GitHub issues </a>或使用dev@dolphinscheduler.apache.org 邮件列表进行讨论。</p>
-<h2>邮件列表</h2>
-<ul>
-<li><a href="https://lists.apache.org/list.html?dev@dolphinscheduler.apache.org">dev@dolphinscheduler.apache.org</a> 是为那些想为DolphinScheduler贡献代码的人准备的。 <a href="mailto:dev-subscribe@dolphinscheduler.apache.org?subject=(send%20this%20email%20to%20subscribe)">(订阅)</a> <a href="mailto:dev-unsubscribe@dolphinscheduler.apache.org?subject=(send%20this%20email%20to%20unsubscribe)">(退订)</a> <a href="http://lists.apache.org/list.html?dev@dolphinscheduler.apache.org">(存档)</a></li>
-</ul>
-<p>使用电子邮件时的一些快速提示:</p>
-<ul>
-<li>在提出问题之前:
-<ul>
-<li>请在StackOverflow的 <a href="https://stackoverflow.com/questions/tagged/apache-dolphinscheduler">apache-dolphinscheduler</a> 标签下进行搜索,看看你的问题是否已经被回答。</li>
-</ul>
-</li>
-<li>在你的邮件的主题栏里加上标签会帮助你得到更快的回应,例如:[ApiServer]:如何获得开放的api接口?</li>
-<li>可以通过以下标签定义你的主题。
-<ul>
-<li>组件相关:MasterServer、ApiServer、WorkerServer、AlertServer等等。</li>
-<li>级别:Beginner、Intermediate、Advanced</li>
-<li>场景相关:Debug,、How-to</li>
-</ul>
-</li>
-<li>如果内容包括错误日志或长代码,请使用 <a href="https://gist.github.com/">GitHub gist</a>,并在邮件中只附加相关代码/日志的几行。</li>
-</ul>
-<h2>Chat Rooms</h2>
-<p>聊天室是快速提问或讨论具体话题的好地方。</p>
-<p>以下聊天室是Apache DolphinScheduler的正式组成部分:</p>
-<p>​	Slack工作区的网址:<a href="http://asf-dolphinscheduler.slack.com/">http://asf-dolphinscheduler.slack.com/</a></p>
-<p>​	你可以通过该邀请链接加入:<a href="https://s.apache.org/dolphinscheduler-slack">https://s.apache.org/dolphinscheduler-slack</a></p>
-<p>此聊天室用于与DolphinScheduler使用相关的问题讨论。</p>
-</div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
-  <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
-  <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
-  <script>window.rootPath = '';</script>
-  <script src="/build/vendor.5cf22d1.js"></script>
-  <script src="/build/docs.md.1247151.js"></script>
-  <script>
-    var _hmt = _hmt || [];
-    (function() {
-      var hm = document.createElement("script");
-      hm.src = "https://hm.baidu.com/hm.js?4e7b4b400dd31fa015018a435c64d06f";
-      var s = document.getElementsByTagName("script")[0];
-      s.parentNode.insertBefore(hm, s);
-    })();
-  </script>
-  <!-- Global site tag (gtag.js) - Google Analytics -->
-  <script async src="https://www.googletagmanager.com/gtag/js?id=G-899J8PYKJZ"></script>
-  <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'G-899J8PYKJZ');
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/development/have-questions.json b/zh-cn/docs/dev/user_doc/development/have-questions.json
deleted file mode 100644
index ae8dc611b..000000000
--- a/zh-cn/docs/dev/user_doc/development/have-questions.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "filename": "have-questions.md",
-  "__html": "<h1>当你遇到问题时</h1>\n<h2>StackOverflow</h2>\n<p>如果在使用上有疑问,建议你使用StackOverflow标签 <a href=\"https://stackoverflow.com/questions/tagged/apache-dolphinscheduler\">apache-dolphinscheduler</a>,这是一个DolphinScheduler用户问答的活跃论坛。</p>\n<p>使用StackOverflow时的快速提示:</p>\n<ul>\n<li>\n<p>在提交问题之前:</p>\n<ul>\n<li>在StackOverflow的 <a href=\"https://stackoverflow.com/questions/tagged/apache-dolphinscheduler\">apache-dolphinscheduler</a> 标签下进行搜索,看看你的问题是否已经被回答。</li>\n</ul>\n</li>\n<li>\n<p>请遵守StackOverflo [...]
-  "link": "/dist/zh-cn/docs/dev/user_doc/development/have-questions.html",
-  "meta": {}
-}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/user_doc/guide/alert/enterprise-wechat.html b/zh-cn/docs/dev/user_doc/guide/alert/enterprise-wechat.html
index 15f051e65..4c42093e5 100644
--- a/zh-cn/docs/dev/user_doc/guide/alert/enterprise-wechat.html
+++ b/zh-cn/docs/dev/user_doc/guide/alert/enterprise-wechat.html
@@ -11,12 +11,43 @@
 </head>
 <body>
   <div id="root"><div class="md2html docs-page" data-reactroot=""><header class="header-container header-container-dark"><div class="banner-tips"><div>🤔 有关于 Apache DolphinScheduler 的疑问,加入 Slack 频道来讨论他们 <a class="link-tips" href="https://join.slack.com/t/asf-dolphinscheduler/shared_invite/zt-omtdhuio-_JISsxYhiVsltmC5h38yfw">join #dolphinscheduler channel</a>! 🌟</div></div><div class="header-body"><span class="mobile-menu-btn mobile-menu-btn-dark"></span><a href="/zh-cn/index.html"><img cl [...]
-<p>如果您需要使用到企业微信进行告警,请在告警实例管理里创建告警实例,选择 WeChat 插件。企业微信的配置样例如下</p>
+<p>如果您需要使用到企业微信进行告警,请在告警实例管理里创建告警实例,选择 WeChat 插件。企业微信的配置样例如下:</p>
 <p><img src="/img/alert/enterprise-wechat-plugin.png" alt="enterprise-wechat-plugin"></p>
-<p>其中 send.type 分别对应企微文档:</p>
+<h2>发送类型</h2>
+<p>其中<code>send.type</code>分别对应向企业微信自定义应用发送和向企业微信API创建的群聊发送消息。</p>
+<h3>应用</h3>
+<p>应用指将告警结果通过企业微信的自定义应用进行通知,支持向特定用户发送消息和对所有人发送消息。目前还不支持部门和标签,欢迎提PR贡献代码。
+下图是应用告警配置的示例:</p>
+<p><img src="/img/alert/wechat-app-form-example.png" alt="enterprise-wechat-app-msg-config"></p>
+<p>下图是<code>应用``MARKDOWN</code>告警消息的示例:</p>
+<p><img src="/img/alert/enterprise-wechat-app-msg-md.png" alt="enterprise-wechat-app-msg-markdown"></p>
+<p>下图是<code>应用``TEXT</code>告警消息的示例:</p>
+<p><img src="/img/alert/enterprise-wechat-app-msg.png" alt="enterprise-wechat-app-msg-text"></p>
+<h4>前置</h4>
+<p>向企业微信应用发送消息之前需要在企业微信中创建自定义应用,请在<a href="https://work.weixin.qq.com/wework_admin/frame#apps">应用页面</a> 进行创建,获取应用的<code>AgentId</code>并将可见范围设为根。</p>
+<h4>向指定用户发消息</h4>
+<p>企业微信应用支持向特定用户发送消息和对所有人发送消息,分别为使用<code>|</code>分隔多个userId和使用<code>@all</code>向所有人发送信息。
+获取用户的userId请参考<a href="https://developer.work.weixin.qq.com/document/path/95402">官方文档</a>根据手机号获取userId。
+下图是获取userId接口的示例:</p>
+<p><img src="/img/alert/enterprise-wechat-query-userid.png" alt="enterprise-wechat-create-group"></p>
+<h4>参考文档</h4>
 <p>应用:<a href="https://work.weixin.qq.com/api/doc/90000/90135/90236">https://work.weixin.qq.com/api/doc/90000/90135/90236</a></p>
+<h3>群聊</h3>
+<p>群聊指将告警结果通过企业微信API创建的群聊进行通知,会向该群聊下的所有人发送消息,不支持向特定用户发送消息。
+下图是群聊告警配置的示例:</p>
+<p><img src="/img/alert/wechat-group-form-example.png" alt="enterprise-wechat-group-msg-config"></p>
+<p>下图是<code>群聊``MARKDOWN</code>告警消息的示例:</p>
+<p><img src="/img/alert/enterprise-wechat-group-msg-md.png" alt="enterprise-wechat-group-msg-markdown"></p>
+<p>下图是<code>群聊``TEXT</code>告警消息的示例:</p>
+<p><img src="/img/alert/enterprise-wechat-group-msg.png" alt="enterprise-wechat-group-msg-text"></p>
+<h4>前置</h4>
+<p>向企业微信群聊发送消息之前需要通过企业微信的API创建群聊,请参考<a href="https://developer.work.weixin.qq.com/document/path/90245">官方文档</a> 进行创建群聊并获取<code>chatid</code>。
+其中获取用户的userId请参考<a href="https://developer.work.weixin.qq.com/document/path/95402">官方文档</a>根据手机号获取userId。
+下图是创建新聊天群组和获取userId接口的示例:</p>
+<p><img src="/img/alert/enterprise-wechat-create-group.png" alt="enterprise-wechat-create-group"></p>
+<p><img src="/img/alert/enterprise-wechat-query-userid.png" alt="enterprise-wechat-create-group"></p>
+<h4>参考文档</h4>
 <p>群聊:<a href="https://work.weixin.qq.com/api/doc/90000/90135/90248">https://work.weixin.qq.com/api/doc/90000/90135/90248</a></p>
-<p>user.send.msg 对应文档中的 content,与此相对应的值的变量为 {msg}</p>
 </div></section><footer class="footer-container"><div class="footer-body"><div><h3>联系我们</h3><h4>有问题需要反馈?请通过以下方式联系我们。</h4></div><div class="contact-container"><ul><li><a href="/zh-cn/community/development/subscribe.html"><img class="img-base" src="/img/emailgray.png"/><img class="img-change" src="/img/emailblue.png"/><p>邮件列表</p></a></li><li><a href="https://twitter.com/dolphinschedule"><img class="img-base" src="/img/twittergray.png"/><img class="img-change" src="/img/twitterblue.png"/><p [...]
   <script src="//cdn.jsdelivr.net/npm/react@15.6.2/dist/react-with-addons.min.js"></script>
   <script src="//cdn.jsdelivr.net/npm/react-dom@15.6.2/dist/react-dom.min.js"></script>
diff --git a/zh-cn/docs/dev/user_doc/guide/alert/enterprise-wechat.json b/zh-cn/docs/dev/user_doc/guide/alert/enterprise-wechat.json
index a06b27951..bc351b9b1 100644
--- a/zh-cn/docs/dev/user_doc/guide/alert/enterprise-wechat.json
+++ b/zh-cn/docs/dev/user_doc/guide/alert/enterprise-wechat.json
@@ -1,6 +1,6 @@
 {
   "filename": "enterprise-wechat.md",
-  "__html": "<h1>企业微信</h1>\n<p>如果您需要使用到企业微信进行告警,请在告警实例管理里创建告警实例,选择 WeChat 插件。企业微信的配置样例如下</p>\n<p><img src=\"/img/alert/enterprise-wechat-plugin.png\" alt=\"enterprise-wechat-plugin\"></p>\n<p>其中 send.type 分别对应企微文档:</p>\n<p>应用:<a href=\"https://work.weixin.qq.com/api/doc/90000/90135/90236\">https://work.weixin.qq.com/api/doc/90000/90135/90236</a></p>\n<p>群聊:<a href=\"https://work.weixin.qq.com/api/doc/90000/90135/90248\">https://work.weixin.qq.com/api/doc/90000/90135/90248</a></p>\n<p>use [...]
+  "__html": "<h1>企业微信</h1>\n<p>如果您需要使用到企业微信进行告警,请在告警实例管理里创建告警实例,选择 WeChat 插件。企业微信的配置样例如下:</p>\n<p><img src=\"/img/alert/enterprise-wechat-plugin.png\" alt=\"enterprise-wechat-plugin\"></p>\n<h2>发送类型</h2>\n<p>其中<code>send.type</code>分别对应向企业微信自定义应用发送和向企业微信API创建的群聊发送消息。</p>\n<h3>应用</h3>\n<p>应用指将告警结果通过企业微信的自定义应用进行通知,支持向特定用户发送消息和对所有人发送消息。目前还不支持部门和标签,欢迎提PR贡献代码。\n下图是应用告警配置的示例:</p>\n<p><img src=\"/img/alert/wechat-app-form-example.png\" alt=\"enterprise-wechat-app-msg-config\"></p>\n<p>下图是<code> [...]
   "link": "/dist/zh-cn/docs/dev/user_doc/guide/alert/enterprise-wechat.html",
   "meta": {}
 }
\ No newline at end of file