You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2019/12/13 03:42:01 UTC

[dubbo-website] branch asf-site updated: test doc archive

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

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


The following commit(s) were added to refs/heads/asf-site by this push:
     new cb550a5  test doc archive
cb550a5 is described below

commit cb550a5116e2c7dc1062aed849049264e8c22f12
Author: ken.lj <ke...@gmail.com>
AuthorDate: Fri Dec 13 11:41:47 2019 +0800

    test doc archive
---
 .../v2.7.3/zh-cn/blog/Configuration Conclude.html  |  189 ++
 .../v2.7.3/zh-cn/blog/Configuration Conclude.json  |    6 +
 .../Dubbo-supporting-gRPC-HTTP2-and-protobuf.html  |  634 +++++++
 .../Dubbo-supporting-gRPC-HTTP2-and-protobuf.json  |    6 +
 .../zh-cn/blog/Guides for upgrading to 2.7.x.html  |  342 ++++
 .../zh-cn/blog/Guides for upgrading to 2.7.x.json  |    6 +
 .../zh-cn/blog/Guides-for-upgrading-to-27x.html    |  342 ++++
 .../zh-cn/blog/Guides-for-upgrading-to-27x.json    |    6 +
 .../v2.7.3/zh-cn/blog/apachecon-na-2018.html       |   34 +
 .../v2.7.3/zh-cn/blog/apachecon-na-2018.json       |   10 +
 .../blog/build-new-docker-image-in-dockerhub.html  |   73 +
 .../blog/build-new-docker-image-in-dockerhub.json  |   10 +
 doc-archive/v2.7.3/zh-cn/blog/download.html        |  189 ++
 doc-archive/v2.7.3/zh-cn/blog/download.json        |   10 +
 doc-archive/v2.7.3/zh-cn/blog/dubbo-101.html       |  350 ++++
 doc-archive/v2.7.3/zh-cn/blog/dubbo-101.json       |   10 +
 .../v2.7.3/zh-cn/blog/dubbo-27-features.html       |  197 ++
 .../v2.7.3/zh-cn/blog/dubbo-27-features.json       |   10 +
 doc-archive/v2.7.3/zh-cn/blog/dubbo-admin.html     |   96 +
 doc-archive/v2.7.3/zh-cn/blog/dubbo-admin.json     |    6 +
 .../v2.7.3/zh-cn/blog/dubbo-annotation-driven.html |  554 ++++++
 .../v2.7.3/zh-cn/blog/dubbo-annotation-driven.json |    6 +
 .../v2.7.3/zh-cn/blog/dubbo-annotation.html        |  356 ++++
 .../v2.7.3/zh-cn/blog/dubbo-annotation.json        |   10 +
 ...o-basic-usage-dubbo-consumer-configuration.html |  247 +++
 ...o-basic-usage-dubbo-consumer-configuration.json |    6 +
 ...o-basic-usage-dubbo-provider-configuration.html |  400 ++++
 ...o-basic-usage-dubbo-provider-configuration.json |   10 +
 .../zh-cn/blog/dubbo-cluster-error-handling.html   |  232 +++
 .../zh-cn/blog/dubbo-cluster-error-handling.json   |   10 +
 .../v2.7.3/zh-cn/blog/dubbo-compatible.html        |  198 ++
 .../v2.7.3/zh-cn/blog/dubbo-compatible.json        |   10 +
 .../zh-cn/blog/dubbo-context-information.html      |  156 ++
 .../zh-cn/blog/dubbo-context-information.json      |   10 +
 .../zh-cn/blog/dubbo-contribute-to-opensource.html |  157 ++
 .../zh-cn/blog/dubbo-contribute-to-opensource.json |   10 +
 .../v2.7.3/zh-cn/blog/dubbo-copywriting-style.html |  396 ++++
 .../v2.7.3/zh-cn/blog/dubbo-copywriting-style.json |   10 +
 doc-archive/v2.7.3/zh-cn/blog/dubbo-echo-test.html |  111 ++
 doc-archive/v2.7.3/zh-cn/blog/dubbo-echo-test.json |    6 +
 .../blog/dubbo-externalized-configuration.html     |  543 ++++++
 .../blog/dubbo-externalized-configuration.json     |    6 +
 doc-archive/v2.7.3/zh-cn/blog/dubbo-fescar.html    |  215 +++
 doc-archive/v2.7.3/zh-cn/blog/dubbo-fescar.json    |   10 +
 .../v2.7.3/zh-cn/blog/dubbo-generic-invoke.html    |  171 ++
 .../v2.7.3/zh-cn/blog/dubbo-generic-invoke.json    |   10 +
 .../zh-cn/blog/dubbo-gracefully-shutdown.html      |  130 ++
 .../zh-cn/blog/dubbo-gracefully-shutdown.json      |   10 +
 .../v2.7.3/zh-cn/blog/dubbo-heartbeat-design.html  |  358 ++++
 .../v2.7.3/zh-cn/blog/dubbo-heartbeat-design.json  |   10 +
 .../zh-cn/blog/dubbo-integrate-with-hystrix.html   |  198 ++
 .../zh-cn/blog/dubbo-integrate-with-hystrix.json   |   10 +
 doc-archive/v2.7.3/zh-cn/blog/dubbo-invoke.html    |  193 ++
 doc-archive/v2.7.3/zh-cn/blog/dubbo-invoke.json    |   10 +
 doc-archive/v2.7.3/zh-cn/blog/dubbo-k8s.html       |  120 ++
 doc-archive/v2.7.3/zh-cn/blog/dubbo-k8s.json       |   10 +
 .../v2.7.3/zh-cn/blog/dubbo-loadbalance.html       |  251 +++
 .../v2.7.3/zh-cn/blog/dubbo-loadbalance.json       |   10 +
 .../v2.7.3/zh-cn/blog/dubbo-local-call.html        |   85 +
 .../v2.7.3/zh-cn/blog/dubbo-local-call.json        |    6 +
 .../v2.7.3/zh-cn/blog/dubbo-meet-arthas.html       |  325 ++++
 .../v2.7.3/zh-cn/blog/dubbo-meet-arthas.json       |   10 +
 .../blog/dubbo-meetup-beijing-may-12th-2018.html   |   41 +
 .../blog/dubbo-meetup-beijing-may-12th-2018.json   |   10 +
 .../v2.7.3/zh-cn/blog/dubbo-meetup-chengdu.html    |   41 +
 .../v2.7.3/zh-cn/blog/dubbo-meetup-chengdu.json    |   10 +
 .../v2.7.3/zh-cn/blog/dubbo-meetup-hangzhou.html   |   43 +
 .../v2.7.3/zh-cn/blog/dubbo-meetup-hangzhou.json   |   10 +
 .../blog/dubbo-meetup-shanghai-jun-23rd-2018.html  |   41 +
 .../blog/dubbo-meetup-shanghai-jun-23rd-2018.json  |   10 +
 .../v2.7.3/zh-cn/blog/dubbo-meetup-shenzhen.html   |   40 +
 .../v2.7.3/zh-cn/blog/dubbo-meetup-shenzhen.json   |   10 +
 .../v2.7.3/zh-cn/blog/dubbo-mesh-in-thinking.html  |  115 ++
 .../v2.7.3/zh-cn/blog/dubbo-mesh-in-thinking.json  |   10 +
 .../blog/dubbo-mesh-service-mesh-exploring.html    |  147 ++
 .../blog/dubbo-mesh-service-mesh-exploring.json    |   10 +
 .../zh-cn/blog/dubbo-network-interfaces.html       |  406 +++++
 .../zh-cn/blog/dubbo-network-interfaces.json       |   10 +
 doc-archive/v2.7.3/zh-cn/blog/dubbo-new-async.html |  412 +++++
 doc-archive/v2.7.3/zh-cn/blog/dubbo-new-async.json |   10 +
 doc-archive/v2.7.3/zh-cn/blog/dubbo-protocol.html  |  195 ++
 doc-archive/v2.7.3/zh-cn/blog/dubbo-protocol.json  |   10 +
 .../blog/dubbo-registry-nacos-integration.html     |  435 +++++
 .../blog/dubbo-registry-nacos-integration.json     |    6 +
 doc-archive/v2.7.3/zh-cn/blog/dubbo-rest.html      |  671 +++++++
 doc-archive/v2.7.3/zh-cn/blog/dubbo-rest.json      |    6 +
 doc-archive/v2.7.3/zh-cn/blog/dubbo-stub-mock.html |  238 +++
 doc-archive/v2.7.3/zh-cn/blog/dubbo-stub-mock.json |    6 +
 doc-archive/v2.7.3/zh-cn/blog/dubbo-zk.html        |  275 +++
 doc-archive/v2.7.3/zh-cn/blog/dubbo-zk.json        |   10 +
 doc-archive/v2.7.3/zh-cn/blog/dubbo2-js.html       |  243 +++
 doc-archive/v2.7.3/zh-cn/blog/dubbo2-js.json       |   10 +
 .../v2.7.3/zh-cn/blog/dubboAsync_client.html       |  102 ++
 .../v2.7.3/zh-cn/blog/dubboAsync_client.json       |   10 +
 .../v2.7.3/zh-cn/blog/dubboAsync_server.html       |  100 +
 .../v2.7.3/zh-cn/blog/dubboAsync_server.json       |   10 +
 .../v2.7.3/zh-cn/blog/first-dubbo-filter.html      |  200 ++
 .../v2.7.3/zh-cn/blog/first-dubbo-filter.json      |    6 +
 doc-archive/v2.7.3/zh-cn/blog/gsoc-2018.html       |   34 +
 doc-archive/v2.7.3/zh-cn/blog/gsoc-2018.json       |   10 +
 .../zh-cn/blog/how-to-involve-dubbo-community.html |  107 ++
 .../zh-cn/blog/how-to-involve-dubbo-community.json |   10 +
 doc-archive/v2.7.3/zh-cn/blog/index.html           |   32 +
 .../zh-cn/blog/introduction-to-dubbo-qos.html      |  245 +++
 .../zh-cn/blog/introduction-to-dubbo-qos.json      |   10 +
 .../zh-cn/blog/introduction-to-dubbo-spi-2.html    |  395 ++++
 .../zh-cn/blog/introduction-to-dubbo-spi-2.json    |   10 +
 .../zh-cn/blog/introduction-to-dubbo-spi.html      |  217 +++
 .../zh-cn/blog/introduction-to-dubbo-spi.json      |   10 +
 .../zh-cn/blog/introduction-to-dubbo-url.html      |  153 ++
 .../zh-cn/blog/introduction-to-dubbo-url.json      |   10 +
 doc-archive/v2.7.3/zh-cn/blog/meet-dubbo.html      |   68 +
 doc-archive/v2.7.3/zh-cn/blog/meet-dubbo.json      |   10 +
 .../zh-cn/blog/optimization-branch-prediction.html |  151 ++
 .../zh-cn/blog/optimization-branch-prediction.json |    8 +
 doc-archive/v2.7.3/zh-cn/blog/pinpoint.html        |  411 +++++
 doc-archive/v2.7.3/zh-cn/blog/pinpoint.json        |   10 +
 .../zh-cn/blog/prepare-an-apache-release.html      |  438 +++++
 .../zh-cn/blog/prepare-an-apache-release.json      |   10 +
 .../v2.7.3/zh-cn/blog/qcon-beijing-2018.html       |   34 +
 .../v2.7.3/zh-cn/blog/qcon-beijing-2018.json       |   10 +
 .../v2.7.3/zh-cn/blog/rpc-introduction.html        |  153 ++
 .../v2.7.3/zh-cn/blog/rpc-introduction.json        |   10 +
 .../blog/sentinel-introduction-for-dubbo.html      |  137 ++
 .../blog/sentinel-introduction-for-dubbo.json      |   10 +
 .../v2.7.3/zh-cn/blog/service-and-version.html     |  213 +++
 .../v2.7.3/zh-cn/blog/service-and-version.json     |    6 +
 doc-archive/v2.7.3/zh-cn/blog/service-test.html    |  179 ++
 doc-archive/v2.7.3/zh-cn/blog/service-test.json    |    6 +
 .../spring-boot-dubbo-start-stop-analysis.html     |  220 +++
 .../spring-boot-dubbo-start-stop-analysis.json     |   10 +
 .../v2.7.3/zh-cn/blog/test-verification.html       |  111 ++
 .../v2.7.3/zh-cn/blog/test-verification.json       |    6 +
 .../v2.7.3/zh-cn/blog/tracing-with-skywalking.html |  138 ++
 .../v2.7.3/zh-cn/blog/tracing-with-skywalking.json |   10 +
 .../v2.7.3/zh-cn/blog/use-zipkin-in-dubbo.html     |  538 ++++++
 .../v2.7.3/zh-cn/blog/use-zipkin-in-dubbo.json     |   10 +
 doc-archive/v2.7.3/zh-cn/community/index.html      |   32 +
 doc-archive/v2.7.3/zh-cn/docs/admin/README.html    |   33 +
 doc-archive/v2.7.3/zh-cn/docs/admin/README.json    |    6 +
 doc-archive/v2.7.3/zh-cn/docs/admin/SUMMARY.html   |   41 +
 doc-archive/v2.7.3/zh-cn/docs/admin/SUMMARY.json   |    6 +
 .../zh-cn/docs/admin/install/admin-console.html    |   61 +
 .../zh-cn/docs/admin/install/admin-console.json    |    6 +
 .../zh-cn/docs/admin/install/consumer-demo.html    |   45 +
 .../zh-cn/docs/admin/install/consumer-demo.json    |    6 +
 .../zh-cn/docs/admin/install/introduction.html     |   45 +
 .../zh-cn/docs/admin/install/introduction.json     |    6 +
 .../zh-cn/docs/admin/install/provider-demo.html    |   44 +
 .../zh-cn/docs/admin/install/provider-demo.json    |    6 +
 .../v2.7.3/zh-cn/docs/admin/install/redis.html     |   72 +
 .../v2.7.3/zh-cn/docs/admin/install/redis.json     |    6 +
 .../docs/admin/install/simple-monitor-center.html  |   34 +
 .../docs/admin/install/simple-monitor-center.json  |    6 +
 .../docs/admin/install/simple-registry-center.html |   33 +
 .../docs/admin/install/simple-registry-center.json |    6 +
 .../v2.7.3/zh-cn/docs/admin/install/zookeeper.html |  101 +
 .../v2.7.3/zh-cn/docs/admin/install/zookeeper.json |    6 +
 .../v2.7.3/zh-cn/docs/admin/introduction.html      |   95 +
 .../v2.7.3/zh-cn/docs/admin/introduction.json      |    6 +
 doc-archive/v2.7.3/zh-cn/docs/admin/metrics.html   |   33 +
 doc-archive/v2.7.3/zh-cn/docs/admin/metrics.json   |    6 +
 .../v2.7.3/zh-cn/docs/admin/ops/dubbo-ops.html     |   45 +
 .../v2.7.3/zh-cn/docs/admin/ops/dubbo-ops.json     |    6 +
 .../v2.7.3/zh-cn/docs/admin/ops/introduction.html  |   33 +
 .../v2.7.3/zh-cn/docs/admin/ops/introduction.json  |    6 +
 .../v2.7.3/zh-cn/docs/admin/ops/pinpoint.html      |  411 +++++
 .../v2.7.3/zh-cn/docs/admin/ops/pinpoint.json      |    6 +
 .../v2.7.3/zh-cn/docs/admin/ops/skywalking.html    |  138 ++
 .../v2.7.3/zh-cn/docs/admin/ops/skywalking.json    |    6 +
 .../v2.7.3/zh-cn/docs/admin/serviceGovernance.html |   68 +
 .../v2.7.3/zh-cn/docs/admin/serviceGovernance.json |    6 +
 .../v2.7.3/zh-cn/docs/admin/serviceSearch.html     |   37 +
 .../v2.7.3/zh-cn/docs/admin/serviceSearch.json     |    6 +
 .../v2.7.3/zh-cn/docs/admin/serviceTest.html       |   33 +
 .../v2.7.3/zh-cn/docs/admin/serviceTest.json       |    6 +
 doc-archive/v2.7.3/zh-cn/docs/dev/README.html      |   33 +
 doc-archive/v2.7.3/zh-cn/docs/dev/README.json      |    6 +
 doc-archive/v2.7.3/zh-cn/docs/dev/SPI.html         |  203 +++
 doc-archive/v2.7.3/zh-cn/docs/dev/SPI.json         |    6 +
 doc-archive/v2.7.3/zh-cn/docs/dev/SUMMARY.html     |   88 +
 doc-archive/v2.7.3/zh-cn/docs/dev/SUMMARY.json     |    6 +
 doc-archive/v2.7.3/zh-cn/docs/dev/TCK.html         |   46 +
 doc-archive/v2.7.3/zh-cn/docs/dev/TCK.json         |    6 +
 doc-archive/v2.7.3/zh-cn/docs/dev/build.html       |   81 +
 doc-archive/v2.7.3/zh-cn/docs/dev/build.json       |    6 +
 doc-archive/v2.7.3/zh-cn/docs/dev/checklist.html   |   59 +
 doc-archive/v2.7.3/zh-cn/docs/dev/checklist.json   |    6 +
 doc-archive/v2.7.3/zh-cn/docs/dev/code-smell.html  |  160 ++
 doc-archive/v2.7.3/zh-cn/docs/dev/code-smell.json  |    6 +
 doc-archive/v2.7.3/zh-cn/docs/dev/coding.html      |   91 +
 doc-archive/v2.7.3/zh-cn/docs/dev/coding.json      |    6 +
 .../v2.7.3/zh-cn/docs/dev/configcenter/design.html |  103 ++
 .../v2.7.3/zh-cn/docs/dev/configcenter/design.json |    6 +
 doc-archive/v2.7.3/zh-cn/docs/dev/contract.html    |   45 +
 doc-archive/v2.7.3/zh-cn/docs/dev/contract.json    |    6 +
 .../v2.7.3/zh-cn/docs/dev/contribution.html        |  352 ++++
 .../v2.7.3/zh-cn/docs/dev/contribution.json        |    6 +
 doc-archive/v2.7.3/zh-cn/docs/dev/design.html      |  114 ++
 doc-archive/v2.7.3/zh-cn/docs/dev/design.json      |    6 +
 .../v2.7.3/zh-cn/docs/dev/implementation.html      |  209 +++
 .../v2.7.3/zh-cn/docs/dev/implementation.json      |    6 +
 doc-archive/v2.7.3/zh-cn/docs/dev/impls/cache.html |   94 +
 doc-archive/v2.7.3/zh-cn/docs/dev/impls/cache.json |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/cluster.html       |   89 +
 .../v2.7.3/zh-cn/docs/dev/impls/cluster.json       |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/compiler.html      |   71 +
 .../v2.7.3/zh-cn/docs/dev/impls/compiler.json      |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/config-center.html |  117 ++
 .../v2.7.3/zh-cn/docs/dev/impls/config-center.json |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/container.html     |   77 +
 .../v2.7.3/zh-cn/docs/dev/impls/container.json     |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/dispatcher.html    |   77 +
 .../v2.7.3/zh-cn/docs/dev/impls/dispatcher.json    |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/exchanger.html     |  100 +
 .../v2.7.3/zh-cn/docs/dev/impls/exchanger.json     |    6 +
 .../zh-cn/docs/dev/impls/exporter-listener.html    |   78 +
 .../zh-cn/docs/dev/impls/exporter-listener.json    |    6 +
 .../zh-cn/docs/dev/impls/extension-factory.html    |   72 +
 .../zh-cn/docs/dev/impls/extension-factory.json    |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/filter.html        |  104 ++
 .../v2.7.3/zh-cn/docs/dev/impls/filter.json        |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/introduction.html  |   34 +
 .../v2.7.3/zh-cn/docs/dev/impls/introduction.json  |    6 +
 .../zh-cn/docs/dev/impls/invoker-listener.html     |   77 +
 .../zh-cn/docs/dev/impls/invoker-listener.json     |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/load-balance.html  |   78 +
 .../v2.7.3/zh-cn/docs/dev/impls/load-balance.json  |    6 +
 .../zh-cn/docs/dev/impls/logger-adapter.html       |   93 +
 .../zh-cn/docs/dev/impls/logger-adapter.json       |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/merger.html        |   74 +
 .../v2.7.3/zh-cn/docs/dev/impls/merger.json        |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/monitor.html       |   87 +
 .../v2.7.3/zh-cn/docs/dev/impls/monitor.json       |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/networker.html     |   74 +
 .../v2.7.3/zh-cn/docs/dev/impls/networker.json     |    6 +
 doc-archive/v2.7.3/zh-cn/docs/dev/impls/page.html  |   76 +
 doc-archive/v2.7.3/zh-cn/docs/dev/impls/page.json  |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/protocol.html      |  160 ++
 .../v2.7.3/zh-cn/docs/dev/impls/protocol.json      |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/proxy-factory.html |   80 +
 .../v2.7.3/zh-cn/docs/dev/impls/proxy-factory.json |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/registry.html      |  207 +++
 .../v2.7.3/zh-cn/docs/dev/impls/registry.json      |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/remoting.html      |  133 ++
 .../v2.7.3/zh-cn/docs/dev/impls/remoting.json      |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/router.html        |   76 +
 .../v2.7.3/zh-cn/docs/dev/impls/router.json        |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/serialize.html     |   89 +
 .../v2.7.3/zh-cn/docs/dev/impls/serialize.json     |    6 +
 .../zh-cn/docs/dev/impls/status-checker.html       |   79 +
 .../zh-cn/docs/dev/impls/status-checker.json       |    6 +
 .../zh-cn/docs/dev/impls/telnet-handler.html       |   89 +
 .../zh-cn/docs/dev/impls/telnet-handler.json       |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/threadpool.html    |   75 +
 .../v2.7.3/zh-cn/docs/dev/impls/threadpool.json    |    6 +
 .../v2.7.3/zh-cn/docs/dev/impls/validation.html    |   85 +
 .../v2.7.3/zh-cn/docs/dev/impls/validation.json    |    6 +
 .../v2.7.3/zh-cn/docs/dev/introduction.html        |   33 +
 .../v2.7.3/zh-cn/docs/dev/introduction.json        |    6 +
 .../zh-cn/docs/dev/principals/code-detail.html     |   53 +
 .../zh-cn/docs/dev/principals/code-detail.json     |    6 +
 .../zh-cn/docs/dev/principals/configuration.html   |   96 +
 .../zh-cn/docs/dev/principals/configuration.json   |    6 +
 .../v2.7.3/zh-cn/docs/dev/principals/dummy.html    |  210 +++
 .../v2.7.3/zh-cn/docs/dev/principals/dummy.json    |    6 +
 .../zh-cn/docs/dev/principals/expansibility.html   |   43 +
 .../zh-cn/docs/dev/principals/expansibility.json   |    6 +
 .../zh-cn/docs/dev/principals/extension.html       |  118 ++
 .../zh-cn/docs/dev/principals/extension.json       |    6 +
 .../docs/dev/principals/general-knowledge.html     |   68 +
 .../docs/dev/principals/general-knowledge.json     |    6 +
 .../zh-cn/docs/dev/principals/introduction.html    |   34 +
 .../zh-cn/docs/dev/principals/introduction.json    |    6 +
 .../zh-cn/docs/dev/principals/robustness.html      |   81 +
 .../zh-cn/docs/dev/principals/robustness.json      |    6 +
 doc-archive/v2.7.3/zh-cn/docs/dev/release.html     |   65 +
 doc-archive/v2.7.3/zh-cn/docs/dev/release.json     |    6 +
 .../committer-guide/apache-dubbo-page_dev.html     |   48 +
 .../committer-guide/apache-dubbo-page_dev.json     |    6 +
 .../committer-guide/label-an-issue-guide_dev.html  |   69 +
 .../committer-guide/label-an-issue-guide_dev.json  |    6 +
 .../committer-guide/new-committer-guide_dev.html   |  103 ++
 .../committer-guide/new-committer-guide_dev.json   |    6 +
 .../developers/committer-guide/release-guide.html  |   34 +
 .../developers/committer-guide/release-guide.json  |    6 +
 .../committer-guide/release-guide_dev.html         |  412 +++++
 .../committer-guide/release-guide_dev.json         |    9 +
 .../committer-guide/website-guide_dev.html         |   37 +
 .../committer-guide/website-guide_dev.json         |    6 +
 .../contributor-guide/become-a-committer_dev.html  |   40 +
 .../contributor-guide/become-a-committer_dev.json  |    6 +
 .../contributor-guide/cla-signing-guide_dev.html   |   59 +
 .../contributor-guide/cla-signing-guide_dev.json   |    6 +
 .../dubbo-extension-guide_dev.html                 |   66 +
 .../dubbo-extension-guide_dev.json                 |    6 +
 .../mailing-list-subscription-guide_dev.html       |  111 ++
 .../mailing-list-subscription-guide_dev.json       |    6 +
 .../new-contributor-guide_dev.html                 |   59 +
 .../new-contributor-guide_dev.json                 |    6 +
 .../reporting-security-issues_dev.html             |   46 +
 .../reporting-security-issues_dev.json             |    6 +
 .../software-donation-guide_dev.html               |  144 ++
 .../software-donation-guide_dev.json               |    6 +
 .../contributor-guide/test-coverage-guide_dev.html |   53 +
 .../contributor-guide/test-coverage-guide_dev.json |    6 +
 .../zh-cn/docs/developers/developers_dev.html      |  344 ++++
 .../zh-cn/docs/developers/developers_dev.json      |    6 +
 .../v2.7.3/zh-cn/docs/developers/guide_dev.html    |  108 ++
 .../v2.7.3/zh-cn/docs/developers/guide_dev.json    |    6 +
 .../zh-cn/docs/developers/user-guide/faq_dev.html  |   48 +
 .../zh-cn/docs/developers/user-guide/faq_dev.json  |    6 +
 .../docs/source_code_guide/adaptive-extension.html |  697 +++++++
 .../docs/source_code_guide/adaptive-extension.json |   10 +
 .../zh-cn/docs/source_code_guide/cluster.html      |  559 ++++++
 .../zh-cn/docs/source_code_guide/cluster.json      |   10 +
 .../zh-cn/docs/source_code_guide/directory.html    |  516 ++++++
 .../zh-cn/docs/source_code_guide/directory.json    |   10 +
 .../zh-cn/docs/source_code_guide/dubbo-spi.html    |  394 ++++
 .../zh-cn/docs/source_code_guide/dubbo-spi.json    |   10 +
 .../docs/source_code_guide/export-service.html     | 1387 ++++++++++++++
 .../docs/source_code_guide/export-service.json     |   10 +
 .../zh-cn/docs/source_code_guide/loadbalance.html  |  745 ++++++++
 .../zh-cn/docs/source_code_guide/loadbalance.json  |   10 +
 .../docs/source_code_guide/refer-service.html      |  856 +++++++++
 .../docs/source_code_guide/refer-service.json      |   10 +
 .../zh-cn/docs/source_code_guide/router.html       |  460 +++++
 .../zh-cn/docs/source_code_guide/router.json       |   10 +
 .../service-invoking-process.html                  | 1921 ++++++++++++++++++++
 .../service-invoking-process.json                  |   10 +
 doc-archive/v2.7.3/zh-cn/docs/user/README.html     |   34 +
 doc-archive/v2.7.3/zh-cn/docs/user/README.json     |    6 +
 doc-archive/v2.7.3/zh-cn/docs/user/SUMMARY.html    |  165 ++
 doc-archive/v2.7.3/zh-cn/docs/user/SUMMARY.json    |    6 +
 .../v2.7.3/zh-cn/docs/user/benchmark-tool.html     |   72 +
 .../v2.7.3/zh-cn/docs/user/benchmark-tool.json     |    6 +
 .../v2.7.3/zh-cn/docs/user/best-practice.html      |   64 +
 .../v2.7.3/zh-cn/docs/user/best-practice.json      |   10 +
 .../v2.7.3/zh-cn/docs/user/capacity-plan.html      |   48 +
 .../v2.7.3/zh-cn/docs/user/capacity-plan.json      |   10 +
 .../zh-cn/docs/user/configuration/annotation.html  |   97 +
 .../zh-cn/docs/user/configuration/annotation.json  |   10 +
 .../v2.7.3/zh-cn/docs/user/configuration/api.html  |  143 ++
 .../v2.7.3/zh-cn/docs/user/configuration/api.json  |    6 +
 .../docs/user/configuration/config-center.html     |  132 ++
 .../docs/user/configuration/config-center.json     |    6 +
 .../configuration/configuration-load-process.html  |  175 ++
 .../configuration/configuration-load-process.json  |    6 +
 .../user/configuration/environment-variables.html  |   58 +
 .../user/configuration/environment-variables.json  |    6 +
 .../zh-cn/docs/user/configuration/index.html       |   33 +
 .../zh-cn/docs/user/configuration/index.json       |    6 +
 .../user/configuration/properties deprecated.html  |   65 +
 .../user/configuration/properties deprecated.json  |    6 +
 .../user/configuration/properties-deprecated.html  |   65 +
 .../user/configuration/properties-deprecated.json  |    6 +
 .../zh-cn/docs/user/configuration/properties.html  |   61 +
 .../zh-cn/docs/user/configuration/properties.json  |    6 +
 .../v2.7.3/zh-cn/docs/user/configuration/xml.html  |  160 ++
 .../v2.7.3/zh-cn/docs/user/configuration/xml.json  |    6 +
 .../v2.7.3/zh-cn/docs/user/coveragence.html        |   43 +
 .../v2.7.3/zh-cn/docs/user/coveragence.json        |    6 +
 .../user/demos/GooglePb-generic-reference.html     |  106 ++
 .../user/demos/GooglePb-generic-reference.json     |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/accesslog.html    |   40 +
 .../v2.7.3/zh-cn/docs/user/demos/accesslog.json    |    6 +
 .../docs/user/demos/async-call-deprecated.html     |   82 +
 .../docs/user/demos/async-call-deprecated.json     |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/async-call.html   |  129 ++
 .../v2.7.3/zh-cn/docs/user/demos/async-call.json   |    6 +
 .../docs/user/demos/async-execute-on-provider.html |   98 +
 .../docs/user/demos/async-execute-on-provider.json |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/attachment.html   |   57 +
 .../v2.7.3/zh-cn/docs/user/demos/attachment.json   |    6 +
 .../zh-cn/docs/user/demos/callback-parameter.html  |  129 ++
 .../zh-cn/docs/user/demos/callback-parameter.json  |    6 +
 .../zh-cn/docs/user/demos/concurrency-control.html |   70 +
 .../zh-cn/docs/user/demos/concurrency-control.json |    6 +
 .../zh-cn/docs/user/demos/config-connections.html  |   57 +
 .../zh-cn/docs/user/demos/config-connections.json  |    6 +
 .../docs/user/demos/config-rule-deprecated.html    |   79 +
 .../docs/user/demos/config-rule-deprecated.json    |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/config-rule.html  |  210 +++
 .../v2.7.3/zh-cn/docs/user/demos/config-rule.json  |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/context.html      |   64 +
 .../v2.7.3/zh-cn/docs/user/demos/context.json      |    6 +
 .../zh-cn/docs/user/demos/delay-publish.html       |   75 +
 .../zh-cn/docs/user/demos/delay-publish.json       |    6 +
 .../docs/user/demos/distributed-transaction.html   |   43 +
 .../docs/user/demos/distributed-transaction.json   |    6 +
 doc-archive/v2.7.3/zh-cn/docs/user/demos/dump.html |   46 +
 doc-archive/v2.7.3/zh-cn/docs/user/demos/dump.json |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/echo-service.html |   49 +
 .../v2.7.3/zh-cn/docs/user/demos/echo-service.json |    6 +
 .../zh-cn/docs/user/demos/events-notify.html       |  112 ++
 .../zh-cn/docs/user/demos/events-notify.json       |    6 +
 .../zh-cn/docs/user/demos/explicit-target.html     |   62 +
 .../zh-cn/docs/user/demos/explicit-target.json     |    6 +
 .../docs/user/demos/fault-tolerent-strategy.html   |   84 +
 .../docs/user/demos/fault-tolerent-strategy.json   |    6 +
 .../zh-cn/docs/user/demos/generic-reference.html   |  108 ++
 .../zh-cn/docs/user/demos/generic-reference.json   |    6 +
 .../zh-cn/docs/user/demos/generic-service.html     |   66 +
 .../zh-cn/docs/user/demos/generic-service.json     |    6 +
 .../zh-cn/docs/user/demos/graceful-shutdown.html   |   53 +
 .../zh-cn/docs/user/demos/graceful-shutdown.json   |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/group-merger.html |   71 +
 .../v2.7.3/zh-cn/docs/user/demos/group-merger.json |    6 +
 .../zh-cn/docs/user/demos/hostname-binding.html    |  111 ++
 .../zh-cn/docs/user/demos/hostname-binding.json    |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/index.html        |   33 +
 .../v2.7.3/zh-cn/docs/user/demos/index.json        |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/introduction.html |   36 +
 .../v2.7.3/zh-cn/docs/user/demos/introduction.json |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/lazy-connect.html |   43 +
 .../v2.7.3/zh-cn/docs/user/demos/lazy-connect.json |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/loadbalance.html  |   76 +
 .../v2.7.3/zh-cn/docs/user/demos/loadbalance.json  |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/local-call.html   |   57 +
 .../v2.7.3/zh-cn/docs/user/demos/local-call.json   |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/local-mock.html   |  101 +
 .../v2.7.3/zh-cn/docs/user/demos/local-mock.json   |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/local-stub.html   |   71 +
 .../v2.7.3/zh-cn/docs/user/demos/local-stub.json   |    6 +
 .../zh-cn/docs/user/demos/logger-strategy.html     |   52 +
 .../zh-cn/docs/user/demos/logger-strategy.json     |    6 +
 .../zh-cn/docs/user/demos/metadata-report.html     |  328 ++++
 .../zh-cn/docs/user/demos/metadata-report.json     |    6 +
 .../zh-cn/docs/user/demos/multi-protocols.html     |   68 +
 .../zh-cn/docs/user/demos/multi-protocols.json     |    6 +
 .../zh-cn/docs/user/demos/multi-registry.html      |  103 ++
 .../zh-cn/docs/user/demos/multi-registry.json      |    6 +
 .../zh-cn/docs/user/demos/multi-versions.html      |   62 +
 .../zh-cn/docs/user/demos/multi-versions.json      |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/netty4.html       |   64 +
 .../v2.7.3/zh-cn/docs/user/demos/netty4.json       |    6 +
 .../docs/user/demos/parameter-validation.html      |  194 ++
 .../docs/user/demos/parameter-validation.json      |    6 +
 .../zh-cn/docs/user/demos/preflight-check.html     |   63 +
 .../zh-cn/docs/user/demos/preflight-check.json     |    6 +
 .../docs/user/demos/reference-config-cache.html    |   56 +
 .../docs/user/demos/reference-config-cache.json    |    6 +
 .../zh-cn/docs/user/demos/registry-only.html       |   42 +
 .../zh-cn/docs/user/demos/registry-only.json       |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/result-cache.html |   58 +
 .../v2.7.3/zh-cn/docs/user/demos/result-cache.json |    6 +
 .../docs/user/demos/routing-rule deprecated.html   |  207 +++
 .../docs/user/demos/routing-rule deprecated.json   |    6 +
 .../docs/user/demos/routing-rule-deprecated.html   |  207 +++
 .../docs/user/demos/routing-rule-deprecated.json   |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/routing-rule.html |  254 +++
 .../v2.7.3/zh-cn/docs/user/demos/routing-rule.json |    6 +
 .../zh-cn/docs/user/demos/serialization.html       |   92 +
 .../zh-cn/docs/user/demos/serialization.json       |    6 +
 .../zh-cn/docs/user/demos/service-container.html   |   83 +
 .../zh-cn/docs/user/demos/service-container.json   |    6 +
 .../zh-cn/docs/user/demos/service-downgrade.html   |   51 +
 .../zh-cn/docs/user/demos/service-downgrade.json   |    6 +
 .../zh-cn/docs/user/demos/service-group.html       |   52 +
 .../zh-cn/docs/user/demos/service-group.json       |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/set-host.html     |   88 +
 .../v2.7.3/zh-cn/docs/user/demos/set-host.json     |    6 +
 .../docs/user/demos/simplify-registry-data.html    |  328 ++++
 .../docs/user/demos/simplify-registry-data.json    |    6 +
 .../zh-cn/docs/user/demos/static-service.html      |   52 +
 .../zh-cn/docs/user/demos/static-service.json      |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/stickiness.html   |   42 +
 .../v2.7.3/zh-cn/docs/user/demos/stickiness.json   |    6 +
 .../zh-cn/docs/user/demos/subscribe-only.html      |   42 +
 .../zh-cn/docs/user/demos/subscribe-only.json      |    6 +
 .../v2.7.3/zh-cn/docs/user/demos/thread-model.html |   55 +
 .../v2.7.3/zh-cn/docs/user/demos/thread-model.json |    6 +
 .../zh-cn/docs/user/demos/token-authorization.html |   51 +
 .../zh-cn/docs/user/demos/token-authorization.json |    6 +
 .../v2.7.3/zh-cn/docs/user/dependencies.html       |   94 +
 .../v2.7.3/zh-cn/docs/user/dependencies.json       |   10 +
 .../docs/user/languages/erlang/reference.html      |   45 +
 .../docs/user/languages/erlang/reference.json      |    6 +
 .../docs/user/languages/erlang/serialization.html  |   60 +
 .../docs/user/languages/erlang/serialization.json  |    6 +
 .../zh-cn/docs/user/languages/erlang/service.html  |   75 +
 .../zh-cn/docs/user/languages/erlang/service.json  |    6 +
 .../zh-cn/docs/user/languages/erlang/start.html    |   77 +
 .../zh-cn/docs/user/languages/erlang/start.json    |    6 +
 doc-archive/v2.7.3/zh-cn/docs/user/maturity.html   |  637 +++++++
 doc-archive/v2.7.3/zh-cn/docs/user/maturity.json   |   10 +
 doc-archive/v2.7.3/zh-cn/docs/user/perf-test.html  |  349 ++++
 doc-archive/v2.7.3/zh-cn/docs/user/perf-test.json  |   10 +
 .../zh-cn/docs/user/preface/architecture.html      |  138 ++
 .../zh-cn/docs/user/preface/architecture.json      |    6 +
 .../v2.7.3/zh-cn/docs/user/preface/background.html |   43 +
 .../v2.7.3/zh-cn/docs/user/preface/background.json |    6 +
 .../v2.7.3/zh-cn/docs/user/preface/index.html      |   33 +
 .../v2.7.3/zh-cn/docs/user/preface/index.json      |    6 +
 .../zh-cn/docs/user/preface/requirements.html      |   39 +
 .../zh-cn/docs/user/preface/requirements.json      |   10 +
 .../v2.7.3/zh-cn/docs/user/preface/usage.html      |   60 +
 .../v2.7.3/zh-cn/docs/user/preface/usage.json      |    6 +
 .../v2.7.3/zh-cn/docs/user/quick-start.html        |  140 ++
 .../v2.7.3/zh-cn/docs/user/quick-start.json        |   10 +
 doc-archive/v2.7.3/zh-cn/docs/user/recommend.html  |  168 ++
 doc-archive/v2.7.3/zh-cn/docs/user/recommend.json  |   10 +
 .../v2.7.3/zh-cn/docs/user/references/api.html     |   77 +
 .../v2.7.3/zh-cn/docs/user/references/api.json     |    6 +
 .../v2.7.3/zh-cn/docs/user/references/maven.html   |   48 +
 .../v2.7.3/zh-cn/docs/user/references/maven.json   |    6 +
 .../user/references/metadata/introduction.html     |  328 ++++
 .../user/references/metadata/introduction.json     |    6 +
 .../user/references/metadata/metadata-redis.html   |   33 +
 .../user/references/metadata/metadata-redis.json   |    6 +
 .../references/metadata/metadata-zookeeper.html    |   33 +
 .../references/metadata/metadata-zookeeper.json    |    6 +
 .../zh-cn/docs/user/references/protocol/dubbo.html |  149 ++
 .../zh-cn/docs/user/references/protocol/dubbo.json |    6 +
 .../docs/user/references/protocol/hessian.html     |   85 +
 .../docs/user/references/protocol/hessian.json     |    6 +
 .../zh-cn/docs/user/references/protocol/http.html  |   81 +
 .../zh-cn/docs/user/references/protocol/http.json  |    6 +
 .../user/references/protocol/introduction.html     |   34 +
 .../user/references/protocol/introduction.json     |    6 +
 .../docs/user/references/protocol/memcached.html   |   66 +
 .../docs/user/references/protocol/memcached.json   |    6 +
 .../zh-cn/docs/user/references/protocol/redis.html |   66 +
 .../zh-cn/docs/user/references/protocol/redis.json |    6 +
 .../zh-cn/docs/user/references/protocol/rest.html  |  533 ++++++
 .../zh-cn/docs/user/references/protocol/rest.json  |    6 +
 .../zh-cn/docs/user/references/protocol/rmi.html   |   98 +
 .../zh-cn/docs/user/references/protocol/rmi.json   |    6 +
 .../docs/user/references/protocol/thrift.html      |   63 +
 .../docs/user/references/protocol/thrift.json      |    6 +
 .../docs/user/references/protocol/webservice.html  |  116 ++
 .../docs/user/references/protocol/webservice.json  |    6 +
 .../v2.7.3/zh-cn/docs/user/references/qos.html     |  225 +++
 .../v2.7.3/zh-cn/docs/user/references/qos.json     |    6 +
 .../user/references/registry/introduction.html     |   34 +
 .../user/references/registry/introduction.json     |    6 +
 .../docs/user/references/registry/multicast.html   |   56 +
 .../docs/user/references/registry/multicast.json   |    6 +
 .../zh-cn/docs/user/references/registry/nacos.html |  111 ++
 .../zh-cn/docs/user/references/registry/nacos.json |    6 +
 .../zh-cn/docs/user/references/registry/redis.html |   95 +
 .../zh-cn/docs/user/references/registry/redis.json |    6 +
 .../docs/user/references/registry/simple.html      |   65 +
 .../docs/user/references/registry/simple.json      |    6 +
 .../docs/user/references/registry/zookeeper.html   |  128 ++
 .../docs/user/references/registry/zookeeper.json   |    6 +
 .../v2.7.3/zh-cn/docs/user/references/telnet.html  |  124 ++
 .../v2.7.3/zh-cn/docs/user/references/telnet.json  |    6 +
 .../user/references/xml/dubbo-application.html     |  130 ++
 .../user/references/xml/dubbo-application.json     |    6 +
 .../docs/user/references/xml/dubbo-argument.html   |   84 +
 .../docs/user/references/xml/dubbo-argument.json   |    6 +
 .../user/references/xml/dubbo-config-center.html   |  166 ++
 .../user/references/xml/dubbo-config-center.json   |    6 +
 .../docs/user/references/xml/dubbo-consumer.html   |  230 +++
 .../docs/user/references/xml/dubbo-consumer.json   |    6 +
 .../docs/user/references/xml/dubbo-method.html     |  215 +++
 .../docs/user/references/xml/dubbo-method.json     |    6 +
 .../docs/user/references/xml/dubbo-module.html     |   90 +
 .../docs/user/references/xml/dubbo-module.json     |    6 +
 .../docs/user/references/xml/dubbo-monitor.html    |   70 +
 .../docs/user/references/xml/dubbo-monitor.json    |    6 +
 .../docs/user/references/xml/dubbo-parameter.html  |   78 +
 .../docs/user/references/xml/dubbo-parameter.json  |    6 +
 .../docs/user/references/xml/dubbo-protocol.html   |  290 +++
 .../docs/user/references/xml/dubbo-protocol.json   |    6 +
 .../docs/user/references/xml/dubbo-provider.html   |  490 +++++
 .../docs/user/references/xml/dubbo-provider.json   |    6 +
 .../docs/user/references/xml/dubbo-reference.html  |  320 ++++
 .../docs/user/references/xml/dubbo-reference.json  |    6 +
 .../docs/user/references/xml/dubbo-registry.html   |  230 +++
 .../docs/user/references/xml/dubbo-registry.json   |   10 +
 .../docs/user/references/xml/dubbo-service.html    |  360 ++++
 .../docs/user/references/xml/dubbo-service.json    |    6 +
 .../docs/user/references/xml/introduction.html     |   52 +
 .../docs/user/references/xml/introduction.json     |    6 +
 doc-archive/v2.7.3/zh-cn/docs/user/rest.html       |  955 ++++++++++
 doc-archive/v2.7.3/zh-cn/docs/user/rest.json       |   10 +
 .../v2.7.3/zh-cn/docs/user/serialization.html      |  299 +++
 .../v2.7.3/zh-cn/docs/user/serialization.json      |    6 +
 .../v2.7.3/zh-cn/docs/user/simple-monitor.html     |  112 ++
 .../v2.7.3/zh-cn/docs/user/simple-monitor.json     |    6 +
 .../v2.7.3/zh-cn/docs/user/version-upgrading.html  |   38 +
 .../v2.7.3/zh-cn/docs/user/version-upgrading.json  |    6 +
 .../v2.7.3/zh-cn/docs/user/versions/index.html     |   34 +
 .../v2.7.3/zh-cn/docs/user/versions/index.json     |    6 +
 .../zh-cn/docs/user/versions/version-270.html      |  340 ++++
 .../zh-cn/docs/user/versions/version-270.json      |   10 +
 .../docs/user/versions/version-upgrading.html      |   38 +
 .../docs/user/versions/version-upgrading.json      |    6 +
 doc-archive/v2.7.3/zh-cn/download/index.html       |   32 +
 doc-archive/v2.7.3/zh-cn/ecology/index.html        |   32 +
 doc-archive/v2.7.3/zh-cn/index.html                |   32 +
 593 files changed, 49144 insertions(+)

diff --git a/doc-archive/v2.7.3/zh-cn/blog/Configuration Conclude.html b/doc-archive/v2.7.3/zh-cn/blog/Configuration Conclude.html
new file mode 100644
index 0000000..6176f4c
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/Configuration Conclude.html	
@@ -0,0 +1,189 @@
+<!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="Configuration Conclude" />
+	<meta name="description" content="Configuration Conclude" />
+	<!-- 网页标签标题 -->
+	<title>Configuration Conclude</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>我们这篇文章主要讲在<strong>应用启动阶段,Dubbo框架如何将所需要的配置采集起来</strong>(包括应用配置、注册中心配置、服务配置等),以完成服务的暴露和引用流程。</p>
+<p>根据驱动方式的不同(比如Spring或裸API编程)配置形式上肯定会有所差异,这个我们接下来会对<a href="#%E5%87%A0%E7%A7%8D%E7%BC%96%E7%A8%8B%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F">每种方式分别展开介绍</a>。除了外围驱动方式上的差异,Dubbo的配置读取总体上遵循了以下几个原则:</p>
+<ol>
+<li>Dubbo支持了多层级的配置,并预定按优先级自动实现配置间的覆盖,最终被汇总到数据总线URL驱动后续的服务暴露、引用等流程。</li>
+<li>ApplicationConfig、ServiceConfig、ReferenceConfig可以被理解成配置来源的一种,是直接面向用户编程的配置采集方式。</li>
+<li>配置格式以Properties为主,在key的命名上有一套自己的<a href="#%E9%85%8D%E7%BD%AE%E6%A0%BC%E5%BC%8F">规范</a></li>
+</ol>
+<h2>配置来源</h2>
+<p>首先,从Dubbo支持的配置来源说起,默认有四种配置来源:</p>
+<ul>
+<li>JVM System Properties,-D参数</li>
+<li>Externalized Configuration,外部化配置</li>
+<li>ServiceConfig、ReferenceConfig等编程接口采集的配置</li>
+<li>本地配置文件dubbo.properties</li>
+</ul>
+<h3>覆盖关系</h3>
+<p>下图展示了配置覆盖关系的优先级,从上到下优先级依次降低:</p>
+<p><img src="../../img/blog/configuration.jpg" alt="覆盖关系"></p>
+<h3>外部化配置</h3>
+<p>外部化配置即Config Center是2.7.0中新引入的一种配置源,目的是能实现配置的集中式管理,对于配置集中管理业界已经有很多成熟的专业配置系统如Apollo, Nacos等,Dubbo所做的只是保证能配合这些系统正常工作。</p>
+<p>2.7.0版本开始支持<code>Zookeeper</code>、<code>Apollo</code>两种配置存储。</p>
+<p>以Zookeeper为例,外部化配置就是存储在<code>/dubbo/config/dubbo/dubbo.properties</code>路径下的<code>.properties</code>文件:</p>
+<pre><code class="language-properties"><span class="hljs-comment"># 将注册中心地址、元数据中心地址等配置集中管理,可以做到统一环境、减少开发侧感知。</span>
+<span class="hljs-meta">dubbo.registry.address</span>=<span class="hljs-string">zookeeper://127.0.0.1:2181</span>
+<span class="hljs-meta">dubbo.registry.simplified</span>=<span class="hljs-string">true</span>
+
+<span class="hljs-meta">dubbo.metadataReport.address</span>=<span class="hljs-string">zookeeper://127.0.0.1:2181</span>
+
+<span class="hljs-meta">dubbo.protocol.name</span>=<span class="hljs-string">dubbo</span>
+<span class="hljs-meta">dubbo.protocol.port</span>=<span class="hljs-string">20880</span>
+
+<span class="hljs-meta">dubbo.application.qos.port</span>=<span class="hljs-string">33333</span>
+</code></pre>
+<p>所谓Dubbo对这些配置中心的支持,本质上就是把<code>.properties</code>从远程拉取到本地,然后和本地的配置做一次融合。所以理论上只要Dubbo框架能拿到需要的配置就可以正常的工作,所以Dubbo还提供了以下API,让用户将自己组织好的配置塞给Dubbo框架(至于配置从哪里来是用户要完成的事情),这样Dubbo框架就不再直接和Apollo或Zookeeper做读取配置交互。</p>
+<pre><code class="language-java">Map&lt;String, String&gt; dubboConfigurations = <span class="hljs-keyword">new</span> HashMap&lt;&gt;();
+dubboConfigurations.put(<span class="hljs-string">"dubbo.registry.address"</span>, <span class="hljs-string">"zookeeper://127.0.0.1:2181"</span>);
+dubboConfigurations.put(<span class="hljs-string">"dubbo.registry.simplified"</span>, <span class="hljs-string">"true"</span>);
+
+ConfigCenterConfig configCenter = <span class="hljs-keyword">new</span> ConfigCenterConfig();
+configCenter.setExternalConfig(dubboConfigurations);
+</code></pre>
+<h2>配置格式</h2>
+<p>目前Dubbo支持的所有配置都是<code>.properties</code>格式的,包括<code>-D</code>、<code>Externalized Configuration</code>等,<code>.properties</code>中的所有配置项遵循一种<code>path-based</code>的配置格式:</p>
+<pre><code class="language-properties"><span class="hljs-comment"># 应用级别</span>
+<span class="hljs-meta">dubbo.{config-type}[.{config-id}].{config-item}</span>=<span class="hljs-string">{config-item-value}</span>
+<span class="hljs-comment"># 服务级别</span>
+<span class="hljs-meta">dubbo.service.{interface-name}[.{method-name}].{config-item}</span>=<span class="hljs-string">{config-item-value}</span>
+<span class="hljs-meta">dubbo.reference.{interface-name}[.{method-name}].{config-item}</span>=<span class="hljs-string">{config-item-value}</span>
+<span class="hljs-comment"># 多配置项</span>
+<span class="hljs-meta">dubbo.{config-type}s.{config-id}.{config-item}</span>=<span class="hljs-string">{config-item-value}</span>
+</code></pre>
+<ul>
+<li>应用级别</li>
+</ul>
+<pre><code class="language-properties"><span class="hljs-meta">dubbo.application.name</span>=<span class="hljs-string">demo-provider</span>
+<span class="hljs-meta">dubbo.registry.address</span>=<span class="hljs-string">zookeeper://127.0.0.1:2181</span>
+<span class="hljs-meta">dubbo.protocol.port</span>=<span class="hljs-string">-1</span>
+</code></pre>
+<ul>
+<li>服务级别</li>
+</ul>
+<pre><code class="language-properties"><span class="hljs-meta">dubbo.service.org.apache.dubbo.samples.api.DemoService.timeout</span>=<span class="hljs-string">5000</span>
+<span class="hljs-meta">dubbo.reference.org.apache.dubbo.samples.api.DemoService.tineout</span>=<span class="hljs-string">6000</span>
+<span class="hljs-meta">dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.timeout</span>=<span class="hljs-string">7000</span>
+</code></pre>
+<ul>
+<li>多配置项</li>
+</ul>
+<pre><code class="language-properties"><span class="hljs-meta">dubbo.registries.unit1.address</span>=<span class="hljs-string">zookeeper://127.0.0.1:2181</span>
+<span class="hljs-meta">dubbo.registries.unit2.address</span>=<span class="hljs-string">zookeeper://127.0.0.1:2182</span>
+
+<span class="hljs-meta">dubbo.protocols.dubbo.name</span>=<span class="hljs-string">dubbo</span>
+<span class="hljs-meta">dubbo.protocols.dubbo.port</span>=<span class="hljs-string">20880</span>
+<span class="hljs-meta">dubbo.protocols.hessian.name</span>=<span class="hljs-string">hessian</span>
+<span class="hljs-meta">dubbo.protocols.hessian.port</span>=<span class="hljs-string">8089</span>
+</code></pre>
+<h2>几种编程配置方式</h2>
+<p>接下来,我们看一下选择不同的开发方式时,对应到<code>ServiceConfig、ReferenceConfig等编程接口采集的配置</code>的变化。</p>
+<h3>Spring</h3>
+<ul>
+<li>XML</li>
+</ul>
+<p>参见<a href="https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-basic">示例</a></p>
+<pre><code class="language-xml">  <span class="hljs-comment">&lt;!-- dubbo-provier.xml --&gt;</span>
+
+  <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"demo-provider"</span>/&gt;</span>
+  <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:conig-center</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span>/&gt;</span>
+
+  <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span> <span class="hljs-attr">simplified</span>=<span class="hljs-string">"true"</span>/&gt;</span>
+  <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:metadata-report</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"redis://127.0.0.1:6379"</span>/&gt;</span>
+  <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"dubbo"</span> <span class="hljs-attr">port</span>=<span class="hljs-string">"20880"</span>/&gt;</span>
+
+  <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.apache.dubbo.samples.basic.impl.DemoServiceImpl"</span>/&gt;</span>
+  <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.samples.basic.api.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span>/&gt;</span>
+</code></pre>
+<ul>
+<li>Annotation</li>
+</ul>
+<p>参见<a href="https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-annotation">示例</a></p>
+<pre><code class="language-java">  <span class="hljs-comment">// AnnotationService服务实现</span>
+
+  <span class="hljs-meta">@Service</span>
+  <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AnnotationServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">AnnotationService</span> </span>{
+      <span class="hljs-meta">@Override</span>
+      <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">sayHello</span><span class="hljs-params">(String name)</span> </span>{
+          System.out.println(<span class="hljs-string">"async provider received: "</span> + name);
+          <span class="hljs-keyword">return</span> <span class="hljs-string">"annotation: hello, "</span> + name;
+      }
+  }
+</code></pre>
+<pre><code class="language-properties"><span class="hljs-comment">  ## dubbo.properties</span>
+
+  <span class="hljs-meta">dubbo.application.name</span>=<span class="hljs-string">annotation-provider</span>
+  <span class="hljs-meta">dubbo.registry.address</span>=<span class="hljs-string">zookeeper://127.0.0.1:2181</span>
+  <span class="hljs-meta">dubbo.protocol.name</span>=<span class="hljs-string">dubbo</span>
+  <span class="hljs-meta">dubbo.protocol.port</span>=<span class="hljs-string">20880</span>
+</code></pre>
+<ul>
+<li>Spring Boot</li>
+</ul>
+<p>参见<a href="https://github.com/apache/dubbo-spring-boot-project/tree/master/dubbo-spring-boot-samples">示例</a></p>
+<pre><code class="language-properties"><span class="hljs-comment">  ## application.properties</span>
+<span class="hljs-comment">
+  # Spring boot application</span>
+  <span class="hljs-meta">spring.application.name</span>=<span class="hljs-string">dubbo-externalized-configuration-provider-sample</span>
+<span class="hljs-comment">
+  # Base packages to scan Dubbo Component: @com.alibaba.dubbo.config.annotation.Service</span>
+  <span class="hljs-meta">dubbo.scan.base-packages</span>=<span class="hljs-string">com.alibaba.boot.dubbo.demo.provider.service</span>
+<span class="hljs-comment">
+  # Dubbo Application</span>
+<span class="hljs-comment">  ## The default value of dubbo.application.name is ${spring.application.name}</span>
+<span class="hljs-comment">  ## dubbo.application.name=${spring.application.name}</span>
+<span class="hljs-comment">
+  # Dubbo Protocol</span>
+  <span class="hljs-meta">dubbo.protocol.name</span>=<span class="hljs-string">dubbo</span>
+  <span class="hljs-meta">dubbo.protocol.port</span>=<span class="hljs-string">12345</span>
+<span class="hljs-comment">
+  ## Dubbo Registry</span>
+  <span class="hljs-meta">dubbo.registry.address</span>=<span class="hljs-string">N/A</span>
+<span class="hljs-comment">
+  ## DemoService version</span>
+  <span class="hljs-meta">demo.service.version</span>=<span class="hljs-string">1.0.0</span>
+</code></pre>
+<h3>API</h3>
+<pre><code class="language-java"><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">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> IOException </span>{
+    ServiceConfig&lt;GreetingsService&gt; service = <span class="hljs-keyword">new</span> ServiceConfig&lt;&gt;();
+    service.setApplication(<span class="hljs-keyword">new</span> ApplicationConfig(<span class="hljs-string">"first-dubbo-provider"</span>));
+    service.setRegistry(<span class="hljs-keyword">new</span> RegistryConfig(<span class="hljs-string">"multicast://224.5.6.7:1234"</span>));
+    service.setInterface(GreetingsService.class);
+    service.setRef(<span class="hljs-keyword">new</span> GreetingsServiceImpl());
+    service.export();
+    System.out.println(<span class="hljs-string">"first-dubbo-provider is running."</span>);
+    System.in.read();
+}
+</code></pre>
+<p>参考<a href="https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-api">示例</a></p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making proce [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
diff --git a/doc-archive/v2.7.3/zh-cn/blog/Configuration Conclude.json b/doc-archive/v2.7.3/zh-cn/blog/Configuration Conclude.json
new file mode 100644
index 0000000..366562e
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/Configuration Conclude.json	
@@ -0,0 +1,6 @@
+{
+  "filename": "Configuration Conclude.md",
+  "__html": "<h1>配置方式总结</h1>\n<p>我们这篇文章主要讲在<strong>应用启动阶段,Dubbo框架如何将所需要的配置采集起来</strong>(包括应用配置、注册中心配置、服务配置等),以完成服务的暴露和引用流程。</p>\n<p>根据驱动方式的不同(比如Spring或裸API编程)配置形式上肯定会有所差异,这个我们接下来会对<a href=\"#%E5%87%A0%E7%A7%8D%E7%BC%96%E7%A8%8B%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F\">每种方式分别展开介绍</a>。除了外围驱动方式上的差异,Dubbo的配置读取总体上遵循了以下几个原则:</p>\n<ol>\n<li>Dubbo支持了多层级的配置,并预定按优先级自动实现配置间的覆盖,最终被汇总到数据总线URL驱动后续的服务暴露、引用等流程。</li>\n<li>ApplicationConfig、ServiceConfig、ReferenceConfig可以被理解成配置来源的一种,是直接面向用户编程的配置采集方式。</li>\n< [...]
+  "link": "/zh-cn/blog/Configuration Conclude.html",
+  "meta": {}
+}
diff --git a/doc-archive/v2.7.3/zh-cn/blog/Dubbo-supporting-gRPC-HTTP2-and-protobuf.html b/doc-archive/v2.7.3/zh-cn/blog/Dubbo-supporting-gRPC-HTTP2-and-protobuf.html
new file mode 100644
index 0000000..ea75877
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/Dubbo-supporting-gRPC-HTTP2-and-protobuf.html
@@ -0,0 +1,634 @@
+<!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="Dubbo-supporting-gRPC-HTTP2-and-protobuf" />
+	<meta name="description" content="Dubbo-supporting-gRPC-HTTP2-and-protobuf" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo-supporting-gRPC-HTTP2-and-protobuf</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>本文整理自刘军在 Dubbo 成都 meetup 上分享的《Dubbo 在多语言和协议穿透性方向上的探索》。</p>
+<p>本文总体上可分为基础产品简介、Dubbo 对 gRPC (HTTP/2) 和 Protobuf 的支持及示例演示三部分,在简介部分介绍了 Dubbo、HTTP/2、gRPC、Protobuf 的基本概念和特点;第二部分介绍了 Dubbo 为何要支持 gRPC (HTTP/2) 和 Protobuf,以及这种支持为 gRPC 和 Dubbo 开发带来的好处与不同;第三部分通过两个实例分别演示了 Dubbo gRPC 和 Dubbo Protobuf 的使用方式。</p>
+<h2>基本介绍</h2>
+<h3>Dubbo 协议</h3>
+<p>从协议层面展开,以下是当前 2.7 版本支持的 Dubbo 协议</p>
+<p><img src="img/blog/grpc/dubbo-ptotocol.png" alt="image-20191029103919557"></p>
+<p>众所周知,Dubbo 协议是直接定义在 TCP 传输层协议之上,由于 TCP 高可靠全双工的特点,为 Dubbo 协议的定义提供了最大的灵活性,但同时也正是因为这样的灵活性,RPC 协议普遍都是定制化的私有协议,Dubbo 同样也面临这个问题。在这里我们着重讲一下 Dubbo 在协议通用性方面值得改进的地方,关于协议详细解析请参见<a href="http://dubbo.apache.org/zh-cn/blog/dubbo-protocol.html">官网博客</a></p>
+<ul>
+<li>Dubbo 协议体 Body 中有一个可扩展的 attachments 部分,这给 RPC 方法之外额外传递附加属性提供了可能,是一个很好的设计。但是类似的 Header 部分,却缺少类似的可扩展 attachments,这点可参考 HTTP 定义的 Ascii Header 设计,将 Body Attachments 和 Header Attachments 做职责划分。</li>
+<li>Body 协议体中的一些 RPC 请求定位符如 Service Name、Method Name、Version 等,可以提到 Header 中,和具体的序列化协议解耦,以更好的被网络基础设施识别或用于流量管控。</li>
+<li>扩展性不够好,欠缺协议升级方面的设计,如 Header 头中没有预留的状态标识位,或者像 HTTP 有专为协议升级或协商设计的特殊 packet。</li>
+<li>在 Java 版本的代码实现上,不够精简和通用。如在链路传输中,存在一些语言绑定的内容;消息体中存在冗余内容,如 Service Name 在 Body 和 Attachments 中都存在。</li>
+</ul>
+<h3>HTTP/1</h3>
+<p>相比于直接构建与 TPC 传输层的私有 RPC 协议,构建于 HTTP 之上的远程调用解决方案会有更好的通用性,如WebServices 或 REST 架构,使用 HTTP + JSON 可以说是一个事实标准的解决方案。</p>
+<p>之所有选择构建在 HTTP 之上,我认为有两个最大的优势:</p>
+<ol>
+<li>HTTP 的语义和可扩展性能很好的满足 RPC 调用需求。</li>
+<li>通用性,HTTP 协议几乎被网络上的所有设备所支持,具有很好的协议穿透性。</li>
+</ol>
+<p><img src="../../img/blog/grpc/http1.png" alt="image-20191029113404906"></p>
+<p>具体来说,HTTP/1 的优势和限制是:</p>
+<ul>
+<li>
+<p>典型的 Request – Response 模型,一个链路上一次只能有一个等待的 Request 请求</p>
+</li>
+<li>
+<p>HTTP/1 支持 Keep-Alive 链接,避免了链接重复创建开销</p>
+</li>
+<li>
+<p>Human Readable Headers,使用更通用、更易于人类阅读的头部传输格式</p>
+</li>
+<li>
+<p>无直接 Server Push 支持,需要使用 Polling Long-Polling 等变通模式</p>
+</li>
+</ul>
+<h3>HTTP/2</h3>
+<p>HTTP/2 保留了 HTTP/1 的所有语义,在保持兼容的同时,在通信模型和传输效率上做了很大的改进。</p>
+<p><img src="../../img/blog/grpc/http2.png" alt="image-20191029113416731"></p>
+<ul>
+<li>
+<p>支持单条链路上的 Multiplexing,相比于 Request - Response 独占链路,基于 Frame 实现更高效利用链路</p>
+</li>
+<li>
+<p>Request - Stream 语义,原生支持 Server Push 和 Stream 数据传输</p>
+</li>
+<li>
+<p>Flow Control,单条 Stream 粒度的和整个链路粒度的流量控制</p>
+</li>
+<li>
+<p>头部压缩 HPACK</p>
+</li>
+<li>
+<p>Binary Frame</p>
+</li>
+<li>
+<p>原生 TLS 支持</p>
+</li>
+</ul>
+<h3>gRPC</h3>
+<p>上面提到了在 HTTP 及 TCP 协议之上构建 RPC 协议各自的优缺点,相比于 Dubbo 构建于 TPC 传输层之上,Google 选择将 gRPC 直接定义在 HTTP/2 协议之上,关于 gRPC 的 [基本介绍](<a href="https://platformlab.stanford.edu/Seminar">https://platformlab.stanford.edu/Seminar</a> Talks/gRPC.pdf)和 <a href="https://grpc.io/blog/principles/?spm=ata.13261165.0.0.2be55017XbUhs8">设计愿景</a> 请参考以上两篇文章,我这里仅摘取 设计愿景 中几个能反映 gRPC 设计目的特性来做简单说明。</p>
+<ul>
+<li>
+<p>Coverage &amp; Simplicity,协议设计和框架实现要足够通用和简单,能运行在任何设备之上,甚至一些资源首先的如 IoT、Mobile 等设备。</p>
+</li>
+<li>
+<p>Interoperability &amp; Reach,要构建在更通用的协议之上,协议本身要能被网络上几乎所有的基础设施所支持。</p>
+</li>
+<li>
+<p>General Purpose &amp; Performant,要在场景和性能间做好平衡,首先协议本身要是适用于各种场景的,同时也要尽量有高的性能。</p>
+</li>
+<li>
+<p>Payload Agnostic,协议上传输的负载要保持语言和平台中立。</p>
+</li>
+<li>
+<p>Streaming,要支持 Request - Response、Request - Stream、Bi-Steam 等通信模型。</p>
+</li>
+<li>
+<p>Flow Control,协议自身具备流量感知和限制的能力。</p>
+</li>
+<li>
+<p>Metadata Exchange,在 RPC 服务定义之外,提供额外附加数据传输的能力。</p>
+</li>
+</ul>
+<p>总的来说,在这样的设计理念指导下,gRPC 最终被设计为一个跨语言、跨平台的、通用的、高性能的、基于 HTTP/2 的 RPC 协议和框架。</p>
+<h3>Protobuf</h3>
+<p><a href="https://developers.google.com/protocol-buffers/docs/overview">Protocol buffers (Protobuf)</a> 是 Google 推出的一个跨平台、语言中立的结构化数据描述和序列化的产品,它定义了一套结构化数据定义的协议,同时也提供了相应的 <a href="https://github.com/protocolbuffers/protobuf/releases/tag/v3.10.0">Compiler</a> 工具,用来将语言中立的描述转化为相应语言的具体描述。</p>
+<p>它的一些特性包括:</p>
+<ul>
+<li>
+<p>跨语言 跨平台,语言中立的数据描述格式,默认提供了生成多种语言的 Compiler 工具。</p>
+</li>
+<li>
+<p>安全性,由于反序列化的范围和输出内容格式都是 Compiler 在编译时预生成的,因此绕过了类似 Java Deserialization Vulnarability 的问题。</p>
+</li>
+<li>
+<p>二进制 高性能</p>
+</li>
+<li>
+<p>强类型</p>
+</li>
+<li>
+<p>字段变更向后兼容</p>
+</li>
+</ul>
+<pre><code class="language-idl">message Person {
+  required string name = 1;
+  required int32 id = 2;
+  optional string email = 3;
+
+  enum PhoneType {
+    MOBILE = 0;
+    HOME = 1;
+    WORK = 2;
+  }
+
+  message PhoneNumber {
+    required string number = 1;
+    optional PhoneType type = 2 [default = HOME];
+  }
+
+  repeated PhoneNumber phone = 4;
+}
+</code></pre>
+<p>除了结构化数据描述之外,Protobuf 还支持定义 RPC 服务,它允许我们定义一个 <code>.proto</code> 的服务描述文件,进而利用 Protobuf Compiler 工具生成特定语言和 RPC 框架的接口和 stub。后续将要具体讲到的 gRPC + Protobuf、Dubbo-gRPC + Protobuf 以及 Dubbo + Protobuf 都是通过定制 Compiler 类实现的。</p>
+<pre><code class="language-idl">service SearchService {
+ rpc Search (SearchRequest) returns (SearchResponse);
+}
+</code></pre>
+<h2>Dubbo 所做的支持</h2>
+<p>跨语言的服务开发涉及到多个方面,从服务定义、RPC 协议到序列化协议都要做到语言中立,同时还针对每种语言有对应的 SDK 实现。虽然得益于社区的贡献,现在 Dubbo 在多语言 SDK 实现上逐步有了起色,已经提供了包括 Java, Go, PHP, C#, Python, NodeJs, C 等版本的客户端或全量实现版本,但在以上提到的跨语言友好型方面,以上三点还是有很多可改进之处。</p>
+<ul>
+<li>
+<p>协议,上面我们已经分析过 Dubbo 协议既有的缺点,如果能在 HTTP/2 之上构建应用层协议,则无疑能避免这些弊端,同时最大可能的提高协议的穿透性,避免网关等协议转换组件的存在,更有利于链路上的流量管控。考虑到 gRPC 是构建在 HTTP/2 之上,并且已经是云原生领域推荐的通信协议,Dubbo 在第一阶段选择了直接支持 gRPC 协议作为当前的 HTTP/2 解决方案。我们也知道 gRPC 框架自身的弊端在于易用性不足以及服务治理能力欠缺(这也是目前绝大多数厂商不会直接裸用 gRPC 框架的原因),通过将其集成进 Dubbo 框架,用户可以方便的使用 Dubbo 编程模型 + Dubbo 服务治理 + gRPC 协议通信的组合。</p>
+</li>
+<li>
+<p>服务定义,当前 Dubbo 的服务定义和具体的编程语言绑定,没有提供一种语言中立的服务描述格式,比如 Java 就是定义 Interface 接口,到了其他语言又得重新以另外的格式定义一遍。因此 Dubbo 通过支持 Protobuf 实现了语言中立的服务定义。</p>
+</li>
+<li>
+<p>序列化,Dubbo 当前支持的序列化包括 Json、Hessian2、Kryo、FST、Java 等,而这其中支持跨语言的只有 Json、Hessian2,通用的 Json 有固有的性能问题,而 Hessian2 无论在效率还是多语言 SDK 方面都有所欠缺。为此,Dubbo 通过支持 Protobuf 序列化来提供更高效、易用的跨语言序列化方案。</p>
+</li>
+</ul>
+<h2>示例</h2>
+<h3>示例 1,使用 Dubbo 开发 gRPC 服务</h3>
+<p><a href="https://grpc.io/">gRPC</a> 是 Google 开源的构建在 HTTP/2 之上的一个 PRC 通信协议。Dubbo 依赖其灵活的协议扩展机制,增加了对 gRPC (HTTP/2) 协议的支持。</p>
+<p>目前的支持限定在 Dubbo Java 语言版本,后续 Go 语言或其他语言版本将会以类似方式提供支持。下面,通过一个<a href="https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-grpc">简单的示例</a>来演示如何在 Dubbo 中使用 gRPC 协议通信。</p>
+<h4>1. 定义服务 IDL</h4>
+<p>首先,通过标准的 Protobuf 协议定义服务如下:</p>
+<pre><code class="language-idl">syntax = &quot;proto3&quot;;
+
+option java_multiple_files = true;
+option java_package = &quot;io.grpc.examples.helloworld&quot;;
+option java_outer_classname = &quot;HelloWorldProto&quot;;
+option objc_class_prefix = &quot;HLW&quot;;
+
+package helloworld;
+
+// The greeting service definition.
+service Greeter {
+  // Sends a greeting
+  rpc SayHello (HelloRequest) returns (HelloReply) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+  string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply {
+  string message = 1;
+}
+
+</code></pre>
+<p>在此,我们定义了一个只有一个方法 sayHello 的 Greeter 服务,同时定义了方法的入参和出参,</p>
+<h4>2. PCompiler 生成 Stub</h4>
+<ol>
+<li>定义 Maven Protobuf Compiler 插件工具。这里我们扩展了 Protobuf 的 Compiler 工具,以用来生成 Dubbo 特有的 RPC stub,此当前以 Maven 插件的形式发布。</li>
+</ol>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">plugin</span>&gt;</span>
+  <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.xolstice.maven.plugins<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
+  <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>protobuf-maven-plugin<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
+  <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>0.5.1<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
+  <span class="hljs-tag">&lt;<span class="hljs-name">configuration</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">protocArtifact</span>&gt;</span>com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}	
+    <span class="hljs-tag">&lt;/<span class="hljs-name">protocArtifact</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">pluginId</span>&gt;</span>dubbo-grpc-java<span class="hljs-tag">&lt;/<span class="hljs-name">pluginId</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">pluginArtifact</span>&gt;</span>org.apache.dubbo:protoc-gen-dubbo-java:1.19.0-SNAPSHOT:exe:${os.detected.classifier}<span class="hljs-tag">&lt;/<span class="hljs-name">pluginArtifact</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">outputDirectory</span>&gt;</span>build/generated/source/proto/main/java<span class="hljs-tag">&lt;/<span class="hljs-name">outputDirectory</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">clearOutputDirectory</span>&gt;</span>false<span class="hljs-tag">&lt;/<span class="hljs-name">clearOutputDirectory</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">pluginParameter</span>&gt;</span>grpc<span class="hljs-tag">&lt;/<span class="hljs-name">pluginParameter</span>&gt;</span>
+  <span class="hljs-tag">&lt;/<span class="hljs-name">configuration</span>&gt;</span>
+  <span class="hljs-tag">&lt;<span class="hljs-name">executions</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">execution</span>&gt;</span>
+      <span class="hljs-tag">&lt;<span class="hljs-name">goals</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">goal</span>&gt;</span>compile<span class="hljs-tag">&lt;/<span class="hljs-name">goal</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">goal</span>&gt;</span>compile-custom<span class="hljs-tag">&lt;/<span class="hljs-name">goal</span>&gt;</span>
+      <span class="hljs-tag">&lt;/<span class="hljs-name">goals</span>&gt;</span>
+    <span class="hljs-tag">&lt;/<span class="hljs-name">execution</span>&gt;</span>
+  <span class="hljs-tag">&lt;/<span class="hljs-name">executions</span>&gt;</span>
+<span class="hljs-tag">&lt;/<span class="hljs-name">plugin</span>&gt;</span>
+</code></pre>
+<p>其中,</p>
+<p>pluginArtifact 指定了 Dubbo 定制版本的 Java Protobuf Compiler 插件,通过这个插件来在编译过程中生成 Dubbo 定制版本的 gRPC stub。</p>
+<pre><code class="language-xml"> <span class="hljs-tag">&lt;<span class="hljs-name">pluginArtifact</span>&gt;</span>org.apache.dubbo:protoc-gen-dubbo-java:1.19.0-SNAPSHOT:exe:${os.detected.classifier}<span class="hljs-tag">&lt;/<span class="hljs-name">pluginArtifact</span>&gt;</span>
+</code></pre>
+<p>由于 <code>protoc-gen-dubbo-java</code> 支持 gRPC 和 Dubbo 两种协议,可生成的 stub 类型,默认值是 gRPC,关于 dubbo 协议的使用可参见 <a href="">使用 Protobuf 开发 Dubbo 服务</a>。</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">pluginParameter</span>&gt;</span>grpc<span class="hljs-tag">&lt;/<span class="hljs-name">pluginParameter</span>&gt;</span>
+</code></pre>
+<ol start="2">
+<li>
+<p>生成 Java Bean 和 Dubbo-gRPC stub</p>
+<pre><code class="language-sh"><span class="hljs-comment"># 运行以下 maven 命令</span>
+$ mvn clean compile
+</code></pre>
+<p>生成的 Stub 和消息类 如下:
+<img src="../../img/blog/grpc/compiler-classes.png" alt="image-20191026130516896"></p>
+<p>重点关注 GreeterGrpc ,包含了所有 gRPC 标准的 stub 类/方法,同时增加了 Dubbo 特定的接口,之后 Provider 端的服务暴露和 Consumer 端的服务调用都将依赖这个接口。</p>
+<pre><code class="language-java"><span class="hljs-comment">/**
+ * Code generated for Dubbo
+ */</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">IGreeter</span> </span>{
+
+<span class="hljs-keyword">default</span> <span class="hljs-keyword">public</span> io.grpc.examples.helloworld.<span class="hljs-function">HelloReply 	<span class="hljs-title">sayHello</span><span class="hljs-params">(io.grpc.examples.helloworld.HelloRequest request)</span> </span>{
+   <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> UnsupportedOperationException(<span class="hljs-string">"No need to override this method, extend XxxImplBase and override all methods it allows."</span>);
+}
+
+<span class="hljs-keyword">default</span> <span class="hljs-keyword">public</span> com.google.common.util.concurrent.ListenableFuture&lt;io.grpc.examples.helloworld.HelloReply&gt; sayHelloAsync(
+    io.grpc.examples.helloworld.HelloRequest request) {
+   <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> UnsupportedOperationException(<span class="hljs-string">"No need to override this method, extend XxxImplBase and override all methods it allows."</span>);
+}
+
+<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sayHello</span><span class="hljs-params">(io.grpc.examples.helloworld.HelloRequest request,
+    io.grpc.stub.StreamObserver&lt;io.grpc.examples.helloworld.HelloReply&gt; responseObserver)</span></span>;
+
+}
+</code></pre>
+</li>
+</ol>
+<h4>3. 业务逻辑开发</h4>
+<p>继承 <code>GreeterGrpc.GreeterImplBase</code> (来自第 2 步),编写业务逻辑,这点和原生 gRPC 是一致的。</p>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> org.apache.dubbo.samples.basic.impl;
+
+<span class="hljs-keyword">import</span> io.grpc.examples.helloworld.GreeterGrpc;
+<span class="hljs-keyword">import</span> io.grpc.examples.helloworld.HelloReply;
+<span class="hljs-keyword">import</span> io.grpc.examples.helloworld.HelloRequest;
+<span class="hljs-keyword">import</span> io.grpc.stub.StreamObserver;
+
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GrpcGreeterImpl</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">GreeterGrpc</span>.<span class="hljs-title">GreeterImplBase</span> </span>{
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sayHello</span><span class="hljs-params">(HelloRequest request, StreamObserver&lt;HelloReply&gt; responseObserver)</span> 		</span>{
+        System.out.println(<span class="hljs-string">"Received request from client."</span>);
+        System.out.println(<span class="hljs-string">"Executing thread is "</span> + Thread.currentThread().getName());
+        HelloReply reply = HelloReply.newBuilder()
+          .setMessage(<span class="hljs-string">"Hello "</span> + 	request.getName()).build();
+        responseObserver.onNext(reply);
+        responseObserver.onCompleted();
+    }
+}
+</code></pre>
+<h4>4. Provider 端暴露 Dubbo 服务</h4>
+<p>以 Spring XML 为例</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"demo-provider"</span>/&gt;</span>
+
+<span class="hljs-comment">&lt;!-- 指定服务暴露协议为 gRPC --&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"grpc"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"grpc"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://${zookeeper.address:127.0.0.1}:2181"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"greeter"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.apache.dubbo.samples.basic.impl.GrpcGreeterImpl"</span>/&gt;</span>
+
+<span class="hljs-comment">&lt;!-- 指定 protoc-gen-dubbo-java 生成的接口 --&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"io.grpc.examples.helloworld.GreeterGrpc$IGreeter"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"greeter"</span> <span class="hljs-attr">protocol</span>=<span class="hljs-string">"grpc"</span>/&gt;</span>
+</code></pre>
+<pre><code class="language-java"><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">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception </span>{
+  ClassPathXmlApplicationContext context =
+    <span class="hljs-keyword">new</span> ClassPathXmlApplicationContext(<span class="hljs-string">"spring/dubbo-demo-provider.xml"</span>);
+  context.start();
+
+  System.out.println(<span class="hljs-string">"dubbo service started"</span>);
+  <span class="hljs-keyword">new</span> CountDownLatch(<span class="hljs-number">1</span>).await();
+}
+</code></pre>
+<h4>5. 引用 Dubbo 服务</h4>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"demo-consumer"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://${zookeeper.address:127.0.0.1}:2181"</span>/&gt;</span>
+
+<span class="hljs-comment">&lt;!-- 指定 protoc-gen-dubbo-java 生成的接口 --&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"greeter"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"io.grpc.examples.helloworld.GreeterGrpc$IGreeter"</span> <span class="hljs-attr">protocol</span>=<span class="hljs-string">"grpc"</span>/&gt;</span>
+</code></pre>
+<pre><code class="language-java"><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">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> IOException </span>{
+  ClassPathXmlApplicationContext context =
+    <span class="hljs-keyword">new</span> ClassPathXmlApplicationContext(<span class="hljs-string">"spring/dubbo-demo-consumer.xml"</span>);
+  context.start();
+
+  GreeterGrpc.IGreeter greeter = (GreeterGrpc.IGreeter) context.getBean(<span class="hljs-string">"greeter"</span>);
+
+  HelloReply reply = greeter.sayHello(HelloRequest.newBuilder().setName(<span class="hljs-string">"world!"</span>).build());
+  System.out.println(<span class="hljs-string">"Result: "</span> + reply.getMessage());
+
+  System.in.read();
+}
+</code></pre>
+<h4>示例1附:高级用法</h4>
+<p><strong>一、异步调用</strong></p>
+<p>再来看一遍 <code>protoc-gen-dubbo-java</code> 生成的接口:</p>
+<pre><code class="language-java"><span class="hljs-comment">/**
+ * Code generated for Dubbo
+ */</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">IGreeter</span> </span>{
+  <span class="hljs-function"><span class="hljs-keyword">default</span> <span class="hljs-keyword">public</span> HelloReply <span class="hljs-title">sayHello</span><span class="hljs-params">(HelloRequest request)</span> </span>{
+     <span class="hljs-comment">// ......</span>
+  }
+  <span class="hljs-function"><span class="hljs-keyword">default</span> <span class="hljs-keyword">public</span> ListenableFuture&lt;HelloReply&gt; <span class="hljs-title">sayHelloAsync</span><span class="hljs-params">(HelloRequest request)</span> </span>{
+     <span class="hljs-comment">// ......</span>
+  }
+  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sayHello</span><span class="hljs-params">(HelloRequest request, StreamObserver&lt;HelloReply&gt; responseObserver)</span></span>;
+}
+</code></pre>
+<p>这里为 sayHello 方法生成了三种类型的重载方法,分别用于同步调用、异步调用和流式调用,如果消费端要进行异步调用,直接调用 sayHelloAsync() 即可:</p>
+<pre><code class="language-java"><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">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> IOException </span>{
+	<span class="hljs-comment">// ...</span>
+  GreeterGrpc.IGreeter greeter = (GreeterGrpc.IGreeter) context.getBean(<span class="hljs-string">"greeter"</span>);
+  ListenableFuture&lt;HelloReply&gt; future =   
+        greeter.sayHAsyncello(HelloRequest.newBuilder().setName(<span class="hljs-string">"world!"</span>).build());
+  <span class="hljs-comment">// ...</span>
+}
+</code></pre>
+<p><strong>二、高级配置</strong></p>
+<p>由于当前实现方式是直接集成了 gRPC-java SDK,因此很多配置还没有和 Dubbo 侧对齐,或者还没有以 Dubbo 的配置形式开放,因此,为了提供最大的灵活性,我们直接把 gRPC-java 的配置接口暴露了出来。</p>
+<p>绝大多数场景下,你可能并不会用到以下扩展,因为它们更多的是对 gRPC 协议的拦截或者 HTTP/2 层面的配置。同时使用这些扩展点可能需要对 HTTP/2 或 gRPC 有基本的了解。</p>
+<p><strong>扩展点</strong></p>
+<p>目前支持的扩展点如下:</p>
+<ul>
+<li>
+<p>org.apache.dubbo.rpc.protocol.grpc.interceptors.ClientInterceptor</p>
+</li>
+<li>
+<p>org.apache.dubbo.rpc.protocol.grpc.interceptors.GrpcConfigurator</p>
+</li>
+<li>
+<p>org.apache.dubbo.rpc.protocol.grpc.interceptors.ServerInterceptor</p>
+</li>
+<li>
+<p>org.apache.dubbo.rpc.protocol.grpc.interceptors.ServerTransportFilter</p>
+</li>
+</ul>
+<p>GrpcConfigurator 是最通用的扩展点,我们以此为例来说明一下,其基本定义如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">GrpcConfigurator</span> </span>{
+    <span class="hljs-comment">// 用来定制 gRPC NettyServerBuilder</span>
+    <span class="hljs-function"><span class="hljs-keyword">default</span> NettyServerBuilder <span class="hljs-title">configureServerBuilder</span><span class="hljs-params">(NettyServerBuilder builder, URL url)</span> </span>{
+        <span class="hljs-keyword">return</span> builder;
+    }
+    <span class="hljs-comment">// 用来定制 gRPC NettyChannelBuilder</span>
+    <span class="hljs-function"><span class="hljs-keyword">default</span> NettyChannelBuilder <span class="hljs-title">configureChannelBuilder</span><span class="hljs-params">(NettyChannelBuilder builder, URL url)</span> </span>{
+        <span class="hljs-keyword">return</span> builder;
+    }
+    <span class="hljs-comment">// 用来定制 gRPC CallOptions, 定义某个服务在每次请求间传递数据</span>
+    <span class="hljs-function"><span class="hljs-keyword">default</span> CallOptions <span class="hljs-title">configureCallOptions</span><span class="hljs-params">(CallOptions options, URL url)</span> </span>{
+        <span class="hljs-keyword">return</span> options;
+    }
+}
+</code></pre>
+<p>以下是一个示例扩展实现:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyGrpcConfigurator</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">GrpcConfigurator</span> </span>{
+    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> ExecutorService executor = Executors
+            .newFixedThreadPool(<span class="hljs-number">200</span>, <span class="hljs-keyword">new</span> NamedThreadFactory(<span class="hljs-string">"Customized-grpc"</span>, <span class="hljs-keyword">true</span>));
+
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> NettyServerBuilder <span class="hljs-title">configureServerBuilder</span><span class="hljs-params">(NettyServerBuilder builder, URL url)</span> </span>{
+        <span class="hljs-keyword">return</span> builder.executor(executor);
+    }
+
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> NettyChannelBuilder <span class="hljs-title">configureChannelBuilder</span><span class="hljs-params">(NettyChannelBuilder builder, URL url)</span>
+    </span>{
+        <span class="hljs-keyword">return</span> builder.flowControlWindow(<span class="hljs-number">10</span>);
+    }
+
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> CallOptions <span class="hljs-title">configureCallOptions</span><span class="hljs-params">(CallOptions options, URL url)</span> </span>{
+        <span class="hljs-keyword">return</span> options.withOption(CallOptions.Key.create(<span class="hljs-string">"key"</span>), <span class="hljs-string">"value"</span>);
+    }
+}
+
+</code></pre>
+<p>配置为 Dubbo SPI,`resources/META-INF/services 增加配置文件</p>
+<pre><code class="language-properties"><span class="hljs-attr">default</span>=<span class="hljs-string">org.apache.dubbo.samples.basic.comtomize.MyGrpcConfigurator</span>
+</code></pre>
+<ol>
+<li>
+<p>指定 Provider 端线程池</p>
+<p>默认用的是 Dubbo 的线程池,有 fixed (默认)、cached、direct 等类型。以下演示了切换为业务自定义线程池。</p>
+<pre><code class="language-java"><span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> ExecutorService executor = Executors
+      .newFixedThreadPool(<span class="hljs-number">200</span>, <span class="hljs-keyword">new</span> NamedThreadFactory(<span class="hljs-string">"Customized-grpc"</span>, <span class="hljs-keyword">true</span>));
+
+<span class="hljs-function"><span class="hljs-keyword">public</span> NettyServerBuilder <span class="hljs-title">configureServerBuilder</span><span class="hljs-params">(NettyServerBuilder builder, URL url)</span> 
+</span>{
+  <span class="hljs-keyword">return</span> builder.executor(executor);
+}
+
+</code></pre>
+</li>
+<li>
+<p>指定 Consumer 端限流值</p>
+<p>设置 Consumer 限流值为 10</p>
+<pre><code class="language-java"><span class="hljs-meta">@Override</span>
+<span class="hljs-function"><span class="hljs-keyword">public</span> NettyChannelBuilder <span class="hljs-title">configureChannelBuilder</span><span class="hljs-params">(NettyChannelBuilder builder, URL url)</span>
+</span>{
+  <span class="hljs-keyword">return</span> builder.flowControlWindow(<span class="hljs-number">10</span>);
+}
+
+</code></pre>
+</li>
+<li>
+<p>传递附加参数</p>
+<p>DemoService 服务调用传递 key</p>
+<pre><code class="language-java"><span class="hljs-meta">@Override</span>
+<span class="hljs-function"><span class="hljs-keyword">public</span> CallOptions <span class="hljs-title">configureCallOptions</span><span class="hljs-params">(CallOptions options, URL url)</span> </span>{
+  <span class="hljs-keyword">if</span> (url.getServiceInterface().equals(<span class="hljs-string">"xxx.DemoService"</span>)) {
+    <span class="hljs-keyword">return</span> options.withOption(CallOptions.Key.create(<span class="hljs-string">"key"</span>), <span class="hljs-string">"value"</span>);
+  } <span class="hljs-keyword">else</span> {
+    <span class="hljs-keyword">return</span> options;
+  }
+}
+
+</code></pre>
+</li>
+</ol>
+<p><strong>三、TLS 配置</strong></p>
+<p>配置方式和 Dubbo 提供的通用的 <a href="">TLS 支持</a>一致,具体请参见文档</p>
+<h3>示例 2, 使用 Protobuf 开发 Dubbo 服务</h3>
+<p>下面,我们以一个<a href="https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-protobuf">具体的示例</a>来看一下基于 Protobuf 的 Dubbo 服务开发流程。</p>
+<h4>1. 定义服务</h4>
+<p>通过标准 Protobuf 定义服务</p>
+<pre><code class="language-idl">syntax = &quot;proto3&quot;;
+
+option java_multiple_files = true;
+option java_package = &quot;org.apache.dubbo.demo&quot;;
+option java_outer_classname = &quot;DemoServiceProto&quot;;
+option objc_class_prefix = &quot;DEMOSRV&quot;;
+
+package demoservice;
+
+// The demo service definition.
+service DemoService {
+  rpc SayHello (HelloRequest) returns (HelloReply) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+  string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply {
+  string message = 1;
+}
+
+</code></pre>
+<p>这里定义了一个 DemoService 服务,服务只包含一个 sayHello 方法,同时定义了方法的入参和出参。</p>
+<h4>2. Compiler 编译服务</h4>
+<ol>
+<li>引入 Protobuf Compiler Maven 插件,同时指定 <code>protoc-gen-dubbo-java</code> RPC 扩展</li>
+</ol>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">plugin</span>&gt;</span>
+  <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.xolstice.maven.plugins<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
+  <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>protobuf-maven-plugin<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
+  <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>0.5.1<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
+  <span class="hljs-tag">&lt;<span class="hljs-name">configuration</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">protocArtifact</span>&gt;</span>com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}	
+    <span class="hljs-tag">&lt;/<span class="hljs-name">protocArtifact</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">pluginId</span>&gt;</span>dubbo-grpc-java<span class="hljs-tag">&lt;/<span class="hljs-name">pluginId</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">pluginArtifact</span>&gt;</span>org.apache.dubbo:protoc-gen-dubbo-java:1.19.0-SNAPSHOT:exe:${os.detected.classifier}<span class="hljs-tag">&lt;/<span class="hljs-name">pluginArtifact</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">outputDirectory</span>&gt;</span>build/generated/source/proto/main/java<span class="hljs-tag">&lt;/<span class="hljs-name">outputDirectory</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">clearOutputDirectory</span>&gt;</span>false<span class="hljs-tag">&lt;/<span class="hljs-name">clearOutputDirectory</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">pluginParameter</span>&gt;</span>dubbo<span class="hljs-tag">&lt;/<span class="hljs-name">pluginParameter</span>&gt;</span>
+  <span class="hljs-tag">&lt;/<span class="hljs-name">configuration</span>&gt;</span>
+  <span class="hljs-tag">&lt;<span class="hljs-name">executions</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">execution</span>&gt;</span>
+      <span class="hljs-tag">&lt;<span class="hljs-name">goals</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">goal</span>&gt;</span>compile<span class="hljs-tag">&lt;/<span class="hljs-name">goal</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">goal</span>&gt;</span>compile-custom<span class="hljs-tag">&lt;/<span class="hljs-name">goal</span>&gt;</span>
+      <span class="hljs-tag">&lt;/<span class="hljs-name">goals</span>&gt;</span>
+    <span class="hljs-tag">&lt;/<span class="hljs-name">execution</span>&gt;</span>
+  <span class="hljs-tag">&lt;/<span class="hljs-name">executions</span>&gt;</span>
+<span class="hljs-tag">&lt;/<span class="hljs-name">plugin</span>&gt;</span>
+</code></pre>
+<p>注意,这里与 <a href="https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-grpc">Dubbo 对 gRPC</a> 支持部分的区别在于:
+<code>&lt;pluginParameter&gt;dubbo&lt;/pluginParameter&gt;</code></p>
+<ol start="2">
+<li>
+<p>生成 Dubbo stub</p>
+<pre><code class="language-shell"><span class="hljs-meta">#</span><span class="bash"> 运行以下 maven 命令</span>
+<span class="hljs-meta">$</span><span class="bash">mvn clean compile</span>
+</code></pre>
+<p>生成的 Java 类如下:</p>
+<p><img src="../../img/blog/grpc/compiler-protobuf.png" alt="image-20191028201240976"></p>
+<p>DemoServiceDubbo 为 Dubbo 定制的 stub</p>
+<pre><code class="language-java"><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">DemoServiceDubbo</span> </span>{
+
+  <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> AtomicBoolean registered = <span class="hljs-keyword">new</span> AtomicBoolean();
+
+  <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> Class&lt;?&gt; init() {
+      Class&lt;?&gt; clazz = <span class="hljs-keyword">null</span>;
+      <span class="hljs-keyword">try</span> {
+          clazz = Class.forName(DemoServiceDubbo<span class="hljs-class">.<span class="hljs-keyword">class</span>.<span class="hljs-title">getName</span>())</span>;
+          <span class="hljs-keyword">if</span> (registered.compareAndSet(<span class="hljs-keyword">false</span>, <span class="hljs-keyword">true</span>)) {
+              org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils.marshaller(
+                  org.apache.dubbo.demo.HelloRequest.getDefaultInstance());
+              org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils.marshaller(
+                  org.apache.dubbo.demo.HelloReply.getDefaultInstance());
+          }
+       } <span class="hljs-keyword">catch</span> (ClassNotFoundException e) {
+          <span class="hljs-comment">// ignore </span>
+       }
+       <span class="hljs-keyword">return</span> clazz;
+  }
+
+  <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-title">DemoServiceDubbo</span><span class="hljs-params">()</span> </span>{}
+
+  <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String SERVICE_NAME = <span class="hljs-string">"demoservice.DemoService"</span>;
+
+  <span class="hljs-comment">/**
+   * Code generated for Dubbo
+   */</span>
+  <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">IDemoService</span> </span>{
+
+     <span class="hljs-keyword">static</span> Class&lt;?&gt; clazz = init();
+     org.apache.dubbo.demo.<span class="hljs-function">HelloReply <span class="hljs-title">sayHello</span><span class="hljs-params">(org.apache.dubbo.demo.HelloRequest request)</span></span>;
+
+     java.util.concurrent.CompletableFuture&lt;org.apache.dubbo.demo.HelloReply&gt; sayHelloAsync(
+  org.apache.dubbo.demo.HelloRequest request);
+
+ }
+
+}
+</code></pre>
+<p>最值得注意的是 <code>IDemoService</code> 接口,它会作为 Dubbo 服务定义基础接口。</p>
+</li>
+</ol>
+<h4>3. 开发业务逻辑</h4>
+<p>从这一步开始,所有开发流程就和直接定义 Java 接口一样了。实现接口定义业务逻辑。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DemoServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">DemoServiceDubbo</span>.<span class="hljs-title">IDemoService</span> </span>{
+    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> Logger logger = LoggerFactory.getLogger(DemoServiceImpl<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> HelloReply <span class="hljs-title">sayHello</span><span class="hljs-params">(HelloRequest request)</span> </span>{
+        logger.info(<span class="hljs-string">"Hello "</span> + request.getName() + <span class="hljs-string">", request from consumer: "</span> + RpcContext.getContext().getRemoteAddress());
+        <span class="hljs-keyword">return</span> HelloReply.newBuilder()
+                .setMessage(<span class="hljs-string">"Hello "</span> + request.getName() + <span class="hljs-string">", response from provider: "</span>
+                        + RpcContext.getContext().getLocalAddress())
+                .build();
+    }
+
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> CompletableFuture&lt;HelloReply&gt; <span class="hljs-title">sayHelloAsync</span><span class="hljs-params">(HelloRequest request)</span> </span>{
+        <span class="hljs-keyword">return</span> CompletableFuture.completedFuture(sayHello(request));
+    }
+}
+</code></pre>
+<h4>4. 配置 Provider</h4>
+<p>暴露 Dubbo 服务</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"demo-provider"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"dubbo"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.apache.dubbo.demo.provider.DemoServiceImpl"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoServiceDubbo$IDemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span>/&gt;</span>
+
+</code></pre>
+<pre><code class="language-java"><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">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception </span>{
+  ClassPathXmlApplicationContext context = 
+    <span class="hljs-keyword">new</span> ClassPathXmlApplicationContext(<span class="hljs-string">"spring/dubbo-provider.xml"</span>);
+  context.start();
+  System.in.read();
+}
+</code></pre>
+<h4>5. 配置 Consumer</h4>
+<p>引用 Dubbo 服务</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"demo-consumer"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">check</span>=<span class="hljs-string">"false"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoServiceDubbo$IDemoService"</span>/&gt;</span>
+</code></pre>
+<pre><code class="language-java"><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">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception </span>{
+  ClassPathXmlApplicationContext context = 
+    <span class="hljs-keyword">new</span> ClassPathXmlApplicationContext(<span class="hljs-string">"spring/dubbo-consumer.xml"</span>);
+  context.start();
+  IDemoService demoService = context.getBean(<span class="hljs-string">"demoService"</span>, IDemoService<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+  HelloRequest request = HelloRequest.newBuilder().setName(<span class="hljs-string">"Hello"</span>).build();
+  HelloReply reply = demoService.sayHello(request);
+  System.out.println(<span class="hljs-string">"result: "</span> + reply.getMessage());
+  System.in.read();
+}
+</code></pre>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/Dubbo-supporting-gRPC-HTTP2-and-protobuf.json b/doc-archive/v2.7.3/zh-cn/blog/Dubbo-supporting-gRPC-HTTP2-and-protobuf.json
new file mode 100644
index 0000000..9fe4ff2
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/Dubbo-supporting-gRPC-HTTP2-and-protobuf.json
@@ -0,0 +1,6 @@
+{
+  "filename": "Dubbo-supporting-gRPC-HTTP2-and-protobuf.md",
+  "__html": "<h1>Dubbo 在跨语言和协议穿透性方向上的探索:支持 HTTP/2 gRPC 和 Protobuf</h1>\n<p>本文整理自刘军在 Dubbo 成都 meetup 上分享的《Dubbo 在多语言和协议穿透性方向上的探索》。</p>\n<p>本文总体上可分为基础产品简介、Dubbo 对 gRPC (HTTP/2) 和 Protobuf 的支持及示例演示三部分,在简介部分介绍了 Dubbo、HTTP/2、gRPC、Protobuf 的基本概念和特点;第二部分介绍了 Dubbo 为何要支持 gRPC (HTTP/2) 和 Protobuf,以及这种支持为 gRPC 和 Dubbo 开发带来的好处与不同;第三部分通过两个实例分别演示了 Dubbo gRPC 和 Dubbo Protobuf 的使用方式。</p>\n<h2>基本介绍</h2>\n<h3>Dubbo 协议</h3>\n<p>从协议层面展开,以下是当前 2.7 版本支持的 Dubbo 协议</p>\n<p><img src=\"img/blog/grpc/dubbo-ptotoco [...]
+  "link": "/zh-cn/blog/Dubbo-supporting-gRPC-HTTP2-and-protobuf.html",
+  "meta": {}
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/Guides for upgrading to 2.7.x.html b/doc-archive/v2.7.3/zh-cn/blog/Guides for upgrading to 2.7.x.html
new file mode 100644
index 0000000..dbbb7df
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/Guides for upgrading to 2.7.x.html	
@@ -0,0 +1,342 @@
+<!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="Guides for upgrading to 2.7.x" />
+	<meta name="description" content="Guides for upgrading to 2.7.x" />
+	<!-- 网页标签标题 -->
+	<title>Guides for upgrading to 2.7.x</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>环境要求:需要<strong>Java 8</strong>及以上版本。</p>
+<p>2.7.0版本在改造的过程中遵循了一个原则,即<strong>保持与低版本的兼容性,因此从功能层面来说它是与2.6.x及更低版本完全兼容的</strong>。这里所说的兼容性主要是和<a href="#%E5%8C%85%E5%90%8D%E6%94%B9%E9%80%A0">包重命名</a>相关的,接下来会详细说明影响点。另外,虽然功能用法保持向后兼容,但参考本文能帮助您尽快用到2.7.0版本的新特性。</p>
+<h2>升级步骤</h2>
+<ol>
+<li>升级pom到2.7.0(以all-in-one依赖为例)。</li>
+</ol>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">properties</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">dubbo.version</span>&gt;</span>2.7.0<span class="hljs-tag">&lt;/<span class="hljs-name">dubbo.version</span>&gt;</span>
+<span class="hljs-tag">&lt;/<span class="hljs-name">properties</span>&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dependencyManagement</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
+            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.dubbo<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
+            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>dubbo-dependencies-bom<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
+            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${dubbo.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
+            <span class="hljs-tag">&lt;<span class="hljs-name">type</span>&gt;</span>pom<span class="hljs-tag">&lt;/<span class="hljs-name">type</span>&gt;</span>
+            <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>import<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span>
+        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
+    <span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span>
+<span class="hljs-tag">&lt;/<span class="hljs-name">dependencyManagement</span>&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.dubbo<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>dubbo<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${dubbo.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
+    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>io.netty<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>netty-all<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
+    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
+<span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span>
+</code></pre>
+<p>如果升级依赖后出现API或SPI扩展相关的编译错误,请参考<a href="#%E5%8C%85%E5%90%8D%E6%94%B9%E9%80%A0">包兼容性问题</a></p>
+<p>此时重新部署应用,所有默认行为和2.6.x保持一致,如果要用到2.7的新特性,则需要继续做以下配置(可选):</p>
+<ul>
+<li>简化的URL</li>
+<li>配置元数据中心</li>
+<li>使用外部化配置</li>
+<li>服务治理规则</li>
+<li>使用异步API</li>
+</ul>
+<p>下面我们就对这几部分的配置分别做详细说明。</p>
+<h4>简化的URL</h4>
+<pre><code class="language-xml"><span class="hljs-comment">&lt;!-- simplified="true"表示注册简化版的URL到Registry --&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span> <span class="hljs-attr">simplified</span>=<span class="hljs-string">"true"</span>/&gt;</span>
+</code></pre>
+<pre><code class="language-properties"><span class="hljs-meta">dubbo.registry.simplified</span>=<span class="hljs-string">true</span>
+</code></pre>
+<p>建议将此配置集中管理,参考<a href="#%E4%BD%BF%E7%94%A8%E5%A4%96%E9%83%A8%E5%8C%96%E9%85%8D%E7%BD%AE">外部化配置</a>。</p>
+<blockquote>
+<p>URL简化只是剔除了一些纯粹的查询用的参数,并没有做大刀阔斧的服务发现模型改造,因此精简后的URL完全可以被2.6及以下版本的消费端实现服务发现与调用,同样2.7版本也可以发现和调用低版本的提供者。</p>
+</blockquote>
+<h4>配置元数据中心</h4>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:metadata-report</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"redis://127.0.0.1:6379"</span>/&gt;</span>
+</code></pre>
+<pre><code class="language-properties"><span class="hljs-meta">dubbo.metadataReport.address</span>=<span class="hljs-string">redis://127.0.0.1:6379</span>
+</code></pre>
+<p>建议将此配置集中管理,参考<a href="#%E4%BD%BF%E7%94%A8%E5%A4%96%E9%83%A8%E5%8C%96%E9%85%8D%E7%BD%AE">外部化配置</a>。
+<a href="">元数据中心</a>设计及用途,请参考文档。</p>
+<h4>使用外部化配置</h4>
+<p>需要在项目启动前,使用<a href="https://github.com/apache/dubbo-ops">最新版本Dubbo-OPS</a>完成外部化配置迁移,理论上配置中心支持所有本地dubbo.properties所支持的配置项。</p>
+<p>以XML开发形式为例,假设我们本地有如下配置:</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"demo-provider"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:conig-center</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span> <span class="hljs-attr">simplified</span>=<span class="hljs-string">"true"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:metadata-report</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"redis://127.0.0.1:6379"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"dubbo"</span> <span class="hljs-attr">port</span>=<span class="hljs-string">"20880"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.apache.dubbo.samples.basic.impl.DemoServiceImpl"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.samples.basic.api.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span>/&gt;</span>
+</code></pre>
+<p>通过<a href="http://47.91.207.147/#/management?key=global">OPS控制台</a>将以下全局配置迁移到配置中心,成为所有应用共享的配置。</p>
+<pre><code class="language-properties"><span class="hljs-meta">dubbo.registry.address</span>=<span class="hljs-string">zookeeper://127.0.0.1:2181</span>
+<span class="hljs-meta">dubbo.registry.simplified</span>=<span class="hljs-string">true</span>
+
+<span class="hljs-meta">dubbo.metadataReport.address</span>=<span class="hljs-string">redis://127.0.0.1:6379</span>
+
+<span class="hljs-meta">dubbo.protocol.name</span>=<span class="hljs-string">dubbo</span>
+<span class="hljs-meta">dubbo.protocol.port</span>=<span class="hljs-string">20880</span>
+</code></pre>
+<p>这样应用开发者只需要关心配置中心的配置。</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"demo-provider"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:conig-center</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.apache.dubbo.samples.basic.impl.DemoServiceImpl"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.samples.basic.api.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span>/&gt;</span>
+</code></pre>
+<p>这里增加了一篇<a href="">Dubbo配置方式</a>的说明文档,详细描述了Dubbo当前支持的配置类型、不同配置之间的覆盖关系等。</p>
+<h4>服务治理规则迁移</h4>
+<p>2.7版本可以读取到老的治理规则,因此不用担心升级2.7的应用后老规则会失效,可以选择先升级上线,再慢慢的做增量式规则迁移。</p>
+<p>请参考<a href="http://47.91.207.147/#/governance/routingRule">OPS -&gt; 服务治理</a>了解规则配置方式,这里我们重点关注的是规则格式,以下提供几个简单示例:</p>
+<ul>
+<li>
+<p>条件路由</p>
+<pre><code class="language-yaml"><span class="hljs-meta">---</span>
+<span class="hljs-attr">scope:</span> <span class="hljs-string">application</span>
+<span class="hljs-attr">force:</span> <span class="hljs-literal">true</span>
+<span class="hljs-attr">runtime:</span> <span class="hljs-literal">true</span>
+<span class="hljs-attr">enabled:</span> <span class="hljs-literal">true</span>
+<span class="hljs-attr">key:</span> <span class="hljs-string">governance-conditionrouter-consumer</span>
+<span class="hljs-attr">conditions:</span>
+<span class="hljs-bullet">-</span> <span class="hljs-string">method=sayHello</span> <span class="hljs-string">=&gt;</span> <span class="hljs-string">address=*:20880</span>
+<span class="hljs-bullet">-</span> <span class="hljs-string">method=sayHi</span> <span class="hljs-string">=&gt;</span> <span class="hljs-string">address=*:20881</span>
+<span class="hljs-string">...</span>
+</code></pre>
+</li>
+<li>
+<p>标签路由</p>
+<pre><code class="language-yaml"><span class="hljs-meta">---</span>
+<span class="hljs-attr">force:</span> <span class="hljs-literal">false</span>
+<span class="hljs-attr">runtime:</span> <span class="hljs-literal">true</span>
+<span class="hljs-attr">enabled:</span> <span class="hljs-literal">true</span>
+<span class="hljs-attr">key:</span> <span class="hljs-string">governance-tagrouter-provider</span>
+<span class="hljs-attr">tags:</span>
+<span class="hljs-attr">- name:</span> <span class="hljs-string">tag1</span>
+<span class="hljs-attr">addresses:</span> <span class="hljs-string">["127.0.0.1:20880"]</span>
+<span class="hljs-attr">- name:</span> <span class="hljs-string">tag2</span>
+<span class="hljs-attr">addresses:</span> <span class="hljs-string">["127.0.0.1:20881"]</span>
+<span class="hljs-string">...</span>
+</code></pre>
+</li>
+<li>
+<p>动态配置(覆盖规则)</p>
+<pre><code class="language-yaml"><span class="hljs-meta">---</span>
+<span class="hljs-attr">scope:</span> <span class="hljs-string">service</span>
+<span class="hljs-attr">key:</span> <span class="hljs-string">org.apache.dubbo.samples.governance.api.DemoService</span>
+<span class="hljs-attr">enabled:</span> <span class="hljs-literal">true</span>
+<span class="hljs-attr">configs:</span>
+<span class="hljs-attr">- addresses:</span> <span class="hljs-string">[0.0.0.0]</span>
+<span class="hljs-attr">  side:</span> <span class="hljs-string">consumer</span>
+<span class="hljs-attr">  parameters:</span>
+<span class="hljs-attr">    timeout:</span> <span class="hljs-number">6000</span>
+<span class="hljs-string">...</span>
+</code></pre>
+</li>
+</ul>
+<p>关于治理规则更多详细说明,请参考<a href="">路由规则</a>和<a href="">覆盖规则</a>用户文档。</p>
+<p>也可继续了解<a href="">使用示例</a>。</p>
+<h4>使用异步API</h4>
+<p>这部分的接口和低版本同样是完全兼容的,你仅须在打算使用CompletableFuture<T>提供的回调或者异步组装能力时,再考虑升级这部分内容即可。</p>
+<ul>
+<li>
+<p>定义CompletableFuture<T>类型接口</p>
+</li>
+<li>
+<p>同步签名接口实现Provider端异步执行</p>
+</li>
+<li>
+<p>感知异步返回值的Filter链路</p>
+</li>
+</ul>
+<p>点击链接,了解关于异步API如何使用的更多<a href="">使用示例</a>。</p>
+<h2>包名改造</h2>
+<ol>
+<li>Maven坐标</li>
+</ol>
+<p><strong>groupId 由 <code>com.alibaba</code> 改为 <code>org.apache.dubbo</code></strong></p>
+<ol start="2">
+<li>package</li>
+</ol>
+<p><strong>package 由 <code>com.alibaba.dubbo</code> 改为 <code>org.apache.dubbo</code></strong></p>
+<p>Maven坐标升级比较直观,只需要修改相应的pom文件就可以了;而package变更则可能会带来编译问题,升级过程需要用户修改代码。因此为了减少用户升级成本,让用户可以做到渐进式升级,2.7.0版本继续保留了一些常用基础API和SP<code>com.alibaba.dubb</code>的支持。</p>
+<h4>API编程接口</h4>
+<ul>
+<li>注解</li>
+</ul>
+<table>
+<thead>
+<tr>
+<th>注解</th>
+<th>说明</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>@Reference</td>
+<td>消费端服务引用注解</td>
+</tr>
+<tr>
+<td>@Service</td>
+<td>提供端服务暴露注解</td>
+</tr>
+<tr>
+<td>@EnableDubbo</td>
+<td></td>
+</tr>
+<tr>
+<td>其他常用Spring注解API</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<ul>
+<li>编程API</li>
+</ul>
+<table>
+<thead>
+<tr>
+<th>API</th>
+<th>说明</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>ReferenceConfig</td>
+<td>Service配置采集和引用编程接口</td>
+</tr>
+<tr>
+<td>ServiceConfig</td>
+<td>Service配置采集和暴露编程接口</td>
+</tr>
+<tr>
+<td>ApplicationConfig</td>
+<td>Application配置采集API</td>
+</tr>
+<tr>
+<td>RegistryConfig</td>
+<td>注册中心配置采集API</td>
+</tr>
+<tr>
+<td>ConsumerConfig</td>
+<td>提供端默认配置采集API</td>
+</tr>
+<tr>
+<td>ProviderConfig</td>
+<td>消费端默认配置采集API</td>
+</tr>
+<tr>
+<td>ProtocolConfig</td>
+<td>RPC协议配置采集API</td>
+</tr>
+<tr>
+<td>ArcumentConfig</td>
+<td>服务参数级配置采集API</td>
+</tr>
+<tr>
+<td>MethodConfig</td>
+<td>服务方法级配置采集API</td>
+</tr>
+<tr>
+<td>ModuleConfig</td>
+<td>服务治理Module配置采集API</td>
+</tr>
+<tr>
+<td>MonitorConfig</td>
+<td>监控配置采集API</td>
+</tr>
+<tr>
+<td>RpcContext</td>
+<td>编程上下文API</td>
+</tr>
+</tbody>
+</table>
+<h4>SPI扩展</h4>
+<blockquote>
+<p>如果公司内部有维护的自定义SPI扩展库,在业务工程升级到2.7.0之前,请务必先确保扩展库与2.7.0的兼容性。如果发现有兼容性问题,请通过修改包名引用的方式完成升级,并重新打包。</p>
+</blockquote>
+<table>
+<thead>
+<tr>
+<th>SPI扩展点</th>
+<th>说明</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>Registry</td>
+<td>包括<code>RegistryFactory</code>, <code>Registry</code> ,<code>RegistryService</code>等扩展点</td>
+</tr>
+<tr>
+<td>Protocol</td>
+<td>RPC协议扩展</td>
+</tr>
+<tr>
+<td>Serialization</td>
+<td>序列化协议扩展</td>
+</tr>
+<tr>
+<td>Cluster</td>
+<td>集群容错策略扩展,如Failover, Failfast等</td>
+</tr>
+<tr>
+<td>Loadbalance</td>
+<td>负载均衡策略扩展</td>
+</tr>
+<tr>
+<td>Transporter</td>
+<td>传输框架扩展,如Netty等</td>
+</tr>
+<tr>
+<td>Monitor</td>
+<td>监控中心扩展,包括MonitorFactory, Monitor, MonitorService等</td>
+</tr>
+<tr>
+<td>Router</td>
+<td>路由规则扩展</td>
+</tr>
+<tr>
+<td>Filter</td>
+<td>拦截器扩展</td>
+</tr>
+</tbody>
+</table>
+<h2>FAQ</h2>
+<ol>
+<li>升级后启动出现curator依赖报错</li>
+</ol>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making proce [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
diff --git a/doc-archive/v2.7.3/zh-cn/blog/Guides for upgrading to 2.7.x.json b/doc-archive/v2.7.3/zh-cn/blog/Guides for upgrading to 2.7.x.json
new file mode 100644
index 0000000..cda745c
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/Guides for upgrading to 2.7.x.json	
@@ -0,0 +1,6 @@
+{
+  "filename": "Guides for upgrading to 2.7.x.md",
+  "__html": "<h1>升级与可能的兼容性问题总结</h1>\n<p>环境要求:需要<strong>Java 8</strong>及以上版本。</p>\n<p>2.7.0版本在改造的过程中遵循了一个原则,即<strong>保持与低版本的兼容性,因此从功能层面来说它是与2.6.x及更低版本完全兼容的</strong>。这里所说的兼容性主要是和<a href=\"#%E5%8C%85%E5%90%8D%E6%94%B9%E9%80%A0\">包重命名</a>相关的,接下来会详细说明影响点。另外,虽然功能用法保持向后兼容,但参考本文能帮助您尽快用到2.7.0版本的新特性。</p>\n<h2>升级步骤</h2>\n<ol>\n<li>升级pom到2.7.0(以all-in-one依赖为例)。</li>\n</ol>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">properties</span>&gt;</span>\n    <spa [...]
+  "link": "/zh-cn/blog/Guides for upgrading to 2.7.x.html",
+  "meta": {}
+}
diff --git a/doc-archive/v2.7.3/zh-cn/blog/Guides-for-upgrading-to-27x.html b/doc-archive/v2.7.3/zh-cn/blog/Guides-for-upgrading-to-27x.html
new file mode 100644
index 0000000..30c684f
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/Guides-for-upgrading-to-27x.html
@@ -0,0 +1,342 @@
+<!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="Guides-for-upgrading-to-27x" />
+	<meta name="description" content="Guides-for-upgrading-to-27x" />
+	<!-- 网页标签标题 -->
+	<title>Guides-for-upgrading-to-27x</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>环境要求:需要<strong>Java 8</strong>及以上版本。</p>
+<p>2.7.0版本在改造的过程中遵循了一个原则,即<strong>保持与低版本的兼容性,因此从功能层面来说它是与2.6.x及更低版本完全兼容的</strong>。这里所说的兼容性主要是和<a href="#%E5%8C%85%E5%90%8D%E6%94%B9%E9%80%A0">包重命名</a>相关的,接下来会详细说明影响点。另外,虽然功能用法保持向后兼容,但参考本文能帮助您尽快用到2.7.0版本的新特性。</p>
+<h2>升级步骤</h2>
+<ol>
+<li>升级pom到2.7.0(以all-in-one依赖为例)。</li>
+</ol>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">properties</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">dubbo.version</span>&gt;</span>2.7.0<span class="hljs-tag">&lt;/<span class="hljs-name">dubbo.version</span>&gt;</span>
+<span class="hljs-tag">&lt;/<span class="hljs-name">properties</span>&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dependencyManagement</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
+            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.dubbo<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
+            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>dubbo-dependencies-bom<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
+            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${dubbo.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
+            <span class="hljs-tag">&lt;<span class="hljs-name">type</span>&gt;</span>pom<span class="hljs-tag">&lt;/<span class="hljs-name">type</span>&gt;</span>
+            <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>import<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span>
+        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
+    <span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span>
+<span class="hljs-tag">&lt;/<span class="hljs-name">dependencyManagement</span>&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.dubbo<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>dubbo<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${dubbo.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
+    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>io.netty<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>netty-all<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
+    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
+<span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span>
+</code></pre>
+<p>如果升级依赖后出现API或SPI扩展相关的编译错误,请参考<a href="#%E5%8C%85%E5%90%8D%E6%94%B9%E9%80%A0">包兼容性问题</a></p>
+<p>此时重新部署应用,所有默认行为和2.6.x保持一致,如果要用到2.7的新特性,则需要继续做以下配置(可选):</p>
+<ul>
+<li>简化的URL</li>
+<li>配置元数据中心</li>
+<li>使用外部化配置</li>
+<li>服务治理规则</li>
+<li>使用异步API</li>
+</ul>
+<p>下面我们就对这几部分的配置分别做详细说明。</p>
+<h4>简化的URL</h4>
+<pre><code class="language-xml"><span class="hljs-comment">&lt;!-- simplified="true"表示注册简化版的URL到Registry --&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span> <span class="hljs-attr">simplified</span>=<span class="hljs-string">"true"</span>/&gt;</span>
+</code></pre>
+<pre><code class="language-properties"><span class="hljs-meta">dubbo.registry.simplified</span>=<span class="hljs-string">true</span>
+</code></pre>
+<p>建议将此配置集中管理,参考<a href="#%E4%BD%BF%E7%94%A8%E5%A4%96%E9%83%A8%E5%8C%96%E9%85%8D%E7%BD%AE">外部化配置</a>。</p>
+<blockquote>
+<p>URL简化只是剔除了一些纯粹的查询用的参数,并没有做大刀阔斧的服务发现模型改造,因此精简后的URL完全可以被2.6及以下版本的消费端实现服务发现与调用,同样2.7版本也可以发现和调用低版本的提供者。</p>
+</blockquote>
+<h4>配置元数据中心</h4>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:metadata-report</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"redis://127.0.0.1:6379"</span>/&gt;</span>
+</code></pre>
+<pre><code class="language-properties"><span class="hljs-meta">dubbo.metadataReport.address</span>=<span class="hljs-string">redis://127.0.0.1:6379</span>
+</code></pre>
+<p>建议将此配置集中管理,参考<a href="#%E4%BD%BF%E7%94%A8%E5%A4%96%E9%83%A8%E5%8C%96%E9%85%8D%E7%BD%AE">外部化配置</a>。
+<a href="">元数据中心</a>设计及用途,请参考文档。</p>
+<h4>使用外部化配置</h4>
+<p>需要在项目启动前,使用<a href="https://github.com/apache/dubbo-ops">最新版本Dubbo-OPS</a>完成外部化配置迁移,理论上配置中心支持所有本地dubbo.properties所支持的配置项。</p>
+<p>以XML开发形式为例,假设我们本地有如下配置:</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"demo-provider"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:conig-center</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span> <span class="hljs-attr">simplified</span>=<span class="hljs-string">"true"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:metadata-report</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"redis://127.0.0.1:6379"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"dubbo"</span> <span class="hljs-attr">port</span>=<span class="hljs-string">"20880"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.apache.dubbo.samples.basic.impl.DemoServiceImpl"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.samples.basic.api.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span>/&gt;</span>
+</code></pre>
+<p>通过<a href="http://47.91.207.147/#/management?key=global">OPS控制台</a>将以下全局配置迁移到配置中心,成为所有应用共享的配置。</p>
+<pre><code class="language-properties"><span class="hljs-meta">dubbo.registry.address</span>=<span class="hljs-string">zookeeper://127.0.0.1:2181</span>
+<span class="hljs-meta">dubbo.registry.simplified</span>=<span class="hljs-string">true</span>
+
+<span class="hljs-meta">dubbo.metadataReport.address</span>=<span class="hljs-string">redis://127.0.0.1:6379</span>
+
+<span class="hljs-meta">dubbo.protocol.name</span>=<span class="hljs-string">dubbo</span>
+<span class="hljs-meta">dubbo.protocol.port</span>=<span class="hljs-string">20880</span>
+</code></pre>
+<p>这样应用开发者只需要关心配置中心的配置。</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"demo-provider"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:conig-center</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.apache.dubbo.samples.basic.impl.DemoServiceImpl"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.samples.basic.api.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span>/&gt;</span>
+</code></pre>
+<p>这里增加了一篇<a href="">Dubbo配置方式</a>的说明文档,详细描述了Dubbo当前支持的配置类型、不同配置之间的覆盖关系等。</p>
+<h4>服务治理规则迁移</h4>
+<p>2.7版本可以读取到老的治理规则,因此不用担心升级2.7的应用后老规则会失效,可以选择先升级上线,再慢慢的做增量式规则迁移。</p>
+<p>请参考<a href="http://47.91.207.147/#/governance/routingRule">OPS -&gt; 服务治理</a>了解规则配置方式,这里我们重点关注的是规则格式,以下提供几个简单示例:</p>
+<ul>
+<li>
+<p>条件路由</p>
+<pre><code class="language-yaml"><span class="hljs-meta">---</span>
+<span class="hljs-attr">scope:</span> <span class="hljs-string">application</span>
+<span class="hljs-attr">force:</span> <span class="hljs-literal">true</span>
+<span class="hljs-attr">runtime:</span> <span class="hljs-literal">true</span>
+<span class="hljs-attr">enabled:</span> <span class="hljs-literal">true</span>
+<span class="hljs-attr">key:</span> <span class="hljs-string">governance-conditionrouter-consumer</span>
+<span class="hljs-attr">conditions:</span>
+<span class="hljs-bullet">  -</span> <span class="hljs-string">application=app1</span> <span class="hljs-string">=&gt;</span> <span class="hljs-string">address=*:20880</span>
+<span class="hljs-bullet">  -</span> <span class="hljs-string">application=app2</span> <span class="hljs-string">=&gt;</span> <span class="hljs-string">address=*:20881</span>
+<span class="hljs-string">...</span>
+</code></pre>
+</li>
+<li>
+<p>标签路由</p>
+<pre><code class="language-yaml"><span class="hljs-meta">---</span>
+<span class="hljs-attr">force:</span> <span class="hljs-literal">false</span>
+<span class="hljs-attr">runtime:</span> <span class="hljs-literal">true</span>
+<span class="hljs-attr">enabled:</span> <span class="hljs-literal">true</span>
+<span class="hljs-attr">key:</span> <span class="hljs-string">governance-tagrouter-provider</span>
+<span class="hljs-attr">tags:</span>
+<span class="hljs-attr">  - name:</span> <span class="hljs-string">tag1</span>
+<span class="hljs-attr">    addresses:</span> <span class="hljs-string">["127.0.0.1:20880"]</span>
+<span class="hljs-attr">  - name:</span> <span class="hljs-string">tag2</span>
+<span class="hljs-attr">    addresses:</span> <span class="hljs-string">["127.0.0.1:20881"]</span>
+<span class="hljs-string">...</span>
+</code></pre>
+</li>
+<li>
+<p>动态配置(覆盖规则)</p>
+<pre><code class="language-yaml"><span class="hljs-meta">---</span>
+<span class="hljs-attr">scope:</span> <span class="hljs-string">service</span>
+<span class="hljs-attr">key:</span> <span class="hljs-string">org.apache.dubbo.samples.governance.api.DemoService</span>
+<span class="hljs-attr">enabled:</span> <span class="hljs-literal">true</span>
+<span class="hljs-attr">configs:</span>
+<span class="hljs-attr">- addresses:</span> <span class="hljs-string">[0.0.0.0]</span>
+<span class="hljs-attr">  side:</span> <span class="hljs-string">consumer</span>
+<span class="hljs-attr">  parameters:</span>
+<span class="hljs-attr">    timeout:</span> <span class="hljs-number">6000</span>
+<span class="hljs-string">...</span>
+</code></pre>
+</li>
+</ul>
+<p>关于治理规则更多详细说明,请参考<a href="/docs/zh-cn/user/demos/routing-rule.md">路由规则</a>和<a href="/docs/zh-cn/user/demos/config-rule.md">覆盖规则</a>用户文档。</p>
+<p>也可继续了解<a href="https://github.com/apache/dubbo-samples/tree/samples-for-2.7.0-SNAPSHOT/dubbo-samples-governance">使用示例</a>。</p>
+<h4>使用异步API</h4>
+<p>这部分的接口和低版本同样是完全兼容的,你仅须在打算使用CompletableFuture<T>提供的回调或者异步组装能力时,再考虑升级这部分内容即可。</p>
+<ul>
+<li>
+<p>定义CompletableFuture<T>类型接口</p>
+</li>
+<li>
+<p>同步签名接口实现Provider端异步执行</p>
+</li>
+<li>
+<p>感知异步返回值的Filter链路</p>
+</li>
+</ul>
+<p>点击链接,了解关于异步API如何使用的更多<a href="">使用示例</a>。</p>
+<h2>包名改造</h2>
+<ol>
+<li>Maven坐标</li>
+</ol>
+<p><strong>groupId 由 <code>com.alibaba</code> 改为 <code>org.apache.dubbo</code></strong></p>
+<ol start="2">
+<li>package</li>
+</ol>
+<p><strong>package 由 <code>com.alibaba.dubbo</code> 改为 <code>org.apache.dubbo</code></strong></p>
+<p>Maven坐标升级比较直观,只需要修改相应的pom文件就可以了;而package变更则可能会带来编译问题,升级过程需要用户修改代码。因此为了减少用户升级成本,让用户可以做到渐进式升级,2.7.0版本继续保留了一些常用基础API和SP<code>com.alibaba.dubb</code>的支持。</p>
+<h4>API编程接口</h4>
+<ul>
+<li>注解</li>
+</ul>
+<table>
+<thead>
+<tr>
+<th>注解</th>
+<th>说明</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>@Reference</td>
+<td>消费端服务引用注解</td>
+</tr>
+<tr>
+<td>@Service</td>
+<td>提供端服务暴露注解</td>
+</tr>
+<tr>
+<td>@EnableDubbo</td>
+<td></td>
+</tr>
+<tr>
+<td>其他常用Spring注解API</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<ul>
+<li>编程API</li>
+</ul>
+<table>
+<thead>
+<tr>
+<th>API</th>
+<th>说明</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>ReferenceConfig</td>
+<td>Service配置采集和引用编程接口</td>
+</tr>
+<tr>
+<td>ServiceConfig</td>
+<td>Service配置采集和暴露编程接口</td>
+</tr>
+<tr>
+<td>ApplicationConfig</td>
+<td>Application配置采集API</td>
+</tr>
+<tr>
+<td>RegistryConfig</td>
+<td>注册中心配置采集API</td>
+</tr>
+<tr>
+<td>ConsumerConfig</td>
+<td>提供端默认配置采集API</td>
+</tr>
+<tr>
+<td>ProviderConfig</td>
+<td>消费端默认配置采集API</td>
+</tr>
+<tr>
+<td>ProtocolConfig</td>
+<td>RPC协议配置采集API</td>
+</tr>
+<tr>
+<td>ArcumentConfig</td>
+<td>服务参数级配置采集API</td>
+</tr>
+<tr>
+<td>MethodConfig</td>
+<td>服务方法级配置采集API</td>
+</tr>
+<tr>
+<td>ModuleConfig</td>
+<td>服务治理Module配置采集API</td>
+</tr>
+<tr>
+<td>MonitorConfig</td>
+<td>监控配置采集API</td>
+</tr>
+<tr>
+<td>RpcContext</td>
+<td>编程上下文API</td>
+</tr>
+</tbody>
+</table>
+<h4>SPI扩展</h4>
+<blockquote>
+<p>如果公司内部有维护的自定义SPI扩展库,在业务工程升级到2.7.0之前,请务必先确保扩展库与2.7.0的兼容性。如果发现有兼容性问题,请通过修改包名引用的方式完成升级,并重新打包。</p>
+</blockquote>
+<table>
+<thead>
+<tr>
+<th>SPI扩展点</th>
+<th>说明</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>Registry</td>
+<td>包括<code>RegistryFactory</code>, <code>Registry</code> ,<code>RegistryService</code>等扩展点</td>
+</tr>
+<tr>
+<td>Protocol</td>
+<td>RPC协议扩展</td>
+</tr>
+<tr>
+<td>Serialization</td>
+<td>序列化协议扩展</td>
+</tr>
+<tr>
+<td>Cluster</td>
+<td>集群容错策略扩展,如Failover, Failfast等</td>
+</tr>
+<tr>
+<td>Loadbalance</td>
+<td>负载均衡策略扩展</td>
+</tr>
+<tr>
+<td>Transporter</td>
+<td>传输框架扩展,如Netty等</td>
+</tr>
+<tr>
+<td>Monitor</td>
+<td>监控中心扩展,包括MonitorFactory, Monitor, MonitorService等</td>
+</tr>
+<tr>
+<td>Router</td>
+<td>路由规则扩展</td>
+</tr>
+<tr>
+<td>Filter</td>
+<td>拦截器扩展</td>
+</tr>
+</tbody>
+</table>
+<h2>FAQ</h2>
+<ol>
+<li>升级后启动出现curator依赖报错</li>
+</ol>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making proce [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
diff --git a/doc-archive/v2.7.3/zh-cn/blog/Guides-for-upgrading-to-27x.json b/doc-archive/v2.7.3/zh-cn/blog/Guides-for-upgrading-to-27x.json
new file mode 100644
index 0000000..2ecc73b
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/Guides-for-upgrading-to-27x.json
@@ -0,0 +1,6 @@
+{
+  "filename": "Guides-for-upgrading-to-27x.md",
+  "__html": "<h1>升级与可能的兼容性问题总结</h1>\n<p>环境要求:需要<strong>Java 8</strong>及以上版本。</p>\n<p>2.7.0版本在改造的过程中遵循了一个原则,即<strong>保持与低版本的兼容性,因此从功能层面来说它是与2.6.x及更低版本完全兼容的</strong>。这里所说的兼容性主要是和<a href=\"#%E5%8C%85%E5%90%8D%E6%94%B9%E9%80%A0\">包重命名</a>相关的,接下来会详细说明影响点。另外,虽然功能用法保持向后兼容,但参考本文能帮助您尽快用到2.7.0版本的新特性。</p>\n<h2>升级步骤</h2>\n<ol>\n<li>升级pom到2.7.0(以all-in-one依赖为例)。</li>\n</ol>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">properties</span>&gt;</span>\n    <spa [...]
+  "link": "/zh-cn/blog/Guides-for-upgrading-to-27x.html",
+  "meta": {}
+}
diff --git a/doc-archive/v2.7.3/zh-cn/blog/apachecon-na-2018.html b/doc-archive/v2.7.3/zh-cn/blog/apachecon-na-2018.html
new file mode 100644
index 0000000..d3d6508
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/apachecon-na-2018.html
@@ -0,0 +1,34 @@
+<!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="Dubbo, ApacheCon NA" />
+	<meta name="description" content="本文将向你介绍在ApacheCon大会议程公布上相关Dubbo议题演讲。" />
+	<!-- 网页标签标题 -->
+	<title>ApacheCon大会议程公布</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>罗毅/刘军将在蒙特利尔举办的 ApacheCon 大会上进行题为&quot;Introducing Apache Dubbo(Incubating): What is Dubbo and How it Works&quot;的演讲。请点击<a href="https://apachecon.dukecon.org/acna/2018/#/scheduledEvent/b8db9dc580d85853f">此处</a>查看大会议程,并在<a href="https://www.eventbrite.com/e/apachecon-north-america-2018-registration-43200327342">此处</a>中进行注册。</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/apachecon-na-2018.json b/doc-archive/v2.7.3/zh-cn/blog/apachecon-na-2018.json
new file mode 100644
index 0000000..142aa76
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/apachecon-na-2018.json
@@ -0,0 +1,10 @@
+{
+  "filename": "apachecon-na-2018.md",
+  "__html": "<h2>ApacheCon大会议程公布</h2>\n<p>罗毅/刘军将在蒙特利尔举办的 ApacheCon 大会上进行题为&quot;Introducing Apache Dubbo(Incubating): What is Dubbo and How it Works&quot;的演讲。请点击<a href=\"https://apachecon.dukecon.org/acna/2018/#/scheduledEvent/b8db9dc580d85853f\">此处</a>查看大会议程,并在<a href=\"https://www.eventbrite.com/e/apachecon-north-america-2018-registration-43200327342\">此处</a>中进行注册。</p>\n",
+  "link": "/zh-cn/blog/apachecon-na-2018.html",
+  "meta": {
+    "title": "ApacheCon大会议程公布",
+    "keywords": "Dubbo, ApacheCon NA",
+    "description": "本文将向你介绍在ApacheCon大会议程公布上相关Dubbo议题演讲。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/build-new-docker-image-in-dockerhub.html b/doc-archive/v2.7.3/zh-cn/blog/build-new-docker-image-in-dockerhub.html
new file mode 100644
index 0000000..c11b98b
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/build-new-docker-image-in-dockerhub.html
@@ -0,0 +1,73 @@
+<!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="Dubbo Admin,Docker,Dockerhub" />
+	<meta name="description" content="本文将介绍如何在Dockerhub上发布Dubbo Admin镜像。" />
+	<!-- 网页标签标题 -->
+	<title>在DockerHub发布Dubbo Admin镜像</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>Dubbo Admin是Dubbo的服务治理中心,提供了大量日常运维所需的服务治理、配置管理等功能。</p>
+<p>Dubbo Admin同时包含了前端代码和后端代码,如果用户需要自己下载源码并编译打包,需要花费一定时间。
+特别是对于一些希望快速调研和试用Dubbo Admin的用户,这种流程的体验并不是很好。</p>
+<p>Docker是一个开源的应用容器引擎,让开发者可以打包应用以及依赖包到一个可移植的镜像中,社区对于提供Dubbo Admin镜像的呼声较高。
+Docker官方维护了一个公共仓库DockerHub,该仓库还有很多国内镜像,访问速度快,将Dubbo Admin镜像发布到DockerHub是一个较好的选择。</p>
+<h2>DockerHub账号申请</h2>
+<p>要在DockerHub上发布镜像,自然需要对应的账号。
+而DockerHub有两种常见账号,一种是面向个人的,一种是面向组织的。Apache在DockerHub上有一个组织账号<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>。
+自然我们首选是发布在组织账号下。</p>
+<p>DockerHub对于组织账号的管理是基于组的,也就是一个组织账号下有多个组,每个组有不同的成员,而一个组可以管理一个或者多个镜像。</p>
+<p>所以要做的第一步就是申请权限,这个需要提一个issue给Apache Infrastructure团队,申请DockerHub的镜像仓库和组权限。
+目前镜像和组已经申请好了,只需要申请组的权限就行了,可以参考之前的申请<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>。</p>
+<p>申请完权限以后使用Apache账号登陆应该就可以看到对应的镜像和配置选项了。</p>
+<h2>添加新的构建规则</h2>
+<p>发布镜像到DockerHub有两种办法,一种是本地构建好镜像以后远程push到DockerHub,另外一种是提供Dockerfile并借助DockerHub提供的构建功能直接在DockerHub构建。
+后者明显操作性和便捷性要好很多,目前Dubbo Admin的镜像也是这样构建发布的。</p>
+<p>当Dubbo Admin有新版本发布以后,需要在项目的docker目录新增一个Dockerfile文件,可以参考目前0.1.0版本的Dockerfile<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup>,其中的配置根据具体的版本可能有细微差别,但是大致上是一致的。</p>
+<p>在添加了Dockerfile之后,进入DockerHub对应的管理界面新增Build Rules</p>
+<p><img src="../../img/blog/dockerhub-build-rules.png" alt="dockerhub-build-rules.png | center "></p>
+<p>根据实际情况填写即可。这里需要注意两点:</p>
+<ul>
+<li>latest 版本要和最新的版本配置一致</li>
+<li>不要勾选Autobuild</li>
+</ul>
+<p>勾选Autobuild会导致每次git提交都会触发自动构建,但是由于Dubbo Admin不提供snapshot的Docker镜像,所以只有发布新版本的时候才需要构建发布。</p>
+<p>修改以后点Save,然后手动触发构建即可。</p>
+<h2>总结</h2>
+<p>总的来说DockerHub上发布镜像的步骤并不复杂,如果已经申请过权限的话,操作起来是很流畅的。</p>
+<p>另外DockerHub的构建是需要排队的,有时候会遇到长时间没有开始构建的情况,需要耐心等待。</p>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p><a href="https://hub.docker.com/r/apache">https://hub.docker.com/r/apache</a> <a href="#fnref1" class="footnote-backref">↩︎</a></p>
+</li>
+<li id="fn2" class="footnote-item"><p><a href="https://issues.apache.org/jira/browse/INFRA-18167">https://issues.apache.org/jira/browse/INFRA-18167</a> <a href="#fnref2" class="footnote-backref">↩︎</a></p>
+</li>
+<li id="fn3" class="footnote-item"><p><a href="https://github.com/apache/dubbo-admin/blob/develop/docker/0.1.0/Dockerfile">https://github.com/apache/dubbo-admin/blob/develop/docker/0.1.0/Dockerfile</a> <a href="#fnref3" class="footnote-backref">↩︎</a></p>
+</li>
+</ol>
+</section>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/build-new-docker-image-in-dockerhub.json b/doc-archive/v2.7.3/zh-cn/blog/build-new-docker-image-in-dockerhub.json
new file mode 100644
index 0000000..9e3139d
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/build-new-docker-image-in-dockerhub.json
@@ -0,0 +1,10 @@
+{
+  "filename": "build-new-docker-image-in-dockerhub.md",
+  "__html": "<h1>在DockerHub发布Dubbo Admin镜像</h1>\n<p>Dubbo Admin是Dubbo的服务治理中心,提供了大量日常运维所需的服务治理、配置管理等功能。</p>\n<p>Dubbo Admin同时包含了前端代码和后端代码,如果用户需要自己下载源码并编译打包,需要花费一定时间。\n特别是对于一些希望快速调研和试用Dubbo Admin的用户,这种流程的体验并不是很好。</p>\n<p>Docker是一个开源的应用容器引擎,让开发者可以打包应用以及依赖包到一个可移植的镜像中,社区对于提供Dubbo Admin镜像的呼声较高。\nDocker官方维护了一个公共仓库DockerHub,该仓库还有很多国内镜像,访问速度快,将Dubbo Admin镜像发布到DockerHub是一个较好的选择。</p>\n<h2>DockerHub账号申请</h2>\n<p>要在DockerHub上发布镜像,自然需要对应的账号。\n而DockerHub有两种常见账号,一种是面向个人的,一种是面向组织的。Apache
 在DockerHub上有一个组织账 [...]
+  "link": "/zh-cn/blog/build-new-docker-image-in-dockerhub.html",
+  "meta": {
+    "title": "在DockerHub发布Dubbo Admin镜像",
+    "keywords": "Dubbo Admin,Docker,Dockerhub",
+    "description": "本文将介绍如何在Dockerhub上发布Dubbo Admin镜像。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/download.html b/doc-archive/v2.7.3/zh-cn/blog/download.html
new file mode 100644
index 0000000..a073160
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/download.html
@@ -0,0 +1,189 @@
+<!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="Dubbo, Downloads, Version" />
+	<meta name="description" content="本文将向你介绍如何点击了解各版本详情和升级注意事项。" />
+	<!-- 网页标签标题 -->
+	<title>下载中心</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>验证</h2>
+<p>可以按照这里的<a href="https://www.apache.org/info/verification">步骤</a>, 利用<a href="https://www.apache.org/dist/incubator/dubbo/KEYS">KEYS</a>文件来验证下载。</p>
+<h2>Apache Dubbo</h2>
+<p>请点击了解各<a href="http://dubbo.apache.org/zh-cn/docs/user/versions/index.html">版本详情和升级注意事项</a></p>
+<blockquote>
+<p>GitHub: <a href="https://github.com/apache/incubator-dubbo">https://github.com/apache/incubator-dubbo</a> <br>
+发布说明:<a href="https://github.com/apache/incubator-dubbo/releases">https://github.com/apache/incubator-dubbo/releases</a></p>
+</blockquote>
+<h3>2.7.4.1 (2019-10-27)</h3>
+<ul>
+<li><a href="https://www.apache.org/dyn/closer.cgi?path=dubbo/2.7.4.1/apache-dubbo-2.7.4.1-src.zip">source</a> |
+<a href="https://www.apache.org/dist/dubbo/2.7.4.1/apache-dubbo-2.7.4.1-src.zip.asc">asc</a> |
+<a href="https://www.apache.org/dist/dubbo/2.7.4.1/apache-dubbo-2.7.4.1-src.zip.sha512">sha512</a></li>
+</ul>
+<h3>2.7.4 (2019-10-19)</h3>
+<ul>
+<li><a href="https://www.apache.org/dyn/closer.cgi?path=dubbo/2.7.4/apache-dubbo-2.7.4-src.zip">source</a> |
+<a href="https://www.apache.org/dist/dubbo/2.7.4/apache-dubbo-2.7.4-src.zip.asc">asc</a> |
+<a href="https://www.apache.org/dist/dubbo/2.7.4/apache-dubbo-2.7.4-src.zip.sha512">sha512</a></li>
+</ul>
+<h3>2.7.3 (2019-07-19)</h3>
+<ul>
+<li><a href="https://www.apache.org/dyn/closer.cgi?path=dubbo/2.7.3/apache-dubbo-2.7.3-src.zip">source</a> |
+<a href="https://www.apache.org/dist/dubbo/2.7.3/apache-dubbo-2.7.3-src.zip.asc">asc</a> |
+<a href="https://www.apache.org/dist/dubbo/2.7.3/apache-dubbo-2.7.3-src.zip.sha512">sha512</a></li>
+</ul>
+<h3>2.7.2 (2019-06-06)</h3>
+<ul>
+<li><a href="https://archive.apache.org/dist/dubbo/2.7.2/apache-dubbo-2.7.2-src.zip">source</a> |
+<a href="https://archive.apache.org/dist/dubbo/2.7.2/apache-dubbo-2.7.2-src.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/dubbo/2.7.2/apache-dubbo-2.7.2-src.zip.sha512">sha512</a></li>
+</ul>
+<h3>2.7.1 (2019-03-26)</h3>
+<ul>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/2.7.1/apache-dubbo-incubating-2.7.1-src.zip">source</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.7.1/apache-dubbo-incubating-2.7.1-src.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.7.1/apache-dubbo-incubating-2.7.1-src.zip.sha512">sha512</a></li>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/2.7.1/apache-dubbo-incubating-2.7.1-bin.zip">binary</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.7.1/apache-dubbo-incubating-2.7.1-bin.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.7.1/apache-dubbo-incubating-2.7.1-bin.zip.sha512">sha512</a></li>
+</ul>
+<h3>2.7.0 (2019-01-29)</h3>
+<ul>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/2.7.0/apache-dubbo-incubating-2.7.0-source-release.zip">source</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.7.0/apache-dubbo-incubating-2.7.0-source-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.7.0/apache-dubbo-incubating-2.7.0-source-release.zip.sha512">sha512</a></li>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/2.7.0/apache-dubbo-incubating-2.7.0-bin-release.zip">binary</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.7.0/apache-dubbo-incubating-2.7.0-bin-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.7.0/apache-dubbo-incubating-2.7.0-bin-release.zip.sha512">sha512</a></li>
+</ul>
+<h3>2.6.7 (2019-07-15)</h3>
+<ul>
+<li><a href="https://www.apache.org/dist/dubbo/2.6.7/apache-dubbo-2.6.7-source-release.zip">source</a> |
+<a href="https://www.apache.org/dist/dubbo/2.6.7/apache-dubbo-2.6.7-source-release.zip.asc">asc</a> |
+<a href="https://www.apache.org/dist/dubbo/2.6.7/apache-dubbo-2.6.7-source-release.zip.sha512">sha512</a></li>
+<li><a href="https://www.apache.org/dist/dubbo/2.6.7/apache-dubbo-2.6.7-bin-release.zip">binary</a> |
+<a href="https://www.apache.org/dist/dubbo/2.6.7/apache-dubbo-2.6.7-bin-release.zip.asc">asc</a> |
+<a href="https://www.apache.org/dist/dubbo/2.6.7/apache-dubbo-2.6.7-bin-release.zip.sha512">sha512</a></li>
+</ul>
+<h3>2.6.6 (2019-03-07)</h3>
+<ul>
+<li><a href="https://www.apache.org/dyn/closer.cgi?path=incubator/dubbo/2.6.6/apache-dubbo-incubating-2.6.6-source-release.zip">source</a> |
+<a href="https://www.apache.org/dist/incubator/dubbo/2.6.6/apache-dubbo-incubating-2.6.6-source-release.zip.asc">asc</a> |
+<a href="https://www.apache.org/dist/incubator/dubbo/2.6.6/apache-dubbo-incubating-2.6.6-source-release.zip.sha512">sha512</a></li>
+<li><a href="https://www.apache.org/dyn/closer.cgi?path=incubator/dubbo/2.6.6/apache-dubbo-incubating-2.6.6-bin-release.zip">binary</a> |
+<a href="https://www.apache.org/dist/incubator/dubbo/2.6.6/apache-dubbo-incubating-2.6.6-bin-release.zip.asc">asc</a> |
+<a href="https://www.apache.org/dist/incubator/dubbo/2.6.6/apache-dubbo-incubating-2.6.6-bin-release.zip.sha512">sha512</a></li>
+</ul>
+<h3>2.6.5 (2018-11-23)</h3>
+<ul>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/2.6.5/apache-dubbo-incubating-2.6.5-source-release.zip">source</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.5/apache-dubbo-incubating-2.6.5-source-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.5/apache-dubbo-incubating-2.6.5-source-release.zip.sha512">sha512</a></li>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/2.6.5/apache-dubbo-incubating-2.6.5-bin-release.zip">binary</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.5/apache-dubbo-incubating-2.6.5-bin-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.5/apache-dubbo-incubating-2.6.5-bin-release.zip.sha512">sha512</a></li>
+</ul>
+<h3>2.6.4 (2018-10-08)</h3>
+<ul>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/2.6.4/apache-dubbo-incubating-2.6.4-source-release.zip">source</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.4/apache-dubbo-incubating-2.6.4-source-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.4/apache-dubbo-incubating-2.6.4-source-release.zip.sha512">sha512</a></li>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/2.6.4/apache-dubbo-incubating-2.6.4-bin-release.zip">binary</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.4/apache-dubbo-incubating-2.6.4-bin-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.4/apache-dubbo-incubating-2.6.4-bin-release.zip.sha512">sha512</a></li>
+</ul>
+<h3>2.6.3 (2018-09-11)</h3>
+<ul>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/2.6.3/apache-dubbo-incubating-2.6.3-source-release.zip">source</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.3/apache-dubbo-incubating-2.6.3-source-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.3/apache-dubbo-incubating-2.6.3-source-release.zip.sha512">sha512</a></li>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/2.6.3/apache-dubbo-incubating-2.6.3-bin-release.zip">binary</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.3/apache-dubbo-incubating-2.6.3-bin-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.3/apache-dubbo-incubating-2.6.3-bin-release.zip.sha512">sha512</a></li>
+</ul>
+<h3>2.6.2 (2018-06-07)</h3>
+<ul>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/2.6.2/dubbo-incubating-2.6.2-source-release.zip">source</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.2/dubbo-incubating-2.6.2-source-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.2/dubbo-incubating-2.6.2-source-release.zip.sha512">sha512</a></li>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/2.6.2/dubbo-incubating-2.6.2-bin-release.zip">binary</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.2/dubbo-incubating-2.6.2-bin-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/2.6.2/dubbo-incubating-2.6.2-bin-release.zip.sha512">sha512</a></li>
+</ul>
+<h2>Dubbo Spring Boot Starter</h2>
+<blockquote>
+<p>GitHub: <a href="https://github.com/apache/incubator-dubbo-spring-boot-project">https://github.com/apache/incubator-dubbo-spring-boot-project</a> <br>
+发布说明:<a href="https://github.com/apache/incubator-dubbo-spring-boot-project/releases">https://github.com/apache/incubator-dubbo-spring-boot-project/releases</a></p>
+</blockquote>
+<h3>2.7.1 (2019-04-09)</h3>
+<ul>
+<li><a href="https://www.apache.org/dyn/closer.cgi?path=incubator/dubbo/spring-boot-project/2.7.1/apache-dubbo-spring-boot-project-incubating-2.7.1-source-release.zip">source</a> |
+<a href="https://www.apache.org/dist/incubator/dubbo/spring-boot-project/2.7.1/apache-dubbo-spring-boot-project-incubating-2.7.1-source-release.zip.asc">asc</a> |
+<a href="https://www.apache.org/dist/incubator/dubbo/spring-boot-project/2.7.1/apache-dubbo-spring-boot-project-incubating-2.7.1-source-release.zip.sha512">sha512</a></li>
+<li><a href="https://www.apache.org/dyn/closer.cgi?path=incubator/dubbo/spring-boot-project/2.7.1/apache-dubbo-spring-boot-project-incubating-2.7.1-bin-release.zip">binary</a> |
+<a href="https://www.apache.org/dist/incubator/dubbo/spring-boot-project/2.7.1/apache-dubbo-spring-boot-project-incubating-2.7.1-bin-release.zip.asc">asc</a> |
+<a href="https://www.apache.org/dist/incubator/dubbo/spring-boot-project/2.7.1/apache-dubbo-spring-boot-project-incubating-2.7.1-bin-release.zip.sha512">sha512</a></li>
+</ul>
+<h3>2.7.0 (2019-02-14)</h3>
+<ul>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/2.7.0/apache-dubbo-spring-boot-project-incubating-2.7.0-source-release.zip">source</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/2.7.0/apache-dubbo-spring-boot-project-incubating-2.7.0-source-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/2.7.0/apache-dubbo-spring-boot-project-incubating-2.7.0-source-release.zip.sha512">sha512</a></li>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/2.7.0/apache-dubbo-spring-boot-project-incubating-2.7.0-bin-release.zip">binary</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/2.7.0/apache-dubbo-spring-boot-project-incubating-2.7.0-bin-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/2.7.0/apache-dubbo-spring-boot-project-incubating-2.7.0-bin-release.zip.sha512">sha512</a></li>
+</ul>
+<h3>0.2.1 (2019-01-27)</h3>
+<ul>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/0.2.1/apache-dubbo-spring-boot-project-incubating-0.2.1-source-release.zip">source</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/0.2.1/apache-dubbo-spring-boot-project-incubating-0.2.1-source-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/0.2.1/apache-dubbo-spring-boot-project-incubating-0.2.1-source-release.zip.sha512">sha512</a></li>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/0.2.1/apache-dubbo-spring-boot-project-incubating-0.2.1-bin-release.zip">binary</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/0.2.1/apache-dubbo-spring-boot-project-incubating-0.2.1-bin-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/0.2.1/apache-dubbo-spring-boot-project-incubating-0.2.1-bin-release.zip.sha512">sha512</a></li>
+</ul>
+<h3>0.1.2 (2019-01-27)</h3>
+<ul>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/0.1.2/apache-dubbo-spring-boot-project-incubating-0.1.2-source-release.zip">source</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/0.1.2/apache-dubbo-spring-boot-project-incubating-0.1.2-source-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/0.1.2/apache-dubbo-spring-boot-project-incubating-0.1.2-source-release.zip.sha512">sha512</a></li>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/0.1.2/apache-dubbo-spring-boot-project-incubating-0.1.2-bin-release.zip">binary</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/0.1.2/apache-dubbo-spring-boot-project-incubating-0.1.2-bin-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/spring-boot-project/0.1.2/apache-dubbo-spring-boot-project-incubating-0.1.2-bin-release.zip.sha512">sha512</a></li>
+</ul>
+<h2>Dubbo Admin</h2>
+<blockquote>
+<p>GitHub: <a href="https://github.com/apache/incubator-dubbo-admin">https://github.com/apache/incubator-dubbo-admin</a> <br>
+发布说明:<a href="https://github.com/apache/incubator-dubbo-admin/releases">https://github.com/apache/incubator-dubbo-admin/releases</a></p>
+</blockquote>
+<h3>0.1 (2019-02-15)</h3>
+<ul>
+<li><a href="https://archive.apache.org/dist/incubator/dubbo/dubbo-ops/0.1/apache-dubbo-ops-incubating-0.1-source-release.zip">source</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/dubbo-ops/0.1/apache-dubbo-ops-incubating-0.1-source-release.zip.asc">asc</a> |
+<a href="https://archive.apache.org/dist/incubator/dubbo/dubbo-ops/0.1/apache-dubbo-ops-incubating-0.1-source-release.zip.sha512">sha512</a></li>
+</ul>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/download.json b/doc-archive/v2.7.3/zh-cn/blog/download.json
new file mode 100644
index 0000000..e23dae7
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/download.json
@@ -0,0 +1,10 @@
+{
+  "filename": "download.md",
+  "__html": "<h1>下载中心</h1>\n<h2>验证</h2>\n<p>可以按照这里的<a href=\"https://www.apache.org/info/verification\">步骤</a>, 利用<a href=\"https://www.apache.org/dist/incubator/dubbo/KEYS\">KEYS</a>文件来验证下载。</p>\n<h2>Apache Dubbo</h2>\n<p>请点击了解各<a href=\"http://dubbo.apache.org/zh-cn/docs/user/versions/index.html\">版本详情和升级注意事项</a></p>\n<blockquote>\n<p>GitHub: <a href=\"https://github.com/apache/incubator-dubbo\">https://github.com/apache/incubator-dubbo</a> <br>\n发布说明:<a href=\"https://github.com/apach [...]
+  "link": "/zh-cn/blog/download.html",
+  "meta": {
+    "title": "下载中心",
+    "keywords": "Dubbo, Downloads, Version",
+    "description": "本文将向你介绍如何点击了解各版本详情和升级注意事项。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-101.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-101.html
new file mode 100644
index 0000000..fb6ac09
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-101.html
@@ -0,0 +1,350 @@
+<!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="Dubbo, RPC, RMI" />
+	<meta name="description" content="现代的分布式服务框架的基本概念与 RMI 是类似的,同样是使用 Java 的 Interface 作为服务契约,通过注册中心来完成服务的注册和发现,远程通讯的细节也是通过代理类来屏蔽。" />
+	<!-- 网页标签标题 -->
+	<title>第一个 Dubbo 应用</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>Java RMI 简介</h2>
+<p>Java RMI (Remote Method Invocation)- 远程方法调用,能够让客户端像使用本地调用一样调用服务端 Java 虚拟机中的对象方法。RMI 是面向对象语言领域对 RPC (Remote Procedure Call)的完善,用户无需依靠 IDL 的帮助来完成分布式调用,而是通过依赖接口这种更简单自然的方式。</p>
+<h3>Java RMI 工作原理</h3>
+<p>一个典型的 RMI 调用如下图所示:</p>
+<ol>
+<li>服务端向 RMI 注册服务绑定自己的地址,</li>
+<li>客户端通过 RMI 注册服务获取目标地址,</li>
+<li>客户端调用本地的 Stub 对象上的方法,和调用本地对象上的方法一致,</li>
+<li>本地存根对象将调用信息打包,通过网络发送到服务端,</li>
+<li>服务端的 Skeleton 对象收到网络请求之后,将调用信息解包,</li>
+<li>然后找到真正的服务对象发起调用,并将返回结果打包通过网络发送回客户端。</li>
+</ol>
+<p><img src="../../img/blog/rmi-flow.png" alt="RMI Flow"></p>
+<p>(来源:<a href="https://www.cs.rutgers.edu/~pxk/417/notes/images/rpc-rmi_flow.png">https://www.cs.rutgers.edu/~pxk/417/notes/images/rpc-rmi_flow.png</a>)</p>
+<h3>Java RMI 基本概念</h3>
+<p>Java RMI 是 Java 领域创建分布式应用的技术基石。后续的 EJB 技术,以及现代的分布式服务框架,其中的基本理念依旧是 Java RMI 的延续。在 RMI 调用中,有以下几个核心的概念:</p>
+<ol>
+<li>
+<p>通过<strong>接口</strong>进行远程调用</p>
+</li>
+<li>
+<p>通过客户端的 <strong>Stub 对象</strong>和服务端的 <strong>Skeleton 对象</strong>的帮助将远程调用伪装成本地调用</p>
+</li>
+<li>
+<p>通过 <strong>RMI 注册服务</strong>完成服务的注册和发现</p>
+</li>
+</ol>
+<p>对于第一点,客户端需要依赖接口,而服务端需要提供该接口的实现。</p>
+<p>对于第二点,在 J2SE 1.5 版本之前需要通过 rmic 预先编译好客户端的 Stub 对象和服务端的 Skeleton 对象。在之后的版本中,不再需要事先生成 Stub 和 Skeleton 对象。</p>
+<p>下面通过示例代码简单的展示 RMI 中的服务注册和发现</p>
+<h4>服务端的服务注册</h4>
+<pre><code class="language-java">Hello obj = <span class="hljs-keyword">new</span> HelloImpl(); <span class="hljs-comment">// #1</span>
+Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, <span class="hljs-number">0</span>); <span class="hljs-comment">// #2</span>
+Registry registry = LocateRegistry.createRegistry(<span class="hljs-number">1099</span>); <span class="hljs-comment">// #3</span>
+registry.rebind(<span class="hljs-string">"Hello"</span>, stub); <span class="hljs-comment">// #4</span>
+</code></pre>
+<p>说明:</p>
+<ol>
+<li>初始化服务对象实例,</li>
+<li>通过 <em>UnicastRemoteObject.exportObject</em> 生成可以与服务端通讯的 Stub 对象,</li>
+<li>创建一个本地的 RMI 注册服务,监听端口为 1099。该注册服务运行在服务端,也可以单独启动一个注册服务的进程,</li>
+<li>将 Stub 对象绑定到注册服务上,这样,客户端可以通过 <em>Hello</em> 这个名字查找到该远程对象。</li>
+</ol>
+<h4>客户端的服务发现</h4>
+<pre><code class="language-java">Registry registry = LocateRegistry.getRegistry(); <span class="hljs-comment">// #1</span>
+Hello stub = (Hello) registry.lookup(<span class="hljs-string">"Hello"</span>); <span class="hljs-comment">// #2</span>
+String response = stub.sayHello(); <span class="hljs-comment">// #3</span>
+</code></pre>
+<p>说明:</p>
+<ol>
+<li>获取注册服务实例,在本例中,由于没有传入任何参数,假定要获取的注册服务实例部署在本机,并监听在 1099 端口上,</li>
+<li>从注册服务中查找服务名为 <em>Hello</em> 的远程对象,</li>
+<li>通过获取的 Stub 对象发起一次 RMI 调用并获得结果。</li>
+</ol>
+<p>理解 RMI 的工作原理和基本概念,对掌握现代分布式服务框架很有帮助,建议进一步的阅读 RMI 官方教材 <sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>。</p>
+<h2>Dubbo 基本概念</h2>
+<p>现代的分布式服务框架的基本概念与 RMI 是类似的,同样是使用 Java 的 Interface 作为服务契约,通过注册中心来完成服务的注册和发现,远程通讯的细节也是通过代理类来屏蔽。具体来说,Dubbo 在工作时有以下四个角色参与:</p>
+<ol>
+<li>服务提供者 - 启动时在指定端口上暴露服务,并将服务地址和端口注册到注册中心上</li>
+<li>服务消费者 - 启动时向注册中心订阅自己感兴趣的服务,以便获得服务提供方的地址列表</li>
+<li>注册中心 - 负责服务的注册和发现,负责保存服务提供方上报的地址信息,并向服务消费方推送</li>
+<li>监控中心 - 负责收集服务提供方和消费方的运行状态,比如服务调用次数、延迟等,用于监控</li>
+<li>运行容器 - 负责服务提供方的初始化、加载以及运行的生命周期管理</li>
+</ol>
+<p><img src="../../img/blog/dubbo-architecture.png" alt="dubbo-architecture"></p>
+<p><strong>部署阶段</strong></p>
+<ul>
+<li>服务提供者在指定端口暴露服务,并向注册中心注册服务信息。</li>
+<li>服务消费者向注册中心发起服务地址列表的订阅。</li>
+</ul>
+<p><strong>运行阶段</strong></p>
+<ul>
+<li>注册中心向服务消费者推送地址列表信息。</li>
+<li>服务消费者收到地址列表后,从其中选取一个向目标服务发起调用。</li>
+<li>调用过程服务消费者和服务提供者的运行状态上报给监控中心。</li>
+</ul>
+<h2>基于 API 的 Dubbo 应用</h2>
+<p>Dubbo 的应用一般都是通过 Spring 来组装的。为了快速获得一个可以工作的 Dubbo 应用,这里的示例摒弃了复杂的配置,而改用面向 Dubbo API 的方式来构建服务提供者和消费者,另外,注册中心和监控中心在本示例中也不需要安装和配置。</p>
+<p>在生产环境,Dubbo 的服务需要一个分布式的服务注册中心与之配合,比如,ZooKeeper。为了方便开发,Dubbo 提供了直连<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>以及组播<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup>两种方式,从而避免额外搭建注册中心的工作。在本例中,将使用组播的方式来完成服务的注册和发现。</p>
+<h3>定义服务契约</h3>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">GreetingsService</span> </span>{
+    <span class="hljs-function">String <span class="hljs-title">sayHi</span><span class="hljs-params">(String name)</span></span>; <span class="hljs-comment">// #1</span>
+}
+</code></pre>
+<p><strong>说明</strong>:</p>
+<ol>
+<li>定义了一个简单的服务契约 <em>GreetingsService</em>,其中只有一个方法 <em>sayHi</em> 可供调用,入参是 <em>String</em> 类型,返回值也是 <em>String</em> 类型。</li>
+</ol>
+<h3>提供契约的实现</h3>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GreetingsServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">GreetingsService</span> </span>{ <span class="hljs-comment">// #1</span>
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">sayHi</span><span class="hljs-params">(String name)</span> </span>{
+        <span class="hljs-keyword">return</span> <span class="hljs-string">"hi, "</span> + name; <span class="hljs-comment">// #2</span>
+    }
+}
+</code></pre>
+<p><strong>说明</strong>:</p>
+<ol>
+<li>服务提供者需要实现服务契约 <em>GreetingsService</em> 接口。</li>
+<li>该实现简单的返回一个欢迎信息,如果入参是 <em>dubbo</em>,则返回 <em>hi, dubbo</em>。</li>
+</ol>
+<h3>实现 Dubbo 服务提供方</h3>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Application</span> </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">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> IOException </span>{
+        ServiceConfig&lt;GreetingsService&gt; service = <span class="hljs-keyword">new</span> ServiceConfig&lt;&gt;(); <span class="hljs-comment">// #1</span>
+        service.setApplication(<span class="hljs-keyword">new</span> ApplicationConfig(<span class="hljs-string">"first-dubbo-provider"</span>)); <span class="hljs-comment">// #2</span>
+        service.setRegistry(<span class="hljs-keyword">new</span> RegistryConfig(<span class="hljs-string">"multicast://224.5.6.7:1234"</span>)); <span class="hljs-comment">// #3</span>
+        service.setInterface(GreetingsService<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>; <span class="hljs-comment">// #4</span>
+        service.setRef(<span class="hljs-keyword">new</span> GreetingsServiceImpl()); <span class="hljs-comment">// #5</span>
+        service.export(); <span class="hljs-comment">// #6</span>
+        System.in.read(); <span class="hljs-comment">// #7</span>
+    }
+}
+</code></pre>
+<p><strong>说明</strong>:</p>
+<ol>
+<li>创建一个 <em>ServiceConfig</em> 的实例,泛型参数信息是服务接口类型,即 <em>GreetingsService</em>。</li>
+<li>生成一个 <em>ApplicationConfig</em> 的实例,并将其装配进 <em>ServiceConfig</em>。</li>
+<li>生成一个 <em>RegistryConfig</em> 实例,并将其装配进 <em>ServiceConfig</em>,这里使用的是组播方式,参数是 <code>multicast://224.5.6.7:1234</code>。合法的组播地址范围为:<em>224.0.0.0 - 239.255.255.255</em></li>
+<li>将服务契约 <em>GreetingsService</em> 装配进 <em>ServiceConfig</em>。</li>
+<li>将服务提供者提供的实现 <em>GreetingsServiceImpl</em> 的实例装配进 <em>ServiceConfig</em>。</li>
+<li><em>ServiceConfig</em> 已经具备足够的信息,开始对外暴露服务,默认监听端口是 <em>20880</em>。</li>
+<li>为了防止服务端退出,按任意键或者 <em>ctrl-c</em> 退出。</li>
+</ol>
+<h3>实现 Dubbo 服务调用方</h3>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Application</span> </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">main</span><span class="hljs-params">(String[] args)</span> </span>{
+        ReferenceConfig&lt;GreetingsService&gt; reference = <span class="hljs-keyword">new</span> ReferenceConfig&lt;&gt;(); <span class="hljs-comment">// #1</span>
+        reference.setApplication(<span class="hljs-keyword">new</span> ApplicationConfig(<span class="hljs-string">"first-dubbo-client"</span>)); <span class="hljs-comment">// #2</span>
+        reference.setRegistry(<span class="hljs-keyword">new</span> RegistryConfig(<span class="hljs-string">"multicast://224.5.6.7:1234"</span>)); <span class="hljs-comment">// #3</span>
+        reference.setInterface(GreetingsService<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>; <span class="hljs-comment">// #4</span>
+        GreetingsService greetingsService = reference.get(); <span class="hljs-comment">// #5</span>
+        String message = greetingsService.sayHi(<span class="hljs-string">"dubbo"</span>); <span class="hljs-comment">// #6</span>
+        System.out.println(message); <span class="hljs-comment">// #7</span>
+    }
+}
+</code></pre>
+<p><strong>说明</strong>:</p>
+<ol>
+<li>创建一个 <em>ReferenceConfig</em> 的实例,同样,泛型参数信息是服务接口类型,即 <em>GreetingService</em>。</li>
+<li>生成一个 <em>ApplicationConfig</em> 的实例,并将其装配进 <em>ReferenceConfig</em>。</li>
+<li>生成一个 <em>RegistryConfig</em> 实例,并将其装配进 <em>ReferenceConfig</em>,注意这里的组播地址信息需要与服务提供方的相同。</li>
+<li>将服务契约 <em>GreetingsService</em> 装配进 <em>ReferenceConfig</em>。</li>
+<li>从 <em>ReferenceConfig</em> 中获取到 <em>GreetingService</em> 的代理。</li>
+<li>通过 <em>GreetingService</em> 的代理发起远程调用,传入的参数为 <em>dubbo</em>。</li>
+<li>打印返回结果 <em>hi, dubbo</em>。</li>
+</ol>
+<h3>运行</h3>
+<p>完整的示例在 <a href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-api">https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-api</a> 上提供。在完整的示例中,由于配置了 <em>exec-maven-plugin</em>,可以很方便的在命令行下通过 maven 的方式执行。当然,您也可以在 IDE 里直接执行,但是需要注意的是,由于使用了组播的方式来发现服务,运行时需要指定 <em>-Djava.net.preferIPv4Stack=true</em>。</p>
+<h4>构建示例</h4>
+<p>通过以下的命令来同步示例代码并完成构建:</p>
+<ol>
+<li>同步代码:git clone <a href="https://github.com/dubbo/dubbo-samples.git">https://github.com/dubbo/dubbo-samples.git</a></li>
+<li>构建:mvn clean package</li>
+</ol>
+<pre><code class="language-bash">$ git <span class="hljs-built_in">clone</span> https://github.com/dubbo/dubbo-samples.git
+$ <span class="hljs-built_in">cd</span> dubbo-samples/dubbo-samples-api/
+$ mvn clean package
+INFO] Scanning <span class="hljs-keyword">for</span> projects...
+[INFO]
+[INFO] ------------------------------------------------------------------------
+[INFO] Building dubbo-samples-api 1.0-SNAPSHOT
+[INFO] ------------------------------------------------------------------------
+[INFO]
+[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ dubbo-samples-api ---
+...
+[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESS
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time: 2.182 s
+[INFO] Finished at: 2018-05-28T14:56:08+08:00
+[INFO] Final Memory: 20M/353M
+[INFO] ------------------------------------------------------------------------
+</code></pre>
+<p>当看到 <em>BUILD SUCCESS</em> 的时候表明构建完成,下面就可以开始进入运行阶段了。</p>
+<h4>运行服务端</h4>
+<p>通过运行以下的 maven 命令来启动服务提供者:</p>
+<pre><code class="language-bash">$ mvn -Djava.net.preferIPv4Stack=<span class="hljs-literal">true</span> -Dexec.mainClass=com.alibaba.dubbo.samples.server.Application <span class="hljs-built_in">exec</span>:java
+[INFO] Scanning <span class="hljs-keyword">for</span> projects...
+[INFO]                                                                         
+[INFO] ------------------------------------------------------------------------
+[INFO] Building dubbo-samples-api 1.0-SNAPSHOT
+[INFO] ------------------------------------------------------------------------
+[INFO] 
+[INFO] --- <span class="hljs-built_in">exec</span>-maven-plugin:1.6.0:java (default-cli) @ dubbo-samples-api ---
+log4j:WARN No appenders could be found <span class="hljs-keyword">for</span> logger (com.alibaba.dubbo.common.logger.LoggerFactory).
+log4j:WARN Please initialize the log4j system properly.
+log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html<span class="hljs-comment">#noconfig for more info.</span>
+first-dubbo-provider is running.
+</code></pre>
+<p>当 <em>first-dubbo-provider is running.</em> 出现时,代表服务提供者已经启动就绪,等待客户端的调用。</p>
+<h4>运行客户端</h4>
+<p>通过运行以下的 maven 命令来调用服务:</p>
+<pre><code class="language-bash">$ mvn -Djava.net.preferIPv4Stack=<span class="hljs-literal">true</span> -Dexec.mainClass=com.alibaba.dubbo.samples.client.Application <span class="hljs-built_in">exec</span>:java
+[INFO] Scanning <span class="hljs-keyword">for</span> projects...
+[INFO]                                                                         
+[INFO] ------------------------------------------------------------------------
+[INFO] Building dubbo-samples-api 1.0-SNAPSHOT
+[INFO] ------------------------------------------------------------------------
+[INFO] 
+[INFO] --- <span class="hljs-built_in">exec</span>-maven-plugin:1.6.0:java (default-cli) @ dubbo-samples-api ---
+log4j:WARN No appenders could be found <span class="hljs-keyword">for</span> logger (com.alibaba.dubbo.common.logger.LoggerFactory).
+log4j:WARN Please initialize the log4j system properly.
+log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html<span class="hljs-comment">#noconfig for more info.</span>
+hi, dubbo
+</code></pre>
+<p>可以看到, <em>hi, dubbo</em> 是从服务提供者返回的执行结果。</p>
+<h2>快速生成 Dubbo 应用</h2>
+<p>Dubbo 还提供了一个公共服务快速搭建基于 Spring Boot 的 Dubbo 应用。访问 <a href="http://start.dubbo.io">http://start.dubbo.io</a> 并按照下图所示来生成示例工程:</p>
+<p><img src="../../img/blog/dubbo-initializr.png" alt="dubbo initializr"></p>
+<p><strong>说明</strong>:</p>
+<ol>
+<li>在 <em>Group</em> 中提供 maven groupId,默认值是 <em>com.example</em>。</li>
+<li>在 <em>Artifact</em> 中提供 maven artifactId,默认值是 <em>demo</em>。</li>
+<li>在 <em>DubboServiceName</em> 中提供服务名,默认值是 <em>com.example.HelloService</em>。</li>
+<li>在 <em>DubboServiceVersion</em> 中提供服务的版本,默认值是 <em>1.0.0</em>。</li>
+<li>在 <em>Client/Server</em> 中选取本次构建的工程是服务提供者 (Server) 还是服务消费者 (Client),默认值是 <em>server</em>。</li>
+<li>使用 <em>embeddedZookeeper</em> 作为服务注册发现,默认为勾选。</li>
+<li>是否激活 qos 端口,默认为不勾选,如果勾选可以通过 <em>22222</em> 端口访问。</li>
+<li>点击 <em>Generate Project</em> 即可下载生成好的工程。</li>
+</ol>
+<p>在本例中展示的是服务提供者,同样的,通过在生成界面选取 <em>client</em> 来生成对应的服务消费者。</p>
+<h3>运行</h3>
+<p>用 IDE 打开生成好的工程,可以发现应用是一个典型的 Spring Boot 应用。程序的入口如下所示:</p>
+<pre><code class="language-java"><span class="hljs-meta">@SpringBootApplication</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DemoApplication</span> </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">main</span><span class="hljs-params">(String[] args)</span> </span>{
+		<span class="hljs-keyword">new</span> EmbeddedZooKeeper(<span class="hljs-number">2181</span>, <span class="hljs-keyword">false</span>).start();  <span class="hljs-comment">// #1</span>
+		SpringApplication.run(DemoApplication<span class="hljs-class">.<span class="hljs-keyword">class</span>, <span class="hljs-title">args</span>)</span>; <span class="hljs-comment">// #2</span>
+	}
+}
+</code></pre>
+<p><strong>说明</strong>:</p>
+<ol>
+<li>在 <em>2181</em> 端口上启动嵌入式 <em>ZooKeeper</em>。</li>
+<li>启动 <em>Spring Boot</em> 上下文。</li>
+</ol>
+<p>可以直接在 IDE 中运行,输出结果如下:</p>
+<pre><code class="language-bash">2018-05-28 16:59:38.072  INFO 59943 --- [           main] a.b.d.c.e.WelcomeLogoApplicationListener : 
+
+  ████████▄  ███    █▄  ▀█████████▄  ▀█████████▄   ▄██████▄  
+  ███   ▀███ ███    ███   ███    ███   ███    ███ ███    ███ 
+  ███    ███ ███    ███   ███    ███   ███    ███ ███    ███ 
+  ███    ███ ███    ███  ▄███▄▄▄██▀   ▄███▄▄▄██▀  ███    ███ 
+  ███    ███ ███    ███ ▀▀███▀▀▀██▄  ▀▀███▀▀▀██▄  ███    ███ 
+  ███    ███ ███    ███   ███    ██▄   ███    ██▄ ███    ███ 
+  ███   ▄███ ███    ███   ███    ███   ███    ███ ███    ███ 
+  ████████▀  ████████▀  ▄█████████▀  ▄█████████▀   ▀██████▀  
+                                                             
+
+ :: Dubbo Spring Boot (v0.1.0) : https://github.com/dubbo/dubbo-spring-boot-project
+ :: Dubbo (v2.0.1) : https://github.com/alibaba/dubbo
+ :: Google group : http://groups.google.com/group/dubbo
+
+2018-05-28 16:59:38.079  INFO 59943 --- [           main] e.OverrideDubboConfigApplicationListener : Dubbo Config was overridden by externalized configuration {dubbo.application.name=dubbo-demo-server, dubbo.application.qosAcceptForeignIp=<span class="hljs-literal">false</span>, dubbo.application.qosEnable=<span class="hljs-literal">true</span>, dubbo.application.qosPort=22222, dubbo.registry.address=zookeeper://localhost:2181?client=curator, dubbo.registry.id=my-registry, dubbo.scan.bas [...]
+
+...
+
+2018-05-28 16:59:39.624  INFO 59943 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication <span class="hljs-keyword">in</span> 1.746 seconds (JVM running <span class="hljs-keyword">for</span> 2.963)
+</code></pre>
+<p><strong>说明</strong>:</p>
+<ol>
+<li>输出中打印的以 <em>dubbo.</em> 开头的配置信息,定义在 <em>main/resources/application.properties</em> 中。</li>
+</ol>
+<h3>通过 Telnet 管理服务</h3>
+<p>生成工程的时候如果选择了激活 <em>qos</em> 的话,就可以通过 <em>telnet</em> 或者 <em>nc</em> 来管理服务、查看服务状态。</p>
+<pre><code class="language-bash">$ telnet localhost 22222
+Trying 127.0.0.1...
+Connected to localhost.
+Escape character is <span class="hljs-string">'^]'</span>.
+  ████████▄  ███    █▄  ▀█████████▄  ▀█████████▄   ▄██████▄  
+  ███   ▀███ ███    ███   ███    ███   ███    ███ ███    ███ 
+  ███    ███ ███    ███   ███    ███   ███    ███ ███    ███ 
+  ███    ███ ███    ███  ▄███▄▄▄██▀   ▄███▄▄▄██▀  ███    ███ 
+  ███    ███ ███    ███ ▀▀███▀▀▀██▄  ▀▀███▀▀▀██▄  ███    ███ 
+  ███    ███ ███    ███   ███    ██▄   ███    ██▄ ███    ███ 
+  ███   ▄███ ███    ███   ███    ███   ███    ███ ███    ███ 
+  ████████▀  ████████▀  ▄█████████▀  ▄█████████▀   ▀██████▀  
+                                                             
+
+dubbo&gt;
+dubbo&gt;ls
+As Provider side:
++------------------------------+---+
+|     Provider Service Name    |PUB|
++------------------------------+---+
+|com.example.HelloService:1.0.0| Y |
++------------------------------+---+
+As Consumer side:
++---------------------+---+
+|Consumer Service Name|NUM|
++---------------------+---+
+</code></pre>
+<p>目前 <em>qos</em> 支持以下几个命令,更详细的信息请查阅官方文档<sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup>:</p>
+<ul>
+<li><em>ls</em>:列出消费者、提供者信息</li>
+<li><em>online</em>:上线服务</li>
+<li><em>offline</em>:下线服务</li>
+<li><em>help</em>:联机帮助</li>
+</ul>
+<h2>总结</h2>
+<p>在本文中,从 RMI 开始,介绍了 Java 领域分布式调用的基本概念,也就是基于接口编程、通过代理将远程调用伪装成本地、通过注册中心完成服务的注册和发现。</p>
+<p>然后为了简单起见,使用简单的组播注册方式和直接面向 Dubbo API 编程的方式介绍了如何开发一个 Dubbo 的完整应用。深入的了解 <em>ServiceConfig</em> 和 <em>ReferenceConfig</em> 的用法,对于进一步的使用 Spring XML 配置、乃至 Spring Boot 的编程方式有这很大的帮助。</p>
+<p>最后,简单的介绍了如何通过 Dubbo 团队提供的公共服务 <a href="http://start.dubbo.io">start.dubbo.io</a> 快速搭建基于 Spring Boot 的 Dubbo 应用,并通过 <em>qos</em> 来做 Dubbo 服务的简单运维。</p>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p><a href="https://docs.oracle.com/javase/6/docs/technotes/guides/rmi/hello/hello-world.html">Getting Started Using JavaTM RMI</a> <a href="#fnref1" class="footnote-backref">↩︎</a></p>
+</li>
+<li id="fn2" class="footnote-item"><p><a href="http://dubbo.apache.org/zh-cn/docs/user/demos/explicit-target.html">直连提供者</a> <a href="#fnref2" class="footnote-backref">↩︎</a></p>
+</li>
+<li id="fn3" class="footnote-item"><p><a href="http://dubbo.apache.org/zh-cn/docs/user/references/registry/multicast.html">Multicast 注册中心</a> <a href="#fnref3" class="footnote-backref">↩︎</a></p>
+</li>
+<li id="fn4" class="footnote-item"><p><a href="http://dubbo.apache.org/zh-cn/docs/user/references/qos.html">在线运维命令</a> <a href="#fnref4" class="footnote-backref">↩︎</a></p>
+</li>
+</ol>
+</section>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-101.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-101.json
new file mode 100644
index 0000000..9541bab
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-101.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-101.md",
+  "__html": "<h1>第一个 Dubbo 应用</h1>\n<h2>Java RMI 简介</h2>\n<p>Java RMI (Remote Method Invocation)- 远程方法调用,能够让客户端像使用本地调用一样调用服务端 Java 虚拟机中的对象方法。RMI 是面向对象语言领域对 RPC (Remote Procedure Call)的完善,用户无需依靠 IDL 的帮助来完成分布式调用,而是通过依赖接口这种更简单自然的方式。</p>\n<h3>Java RMI 工作原理</h3>\n<p>一个典型的 RMI 调用如下图所示:</p>\n<ol>\n<li>服务端向 RMI 注册服务绑定自己的地址,</li>\n<li>客户端通过 RMI 注册服务获取目标地址,</li>\n<li>客户端调用本地的 Stub 对象上的方法,和调用本地对象上的方法一致,</li>\n<li>本地存根对象将调用信息打包,通过网络发送到服务端,</li>\n<li>服务端的 Skeleton 对象收到网络请求之后,将调用信息解包,</li>\n<li>然后找到真正 [...]
+  "link": "/zh-cn/blog/dubbo-101.html",
+  "meta": {
+    "title": "第一个 Dubbo 应用",
+    "keywords": "Dubbo, RPC, RMI",
+    "description": "现代的分布式服务框架的基本概念与 RMI 是类似的,同样是使用 Java 的 Interface 作为服务契约,通过注册中心来完成服务的注册和发现,远程通讯的细节也是通过代理类来屏蔽。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-27-features.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-27-features.html
new file mode 100644
index 0000000..b4d3324
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-27-features.html
@@ -0,0 +1,197 @@
+<!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="Dubbo2.7" />
+	<meta name="description" content="异步化改造,三大中心改造,服务治理增强" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo2.7 三大新特性详解</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>1 背景介绍</h2>
+<p>自 2017 年 7 月阿里重启 Dubbo 开源,到目前为止 github star 数,contributor 数都有了非常大的提升。2018 年 2 月 9 日阿里决定将 Dubbo 项目贡献给 Apache,经过一周的投票,顺利成为了 Apache 的孵化项目,也就是大家现在看到的 <strong>Incubator Dubbo</strong>。预计在 2019 年 4 月,Dubbo 可以达成毕业,成为 Apache 的顶级项目。</p>
+<h2>2 分支介绍</h2>
+<p><img src="http://kirito.iocoder.cn/image-20190321153455566.png" alt="分支"></p>
+<p>Dubbo 目前有如图所示的 5 个分支,其中 2.7.1-release 只是一个临时分支,忽略不计,对其他 4 个分支进行介绍。</p>
+<ul>
+<li>2.5.x 近期已经通过投票,Dubbo 社区即将停止对其的维护。</li>
+<li>2.6.x 为长期支持的版本,也是 Dubbo 贡献给 Apache 之前的版本,其包名前缀为:com.alibaba,JDK 版本对应 1.6。</li>
+<li>3.x-dev 是前瞻性的版本,对 Dubbo 进行一些高级特性的补充,如支持 rx 特性。</li>
+<li>master 为长期支持的版本,版本号为 2.7.x,也是 Dubbo 贡献给 Apache 的开发版本,其包名前缀为:org.apache,JDK 版本对应 1.8。</li>
+</ul>
+<blockquote>
+<p>如果想要研究 Dubbo 的源码,建议直接浏览 master 分支。</p>
+</blockquote>
+<h2>3 Dubbo 2.7 新特性</h2>
+<p>Dubbo 2.7.x 作为 Apache 的孵化版本,除了代码优化之外,还新增了许多重磅的新特性,本文将会介绍其中最典型的三个新特性:</p>
+<ul>
+<li>异步化改造</li>
+<li>三大中心改造</li>
+<li>服务治理增强</li>
+</ul>
+<h2>4 异步化改造</h2>
+<h3>4.1 几种调用方式</h3>
+<p><img src="http://kirito.iocoder.cn/image-20190321160844133.png" alt="调用方式"></p>
+<p>在远程方法调用中,大致可以分为这 4 种调用方式。oneway 指的是客户端发送消息后,不需要接受响应。对于那些不关心服务端响应的请求,比较适合使用 oneway 通信。</p>
+<blockquote>
+<p>注意,void hello() 方法在远程方法调用中,不属于 oneway 调用,虽然 void 方法表达了不关心返回值的语义,但在 RPC 层面,仍然需要做通信层的响应。</p>
+</blockquote>
+<p>sync 是最常用的通信方式,也是默认的通信方法。</p>
+<p>future 和 callback 都属于异步调用的范畴,他们的区别是:在接收响应时,future.get() 会导致线程的阻塞;callback 通常会设置一个回调线程,当接收到响应时,自动执行,不会对当前线程造成阻塞。</p>
+<h3>4.2 Dubbo 2.6 异步化</h3>
+<p>异步化的优势在于客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小。介绍 2.7 中的异步化改造之前,先回顾一下如何在 2.6 中使用 Dubbo 异步化的能力。</p>
+<ol>
+<li>将同步接口声明成 <code>async=true</code><pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"asyncService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.api.AsyncService"</span> <span class="hljs-attr">async</span>=<span class="hljs-string">"true"</span>/&gt;</span>
+</code></pre>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">AsyncService</span> </span>{
+    <span class="hljs-function">String <span class="hljs-title">sayHello</span><span class="hljs-params">(String name)</span></span>;
+}
+</code></pre>
+</li>
+<li>通过上下文类获取 future<pre><code class="language-java">AsyncService.sayHello(<span class="hljs-string">"Han Meimei"</span>);
+Future&lt;String&gt; fooFuture = RpcContext.getContext().getFuture();
+fooFuture.get();
+</code></pre>
+</li>
+</ol>
+<p>可以看出,这样的使用方式,不太符合异步编程的习惯,竟然需要从一个上下文类中获取到 Future。如果同时进行多个异步调用,使用不当很容易造成上下文污染。而且,Future 并不支持 callback 的调用方式。这些弊端在 Dubbo 2.7 中得到了改进。</p>
+<h3>4.3 Dubbo 2.7 异步化</h3>
+<ol>
+<li>无需配置中特殊声明,显式声明异步接口即可<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">AsyncService</span> </span>{
+    <span class="hljs-function">String <span class="hljs-title">sayHello</span><span class="hljs-params">(String name)</span></span>;
+    <span class="hljs-function"><span class="hljs-keyword">default</span> CompletableFuture&lt;String&gt; <span class="hljs-title">sayHiAsync</span><span class="hljs-params">(String name)</span> </span>{
+        <span class="hljs-keyword">return</span> CompletableFuture.completedFuture(sayHello(name));
+    }
+}
+</code></pre>
+</li>
+<li>使用 callback 方式处理返回值<pre><code class="language-java">CompletableFuture&lt;String&gt; future = asyncService.sayHiAsync(<span class="hljs-string">"Han MeiMei"</span>);
+future.whenComplete((retValue, exception) -&gt; {
+    <span class="hljs-keyword">if</span> (exception == <span class="hljs-keyword">null</span>) {
+        System.out.println(retValue);
+    } <span class="hljs-keyword">else</span> {
+        exception.printStackTrace();
+    }
+});
+</code></pre>
+</li>
+</ol>
+<p>Dubbo 2.7 中使用了 JDK1.8 提供的 <code>CompletableFuture</code> 原生接口对自身的异步化做了改进。<code>CompletableFuture</code> 可以支持 future 和 callback 两种调用方式,用户可以根据自己的喜好和场景选择使用,非常灵活。</p>
+<h3>4.4 异步化设计 FAQ</h3>
+<p>Q:如果 RPC 接口只定义了同步接口,有办法使用异步调用吗?</p>
+<p>A:2.6 中的异步调用唯一的优势在于,不需要在接口层面做改造,又可以进行异步调用,这种方式仍然在 2.7 中保留;使用 Dubbo 官方提供的 compiler hacker,编译期自动重写同步方法,请<a href="https://github.com/dubbo/dubbo-async-processor#compiler-hacker-processer">在此</a>讨论和跟进具体进展。</p>
+<hr>
+<p>Q:关于异步接口的设计问题,为何不提供编译插件,根据原接口,自动编译出一个 XxxAsync 接口?</p>
+<p>A:Dubbo 2.7 采用过这种设计,但接口的膨胀会导致服务类的增量发布,而且接口名的变化会影响服务治理的一些相关逻辑,改为方法添加 Async 后缀相对影响范围较小。</p>
+<hr>
+<p>Q:Dubbo 分为了客户端异步和服务端异步,刚刚你介绍的是客户端异步,为什么不提服务端异步呢?</p>
+<p>A:Dubbo 2.7 新增了服务端异步的支持,但实际上,Dubbo 的业务线程池模型,本身就可以理解为异步调用,个人认为服务端异步的特性较为鸡肋。</p>
+<h2>5 三大中心改造</h2>
+<p>三大中心指的:注册中心,元数据中心,配置中心。</p>
+<p>在 2.7 之前的版本,Dubbo 只配备了注册中心,主流使用的注册中心为 zookeeper。新增加了元数据中心和配置中心,自然是为了解决对应的痛点,下面我们来详细阐释三大中心改造的原因。</p>
+<h3>5.1 元数据改造</h3>
+<p>元数据是什么?元数据定义为描述数据的数据,在服务治理中,例如服务接口名,重试次数,版本号等等都可以理解为元数据。在 2.7 之前,元数据一股脑丢在了注册中心之中,这造成了一系列的问题:</p>
+<p><strong>推送量大 -&gt; 存储数据量大 -&gt; 网络传输量大 -&gt; 延迟严重</strong></p>
+<p>生产者端注册 30+ 参数,有接近一半是不需要作为注册中心进行传递;消费者端注册 25+ 参数,只有个别需要传递给注册中心。有了以上的理论分析,Dubbo 2.7 进行了大刀阔斧的改动,只将真正属于服务治理的数据发布到注册中心之中,大大降低了注册中心的负荷。</p>
+<p>同时,将全量的元数据发布到另外的组件中:元数据中心。元数据中心目前支持 redis(推荐),zookeeper。这也为 Dubbo 2.7 全新的 Dubbo Admin 做了准备,关于新版的 Dubbo Admin,我将会后续准备一篇独立的文章进行介绍。</p>
+<p>示例:使用 zookeeper 作为元数据中心</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:metadata-report</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span>/&gt;</span>
+</code></pre>
+<h3>5.2 Dubbo 2.6 元数据</h3>
+<pre><code class="language-shell">dubbo://30.5.120.185:20880/com.alibaba.dubbo.demo.DemoService?
+anyhost=true&amp;
+application=demo-provider&amp;
+interface=com.alibaba.dubbo.demo.DemoService&amp;
+methods=sayHello&amp;
+bean.name=com.alibaba.dubbo.demo.DemoService&amp;
+dubbo=2.0.2&amp;
+executes=4500&amp;
+generic=false&amp;
+owner=kirito&amp;
+pid=84228&amp;
+retries=7&amp;
+side=provider&amp;
+timestamp=1552965771067
+</code></pre>
+<p>从本地的 zookeeper 中取出一条服务数据,通过解码之后,可以看出,的确有很多参数是不必要。</p>
+<h3>5.3 Dubbo 2.7 元数据</h3>
+<p>在 2.7 中,如果不进行额外的配置,zookeeper 中的数据格式仍然会和 Dubbo 2.6 保持一致,这主要是为了保证兼容性,让 Dubbo 2.6 的客户端可以调用 Dubbo 2.7 的服务端。如果整体迁移到 2.7,则可以为注册中心开启简化配置的参数:</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">“zookeeper://127.0.0.1:2181”</span> <span class="hljs-attr">simplified</span>=<span class="hljs-string">"true"</span>/&gt;</span>
+</code></pre>
+<p>Dubbo 将会只上传那些必要的服务治理数据,一个简化过后的数据如下所示:</p>
+<pre><code class="language-shell">dubbo://30.5.120.185:20880/org.apache.dubbo.demo.api.DemoService?
+application=demo-provider&amp;
+dubbo=2.0.2&amp;
+release=2.7.0&amp;
+timestamp=1552975501873
+</code></pre>
+<p>对于那些非必要的服务信息,仍然全量存储在元数据中心之中:</p>
+<p><img src="http://kirito.iocoder.cn/image-20190321175852034.png" alt="元数据"></p>
+<blockquote>
+<p>元数据中心的数据可以被用于服务测试,服务 MOCK 等功能。目前注册中心配置中 simplified 的默认值为 false,因为考虑到了迁移的兼容问题,在后续迭代中,默认值将会改为 true。</p>
+</blockquote>
+<h3>5.4 配置中心支持</h3>
+<p>衡量配置中心的必要性往往从三个角度出发:</p>
+<ol>
+<li>
+<p>分布式配置统一管理</p>
+</li>
+<li>
+<p>动态变更推送</p>
+</li>
+<li>
+<p>安全性</p>
+</li>
+</ol>
+<p>Spring Cloud Config, Apollo, Nacos 等分布式配置中心组件都对上述功能有不同程度的支持。在 2.7 之前的版本中,在 zookeeper 中设置了部分节点:configurators,routers,用于管理部分配置和路由信息,它们可以理解为 Dubbo 配置中心的雏形。在 2.7 中,Dubbo 正式支持了配置中心,目前支持的几种注册中心 Zookeeper,Apollo,Nacos(2.7.1-release 支持)。</p>
+<p>在 Dubbo 中,配置中心主要承担了两个作用</p>
+<ul>
+<li>
+<p>外部化配置。启动配置的集中式存储</p>
+</li>
+<li>
+<p>服务治理。服务治理规则的存储与通知</p>
+</li>
+</ul>
+<p>示例:使用 Zookeeper 作为配置中心</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:config-center</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span>/&gt;</span>
+</code></pre>
+<p>引入配置中心后,需要注意配置项的覆盖问题,优先级如图所示</p>
+<p><img src="http://kirito.iocoder.cn/configuration.jpg" alt="配置覆盖优先级"></p>
+<h2>6 服务治理增强</h2>
+<p>我更倾向于将 Dubbo 当做一个服务治理框架,而不仅仅是一个 RPC 框架。在 2.7 中,Dubbo 对其服务治理能力进行了增强,增加了标签路由的能力,并抽象出了应用路由和服务路由的概念。在最后一个特性介绍中,着重对标签路由 TagRouter 进行探讨。</p>
+<blockquote>
+<p>在服务治理中,路由层和负载均衡层的对比。区别 1,Router:m 选 n,LoadBalance:n 选 1;区别 2,路由往往是叠加使用的,负载均衡只能配置一种。</p>
+</blockquote>
+<p>在很长的一段时间内,Dubbo 社区经常有人提的一个问题是:Dubbo 如何实现流量隔离和灰度发布,直到 2.7 提供了标签路由,用户可以使用这个功能,来实现上述的需求。</p>
+<p><img src="http://kirito.iocoder.cn/image-20190321191620078.png" alt="标签路由"></p>
+<p>标签路由提供了这样一个能力,当调用链路为 A -&gt; B -&gt; C -&gt; D 时,用户给请求打标,最典型的打标方式可以借助 attachment(他可以在分布式调用中传递下去),调用会优先请求那些匹配的服务端,如 A -&gt; B,C -&gt; D,由于集群中未部署 C 节点,则会降级到普通节点。</p>
+<p>打标方式会收到集成系统差异的影响,从而导致很大的差异,所以 Dubbo 只提供了 <code>RpcContext.getContext().setAttachment()</code> 这样的基础接口,用户可以使用 SPI 扩展,或者 server filter 的扩展,对测试流量进行打标,引导进入隔离环境/灰度环境。</p>
+<p>新版的 Dubbo Admin 提供了标签路由的配置项:</p>
+<p><img src="http://kirito.iocoder.cn/image-20190321192540774.png" alt="标签路由配置"></p>
+<p>Dubbo 用户可以在自己系统的基础上对标签路由进行二次扩展,或者借鉴标签路由的设计,实现自己系统的流量隔离,灰度发布。</p>
+<h2>7 总结</h2>
+<p>本文介绍了 Dubbo 2.7 比较重要的三大新特性:异步化改造,三大中心改造,服务治理增强。Dubbo 2.7 还包含了很多功能优化、特性升级,可以在项目源码的 <a href="https://github.com/apache/dubbo/blob/master/CHANGES.md">CHANGES.md</a> 中浏览全部的改动点。最后提供一份 Dubbo 2.7 的升级文档:<a href="http://dubbo.apache.org/zh-cn/docs/user/versions/version-270.html">2.7迁移文档</a>,欢迎体验。</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-27-features.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-27-features.json
new file mode 100644
index 0000000..44b2a7a
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-27-features.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-27-features.md",
+  "__html": "<h1></h1>\n<h2>1 背景介绍</h2>\n<p>自 2017 年 7 月阿里重启 Dubbo 开源,到目前为止 github star 数,contributor 数都有了非常大的提升。2018 年 2 月 9 日阿里决定将 Dubbo 项目贡献给 Apache,经过一周的投票,顺利成为了 Apache 的孵化项目,也就是大家现在看到的 <strong>Incubator Dubbo</strong>。预计在 2019 年 4 月,Dubbo 可以达成毕业,成为 Apache 的顶级项目。</p>\n<h2>2 分支介绍</h2>\n<p><img src=\"http://kirito.iocoder.cn/image-20190321153455566.png\" alt=\"分支\"></p>\n<p>Dubbo 目前有如图所示的 5 个分支,其中 2.7.1-release 只是一个临时分支,忽略不计,对其他 4 个分支进行介绍。</p>\n<ul>\n<li>2.5.x 近期已经通过投票,Dubbo 社区即将停止对其的维 [...]
+  "link": "/zh-cn/blog/dubbo-27-features.html",
+  "meta": {
+    "title": "Dubbo2.7 三大新特性详解",
+    "keywords": "Dubbo2.7",
+    "description": "异步化改造,三大中心改造,服务治理增强"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-admin.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-admin.html
new file mode 100644
index 0000000..ab2d2cd
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-admin.html
@@ -0,0 +1,96 @@
+<!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="dubbo-admin" />
+	<meta name="description" content="dubbo-admin" />
+	<!-- 网页标签标题 -->
+	<title>dubbo-admin</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<pre><code>Demo地址:http://47.91.207.147/#/service  
+github: https://github.com/apache/dubbo-ops
+</code></pre>
+<p>Dubbo Admin之前的版本过于老旧,也长期疏于维护,因此在去年年中的时候,对该项目进行了一次重构,项目结构上的变化如下:</p>
+<ul>
+<li>将后端框架从webx替换成spring boot</li>
+<li>前端采用Vue和Vuetify.js作为开发框架</li>
+<li>移除velocity模板</li>
+<li>集成swagger,提供api管理功能</li>
+</ul>
+<p>当前版本的Dubbo Admin包含了之前版本中的绝大部分功能,包括服务治理,服务查询等,同时支持了Dubbo2.7中服务治理的新特性。</p>
+<h2>配置规范</h2>
+<p>由于在Dubbo2.7中,配置中心和注册中心做了分离,并且增加了元数据中心,因此Dubbo Admin的配置方式也做了更新,<code>application.properties</code>中的配置如下:</p>
+<pre><code class="language-properties"><span class="hljs-meta">admin.registry.address</span>=<span class="hljs-string">zookeeper://127.0.0.1:2181</span>
+<span class="hljs-meta">admin.config-center</span>=<span class="hljs-string">zookeeper://127.0.0.1:2181</span>
+<span class="hljs-meta">admin.metadata-report.address</span>=<span class="hljs-string">zookeeper://127.0.0.1:2181</span>
+</code></pre>
+<p>也可以和Dubbo2.7一样,在配置中心指定元数据和注册中心的地址,以zookeeper为例,配置的路径和内容如下:</p>
+<pre><code class="language-properties"><span class="hljs-comment"># /dubbo/config/dubbo/dubbo.properties</span>
+<span class="hljs-meta">dubbo.registry.address</span>=<span class="hljs-string">zookeeper://127.0.0.1:2181</span>
+<span class="hljs-meta">dubbo.metadata-report.address</span>=<span class="hljs-string">zookeeper://127.0.0.1:2181</span>
+</code></pre>
+<p>配置中心里的地址会覆盖掉本地<code>application.properties</code>的配置</p>
+<h2>功能介绍</h2>
+<p>功能上,主要延续了之前版本的功能,包括服务查询和服务治理,2.7版本在服务治理的功能上有了很大的改进,这些改进也大部分都会以Dubbo Admin作为入口来体现。</p>
+<h3>标签路由</h3>
+<p>标签路由是Dubbo2.7引入的新功能,配置以应用作为维度,给不同的服务器打上不同名字的标签,配置如下图所示:
+<img src="../../img/blog/admin/route.jpg" alt="tag">
+调用的时候,客户端可以通过<code>setAttachment</code>的方式,来设置不同的标签名称,比如本例中,<code>setAttachment(tag1)</code>,客户端的选址范围就在如图所示的三台机器中,可以通过这种方式来实现流量隔离,灰度发布等功能。</p>
+<h3>应用级别的服务治理</h3>
+<p>在Dubbo2.6及更早版本中,所有的服务治理规则都只针对服务粒度,如果要把某条规则作用到应用粒度上,需要为应用下的所有服务配合相同的规则,变更,删除的时候也需要对应的操作,这样的操作很不友好,因此Dubbo2.7版本中增加了应用粒度的服务治理操作,对于条件路由(包括黑白名单),动态配置(包括权重,负载均衡)都可以做应用级别的配置:<br>
+<img src="../../img/blog/admin/conditionRoute.jpg" alt="condition"><br>
+上图是条件路由的配置,可以按照应用名,服务名两个维度来填写,也可以按照这两个维度来查询。</p>
+<p><img src="../../img/blog/admin/weight.jpg" alt="weight"><br>
+条件路由,标签路由和动态配置都采用了<code>yaml</code>格式的文本编写,其他的规则配置还是采用了表单的形式。</p>
+<h4>关于兼容性</h4>
+<p>Dubbo2.6到Dubbo2.7,服务治理发生了比较大的变化,Dubbo Admin兼容两个版本的用法:</p>
+<ul>
+<li>对于服务级别的配置,会按照Dubbo2.6(URL)和Dubbo2.7(配置文件)两种格式进行写入,保证Dubbo2.6的客户端能够正确读取,解析规则</li>
+<li>对于应用级别的配置,包括标签路由,只会按照Dubbo2.7的格式进行写入,因为Dubbo2.6无此功能,不需要做向前兼容。</li>
+<li>Dubbo Admin只会按照Dubbo2.7的格式进行配置读取,因此,所有在Dubbo Admin上做的配置都可以被读到,但是之前遗留的,Dubbo2.6格式的URL无法被读取。</li>
+<li>对于同一个应用或者服务,每种规则只能够配置一条,否则新的会覆盖旧的。</li>
+</ul>
+<h3>配置管理</h3>
+<p>配置管理也是配合Dubbo2.7新增的功能,在Dubbo2.7中,增加了全局和应用维度的配置,</p>
+<ul>
+<li>全局配置:
+<img src="../../img/blog/admin/config.jpg" alt="config"><br>
+全局配置里可以指定注册中心,元数据中心的地址,服务端和客户端的超时时间等,这些配置在全局内生效。除了配置写入,也可以用来查看。如果使用zookeeper作为注册中心和元数据中心,还可以看到配置文件所在位置的目录结构。</li>
+<li>应用, 服务配置<br>
+<img src="../../img/blog/admin/appConfig.jpg" alt="appConfig"><br>
+应用级别的配置可以为应用或者应用内的服务指定配置,在服务维度上,需要区分提供者和消费者。<code>dubbo.reference.{serviceName}</code>表示作为该服务消费者的配置,<code>dubbo.provider.{servcieName}</code>表示作为该服务提供者的配置。优先级服务 &gt; 应用 &gt; 全局。其中注册中心和元数据中心的地址,只能在全局配置中指定,这也是Dubbo2.7中推荐的使用方式。</li>
+</ul>
+<h3>元数据和服务测试</h3>
+<p>元数据是Dubbo2.7中新引入的元素,主要的使用场景就在Dubbo Admin中,主要体现在两个地方:</p>
+<ul>
+<li>服务详情展示:<br>
+<img src="../../img/blog/admin/metadata.jpg" alt="metadata"><br>
+跟之前版本相比,Dubbo2.7中增加了对服务方法完整签名的记录,因此服务详情中也增加了方法信息的详情,可以看到方法名,方法参数列表以及返回值信息。</li>
+<li>服务测试:<br>
+<img src="../../img/blog/admin/test.jpg" alt="test">
+更重要的,元数据为服务测试提供了数据基础,可以在页面上调用真实的服务提供者,方便测试,也不需要为了调用服务去搭建一套Dubbo环境以及编写消费端代码。</li>
+</ul>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-admin.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-admin.json
new file mode 100644
index 0000000..b88c935
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-admin.json
@@ -0,0 +1,6 @@
+{
+  "filename": "dubbo-admin.md",
+  "__html": "<h1>新版Dubbo Admin介绍</h1>\n<pre><code>Demo地址:http://47.91.207.147/#/service  \ngithub: https://github.com/apache/dubbo-ops\n</code></pre>\n<p>Dubbo Admin之前的版本过于老旧,也长期疏于维护,因此在去年年中的时候,对该项目进行了一次重构,项目结构上的变化如下:</p>\n<ul>\n<li>将后端框架从webx替换成spring boot</li>\n<li>前端采用Vue和Vuetify.js作为开发框架</li>\n<li>移除velocity模板</li>\n<li>集成swagger,提供api管理功能</li>\n</ul>\n<p>当前版本的Dubbo Admin包含了之前版本中的绝大部分功能,包括服务治理,服务查询等,同时支持了Dubbo2.7中服务治理的新特性。</p>\n<h2>配置规范</h2>\n<p>由于在Dubbo2.7中,配置中心和注册中心做了分离,并且增加了元数据中心, [...]
+  "link": "/zh-cn/blog/dubbo-admin.html",
+  "meta": {}
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-annotation-driven.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-annotation-driven.html
new file mode 100644
index 0000000..a3ec962
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-annotation-driven.html
@@ -0,0 +1,554 @@
+<!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="dubbo-annotation-driven" />
+	<meta name="description" content="dubbo-annotation-driven" />
+	<!-- 网页标签标题 -->
+	<title>dubbo-annotation-driven</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>注解驱动(Annotation-Driven)</h2>
+<h3><code>@DubboComponentScan</code></h3>
+<h4>起始版本: <code>2.5.7</code></h4>
+<h4><code>&lt;dubbo:annotation&gt;</code>历史遗留问题</h4>
+<h5>1. 注解支持不充分</h5>
+<p>在 Dubbo  <code>2.5.7</code>之前的版本 ,Dubbo 提供了两个核心注解 <code>@Service</code> 以及 <code>@Reference</code>,分别用于Dubbo 服务提供和 Dubbo 服务引用。</p>
+<p>其中,<code>@Service</code> 作为 XML 元素 <code>&lt;dubbo:service&gt;</code>的替代注解,与 Spring Framework <code>@org.springframework.stereotype.Service</code> 类似,用于服务提供方 Dubbo 服务暴露。与之相对应的<code>@Reference</code>,则是替代<code>&lt;dubbo:reference</code> 元素,类似于 Spring 中的 <code>@Autowired</code>。</p>
+<p><code>2.5.7</code> 之前的Dubbo,与早期的 Spring Framework 2.5 存在类似的不足,即注解支持不够充分。注解需要和 XML 配置文件配合使用,如下所示:</p>
+<pre><code class="language-xml"><span class="hljs-meta">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">beans</span> <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">"http://www.w3.org/2001/XMLSchema-instance"</span>
+       <span class="hljs-attr">xmlns:dubbo</span>=<span class="hljs-string">"http://code.alibabatech.com/schema/dubbo"</span>
+       <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.springframework.org/schema/beans"</span>
+       <span class="hljs-attr">xsi:schemaLocation</span>=<span class="hljs-string">"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+	http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"</span>&gt;</span>
+
+    <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"annotation-provider"</span>/&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"127.0.0.1:4548"</span>/&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:annotation</span> <span class="hljs-attr">package</span>=<span class="hljs-string">"com.alibaba.dubbo.config.spring.annotation.provider"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;/<span class="hljs-name">beans</span>&gt;</span>
+</code></pre>
+<h5>2.  <code>@Service</code> Bean 不支持 Spring AOP</h5>
+<p>同时,使用 <code>&lt;dubbo:annotation&gt;</code> 方式扫描后的Dubbo <code>@Service</code> ,在 Spring 代理方面存在问题,如 GitHub 上的 issue <a href="https://github.com/alibaba/dubbo/issues/794%EF%BC%9A">https://github.com/alibaba/dubbo/issues/794:</a></p>
+<blockquote>
+<p>关于dubbo @Service注解生成ServiceBean时, interface获取成spring 的代理对象的bug</p>
+<blockquote>
+<p>在项目里, 我使用了</p>
+<pre><code class="language-java"><span class="hljs-meta">@Service</span>
+<span class="hljs-meta">@Transactional</span>
+<span class="hljs-meta">@com</span>.alibaba.dubbo.config.annotation.Service
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SUserJpushServiceImp</span>
+</span></code></pre>
+<p>的形式, 来暴露服务。但是在发布服务的时候, interface class 是通过
+<code>serviceConfig.setInterface(bean.getClass().getInterfaces()[0]);</code>
+的形式获取, 刚好, 我的service都使用了@Transactional注解, 对象被代理了。所以获取到的interface是Spring的代理接口...</p>
+</blockquote>
+</blockquote>
+<p>不少热心的小伙伴不仅发现这个历史遗留问题,而且提出了一些修复方案。同时,为了更好地适配 Spring 生命周期以及将 Dubbo 完全向注解驱动编程模型过渡,因此,引入了全新 Dubbo 组件扫描注解 - <code>@DubboComponentScan</code>。</p>
+<blockquote>
+<p>注: <code>&lt;dubbo:annotation&gt;</code>  Spring AOP 问题将在 <code>2.5.9</code> 中修复:<a href="https://github.com/alibaba/dubbo/issues/1125">https://github.com/alibaba/dubbo/issues/1125</a></p>
+</blockquote>
+<h5>3. @Reference 不支持字段继承性</h5>
+<p>假设有一个 Spring Bean <code>AnnotationAction</code> 直接通过字段<code>annotationService</code> 标记 <code>@Reference</code> 引用 <code>AnnotationService</code> :</p>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.dubbo.examples.annotation.action;
+
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.config.annotation.Reference;
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.examples.annotation.api.AnnotationService;
+<span class="hljs-keyword">import</span> org.springframework.stereotype.Component;
+
+
+<span class="hljs-meta">@Component</span>(<span class="hljs-string">"annotationAction"</span>)
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AnnotationAction</span> </span>{
+
+    <span class="hljs-meta">@Reference</span>
+    <span class="hljs-keyword">private</span> AnnotationService annotationService;
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">doSayHello</span><span class="hljs-params">(String name)</span> </span>{
+        <span class="hljs-keyword">return</span> annotationService.sayHello(name);
+    }
+
+}
+</code></pre>
+<p>当<code>AnnotationAction</code>  被 XML 元素 <code>&lt;dubbo:annotation&gt;</code> 扫描后:</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:annotation</span> <span class="hljs-attr">package</span>=<span class="hljs-string">"com.alibaba.dubbo.examples.annotation.action"</span>/&gt;</span>
+</code></pre>
+<p>字段 <code>annotationService</code> 能够引用到 <code>AnnotationService</code>,执行 <code>doSayHello</code> 方法能够正常返回。</p>
+<p>如果将字段<code>annotationService</code>  抽取到<code>AnnotationAction</code> 的父类<code>BaseAction</code> 后,<code>AnnotationService</code> 无法再被引用,改造如下所示:</p>
+<p><code>AnnotationAction.java</code></p>
+<pre><code class="language-java"><span class="hljs-meta">@Component</span>(<span class="hljs-string">"annotationAction"</span>)
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AnnotationAction</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">BaseAction</span> </span>{
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">doSayHello</span><span class="hljs-params">(String name)</span> </span>{
+        <span class="hljs-keyword">return</span> getAnnotationService().sayHello(name);
+    }
+
+}
+</code></pre>
+<p><code>BaseAction.java</code></p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BaseAction</span> </span>{
+
+    <span class="hljs-meta">@Reference</span>
+    <span class="hljs-keyword">private</span> AnnotationService annotationService;
+
+    <span class="hljs-function"><span class="hljs-keyword">protected</span> AnnotationService <span class="hljs-title">getAnnotationService</span><span class="hljs-params">()</span> </span>{
+        <span class="hljs-keyword">return</span> annotationService;
+    }
+}
+</code></pre>
+<p>改造后,再次执行 <code>doSayHello</code> 方法,<code>NullPointerException</code> 将会被抛出。说明<code>&lt;dubbo:annotation&gt;</code> 并不支持<code>@Reference</code> 字段继承性。</p>
+<p>了解了历史问题,集合整体愿景,下面介绍<code>@DubboComponentScan</code> 的设计原则。</p>
+<h4>设计原则</h4>
+<p>Spring Framework 3.1 引入了新 Annotation - <code>@ComponentScan</code> , 完全替代了 XML 元素 <code>&lt;context:component-scan&gt;</code> 。同样, <code>@DubboComponentScan</code>  作为 Dubbo <code>2.5.7</code> 新增的 Annotation,也是XML 元素  <code>&lt;dubbo:annotation&gt;</code> 的替代方案。</p>
+<p>在命名上(类名以及属性方法),为了简化使用和关联记忆,Dubbo 组件扫描 Annotation <code>@DubboComponentScan</code>,借鉴了 Spring Boot 1.3 引入的 <code>@ServletComponentScan</code>。定义如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-meta">@interface</span> DubboComponentScan {
+
+    <span class="hljs-comment">/**
+     * Alias for the {<span class="hljs-doctag">@link</span> #basePackages()} attribute. Allows for more concise annotation
+     * declarations e.g.: {<span class="hljs-doctag">@code</span> <span class="hljs-doctag">@DubboComponentScan</span>("org.my.pkg")} instead of
+     * {<span class="hljs-doctag">@code</span> <span class="hljs-doctag">@DubboComponentScan</span>(basePackages="org.my.pkg")}.
+     *
+     * <span class="hljs-doctag">@return</span> the base packages to scan
+     */</span>
+    String[] value() <span class="hljs-keyword">default</span> {};
+
+    <span class="hljs-comment">/**
+     * Base packages to scan for annotated <span class="hljs-doctag">@Service</span> classes. {<span class="hljs-doctag">@link</span> #value()} is an
+     * alias for (and mutually exclusive with) this attribute.
+     * &lt;p&gt;
+     * Use {<span class="hljs-doctag">@link</span> #basePackageClasses()} for a type-safe alternative to String-based
+     * package names.
+     *
+     * <span class="hljs-doctag">@return</span> the base packages to scan
+     */</span>
+    String[] basePackages() <span class="hljs-keyword">default</span> {};
+
+    <span class="hljs-comment">/**
+     * Type-safe alternative to {<span class="hljs-doctag">@link</span> #basePackages()} for specifying the packages to
+     * scan for annotated <span class="hljs-doctag">@Service</span> classes. The package of each class specified will be
+     * scanned.
+     *
+     * <span class="hljs-doctag">@return</span> classes from the base packages to scan
+     */</span>
+    Class&lt;?&gt;[] basePackageClasses() <span class="hljs-keyword">default</span> {};
+
+}
+</code></pre>
+<blockquote>
+<p>注意:<code>basePackages()</code> 和 <code>value()</code> 均能支持占位符(placeholder)指定的包名</p>
+</blockquote>
+<p>在职责上,<code>@DubboComponentScan</code> 相对于 Spring Boot <code>@ServletComponentScan</code> 更为繁重,原因在于处理 Dubbo  <code>@Service</code> 类暴露 Dubbo 服务外,还有帮助 Spring  Bean <code>@Reference</code>字段或者方法注入 Dubbo 服务代理。</p>
+<p>在场景上,Spring Framework <code>@ComponentScan</code> 组件扫描逻辑更为复杂。而在 <code>@DubboComponentScan</code>  只需关注 <code>@Service</code> 和 <code>@Reference</code> 处理。</p>
+<p>在功能上, <code>@DubboComponentScan</code>  不但需要提供完整 Spring AOP 支持的能力,而且还得具备<code>@Reference</code> 字段可继承性的能力。</p>
+<p>了解基本设计原则后,下面通过完整的示例,简介<code>@DubboComponentScan</code> 使用方法以及注意事项。</p>
+<h4>使用方法</h4>
+<p>后续通过服务提供方(<code>@Serivce</code>)以及服务消费方(<code>@Reference</code>)两部分来介绍<code>@DubboComponentScan</code> 使用方法。</p>
+<p>假设,服务提供方和服务消费分均依赖服务接口<code>DemoService</code>:</p>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.dubbo.demo;
+
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">DemoService</span> </span>{
+
+    <span class="hljs-function">String <span class="hljs-title">sayHello</span><span class="hljs-params">(String name)</span></span>;
+
+}
+</code></pre>
+<h5>服务提供方(<code>@Serivce</code>)</h5>
+<h6>实现 <code>DemoService</code></h6>
+<p>服务提供方实现<code>DemoService</code>  - <code>AnnotationDemoService</code> ,同时标注 Dubbo <code>@Service</code> :</p>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.dubbo.demo.provider;
+
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.config.annotation.Service;
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.demo.DemoService;
+
+<span class="hljs-comment">/**
+ * Annotation {<span class="hljs-doctag">@link</span> DemoService} 实现
+ *
+ * <span class="hljs-doctag">@author</span> &lt;a href="mailto:mercyblitz@gmail.com"&gt;Mercy&lt;/a&gt;
+ */</span>
+<span class="hljs-meta">@Service</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AnnotationDemoService</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">DemoService</span> </span>{
+
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">sayHello</span><span class="hljs-params">(String name)</span> </span>{
+        <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello , "</span> + name;
+    }
+
+}
+</code></pre>
+<h6>服务提供方 Annotation 配置</h6>
+<p>将 <code>AnnotationDemoService</code> 暴露成Dubbo 服务,需要依赖 Spring Bean:<code>ApplicationConfig</code>、<code>ProtocolConfig</code> 以及 <code>RegistryConfig</code>  。这三个 Spring Bean 过去可通过 XML 文件方式组装 Spring Bean:</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">beans</span> <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">"http://www.w3.org/2001/XMLSchema-instance"</span>
+       <span class="hljs-attr">xmlns:dubbo</span>=<span class="hljs-string">"http://code.alibabatech.com/schema/dubbo"</span>
+       <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.springframework.org/schema/beans"</span>
+       <span class="hljs-attr">xsi:schemaLocation</span>=<span class="hljs-string">"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+    http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
+    "</span>&gt;</span>
+
+    <span class="hljs-comment">&lt;!-- 当前应用信息配置 --&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"dubbo-annotation-provider"</span>/&gt;</span>
+
+    <span class="hljs-comment">&lt;!-- 连接注册中心配置 --&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my-registry"</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"N/A"</span>/&gt;</span>
+
+    <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"dubbo"</span> <span class="hljs-attr">port</span>=<span class="hljs-string">"12345"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;/<span class="hljs-name">beans</span>&gt;</span>
+</code></pre>
+<p>以上装配方式不予推荐,推荐使用 Annotation 配置,因此可以换成 Spring <code>@Configuration</code> Bean 的形式:</p>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.dubbo.demo.config;
+
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.config.ApplicationConfig;
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.config.ProtocolConfig;
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.config.RegistryConfig;
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;
+<span class="hljs-keyword">import</span> org.springframework.context.annotation.Bean;
+<span class="hljs-keyword">import</span> org.springframework.context.annotation.Configuration;
+
+<span class="hljs-comment">/**
+ * 服务提供方配置
+ *
+ * <span class="hljs-doctag">@author</span> &lt;a href="mailto:mercyblitz@gmail.com"&gt;Mercy&lt;/a&gt;
+ */</span>
+<span class="hljs-meta">@Configuration</span>
+<span class="hljs-meta">@DubboComponentScan</span>(<span class="hljs-string">"com.alibaba.dubbo.demo.provider"</span>) <span class="hljs-comment">// 扫描 Dubbo 组件</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProviderConfiguration</span> </span>{
+
+    <span class="hljs-comment">/**
+     * 当前应用配置
+     */</span>
+    <span class="hljs-meta">@Bean</span>(<span class="hljs-string">"dubbo-annotation-provider"</span>)
+    <span class="hljs-function"><span class="hljs-keyword">public</span> ApplicationConfig <span class="hljs-title">applicationConfig</span><span class="hljs-params">()</span> </span>{
+        ApplicationConfig applicationConfig = <span class="hljs-keyword">new</span> ApplicationConfig();
+        applicationConfig.setName(<span class="hljs-string">"dubbo-annotation-provider"</span>);
+        <span class="hljs-keyword">return</span> applicationConfig;
+    }
+
+    <span class="hljs-comment">/**
+     * 当前连接注册中心配置
+     */</span>
+    <span class="hljs-meta">@Bean</span>(<span class="hljs-string">"my-registry"</span>)
+    <span class="hljs-function"><span class="hljs-keyword">public</span> RegistryConfig <span class="hljs-title">registryConfig</span><span class="hljs-params">()</span> </span>{
+        RegistryConfig registryConfig = <span class="hljs-keyword">new</span> RegistryConfig();
+        registryConfig.setAddress(<span class="hljs-string">"N/A"</span>);
+        <span class="hljs-keyword">return</span> registryConfig;
+    }
+
+    <span class="hljs-comment">/**
+     * 当前连接注册中心配置
+     */</span>
+    <span class="hljs-meta">@Bean</span>(<span class="hljs-string">"dubbo"</span>)
+    <span class="hljs-function"><span class="hljs-keyword">public</span> ProtocolConfig <span class="hljs-title">protocolConfig</span><span class="hljs-params">()</span> </span>{
+        ProtocolConfig protocolConfig = <span class="hljs-keyword">new</span> ProtocolConfig();
+        protocolConfig.setName(<span class="hljs-string">"dubbo"</span>);
+        protocolConfig.setPort(<span class="hljs-number">12345</span>);
+        <span class="hljs-keyword">return</span> protocolConfig;
+    }
+}
+</code></pre>
+<h6>服务提供方引导类</h6>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.dubbo.demo.bootstrap;
+
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.demo.DemoService;
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.demo.config.ProviderConfiguration;
+<span class="hljs-keyword">import</span> org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+<span class="hljs-comment">/**
+ * 服务提供方引导类
+ *
+ * <span class="hljs-doctag">@author</span> &lt;a href="mailto:mercyblitz@gmail.com"&gt;Mercy&lt;/a&gt;
+ */</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProviderBootstrap</span> </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">main</span><span class="hljs-params">(String[] args)</span> </span>{
+        <span class="hljs-comment">// 创建 Annotation 配置上下文</span>
+        AnnotationConfigApplicationContext context = <span class="hljs-keyword">new</span> AnnotationConfigApplicationContext();
+        <span class="hljs-comment">// 注册配置 Bean</span>
+        context.register(ProviderConfiguration<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        <span class="hljs-comment">// 启动上下文</span>
+        context.refresh();
+        <span class="hljs-comment">// 获取 DemoService Bean</span>
+        DemoService demoService = context.getBean(DemoService<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        <span class="hljs-comment">// 执行 sayHello 方法</span>
+        String message = demoService.sayHello(<span class="hljs-string">"World"</span>);
+        <span class="hljs-comment">// 控制台输出信息</span>
+        System.out.println(message);
+    }
+    
+}
+</code></pre>
+<p><code>ProviderBootstrap</code> 启动并执行后,控制输出与预期一致:</p>
+<pre><code>Hello , World
+</code></pre>
+<p>以上直接结果说明 <code>@DubboComponentScan(&quot;com.alibaba.dubbo.demo.provider&quot;)</code> 扫描后,标注 Dubbo <code>@Service</code> 的 <code>AnnotationDemoService</code> 被注册成 Spring Bean,可从 Spring ApplicationContext 自由获取。</p>
+<h5>服务消费方(<code>@Reference</code>)</h5>
+<h6>服务 <code>DemoService</code></h6>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.dubbo.demo.consumer;
+
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.config.annotation.Reference;
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.demo.DemoService;
+
+<span class="hljs-comment">/**
+ * Annotation 驱动 {<span class="hljs-doctag">@link</span> DemoService} 消费方
+ *
+ * <span class="hljs-doctag">@author</span> &lt;a href="mailto:mercyblitz@gmail.com"&gt;Mercy&lt;/a&gt;
+ */</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AnnotationDemoServiceConsumer</span> </span>{
+
+    <span class="hljs-meta">@Reference</span>(url = <span class="hljs-string">"dubbo://127.0.0.1:12345"</span>)
+    <span class="hljs-keyword">private</span> DemoService demoService;
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">doSayHell</span><span class="hljs-params">(String name)</span> </span>{
+        <span class="hljs-keyword">return</span> demoService.sayHello(name);
+    }
+}
+</code></pre>
+<h6>服务消费方 Annotation 配置</h6>
+<p>与服务提供方配置类似,服务消费方也许 Dubbo 相关配置 Bean - <code>ConsumerConfiguration</code></p>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.dubbo.demo.config;
+
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.config.ApplicationConfig;
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.config.RegistryConfig;
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.demo.consumer.AnnotationDemoServiceConsumer;
+<span class="hljs-keyword">import</span> org.springframework.context.annotation.Bean;
+<span class="hljs-keyword">import</span> org.springframework.context.annotation.Configuration;
+
+<span class="hljs-comment">/**
+ * 服务消费方配置
+ *
+ * <span class="hljs-doctag">@author</span> &lt;a href="mailto:mercyblitz@gmail.com"&gt;Mercy&lt;/a&gt;
+ */</span>
+<span class="hljs-meta">@Configuration</span>
+<span class="hljs-meta">@DubboComponentScan</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ConsumerConfiguration</span> </span>{
+
+    <span class="hljs-comment">/**
+     * 当前应用配置
+     */</span>
+    <span class="hljs-meta">@Bean</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> ApplicationConfig <span class="hljs-title">applicationConfig</span><span class="hljs-params">()</span> </span>{
+        ApplicationConfig applicationConfig = <span class="hljs-keyword">new</span> ApplicationConfig();
+        applicationConfig.setName(<span class="hljs-string">"dubbo-annotation-consumer"</span>);
+        <span class="hljs-keyword">return</span> applicationConfig;
+    }
+
+    <span class="hljs-comment">/**
+     * 当前连接注册中心配置
+     */</span>
+    <span class="hljs-meta">@Bean</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> RegistryConfig <span class="hljs-title">registryConfig</span><span class="hljs-params">()</span> </span>{
+        RegistryConfig registryConfig = <span class="hljs-keyword">new</span> RegistryConfig();
+        registryConfig.setAddress(<span class="hljs-string">"N/A"</span>);
+        <span class="hljs-keyword">return</span> registryConfig;
+    }
+
+    <span class="hljs-comment">/**
+     * 注册 AnnotationDemoServiceConsumer,<span class="hljs-doctag">@DubboComponentScan</span> 将处理其中 <span class="hljs-doctag">@Reference</span> 字段。
+     * 如果 AnnotationDemoServiceConsumer 非 Spring Bean 的话,
+     * 即使 <span class="hljs-doctag">@DubboComponentScan</span> 指定 package 也不会进行处理,与 Spring <span class="hljs-doctag">@Autowired</span> 同理
+     */</span>
+    <span class="hljs-meta">@Bean</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> AnnotationDemoServiceConsumer <span class="hljs-title">annotationDemoServiceConsumer</span><span class="hljs-params">()</span> </span>{
+        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> AnnotationDemoServiceConsumer();
+    }
+
+}
+</code></pre>
+<h6>服务消费方引导类</h6>
+<p>服务消费方需要先引导服务提供方,下面的实例将会启动两个 Spring 应用上下文,首先引导服务提供方 Spring 应用上下文,同时,需要复用前面Annotation 配置 <code>ProviderConfiguration</code>:</p>
+<pre><code class="language-java">    <span class="hljs-comment">/**
+     * 启动服务提供方上下文
+     */</span>
+    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">startProviderContext</span><span class="hljs-params">()</span> </span>{
+        <span class="hljs-comment">// 创建 Annotation 配置上下文</span>
+        AnnotationConfigApplicationContext providerContext = <span class="hljs-keyword">new</span> AnnotationConfigApplicationContext();
+        <span class="hljs-comment">// 注册配置 Bean</span>
+        providerContext.register(ProviderConfiguration<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        <span class="hljs-comment">// 启动服务提供方上下文</span>
+        providerContext.refresh();
+    }
+</code></pre>
+<p>然后引导服务消费方Spring 应用上下文:</p>
+<pre><code class="language-java">    <span class="hljs-comment">/**
+     * 启动并且返回服务消费方上下文
+     *
+     * <span class="hljs-doctag">@return</span> AnnotationConfigApplicationContext
+     */</span>
+    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> ApplicationContext <span class="hljs-title">startConsumerContext</span><span class="hljs-params">()</span> </span>{
+        <span class="hljs-comment">// 创建服务消费方 Annotation 配置上下文</span>
+        AnnotationConfigApplicationContext consumerContext = <span class="hljs-keyword">new</span> AnnotationConfigApplicationContext();
+        <span class="hljs-comment">// 注册服务消费方配置 Bean</span>
+        consumerContext.register(ConsumerConfiguration<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        <span class="hljs-comment">// 启动服务消费方上下文</span>
+        consumerContext.refresh();
+        <span class="hljs-comment">// 返回服务消费方 Annotation 配置上下文</span>
+        <span class="hljs-keyword">return</span> consumerContext;
+    }
+</code></pre>
+<p>完整的引导类实现:</p>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.dubbo.demo.bootstrap;
+
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.demo.config.ConsumerConfiguration;
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.demo.config.ProviderConfiguration;
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.demo.consumer.AnnotationDemoServiceConsumer;
+<span class="hljs-keyword">import</span> org.springframework.context.ApplicationContext;
+<span class="hljs-keyword">import</span> org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+<span class="hljs-comment">/**
+ * 服务消费端引导类
+ *
+ * <span class="hljs-doctag">@author</span> &lt;a href="mailto:mercyblitz@gmail.com"&gt;Mercy&lt;/a&gt;
+ */</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ConsumerBootstrap</span> </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">main</span><span class="hljs-params">(String[] args)</span> </span>{
+        <span class="hljs-comment">// 启动服务提供方上下文</span>
+        startProviderContext();
+        <span class="hljs-comment">// 启动并且返回服务消费方上下文</span>
+        ApplicationContext consumerContext = startConsumerContext();
+        <span class="hljs-comment">// 获取 AnnotationDemoServiceConsumer Bean</span>
+        AnnotationDemoServiceConsumer consumer = consumerContext.getBean(AnnotationDemoServiceConsumer<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        <span class="hljs-comment">// 执行 doSayHello 方法</span>
+        String message = consumer.doSayHello(<span class="hljs-string">"World"</span>);
+        <span class="hljs-comment">// 输出执行结果</span>
+        System.out.println(message);
+    }
+
+    <span class="hljs-comment">/**
+     * 启动并且返回服务消费方上下文
+     *
+     * <span class="hljs-doctag">@return</span> AnnotationConfigApplicationContext
+     */</span>
+    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> ApplicationContext <span class="hljs-title">startConsumerContext</span><span class="hljs-params">()</span> </span>{
+        <span class="hljs-comment">// 创建服务消费方 Annotation 配置上下文</span>
+        AnnotationConfigApplicationContext consumerContext = <span class="hljs-keyword">new</span> AnnotationConfigApplicationContext();
+        <span class="hljs-comment">// 注册服务消费方配置 Bean</span>
+        consumerContext.register(ConsumerConfiguration<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        <span class="hljs-comment">// 启动服务消费方上下文</span>
+        consumerContext.refresh();
+        <span class="hljs-comment">// 返回服务消费方 Annotation 配置上下文</span>
+        <span class="hljs-keyword">return</span> consumerContext;
+    }
+
+    <span class="hljs-comment">/**
+     * 启动服务提供方上下文
+     */</span>
+    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">startProviderContext</span><span class="hljs-params">()</span> </span>{
+        <span class="hljs-comment">// 创建 Annotation 配置上下文</span>
+        AnnotationConfigApplicationContext providerContext = <span class="hljs-keyword">new</span> AnnotationConfigApplicationContext();
+        <span class="hljs-comment">// 注册配置 Bean</span>
+        providerContext.register(ProviderConfiguration<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        <span class="hljs-comment">// 启动服务提供方上下文</span>
+        providerContext.refresh();
+    }
+
+}
+</code></pre>
+<p>运行<code>ConsumerBootstrap</code>结果,仍然符合期望,<code>AnnotationDemoServiceConsumer</code> 输出:</p>
+<pre><code>Hello , World
+</code></pre>
+<h4>Spring AOP 支持</h4>
+<p>前面提到 <code>&lt;dubbo:annotation&gt;</code>  注册 Dubbo <code>@Service</code> 组件后,在 Spring AOP 支持方面存在问题。事务作为 Spring AOP 的功能扩展,自然也会在 <code>&lt;dubbo:annotation&gt;</code>中不支持。</p>
+<p><code>@DubboComponentScan</code> 针对以上问题,实现了对 Spring AOP 是完全兼容。将上述服务提供方 Annotation 配置做出一定的调整,标注<code>@EnableTransactionManagement</code> 以及自定义实现<code>PlatformTransactionManager</code> :</p>
+<pre><code class="language-java"><span class="hljs-meta">@Configuration</span>
+<span class="hljs-meta">@DubboComponentScan</span>(<span class="hljs-string">"com.alibaba.dubbo.demo.provider"</span>) <span class="hljs-comment">// 扫描 Dubbo 组件</span>
+<span class="hljs-meta">@EnableTransactionManagement</span> <span class="hljs-comment">// 激活事务管理</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProviderConfiguration</span> </span>{
+  <span class="hljs-comment">// 省略其他配置 Bean 定义</span>
+  
+    <span class="hljs-comment">/**
+     * 自定义事务管理器
+     */</span>
+    <span class="hljs-meta">@Bean</span>
+    <span class="hljs-meta">@Primary</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> PlatformTransactionManager <span class="hljs-title">transactionManager</span><span class="hljs-params">()</span> </span>{
+        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> PlatformTransactionManager() {
+
+            <span class="hljs-meta">@Override</span>
+            <span class="hljs-function"><span class="hljs-keyword">public</span> TransactionStatus <span class="hljs-title">getTransaction</span><span class="hljs-params">(TransactionDefinition definition)</span> <span class="hljs-keyword">throws</span> TransactionException </span>{
+                System.out.println(<span class="hljs-string">"get transaction ..."</span>);
+                <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> SimpleTransactionStatus();
+            }
+
+            <span class="hljs-meta">@Override</span>
+            <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">commit</span><span class="hljs-params">(TransactionStatus status)</span> <span class="hljs-keyword">throws</span> TransactionException </span>{
+                System.out.println(<span class="hljs-string">"commit transaction ..."</span>);
+            }
+
+            <span class="hljs-meta">@Override</span>
+            <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">rollback</span><span class="hljs-params">(TransactionStatus status)</span> <span class="hljs-keyword">throws</span> TransactionException </span>{
+                System.out.println(<span class="hljs-string">"rollback transaction ..."</span>);
+            }
+        };
+    }
+}
+</code></pre>
+<p>同时调整 <code>AnnotationDemoService</code>  - 增加<code>@Transactional</code> 注解:</p>
+<pre><code class="language-java"><span class="hljs-meta">@Service</span>
+<span class="hljs-meta">@Transactional</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AnnotationDemoService</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">DemoService</span> </span>{
+	<span class="hljs-comment">// 省略实现,保持不变</span>
+}
+</code></pre>
+<p>再次运行<code>ConsumerBootstrap</code> , 观察控制台输出内容:</p>
+<pre><code>get transaction ...
+commit transaction ...
+Hello , World
+</code></pre>
+<p>输入内容中多处了两行,说明自定义 <code>PlatformTransactionManager</code> <code>getTransaction(TransactionDefinition)</code> 以及 <code>commit(TransactionStatus)</code> 方法被执行,进而说明 <code>AnnotationDemoService</code> 的<code>sayHello(String)</code> 方法执行时,事务也伴随执行。</p>
+<h4>注意事项</h4>
+<p><code>ConsumerConfiguration</code> 上的  <code>@DubboComponentScan</code> 并没有指定 <code>basePackages</code> 扫描,这种情况会将<code>ConsumerConfiguration</code>  当做 <code>basePackageClasses</code> ,即扫描<code>ConsumerConfiguration</code> 所属的 package  <code>com.alibaba.dubbo.demo.config</code> 以及子 package。由于当前示例中,不存在标注 Dubbo <code>@Service</code>的类,因此在运行时日志(如果开启的话)会输出警告信息:</p>
+<pre><code>WARN :  [DUBBO] No Spring Bean annotating Dubbo's @Service was found in Spring BeanFactory, dubbo version: 2.0.0, current host: 127.0.0.1
+</code></pre>
+<p>以上信息大可不必担忧,因为 <code>@DubboComponentScan</code>  除了扫描 Dubbo <code>@Service</code> 组件以外,还将处理 <code>@Reference</code>字段注入。然而读者特别关注<code>@Reference</code>字段注入的规则。</p>
+<p>以上实现为例,<code>AnnotationDemoServiceConsumer</code> 必须申明为 Spring  <code>@Bean</code> 或者 <code>@Component</code>(或者其派生注解),否则 <code>@DubboComponentScan</code> 不会主动将标注 <code>@Reference</code>字段所在的声明类提成为 Spring Bean,换句话说,如果 <code>@Reference</code>字段所在的声明类不是 Spring Bean 的话, <code>@DubboComponentScan</code> 不会处理<code>@Reference</code>注入,其原理与 Spring <code>@Autowired</code> 一致。</p>
+<p>以上使用不当可能会导致相关问题,如 GitHub 上曾有小伙伴提问:<a href="https://github.com/alibaba/dubbo/issues/825">https://github.com/alibaba/dubbo/issues/825</a></p>
+<blockquote>
+<p><strong>li362692680</strong> 提问:</p>
+<blockquote>
+<p>@DubboComponentScan注解在消费端扫描包时扫描的是 @Service注解??不是@Reference注解??
+启动时报
+DubboComponentScanRegistrar-85]-[main]-[INFO] 0 annotated @Service Components { [] }</p>
+</blockquote>
+<p>笔者(<strong>mercyblitz</strong>)回复:</p>
+<blockquote>
+<p><code>@Reference</code> 类似于 <code>@Autowired</code> 一样,首先其申明的类必须被 Spring 上下文当做一个Bean,因此,Dubbo 并没有直接将 <code>@Reference</code>  字段所在的类提升成 Bean。</p>
+<p>综上所述,这并不是一个问题,而是用法不当!</p>
+</blockquote>
+</blockquote>
+<h4>已知问题</h4>
+<p>最新发布的 Dubbo <code>2.5.8</code> 中,<code>@DubboComponentScan</code>  在以下特殊场景下存在 Spring <code>@Service</code> 不兼容情况:</p>
+<blockquote>
+<p>假设有两个服务实现类 <code>A</code> 和 <code>B</code>,同时存放在<code>com.acme</code> 包下:</p>
+<ul>
+<li><code>A</code> 标注  Dubbo <code>@Service</code></li>
+<li><code>B</code> 标注  Dubbo <code>@Service</code> 和 Spring <code>@Service</code></li>
+</ul>
+<p>当 Spring <code>@ComponentScan</code> 先扫描<code>com.acme</code> 包时,<code>B</code> 被当做 Spring Bean 的候选类。随后,<code>@DubboComponentScan</code> 也扫描相同的包。当应用启动时,<code>A</code> 和 <code>B</code>  虽然都是  Spring Bean,可仅 <code>A</code> 能够暴露 Dubbo 服务,<code>B</code> 则丢失。</p>
+</blockquote>
+<p>问题版本:<code>2.5.7</code>、<code>2.5.8</code></p>
+<p>问题详情:<a href="https://github.com/alibaba/dubbo/issues/1120">https://github.com/alibaba/dubbo/issues/1120</a></p>
+<p>修复版本:<code>2.5.9</code>(下个版本)</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-annotation-driven.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-annotation-driven.json
new file mode 100644
index 0000000..fb5694d
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-annotation-driven.json
@@ -0,0 +1,6 @@
+{
+  "filename": "dubbo-annotation-driven.md",
+  "__html": "<h1>Dubbo 注解驱动(Annotation-Driven)</h1>\n<h2>注解驱动(Annotation-Driven)</h2>\n<h3><code>@DubboComponentScan</code></h3>\n<h4>起始版本: <code>2.5.7</code></h4>\n<h4><code>&lt;dubbo:annotation&gt;</code>历史遗留问题</h4>\n<h5>1. 注解支持不充分</h5>\n<p>在 Dubbo  <code>2.5.7</code>之前的版本 ,Dubbo 提供了两个核心注解 <code>@Service</code> 以及 <code>@Reference</code>,分别用于Dubbo 服务提供和 Dubbo 服务引用。</p>\n<p>其中,<code>@Service</code> 作为 XML 元素 <code>&lt;dubbo:service&gt;</code>的替代注解,与 Spring Framework <code>@org.springfra [...]
+  "link": "/zh-cn/blog/dubbo-annotation-driven.html",
+  "meta": {}
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-annotation.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-annotation.html
new file mode 100644
index 0000000..47ef246
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-annotation.html
@@ -0,0 +1,356 @@
+<!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="Dubbo, Annotation, Spring" />
+	<meta name="description" content="介绍了如何使用注解方式而非 XML 方式来开发 Dubbo 应用,可以学习到如何使用 @EnableDubbo、@Service、@Reference 的用法。" />
+	<!-- 网页标签标题 -->
+	<title>在 Dubbo 中使用注解</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>随着微服务架构的广泛地推广和实施。在 Java 生态系统中,以 Spring Boot 和 Spring Cloud 为代表的微服务框架,引入了全新的编程模型,包括:</p>
+<ul>
+<li>注解驱动(Annotation-Driven)</li>
+<li>外部化配置(External Configuration)</li>
+<li>以及自动装配(Auto-Configure)</li>
+</ul>
+<p>新的编程模型无需 XML 配置、简化部署、提升开发效率。为了更好地实践微服务架构,Dubbo 从 <code>2.5.8</code> 版本开始, 分别针对了上述的三个场景,提供了更完善的支持。本文不讨论传统的 XML 配置方式,而是侧重介绍注解这种方式。外部配置、自动装配两种自动装配会在另外的文章中专门介绍。</p>
+<h2>注解介绍</h2>
+<h3>@EnableDubbo</h3>
+<p><code>@EnableDubbo</code> 注解是 <code>@EnableDubboConfig</code> 和 <code>@DubboComponentScan</code>两者组合的便捷表达方式。与注解驱动相关的是 <code>@DubboComponentScan</code>。</p>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> org.apache.dubbo.config.spring.context.annotation;
+
+<span class="hljs-meta">@EnableDubboConfig</span>
+<span class="hljs-meta">@DubboComponentScan</span>
+<span class="hljs-keyword">public</span> <span class="hljs-meta">@interface</span> EnableDubbo {
+    <span class="hljs-comment">/**
+     * Base packages to scan for annotated <span class="hljs-doctag">@Service</span> classes.
+     * &lt;p&gt;
+     * Use {<span class="hljs-doctag">@link</span> #scanBasePackageClasses()} for a type-safe alternative to String-based
+     * package names.
+     *
+     * <span class="hljs-doctag">@return</span> the base packages to scan
+     * <span class="hljs-doctag">@see</span> DubboComponentScan#basePackages()
+     */</span>
+    <span class="hljs-meta">@AliasFor</span>(annotation = DubboComponentScan<span class="hljs-class">.<span class="hljs-keyword">class</span>, <span class="hljs-title">attribute</span> </span>= <span class="hljs-string">"basePackages"</span>)
+    String[] scanBasePackages() <span class="hljs-keyword">default</span> {};
+
+    <span class="hljs-comment">/**
+     * Type-safe alternative to {<span class="hljs-doctag">@link</span> #scanBasePackages()} for specifying the packages to
+     * scan for annotated <span class="hljs-doctag">@Service</span> classes. The package of each class specified will be
+     * scanned.
+     *
+     * <span class="hljs-doctag">@return</span> classes from the base packages to scan
+     * <span class="hljs-doctag">@see</span> DubboComponentScan#basePackageClasses
+     */</span>
+    <span class="hljs-meta">@AliasFor</span>(annotation = DubboComponentScan<span class="hljs-class">.<span class="hljs-keyword">class</span>, <span class="hljs-title">attribute</span> </span>= <span class="hljs-string">"basePackageClasses"</span>)
+    Class&lt;?&gt;[] scanBasePackageClasses() <span class="hljs-keyword">default</span> {};    
+}
+</code></pre>
+<p>通过 <code>@EnableDubbo</code> 可以在指定的包名下(通过 <code>scanBasePackages</code>),或者指定的类中(通过 <code>scanBasePackageClasses</code>)扫描 Dubbo 的服务提供者(以 <code>@Service</code> 标注)以及 Dubbo 的服务消费者(以 <code>Reference</code> 标注)。</p>
+<p>扫描到 Dubbo 的服务提供方和消费者之后,对其做相应的组装并初始化,并最终完成服务暴露或者引用的工作。</p>
+<p>当然,如果不使用外部化配置(External Configuration)的话,也可以直接使用 <code>@DubboComponentScan</code>。</p>
+<h3>@Service</h3>
+<p><code>@Service</code> 用来配置 Dubbo 的服务提供方,比如:</p>
+<pre><code class="language-java"><span class="hljs-meta">@Service</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AnnotatedGreetingService</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">GreetingService</span> </span>{
+    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">sayHello</span><span class="hljs-params">(String name)</span> </span>{
+        <span class="hljs-keyword">return</span> <span class="hljs-string">"hello, "</span> + name;
+    }
+}
+</code></pre>
+<p>通过 <code>@Service</code> 上提供的属性,可以进一步的定制化 Dubbo 的服务提供方:</p>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> org.apache.dubbo.config.annotation;
+
+<span class="hljs-meta">@Documented</span>
+<span class="hljs-meta">@Retention</span>(RetentionPolicy.RUNTIME)
+<span class="hljs-meta">@Target</span>({ElementType.TYPE}) <span class="hljs-comment">// #1</span>
+<span class="hljs-meta">@Inherited</span>
+<span class="hljs-keyword">public</span> <span class="hljs-meta">@interface</span> Service {
+    Class&lt;?&gt; interfaceClass() <span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span><span class="hljs-class">.<span class="hljs-keyword">class</span></span>; <span class="hljs-comment">// #2</span>
+    <span class="hljs-function">String <span class="hljs-title">interfaceName</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #3</span>
+    <span class="hljs-function">String <span class="hljs-title">version</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #4</span>
+    <span class="hljs-function">String <span class="hljs-title">group</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #5</span>
+    <span class="hljs-function"><span class="hljs-keyword">boolean</span> <span class="hljs-title">export</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">true</span></span>; <span class="hljs-comment">// #6</span>
+    <span class="hljs-function"><span class="hljs-keyword">boolean</span> <span class="hljs-title">register</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">true</span></span>; <span class="hljs-comment">// #7</span>
+    
+    <span class="hljs-function">String <span class="hljs-title">application</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #8</span>
+    <span class="hljs-function">String <span class="hljs-title">module</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #9</span>
+    <span class="hljs-function">String <span class="hljs-title">provider</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #10</span>
+    String[] protocol() <span class="hljs-keyword">default</span> {}; <span class="hljs-comment">// #11</span>
+    <span class="hljs-function">String <span class="hljs-title">monitor</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #12</span>
+    String[] registry() <span class="hljs-keyword">default</span> {}; <span class="hljs-comment">// #13</span>
+}
+</code></pre>
+<p>其中比较重要的有:</p>
+<ol>
+<li>@Service 只能定义在一个类上,表示一个服务的具体实现</li>
+<li>interfaceClass:指定服务提供方实现的 interface 的类</li>
+<li>interfaceName:指定服务提供方实现的 interface 的类名</li>
+<li>version:指定服务的版本号</li>
+<li>group:指定服务的分组</li>
+<li>export:是否暴露服务</li>
+<li>registry:是否向注册中心注册服务</li>
+<li>application:应用配置</li>
+<li>module:模块配置</li>
+<li>provider:服务提供方配置</li>
+<li>protocol:协议配置</li>
+<li>monitor:监控中心配置</li>
+<li>registry:注册中心配置</li>
+</ol>
+<p>另外,需要注意的是,application、module、provider、protocol、monitor、registry(从 8 到 13)需要提供的是对应的 spring bean 的名字,而这些 bean 的组装要么通过传统的 XML 配置方式完成,要么通过现代的 Java Config 来完成。在本文中,将会展示 Java Config 的使用方式。</p>
+<h3>@Reference</h3>
+<p><code>@Reference</code> 用来配置 Dubbo 的服务消费方,比如:</p>
+<pre><code class="language-java"><span class="hljs-meta">@Component</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GreetingServiceConsumer</span> </span>{
+    <span class="hljs-meta">@Reference</span>
+    <span class="hljs-keyword">private</span> GreetingService greetingService;
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">doSayHello</span><span class="hljs-params">(String name)</span> </span>{
+        <span class="hljs-keyword">return</span> greetingService.sayHello(name);
+    }
+}
+</code></pre>
+<p>通过 <code>@Reference</code> 上提供的属性,可以进一步的定制化 Dubbo 的服务消费方:</p>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> org.apache.dubbo.config.annotation;
+
+<span class="hljs-meta">@Documented</span>
+<span class="hljs-meta">@Retention</span>(RetentionPolicy.RUNTIME)
+<span class="hljs-meta">@Target</span>({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) <span class="hljs-comment">// #1</span>
+<span class="hljs-keyword">public</span> <span class="hljs-meta">@interface</span> Reference {
+    Class&lt;?&gt; interfaceClass() <span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span><span class="hljs-class">.<span class="hljs-keyword">class</span></span>; <span class="hljs-comment">// #2</span>
+    <span class="hljs-function">String <span class="hljs-title">interfaceName</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #3</span>
+    <span class="hljs-function">String <span class="hljs-title">version</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #4</span>
+    <span class="hljs-function">String <span class="hljs-title">group</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #5</span>
+    <span class="hljs-function">String <span class="hljs-title">url</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #6</span>
+    
+    <span class="hljs-function">String <span class="hljs-title">application</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #7</span>
+    <span class="hljs-function">String <span class="hljs-title">module</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #8</span>
+    <span class="hljs-function">String <span class="hljs-title">consumer</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #9</span>
+    <span class="hljs-function">String <span class="hljs-title">protocol</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #10</span>
+    <span class="hljs-function">String <span class="hljs-title">monitor</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> ""</span>; <span class="hljs-comment">// #11</span>
+    String[] registry() <span class="hljs-keyword">default</span> {}; <span class="hljs-comment">// #12</span>
+}
+</code></pre>
+<p>其中比较重要的有:</p>
+<ol>
+<li>@Reference 可以定义在类中的一个字段上,也可以定义在一个方法上,甚至可以用来修饰另一个 annotation,表示一个服务的引用。通常 @Reference 定义在一个字段上</li>
+<li>interfaceClass:指定服务的 interface 的类</li>
+<li>interfaceName:指定服务的 interface 的类名</li>
+<li>version:指定服务的版本号</li>
+<li>group:指定服务的分组</li>
+<li>url:通过指定服务提供方的 URL 地址直接绕过注册中心发起调用</li>
+<li>application:应用配置</li>
+<li>module:模块配置</li>
+<li>consumer:服务消费方配置</li>
+<li>protocol:协议配置</li>
+<li>monitor:监控中心配置</li>
+<li>registry:注册中心配置</li>
+</ol>
+<p>另外,需要注意的是,application、module、consumer、protocol、monitor、registry(从 7 到 12)需要提供的是对应的 spring bean 的名字,而这些 bean 的组装要么通过传统的 XML 配置方式完成,要么通过现代的 Java Config 来完成。在本文中,将会展示 Java Config 的使用方式。</p>
+<h2>示例实战</h2>
+<p>了解了 <code>@EnableDubbo</code>, <code>@Service</code>,<code>@Reference</code> 的作用,下面以一个实际的例子来展示如何使用 annotation 来开发 Dubbo 应用。以下的代码可以在 <a href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-annotation">https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-annotation</a> 中找到。</p>
+<h3>1. 接口定义</h3>
+<p>定义一个简单的 <code>GreetingService</code> 接口,里面只有一个简单的方法 <code>sayHello</code> 向调用者问好。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">GreetingService</span> </span>{
+    <span class="hljs-function">String <span class="hljs-title">sayHello</span><span class="hljs-params">(String name)</span></span>;
+}
+</code></pre>
+<h3>2. 服务端:服务实现</h3>
+<p>实现 <code>GreetingService</code> 接口,并通过 <code>@Service</code> 来标注其为 Dubbo 的一个服务。</p>
+<pre><code class="language-java"><span class="hljs-meta">@Service</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AnnotatedGreetingService</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">GreetingService</span> </span>{
+    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">sayHello</span><span class="hljs-params">(String name)</span> </span>{
+        <span class="hljs-keyword">return</span> <span class="hljs-string">"hello, "</span> + name;
+    }
+}
+</code></pre>
+<h3>3. 服务端:组装服务提供方</h3>
+<p>通过 Spring 中 Java Config 的技术(<code>@Configuration</code>)和 annotation 扫描(<code>@EnableDubbo</code>)来发现、组装、并向外提供 Dubbo 的服务。</p>
+<pre><code class="language-java"><span class="hljs-meta">@Configuration</span>
+<span class="hljs-meta">@EnableDubbo</span>(scanBasePackages = <span class="hljs-string">"com.alibaba.dubbo.samples.impl"</span>)
+<span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProviderConfiguration</span> </span>{
+    <span class="hljs-meta">@Bean</span> <span class="hljs-comment">// #1</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> ProviderConfig <span class="hljs-title">providerConfig</span><span class="hljs-params">()</span> </span>{
+        ProviderConfig providerConfig = <span class="hljs-keyword">new</span> ProviderConfig();
+        providerConfig.setTimeout(<span class="hljs-number">1000</span>);
+        <span class="hljs-keyword">return</span> providerConfig;
+    }
+
+    <span class="hljs-meta">@Bean</span> <span class="hljs-comment">// #2</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> ApplicationConfig <span class="hljs-title">applicationConfig</span><span class="hljs-params">()</span> </span>{
+        ApplicationConfig applicationConfig = <span class="hljs-keyword">new</span> ApplicationConfig();
+        applicationConfig.setName(<span class="hljs-string">"dubbo-annotation-provider"</span>);
+        <span class="hljs-keyword">return</span> applicationConfig;
+    }
+
+    <span class="hljs-meta">@Bean</span> <span class="hljs-comment">// #3</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> RegistryConfig <span class="hljs-title">registryConfig</span><span class="hljs-params">()</span> </span>{
+        RegistryConfig registryConfig = <span class="hljs-keyword">new</span> RegistryConfig();
+        registryConfig.setProtocol(<span class="hljs-string">"zookeeper"</span>);
+        registryConfig.setAddress(<span class="hljs-string">"localhost"</span>);
+        registryConfig.setPort(<span class="hljs-number">2181</span>);
+        <span class="hljs-keyword">return</span> registryConfig;
+    }
+
+    <span class="hljs-meta">@Bean</span> <span class="hljs-comment">// #4</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> ProtocolConfig <span class="hljs-title">protocolConfig</span><span class="hljs-params">()</span> </span>{
+        ProtocolConfig protocolConfig = <span class="hljs-keyword">new</span> ProtocolConfig();
+        protocolConfig.setName(<span class="hljs-string">"dubbo"</span>);
+        protocolConfig.setPort(<span class="hljs-number">20880</span>);
+        <span class="hljs-keyword">return</span> protocolConfig;
+    }
+}
+</code></pre>
+<p>说明:</p>
+<ul>
+<li>
+<p>通过 <code>@EnableDubbo</code> 指定在 <code>com.alibaba.dubbo.samples.impl</code> 下扫描所有标注有 <code>@Service</code> 的类</p>
+</li>
+<li>
+<p>通过 <code>@Configuration</code> 将 ProviderConfiguration 中所有的 <code>@Bean</code> 通过 Java Config 的方式组装出来并注入给 Dubbo 服务,也就是标注有 <code>@Service</code> 的类。这其中就包括了:</p>
+<ol>
+<li>ProviderConfig:服务提供方配置</li>
+<li>ApplicationConfig:应用配置</li>
+<li>RegistryConfig:注册中心配置</li>
+<li>ProtocolConfig:协议配置</li>
+</ol>
+</li>
+</ul>
+<h3>4. 服务端:启动服务</h3>
+<p>在 <code>main</code> 方法中通过启动一个 Spring Context 来对外提供 Dubbo 服务。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProviderBootstrap</span> </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">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception </span>{
+        <span class="hljs-keyword">new</span> EmbeddedZooKeeper(<span class="hljs-number">2181</span>, <span class="hljs-keyword">false</span>).start(); <span class="hljs-comment">// #1</span>
+        AnnotationConfigApplicationContext context = <span class="hljs-keyword">new</span> AnnotationConfigApplicationContext(ProviderConfiguration<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>; <span class="hljs-comment">// #2</span>
+        context.start(); <span class="hljs-comment">// #3</span>
+        System.in.read(); <span class="hljs-comment">// #4</span>
+    }
+}
+</code></pre>
+<p>说明:</p>
+<ol>
+<li>启动一个嵌入式的 zookeeper 在 2181 端口上提供注册中心的服务</li>
+<li>初始化一个 <code>AnnotationConfigApplicationContext</code> 的示例,并将 <code>ProviderConfiguration</code> 传入以完成 Dubbo 服务的自动发现和装配</li>
+<li>启动 Spring Context,开始提供对外的 Dubbo 服务</li>
+<li>因为是服务端,需要通过阻塞主线程来防止进程退出</li>
+</ol>
+<p>启动服务端的 <code>main</code> 方法,将会看到下面的输出,代表服务端启动成功,并在注册中心(ZookeeperRegistry)上注册了 <code>GreetingService</code> 这个服务:</p>
+<pre><code class="language-sh">[01/08/18 02:12:51:051 CST] main  INFO transport.AbstractServer:  [DUBBO] Start NettyServer <span class="hljs-built_in">bind</span> /0.0.0.0:20880, <span class="hljs-built_in">export</span> /192.168.99.1:20880, dubbo version: 2.6.2, current host: 192.168.99.1
+
+[01/08/18 02:12:51:051 CST] main  INFO zookeeper.ZookeeperRegistry:  [DUBBO] Register: dubbo://192.168.99.1:20880/com.alibaba.dubbo.samples.api.GreetingService?anyhost=<span class="hljs-literal">true</span>&amp;application=dubbo-annotation-provider&amp;default.timeout=1000&amp;dubbo=2.6.2&amp;generic=<span class="hljs-literal">false</span>&amp;interface=com.alibaba.dubbo.samples.api
+</code></pre>
+<h3>5. 客户端:引用服务</h3>
+<p>通过 <code>@Reference</code> 来标记 <code>GreetingService</code> 接口的成员变量 greetingService 是一个 Dubbo 服务的引用,也就是说,可以简单的通过该接口向远端的服务提供方发起调用,而客户端并没有实现 <code>GreetingService</code> 接口。</p>
+<pre><code class="language-java"><span class="hljs-meta">@Component</span>(<span class="hljs-string">"annotatedConsumer"</span>)
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GreetingServiceConsumer</span> </span>{
+    <span class="hljs-meta">@Reference</span>
+    <span class="hljs-keyword">private</span> GreetingService greetingService;
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">doSayHello</span><span class="hljs-params">(String name)</span> </span>{
+        <span class="hljs-keyword">return</span> greetingService.sayHello(name);
+    }
+}
+</code></pre>
+<h3>6. 客户端:组装服务消费者</h3>
+<p>与 <strong>3. 服务端:组装服务提供方</strong> 类似,通过 Spring 中 Java Config 的技术(<code>@Configuration</code>)和 annotation 扫描(<code>@EnableDubbo</code>)来发现、组装 Dubbo 服务的消费者。</p>
+<pre><code class="language-java"><span class="hljs-meta">@Configuration</span>
+<span class="hljs-meta">@EnableDubbo</span>(scanBasePackages = <span class="hljs-string">"com.alibaba.dubbo.samples.action"</span>)
+<span class="hljs-meta">@ComponentScan</span>(value = {<span class="hljs-string">"com.alibaba.dubbo.samples.action"</span>})
+<span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ConsumerConfiguration</span> </span>{
+    <span class="hljs-meta">@Bean</span> <span class="hljs-comment">// #1</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> ApplicationConfig <span class="hljs-title">applicationConfig</span><span class="hljs-params">()</span> </span>{
+        ApplicationConfig applicationConfig = <span class="hljs-keyword">new</span> ApplicationConfig();
+        applicationConfig.setName(<span class="hljs-string">"dubbo-annotation-consumer"</span>);
+        <span class="hljs-keyword">return</span> applicationConfig;
+    }
+
+    <span class="hljs-meta">@Bean</span> <span class="hljs-comment">// #2</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> ConsumerConfig <span class="hljs-title">consumerConfig</span><span class="hljs-params">()</span> </span>{
+        ConsumerConfig consumerConfig = <span class="hljs-keyword">new</span> ConsumerConfig();
+        consumerConfig.setTimeout(<span class="hljs-number">3000</span>);
+        <span class="hljs-keyword">return</span> consumerConfig;
+    }
+
+    <span class="hljs-meta">@Bean</span> <span class="hljs-comment">// #3</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> RegistryConfig <span class="hljs-title">registryConfig</span><span class="hljs-params">()</span> </span>{
+        RegistryConfig registryConfig = <span class="hljs-keyword">new</span> RegistryConfig();
+        registryConfig.setProtocol(<span class="hljs-string">"zookeeper"</span>);
+        registryConfig.setAddress(<span class="hljs-string">"localhost"</span>);
+        registryConfig.setPort(<span class="hljs-number">2181</span>);
+        <span class="hljs-keyword">return</span> registryConfig;
+    }
+}
+</code></pre>
+<p>说明:</p>
+<ul>
+<li>通过 <code>@EnableDubbo</code> 指定在 <code>com.alibaba.dubbo.samples.impl</code> 下扫描所有标注有 `@Reference 的类</li>
+<li>通过 <code>@Configuration</code> 将 ConsumerConfiguration 中所有的 <code>@Bean</code> 通过 Java Config 的方式组装出来并注入给 Dubbo 服务消费者,也就是标注有 `@Reference 的类。这其中就包括了:
+<ol>
+<li>ApplicationConfig:应用配置</li>
+<li>ConsumerConfig:服务消费者配置</li>
+<li>RegistryConfig:注册中心配置,注意:这里的配置需要与服务提供方启动的 EmbeddedZooKeeper 的配置信息保持一致</li>
+</ol>
+</li>
+</ul>
+<h3>7. 客户端:发起远程调用</h3>
+<p>在 <code>main</code> 方法中通过启动一个 Spring Context,从其中查找到组装好的 Dubbo 的服务消费者,并发起一次远程调用。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ConsumerBootstrap</span> </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">main</span><span class="hljs-params">(String[] args)</span> </span>{
+        AnnotationConfigApplicationContext context = <span class="hljs-keyword">new</span> AnnotationConfigApplicationContext(ConsumerConfiguration<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>; <span class="hljs-comment">// #1</span>
+        context.start(); <span class="hljs-comment">// #2</span>
+        GreetingServiceConsumer greetingServiceConsumer = context.getBean(GreetingServiceConsumer<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>; <span class="hljs-comment">// #3</span>
+        String hello = greetingServiceConsumer.doSayHello(<span class="hljs-string">"annotation"</span>); <span class="hljs-comment">// #4</span>
+        System.out.println(<span class="hljs-string">"result: "</span> + hello); <span class="hljs-comment">// #5</span>
+    }
+}
+</code></pre>
+<p>说明:</p>
+<ol>
+<li>
+<p>初始化一个 <code>AnnotationConfigApplicationContext</code> 的示例,并将 <code>ConsumerConfiguration</code> 传入以完成 Dubbo 服务消费者的自动发现和装配</p>
+</li>
+<li>
+<p>启动 Spring Context</p>
+</li>
+<li>
+<p>从 Context 中查找出类型为 <code>GreetingServiceConsumer</code> 的 Bean</p>
+</li>
+<li>
+<p>调用 <code>doSayHello</code> 方法,最终通过 Dubbo 的服务引用(由 <code>@Reference</code> 标注)发起一次远程调用</p>
+</li>
+<li>
+<p>打印调用结果</p>
+</li>
+</ol>
+<p>启动客户端的 <code>main</code> 方法,将会看到下面的输出,其中返回结果为 result: hello, annotation:</p>
+<pre><code class="language-sh">[01/08/18 02:38:40:040 CST] main  INFO config.AbstractConfig:  [DUBBO] Refer dubbo service com.alibaba.dubbo.samples.api.GreetingService from url zookeeper://localhost:2181/com.alibaba.dubbo.registry.RegistryService?anyhost=<span class="hljs-literal">true</span>&amp;application=dubbo-annotation-consumer&amp;check=<span class="hljs-literal">false</span>&amp;default.timeout=3000&amp;dubbo=2.6.2&amp;generic=<span class="hljs-literal">false</span>&amp;interface [...]
+[01/08/18 02:38:40:040 CST] main  INFO annotation.ReferenceBeanBuilder: &lt;dubbo:reference object=<span class="hljs-string">"com.alibaba.dubbo.common.bytecode.proxy0@673be18f"</span> singleton=<span class="hljs-string">"true"</span> interface=<span class="hljs-string">"com.alibaba.dubbo.samples.api.GreetingService"</span> uniqueServiceName=<span class="hljs-string">"com.alibaba.dubbo.samples.api.GreetingService"</span> generic=<span class="hljs-string">"false"</span> id=<span class="hlj [...]
+result: hello, annotation
+</code></pre>
+<h2>总结</h2>
+<p>通过本文的学习,读者可以掌握 Dubbo 专属的 annotation <code>@EnableDubbo</code>、<code>@Service</code>、<code>@Reference</code> 的基本概念,并通过一个简单 Dubbo 应用的实战开发掌握其基本的用法。</p>
+<p>Spring 除了传统的 XML 配置之外,还提供了注解驱动、外部化配置、以及自动装配等更现代的配置方式。本文专注在介绍通过注解方式来开发 Dubbo 应用,可以看到,与 XML 配置相比,注解方式编程更加简洁明快。在今后的博文中,会进一步的介绍在 Dubbo 中使用外部化配置、以及自动装配的方法。</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-annotation.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-annotation.json
new file mode 100644
index 0000000..c584649
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-annotation.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-annotation.md",
+  "__html": "<h1>在 Dubbo 中使用注解</h1>\n<p>随着微服务架构的广泛地推广和实施。在 Java 生态系统中,以 Spring Boot 和 Spring Cloud 为代表的微服务框架,引入了全新的编程模型,包括:</p>\n<ul>\n<li>注解驱动(Annotation-Driven)</li>\n<li>外部化配置(External Configuration)</li>\n<li>以及自动装配(Auto-Configure)</li>\n</ul>\n<p>新的编程模型无需 XML 配置、简化部署、提升开发效率。为了更好地实践微服务架构,Dubbo 从 <code>2.5.8</code> 版本开始, 分别针对了上述的三个场景,提供了更完善的支持。本文不讨论传统的 XML 配置方式,而是侧重介绍注解这种方式。外部配置、自动装配两种自动装配会在另外的文章中专门介绍。</p>\n<h2>注解介绍</h2>\n<h3>@EnableDubbo</h3>\n<p><code>@EnableDubbo</code> 注解是 <code>@ [...]
+  "link": "/zh-cn/blog/dubbo-annotation.html",
+  "meta": {
+    "title": "在 Dubbo 中使用注解",
+    "keywords": "Dubbo, Annotation, Spring",
+    "description": "介绍了如何使用注解方式而非 XML 方式来开发 Dubbo 应用,可以学习到如何使用 @EnableDubbo、@Service、@Reference 的用法。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-basic-usage-dubbo-consumer-configuration.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-basic-usage-dubbo-consumer-configuration.html
new file mode 100644
index 0000000..8b1d614
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-basic-usage-dubbo-consumer-configuration.html
@@ -0,0 +1,247 @@
+<!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="dubbo-basic-usage-dubbo-consumer-configuration" />
+	<meta name="description" content="dubbo-basic-usage-dubbo-consumer-configuration" />
+	<!-- 网页标签标题 -->
+	<title>dubbo-basic-usage-dubbo-consumer-configuration</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>Dubbo Consumer配置</h2>
+<h3>Consumer配置详解</h3>
+<p>配置Dubbo Consumer有3种方式:XML配置,API调用方式配置,注解方式配置。</p>
+<h4>XML配置</h4>
+<h6>最简单的配置的样例:</h6>
+<pre><code>
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
+    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+    xmlns:dubbo=&quot;http://dubbo.apache.org/schema/dubbo&quot;
+    xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd&quot;&gt;  
+    &lt;dubbo:application name=&quot;hello-world-app&quot; /&gt;  
+    &lt;dubbo:registry address=&quot;multicast://224.5.6.7:1234&quot; /&gt;  
+    &lt;dubbo:protocol name=&quot;dubbo&quot; port=&quot;20880&quot; /&gt;  
+    &lt;dubbo:reference id=&quot;demoServiceRemote&quot; interface=&quot;com.alibaba.dubbo.demo.DemoService&quot; /&gt;  
+&lt;/beans&gt;
+</code></pre>
+<blockquote>
+<p>支持的配置标签及对应的配置项详解,参考provider中的用法。</p>
+</blockquote>
+<blockquote>
+<p>接下来重点讲解下&lt;dubbo:reference/&gt;的配置。</p>
+</blockquote>
+<ul>
+<li>&lt;dubbo:reference/&gt;支持的主要属性列表:</li>
+</ul>
+<table>
+<thead>
+<tr>
+<th>属性名</th>
+<th>说明</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>id</td>
+<td>服务引用id,作为java bean id,需要唯一</td>
+</tr>
+<tr>
+<td>interface</td>
+<td>接口名,用于查找服务</td>
+</tr>
+<tr>
+<td>version</td>
+<td>版本号,与服务提供者的版本一致</td>
+</tr>
+<tr>
+<td>timeout</td>
+<td>服务方法调用超时时间(毫秒)</td>
+</tr>
+<tr>
+<td>retries</td>
+<td>远程服务调用重试次数,不包括第一次调用,不需要重试请设为0</td>
+</tr>
+<tr>
+<td>connections</td>
+<td>对每个提供者的最大连接数,rmi、http、hessian等短连接协议表示限制连接数,dubbo等长连接协表示建立的长连接个数</td>
+</tr>
+<tr>
+<td>loadbalance</td>
+<td>负载均衡策略,可选值:random,roundrobin,leastactive,分别表示:随机,轮询,最少活跃调用</td>
+</tr>
+<tr>
+<td>async</td>
+<td>是否异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程</td>
+</tr>
+<tr>
+<td>generic</td>
+<td>泛化调用,可以绕过</td>
+</tr>
+<tr>
+<td>check</td>
+<td>启动时检查提供者是否存在,true报错,false忽略</td>
+</tr>
+<tr>
+<td>actives</td>
+<td>每服务消费者每服务每方法最大并发调用数</td>
+</tr>
+</tbody>
+</table>
+<p>其他配置属性请参考xsd:<a href="http://dubbo.apache.org/schema/dubbo/dubbo.xsd">http://dubbo.apache.org/schema/dubbo/dubbo.xsd</a></p>
+<ul>
+<li>&lt;dubbo:method/&gt;作为&lt;dubbo:reference/&gt;的子元素,它可以针对方法进行配置。比较常用的属性有:</li>
+</ul>
+<table>
+<thead>
+<tr>
+<th>属性名</th>
+<th>说明</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>executes</td>
+<td>服务执行的请求上限</td>
+</tr>
+<tr>
+<td>retries</td>
+<td>超时重试次数</td>
+</tr>
+<tr>
+<td>timeout</td>
+<td>调用超时时间</td>
+</tr>
+<tr>
+<td>loadbalance</td>
+<td>负载均衡策略,可选值:random,roundrobin,leastactive,分别表示:随机,轮询,最少活跃调用</td>
+</tr>
+<tr>
+<td>async</td>
+<td>是否异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程</td>
+</tr>
+<tr>
+<td>actives</td>
+<td>每服务消费者最大并发调用限制</td>
+</tr>
+</tbody>
+</table>
+<p>其他属性,可以参考上面的xsd。</p>
+<h6>配置的覆盖关系</h6>
+<p><img src="https://cdn.nlark.com/lark/0/2018/png/15841/1536496436861-1b63bc4e-3e59-4aa3-800e-a32cfe64950d.png" alt="undefined"></p>
+<center>配置的覆盖关系图</center> 
+<p>其中包含了consumer端和provider的配置,注意区分。</p>
+<h4>annotation</h4>
+<h6>Reference注解远程服务</h6>
+<pre><code>
+public class AnnotationConsumeService { 
+
+    @com.alibaba.dubbo.config.annotation.Reference 
+    public AnnotateService annotateService; 
+
+    // ...
+
+}
+
+</code></pre>
+<p>这种方式的配置和前面用xml配置的方式是一样的效果。</p>
+<blockquote>
+<p>指定dubbo扫描路径的方式,可以参考前一章节中provider的实现。</p>
+</blockquote>
+<h4>api直接触发</h4>
+<pre><code>import com.alibaba.dubbo.rpc.config.ApplicationConfig;
+import com.alibaba.dubbo.rpc.config.RegistryConfig;
+import com.alibaba.dubbo.rpc.config.ConsumerConfig;
+import com.alibaba.dubbo.rpc.config.ReferenceConfig;
+import com.xxx.XxxService;
+// 当前应用配置
+
+ApplicationConfig application = new ApplicationConfig();
+application.setName(&quot;yyy&quot;);
+// 连接注册中心配置
+RegistryConfig registry = new RegistryConfig();
+registry.setAddress(&quot;10.20.130.230:9090&quot;);
+registry.setUsername(&quot;aaa&quot;);
+registry.setPassword(&quot;bbb&quot;);
+ 
+// 注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供方的连接
+// 引用远程服务
+ReferenceConfig&lt;XxxService&gt; reference = new ReferenceConfig&lt;XxxService&gt;(); // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
+
+reference.setApplication(application);
+reference.setRegistry(registry); // 多个注册中心可以用setRegistries()
+reference.setInterface(XxxService.class);
+reference.setVersion(&quot;1.0.0&quot;);
+
+// 和本地bean一样使用xxxService
+XxxService xxxService = reference.get(); 
+</code></pre>
+<h6>method特殊设置</h6>
+<pre><code>
+// 方法级配置
+List&lt;MethodConfig&gt; methods = new ArrayList&lt;MethodConfig&gt;();
+MethodConfig method = new MethodConfig();
+method.setName(&quot;createXxx&quot;);
+method.setTimeout(10000);
+method.setRetries(0);
+methods.add(method); 
+// 引用远程服务
+ReferenceConfig&lt;XxxService&gt; reference = new ReferenceConfig&lt;XxxService&gt;(); // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
+...
+reference.setMethods(methods); // 设置方法级配置
+</code></pre>
+<h3>Consumer 调用远程服务</h3>
+<p>上面章节更多从配置角度出发,接下来通过一个完整的例子,来讲解下dubbo consumer的完整使用。</p>
+<p>这个例子中只有一个服务UserReadService,有一个方法 getUserById。 需要将通过Dubbo调用远程的服务。具体的步骤如下:</p>
+<p>1.创建一个工程
+如果本来已经有工程,可以忽略。创建一个spring boot工程,可以通过 <a href="https://start.spring.io/">https://start.spring.io/</a> 创建。<br>
+服务的提供方,已经在provider章节中进行了定义。
+2.调用服务</p>
+<pre><code>@RestController
+public class UserTestController{
+    @Autowired 
+    private UserReadService userReadService;
+    @RequestMapping(&quot;/user/getById&quot;)
+    public String getUserById(Long id){
+        // just test
+        return userReadService.getUserById(id).toString();
+    }
+}
+</code></pre>
+<p>3.Dubbo配置</p>
+<pre><code>
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
+    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+    xmlns:dubbo=&quot;http://dubbo.apache.org/schema/dubbo&quot;
+    xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd&quot;&gt;  
+    &lt;dubbo:application name=&quot;hello-world-app&quot; /&gt;  
+    &lt;dubbo:registry address=&quot;multicast://224.5.6.7:1234&quot; /&gt;  
+    &lt;dubbo:protocol name=&quot;dubbo&quot; port=&quot;20880&quot; /&gt;  
+    &lt;dubbo:reference id=&quot;userReadService&quot; interface=&quot;com.package.UserReadService&quot;check=&quot;false&quot; /&gt;  
+&lt;/beans&gt;
+</code></pre>
+<p>Dubbo配置的其他方式可以参考上一章节的相关配置,或者使用集成dubbo spring boot starter方式。</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-basic-usage-dubbo-consumer-configuration.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-basic-usage-dubbo-consumer-configuration.json
new file mode 100644
index 0000000..a95fd75
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-basic-usage-dubbo-consumer-configuration.json
@@ -0,0 +1,6 @@
+{
+  "filename": "dubbo-basic-usage-dubbo-consumer-configuration.md",
+  "__html": "<h1>Dubbo基本用法-Dubbo Consumer配置</h1>\n<h2>Dubbo Consumer配置</h2>\n<h3>Consumer配置详解</h3>\n<p>配置Dubbo Consumer有3种方式:XML配置,API调用方式配置,注解方式配置。</p>\n<h4>XML配置</h4>\n<h6>最简单的配置的样例:</h6>\n<pre><code>\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\n&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;\n    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;\n    xmlns:dubbo=&quot;http://dubbo.apache.org/schema/dubbo&quot;\n    xsi:schema [...]
+  "link": "/zh-cn/blog/dubbo-basic-usage-dubbo-consumer-configuration.html",
+  "meta": {}
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.html
new file mode 100644
index 0000000..0e64304
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.html
@@ -0,0 +1,400 @@
+<!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="Dubbo, Provider, Configuration" />
+	<meta name="description" content="主要讲述如何配置dubbo,按照配置方式上可以分为:XML配置,properties方式配置,注解方式配置,API调用方式配置。" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo基础用法之Provider配置</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>Dubbo基本用法</h2>
+<p>本章节主要讲述如何配置dubbo,按照配置方式上分,可以分为:XML配置,properties方式配置,注解方式配置,API调用方式配置。
+按照功能角度进行划分,可以分为Dubbo Provider和Dubbo Consumer。接下来章节中,分别对dubbo provider和Dubbo consumer进行讲解。</p>
+<h3>Dubbo Provider配置</h3>
+<h4>Provider 配置详解</h4>
+<p>配置Dubbo Provider有4种方式:XML配置,properties方式配置,API调用方式配置,注解方式配置。</p>
+<h5>XML配置</h5>
+<h6>最简单的配置的样例:</h6>
+<pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
+    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+    xmlns:dubbo=&quot;http://dubbo.apache.org/schema/dubbo&quot;
+    xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd&quot;&gt;  
+    &lt;dubbo:application name=&quot;hello-world-app&quot; /&gt;  
+    &lt;dubbo:registry address=&quot;multicast://224.5.6.7:1234&quot; /&gt;  
+    &lt;dubbo:protocol name=&quot;dubbo&quot; port=&quot;20880&quot; /&gt;  
+    &lt;dubbo:service interface=&quot;com.alibaba.dubbo.demo.DemoService&quot; ref=&quot;demoServiceLocal&quot; /&gt;  
+    &lt;dubbo:reference id=&quot;demoServiceRemote&quot; interface=&quot;com.alibaba.dubbo.demo.DemoService&quot; /&gt;  
+&lt;/beans&gt;
+</code></pre>
+<p>上面样例中,注意下dubbo schema的写法:</p>
+<pre><code>&lt;beans xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+       xmlns:dubbo=&quot;http://code.alibabatech.com/schema/dubbo&quot;
+       xmlns=&quot;http://www.springframework.org/schema/beans&quot;
+       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
+       http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd&quot;&gt;
+</code></pre>
+<h6>支持的配置标签</h6>
+<table>
+<thead>
+<tr>
+<th>标签</th>
+<th>用途</th>
+<th style="text-align:left">解释</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>&lt;dubbo:service/&gt;</td>
+<td>服务配置</td>
+<td style="text-align:left">用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心</td>
+</tr>
+<tr>
+<td>&lt;dubbo:reference/&gt;</td>
+<td>引用配置</td>
+<td style="text-align:left">用于创建一个远程服务代理,一个引用可以指向多个注册中心</td>
+</tr>
+<tr>
+<td>&lt;dubbo:protocol/&gt;</td>
+<td>协议配置</td>
+<td style="text-align:left">用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受</td>
+</tr>
+<tr>
+<td>&lt;dubbo:application/&gt;</td>
+<td>应用配置</td>
+<td style="text-align:left">用于配置当前应用信息,不管该应用是提供者还是消费者</td>
+</tr>
+<tr>
+<td>&lt;dubbo:module/&gt;</td>
+<td>模块配置</td>
+<td style="text-align:left">用于配置当前模块信息,可选</td>
+</tr>
+<tr>
+<td>&lt;dubbo:registry/&gt;</td>
+<td>注册中心配置</td>
+<td style="text-align:left">用于配置连接注册中心相关信息</td>
+</tr>
+<tr>
+<td>&lt;dubbo:monitor/&gt;</td>
+<td>监控中心配置</td>
+<td style="text-align:left">用于配置连接监控中心相关信息,可选</td>
+</tr>
+<tr>
+<td>&lt;dubbo:provider/&gt;</td>
+<td>提供方配置</td>
+<td style="text-align:left">当 ProtocolConfig 和 ServiceConfig 某属性没有配置时,采用此缺省值,可选</td>
+</tr>
+<tr>
+<td>&lt;dubbo:consumer/&gt;</td>
+<td>消费方配置</td>
+<td style="text-align:left">当 ReferenceConfig 某属性没有配置时,采用此缺省值,可选</td>
+</tr>
+<tr>
+<td>&lt;dubbo:method/&gt;</td>
+<td>方法配置</td>
+<td style="text-align:left">用于 ServiceConfig 和 ReferenceConfig 指定方法级的配置信息</td>
+</tr>
+<tr>
+<td>&lt;dubbo:argument/&gt;</td>
+<td>参数配置</td>
+<td style="text-align:left">用于指定方法参数配置</td>
+</tr>
+</tbody>
+</table>
+<p><img src="https://cdn.yuque.com/lark/0/2018/png/15841/1527849348155-8423d401-9ea4-4dc6-8720-d9e3d90963b6.png" alt="undefined"></p>
+ <center>配置之间关系图</center>
+<h6>配置项详解</h6>
+<ul>
+<li>
+<p>&lt;dubbo:application name=&quot;hello-world-app&quot; /&gt;<br>
+用于指定应用名,这里需要保证应用名唯一,这个应用名在后续的console admin中可以在列表中显示,方便管理。</p>
+</li>
+<li>
+<p>&lt;dubbo:registry address=&quot;multicast://224.5.6.7:1234&quot; /&gt;<br>
+注册中心配置,和服务发现的具体机制有关系。可以是zookeeper地址,也可以eureka地址。上面这个是广播地址,在本地服务调用的测试过程中非常方便。</p>
+</li>
+<li>
+<p>&lt;dubbo:protocol name=&quot;dubbo&quot; port=&quot;20880&quot; /&gt;<br>
+这里是传输的协议和默认端口,一般不需要更改。</p>
+</li>
+</ul>
+<blockquote>
+<p>接下来重点讲解下&lt;dubbo:service/&gt;的配置。</p>
+</blockquote>
+<ul>
+<li>&lt;dubbo:service/&gt;支持的主要属性列表:</li>
+</ul>
+<table>
+<thead>
+<tr>
+<th>属性名</th>
+<th>说明</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>version</td>
+<td>版本号</td>
+</tr>
+<tr>
+<td>scope</td>
+<td>服务可见性, 值为:local 或者 remote,默认为remote</td>
+</tr>
+<tr>
+<td>actives</td>
+<td>最大的激活的请求数</td>
+</tr>
+<tr>
+<td>async</td>
+<td>方法调用是否异步,默认为false</td>
+</tr>
+<tr>
+<td>cache</td>
+<td>服务缓存,可选值:lru/threadlocal/jcache</td>
+</tr>
+<tr>
+<td>callbacks</td>
+<td>callback实例的限制</td>
+</tr>
+<tr>
+<td>generic</td>
+<td>泛化调用,可以绕过</td>
+</tr>
+<tr>
+<td>class</td>
+<td>Service的实现的类名</td>
+</tr>
+<tr>
+<td>connections</td>
+<td>这个服务里的连接数</td>
+</tr>
+<tr>
+<td>delay</td>
+<td>发布服务延迟的毫秒数</td>
+</tr>
+<tr>
+<td>executes</td>
+<td>服务执行的请求上限</td>
+</tr>
+<tr>
+<td>retries</td>
+<td>超时重试次数</td>
+</tr>
+<tr>
+<td>timeout</td>
+<td>调用超时时间</td>
+</tr>
+</tbody>
+</table>
+<p>其他配置属性请参考xsd:<a href="http://dubbo.apache.org/schema/dubbo/dubbo.xsd">http://dubbo.apache.org/schema/dubbo/dubbo.xsd</a></p>
+<ul>
+<li>&lt;dubbo:method/&gt;作为&lt;dubbo:service/&gt;的子元素,它可以针对方法进行配置。比较常用的属性有:</li>
+</ul>
+<table>
+<thead>
+<tr>
+<th>属性名</th>
+<th>说明</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>executes</td>
+<td>服务执行的请求上限</td>
+</tr>
+<tr>
+<td>retries</td>
+<td>超时重试次数</td>
+</tr>
+<tr>
+<td>timeout</td>
+<td>调用超时时间</td>
+</tr>
+</tbody>
+</table>
+<p>其他属性,可以参考上面的xsd。</p>
+<h6>配置的覆盖关系</h6>
+<p><img src="https://cdn.yuque.com/lark/0/2018/png/15841/1527849374313-94a5ea24-0e72-4d83-871b-e0e95eab646a.png" alt="undefined"></p>
+<center>配置的覆盖关系图</center>
+<p>这里的覆盖关系包含了Provider和Consumer两端的配置,如果对consumer有疑问,可以参考后一章节的consumer章节之后再来理解。</p>
+<h4>dubbo.properties方式配置</h4>
+<blockquote>
+<p>如果公共配置很简单,没有多注册中心,多协议等情况,或者想多个 Spring 容器想共享配置,可以使用 dubbo.properties 作为缺省配置。</p>
+</blockquote>
+<p>Dubbo 将自动加载 classpath 根目录下的 dubbo.properties,可以通过JVM启动参数 -Ddubbo.properties.file=xxx.properties 改变缺省配置位置。</p>
+<h6>dubbo.properties配置样例</h6>
+<pre><code># 应用名
+dubbo.application.name=dubbodemo-provider
+# 注册中心地址
+dubbo.registry.address=zookeeper://localhost:2181
+# 广播的注册中心样例
+#dubbo.registry.address=multicast://224.5.6.7:1234
+# 调用协议地址
+dubbo.protocol.name=dubbo
+dubbo.protocol.port=28080
+</code></pre>
+<h6>映射规则</h6>
+<p>将 XML 配置的标签名,加属性名,用点分隔,多个属性拆成多行</p>
+<ul>
+<li>比如:dubbo.application.name=foo等价于&lt;dubbo:application name=&quot;foo&quot; /&gt;</li>
+<li>比如:dubbo.registry.address=10.20.153.10:9090等价于&lt;dubbo:registry address=&quot;10.20.153.10:9090&quot; /&gt;</li>
+</ul>
+<p>如果 XML 有多行同名标签配置,可用 id 号区分,如果没有 id 号将对所有同名标签生效</p>
+<ul>
+<li>比如:dubbo.protocol.rmi.port=1234等价于&lt;dubbo:protocol id=&quot;rmi&quot; name=&quot;rmi&quot; port=&quot;1234&quot; /&gt;</li>
+<li>比如:dubbo.registry.china.address=10.20.153.10:9090等价于&lt;dubbo:registry id=&quot;china&quot; address=&quot;10.20.153.10:9090&quot; /&gt;</li>
+</ul>
+<h6>覆盖策略</h6>
+<p><img src="https://cdn.yuque.com/lark/0/2018/png/15841/1527849393591-2c3de248-1b3d-47d3-bd10-8b415e9fcd39.png" alt="undefined"></p>
+<ul>
+<li>JVM 启动 -D 参数优先,这样可以使用户在部署和启动时进行参数重写,比如在启动时需改变协议的端口。</li>
+<li>XML 次之,如果在 XML 中有配置,则 dubbo.properties 中的相应配置项无效。</li>
+<li>Properties 最后,相当于缺省值,只有 XML 没有配置时,dubbo.properties 的相应配置项才会生效,通常用于共享公共配置,比如应用名。</li>
+</ul>
+<blockquote>
+<p>注意:</p>
+</blockquote>
+<ol>
+<li>如果 classpath 根目录下存在多个 dubbo.properties,比如多个 jar 包中有 dubbo.properties,Dubbo 会任意加载,并打印 Error 日志,后续可能改为抛异常。 ↩</li>
+<li>协议的 id 没配时,缺省使用协议名作为 id</li>
+</ol>
+<h5>注解配置</h5>
+<h6>Service注解暴露服务</h6>
+<pre><code>import com.alibaba.dubbo.config.annotation.Service;
+
+@Service(timeout = 5000)
+public class AnnotateServiceImpl implements AnnotateService { 
+    // ...
+}
+</code></pre>
+<h6>javaconfig形式配置公共模块</h6>
+<pre><code>@Configuration
+public class DubboConfiguration {
+
+    @Bean
+    public ApplicationConfig applicationConfig() {
+        ApplicationConfig applicationConfig = new ApplicationConfig();
+        applicationConfig.setName(&quot;provider-test&quot;);
+        return applicationConfig;
+    }
+
+    @Bean
+    public RegistryConfig registryConfig() {
+        RegistryConfig registryConfig = new RegistryConfig();
+        registryConfig.setAddress(&quot;zookeeper://127.0.0.1:2181&quot;);
+        registryConfig.setClient(&quot;curator&quot;);
+        return registryConfig;
+    }
+}
+</code></pre>
+<p>这种方式的配置和前面用xml配置的方式是一样的效果。</p>
+<h6>指定dubbo扫描路径</h6>
+<pre><code>@SpringBootApplication
+@DubboComponentScan(basePackages = &quot;com.alibaba.dubbo.test.service.impl&quot;)
+public class ProviderTestApp {
+    // ...
+}
+</code></pre>
+<p>或者使用spring bean xml配置方式:</p>
+<pre><code>&lt;dubbo:annotation package=&quot;com.chanshuyi.service.impl&quot; /&gt;
+</code></pre>
+<h5>代码配置</h5>
+<pre><code>import com.alibaba.dubbo.rpc.config.ApplicationConfig;
+import com.alibaba.dubbo.rpc.config.RegistryConfig;
+import com.alibaba.dubbo.rpc.config.ProviderConfig;
+import com.alibaba.dubbo.rpc.config.ServiceConfig;
+import com.xxx.XxxService;
+import com.xxx.XxxServiceImpl;
+
+// 服务实现
+XxxService xxxService = new XxxServiceImpl();
+
+// 当前应用配置
+ApplicationConfig application = new ApplicationConfig();
+application.setName(&quot;xxx&quot;);
+
+// 连接注册中心配置
+RegistryConfig registry = new RegistryConfig();
+registry.setAddress(&quot;10.20.130.230:9090&quot;);
+registry.setUsername(&quot;aaa&quot;);
+registry.setPassword(&quot;bbb&quot;);
+
+// 服务提供者协议配置
+ProtocolConfig protocol = new ProtocolConfig();
+protocol.setName(&quot;dubbo&quot;);
+protocol.setPort(12345);
+protocol.setThreads(200);
+
+// 注意:ServiceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口
+
+// 服务提供者暴露服务配置
+ServiceConfig&lt;XxxService&gt; service = new ServiceConfig&lt;XxxService&gt;(); // 此实例很重,封装了与注册中心的连接,请自行缓存,否则可能造成内存和连接泄漏
+service.setApplication(application);
+service.setRegistry(registry); // 多个注册中心可以用setRegistries()
+service.setProtocol(protocol); // 多个协议可以用setProtocols()
+service.setInterface(XxxService.class);
+service.setRef(xxxService);
+service.setVersion(&quot;1.0.0&quot;);
+
+// 暴露及注册服务
+service.export();
+</code></pre>
+<p>一般在spring应用中,不推荐使用这种方式。 具体的含义这里不做解释,可以通过github查看源码。</p>
+<h3>Provider 接口和实现</h3>
+<p>上面章节更多从配置角度出发,接下来通过一个完整的例子,来讲解下dubbo provider的完整使用。</p>
+<p>这个例子中只有一个服务UserReadService,有一个方法 getUserById。 需要将这个服务通过Dubbo暴露给远程的服务。具体的步骤如下:</p>
+<p>1.创建工程
+如果本来已经有工程,可以忽略。创建一个spring boot工程,可以通过 <a href="https://start.spring.io/">https://start.spring.io/</a> 创建。
+2.定义接口
+定义接口:UserReadService</p>
+<pre><code>public interface UserReadService{
+public User getUserById(Long userId);
+}
+</code></pre>
+<p>这个接口一般来说会放到独立的jar包里,作为client包。 其他应用要消费这个服务的时候,一般来说需要应用引用这个client包。(除了泛化调用)
+3.实现接口
+实现UserReadService, 当前实现部署在Provider的应用中。</p>
+<pre><code>public UserReadServiceImpl implements UserReadService{
+    public User getUserById(Long userId){
+        return xxx;
+    }
+}
+</code></pre>
+<p>4.Dubbo配置</p>
+<pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
+    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+    xmlns:dubbo=&quot;http://dubbo.apache.org/schema/dubbo&quot;
+    xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd&quot;&gt;  
+    &lt;dubbo:application name=&quot;hello-world-app&quot; /&gt;  
+    &lt;dubbo:registry address=&quot;multicast://224.5.6.7:1234&quot; /&gt;  
+    &lt;dubbo:protocol name=&quot;dubbo&quot; port=&quot;20880&quot; /&gt;  
+    &lt;bean id=&quot;userReadService&quot; class=&quot;com.package.UserReadServiceImpl&quot;/&gt;
+    &lt;dubbo:service interface=&quot;com.package.UserReadService&quot; ref=&quot;userReadService&quot; /&gt;  
+&lt;/beans&gt;
+</code></pre>
+<p>Dubbo配置的其他方式可以参考上一章节的相关配置,或者使用集成dubbo spring boot starter方式。</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.json
new file mode 100644
index 0000000..51b3be7
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-basic-usage-dubbo-provider-configuration.md",
+  "__html": "<h1>Dubbo基本用法之Provider配置</h1>\n<h2>Dubbo基本用法</h2>\n<p>本章节主要讲述如何配置dubbo,按照配置方式上分,可以分为:XML配置,properties方式配置,注解方式配置,API调用方式配置。\n按照功能角度进行划分,可以分为Dubbo Provider和Dubbo Consumer。接下来章节中,分别对dubbo provider和Dubbo consumer进行讲解。</p>\n<h3>Dubbo Provider配置</h3>\n<h4>Provider 配置详解</h4>\n<p>配置Dubbo Provider有4种方式:XML配置,properties方式配置,API调用方式配置,注解方式配置。</p>\n<h5>XML配置</h5>\n<h6>最简单的配置的样例:</h6>\n<pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\n&lt;beans xmlns=&quot;htt [...]
+  "link": "/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.html",
+  "meta": {
+    "title": "Dubbo基础用法之Provider配置",
+    "keywords": "Dubbo, Provider, Configuration",
+    "description": "主要讲述如何配置dubbo,按照配置方式上可以分为:XML配置,properties方式配置,注解方式配置,API调用方式配置。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-cluster-error-handling.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-cluster-error-handling.html
new file mode 100644
index 0000000..5c4cab7
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-cluster-error-handling.html
@@ -0,0 +1,232 @@
+<!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="Dubbo, RPC, cluster, Error-handling" />
+	<meta name="description" content="在分布式系统中,集群某个某些节点出现问题是大概率事件,因此在设计分布式RPC框架的过程中,必须要把失败作为设计的一等公民来对待。一次调用失败之后,应该如何选择对失败的选择策略,这是一个见仁见智的问题,每种策略可能都有自己独特的应用场景。因此,作为框架来说,应当针对不同场景提供多种策略,供用户进行选择。本文介绍了Dubbo框架提供的多种错误处理策略,并通过实例说明如何进行配置。" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo集群容错</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>在分布式系统中,集群某个某些节点出现问题是大概率事件,因此在设计分布式RPC框架的过程中,必须要把失败作为设计的一等公民来对待。一次调用失败之后,应该如何选择对失败的选择策略,这是一个见仁见智的问题,每种策略可能都有自己独特的应用场景。因此,作为框架来说,应当针对不同场景提供多种策略,供用户进行选择。</p>
+<p>在Dubbo设计中,通过Cluster这个接口的抽象,把一组可供调用的Provider信息组合成为一个统一的<code>Invoker</code>供调用方进行调用。经过路由规则过滤,负载均衡选址后,选中一个具体地址进行调用,如果调用失败,则会按照集群配置的容错策略进行容错处理。</p>
+<p>Dubbo默认内置了若干容错策略,如果不能满足用户需求,则可以通过自定义容错策略进行配置。</p>
+<h3>内置容错策略</h3>
+<p>Dubbo主要内置了如下几种策略:</p>
+<ul>
+<li>Failover(失败自动切换)</li>
+<li>Failsafe(失败安全)</li>
+<li>Failfast(快速失败)</li>
+<li>Failback(失败自动恢复)</li>
+<li>Forking(并行调用)</li>
+<li>Broadcast(广播调用)</li>
+</ul>
+<p>这些名称比较相似,概念也比较容易混淆,下面逐一进行解释。</p>
+<h4>Failover(失败自动切换)</h4>
+<p><code>Failover</code>是高可用系统中的一个常用概念,服务器通常拥有主备两套机器配置,如果主服务器出现故障,则自动切换到备服务器中,从而保证了整体的高可用性。</p>
+<p>Dubbo也借鉴了这个思想,并且把它作为Dubbo<code>默认的容错策略</code>。当调用出现失败的时候,根据配置的重试次数,会自动从其他可用地址中重新选择一个可用的地址进行调用,直到调用成功,或者是达到重试的上限位置。</p>
+<p>Dubbo里默认配置的重试次数是2,也就是说,算上第一次调用,最多会调用3次。</p>
+<p>其配置方法,容错策略既可以在服务提供方配置,也可以服务调用方进行配置。而重试次数的配置则更为灵活,既可以在服务级别进行配置,也可以在方法级别进行配置。具体优先顺序为:</p>
+<pre><code>服务调用方方法级配置 &gt; 服务调用方服务级配置 &gt; 服务提供方方法级配置 &gt; 服务提供方服务级配置
+</code></pre>
+<p>以XML方式为例,具体配置方法如下:</p>
+<p>服务提供方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"failover"</span> <span class="hljs-attr">retries</span>=<span class="hljs-string">"2"</span> /&gt;</span>
+</code></pre>
+<p>服务提供方,方法级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span><span class="hljs-attr">cluster</span>=<span class="hljs-string">"failover"</span>&gt;</span>
+     <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:method</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"sayHello"</span> <span class="hljs-attr">retries</span>=<span class="hljs-string">"2"</span> /&gt;</span>
+ <span class="hljs-tag">&lt;/<span class="hljs-name">dubbo:reference</span>&gt;</span>
+</code></pre>
+<p>服务调用方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"failover"</span> <span class="hljs-attr">retries</span>=<span class="hljs-string">"1"</span>/&gt;</span>
+</code></pre>
+<p>服务调用方,方法级配置:</p>
+<pre><code class="language-xml"> <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"failover"</span>&gt;</span>
+     <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:method</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"sayHello"</span> <span class="hljs-attr">retries</span>=<span class="hljs-string">"3"</span> /&gt;</span>
+ <span class="hljs-tag">&lt;/<span class="hljs-name">dubbo:reference</span>&gt;</span>
+</code></pre>
+<p>Failover可以自动对失败进行重试,对调用者屏蔽了失败的细节,但是Failover策略也会带来一些副作用:</p>
+<ul>
+<li>重试会额外增加一下开销,例如增加资源的使用,在高负载系统下,额外的重试可能让系统雪上加霜。</li>
+<li>重试会增加调用的响应时间。</li>
+<li>某些情况下,重试甚至会造成资源的浪费。考虑一个调用场景,A-&gt;B-&gt;C,如果A处设置了超时100ms,再B-&gt;C的第一次调用完成时已经超过了100ms,但很不幸B-&gt;C失败,这时候会进行重试,但其实这时候重试已经没有意义,因此在A看来这次调用已经超时,A可能已经开始执行其他逻辑。</li>
+</ul>
+<h4>Failsafe(失败安全)</h4>
+<p>失败安全策略的核心是即使失败了也不会影响整个调用流程。通常情况下用于旁路系统或流程中,它的失败不影响核心业务的正确性。在实现上,当出现调用失败时,会忽略此错误,并记录一条日志,同时返回一个空结果,在上游看来调用是成功的。</p>
+<p>应用场景,可以用于写入审计日志等操作。</p>
+<p>具体配置方法:</p>
+<p>服务提供方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"failsafe"</span> /&gt;</span>
+</code></pre>
+<p>服务调用方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"failsafe"</span>/&gt;</span>
+</code></pre>
+<p>其中服务调用方配置优先于服务提供方配置。</p>
+<h4>Failfast(快速失败)</h4>
+<p>某些业务场景中,某些操作可能是非幂等的,如果重复发起调用,可能会导致出现脏数据等。例如调用某个服务,其中包含一个数据库的写操作,如果写操作完成,但是在发送结果给调用方的过程中出错了,那么在调用发看来这次调用失败了,但其实数据写入已经完成。这种情况下,重试可能并不是一个好策略,这时候就需要使用到<code>Failfast</code>策略,调用失败立即报错。让调用方来决定下一步的操作并保证业务的幂等性。</p>
+<p>具体配置方法:</p>
+<p>服务提供方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"failfast"</span> /&gt;</span>
+</code></pre>
+<p>服务调用方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"failfast"</span>/&gt;</span>
+</code></pre>
+<p>其中服务调用方配置优先于服务提供方配置。</p>
+<h4>Failback(失败自动恢复)</h4>
+<p><code>Failback</code>通常和<code>Failover</code>两个概念联系在一起。在高可用系统中,当主机发生故障,通过<code>Failover</code>进行主备切换后,待故障恢复后,系统应该具备自动恢复原始配置的能力。</p>
+<p>Dubbo中的<code>Failback</code>策略中,如果调用失败,则此次失败相当于<code>Failsafe</code>,将返回一个空结果。而与<code>Failsafe</code>不同的是,Failback策略会将这次调用加入内存中的失败列表中,对于这个列表中的失败调用,会在另一个线程中进行异步重试,重试如果再发生失败,则会忽略,即使重试调用成功,原来的调用方也感知不到了。因此它通常适合于,对于实时性要求不高,且不需要返回值的一些异步操作。</p>
+<p>具体配置方法:</p>
+<p>服务提供方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"failsafe"</span> /&gt;</span>
+</code></pre>
+<p>服务调用方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"failsafe"</span>/&gt;</span>
+</code></pre>
+<p>其中服务调用方配置优先于服务提供方配置。</p>
+<p>按照目前的实现,Failback策略还有一些局限,例如内存中的失败调用列表没有上限,可能导致堆积,异步重试的执行间隔无法调整,默认是5秒。</p>
+<h4>Forking(并行调用)</h4>
+<p>上述几种策略中,主要都是针对调用失败发生后如何进行弥补的角度去考虑的,而<code>Forking</code>策略则跟上述几种策略不同,是一种典型的用成本换时间的思路。即第一次调用的时候就同时发起多个调用,只要其中一个调用成功,就认为成功。在资源充足,且对于失败的容忍度较低的场景下,可以采用此策略。</p>
+<p>具体配置方法:</p>
+<p>服务提供方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"forking"</span> /&gt;</span>
+</code></pre>
+<p>服务调用方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"forking"</span>/&gt;</span>
+</code></pre>
+<p>其中服务调用方配置优先于服务提供方配置。</p>
+<h4>Broadcast(广播调用)</h4>
+<p>在某些场景下,可能需要对服务的所有提供者进行操作,此时可以使用广播调用策略。此策略会逐个调用所有提供者,只要任意有一个提供者出错,则认为此次调用出错。通常用于通知所有提供者更新缓存或日志等本地资源信息。</p>
+<p>具体配置方法:</p>
+<p>服务提供方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"broadcast"</span> /&gt;</span>
+</code></pre>
+<p>服务调用方,服务级配置</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"broadcast"</span>/&gt;</span>
+</code></pre>
+<p>其中服务调用方配置优先于服务提供方配置。</p>
+<h4>各种策略对比</h4>
+<p>下表对各种策略做一个简单对比,</p>
+<table>
+<thead>
+<tr>
+<th>策略名称</th>
+<th>优点</th>
+<th>缺点</th>
+<th>主要应用场景</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>Failover</td>
+<td>对调用者屏蔽调用失败的信息</td>
+<td>增加RT,额外资源开销,资源浪费</td>
+<td>对调用rt不敏感的场景</td>
+</tr>
+<tr>
+<td>Failfast</td>
+<td>业务快速感知失败状态进行自主决策</td>
+<td>产生较多报错的信息</td>
+<td>非幂等性操作,需要快速感知失败的场景</td>
+</tr>
+<tr>
+<td>Failsafe</td>
+<td>即使失败了也不会影响核心流程</td>
+<td>对于失败的信息不敏感,需要额外的监控</td>
+<td>旁路系统,失败不影响核心流程正确性的场景</td>
+</tr>
+<tr>
+<td>Failback</td>
+<td>失败自动异步重试</td>
+<td>重试任务可能堆积</td>
+<td>对于实时性要求不高,且不需要返回值的一些异步操作</td>
+</tr>
+<tr>
+<td>Forking</td>
+<td>并行发起多个调用,降低失败概率</td>
+<td>消耗额外的机器资源,需要确保操作幂等性</td>
+<td>资源充足,且对于失败的容忍度较低,实时性要求高的场景</td>
+</tr>
+<tr>
+<td>Broadcast</td>
+<td>支持对所有的服务提供者进行操作</td>
+<td>资源消耗很大</td>
+<td>通知所有提供者更新缓存或日志等本地资源信息</td>
+</tr>
+</tbody>
+</table>
+<h3>自定义容错策略</h3>
+<p>如果上述内置的容错策略无法满足你的需求,还可以通过扩展的方式来实现自定义容错策略。</p>
+<h4>扩展接口</h4>
+<p><code>com.alibaba.dubbo.rpc.cluster.Cluster</code></p>
+<h4>扩展配置</h4>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"xxx"</span> /&gt;</span>
+</code></pre>
+<h4>扩展示例</h4>
+<p>下面通过一个例子来展示如何使用自定义的容错策略。
+Maven 项目结构:</p>
+<pre><code>src
+ |-main
+    |-java
+        |-com
+            |-xxx
+                |-XxxCluster.java (实现Cluster接口)
+    |-resources
+        |-META-INF
+            |-dubbo
+                |-org.apache.dubbo.rpc.cluster.Cluster (纯文本文件,内容为:xxx=com.xxx.XxxCluster)
+</code></pre>
+<p>XxxCluster.java:</p>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
+ 
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.Cluster;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.Directory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.LoadBalance;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invocation;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Result;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
+
+<span class="hljs-keyword">import</span> java.util.List;
+
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxCluster</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Cluster</span> </span>{
+
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-keyword">public</span> &lt;T&gt; <span class="hljs-function">Invoker&lt;T&gt; <span class="hljs-title">join</span><span class="hljs-params">(Directory&lt;T&gt; directory)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> AbstractClusterInvoker&lt;T&gt;() {
+            <span class="hljs-meta">@Override</span>
+            <span class="hljs-function"><span class="hljs-keyword">protected</span> Result <span class="hljs-title">doInvoke</span><span class="hljs-params">(Invocation invocation, List&lt;Invoker&lt;T&gt;&gt; invokers, LoadBalance loadbalance)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+                <span class="hljs-comment">// your custimzed fault tolarence strategy goes here</span>
+            }
+        };
+    }
+
+}
+</code></pre>
+<p><code>META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.Cluster</code>文件的内容为</p>
+<pre><code>xxx=com.xxx.XxxCluster
+</code></pre>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-cluster-error-handling.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-cluster-error-handling.json
new file mode 100644
index 0000000..b158a33
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-cluster-error-handling.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-cluster-error-handling.md",
+  "__html": "<h3>Design For failure</h3>\n<p>在分布式系统中,集群某个某些节点出现问题是大概率事件,因此在设计分布式RPC框架的过程中,必须要把失败作为设计的一等公民来对待。一次调用失败之后,应该如何选择对失败的选择策略,这是一个见仁见智的问题,每种策略可能都有自己独特的应用场景。因此,作为框架来说,应当针对不同场景提供多种策略,供用户进行选择。</p>\n<p>在Dubbo设计中,通过Cluster这个接口的抽象,把一组可供调用的Provider信息组合成为一个统一的<code>Invoker</code>供调用方进行调用。经过路由规则过滤,负载均衡选址后,选中一个具体地址进行调用,如果调用失败,则会按照集群配置的容错策略进行容错处理。</p>\n<p>Dubbo默认内置了若干容错策略,如果不能满足用户需求,则可以通过自定义容错策略进行配置。</p>\n<h3>内置容错
 策略</h3>\n<p>Dubbo主要内置了如下几种策略:</p>\n<ul>\n<li>Failover(失败自动切换)</li>\n<li>Failsaf [...]
+  "link": "/zh-cn/blog/dubbo-cluster-error-handling.html",
+  "meta": {
+    "title": "Dubbo集群容错",
+    "keywords": "Dubbo, RPC, cluster, Error-handling",
+    "description": "在分布式系统中,集群某个某些节点出现问题是大概率事件,因此在设计分布式RPC框架的过程中,必须要把失败作为设计的一等公民来对待。一次调用失败之后,应该如何选择对失败的选择策略,这是一个见仁见智的问题,每种策略可能都有自己独特的应用场景。因此,作为框架来说,应当针对不同场景提供多种策略,供用户进行选择。本文介绍了Dubbo框架提供的多种错误处理策略,并通过实例说明如何进行配置。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-compatible.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-compatible.html
new file mode 100644
index 0000000..302e9b0
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-compatible.html
@@ -0,0 +1,198 @@
+<!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="Dubbo, repackage, 兼容" />
+	<meta name="description" content="本文简单描述了2.7.x repackage后对老版本的兼容性实现方案。" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo 2.7.x repackage后的兼容实现方案</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>Dubbo至加入Apache孵化器以来,一个很强的诉求就是需要rename groupId和package name,这两项工作在项目毕业前需要完成。其中rename package相对来说复杂一些,除了要修改所有类的包名为<code>org.apache.dubbo</code>外,更多的是需要考虑如何老版本的兼容性。</p>
+<p>常见的兼容性包括但不限于以下几种情况:</p>
+<ul>
+<li>用户API
+<ul>
+<li>编程API</li>
+<li>Spring注解</li>
+</ul>
+</li>
+<li>扩展SPI
+<ul>
+<li>扩展Filter</li>
+</ul>
+</li>
+</ul>
+<p>2.7.x里就是通过增加了一个新的模块<code>dubbo-compatible</code>来解决以上兼容性问题。</p>
+<h2>编程使用API</h2>
+<p>编程使用API是最直接最原始的使用方式,其他方式诸如Spring schema、注解等方式都是基于原始API的;因此非常有必要对API编程形式进行兼容。</p>
+<p>所有编程相关API的兼容代码均在<code>com.alibaba.dubbo.config</code>包下,下面我们看看几个常见API的兼容实现。</p>
+<h3>ApplicationConfig</h3>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.dubbo.config;
+
+<span class="hljs-meta">@Deprecated</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ApplicationConfig</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">org</span>.<span class="hljs-title">apache</span>.<span class="hljs-title">dubbo</span>.<span class="hljs-title">config</span>.<span class="hljs-title">ApplicationConfig</span> </span>{
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ApplicationConfig</span><span class="hljs-params">()</span> </span>{
+        <span class="hljs-keyword">super</span>();
+    }
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ApplicationConfig</span><span class="hljs-params">(String name)</span> </span>{
+        <span class="hljs-keyword">super</span>(name);
+    }
+}
+</code></pre>
+<h3>ProtocolConfig</h3>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.dubbo.config;
+
+<span class="hljs-meta">@Deprecated</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProtocolConfig</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">org</span>.<span class="hljs-title">apache</span>.<span class="hljs-title">dubbo</span>.<span class="hljs-title">config</span>.<span class="hljs-title">ProtocolConfig</span> </span>{
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ProtocolConfig</span><span class="hljs-params">()</span> </span>{
+    }
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ProtocolConfig</span><span class="hljs-params">(String name)</span> </span>{
+        <span class="hljs-keyword">super</span>(name);
+    }
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ProtocolConfig</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> port)</span> </span>{
+        <span class="hljs-keyword">super</span>(name, port);
+    }
+}
+</code></pre>
+<p>可以看到:</p>
+<ol>
+<li>兼容类是直接通过继续repacakge后的类,达到最大程度的代码复用;</li>
+<li>构造函数也需要保持兼容;</li>
+</ol>
+<p>整个兼容包中,除了上述API以外,包括一些常用的类比如<code>Constants</code>、<code>URL</code>以及绝大部分的兼容类都是通过简单的继承,让用户基于老的API实现的类能正确运行。</p>
+<h2>Spring注解</h2>
+<p>Spring注解诸如<code>@EnableDubbo</code>、<code>@Service</code>以及<code>@Reference</code>,由于不能使用继承,故这些注解类是通过代码拷贝来实现的;用于处理这些注解的Spring BeanPostProcessor以及Parser等相关的类,也是通过拷贝来实现;</p>
+<p>这类兼容代码分别位于兼容包的以下几个package中:</p>
+<ul>
+<li>com.alibaba.dubbo.config.annotation</li>
+<li>com.alibaba.dubbo.config.spring.context.annotation</li>
+<li>org.apache.dubbo.config.spring</li>
+</ul>
+<p>所以这里要特别强调的是,这类代码在2.7.x里存在2份,因此有修改的同时需要同步修改。</p>
+<h2>扩展SPI</h2>
+<p>Dubbo的SPI扩展机制,可以通过<a href="http://dubbo.apache.org/zh-cn/blog/introduction-to-dubbo-spi.html">Dubbo可扩展机制实战</a>这篇博客详细了解。</p>
+<p>以Filter扩展为例,简单来说就是:</p>
+<ol>
+<li>
+<p>MyFilter需要实现Filter接口</p>
+</li>
+<li>
+<p>在META-INF/dubbo下,增加META-INF/dubbo/com.alibaba.dubbo.rpc.Filter,内容为:</p>
+<pre><code>myFilter=com.test.MyFilter
+</code></pre>
+</li>
+</ol>
+<p>看似简单的两点,对Dubbo框架来说,需要:</p>
+<ol>
+<li>正确加载配置文件META-INF/dubbo/com.alibaba.dubbo.rpc.Filter</li>
+<li>正确加载MyFilter类并执行invoke方法</li>
+</ol>
+<p>下面分别介绍Dubbo框架怎么实现以上几点。</p>
+<h3>正确加载META-INF/dubbo/com.alibaba.dubbo.rpc.Filter</h3>
+<p>Dubbo SPI机制在查找配置文件时,是根据扩展点的类名来查找的,以Filter为例,在包名变为org.apache.dubbo后,查询的目录变成:</p>
+<ul>
+<li>META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter</li>
+<li>META-INF/dubbo/org.apache.dubbo.rpc.Filter</li>
+<li>META-INF/services/org.apache.dubbo.rpc.Filter</li>
+</ul>
+<p>但是用户之前按老的包实现的Filter,其配置是放在类似<code>META-INF/dubbo/com.alibaba.dubbo.rpc.Filter</code>的,如果框架不做特殊处理,是不会加载老配置的。</p>
+<p>因此在<code>ExtensionLoader</code>这个类里,做了特殊的处理:</p>
+<pre><code class="language-java">    <span class="hljs-comment">// synchronized in getExtensionClasses</span>
+    <span class="hljs-keyword">private</span> Map&lt;String, Class&lt;?&gt;&gt; loadExtensionClasses() {
+        <span class="hljs-keyword">final</span> SPI defaultAnnotation = type.getAnnotation(SPI<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        <span class="hljs-keyword">if</span> (defaultAnnotation != <span class="hljs-keyword">null</span>) {
+            String value = defaultAnnotation.value();
+            <span class="hljs-keyword">if</span> ((value = value.trim()).length() &gt; <span class="hljs-number">0</span>) {
+                String[] names = NAME_SEPARATOR.split(value);
+                <span class="hljs-keyword">if</span> (names.length &gt; <span class="hljs-number">1</span>) {
+                    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"more than 1 default extension name on extension "</span> + type.getName()
+                            + <span class="hljs-string">": "</span> + Arrays.toString(names));
+                }
+                <span class="hljs-keyword">if</span> (names.length == <span class="hljs-number">1</span>) cachedDefaultName = names[<span class="hljs-number">0</span>];
+            }
+        }
+
+        Map&lt;String, Class&lt;?&gt;&gt; extensionClasses = <span class="hljs-keyword">new</span> HashMap&lt;String, Class&lt;?&gt;&gt;();
+        loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName());
+        loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName().replace(<span class="hljs-string">"org.apache"</span>, <span class="hljs-string">"com.alibaba"</span>));
+        loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName());
+        loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName().replace(<span class="hljs-string">"org.apache"</span>, <span class="hljs-string">"com.alibaba"</span>));
+        loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName());
+        loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName().replace(<span class="hljs-string">"org.apache"</span>, <span class="hljs-string">"com.alibaba"</span>));
+        <span class="hljs-keyword">return</span> extensionClasses;
+    }
+</code></pre>
+<p>可以看到,除了加载新配置外,老配置文件也会进行扫描。</p>
+<h3>正确加载MyFilter类</h3>
+<p><code>com.alibaba.dubbo.rpc.Filter</code>接口除了要继承自<code>org.apache.dubbo.rpc.Filter</code>以外,其唯一的方法invoke也需要做特殊处理。我们看看它的方法签名:</p>
+<p><code>Result invoke(Invoker&lt;?&gt; invoker, Invocation invocation) throws RpcException;</code></p>
+<p>这里参数、返回值、异常都会被实现类<code>MyFilter</code>用到,因此这些类也需要有兼容类;而参数、返回值不同,对于接口来说是不同的方法,因此:</p>
+<ul>
+<li>需要在com.alibaba.dubbo.rpc.Filter里,定义老的invoke方法,MyFilter会覆盖这个方法;</li>
+<li>org.apache.dubbo.rpc.Filter里的invoke方法,需要找一个地方来实现桥接,框架调用Filter链执行到新的invoke方法时,新的参数如何转换成老参数,老返回值如何转换成新的返回值;</li>
+</ul>
+<p>这里就用到了JDK8的新特性:接口default方法。</p>
+<pre><code class="language-java"><span class="hljs-meta">@Deprecated</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Filter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">org</span>.<span class="hljs-title">apache</span>.<span class="hljs-title">dubbo</span>.<span class="hljs-title">rpc</span>.<span class="hljs-title">Filter</span> </span>{
+
+    <span class="hljs-function">Result <span class="hljs-title">invoke</span><span class="hljs-params">(Invoker&lt;?&gt; invoker, Invocation invocation)</span> <span class="hljs-keyword">throws</span> RpcException</span>;
+
+    <span class="hljs-keyword">default</span> org.apache.dubbo.rpc.<span class="hljs-function">Result <span class="hljs-title">invoke</span><span class="hljs-params">(org.apache.dubbo.rpc.Invoker&lt;?&gt; invoker,
+                                               org.apache.dubbo.rpc.Invocation invocation)</span>
+            <span class="hljs-keyword">throws</span> org.apache.dubbo.rpc.RpcException </span>{
+        Result.CompatibleResult result = (Result.CompatibleResult) invoke(<span class="hljs-keyword">new</span> Invoker.CompatibleInvoker&lt;&gt;(invoker),
+                <span class="hljs-keyword">new</span> Invocation.CompatibleInvocation(invocation));
+        <span class="hljs-keyword">return</span> result.getDelegate();
+    }
+}
+</code></pre>
+<p>可以看到,default方法里,对参数进行了包装,然后调用老的invoke方法,并将返回值进行解包后返回给Dubbo框架。这里Result.CompatibleResult、Invocation.CompatibleInvocation以及Invoker.CompatibleInvoker都用到了代理模式。</p>
+<p>感兴趣的同学可以详细看一下以下几个类:</p>
+<ul>
+<li>com.alibaba.dubbo.rpc.Invocation</li>
+<li>com.alibaba.dubbo.rpc.Invoker</li>
+<li>com.alibaba.dubbo.rpc.Result</li>
+</ul>
+<h2>后续todo list</h2>
+<p>目前兼容包仅仅是对常见的API及SPI做了支持,列表如下:</p>
+<ul>
+<li>com.alibaba.dubbo.rpc.Filter / Invocation / Invoker / Result / RpcContext / RpcException</li>
+<li>com.alibaba.dubbo.config.*Config</li>
+<li>com.alibaba.dubbo.config.annotation.Reference / Service</li>
+<li>com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo</li>
+<li>com.alibaba.dubbo.common.Constants / URL</li>
+<li>com.alibaba.dubbo.common.extension.ExtensionFactory</li>
+<li>com.alibaba.dubbo.common.serialize.Serialization / ObjectInput / ObjectOutput</li>
+<li>com.alibaba.dubbo.cache.CacheFactory / Cache</li>
+<li>com.alibaba.dubbo.rpc.service.EchoService / GenericService</li>
+</ul>
+<p>大家如果在试用的过程中发现有任何问题请及时提出;同时如果对其他扩展点有兼容需求,也请大家提出来,也非常欢迎大家自己解决并贡献出来。</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-compatible.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-compatible.json
new file mode 100644
index 0000000..2b9b792
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-compatible.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-compatible.md",
+  "__html": "<h1>Dubbo 2.7.x repackage后的兼容实现方案</h1>\n<p>Dubbo至加入Apache孵化器以来,一个很强的诉求就是需要rename groupId和package name,这两项工作在项目毕业前需要完成。其中rename package相对来说复杂一些,除了要修改所有类的包名为<code>org.apache.dubbo</code>外,更多的是需要考虑如何老版本的兼容性。</p>\n<p>常见的兼容性包括但不限于以下几种情况:</p>\n<ul>\n<li>用户API\n<ul>\n<li>编程API</li>\n<li>Spring注解</li>\n</ul>\n</li>\n<li>扩展SPI\n<ul>\n<li>扩展Filter</li>\n</ul>\n</li>\n</ul>\n<p>2.7.x里就是通过增加了一个新的模块<code>dubbo-compatible</code>来解决以上兼容性问题。</p>\n<h2>编程使用API</h2>\n<p>编程使用API是最直接最原始的使用方式,其他方 [...]
+  "link": "/zh-cn/blog/dubbo-compatible.html",
+  "meta": {
+    "title": "Dubbo 2.7.x repackage后的兼容实现方案",
+    "keywords": "Dubbo, repackage, 兼容",
+    "description": "本文简单描述了2.7.x repackage后对老版本的兼容性实现方案。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-context-information.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-context-information.html
new file mode 100644
index 0000000..736561e
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-context-information.html
@@ -0,0 +1,156 @@
+<!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="Dubbo,RPC Context, Attachment" />
+	<meta name="description" content="介绍Dubbo上下文信息的作用、应用场景、使用方式以及注意事项" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo 上下文信息</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>简介</h2>
+<p>上下文信息是一次 RPC 调用过程中附带的环境信息,如方法名、参数类型、真实参数、本端/对端地址等。这些数据仅属于一次调用,作用于 Consumer 到 Provider 调用的整个流程。</p>
+<p>提供上下文信息是 RPC 框架很重要的一个功能,使用上下文不仅可以为单次调用指定不同配置,还能在此基础上提供强大的上层功能,如分布式链路追踪。其实现原理就是在上下文中维护一个<code>span_id</code>,Consumer 和 Provider 通过传递<code>span_id</code>来连接一次RPC调用,分别上报日志后可以在追踪系统中串联并展示完整的调用流程。这样可以更方便地发现异常,定位问题。</p>
+<h2>使用说明</h2>
+<p>Dubbo中代表上下文的类是<code>org.apache.dubbo.rpc.RpcContext</code>,可通过下述代码来获取上下文信息。</p>
+<pre><code>RpcContext.getContext()
+</code></pre>
+<h2>使用场景</h2>
+<h3>获取调用信息</h3>
+<table>
+<thead>
+<tr>
+<th style="text-align:left">方法名</th>
+<th>用途</th>
+<th>作用范围</th>
+<th>说明</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td style="text-align:left">getRequest</td>
+<td>获取 RPC 请求对象</td>
+<td>Consumer</td>
+<td>获取底层 RPC 请求对象,例如 HttpServletRequest,其他情况为 null</td>
+</tr>
+<tr>
+<td style="text-align:left">getResponse</td>
+<td>获取 RPC 请求响应</td>
+<td>Consumer</td>
+<td>获取底层 RPC 响应对象,例如HttpServletResponse,其他情况为 null</td>
+</tr>
+<tr>
+<td style="text-align:left">isProviderSide</td>
+<td>当前是否属于 Provider 上下文</td>
+<td>Both</td>
+<td>服务被调用时为 true,调用其他服务时为false</td>
+</tr>
+<tr>
+<td style="text-align:left">isConsumerSide</td>
+<td>当前是否属于 Consumer 上下文</td>
+<td>Both</td>
+<td>服务被调用时为 false,调用其他服务时为 true</td>
+</tr>
+<tr>
+<td style="text-align:left">getUrls</td>
+<td>获取当前能调用的 Url 列表</td>
+<td>Both</td>
+<td>Consumer 端会根据不同的 Failover 策略实时变化</td>
+</tr>
+<tr>
+<td style="text-align:left">getRemotePort</td>
+<td>获取远端端口</td>
+<td>Both</td>
+<td>Consumer 端为最后一次调用的 Provider 端口,Provider 为当前请求的 Consumer 端口</td>
+</tr>
+<tr>
+<td style="text-align:left">getRemoteHost</td>
+<td>获取远端主机地址</td>
+<td>Both</td>
+<td></td>
+</tr>
+<tr>
+<td style="text-align:left">getRemoteHostName</td>
+<td>获取远端主机名</td>
+<td>Both</td>
+<td></td>
+</tr>
+<tr>
+<td style="text-align:left">getRemoteAddressString</td>
+<td>获取远端地址</td>
+<td>Both</td>
+<td></td>
+</tr>
+<tr>
+<td style="text-align:left">getRemoteAddress</td>
+<td>获取远端地址</td>
+<td>Both</td>
+<td></td>
+</tr>
+<tr>
+<td style="text-align:left">getLocalPort</td>
+<td>获取本端端口</td>
+<td>Both</td>
+<td></td>
+</tr>
+<tr>
+<td style="text-align:left">getLocalHost</td>
+<td>获取本端主机地址</td>
+<td>Both</td>
+<td></td>
+</tr>
+<tr>
+<td style="text-align:left">getLocalHostName</td>
+<td>获取本端主机名</td>
+<td>Both</td>
+<td></td>
+</tr>
+<tr>
+<td style="text-align:left">getLocalAddressString</td>
+<td>获取本端地址</td>
+<td>Both</td>
+<td></td>
+</tr>
+<tr>
+<td style="text-align:left">getLocalAddress</td>
+<td>获取本端地址</td>
+<td>Both</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h3>传递用户参数</h3>
+<h4>本端传递</h4>
+<p>调用<code>get</code>和<code>set</code>方法即可完成参数传递。主要用于本端 Filter 之间的数据共享。</p>
+<h4>对端传递</h4>
+<p>调用<code>setAttachment</code>和<code>getAttachment</code>即可完成对端数据传递,这些数据会经过 RPC 传递到对端。例如 Consumer 向 Provider 传递<code>span_id</code>。</p>
+<ul>
+<li>Dubbo已经支持从 Provider 端向 Consumer 端传递参数,读写方式和 Consumer 端调用时的方式一样。</li>
+</ul>
+<h3>异步调用</h3>
+<p>在异步调用时,可通过<code>getCompletableFuture</code>或<code>getFuture</code>获取相关的 Future,异步调用相关文档请参阅:<a href="http://Dubbo.apache.org/zh-cn/docs/user/demos/async-call.html">异步调用</a></p>
+<h2>注意事项</h2>
+<p>Dubbo 内部使用 ThreadLocal 的方式存储每次调用的上下文信息,当接收到请求或发起请求时,当前线程会更新 RpcContext。例如,服务 A 调用服务 B,服务 B 调用服务 C,在 B 调 C 之前,RpcContext 记录的是 A 调 B 的信息,在 B 调 C 之后,RpcContext 记录的是 B 调 C 的信息。</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-context-information.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-context-information.json
new file mode 100644
index 0000000..869474b
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-context-information.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-context-information.md",
+  "__html": "<h1>Dubbo 上下文信息</h1>\n<h2>简介</h2>\n<p>上下文信息是一次 RPC 调用过程中附带的环境信息,如方法名、参数类型、真实参数、本端/对端地址等。这些数据仅属于一次调用,作用于 Consumer 到 Provider 调用的整个流程。</p>\n<p>提供上下文信息是 RPC 框架很重要的一个功能,使用上下文不仅可以为单次调用指定不同配置,还能在此基础上提供强大的上层功能,如分布式链路追踪。其实现原理就是在上下文中维护一个<code>span_id</code>,Consumer 和 Provider 通过传递<code>span_id</code>来连接一次RPC调用,分别上报日志后可以在追踪系统中串联并展示完整的调用流程。这样可以更方便地发现异常,定位问题。</p>\n<h2>使用说明</h2>\n<p>Dubbo中代表上下文的类是<code>org.apache.dubbo.rpc.RpcContext</code>,可通过下述代码来获取上下文信息。</p>\n<pre><code>RpcContext.ge [...]
+  "link": "/zh-cn/blog/dubbo-context-information.html",
+  "meta": {
+    "title": "Dubbo 上下文信息",
+    "keywords": "Dubbo,RPC Context, Attachment",
+    "description": "介绍Dubbo上下文信息的作用、应用场景、使用方式以及注意事项"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-contribute-to-opensource.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-contribute-to-opensource.html
new file mode 100644
index 0000000..0c1b1de
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-contribute-to-opensource.html
@@ -0,0 +1,157 @@
+<!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="Dubbo, opensource" />
+	<meta name="description" content="本文将会以 dubbo 项目为例向你阐释,给开源项目做贡献并不是一件难事" />
+	<!-- 网页标签标题 -->
+	<title>以Dubbo为例,聊聊如何向开源项目做贡献</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>Github 上有众多优秀的开源项目,大多数 IT 从业者将其当做了予取予求的工具库,遇到什么需求,先去 Github 搜一把,但有没有想过有一天自己也可以给开源事业做一些贡献呢?本文将会以 dubbo 项目为例,向你阐释,给开源项目做贡献并不是一件难事。</p>
+<h2>1 为何要给开源贡献力量</h2>
+<p>为开源项目做贡献得到的收益是多方面的,为了让你有足够的信心加入到开源项目中,我在文章最开始列举出它的诸多好处。</p>
+<h3>1.1 巩固技能</h3>
+<p>无论你是提交代码,撰写文档,提交 Issue,组织活动,当你切身参与到一个开源项目中,相关的技能都会得到历练,并且在开源项目中找到自己的位置。一方面,日常工作中我们中的大多数人接触到的是业务场景,并没有太多机会接触到基础架构组件,开源项目为我们提供了一个平台,在这里,你可以尽情挑选自己熟悉的项目为它添砖加瓦(以 Dubbo 为例,并不是所有 IT 公司都有能力自研服务治理框架);另一方面,你所提交的代码,会有管理员协助审核,他们会给出专业的建议,更好的代码规范以及更优的编程思路最终都会变成你的经验。</p>
+<h3>1.2 结交朋友</h3>
+<p>开源社区为你提供了一个平台,在这里,你可以认识很多纯粹的技术爱好者,开源贡献者是最符合 geek 定义的那群人,你所接触到的往往是某个领域最厉害的那批人。</p>
+<h3>1.3 建立口碑</h3>
+<p>这是一个很好的展示个人实力的地方,俗话说:talk is cheap,show me the code. 作为技术人员,没有什么比一个漂亮的 Github 主页更有说服力的了。如果你能够为开源项目做出可观的贡献,你也将收获到业界的知名度,此时开源项目的成就和你是密不可分的。</p>
+<h3>1.4 传承开源精神</h3>
+<p>只有源源不断的贡献者给开源项目添砖加瓦,才可以为 Github 一类的开源社区形成良好的开源风气。否则,只有输出没有输入,开源会失去活力。</p>
+<h3>1.5 养成习惯</h3>
+<p>相信我,一旦养成了每天提交代码的习惯,就像你不想中断打卡一样,你绝不想中断 commit。不止有英语打卡,健身打卡,还有开源打卡!</p>
+<p><img src="http://ov0zuistv.bkt.clouddn.com/image-20180827141007663.png" alt="开源程序员的日常"></p>
+<h2>2 贡献代码时的一些疑难杂症</h2>
+<p>如果你是一名开源界的新手,可能会对贡献的流程心生畏惧。比如:我该怎么修改代码并提交?我的代码要是存在bug怎么办?我的代码别人会不会很 low?我该如何寻找合适的开源项目?开源社区那么多的工具和词汇都是什么意思?</p>
+<p>文章的第二部分将从一个<strong>小白</strong>的角度,介绍一下开源中的一些常见问题。</p>
+<h3>2.1 git 常规操作</h3>
+<p>一般而言,我们选择使用 git 来作为版本管理的工具,你不一定要非常熟练的使用它,在我看来掌握 clone,add,commit,pull,push 即可,遇到复杂的场景,你还有谷歌。</p>
+<p><strong>fork 与 clone</strong></p>
+<p><img src="http://ov0zuistv.bkt.clouddn.com/image-20180827143942178.png" alt="fork 与 clone"></p>
+<p>如果你只是想下载源码,查看他的源码实现,使用 Clone or download 按钮即可。</p>
+<p>如果你想要给开源项目做改动,并且最终请求合并,让开源项目存在你贡献的代码,就应该使用 fork。</p>
+<p>fork 将会复制一份当前主分支的代码进入到你的仓库中,之后你所有的修改,应当基于自己的仓库进行,在功能开发/bug 修复之后,可以使用你的仓库向源仓库提交 pull request。只有源仓库的管理员才有权利合并你的请求。</p>
+<p>一些可能对你有帮助的高级指令。</p>
+<pre><code class="language-shell"><span class="hljs-meta">#</span><span class="bash"> 设置源仓库</span>
+git remote add upstream https://github.com/apache/dubbo.git
+<span class="hljs-meta">#</span><span class="bash"> 拉取源仓库的更新</span>
+git fetch upstream
+<span class="hljs-meta">#</span><span class="bash"> 将自己仓库的主分支合并源仓库的更新</span>
+git checkout master
+git merge upstream/master
+</code></pre>
+<p><strong>pull request</strong></p>
+<p><img src="http://ov0zuistv.bkt.clouddn.com/image-20180827150703869.png" alt="pull request"></p>
+<p>pull request 经常被缩写为 PR,指的是一次向源仓库请求合并的行为,如上是我 fork 了 dubbo 的仓库之后才存在的操作按钮。</p>
+<p><strong>源仓库视角的 pull request</strong></p>
+<p><img src="http://ov0zuistv.bkt.clouddn.com/image-20180827155239155.png" alt="pull request management"></p>
+<p>管理者会对 pull request 涉及的改动进行 review,以确保你的代码是符合规范的,逻辑有没有偏差,以及符合框架的功能需求。</p>
+<h3>2.2 Travis CI</h3>
+<p>一些自动化的 CI 流程被植入在每一次 pull request 的构建之中,用于给开源仓库去校验提交者的代码是否符合既定的规范,如:是否有编译问题,单元测试是否通过,覆盖率是否达标,代码风格是否合规等等。</p>
+<p><img src="http://ov0zuistv.bkt.clouddn.com/image-20180827160503114.png" alt="CI报告"></p>
+<p>一般情况下,必须通过 CI,你的 pull request 才会被管理 review。</p>
+<h3>2.3 Mailing list</h3>
+<p>每个开源项目都会有自己的贡献规范,可以参考首页的 Contributing,来获取具体的信息。dubbo 作为一个孵化中的 apache 项目,遵守了 apache 的传统,在 <a href="https://github.com/apache/dubbo/blob/master/CONTRIBUTING.md">Contributing</a> 中描述道:当你有新特性想要贡献给 Dubbo 时,官方推荐使用 Mailing list 的方式描述一遍你想要做的改动。</p>
+<p>Mailing list 简单来说,就是一个邮件通知机制,所有的 Dubbo 开发者都会订阅该邮箱:dev@dubbo.apache.org。有任何新特性的改动,或者什么建议想要通知其他开发者,都可以通过向该邮箱发送邮件来达到这个目的,相同地,你也会收到其转发的其他开发者的邮件。</p>
+<p>或者你是一个 Dubbo 的使用者,你想要得知开发者的改造方向,也可以订阅,这个<a href="https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide">指南</a>可以帮助你订阅 Dubbo 的 Mailing list。</p>
+<blockquote>
+<p>作为一个 modern developer,你可能觉得 mailing list 的交流方式存在滞后性,这样的沟通方式不是特别的高效,但它作为 apache 项目的推荐交流方式存在其特殊的原因,在此不多赘述。总之遵循一个原则:bug fix或者讨论,可以在 github issue 中进行,影响较大的特性和讨论则推荐在 mailing list 中展开。</p>
+</blockquote>
+<h2>3 其他贡献形式</h2>
+<p>不仅仅只有贡献代码,修复 bug 等行为才算作为开源做贡献,以下这些行为也属于主要形式:</p>
+<h3>3.1 撰写文档</h3>
+<p><a href="http://dubbo.apache.org/zh-cn/">Dubbo文档</a>是其开源组成成分的重要一环,其内容源文件位于:<a href="https://github.com/apache/dubbo-website">https://github.com/apache/dubbo-website</a>。同样也是一个 Git 仓库,任何你想要对 dubbo 知识点的补充,都可以在这儿提交 pull request,只需要一些 markdown 的语法知识,和一些可有可无的 npm 语法即可。如果你觉得贡献代码对于现在的自己仍然有点难度,不妨从贡献文档开始接触开源。</p>
+<h3>3.2 ISSUE</h3>
+<p>无论是 Github 中的 Issue 还是 mailing list 中的讨论,无论是提出问题,汇报 bug,还是回答问题(bugfix 则不仅仅需要 Issue 了),协助管理者 review pull request,都是贡献的一种形式,勿以善小而不为。</p>
+<h3>3.3 其他行为</h3>
+<p>任何你能够想到的,可以帮助开源项目变得更好的的行为,都属于开源贡献。例如,给每个 Issue 打上合适的 tag,关闭重复的 Issue,链接相关联的 Issue,线下组织沙龙,回答 Stack Overflow 上相关的问题,以及文档中一个错别字的修改等等。</p>
+<h2>4 开源最佳实践</h2>
+<h3>4.1 有效沟通</h3>
+<p>无论你处于什么样的目的:仅仅是一次性的贡献,亦或是永久性的加入社区,都的和他人进行沟通和交往,这是你要在开源圈发展必须修炼的技能。</p>
+<p>在你开启一个isse或PR之前,或者是在聊天室问问题之前,请牢记下面所列出的几点建议,会让你的工作更加的高效。</p>
+<p><strong>给出上下文</strong> 以便于让其他人能够快速的理解。比方说你运行程序时遇到一个错误,要解释你是如何做的,并描述如何才能再现错误现象。又比方说你是提交一个新的想法,要解释你为什么这么想,对于项目有用处吗(不仅仅是只有你!)</p>
+<blockquote>
+<p>😇 <em>“当我做 Y 的时候 X 不能工作”</em></p>
+<p>😢 <em>“X 出问题! 请修复它。”</em></p>
+</blockquote>
+<p><strong>在进一步行动前,做好准备工作。</strong> 不知道没关系,但是要展现你尝试过、努力过。在寻求帮助之前,请确认阅读了项目的 README、文档、问题(开放的和关闭的)、邮件列表,并搜索了网络。当你表现出很强烈的求知欲的时候,人们是非常欣赏这点的,会很乐意的帮助你。</p>
+<blockquote>
+<p>😇 <em>“我不确定 X 是如何实现的,我查阅了相关的帮助文档,然而毫无所获。”</em></p>
+<p>😢 <em>“我该怎么做 X ?”</em></p>
+</blockquote>
+<p><strong>保持请求内容短小而直接。</strong> 正如发送一份邮件,每一次的贡献,无论是多么的简单,都是需要他人去查阅的。很多项目都是请求的人多,提供帮助的人少。相信我,保持简洁,你能得到他人帮助的机会会大大的增加。</p>
+<blockquote>
+<p>😇 <em>“我很乐意写 API 教程。”</em></p>
+<p>😢 <em>” 有一天我驾驶汽车行驶在高速公路上,在某个加油站加油的时候,突发奇想,我们应该这么做,不过在我进一步解释之前,我先和大家展示一下。。。”</em></p>
+</blockquote>
+<p><strong>让所有的沟通都是在公开场合下进行。</strong> 哪怕是很不起眼的小事,也不要去给维护者发私信,除非是你要分享一些敏感信息(诸如安全问题或严重的过失)。你若能够保持谈话是公开的,很多人可以你们交换的意见中学习和受益。</p>
+<blockquote>
+<p>😇 <em>(评论) “@维护者 你好!我们该如何处理这个PR?”</em></p>
+<p>😢 <em>(邮件) “你好,非常抱歉给发信,但是我实在很希望你能看一下我提交的PR。”</em></p>
+</blockquote>
+<p><strong>大胆的提问(但是要谨慎!)。</strong> 每个人参与社区,开始的时候都是新手,哪怕是非常有经验的贡献者也一样,在刚进入一个新的项目的时候,也是新手。出于同样的原因,甚至长期维护人员并不总是熟悉一个项目的每一部分。给他们同样的耐心,你也会得到同样的回报。</p>
+<blockquote>
+<p>😇 <em>“感谢查看了这个错误,我按照您的建议做了,这是输出结果。”</em></p>
+<p>😢 <em>“你为什么不修复我的问题?这难道不是你的项目吗?”</em></p>
+</blockquote>
+<p><strong>尊重社区的决定。</strong> 你的想法可能会和社区的优先级、愿景等有差异,他们可能对于你的想法提供了反馈和最后的决定的理由,这时你应该去积极的讨论,并寻求妥协的办法,维护者必须慎重的考虑你的想法。但是如果你实在是不能同意社区的做法,你可以坚持自己!保持自己的分支,或者另起炉灶。</p>
+<blockquote>
+<p>😇 <em>“你不能支持我的用例,我蛮失望,但是你的解释仅仅是对一小部分用户起作用,我理解是为什么。感谢你的耐心倾听。”</em></p>
+<p>😢 <em>“你为什么不支持我的用例?这是不可接受的!”</em></p>
+</blockquote>
+<p><strong>以上几点,要铭记在心。</strong> 开源是由来自世界各地的人们共同协作实现的。面临的问题是跨语言、跨文化、不同的地理为止、不同的时区,另外,撰写文字的沟通更是难上加难,无法传达语气和情绪。请让这些会话都充满善意吧!在以下情形中请保持礼貌:推动一个想法、请求更多的上下文、进一步澄清你的立场。既然你在互联网找到了自己的所需,那么请尝试让它变得更好!</p>
+<h3>4.2 创建 issue</h3>
+<p>你应该在遇到下列情况下,去创建一个 issue:</p>
+<ul>
+<li>报告你自己无法解决的错误</li>
+<li>讨论一个高级主题或想法</li>
+<li>期望实现某新的特性,或者其它项目的想法</li>
+</ul>
+<p>在 issue 的沟通中几点实用的技巧:</p>
+<ul>
+<li><strong>如果你刚好看到一个开放的issue,恰是你打算解决的,</strong> 添加评论,告诉他人你将对此展开工作,并及时响应。这样的话,可以避免他人重复劳动。</li>
+<li><strong>如果说某个issue已经开放很久了,</strong> 这可能是已经有人正在解决中,又或者是早已经解决过了,所以也请添加评论,在打算开始工作之前,最好是确认一下。</li>
+<li><strong>如果你创建了一个issue,但是没多久自己解决了,</strong> 也要添加评论,让其他人知道,然后关闭该issue。记录本身就是对社区的贡献。</li>
+</ul>
+<h3>4.3 创建 pull request</h3>
+<p>在下面的情形时,请你务必使用 PR:</p>
+<ul>
+<li>提交补丁 (例如,纠正拼写错误、损坏的链接、或者是其它较明显的错误)</li>
+<li>开始一项别人请求的任务,或者是过去在issue中早就讨论过的</li>
+</ul>
+<p>一个 PR 并不代表着工作已经完成。它通常是尽早的开启一个PR,是为了其他人可以观看或者给作者反馈意见。只需要在子标题标记为“WIP”(正在进行中)。作者可以在后面添加很多评论。</p>
+<p>如果说项目是托管在 GitHub上的,以下是我们总结出的提交RP的建议:</p>
+<ul>
+<li><strong>Fork 代码仓库</strong> 并克隆到本地,在本地的仓库配置“上游”为远端仓库。这样你可以在提交你的PR时保持和“上游”同步,会减少很多解决冲突的时间。(更多关于同步的说明,请参考<a href="https://help.github.com/articles/syncing-a-fork/">这里</a>.)</li>
+<li><strong>创建一个分支</strong> 用于自己编辑。</li>
+<li><strong>参考任何相关的issue</strong> 或者在你的RP中支持文档(比如. “Closes #37.”)</li>
+<li><strong>包含之前和之后的快照</strong> 如果你的改动是包含了不同的 HTML/CSS。在你的PR中拖拉相应的图片。</li>
+<li><strong>测试你的改动!</strong> 若测试用例存在的话,跑一遍,以覆盖你的更改,若没有的话,则创建相应的用例。无论测试是否存在,一定要确保你的改动不会破坏掉现有的项目。</li>
+<li><strong>和项目现有的风格保持一致</strong> 尽你最大的努力,这也就是意味着在使用缩进、分号、以及注释很可能和你自己的风格大相径庭,但是为了节省维护者的精力,以及未来他人更好的理解和维护,还请你容忍一下。</li>
+</ul>
+<h2>5 成为一个开源贡献者</h2>
+<p>如果你有志于参与开源事业,可以尝试从自己最熟悉的项目开始,开源并不是属于高级开发者的专属词汇,它就是由你我这样的人在需求,修复,构建中演进下去的。Let's try it !</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-contribute-to-opensource.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-contribute-to-opensource.json
new file mode 100644
index 0000000..5aa4b6b
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-contribute-to-opensource.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-contribute-to-opensource.md",
+  "__html": "<h1>以Dubbo为例,聊聊如何向开源项目做贡献</h1>\n<p>Github 上有众多优秀的开源项目,大多数 IT 从业者将其当做了予取予求的工具库,遇到什么需求,先去 Github 搜一把,但有没有想过有一天自己也可以给开源事业做一些贡献呢?本文将会以 dubbo 项目为例,向你阐释,给开源项目做贡献并不是一件难事。</p>\n<h2>1 为何要给开源贡献力量</h2>\n<p>为开源项目做贡献得到的收益是多方面的,为了让你有足够的信心加入到开源项目中,我在文章最开始列举出它的诸多好处。</p>\n<h3>1.1 巩固技能</h3>\n<p>无论你是提交代码,撰写文档,提交 Issue,组织活动,当你切身参与到一个开源项目中,相关的技能都会得到历练,并且在开源项目中找到自己的位置。一方面,日常工作中我们中的大多数人接触到的是业务场景,并没有太多机会接触到基础架构组件�
 �开源项目为我们提供了一个平台,在这里,你可以尽情挑选自己熟悉的项目为它添砖加瓦(以 Dubbo 为例,并不是所有 IT 公司都有能力自研服务治理框架);另一方面,你所提交的 [...]
+  "link": "/zh-cn/blog/dubbo-contribute-to-opensource.html",
+  "meta": {
+    "title": "以Dubbo为例,聊聊如何向开源项目做贡献",
+    "keywords": "Dubbo, opensource",
+    "description": "本文将会以 dubbo 项目为例向你阐释,给开源项目做贡献并不是一件难事"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-copywriting-style.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-copywriting-style.html
new file mode 100644
index 0000000..9c1fa53
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-copywriting-style.html
@@ -0,0 +1,396 @@
+<!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="Dubbo, Copywriting" />
+	<meta name="description" content="统一中文文案、排版的相关用法,降低团队成员之间的沟通成本,增强网站气质。" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo 博客文档中文排版指南</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>[TOC]</p>
+<h2>空格</h2>
+<p>「有研究显示,打字的时候不喜欢在中文和英文之间加空格的人,感情路都走得很辛苦,有七成的比例会在 34 岁的时候跟自己不爱的人结婚,而其余三成的人最后只能把遗产留给自己的猫。毕竟爱情跟书写都需要适时地留白。与大家共勉之。」—— <a href="https://github.com/vinta/pangu.js">vinta/paranoid-auto-spacing</a></p>
+<h3>中英文之间需要增加空格</h3>
+<p>正确:</p>
+<blockquote>
+<p>在 LeanCloud 上,数据存储是围绕 <code>AVObject</code> 进行的。</p>
+</blockquote>
+<p>错误:</p>
+<blockquote>
+<p>在LeanCloud上,数据存储是围绕<code>AVObject</code>进行的。</p>
+</blockquote>
+<blockquote>
+<p>在 LeanCloud上,数据存储是围绕<code>AVObject</code> 进行的。</p>
+</blockquote>
+<p>完整的正确用法:</p>
+<blockquote>
+<p>在 LeanCloud 上,数据存储是围绕 <code>AVObject</code> 进行的。每个 <code>AVObject</code> 都包含了与 JSON 兼容的 key-value 对应的数据。数据是 schema-free 的,你不需要在每个 <code>AVObject</code> 上提前指定存在哪些键,只要直接设定对应的 key-value 即可。</p>
+</blockquote>
+<p>例外:「豆瓣FM」等产品名词,按照官方所定义的格式书写。</p>
+<h3>中文与数字之间需要增加空格</h3>
+<p>正确:</p>
+<blockquote>
+<p>今天出去买菜花了 5000 元。</p>
+</blockquote>
+<p>错误:</p>
+<blockquote>
+<p>今天出去买菜花了 5000元。</p>
+</blockquote>
+<blockquote>
+<p>今天出去买菜花了5000元。</p>
+</blockquote>
+<h3>数字与单位之间需要增加空格</h3>
+<p>正确:</p>
+<blockquote>
+<p>我家的光纤入户宽带有 10 Gbps,SSD 一共有 20 TB。</p>
+</blockquote>
+<p>错误:</p>
+<blockquote>
+<p>我家的光纤入户宽带有 10Gbps,SSD 一共有 10TB。</p>
+</blockquote>
+<p>例外:度/百分比与数字之间不需要增加空格:</p>
+<p>正确:</p>
+<blockquote>
+<p>今天是 233° 的高温。</p>
+</blockquote>
+<blockquote>
+<p>新 MacBook Pro 有 15% 的 CPU 性能提升。</p>
+</blockquote>
+<p>错误:</p>
+<blockquote>
+<p>今天是 233 ° 的高温。</p>
+</blockquote>
+<blockquote>
+<p>新 MacBook Pro 有 15 % 的 CPU 性能提升。</p>
+</blockquote>
+<h3>全角标点与其他字符之间不加空格</h3>
+<p>正确:</p>
+<blockquote>
+<p>刚刚买了一部 iPhone,好开心!</p>
+</blockquote>
+<p>错误:</p>
+<blockquote>
+<p>刚刚买了一部 iPhone ,好开心!</p>
+</blockquote>
+<h3><code>-ms-text-autospace</code> to the rescue?</h3>
+<p>Microsoft 有个 <a href="http://msdn.microsoft.com/en-us/library/ie/ms531164(v=vs.85).aspx"><code>-ms-text-autospace</code></a> 的 CSS 属性可以实现自动为中英文之间增加空白。不过目前并未普及,另外在其他应用场景,例如 OS X、iOS 的用户界面目前并不存在这个特性,所以请继续保持随手加空格的习惯。</p>
+<h2>标点符号</h2>
+<h3>不重复使用标点符号</h3>
+<p>正确:</p>
+<blockquote>
+<p>德国队竟然战胜了巴西队!</p>
+</blockquote>
+<blockquote>
+<p>她竟然对你说「喵」?!</p>
+</blockquote>
+<p>错误:</p>
+<blockquote>
+<p>德国队竟然战胜了巴西队!!</p>
+</blockquote>
+<blockquote>
+<p>德国队竟然战胜了巴西队!!!!!!!!</p>
+</blockquote>
+<blockquote>
+<p>她竟然对你说「喵」??!!</p>
+</blockquote>
+<blockquote>
+<p>她竟然对你说「喵」?!?!??!!</p>
+</blockquote>
+<h2>全角和半角</h2>
+<p>不明白什么是全角(全形)与半角(半形)符号?请查看维基百科词条『<a href="http://zh.wikipedia.org/wiki/%E5%85%A8%E5%BD%A2%E5%92%8C%E5%8D%8A%E5%BD%A2">全角和半角</a>』。</p>
+<h3>使用全角中文标点</h3>
+<p>正确:</p>
+<blockquote>
+<p>嗨!你知道嘛?今天前台的小妹跟我说「喵」了哎!</p>
+</blockquote>
+<blockquote>
+<p>核磁共振成像(NMRI)是什么原理都不知道?JFGI!</p>
+</blockquote>
+<p>错误:</p>
+<blockquote>
+<p>嗨! 你知道嘛? 今天前台的小妹跟我说 “喵” 了哎!</p>
+</blockquote>
+<blockquote>
+<p>嗨!你知道嘛?今天前台的小妹跟我说”喵”了哎!</p>
+</blockquote>
+<blockquote>
+<p>核磁共振成像 (NMRI) 是什么原理都不知道? JFGI!</p>
+</blockquote>
+<blockquote>
+<p>核磁共振成像(NMRI)是什么原理都不知道?JFGI!</p>
+</blockquote>
+<h3>数字使用半角字符</h3>
+<p>正确:</p>
+<blockquote>
+<p>这件蛋糕只卖 1000 元。</p>
+</blockquote>
+<p>错误:</p>
+<blockquote>
+<p>这件蛋糕只卖 1000 元。</p>
+</blockquote>
+<p>例外:在设计稿、宣传海报中如出现极少量数字的情形时,为方便文字对齐,是可以使用全角数字的。</p>
+<h3>遇到完整的英文整句、特殊名词,其內容使用半角标点</h3>
+<p>正确:</p>
+<blockquote>
+<p>乔布斯那句话是怎么说的?「Stay hungry, stay foolish.」</p>
+</blockquote>
+<blockquote>
+<p>推荐你阅读《Hackers &amp; Painters: Big Ideas from the Computer Age》,非常的有趣。</p>
+</blockquote>
+<p>错误:</p>
+<blockquote>
+<p>乔布斯那句话是怎么说的?「Stay hungry,stay foolish。」</p>
+</blockquote>
+<blockquote>
+<p>推荐你阅读《Hackers&Painters:Big Ideas from the Computer Age》,非常的有趣。</p>
+</blockquote>
+<h2>名词</h2>
+<h3>专有名词使用正确的大小写</h3>
+<p>大小写相关用法原属于英文书写范畴,不属于本 wiki 讨论內容,在这里只对部分易错用法进行简述。</p>
+<p>正确:</p>
+<blockquote>
+<p>使用 GitHub 登录</p>
+</blockquote>
+<blockquote>
+<p>我们的客户有 GitHub、Foursquare、Microsoft Corporation、Google、Facebook, Inc.。</p>
+</blockquote>
+<p>错误:</p>
+<blockquote>
+<p>使用 github 登录</p>
+</blockquote>
+<blockquote>
+<p>使用 GITHUB 登录</p>
+</blockquote>
+<blockquote>
+<p>使用 Github 登录</p>
+</blockquote>
+<blockquote>
+<p>使用 gitHub 登录</p>
+</blockquote>
+<blockquote>
+<p>使用 gイんĤЦ8 登录</p>
+</blockquote>
+<blockquote>
+<p>我们的客户有 github、foursquare、microsoft corporation、google、facebook, inc.。</p>
+</blockquote>
+<blockquote>
+<p>我们的客户有 GITHUB、FOURSQUARE、MICROSOFT CORPORATION、GOOGLE、FACEBOOK, INC.。</p>
+</blockquote>
+<blockquote>
+<p>我们的客户有 Github、FourSquare、MicroSoft Corporation、Google、FaceBook, Inc.。</p>
+</blockquote>
+<blockquote>
+<p>我们的客户有 gitHub、fourSquare、microSoft Corporation、google、faceBook, Inc.。</p>
+</blockquote>
+<blockquote>
+<p>我们的客户有 gイんĤЦ8、キouЯƧquムгє、๓เςг๏ร๏Ŧt ς๏гק๏гคtเ๏ภn、900913、ƒ4ᄃëв๏๏к, IПᄃ.。</p>
+</blockquote>
+<p>注意:当网页中需要配合整体视觉风格而出现全部大写/小写的情形,HTML 中请使用标准的大小写规范进行书写;并通过 <code>text-transform: uppercase;</code>/<code>text-transform: lowercase;</code> 对表现形式进行定义。</p>
+<h3>不要使用不地道的缩写</h3>
+<p>正确:</p>
+<blockquote>
+<p>我们需要一位熟悉 JavaScript、HTML5,至少理解一种框架(如 Backbone.js、AngularJS、React 等)的前端开发者。</p>
+</blockquote>
+<p>错误:</p>
+<blockquote>
+<p>我们需要一位熟悉 Js、h5,至少理解一种框架(如 backbone、angular、RJS 等)的 FED。</p>
+</blockquote>
+<h2>争议</h2>
+<p>以下用法略带有个人色彩,即:无论是否遵循下述规则,从语法的角度来讲都是<strong>正确</strong>的。</p>
+<h3>链接之间增加空格</h3>
+<p>用法:</p>
+<blockquote>
+<p>请 <a href="https://www.cnkirito.moe/chinese-copywriting-guidelines/#">提交一个 issue</a> 并分配给相关同事。</p>
+</blockquote>
+<blockquote>
+<p>访问我们网站的最新动态,请 <a href="https://www.cnkirito.moe/chinese-copywriting-guidelines/#">点击这里</a> 进行订阅!</p>
+</blockquote>
+<p>对比用法:</p>
+<blockquote>
+<p>请<a href="https://www.cnkirito.moe/chinese-copywriting-guidelines/#">提交一个 issue</a> 并分配给相关同事。</p>
+</blockquote>
+<blockquote>
+<p>访问我们网站的最新动态,请<a href="https://www.cnkirito.moe/chinese-copywriting-guidelines/#">点击这里</a>进行订阅!</p>
+</blockquote>
+<h3>简体中文使用直角引号</h3>
+<p>用法:</p>
+<blockquote>
+<p>「老师,『有条不紊』的『紊』是什么意思?」</p>
+</blockquote>
+<p>对比用法:</p>
+<blockquote>
+<p>“老师,‘有条不紊’的‘紊’是什么意思?”</p>
+</blockquote>
+<h2>工具</h2>
+<table>
+<thead>
+<tr>
+<th>仓库</th>
+<th>语言</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><a href="https://github.com/vinta/paranoid-auto-spacing">vinta/paranoid-auto-spacing</a></td>
+<td>JavaScript</td>
+</tr>
+<tr>
+<td><a href="https://github.com/huei90/pangu.node">huei90/pangu.node</a></td>
+<td>Node.js</td>
+</tr>
+<tr>
+<td><a href="https://github.com/huacnlee/auto-correct">huacnlee/auto-correct</a></td>
+<td>Ruby</td>
+</tr>
+<tr>
+<td><a href="https://github.com/sparanoid/space-lover">sparanoid/space-lover</a></td>
+<td>PHP (WordPress)</td>
+</tr>
+<tr>
+<td><a href="https://github.com/NauxLiu/auto-correct">nauxliu/auto-correct</a></td>
+<td>PHP</td>
+</tr>
+<tr>
+<td><a href="https://github.com/ricoa/copywriting-correct">ricoa/copywriting-correct</a></td>
+<td>PHP</td>
+</tr>
+<tr>
+<td><a href="https://github.com/hotoo/pangu.vim">hotoo/pangu.vim</a></td>
+<td>Vim</td>
+</tr>
+<tr>
+<td><a href="https://github.com/sparanoid/grunt-auto-spacing">sparanoid/grunt-auto-spacing</a></td>
+<td>Node.js (Grunt)</td>
+</tr>
+<tr>
+<td><a href="https://github.com/hjiang/scripts/blob/master/add-space-between-latin-and-cjk">hjiang/scripts/add-space-between-latin-and-cjk</a></td>
+<td>Python</td>
+</tr>
+</tbody>
+</table>
+<h2>谁在这样做?</h2>
+<table>
+<thead>
+<tr>
+<th>网站</th>
+<th>文案</th>
+<th>UGC</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><a href="http://www.apple.com/cn/">Apple 中国</a></td>
+<td>Yes</td>
+<td>N/A</td>
+</tr>
+<tr>
+<td><a href="http://www.apple.com/hk/">Apple 香港</a></td>
+<td>Yes</td>
+<td>N/A</td>
+</tr>
+<tr>
+<td><a href="http://www.apple.com/tw/">Apple 台湾</a></td>
+<td>Yes</td>
+<td>N/A</td>
+</tr>
+<tr>
+<td><a href="http://www.microsoft.com/zh-cn/">Microsoft 中国</a></td>
+<td>Yes</td>
+<td>N/A</td>
+</tr>
+<tr>
+<td><a href="http://www.microsoft.com/zh-hk/">Microsoft 香港</a></td>
+<td>Yes</td>
+<td>N/A</td>
+</tr>
+<tr>
+<td><a href="http://www.microsoft.com/zh-tw/">Microsoft 台湾</a></td>
+<td>Yes</td>
+<td>N/A</td>
+</tr>
+<tr>
+<td><a href="https://leancloud.cn/">LeanCloud</a></td>
+<td>Yes</td>
+<td>N/A</td>
+</tr>
+<tr>
+<td><a href="https://www.zhihu.com/">知乎</a></td>
+<td>Yes</td>
+<td>部分用户达成</td>
+</tr>
+<tr>
+<td><a href="https://www.v2ex.com/">V2EX</a></td>
+<td>Yes</td>
+<td>Yes</td>
+</tr>
+<tr>
+<td><a href="https://segmentfault.com/">SegmentFault</a></td>
+<td>Yes</td>
+<td>部分用户达成</td>
+</tr>
+<tr>
+<td><a href="http://apple4us.com/">Apple4us</a></td>
+<td>Yes</td>
+<td>N/A</td>
+</tr>
+<tr>
+<td><a href="https://www.wandoujia.com/">豌豆荚</a></td>
+<td>Yes</td>
+<td>N/A</td>
+</tr>
+<tr>
+<td><a href="https://ruby-china.org/">Ruby China</a></td>
+<td>Yes</td>
+<td>标题达成</td>
+</tr>
+<tr>
+<td><a href="https://phphub.org/">PHPHub</a></td>
+<td>Yes</td>
+<td>标题达成</td>
+</tr>
+<tr>
+<td><a href="http://sspai.com/">少数派</a></td>
+<td>Yes</td>
+<td>N/A</td>
+</tr>
+</tbody>
+</table>
+<h2>参考文献</h2>
+<ul>
+<li><a href="http://grammar.about.com/od/punctuationandmechanics/a/Guidelines-For-Using-Capital-Letters.htm">Guidelines for Using Capital Letters</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Letter_case">Letter case - Wikipedia</a></li>
+<li><a href="http://www.oxforddictionaries.com/words/punctuation">Punctuation - Oxford Dictionaries</a></li>
+<li><a href="https://owl.english.purdue.edu/owl/section/1/6/">Punctuation - The Purdue OWL</a></li>
+<li><a href="http://www.wikihow.com/Use-English-Punctuation-Correctly">How to Use English Punctuation Corrently - wikiHow</a></li>
+<li><a href="https://zh.opensuse.org/index.php?title=Help:%E6%A0%BC%E5%BC%8F">格式 - openSUSE</a></li>
+<li><a href="http://zh.wikipedia.org/wiki/%E5%85%A8%E5%BD%A2%E5%92%8C%E5%8D%8A%E5%BD%A2">全角和半角 - 维基百科</a></li>
+<li><a href="http://zh.wikipedia.org/wiki/%E5%BC%95%E8%99%9F">引号 - 维基百科</a></li>
+<li><a href="http://zh.wikipedia.org/wiki/%E7%96%91%E5%95%8F%E9%A9%9A%E5%98%86%E8%99%9F">疑问惊叹号 - 维基百科</a></li>
+</ul>
+<blockquote>
+<p>统一中文文案、排版的相关用法,降低团队成员之间的沟通成本,增强网站气质。原文出处:<a href="https://github.com/mzlogin/chinese-copywriting-guidelines">https://github.com/mzlogin/chinese-copywriting-guidelines</a></p>
+</blockquote>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-copywriting-style.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-copywriting-style.json
new file mode 100644
index 0000000..734b1d2
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-copywriting-style.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-copywriting-style.md",
+  "__html": "<h1>Dubbo 博客文档中文排版指南</h1>\n<p>[TOC]</p>\n<h2>空格</h2>\n<p>「有研究显示,打字的时候不喜欢在中文和英文之间加空格的人,感情路都走得很辛苦,有七成的比例会在 34 岁的时候跟自己不爱的人结婚,而其余三成的人最后只能把遗产留给自己的猫。毕竟爱情跟书写都需要适时地留白。与大家共勉之。」—— <a href=\"https://github.com/vinta/pangu.js\">vinta/paranoid-auto-spacing</a></p>\n<h3>中英文之间需要增加空格</h3>\n<p>正确:</p>\n<blockquote>\n<p>在 LeanCloud 上,数据存储是围绕 <code>AVObject</code> 进行的。</p>\n</blockquote>\n<p>错误:</p>\n<blockquote>\n<p>在LeanCloud上,数据存储是围绕<code>AVObject</code>进行的。</p>\n</blockquote>\n<blockquote> [...]
+  "link": "/zh-cn/blog/dubbo-copywriting-style.html",
+  "meta": {
+    "title": "Dubbo 博客文档中文排版指南",
+    "keywords": "Dubbo, Copywriting",
+    "description": "统一中文文案、排版的相关用法,降低团队成员之间的沟通成本,增强网站气质。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-echo-test.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-echo-test.html
new file mode 100644
index 0000000..f944b7f
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-echo-test.html
@@ -0,0 +1,111 @@
+<!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="dubbo-echo-test" />
+	<meta name="description" content="dubbo-echo-test" />
+	<!-- 网页标签标题 -->
+	<title>dubbo-echo-test</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>回声测试用于检测服务是否可用。客户端通过 EchoService 来使用回声测试。EchoService 申明如下:</p>
+<pre><code class="language-Java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">EchoService</span> </span>{
+
+    <span class="hljs-comment">/**
+     * echo test.
+     *
+     * <span class="hljs-doctag">@param</span> message message.
+     * <span class="hljs-doctag">@return</span> message.
+     */</span>
+    Object $echo(Object message);
+
+}
+</code></pre>
+<p>用户通过 $echo 方法发起的请求,会按照正常请求的流程执行,能够测试整个调用是否通畅,监控系统可以使用回声测试来检测服务可用性。</p>
+<h2>使用范例</h2>
+<p>所有服务引用自动实现 EchoService 接口,用户只需将服务引用强制转型为 EchoService,即可使用。配置和代码范例如下所示。
+Spring 配置:</p>
+<pre><code>&lt;dubbo:reference id=&quot;demoService&quot; interface=&quot;org.apache.dubbo.samples.echo.DemoService&quot; /&gt;
+</code></pre>
+<p>代码:</p>
+<pre><code class="language-Java"><span class="hljs-comment">// 远程服务引用</span>
+DemoService demoService= ctx.getBean(<span class="hljs-string">"demoService"</span>);
+<span class="hljs-comment">// 强制转型为EchoService</span>
+EchoService echoService = (EchoService) demoService;
+<span class="hljs-comment">// 回声测试可用性</span>
+String status = echoService.$echo(<span class="hljs-string">"OK"</span>);
+<span class="hljs-keyword">assert</span>(status.equals(<span class="hljs-string">"OK"</span>));
+</code></pre>
+<h2>实现原理</h2>
+<p>我们在配置服务引用时,并没有配置 EchoService 这个接口,为什么可以直接把服务引用转型为 EchoService 呢?
+用户拿到的服务引用其实是一个 Proxy,Dubbo 在生成 Proxy 的时候,已经默认将 EchoService 这个接口加入到 Proxy 的接口列表中,所以用户拿到的 Proxy 都已经实现了 EchoService。生成代理相关代码如下:</p>
+<pre><code class="language-Java"> <span class="hljs-keyword">public</span> &lt;T&gt; <span class="hljs-function">T <span class="hljs-title">getProxy</span><span class="hljs-params">(Invoker&lt;T&gt; invoker, <span class="hljs-keyword">boolean</span> generic)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+        Class&lt;?&gt;[] interfaces = <span class="hljs-keyword">null</span>;
+        String config = invoker.getUrl().getParameter(Constants.INTERFACES);
+        <span class="hljs-keyword">if</span> (config != <span class="hljs-keyword">null</span> &amp;&amp; config.length() &gt; <span class="hljs-number">0</span>) {
+            String[] types = Constants.COMMA_SPLIT_PATTERN.split(config);
+            <span class="hljs-keyword">if</span> (types != <span class="hljs-keyword">null</span> &amp;&amp; types.length &gt; <span class="hljs-number">0</span>) {
+                interfaces = <span class="hljs-keyword">new</span> Class&lt;?&gt;[types.length + <span class="hljs-number">2</span>];
+                interfaces[<span class="hljs-number">0</span>] = invoker.getInterface();
+                interfaces[<span class="hljs-number">1</span>] = EchoService<span class="hljs-class">.<span class="hljs-keyword">class</span></span>;
+                <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; types.length; i++) {
+                    <span class="hljs-comment">// TODO can we load successfully for a different classloader?.</span>
+                    interfaces[i + <span class="hljs-number">2</span>] = ReflectUtils.forName(types[i]);
+                }
+            }
+        }
+        <span class="hljs-keyword">if</span> (interfaces == <span class="hljs-keyword">null</span>) {
+            interfaces = <span class="hljs-keyword">new</span> Class&lt;?&gt;[]{invoker.getInterface(), EchoService<span class="hljs-class">.<span class="hljs-keyword">class</span>}</span>;
+        }
+
+        <span class="hljs-keyword">if</span> (!GenericService<span class="hljs-class">.<span class="hljs-keyword">class</span>.<span class="hljs-title">isAssignableFrom</span>(<span class="hljs-title">invoker</span>.<span class="hljs-title">getInterface</span>()) &amp;&amp; <span class="hljs-title">generic</span>) </span>{
+            <span class="hljs-keyword">int</span> len = interfaces.length;
+            Class&lt;?&gt;[] temp = interfaces;
+            interfaces = <span class="hljs-keyword">new</span> Class&lt;?&gt;[len + <span class="hljs-number">1</span>];
+            System.arraycopy(temp, <span class="hljs-number">0</span>, interfaces, <span class="hljs-number">0</span>, len);
+            interfaces[len] = com.alibaba.dubbo.rpc.service.GenericService<span class="hljs-class">.<span class="hljs-keyword">class</span></span>;
+        }
+
+        <span class="hljs-keyword">return</span> getProxy(invoker, interfaces);
+    }
+</code></pre>
+<p>通过这种方式,任何服务引用都可以被转型成 EchoService 来使用。
+上面解释了客户端的实现,另外一边,用户在服务端也并没有实现 EchoService,那么客户端 EchoService 发出的调用在服务端是如何处理的呢?框架使用 Filter 机制来处理 EchoService 请求。Filter 实现代码如下:</p>
+<pre><code class="language-Java"><span class="hljs-meta">@Activate</span>(group = Constants.PROVIDER, order = -<span class="hljs-number">110000</span>)
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">EchoFilter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Filter</span> </span>{
+
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> Result <span class="hljs-title">invoke</span><span class="hljs-params">(Invoker&lt;?&gt; invoker, Invocation inv)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+        <span class="hljs-keyword">if</span> (inv.getMethodName().equals(Constants.$ECHO) &amp;&amp; inv.getArguments() != <span class="hljs-keyword">null</span> &amp;&amp; inv.getArguments().length == <span class="hljs-number">1</span>) {
+            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> RpcResult(inv.getArguments()[<span class="hljs-number">0</span>]);
+        }
+        <span class="hljs-keyword">return</span> invoker.invoke(inv);
+    }
+
+}
+</code></pre>
+<p>请求经过 EchoFilter.invoke 方法时,如果判定为 $echo 调用,则直接返回请求参数,否则继续执行 Filter 链。EchoFilter 默认加入到每一个服务提供者的 Filter 链里 EchoFilter.invoke 方法时,如果判定为 $echo 调用,则直接返回请求参数,否则继续执行 Filter 链。EchoFilter 默认加入到每一个服务提供者的 Filter 链里。这样每一个服务提供者自动具备了响应 EchoService 的能力。</p>
+<p>通过上述分析,我们了解了框架是如何通过动态代理和 Filter 机制,使得用户可以透明地使用 EchoService 功能。</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-echo-test.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-echo-test.json
new file mode 100644
index 0000000..d2608cb
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-echo-test.json
@@ -0,0 +1,6 @@
+{
+  "filename": "dubbo-echo-test.md",
+  "__html": "<h1>回声测试</h1>\n<p>回声测试用于检测服务是否可用。客户端通过 EchoService 来使用回声测试。EchoService 申明如下:</p>\n<pre><code class=\"language-Java\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">interface</span> <span class=\"hljs-title\">EchoService</span> </span>{\n\n    <span class=\"hljs-comment\">/**\n     * echo test.\n     *\n     * <span class=\"hljs-doctag\">@param</span> message message.\n     * <span class=\"hljs-doctag\">@return</span> messag [...]
+  "link": "/zh-cn/blog/dubbo-echo-test.html",
+  "meta": {}
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-externalized-configuration.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-externalized-configuration.html
new file mode 100644
index 0000000..b4e3b4e
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-externalized-configuration.html
@@ -0,0 +1,543 @@
+<!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="dubbo-externalized-configuration" />
+	<meta name="description" content="dubbo-externalized-configuration" />
+	<!-- 网页标签标题 -->
+	<title>dubbo-externalized-configuration</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>外部化配置(External Configuration)</h2>
+<p>在<a href="Dubbo-Annotation-Driven.md">Dubbo 注解驱动</a>例子中,无论是服务提供方,还是服务消费方,均需要转配相关配置Bean:</p>
+<pre><code class="language-java">    <span class="hljs-meta">@Bean</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> ApplicationConfig <span class="hljs-title">applicationConfig</span><span class="hljs-params">()</span> </span>{
+        ApplicationConfig applicationConfig = <span class="hljs-keyword">new</span> ApplicationConfig();
+        applicationConfig.setName(<span class="hljs-string">"dubbo-annotation-consumer"</span>);
+        <span class="hljs-keyword">return</span> applicationConfig;
+    }
+</code></pre>
+<p>虽然实现类似于<code>ProviderConfiguration</code> 和 <code>ConsumerConfiguration</code> 这样的 Spring  <code>@Configuration</code> Bean 成本并不高,不过通过 Java Code 的方式定义配置 Bean,或多或少是一种 Hard Code(硬编码)的行为,缺少弹性。</p>
+<p>尽管在 Spring 应用中,可以通过 <code>@Value</code> 或者 <code>Environment</code> 的方式获取外部配置,其代码简洁性以及类型转换灵活性存在明显的不足。因此,Spring Boot  提出了外部化配置(External Configuration)的感念,即通过程序以外的配置源,动态地绑定指定类型。</p>
+<p>随着 Spring Boot / Spring Cloud 应用的流行,开发人员逐渐地接受并且使用 Spring Boot 外部化配置(External Configuration),即通过 <code>application.properties</code> 或者 <code>bootstrap.properties</code> 装配配置 Bean。</p>
+<p>下列表格记录了 Dubbo 内置配置类:</p>
+<table>
+<thead>
+<tr>
+<th>配置类</th>
+<th>标签</th>
+<th>用途</th>
+<th>解释</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><code>ProtocolConfig</code></td>
+<td><code>&lt;dubbo:protocol/&gt;</code></td>
+<td>协议配置</td>
+<td>用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受</td>
+</tr>
+<tr>
+<td><code>ApplicationConfig</code></td>
+<td><code>&lt;dubbo:application/&gt;</code></td>
+<td>应用配置</td>
+<td>用于配置当前应用信息,不管该应用是提供者还是消费者</td>
+</tr>
+<tr>
+<td><code>ModuleConfig</code></td>
+<td><code>&lt;dubbo:module/&gt;</code></td>
+<td>模块配置</td>
+<td>用于配置当前模块信息,可选</td>
+</tr>
+<tr>
+<td><code>RegistryConfig</code></td>
+<td><code>&lt;dubbo:registry/&gt;</code></td>
+<td>注册中心配置</td>
+<td>用于配置连接注册中心相关信息</td>
+</tr>
+<tr>
+<td><code>MonitorConfig</code></td>
+<td><code>&lt;dubbo:monitor/&gt;</code></td>
+<td>监控中心配置</td>
+<td>用于配置连接监控中心相关信息,可选</td>
+</tr>
+<tr>
+<td><code>ProviderConfig</code></td>
+<td><code>&lt;dubbo:provider/&gt;</code></td>
+<td>提供方配置</td>
+<td>当 ProtocolConfig 和 ServiceConfig 某属性没有配置时,采用此缺省值,可选</td>
+</tr>
+<tr>
+<td><code>ConsumerConfig</code></td>
+<td><code>&lt;dubbo:consumer/&gt;</code></td>
+<td>消费方配置</td>
+<td>当 ReferenceConfig 某属性没有配置时,采用此缺省值,可选</td>
+</tr>
+<tr>
+<td><code>MethodConfig</code></td>
+<td><code>&lt;dubbo:method/&gt;</code></td>
+<td>方法配置</td>
+<td>用于 ServiceConfig 和 ReferenceConfig 指定方法级的配置信息</td>
+</tr>
+<tr>
+<td><code>ArgumentConfig</code></td>
+<td><code>&lt;dubbo:argument/&gt;</code></td>
+<td>参数配置</td>
+<td>用于指定方法参数配置</td>
+</tr>
+</tbody>
+</table>
+<p>通过申明对应的 Spring 扩展标签,在 Spring 应用上下文中将自动生成相应的配置 Bean。</p>
+<p>在 Dubbo 官方用户手册的<a href="/docs/zh-cn/user/configuration/configuration-load-process.md">“属性配置”</a>章节中,<code>dubbo.properties</code> 配置属性能够映射到  <code>ApplicationConfig</code> 、<code>ProtocolConfig</code> 以及 <code>RegistryConfig</code> 的字段。从某种意义上来说,<code>dubbo.properties</code>  也是 Dubbo 的外部化配置。</p>
+<p>其中,引用“映射规则”的内容:</p>
+<blockquote>
+<h2>映射规则</h2>
+<p>将 XML 配置的标签名,加属性名,用点分隔,多个属性拆成多行</p>
+<ul>
+<li>比如:<code>dubbo.application.name=foo</code>等价于<code>&lt;dubbo:application name=&quot;foo&quot; /&gt;</code></li>
+<li>比如:<code>dubbo.registry.address=10.20.153.10:9090</code>等价于<code>&lt;dubbo:registryaddress=&quot;10.20.153.10:9090&quot; /&gt;</code></li>
+</ul>
+<p>如果 XML 有多行同名标签配置,可用 id 号区分,如果没有 id 号将对所有同名标签生效</p>
+<ul>
+<li>比如:<code>dubbo.protocol.rmi.port=1234</code>等价于<code>&lt;dubbo:protocol id=&quot;rmi&quot; name=&quot;rmi&quot; port=&quot;1099&quot; /&gt;</code></li>
+<li>比如:<code>dubbo.registry.china.address=10.20.153.10:9090</code>等价于<code>&lt;dubbo:registry id=&quot;china&quot;address=&quot;10.20.153.10:9090&quot; /&gt;</code></li>
+</ul>
+<p>下面是 dubbo.properties 的一个典型配置:</p>
+<pre><code>dubbo.application.name=foo
+dubbo.application.owner=bar
+dubbo.registry.address=10.20.153.10:9090
+</code></pre>
+</blockquote>
+<p>根据“映射规则”,Dubbo 即支持单配置 Bean 映射,也支持多 Bean 映射。综合以上需求,既要兼容 Dubbo 已有的一个或多个 Bean 字段映射绑定,也支持外部化配置。</p>
+<blockquote>
+<p>特别提醒:外部化配置(External Configuration)并非 Spring Boot 特有,即使在 Spring Framework 场景下亦能支持。也就是说 Dubbo 外部化配置即可在 Spring Framework 中工作,也能在 Spring Boot 中运行。</p>
+</blockquote>
+<p>Dubbo 外部化配置(External Configuration) 支持起始版本为:<code>2.5.8</code></p>
+<h3><code>@EnableDubboConfig</code></h3>
+<h4>起始版本:<code>2.5.8</code></h4>
+<h4>使用说明</h4>
+<h5><code>@EnableDubboConfig</code> 定义</h5>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-meta">@interface</span> EnableDubboConfig {
+
+    <span class="hljs-comment">/**
+     * It indicates whether binding to multiple Spring Beans.
+     *
+     * <span class="hljs-doctag">@return</span> the default value is &lt;code&gt;false&lt;/code&gt;
+     * <span class="hljs-doctag">@revised</span> 2.5.9
+     */</span>
+    <span class="hljs-function"><span class="hljs-keyword">boolean</span> <span class="hljs-title">multiple</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">false</span></span>;
+
+}
+</code></pre>
+<ul>
+<li><code>multiple</code> : 表示是否支持多Dubbo 配置 Bean 绑定。默认值为 <code>false</code> ,即单 Dubbo 配置 Bean 绑定</li>
+</ul>
+<h5>单 Dubbo 配置 Bean 绑定</h5>
+<p>为了更好地向下兼容,<code>@EnableDubboConfig</code> 提供外部化配置属性与 Dubbo 配置类之间的绑定,其中映射关系如下:</p>
+<table>
+<thead>
+<tr>
+<th>配置类</th>
+<th>外部化配置属性前缀</th>
+<th>用途</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><code>ProtocolConfig</code></td>
+<td><code>dubbo.protocol</code></td>
+<td>协议配置</td>
+</tr>
+<tr>
+<td><code>ApplicationConfig</code></td>
+<td><code>dubbo.application</code></td>
+<td>应用配置</td>
+</tr>
+<tr>
+<td><code>ModuleConfig</code></td>
+<td><code>dubbo.module</code></td>
+<td>模块配置</td>
+</tr>
+<tr>
+<td><code>RegistryConfig</code></td>
+<td><code>dubbo.registry</code></td>
+<td>注册中心配置</td>
+</tr>
+<tr>
+<td><code>MonitorConfig</code></td>
+<td><code>dubbo.monitor</code></td>
+<td>监控中心配置</td>
+</tr>
+<tr>
+<td><code>ProviderConfig</code></td>
+<td><code>dubbo.provider</code></td>
+<td>提供方配置</td>
+</tr>
+<tr>
+<td><code>ConsumerConfig</code></td>
+<td><code>dubbo.consumer</code></td>
+<td>消费方配置</td>
+</tr>
+</tbody>
+</table>
+<p>当标注 <code>@EnableDubboConfig</code> 的类被扫描注册后,同时  Spring(Spring Boot)应用配置(<code>PropertySources</code>)中存在<code>dubbo.application.*</code> 时,<code>ApplicationConfig</code>  Bean 将被注册到在 Spring 上下文。否则,不会被注册。如果出现<code>dubbo.registry.*</code>的配置,那么,<code>RegistryConfig</code> Bean 将会创建,以此类推。即按需装配 Dubbo 配置 Bean。</p>
+<p>如果需要指定配置 Bean的 id,可通过<code>**.id</code> 属性设置,以<code>dubbo.application</code> 为例:</p>
+<pre><code class="language-properties"><span class="hljs-comment">## application</span>
+<span class="hljs-meta">dubbo.application.id</span> = <span class="hljs-string">applicationBean</span>
+<span class="hljs-meta">dubbo.application.name</span> = <span class="hljs-string">dubbo-demo-application</span>
+</code></pre>
+<p>以上配置等同于以下 Java Config Bean:</p>
+<pre><code class="language-java">    <span class="hljs-meta">@Bean</span>(<span class="hljs-string">"applicationBean"</span>)
+    <span class="hljs-function"><span class="hljs-keyword">public</span> ApplicationConfig <span class="hljs-title">applicationBean</span><span class="hljs-params">()</span> </span>{
+        ApplicationConfig applicationConfig = <span class="hljs-keyword">new</span> ApplicationConfig();
+        applicationConfig.setName(<span class="hljs-string">"dubbo-demo-application"</span>);
+        <span class="hljs-keyword">return</span> applicationConfig;
+    }
+</code></pre>
+<p>大致上配置属性与配置类绑定模式 - <code>dubbo.application.*</code> 映射到 <code>ApplicationConfig</code> 中的字段。</p>
+<blockquote>
+<p>注:当配置属性名称无法在配置类中找到字段时,将会忽略绑定</p>
+</blockquote>
+<h5>多 Dubbo 配置 Bean 绑定</h5>
+<p>Dubbo <code>@Service</code> 和 <code>@Reference</code> 允许 Dubbo 应用关联<code>ApplicationConfig</code> Bean 或者指定多个<code>RegistryConfig</code> Bean 等能力。换句话说,Dubbo 应用上下文中可能存在多个<code>ApplicationConfig</code> 等 Bean定义。</p>
+<p>为了适应以上需要,因此从Dubbo <code>2.5.9</code> 开始,<code>@EnableDubboConfig</code> 支持多 Dubbo 配置 Bean 绑定,同时按照业界规约标准,与单 Dubbo 配置 Bean 绑定约定不同,配置属性前缀均为英文复数形式:</p>
+<blockquote>
+<p>详情请参考 :<a href="https://github.com/alibaba/dubbo/issues/1141">https://github.com/alibaba/dubbo/issues/1141</a></p>
+</blockquote>
+<ul>
+<li><code>dubbo.applications</code></li>
+<li><code>dubbo.modules</code></li>
+<li><code>dubbo.registries</code></li>
+<li><code>dubbo.protocols</code></li>
+<li><code>dubbo.monitors</code></li>
+<li><code>dubbo.providers</code></li>
+<li><code>dubbo.consumers</code></li>
+</ul>
+<p>以<code>dubbo.applications</code> 为例,基本的模式如下:</p>
+<pre><code class="language-properties"><span class="hljs-meta">dubbo.applications.${bean-name}.property-name</span> = <span class="hljs-string">${property-value}</span>
+</code></pre>
+<p>请读者注意,在单 Dubbo 配置 Bean 绑定时,可以通过指定<code>id</code> 属性的方式,定义<code>ApplicationConfig</code> Bean 的ID,即<code>dubbo.application.id</code>。</p>
+<p>而在多 Dubbo 配置 Bean 绑定时,Bean ID 则由<code>dubbo.applications.</code>与属性字段名称(<code>.property-name</code>)之间的字符来表达。</p>
+<p>如下配置:</p>
+<pre><code class="language-properties"><span class="hljs-comment"># multiple Bean definition</span>
+<span class="hljs-meta">dubbo.applications.applicationBean.name</span> = <span class="hljs-string">dubbo-demo-application</span>
+<span class="hljs-meta">dubbo.applications.applicationBean2.name</span> = <span class="hljs-string">dubbo-demo-application2</span>
+<span class="hljs-meta">dubbo.applications.applicationBean3.name</span> = <span class="hljs-string">dubbo-demo-application3</span>
+</code></pre>
+<p>该配置内容中,绑定了三个<code>ApplicationConfig</code> Bean,分别是<code>applicationBean</code>、<code>applicationBean2</code>以及<code>applicationBean3</code></p>
+<h4>示例说明</h4>
+<p><code>@EnableDubboConfig</code> 的使用方法很简答, 再次强调一点,当规约的外部配置存在时,相应的 Dubbo 配置类 才会提升为 Spring Bean。简言之,按需装配。</p>
+<h5>单 Dubbo 配置 Bean 绑定</h5>
+<h6>外部化配置文件</h6>
+<p>将以下内容的外部化配置文件物理路径为:<code>classpath:/META-INF/config.properties</code>:</p>
+<pre><code class="language-properties"><span class="hljs-comment"># 单 Dubbo 配置 Bean 绑定</span>
+<span class="hljs-comment">## application</span>
+<span class="hljs-meta">dubbo.application.id</span> = <span class="hljs-string">applicationBean</span>
+<span class="hljs-meta">dubbo.application.name</span> = <span class="hljs-string">dubbo-demo-application</span>
+<span class="hljs-comment">
+## module</span>
+<span class="hljs-meta">dubbo.module.id</span> = <span class="hljs-string">moduleBean</span>
+<span class="hljs-meta">dubbo.module.name</span> = <span class="hljs-string">dubbo-demo-module</span>
+<span class="hljs-comment">
+## registry</span>
+<span class="hljs-meta">dubbo.registry.address</span> = <span class="hljs-string">zookeeper://192.168.99.100:32770</span>
+<span class="hljs-comment">
+## protocol</span>
+<span class="hljs-meta">dubbo.protocol.name</span> = <span class="hljs-string">dubbo</span>
+<span class="hljs-meta">dubbo.protocol.port</span> = <span class="hljs-string">20880</span>
+<span class="hljs-comment">
+## monitor</span>
+<span class="hljs-meta">dubbo.monitor.address</span> = <span class="hljs-string">zookeeper://127.0.0.1:32770</span>
+<span class="hljs-comment">
+## provider</span>
+<span class="hljs-meta">dubbo.provider.host</span> = <span class="hljs-string">127.0.0.1</span>
+<span class="hljs-comment">
+## consumer</span>
+<span class="hljs-meta">dubbo.consumer.client</span> = <span class="hljs-string">netty</span>
+</code></pre>
+<h6><code>@EnableDubboConfig</code> 配置 Bean</h6>
+<pre><code class="language-java"><span class="hljs-comment">/**
+ * Dubbo 配置 Bean
+ *
+ * <span class="hljs-doctag">@author</span> &lt;a href="mailto:mercyblitz@gmail.com"&gt;Mercy&lt;/a&gt;
+ */</span>
+<span class="hljs-meta">@EnableDubboConfig</span>
+<span class="hljs-meta">@PropertySource</span>(<span class="hljs-string">"META-INF/config.properties"</span>)
+<span class="hljs-meta">@Configuration</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DubboConfiguration</span> </span>{
+
+}
+</code></pre>
+<h6>实现引导类</h6>
+<pre><code class="language-java"><span class="hljs-comment">/**
+ * Dubbo 配置引导类
+ *
+ * <span class="hljs-doctag">@author</span> &lt;a href="mailto:mercyblitz@gmail.com"&gt;Mercy&lt;/a&gt;
+ */</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DubboConfigurationBootstrap</span> </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">main</span><span class="hljs-params">(String[] args)</span> </span>{
+        <span class="hljs-comment">// 创建配置上下文</span>
+        AnnotationConfigApplicationContext context = <span class="hljs-keyword">new</span> AnnotationConfigApplicationContext();
+        <span class="hljs-comment">// 注册当前配置 Bean</span>
+        context.register(DubboConfiguration<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        context.refresh();
+ 	    <span class="hljs-comment">// application</span>
+        ApplicationConfig applicationConfig = context.getBean(<span class="hljs-string">"applicationBean"</span>, ApplicationConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        System.out.printf(<span class="hljs-string">"applicationBean.name = %s \n"</span>, applicationConfig.getName());
+
+        <span class="hljs-comment">// module</span>
+        ModuleConfig moduleConfig = context.getBean(<span class="hljs-string">"moduleBean"</span>, ModuleConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        System.out.printf(<span class="hljs-string">"moduleBean.name = %s \n"</span>, moduleConfig.getName());
+
+        <span class="hljs-comment">// registry</span>
+        RegistryConfig registryConfig = context.getBean(RegistryConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        System.out.printf(<span class="hljs-string">"registryConfig.name = %s \n"</span>, registryConfig.getAddress());
+
+        <span class="hljs-comment">// protocol</span>
+        ProtocolConfig protocolConfig = context.getBean(ProtocolConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        System.out.printf(<span class="hljs-string">"protocolConfig.name = %s \n"</span>, protocolConfig.getName());
+        System.out.printf(<span class="hljs-string">"protocolConfig.port = %s \n"</span>, protocolConfig.getPort());
+
+        <span class="hljs-comment">// monitor</span>
+        MonitorConfig monitorConfig = context.getBean(MonitorConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        System.out.printf(<span class="hljs-string">"monitorConfig.name = %s \n"</span>, monitorConfig.getAddress());
+
+        <span class="hljs-comment">// provider</span>
+        ProviderConfig providerConfig = context.getBean(ProviderConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        System.out.printf(<span class="hljs-string">"providerConfig.name = %s \n"</span>, providerConfig.getHost());
+
+        <span class="hljs-comment">// consumer</span>
+        ConsumerConfig consumerConfig = context.getBean(ConsumerConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        System.out.printf(<span class="hljs-string">"consumerConfig.name = %s \n"</span>, consumerConfig.getClient());
+    }
+}
+</code></pre>
+<h6>执行结果</h6>
+<pre><code>applicationBean.name = dubbo-demo-application 
+moduleBean.name = dubbo-demo-module 
+registryConfig.name = zookeeper://192.168.99.100:32770 
+protocolConfig.name = dubbo 
+protocolConfig.port = 20880 
+monitorConfig.name = zookeeper://127.0.0.1:32770 
+providerConfig.name = 127.0.0.1 
+consumerConfig.name = netty 
+</code></pre>
+<p>不难发现,<code>@EnableDubboConfig</code> 配置 Bean 配合外部化文件 <code>classpath:/META-INF/config.properties</code>,与执行输出内容相同。</p>
+<h5>多 Dubbo 配置 Bean 绑定</h5>
+<h6>外部化配置文件</h6>
+<p>将以下内容的外部化配置文件物理路径为:<code>classpath:/META-INF/multiple-config.properties</code>:</p>
+<pre><code class="language-properties"><span class="hljs-comment"># 多 Dubbo 配置 Bean 绑定</span>
+<span class="hljs-comment">## dubbo.applications</span>
+<span class="hljs-meta">dubbo.applications.applicationBean.name</span> = <span class="hljs-string">dubbo-demo-application</span>
+<span class="hljs-meta">dubbo.applications.applicationBean2.name</span> = <span class="hljs-string">dubbo-demo-application2</span>
+<span class="hljs-meta">dubbo.applications.applicationBean3.name</span> = <span class="hljs-string">dubbo-demo-application3</span>
+</code></pre>
+<h6><code>@EnableDubboConfig</code>  配置 Bean(多)</h6>
+<pre><code class="language-java"><span class="hljs-meta">@EnableDubboConfig</span>(multiple = <span class="hljs-keyword">true</span>)
+<span class="hljs-meta">@PropertySource</span>(<span class="hljs-string">"META-INF/multiple-config.properties"</span>)
+<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DubboMultipleConfiguration</span> </span>{
+
+}	
+</code></pre>
+<h6>实现引导类</h6>
+<pre><code class="language-java"><span class="hljs-comment">/**
+ * Dubbo 配置引导类
+ *
+ * <span class="hljs-doctag">@author</span> &lt;a href="mailto:mercyblitz@gmail.com"&gt;Mercy&lt;/a&gt;
+ */</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DubboConfigurationBootstrap</span> </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">main</span><span class="hljs-params">(String[] args)</span> </span>{
+        <span class="hljs-comment">// 创建配置上下文</span>
+        AnnotationConfigApplicationContext context = <span class="hljs-keyword">new</span> AnnotationConfigApplicationContext();
+        <span class="hljs-comment">// 注册当前配置 Bean</span>
+        context.register(DubboMultipleConfiguration<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        context.refresh();
+
+        <span class="hljs-comment">// 获取 ApplicationConfig Bean:"applicationBean"、"applicationBean2" 和 "applicationBean3"</span>
+        ApplicationConfig applicationBean = context.getBean(<span class="hljs-string">"applicationBean"</span>, ApplicationConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        ApplicationConfig applicationBean2 = context.getBean(<span class="hljs-string">"applicationBean2"</span>, ApplicationConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        ApplicationConfig applicationBean3 = context.getBean(<span class="hljs-string">"applicationBean3"</span>, ApplicationConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+
+        System.out.printf(<span class="hljs-string">"applicationBean.name = %s \n"</span>, applicationBean.getName());
+        System.out.printf(<span class="hljs-string">"applicationBean2.name = %s \n"</span>, applicationBean2.getName());
+        System.out.printf(<span class="hljs-string">"applicationBean3.name = %s \n"</span>, applicationBean3.getName());
+    }
+}
+</code></pre>
+<h6>执行结果</h6>
+<pre><code>applicationBean.name = dubbo-demo-application 
+applicationBean2.name = dubbo-demo-application2 
+applicationBean3.name = dubbo-demo-application3 
+</code></pre>
+<p><code>@EnableDubboConfig(multiple = true)</code> 执行后,运行结果说明<code>ApplicationConfig</code> Bean 以及 ID 的定义方式。</p>
+<h3><code>@EnableDubboConfigBinding</code> &amp; <code>@EnableDubboConfigBindings</code></h3>
+<p><code>@EnableDubboConfig</code>适合绝大多数外部化配置场景,然而无论是单 Bean 绑定,还是多 Bean 绑定,其<strong>外部化配置属性前缀</strong>是固化的,如<code>dubbo.application</code> 以及 <code>dubbo.applications</code> 。</p>
+<p>当应用需要自定义<strong>外部化配置属性前缀</strong>,<code>@EnableDubboConfigBinding</code>能提供更大的弹性,支持单个外部化配置属性前缀(<code>prefix</code>) 与 Dubbo 配置 Bean 类型(<code>AbstractConfig</code> 子类)绑定,如果需要多次绑定时,可使用<code>@EnableDubboConfigBindings</code>。</p>
+<blockquote>
+<p>尽管 Dubbo 推荐使用 Java 8 ,然而实际的情况,运行时的 JDK 的版本可能从 6到8 均有。因此,<code>@EnableDubboConfigBinding</code> 没有实现<code>java.lang.annotation.Repeatable</code>,即允许实现类不支持重复标注<code>@EnableDubboConfigBinding</code>。</p>
+</blockquote>
+<p><code>@EnableDubboConfigBinding</code>  在支持外部化配置属性与 Dubbo 配置类绑定时,与 Dubbo 过去的映射行为不同,被绑定的 Dubbo 配置类将会提升为 Spring Bean,无需提前装配 Dubbo 配置类。同时,支持多 Dubbo 配置Bean 装配。其 Bean 的绑定规则与<code>@EnableDubboConfig</code>一致。</p>
+<h4>起始版本: <code>2.5.8</code></h4>
+<h4>使用说明</h4>
+<h5><code>@EnableDubboConfigBinding</code> 定义</h5>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-meta">@interface</span> EnableDubboConfigBinding {
+
+    <span class="hljs-comment">/**
+     * The name prefix of the properties that are valid to bind to {<span class="hljs-doctag">@link</span> AbstractConfig Dubbo Config}.
+     *
+     * <span class="hljs-doctag">@return</span> the name prefix of the properties to bind
+     */</span>
+    <span class="hljs-function">String <span class="hljs-title">prefix</span><span class="hljs-params">()</span></span>;
+
+    <span class="hljs-comment">/**
+     * <span class="hljs-doctag">@return</span> The binding type of {<span class="hljs-doctag">@link</span> AbstractConfig Dubbo Config}.
+     * <span class="hljs-doctag">@see</span> AbstractConfig
+     * <span class="hljs-doctag">@see</span> ApplicationConfig
+     * <span class="hljs-doctag">@see</span> ModuleConfig
+     * <span class="hljs-doctag">@see</span> RegistryConfig
+     */</span>
+    Class&lt;? extends AbstractConfig&gt; type();
+
+    <span class="hljs-comment">/**
+     * It indicates whether {<span class="hljs-doctag">@link</span> #prefix()} binding to multiple Spring Beans.
+     *
+     * <span class="hljs-doctag">@return</span> the default value is &lt;code&gt;false&lt;/code&gt;
+     */</span>
+    <span class="hljs-function"><span class="hljs-keyword">boolean</span> <span class="hljs-title">multiple</span><span class="hljs-params">()</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">false</span></span>;
+
+}
+</code></pre>
+<ul>
+<li><code>prefix()</code> : 指定待绑定 Dubbo 配置类的外部化配置属性的前缀,比如<code>dubbo.application</code>  为 <code>ApplicationConfig</code> 的外部化配置属性的前缀。<code>prefix()</code> 支持占位符(Placeholder), 并且其关联前缀值是否以&quot;.&quot; 作为结尾字符是可选的,即<code>prefix() = &quot;dubbo.application&quot;</code> 与 <code>prefix() = &quot;dubbo.application.&quot;</code> 效果相同</li>
+<li><code>type()</code> : 指定 Dubbo 配置类,所有 <code>AbstractConfig</code> 的实现子类即可,如<code>ApplicationConfig</code> 、<code>RegistryConfig</code> 以及 <code>ProtocolConfig</code> 等</li>
+<li><code>multiple()</code> : 表明是否需要将<code>prefix()</code>   作为多个 <code>type()</code>   类型的 Spring Bean 外部化配置属性。默认值为<code>false</code>,即默认支持单个类型的 Spring 配置 Bean</li>
+</ul>
+<p>假设标注 <code>@EnableDubboConfigBinding</code> 的实现类被 Spring 应用上下文扫描并且注册后,其中<code>prefix()</code> =  <code>dubbo.app</code> 、 <code>type()</code> = <code>ApplicationConfig.class</code> ,且外部配置内容为:</p>
+<pre><code class="language-properties"><span class="hljs-meta">dubbo.app.id</span> = <span class="hljs-string">applicationBean</span>
+<span class="hljs-meta">dubbo.app.name</span> = <span class="hljs-string">dubbo-demo-application</span>
+</code></pre>
+<p>Spring 应用上下文启动后,一个 ID 为 &quot;applicationBean&quot;   的 <code>ApplicationConfig</code>  Bean 被初始化,其 <code>name</code> 字段被设置为 &quot;dubbo-demo-application&quot;。</p>
+<h5><code>EnableDubboConfigBindings</code> 定义</h5>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-meta">@interface</span> EnableDubboConfigBindings {
+
+    <span class="hljs-comment">/**
+     * The value of {<span class="hljs-doctag">@link</span> EnableDubboConfigBindings}
+     *
+     * <span class="hljs-doctag">@return</span> non-null
+     */</span>
+    EnableDubboConfigBinding[] value();
+
+}
+</code></pre>
+<ul>
+<li><code>value</code> : 指定多个<code>EnableDubboConfigBinding</code>,用于实现外部化配置属性前缀(<code>prefix</code>) 与 Dubbo 配置 Bean 类型(<code>AbstractConfig</code> 子类)绑定。</li>
+</ul>
+<h4>示例说明</h4>
+<h5>外部化配置文件</h5>
+<p>将以下内容的外部化配置文件物理路径为:<code>classpath:/META-INF/bindings.properties</code></p>
+<pre><code class="language-properties"><span class="hljs-comment"># classpath:/META-INF/bindings.properties</span>
+<span class="hljs-comment">## 占位符值 : ApplicationConfig 外部配置属性前缀</span>
+<span class="hljs-meta">applications.prefix</span> = <span class="hljs-string">dubbo.apps.</span>
+<span class="hljs-comment">
+## 多 ApplicationConfig Bean 绑定</span>
+<span class="hljs-meta">dubbo.apps.applicationBean.name</span> = <span class="hljs-string">dubbo-demo-application</span>
+<span class="hljs-meta">dubbo.apps.applicationBean2.name</span> = <span class="hljs-string">dubbo-demo-application2</span>
+<span class="hljs-meta">dubbo.apps.applicationBean3.name</span> = <span class="hljs-string">dubbo-demo-application3</span>
+<span class="hljs-comment">
+## 单 ModuleConfig Bean 绑定</span>
+<span class="hljs-meta">dubbo.module.id</span> = <span class="hljs-string">moduleBean</span>
+<span class="hljs-meta">dubbo.module.name</span> = <span class="hljs-string">dubbo-demo-module</span>
+<span class="hljs-comment">
+## 单 RegistryConfig Bean 绑定</span>
+<span class="hljs-meta">dubbo.registry.address</span> = <span class="hljs-string">zookeeper://192.168.99.100:32770</span>
+</code></pre>
+<h5><code>EnableDubboConfigBindings</code> 配置 Bean</h5>
+<p><code>DubboConfiguration</code> 作为 Dubbo 配置 Bean,除通过 <code>@EnableDubboConfigBinding</code> 绑定之外,还需要 <code>@PropertySource</code> 指定外部化配置文件(<code>classpath:/META-INF/bindings.properties</code>):</p>
+<pre><code class="language-java">/**
+ * Dubbo 配置 Bean
+ *
+ * @author &lt;a href="mailto:mercyblitz@gmail.com"&gt;Mercy&lt;/a&gt;
+ */
+@EnableDubboConfigBindings({
+        @EnableDubboConfigBinding(prefix = "${applications.prefix}",
+                type = ApplicationConfig.class, multiple = true), // 多 ApplicationConfig Bean 绑定
+        @EnableDubboConfigBinding(prefix = "dubbo.module", // 不带 "." 后缀
+                type = ModuleConfig.class), // 单 ModuleConfig Bean 绑定
+        @EnableDubboConfigBinding(prefix = "dubbo.registry.", // 带 "." 后缀
+                type = RegistryConfig.class) // 单 RegistryConfig Bean 绑定
+})
+@PropertySource("META-INF/bindings.properties")
+@Configuration
+public class DubboConfiguration {
+  
+}
+</code></pre>
+<h5>实现引导类</h5>
+<p>通过之前的使用说明,当 <code>EnableDubboConfigBinding</code> 将外部配置化文件<code>classpath:/META-INF/dubbo.properties</code> 绑定到 <code>ApplicationConfig</code>后,其中 Spring Bean &quot;applicationBean&quot; 的 name 字段被设置成 &quot;dubbo-demo-application&quot;。同时, <code>EnableDubboConfigBinding</code>  所标注的 <code>DubboConfiguration</code> 需要被 Sring 应用上下文注册:</p>
+<pre><code class="language-java"><span class="hljs-comment">/**
+ * Dubbo 配置引导类
+ *
+ * <span class="hljs-doctag">@author</span> &lt;a href="mailto:mercyblitz@gmail.com"&gt;Mercy&lt;/a&gt;
+ */</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DubboConfigurationBootstrap</span> </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">main</span><span class="hljs-params">(String[] args)</span> </span>{
+        <span class="hljs-comment">// 创建配置上下文</span>
+        AnnotationConfigApplicationContext context = <span class="hljs-keyword">new</span> AnnotationConfigApplicationContext();
+        <span class="hljs-comment">// 注册当前配置 Bean</span>
+        context.register(DubboConfiguration<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        context.refresh();
+ 		<span class="hljs-comment">// 获取 ApplicationConfig Bean:"applicationBean"、"applicationBean2" 和 "applicationBean3"</span>
+        ApplicationConfig applicationBean = context.getBean(<span class="hljs-string">"applicationBean"</span>, ApplicationConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        ApplicationConfig applicationBean2 = context.getBean(<span class="hljs-string">"applicationBean2"</span>, ApplicationConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+        ApplicationConfig applicationBean3 = context.getBean(<span class="hljs-string">"applicationBean3"</span>, ApplicationConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+
+        System.out.printf(<span class="hljs-string">"applicationBean.name = %s \n"</span>, applicationBean.getName());
+        System.out.printf(<span class="hljs-string">"applicationBean2.name = %s \n"</span>, applicationBean2.getName());
+        System.out.printf(<span class="hljs-string">"applicationBean3.name = %s \n"</span>, applicationBean3.getName());
+
+        <span class="hljs-comment">// 获取 ModuleConfig Bean:"moduleBean"</span>
+        ModuleConfig moduleBean = context.getBean(<span class="hljs-string">"moduleBean"</span>, ModuleConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+
+        System.out.printf(<span class="hljs-string">"moduleBean.name = %s \n"</span>, moduleBean.getName());
+
+        <span class="hljs-comment">// 获取 RegistryConfig Bean</span>
+        RegistryConfig registry = context.getBean(RegistryConfig<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+
+        System.out.printf(<span class="hljs-string">"registry.address = %s \n"</span>, registry.getAddress());
+    }
+}
+</code></pre>
+<h5>运行结果</h5>
+<p><code>DubboConfigurationBootstrap</code> 运行后控制台输出:</p>
+<pre><code>applicationBean.name = dubbo-demo-application 
+applicationBean2.name = dubbo-demo-application2 
+applicationBean3.name = dubbo-demo-application3 
+moduleBean.name = dubbo-demo-module 
+registry.address = zookeeper://192.168.99.100:32770 
+</code></pre>
+<p>输出的内容与<code>classpath:/META-INF/bindings.properties</code> 绑定的内容一致,符合期望。</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-externalized-configuration.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-externalized-configuration.json
new file mode 100644
index 0000000..4aeed08
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-externalized-configuration.json
@@ -0,0 +1,6 @@
+{
+  "filename": "dubbo-externalized-configuration.md",
+  "__html": "<h1>Dubbo 外部化配置(Externalized Configuration)</h1>\n<h2>外部化配置(External Configuration)</h2>\n<p>在<a href=\"Dubbo-Annotation-Driven.md\">Dubbo 注解驱动</a>例子中,无论是服务提供方,还是服务消费方,均需要转配相关配置Bean:</p>\n<pre><code class=\"language-java\">    <span class=\"hljs-meta\">@Bean</span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> ApplicationConfig <span class=\"hljs-title\">applicationConfig</span><span class=\"hljs-params\">()</span> </span>{\n        Applicatio [...]
+  "link": "/zh-cn/blog/dubbo-externalized-configuration.html",
+  "meta": {}
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-fescar.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-fescar.html
new file mode 100644
index 0000000..eb3b2b3
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-fescar.html
@@ -0,0 +1,215 @@
+<!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="Dubbo,Fescar,一致性" />
+	<meta name="description" content="本文主要介绍如何使用Fescar保证Dubbo微服务间的一致性" />
+	<!-- 网页标签标题 -->
+	<title>如何使用Fescar保证Dubbo微服务间的一致性</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>案例</h2>
+<p>用户采购商品业务,整个业务包含3个微服务:</p>
+<ul>
+<li>库存服务: 扣减给定商品的库存数量。</li>
+<li>订单服务: 根据采购请求生成订单。</li>
+<li>账户服务: 用户账户金额扣减。</li>
+</ul>
+<h3>业务结构图</h3>
+<p><img src="../../img/blog/fescar/fescar-1.png" alt="Architecture"></p>
+<h3>StorageService</h3>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">StorageService</span> </span>{
+
+    <span class="hljs-comment">/**
+     * deduct storage count
+     */</span>
+    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">deduct</span><span class="hljs-params">(String commodityCode, <span class="hljs-keyword">int</span> count)</span></span>;
+}
+</code></pre>
+<h3>OrderService</h3>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">OrderService</span> </span>{
+
+    <span class="hljs-comment">/**
+     * create order
+     */</span>
+    <span class="hljs-function">Order <span class="hljs-title">create</span><span class="hljs-params">(String userId, String commodityCode, <span class="hljs-keyword">int</span> orderCount)</span></span>;
+}
+</code></pre>
+<h3>AccountService</h3>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">AccountService</span> </span>{
+
+    <span class="hljs-comment">/**
+     * debit balance of user's account
+     */</span>
+    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">debit</span><span class="hljs-params">(String userId, <span class="hljs-keyword">int</span> money)</span></span>;
+}
+</code></pre>
+<h3>主要的业务逻辑:</h3>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BusinessServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">BusinessService</span> </span>{
+
+    <span class="hljs-keyword">private</span> StorageService storageService;
+
+    <span class="hljs-keyword">private</span> OrderService orderService;
+
+    <span class="hljs-comment">/**
+     * purchase
+     */</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">purchase</span><span class="hljs-params">(String userId, String commodityCode, <span class="hljs-keyword">int</span> orderCount)</span> </span>{
+
+        storageService.deduct(commodityCode, orderCount);
+
+        orderService.create(userId, commodityCode, orderCount);
+    }
+}
+</code></pre>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StorageServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">StorageService</span> </span>{
+
+  <span class="hljs-keyword">private</span> StorageDAO storageDAO;
+  
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">deduct</span><span class="hljs-params">(String commodityCode, <span class="hljs-keyword">int</span> count)</span> </span>{
+        Storage storage = <span class="hljs-keyword">new</span> Storage();
+        storage.setCount(count);
+        storage.setCommodityCode(commodityCode);
+        storageDAO.update(storage);
+    }
+}
+</code></pre>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OrderServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">OrderService</span> </span>{
+
+    <span class="hljs-keyword">private</span> OrderDAO orderDAO;
+
+    <span class="hljs-keyword">private</span> AccountService accountService;
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> Order <span class="hljs-title">create</span><span class="hljs-params">(String userId, String commodityCode, <span class="hljs-keyword">int</span> orderCount)</span> </span>{
+
+        <span class="hljs-keyword">int</span> orderMoney = calculate(commodityCode, orderCount);
+
+        accountService.debit(userId, orderMoney);
+
+        Order order = <span class="hljs-keyword">new</span> Order();
+        order.userId = userId;
+        order.commodityCode = commodityCode;
+        order.count = orderCount;
+        order.money = orderMoney;
+
+        <span class="hljs-keyword">return</span> orderDAO.insert(order);
+    }
+}
+</code></pre>
+<h2>Fescar 分布式事务解决方案</h2>
+<p><img src="../../img/blog/fescar/fescar-2.png" alt="undefined"></p>
+<p>此处仅仅需要一行注解 <code>@GlobalTransactional</code> 写在业务发起方的方法上:</p>
+<pre><code class="language-java">
+    <span class="hljs-meta">@GlobalTransactional</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">purchase</span><span class="hljs-params">(String userId, String commodityCode, <span class="hljs-keyword">int</span> orderCount)</span> </span>{
+        ......
+    }
+</code></pre>
+<h2>Dubbo 与 Fescar 结合的例子</h2>
+<h3>Step 1: 安装数据库</h3>
+<ul>
+<li>要求: MySQL (InnoDB 存储引擎)。</li>
+</ul>
+<p><strong>提示:</strong> 事实上例子中3个微服务需要3个独立的数据库,但为了方便我们使用同一物理库并配置3个逻辑连接串。</p>
+<p>更改以下xml文件中的数据库url、username和password</p>
+<p>dubbo-account-service.xml
+dubbo-order-service.xml
+dubbo-storage-service.xml</p>
+<pre><code class="language-xml">    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"url"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"jdbc:mysql://x.x.x.x:3306/xxx"</span> /&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"xxx"</span> /&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"xxx"</span> /&gt;</span>
+</code></pre>
+<h3>Step 2: 为 Fescar 创建 undo_log 表</h3>
+<p><code>UNDO_LOG</code> 此表用于 Fescar 的AT模式。</p>
+<pre><code class="language-sql"><span class="hljs-comment">-- 注意当 Fescar 版本升级至 0.3.0+ 将由之前的普通索引变更为唯一索引。</span>
+<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-string">`undo_log`</span> (
+  <span class="hljs-string">`id`</span> <span class="hljs-built_in">bigint</span>(<span class="hljs-number">20</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> AUTO_INCREMENT,
+  <span class="hljs-string">`branch_id`</span> <span class="hljs-built_in">bigint</span>(<span class="hljs-number">20</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
+  <span class="hljs-string">`xid`</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-number">100</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
+  <span class="hljs-string">`rollback_info`</span> longblob <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
+  <span class="hljs-string">`log_status`</span> <span class="hljs-built_in">int</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
+  <span class="hljs-string">`log_created`</span> datetime <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
+  <span class="hljs-string">`log_modified`</span> datetime <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
+  <span class="hljs-string">`ext`</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-number">100</span>) <span class="hljs-keyword">DEFAULT</span> <span class="hljs-literal">NULL</span>,
+  PRIMARY <span class="hljs-keyword">KEY</span> (<span class="hljs-string">`id`</span>),
+  <span class="hljs-keyword">UNIQUE</span> <span class="hljs-keyword">KEY</span> <span class="hljs-string">`ux_undo_log`</span> (<span class="hljs-string">`xid`</span>,<span class="hljs-string">`branch_id`</span>)
+) <span class="hljs-keyword">ENGINE</span>=<span class="hljs-keyword">InnoDB</span> AUTO_INCREMENT=<span class="hljs-number">1</span> <span class="hljs-keyword">DEFAULT</span> <span class="hljs-keyword">CHARSET</span>=utf8;
+</code></pre>
+<h3>Step 3: 创建相关业务表</h3>
+<pre><code class="language-sql">
+<span class="hljs-keyword">DROP</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">EXISTS</span> <span class="hljs-string">`storage_tbl`</span>;
+<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-string">`storage_tbl`</span> (
+  <span class="hljs-string">`id`</span> <span class="hljs-built_in">int</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> AUTO_INCREMENT,
+  <span class="hljs-string">`commodity_code`</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">DEFAULT</span> <span class="hljs-literal">NULL</span>,
+  <span class="hljs-string">`count`</span> <span class="hljs-built_in">int</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">DEFAULT</span> <span class="hljs-number">0</span>,
+  PRIMARY <span class="hljs-keyword">KEY</span> (<span class="hljs-string">`id`</span>),
+  <span class="hljs-keyword">UNIQUE</span> <span class="hljs-keyword">KEY</span> (<span class="hljs-string">`commodity_code`</span>)
+) <span class="hljs-keyword">ENGINE</span>=<span class="hljs-keyword">InnoDB</span> <span class="hljs-keyword">DEFAULT</span> <span class="hljs-keyword">CHARSET</span>=utf8;
+
+
+<span class="hljs-keyword">DROP</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">EXISTS</span> <span class="hljs-string">`order_tbl`</span>;
+<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-string">`order_tbl`</span> (
+  <span class="hljs-string">`id`</span> <span class="hljs-built_in">int</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> AUTO_INCREMENT,
+  <span class="hljs-string">`user_id`</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">DEFAULT</span> <span class="hljs-literal">NULL</span>,
+  <span class="hljs-string">`commodity_code`</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">DEFAULT</span> <span class="hljs-literal">NULL</span>,
+  <span class="hljs-string">`count`</span> <span class="hljs-built_in">int</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">DEFAULT</span> <span class="hljs-number">0</span>,
+  <span class="hljs-string">`money`</span> <span class="hljs-built_in">int</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">DEFAULT</span> <span class="hljs-number">0</span>,
+  PRIMARY <span class="hljs-keyword">KEY</span> (<span class="hljs-string">`id`</span>)
+) <span class="hljs-keyword">ENGINE</span>=<span class="hljs-keyword">InnoDB</span> <span class="hljs-keyword">DEFAULT</span> <span class="hljs-keyword">CHARSET</span>=utf8;
+
+
+<span class="hljs-keyword">DROP</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">EXISTS</span> <span class="hljs-string">`account_tbl`</span>;
+<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-string">`account_tbl`</span> (
+  <span class="hljs-string">`id`</span> <span class="hljs-built_in">int</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span> AUTO_INCREMENT,
+  <span class="hljs-string">`user_id`</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">DEFAULT</span> <span class="hljs-literal">NULL</span>,
+  <span class="hljs-string">`money`</span> <span class="hljs-built_in">int</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">DEFAULT</span> <span class="hljs-number">0</span>,
+  PRIMARY <span class="hljs-keyword">KEY</span> (<span class="hljs-string">`id`</span>)
+) <span class="hljs-keyword">ENGINE</span>=<span class="hljs-keyword">InnoDB</span> <span class="hljs-keyword">DEFAULT</span> <span class="hljs-keyword">CHARSET</span>=utf8;
+</code></pre>
+<h3>Step 4: 启动 Fescar-Server 服务</h3>
+<ul>
+<li>下载Server <a href="https://github.com/alibaba/fescar/releases">package</a>, 并解压。</li>
+<li>运行bin目录下的启动脚本。</li>
+</ul>
+<pre><code class="language-shell">sh fescar-server.sh $LISTEN_PORT $PATH_FOR_PERSISTENT_DATA
+
+e.g.
+
+sh fescar-server.sh 8091 /home/admin/fescar/data/
+</code></pre>
+<h3>Step 5: 运行例子</h3>
+<ul>
+<li>启动账户服务 (<a href="https://github.com/fescar-group/fescar-samples/blob/master/dubbo/src/main/java/com/alibaba/fescar/samples/dubbo/starter/DubboAccountServiceStarter.java">DubboAccountServiceStarter</a>)。</li>
+<li>启动库存服务 (<a href="https://github.com/fescar-group/fescar-samples/blob/master/dubbo/src/main/java/com/alibaba/fescar/samples/dubbo/starter/DubboStorageServiceStarter.java">DubboStorageServiceStarter</a>)。</li>
+<li>启动订单服务 (<a href="https://github.com/fescar-group/fescar-samples/blob/master/dubbo/src/main/java/com/alibaba/fescar/samples/dubbo/starter/DubboOrderServiceStarter.java">DubboOrderServiceStarter</a>)。</li>
+<li>运行BusinessService入口 (<a href="https://github.com/fescar-group/fescar-samples/blob/master/dubbo/src/main/java/com/alibaba/fescar/samples/dubbo/starter/DubboBusinessTester.java">DubboBusinessTester</a>)。</li>
+</ul>
+<h3>相关项目</h3>
+<ul>
+<li>fescar:          <a href="https://github.com/alibaba/fescar/">https://github.com/alibaba/fescar/</a></li>
+<li>fescar-samples : <a href="https://github.com/fescar-group/fescar-samples">https://github.com/fescar-group/fescar-samples</a></li>
+</ul>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-fescar.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-fescar.json
new file mode 100644
index 0000000..26b1384
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-fescar.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-fescar.md",
+  "__html": "<h1>如何使用Fescar保证Dubbo微服务间的一致性</h1>\n<h2>案例</h2>\n<p>用户采购商品业务,整个业务包含3个微服务:</p>\n<ul>\n<li>库存服务: 扣减给定商品的库存数量。</li>\n<li>订单服务: 根据采购请求生成订单。</li>\n<li>账户服务: 用户账户金额扣减。</li>\n</ul>\n<h3>业务结构图</h3>\n<p><img src=\"../../img/blog/fescar/fescar-1.png\" alt=\"Architecture\"></p>\n<h3>StorageService</h3>\n<pre><code class=\"language-java\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">interface</span> <span class=\"hljs-title\">Storage [...]
+  "link": "/zh-cn/blog/dubbo-fescar.html",
+  "meta": {
+    "title": "如何使用Fescar保证Dubbo微服务间的一致性",
+    "keywords": "Dubbo,Fescar,一致性",
+    "description": "本文主要介绍如何使用Fescar保证Dubbo微服务间的一致性"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-generic-invoke.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-generic-invoke.html
new file mode 100644
index 0000000..09f46cc
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-generic-invoke.html
@@ -0,0 +1,171 @@
+<!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="Dubbo, Generic invoke" />
+	<meta name="description" content="本文介绍了 Dubbo 泛化调用的使用场景及相关示例" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo的泛化调用</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>以下几种场景可以考虑使用泛化调用:</p>
+<ul>
+<li>服务测试平台</li>
+<li>API 服务网关</li>
+</ul>
+<p>泛化调用主要用于消费端没有 API 接口的情况;不需要引入接口 jar 包,而是直接通过 GenericService 接口来发起服务调用,参数及返回值中的所有 POJO 均用 <code>Map</code> 表示。泛化调用对于服务端无需关注,按正常服务进行暴露即可。</p>
+<p>下面来看看消费端如何使用泛化调用进行服务调用。</p>
+<h2>通过 Spring XML 配置进行泛化调用</h2>
+<p>在 Spring 配置申明 <code>generic=&quot;true&quot;</code>,如:</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"userService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"com.alibaba.dubbo.samples.generic.api.IUserService"</span> <span class="hljs-attr">generic</span>=<span class="hljs-string">"true"</span>/&gt;</span>
+</code></pre>
+<p>需要使用的地方,通过强制类型转化为 GenericService 进行调用:</p>
+<pre><code class="language-java">GenericService userService = (GenericService) context.getBean("userService");
+// primary param and return value
+String name = (String) userService.$invoke("delete", new String[]{int.class.getName()}, new Object[]{1});
+System.out.println(name);
+</code></pre>
+<p>其中:</p>
+<ol>
+<li>GenericService 这个接口只有一个方法,名为 <code>$invoke</code>,它接受三个参数,分别为方法名、方法参数类型数组和参数值数组;</li>
+<li>对于方法参数类型数组
+<ol>
+<li>如果是基本类型,如 int 或 long,可以使用 <code>int.class.getName()</code>获取其类型;</li>
+<li>如果是基本类型数组,如 int[],则可以使用 <code>int[].class.getName()</code>;</li>
+<li>如果是 POJO,则直接使用全类名,如 <code>com.alibaba.dubbo.samples.generic.api.Params</code>。</li>
+</ol>
+</li>
+</ol>
+<h2>通过 API 编程进行泛化调用</h2>
+<pre><code>ApplicationConfig application = new ApplicationConfig();
+application.setName(&quot;api-generic-consumer&quot;);
+
+RegistryConfig registry = new RegistryConfig();
+registry.setAddress(&quot;zookeeper://127.0.0.1:2181&quot;);
+
+application.setRegistry(registry);
+
+ReferenceConfig&lt;GenericService&gt; reference = new ReferenceConfig&lt;GenericService&gt;();
+// 弱类型接口名
+reference.setInterface(&quot;com.alibaba.dubbo.samples.generic.api.IUserService&quot;);
+// 声明为泛化接口
+reference.setGeneric(true);
+
+reference.setApplication(application);
+
+// 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用
+GenericService genericService = reference.get();
+
+String name = (String) genericService.$invoke(&quot;delete&quot;, new String[]{int.class.getName()}, new Object[]{1});
+System.out.println(name);
+</code></pre>
+<p>通过 API 的方式,不需要像 XML 的方式需要提前将服务配置好,可以动态构建 ReferenceConfig;相对 XML 来说,API 的方式更常见。</p>
+<h2>参数或返回值是 POJO 的场景</h2>
+<p>比如方法签名是 <code>User get(Params params);</code>其中 User 有 id 和 name 两个属性,Params 有 query 一个属性。</p>
+<p>以下是消费端的调用代码:</p>
+<pre><code class="language-java">String[] parameterTypes = <span class="hljs-keyword">new</span> String[]{<span class="hljs-string">"com.alibaba.dubbo.samples.generic.api.Params"</span>};
+Map&lt;String, Object&gt; params = <span class="hljs-keyword">new</span> HashMap&lt;String, Object&gt;();
+param.put(<span class="hljs-string">"class"</span>, <span class="hljs-string">"com.alibaba.dubbo.samples.generic.api.Params"</span>);
+param.put(<span class="hljs-string">"query"</span>, <span class="hljs-string">"a=b"</span>);
+Object user = userService.$invoke(<span class="hljs-string">"get"</span>, parameterTypes, <span class="hljs-keyword">new</span> Object[]{param});
+System.out.println(<span class="hljs-string">"sample one result: "</span> + user);
+</code></pre>
+<p>上述代码的输出结果为:</p>
+<pre><code class="language-shell">sample one result: {name=charles, id=1, class=com.alibaba.dubbo.samples.generic.api.User}
+</code></pre>
+<p>这里,Dubbo 框架会自动将 POJO 的返回值转换成 Map。可以看到,返回值 <code>user</code> 是一个 HashMap,里面分别存放了 name、id、class 三个 k/v。</p>
+<h4>泛接口实现</h4>
+<p>泛接口实现方式主要用于服务端没有 API 接口的情况,参数及返回值中的所有 POJO 均用 Map 表示,通常用于框架集成,如实现一个通用的远程服务 Mock 框架,可通过实现 GenericService 接口处理所有服务请求。</p>
+<h3>服务端实现 GenericService</h3>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GenericServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">GenericService</span> </span>{
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-keyword">public</span> Object $invoke(String method, String[] parameterTypes, Object[] args) <span class="hljs-keyword">throws</span> GenericException {
+        <span class="hljs-keyword">if</span> (method.equals(<span class="hljs-string">"hi"</span>)) {
+            <span class="hljs-keyword">return</span> <span class="hljs-string">"hi, "</span> + args[<span class="hljs-number">0</span>];
+        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (method.equals(<span class="hljs-string">"hello"</span>)) {
+            <span class="hljs-keyword">return</span> <span class="hljs-string">"hello, "</span> + args[<span class="hljs-number">0</span>];
+        }
+
+        <span class="hljs-keyword">return</span> <span class="hljs-string">"welcome"</span>;
+    }
+}
+</code></pre>
+<h3>服务端暴露服务</h3>
+<pre><code class="language-java">ApplicationConfig application = <span class="hljs-keyword">new</span> ApplicationConfig();
+application.setName(<span class="hljs-string">"api-generic-provider"</span>);
+
+RegistryConfig registry = <span class="hljs-keyword">new</span> RegistryConfig();
+registry.setAddress(<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span>);
+
+application.setRegistry(registry);
+
+GenericService genericService = <span class="hljs-keyword">new</span> GenericServiceImpl();
+
+ServiceConfig&lt;GenericService&gt; service = <span class="hljs-keyword">new</span> ServiceConfig&lt;GenericService&gt;();
+service.setApplication(application);
+service.setInterface(<span class="hljs-string">"com.alibaba.dubbo.samples.generic.api.HelloService"</span>);
+service.setRef(genericService);
+service.export();
+
+ServiceConfig&lt;GenericService&gt; service2 = <span class="hljs-keyword">new</span> ServiceConfig&lt;GenericService&gt;();
+service2.setApplication(application);
+service2.setInterface(<span class="hljs-string">"com.alibaba.dubbo.samples.generic.api.HiService"</span>);
+service2.setRef(genericService);
+service2.export();
+</code></pre>
+<p>同样,也可以使用 XML 配置的方式暴露服务;此时服务端是没有依赖 HiService 和 HelloService 这两个接口的。</p>
+<h3>消费端进行服务调用</h3>
+<pre><code class="language-java">ApplicationConfig application = <span class="hljs-keyword">new</span> ApplicationConfig();
+application.setName(<span class="hljs-string">"api-generic-consumer"</span>);
+
+RegistryConfig registry = <span class="hljs-keyword">new</span> RegistryConfig();
+registry.setAddress(<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span>);
+
+application.setRegistry(registry);
+
+ReferenceConfig&lt;GenericService&gt; reference = <span class="hljs-keyword">new</span> ReferenceConfig&lt;GenericService&gt;();
+<span class="hljs-comment">// 弱类型接口名</span>
+reference.setInterface(HiService<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+reference.setApplication(application);
+
+HiService hiService = (HiService) reference.get();
+System.out.println(hiService.hi(<span class="hljs-string">"dubbo"</span>));
+
+ReferenceConfig&lt;GenericService&gt; reference2 = <span class="hljs-keyword">new</span> ReferenceConfig&lt;GenericService&gt;();
+<span class="hljs-comment">// 弱类型接口名</span>
+reference2.setInterface(HelloService<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;
+reference2.setApplication(application);
+
+HelloService helloService = (HelloService) reference2.get();
+System.out.println(helloService.hello(<span class="hljs-string">"community"</span>));
+</code></pre>
+<p>同样,消费端也可以使用 XML 配置的方式引用服务,然后进行调用。这里可以看到调用方式为普通的服务调用,并非泛化调用。当然使用泛化调用也是可以的。</p>
+<p>到这里为止,一个简易的服务 Mock 平台就成功上线了!</p>
+<h2>其他</h2>
+<ul>
+<li>本文介绍的泛化调用和泛接口实现,都是在原生的 <code>Dubbo</code> 协议之上的。在 2.6.2 版本之前,其他协议如 http/hessian 等是不支持泛化调用的,2.6.3 版本将会对这两个协议的泛化调用做支持。</li>
+<li>本文中提到的相关示例代码可以在 dubbo-samples中找到:<a href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-generic">https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-generic</a></li>
+</ul>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-generic-invoke.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-generic-invoke.json
new file mode 100644
index 0000000..4b2d6db
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-generic-invoke.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-generic-invoke.md",
+  "__html": "<h1>Dubbo的泛化调用</h1>\n<p>以下几种场景可以考虑使用泛化调用:</p>\n<ul>\n<li>服务测试平台</li>\n<li>API 服务网关</li>\n</ul>\n<p>泛化调用主要用于消费端没有 API 接口的情况;不需要引入接口 jar 包,而是直接通过 GenericService 接口来发起服务调用,参数及返回值中的所有 POJO 均用 <code>Map</code> 表示。泛化调用对于服务端无需关注,按正常服务进行暴露即可。</p>\n<p>下面来看看消费端如何使用泛化调用进行服务调用。</p>\n<h2>通过 Spring XML 配置进行泛化调用</h2>\n<p>在 Spring 配置申明 <code>generic=&quot;true&quot;</code>,如:</p>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dubbo:reference</span> [...]
+  "link": "/zh-cn/blog/dubbo-generic-invoke.html",
+  "meta": {
+    "title": "Dubbo的泛化调用",
+    "keywords": "Dubbo, Generic invoke",
+    "description": "本文介绍了 Dubbo 泛化调用的使用场景及相关示例"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-gracefully-shutdown.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-gracefully-shutdown.html
new file mode 100644
index 0000000..03cd4b5
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-gracefully-shutdown.html
@@ -0,0 +1,130 @@
+<!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="Dubbo, Gracefully Shutdown, Safely Shutdown" />
+	<meta name="description" content="介绍Dubbo优雅停机的原理和使用方式" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo 优雅停机</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>背景</h2>
+<p>对于任何一个线上应用,如何在服务更新部署过程中保证客户端无感知是开发者必须要解决的问题,即从应用停止到重启恢复服务这个阶段不能影响正常的业务请求。理想条件下,在没有请求的时候再进行更新是最安全可靠的,然而互联网应用必须要保证可用性,因此在技术层面上优化应用更新流程来保证服务在更新时无损是必要的。</p>
+<p>传统的解决方式是通过将应用更新流程划分为手工摘流量、停应用、更新重启三个步骤,由人工操作实现客户端无对更新感知。这种方式简单而有效,但是限制较多:不仅需要使用借助网关的支持来摘流量,还需要在停应用前人工判断来保证在途请求已经处理完毕。这种需要人工介入的方式运维复杂度较高,只能适用规模较小的应用,无法在大规模系统上使用。</p>
+<p>因此,如果在容器/框架级别提供某种自动化机制,来自动进行摘流量并确保处理完以到达的请求,不仅能保证业务不受更新影响,还可以极大地提升更新应用时的运维效率。</p>
+<p>这个机制也就是优雅停机,目前Tomcat/Undertow/Dubbo等容器/框架都有提供相关实现。下面给出正式一些的定义:优雅停机是指在停止应用时,执行的一系列保证应用正常关闭的操作。这些操作往往包括等待已有请求执行完成、关闭线程、关闭连接和释放资源等,优雅停机可以避免非正常关闭程序可能造成数据异常或丢失,应用异常等问题。优雅停机本质上是JVM即将关闭前执行的一些额外的处理代码。</p>
+<h2>适用场景</h2>
+<ul>
+<li>JVM主动关闭(<code>System.exit(int)</code>;</li>
+<li>JVM由于资源问题退出(<code>OOM</code>);</li>
+<li>应用程序接受到<code>SIGTERM</code>或<code>SIGINT</code>信号。</li>
+</ul>
+<h2>配置方式</h2>
+<h3>服务的优雅停机</h3>
+<p>在Dubbo中,优雅停机是默认开启的,停机等待时间为10000毫秒。可以通过配置<code>dubbo.service.shutdown.wait</code>来修改等待时间。</p>
+<p>例如将等待时间设置为20秒可通过增加以下配置实现:</p>
+<pre><code class="language-shell">dubbo.service.shutdown.wait=20000
+</code></pre>
+<h3>容器的优雅停机</h3>
+<p>当使用<code>org.apache.dubbo.container.Main</code>这种容器方式来使用 Dubbo 时,也可以通过配置<code>dubbo.shutdown.hook</code>为<code>true</code>来开启优雅停机。</p>
+<h3>通过QOS优雅上下线</h3>
+<p>基于<code>ShutdownHook</code>方式的优雅停机无法确保所有关闭流程一定执行完,所以 Dubbo 推出了多段关闭的方式来保证服务完全无损。</p>
+<p>多段关闭即将停止应用分为多个步骤,通过运维自动化脚本或手工操作的方式来保证脚本每一阶段都能执行完毕。</p>
+<p>在关闭应用前,首先通过 QOS 的<code>offline</code>指令下线所有服务,然后等待一定时间确保已经到达请求全部处理完毕,由于服务已经在注册中心下线,当前应用不会有新的请求。这时再执行真正的关闭(<code>SIGTERM</code> 或<code>SIGINT</code>)流程,就能保证服务无损。</p>
+<p>QOS可通过 telnet 或 HTTP 方式使用,具体方式请见<a href="http://dubbo.apache.org/zh-cn/docs/user/references/qos.html">Dubbo-QOS命令使用说明</a>。</p>
+<h2>流程</h2>
+<p>Provider在接收到停机指令后</p>
+<ul>
+<li>从注册中心上注销所有服务;</li>
+<li>从配置中心取消监听动态配置;</li>
+<li>向所有连接的客户端发送只读事件,停止接收新请求;</li>
+<li>等待一段时间以处理已到达的请求,然后关闭请求处理线程池;</li>
+<li>断开所有客户端连接。</li>
+</ul>
+<p>Consumer在接收到停机指令后</p>
+<ul>
+<li>拒绝新到请求,直接返回调用异常;</li>
+<li>等待当前已发送请求执行完毕,如果响应超时则强制关闭连接。</li>
+</ul>
+<p>当使用容器方式运行 Dubbo 时,在容器准备退出前,可进行一系列的资源释放和清理工。</p>
+<p>例如使用 SpringContainer时,Dubbo 的ShutdownHook线程会执行<code>ApplicationContext</code>的<code>stop</code>和<code>close</code>方法,保证 Bean的生命周期完整。</p>
+<h2>实现原理</h2>
+<ol>
+<li>
+<p>在加载类<code>org.apache.dubbo.config.AbstractConfig</code>时,通过<code>org.apache.dubbo.config.DubboShutdownHook</code>向JVM注册 ShutdownHook。</p>
+<pre><code class="language-java"><span class="hljs-comment">/**
+ * Register the ShutdownHook
+ */</span>
+<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">register</span><span class="hljs-params">()</span> </span>{
+    <span class="hljs-keyword">if</span> (!registered.get() &amp;&amp; registered.compareAndSet(<span class="hljs-keyword">false</span>, <span class="hljs-keyword">true</span>)) {
+        Runtime.getRuntime().addShutdownHook(getDubboShutdownHook());
+    }
+}
+</code></pre>
+</li>
+<li>
+<p>每个ShutdownHook都是一个单独的线程,由JVM在退出时触发执行<code>org.apache.dubbo.config.DubboShutdownHook</code>。</p>
+<pre><code class="language-java"><span class="hljs-comment">/**
+ * Destroy all the resources, including registries and protocols.
+ */</span>
+<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doDestroy</span><span class="hljs-params">()</span> </span>{
+    <span class="hljs-keyword">if</span> (!destroyed.compareAndSet(<span class="hljs-keyword">false</span>, <span class="hljs-keyword">true</span>)) {
+        <span class="hljs-keyword">return</span>;
+    }
+    <span class="hljs-comment">// destroy all the registries</span>
+    AbstractRegistryFactory.destroyAll();
+    <span class="hljs-comment">// destroy all the protocols</span>
+    destroyProtocols();
+}
+</code></pre>
+</li>
+<li>
+<p>首先关闭所有注册中心,这一步包括:</p>
+<ul>
+<li>从注册中心注销所有已经发布的服务;</li>
+<li>取消订阅当前应用所有依赖的服务;</li>
+<li>断开与注册中心的连接。</li>
+</ul>
+</li>
+<li>
+<p>执行所有<code>Protocol</code>的<code>destroy()</code>,主要包括:</p>
+<ul>
+<li>销毁所有<code>Invoker</code>和<code>Exporter</code>;</li>
+<li>关闭Server,向所有已连接Client发送当前Server只读事件;</li>
+<li>关闭独享/共享Client,断开连接,取消超时和重试任务;</li>
+<li>释放所有相关资源。</li>
+</ul>
+</li>
+<li>
+<p>执行完毕,关闭JVM。</p>
+</li>
+</ol>
+<h2>注意事项</h2>
+<ul>
+<li>使用<code>SIGKILL</code>关闭应用不会执行优雅停机;</li>
+<li>优雅停机不保证会等待所有已发送/到达请求结束;</li>
+<li>配置的优雅停机等待时间<code>timeout</code>不是所有步骤等待时间的总和,而是每一个<code>destroy</code>执行的最大时间。例如配置等待时间为5秒,则关闭Server、关闭Client等步骤会分别等待5秒。</li>
+</ul>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-gracefully-shutdown.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-gracefully-shutdown.json
new file mode 100644
index 0000000..d026b9e
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-gracefully-shutdown.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-gracefully-shutdown.md",
+  "__html": "<h1>Dubbo 优雅停机</h1>\n<h2>背景</h2>\n<p>对于任何一个线上应用,如何在服务更新部署过程中保证客户端无感知是开发者必须要解决的问题,即从应用停止到重启恢复服务这个阶段不能影响正常的业务请求。理想条件下,在没有请求的时候再进行更新是最安全可靠的,然而互联网应用必须要保证可用性,因此在技术层面上优化应用更新流程来保证服务在更新时无损是必要的。</p>\n<p>传统的解决方式是通过将应用更新流程划分为手工摘流量、停应用、更新重启三个步骤,由人工操作实现客户端无对更新感知。这种方式简单而有效,但是限制较多:不仅需要使用借助网关的支持来摘流量,还需要在停应用前人工判断来保证在途请求已经处理完毕。这种需要人工介入的方式运维复杂度较高,只能适用规模较小的应用,无法在大规模系统上使用。</
 p>\n<p>因此,如果在容器/框架级别提供某种自动化机制,来自动进行摘流量并确保处理完以到达的请求,不仅能保证业务不受更新影响,还可以极大地提升更新应用时的运维效率。</p>\n<p>这个机制也就是优雅停机,目前Tomcat/Undertow/ [...]
+  "link": "/zh-cn/blog/dubbo-gracefully-shutdown.html",
+  "meta": {
+    "title": "Dubbo 优雅停机",
+    "keywords": "Dubbo, Gracefully Shutdown, Safely Shutdown",
+    "description": "介绍Dubbo优雅停机的原理和使用方式"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-heartbeat-design.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-heartbeat-design.html
new file mode 100644
index 0000000..adb1b12
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-heartbeat-design.html
@@ -0,0 +1,358 @@
+<!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="Dubbo, 心跳" />
+	<meta name="description" content="一种心跳,两种设计" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo 现有心跳方案总结以及改进建议</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h3>1 前言</h3>
+<p>设计一个好的心跳机制并不是一件容易的事,就我所熟知的几个 RPC 框架,它们的心跳机制可以说大相径庭,这篇文章我将探讨一下<strong>如何设计一个优雅的心跳机制,主要从 Dubbo 的现有方案以及一个改进方案来做分析</strong>。</p>
+<h3>2 预备知识</h3>
+<p>因为后续我们将从源码层面来进行介绍,所以一些服务治理框架的细节还需要提前交代一下,方便大家理解。</p>
+<h4>2.1 客户端如何得知请求失败了?</h4>
+<p>高性能的 RPC 框架几乎都会选择使用 Netty 来作为通信层的组件,非阻塞式通信的高效不需要我做过多的介绍。但也由于非阻塞的特性,导致其发送数据和接收数据是一个异步的过程,所以当存在服务端异常、网络问题时,客户端是接收不到响应的,那么我们如何判断一次 RPC 调用是失败的呢?</p>
+<p>误区一:Dubbo 调用不是默认同步的吗?</p>
+<p>Dubbo 在通信层是异步的,呈现给使用者同步的错觉是因为内部做了阻塞等待,实现了异步转同步。</p>
+<p>误区二: <code>Channel.writeAndFlush</code> 会返回一个 <code>channelFuture</code>,我只需要判断 <code>channelFuture.isSuccess</code> 就可以判断请求是否成功了。</p>
+<p>注意,writeAndFlush 成功并不代表对端接受到了请求,返回值为 true 只能保证写入网络缓冲区成功,并不代表发送成功。</p>
+<p>避开上述两个误区,我们再来回到本小节的标题:客户端如何得知请求失败?<strong>正确的逻辑应当是以客户端接收到失败响应为判断依据</strong>。等等,前面不还在说在失败的场景中,服务端是不会返回响应的吗?没错,既然服务端不会返回,那就只能客户端自己造了。</p>
+<p>一个常见的设计是:客户端发起一个 RPC 请求,会设置一个超时时间 <code>client_timeout</code>,发起调用的同时,客户端会开启一个延迟 <code>client_timeout</code> 的定时器</p>
+<ul>
+<li>接收到正常响应时,移除该定时器。</li>
+<li>定时器倒计时完毕,还没有被移除,则认为请求超时,构造一个失败的响应传递给客户端。</li>
+</ul>
+<p>Dubbo 中的超时判定逻辑:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> DefaultFuture <span class="hljs-title">newFuture</span><span class="hljs-params">(Channel channel, Request request, <span class="hljs-keyword">int</span> timeout)</span> </span>{
+    <span class="hljs-keyword">final</span> DefaultFuture future = <span class="hljs-keyword">new</span> DefaultFuture(channel, request, timeout);
+    <span class="hljs-comment">// timeout check</span>
+    timeoutCheck(future);
+    <span class="hljs-keyword">return</span> future;
+}
+<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">timeoutCheck</span><span class="hljs-params">(DefaultFuture future)</span> </span>{
+    TimeoutCheckTask task = <span class="hljs-keyword">new</span> TimeoutCheckTask(future);
+    TIME_OUT_TIMER.newTimeout(task, future.getTimeout(), TimeUnit.MILLISECONDS);
+}
+<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TimeoutCheckTask</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">TimerTask</span> </span>{
+    <span class="hljs-keyword">private</span> DefaultFuture future;
+    TimeoutCheckTask(DefaultFuture future) {
+        <span class="hljs-keyword">this</span>.future = future;
+    }
+    <span class="hljs-meta">@Override</span>
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">(Timeout timeout)</span> </span>{
+        <span class="hljs-keyword">if</span> (future == <span class="hljs-keyword">null</span> || future.isDone()) {
+            <span class="hljs-keyword">return</span>;
+        }
+        <span class="hljs-comment">// create exception response.</span>
+        Response timeoutResponse = <span class="hljs-keyword">new</span> Response(future.getId());
+        <span class="hljs-comment">// set timeout status.</span>
+        timeoutResponse.setStatus(future.isSent() ? Response.SERVER_TIMEOUT : Response.CLIENT_TIMEOUT);
+        timeoutResponse.setErrorMessage(future.getTimeoutMessage(<span class="hljs-keyword">true</span>));
+        <span class="hljs-comment">// handle response.</span>
+        DefaultFuture.received(future.getChannel(), timeoutResponse);
+    }
+}
+
+</code></pre>
+<p>主要逻辑涉及的类:<code>DubboInvoker</code>,<code>HeaderExchangeChannel</code>,<code>DefaultFuture</code> ,通过上述代码,我们可以得知一个细节,无论是何种调用,都会经过这个定时器的检测,<strong>超时即调用失败,一次 RPC 调用的失败,必须以客户端收到失败响应为准</strong>。</p>
+<h4>2.2 心跳检测需要容错</h4>
+<p>网络通信永远要考虑到最坏的情况,一次心跳失败,不能认定为连接不通,多次心跳失败,才能采取相应的措施。</p>
+<h4>2.3 心跳检测不需要忙检测</h4>
+<p>忙检测的对立面是空闲检测,我们做心跳的初衷,是为了保证连接的可用性,以保证及时采取断连,重连等措施。如果一条通道上有频繁的 RPC 调用正在进行,我们不应该为通道增加负担去发送心跳包。<strong>心跳扮演的角色应当是晴天收伞,雨天送伞。</strong></p>
+<h3>3 Dubbo 现有方案</h3>
+<blockquote>
+<p>本文的源码对应 Dubbo  2.7.x 版本,在 apache 孵化的该版本中,心跳机制得到了增强。</p>
+</blockquote>
+<p>介绍完了一些基础的概念,我们再来看看 Dubbo 是如何设计应用层心跳的。Dubbo 的心跳是双向心跳,客户端会给服务端发送心跳,反之,服务端也会向客户端发送心跳。</p>
+<h4>3.1 连接建立时创建定时器</h4>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HeaderExchangeClient</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ExchangeClient</span> </span>{
+    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> heartbeat;
+    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> heartbeatTimeout;
+    <span class="hljs-keyword">private</span> HashedWheelTimer heartbeatTimer;
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">HeaderExchangeClient</span><span class="hljs-params">(Client client, <span class="hljs-keyword">boolean</span> needHeartbeat)</span> </span>{
+        <span class="hljs-keyword">this</span>.client = client;
+        <span class="hljs-keyword">this</span>.channel = <span class="hljs-keyword">new</span> HeaderExchangeChannel(client);
+        <span class="hljs-keyword">this</span>.heartbeat = client.getUrl().getParameter(Constants.HEARTBEAT_KEY, dubbo != <span class="hljs-keyword">null</span> &amp;&amp; dubbo.startsWith(<span class="hljs-string">"1.0."</span>) ? Constants.DEFAULT_HEARTBEAT : <span class="hljs-number">0</span>);
+        <span class="hljs-keyword">this</span>.heartbeatTimeout = client.getUrl().getParameter(Constants.HEARTBEAT_TIMEOUT_KEY, heartbeat * <span class="hljs-number">3</span>);
+        <span class="hljs-keyword">if</span> (needHeartbeat) { &lt;<span class="hljs-number">1</span>&gt;
+            <span class="hljs-keyword">long</span> tickDuration = calculateLeastDuration(heartbeat);
+            heartbeatTimer = <span class="hljs-keyword">new</span> HashedWheelTimer(<span class="hljs-keyword">new</span> NamedThreadFactory(<span class="hljs-string">"dubbo-client-heartbeat"</span>, <span class="hljs-keyword">true</span>), tickDuration,
+                    TimeUnit.MILLISECONDS, Constants.TICKS_PER_WHEEL); &lt;<span class="hljs-number">2</span>&gt;
+            startHeartbeatTimer();
+        }
+    }
+ }
+</code></pre>
+<p>&lt;1&gt; <strong>默认开启心跳检测的定时器</strong></p>
+<p>&lt;2&gt; <strong>创建了一个 <code>HashedWheelTimer</code> 开启心跳检测</strong>,这是 Netty 所提供的一个经典的时间轮定时器实现,至于它和 jdk 的实现有何不同,不了解的同学也可以关注下,我就不拓展了。</p>
+<p>不仅 <code>HeaderExchangeClient</code> 客户端开起了定时器,<code>HeaderExchangeServer</code> 服务端同样开起了定时器,由于服务端的逻辑和客户端几乎一致,所以后续我并不会重复粘贴服务端的代码。</p>
+<blockquote>
+<p>Dubbo 在早期版本版本中使用的是 schedule 方案,在 2.7.x 中替换成了 HashedWheelTimer。</p>
+</blockquote>
+<h4>3.2 开启两个定时任务</h4>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">startHeartbeatTimer</span><span class="hljs-params">()</span> </span>{
+    <span class="hljs-keyword">long</span> heartbeatTick = calculateLeastDuration(heartbeat);
+    <span class="hljs-keyword">long</span> heartbeatTimeoutTick = calculateLeastDuration(heartbeatTimeout);
+    HeartbeatTimerTask heartBeatTimerTask = <span class="hljs-keyword">new</span> HeartbeatTimerTask(cp, heartbeatTick, heartbeat); &lt;<span class="hljs-number">1</span>&gt;
+    ReconnectTimerTask reconnectTimerTask = <span class="hljs-keyword">new</span> ReconnectTimerTask(cp, heartbeatTimeoutTick, heartbeatTimeout); &lt;<span class="hljs-number">2</span>&gt;
+
+    heartbeatTimer.newTimeout(heartBeatTimerTask, heartbeatTick, TimeUnit.MILLISECONDS);
+    heartbeatTimer.newTimeout(reconnectTimerTask, heartbeatTimeoutTick, TimeUnit.MILLISECONDS);
+}
+</code></pre>
+<p>Dubbo 在 <code>startHeartbeatTimer</code> 方法中主要开启了两个定时器: <code>HeartbeatTimerTask</code>,<code>ReconnectTimerTask</code></p>
+<p>&lt;1&gt; <code>HeartbeatTimerTask</code> 主要用于定时发送心跳请求</p>
+<p>&lt;2&gt; <code>ReconnectTimerTask</code>  主要用于心跳失败之后处理重连,断连的逻辑</p>
+<p>至于方法中的其他代码,其实也是本文的重要分析内容,先容我卖个关子,后面再来看追溯。</p>
+<h4>3.3 定时任务一:发送心跳请求</h4>
+<p>详细解析下心跳检测定时任务的逻辑 <code>HeartbeatTimerTask#doTask</code>:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doTask</span><span class="hljs-params">(Channel channel)</span> </span>{
+    Long lastRead = lastRead(channel);
+    Long lastWrite = lastWrite(channel);
+    <span class="hljs-keyword">if</span> ((lastRead != <span class="hljs-keyword">null</span> &amp;&amp; now() - lastRead &gt; heartbeat)
+        || (lastWrite != <span class="hljs-keyword">null</span> &amp;&amp; now() - lastWrite &gt; heartbeat)) {
+            Request req = <span class="hljs-keyword">new</span> Request();
+            req.setVersion(Version.getProtocolVersion());
+            req.setTwoWay(<span class="hljs-keyword">true</span>);
+            req.setEvent(Request.HEARTBEAT_EVENT);
+            channel.send(req);
+        }
+    }
+}
+</code></pre>
+<p>前面已经介绍过,<strong>Dubbo 采取的是双向心跳设计</strong>,即服务端会向客户端发送心跳,客户端也会向服务端发送心跳,接收的一方更新 lastRead 字段,发送的一方更新 lastWrite 字段,超过心跳间隙的时间,便发送心跳请求给对端。这里的 lastRead/lastWrite 同样会被同一个通道上的普通调用更新,通过更新这两个字段,实现了只在连接空闲时才会真正发送空闲报文的机制,符合我们一开始科普的做法。</p>
+<blockquote>
+<p>注意:不仅仅心跳请求会更新 lastRead 和 lastWrite,普通请求也会。这对应了我们预备知识中的空闲检测机制。</p>
+</blockquote>
+<h4>3.4 定时任务二:处理重连和断连</h4>
+<p>继续研究下重连和断连定时器都实现了什么 <code>ReconnectTimerTask#doTask</code>。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doTask</span><span class="hljs-params">(Channel channel)</span> </span>{
+    Long lastRead = lastRead(channel);
+    Long now = now();
+    <span class="hljs-keyword">if</span> (lastRead != <span class="hljs-keyword">null</span> &amp;&amp; now - lastRead &gt; heartbeatTimeout) {
+        <span class="hljs-keyword">if</span> (channel <span class="hljs-keyword">instanceof</span> Client) {
+            ((Client) channel).reconnect();
+        } <span class="hljs-keyword">else</span> {
+            channel.close();
+        }
+    }
+}
+</code></pre>
+<p>第二个定时器则负责根据客户端、服务端类型来对连接做不同的处理,当超过设置的心跳总时间之后,客户端选择的是重新连接,服务端则是选择直接断开连接。这样的考虑是合理的,客户端调用是强依赖可用连接的,而服务端可以等待客户端重新建立连接。</p>
+<blockquote>
+<p>细心的朋友会发现,这个类被命名为 ReconnectTimerTask 是不太准确的,因为它处理的是重连和断连两个逻辑。</p>
+</blockquote>
+<h4>3.5 定时不精确的问题</h4>
+<p>在 Dubbo 的 issue 中曾经有人反馈过定时不精确的问题,我们来看看是怎么一回事。</p>
+<p>Dubbo 中默认的心跳周期是 60s,设想如下的时序:</p>
+<ul>
+<li>第 0 秒,心跳检测发现连接活跃</li>
+<li>第 1 秒,连接实际断开</li>
+<li>第 60 秒,心跳检测发现连接不活跃</li>
+</ul>
+<p>由于<strong>时间窗口的问题,死链不能够被及时检测出来,最坏情况为一个心跳周期</strong>。</p>
+<p>为了解决上述问题,我们再倒回去看一下上面的 <code>startHeartbeatTimer()</code> 方法</p>
+<pre><code class="language-java"><span class="hljs-keyword">long</span> heartbeatTick = calculateLeastDuration(heartbeat); 
+<span class="hljs-keyword">long</span> heartbeatTimeoutTick = calculateLeastDuration(heartbeatTimeout);
+</code></pre>
+<p>其中 <code>calculateLeastDuration</code> 根据心跳时间和超时时间分别计算出了一个 tick 时间,实际上就是将两个变量除以了 3,使得他们的值缩小,并传入了 <code>HashedWheelTimer</code> 的第二个参数之中</p>
+<pre><code class="language-java">heartbeatTimer.newTimeout(heartBeatTimerTask, heartbeatTick, TimeUnit.MILLISECONDS);
+heartbeatTimer.newTimeout(reconnectTimerTask, heartbeatTimeoutTick, TimeUnit.MILLISECONDS);
+</code></pre>
+<p>tick 的含义便是定时任务执行的频率。这样,通过减少检测间隔时间,增大了及时发现死链的概率,原先的最坏情况是 60s,如今变成了 20s。这个频率依旧可以加快,但需要考虑资源消耗的问题。</p>
+<blockquote>
+<p>定时不准确的问题出现在 Dubbo 的两个定时任务之中,所以都做了 tick 操作。事实上,所有的定时检测的逻辑都存在类似的问题。</p>
+</blockquote>
+<h4>3.6 Dubbo 心跳总结</h4>
+<p>Dubbo 对于建立的每一个连接,同时在客户端和服务端开启了 2 个定时器,一个用于定时发送心跳,一个用于定时重连、断连,执行的频率均为各自检测周期的 1/3。定时发送心跳的任务负责在连接空闲时,向对端发送心跳包。定时重连、断连的任务负责检测 lastRead 是否在超时周期内仍未被更新,如果判定为超时,客户端处理的逻辑是重连,服务端则采取断连的措施。</p>
+<p>先不急着判断这个方案好不好,再来看看改进方案是怎么设计的。</p>
+<h3>4 Dubbo 改进方案</h3>
+<p>实际上我们可以更优雅地实现心跳机制,本小节开始,我将介绍一个新的心跳机制。</p>
+<h4>4.1 IdleStateHandler 介绍</h4>
+<p>Netty 对空闲连接的检测提供了天然的支持,使用 <code>IdleStateHandler</code> 可以很方便的实现空闲检测逻辑。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">IdleStateHandler</span><span class="hljs-params">(
+            <span class="hljs-keyword">long</span> readerIdleTime, <span class="hljs-keyword">long</span> writerIdleTime, <span class="hljs-keyword">long</span> allIdleTime,
+            TimeUnit unit)</span> </span>{}
+</code></pre>
+<ul>
+<li>readerIdleTime:读超时时间</li>
+<li>writerIdleTime:写超时时间</li>
+<li>allIdleTime:所有类型的超时时间</li>
+</ul>
+<p><code>IdleStateHandler</code> 这个类会根据设置的超时参数,循环检测 channelRead 和 write 方法多久没有被调用。当在 pipeline 中加入 <code>IdleSateHandler</code> 之后,可以在此 pipeline 的任意 Handler 的 <code>userEventTriggered</code> 方法之中检测 <code>IdleStateEvent</code> 事件,</p>
+<pre><code class="language-java"><span class="hljs-meta">@Override</span>
+<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">userEventTriggered</span><span class="hljs-params">(ChannelHandlerContext ctx, Object evt)</span> <span class="hljs-keyword">throws</span> Exception </span>{
+    <span class="hljs-keyword">if</span> (evt <span class="hljs-keyword">instanceof</span> IdleStateEvent) {
+        <span class="hljs-comment">//do something</span>
+    }
+    ctx.fireUserEventTriggered(evt);
+}
+</code></pre>
+<p>为什么需要介绍 <code>IdleStateHandler</code> 呢?其实提到它的空闲检测 + 定时的时候,大家应该能够想到了,这不天然是给心跳机制服务的吗?很多服务治理框架都选择了借助 <code>IdleStateHandler</code> 来实现心跳。</p>
+<blockquote>
+<p>IdleStateHandler 内部使用了 eventLoop.schedule(task) 的方式来实现定时任务,使用 eventLoop 线程的好处是还同时保证了<strong>线程安全</strong>,这里是一个小细节。</p>
+</blockquote>
+<h4>4.2 客户端和服务端配置</h4>
+<p>首先是将 <code>IdleStateHandler</code> 加入 pipeline 中。</p>
+<p><strong>客户端:</strong></p>
+<pre><code class="language-java">bootstrap.handler(<span class="hljs-keyword">new</span> ChannelInitializer&lt;NioSocketChannel&gt;() {
+    <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">initChannel</span><span class="hljs-params">(NioSocketChannel ch)</span> <span class="hljs-keyword">throws</span> Exception </span>{
+        ch.pipeline().addLast(<span class="hljs-string">"clientIdleHandler"</span>, <span class="hljs-keyword">new</span> IdleStateHandler(<span class="hljs-number">60</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>));
+    }
+});
+</code></pre>
+<p><strong>服务端:</strong></p>
+<pre><code class="language-java">serverBootstrap.childHandler(<span class="hljs-keyword">new</span> ChannelInitializer&lt;NioSocketChannel&gt;() {
+    <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">initChannel</span><span class="hljs-params">(NioSocketChannel ch)</span> <span class="hljs-keyword">throws</span> Exception </span>{
+        ch.pipeline().addLast(<span class="hljs-string">"serverIdleHandler"</span>,<span class="hljs-keyword">new</span> IdleStateHandler(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">200</span>));
+    }
+}
+</code></pre>
+<p>客户端配置了 read 超时为 60s,服务端配置了 write/read 超时为 200s,先在此埋下两个伏笔:</p>
+<ol>
+<li>为什么客户端和服务端配置的超时时间不一致?</li>
+<li>为什么客户端检测的是读超时,而服务端检测的是读写超时?</li>
+</ol>
+<h4>4.3 空闲超时逻辑 — 客户端</h4>
+<p>对于空闲超时的处理逻辑,客户端和服务端是不同的。首先来看客户端</p>
+<pre><code class="language-java"><span class="hljs-meta">@Override</span>
+<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">userEventTriggered</span><span class="hljs-params">(ChannelHandlerContext ctx, Object evt)</span> <span class="hljs-keyword">throws</span> Exception </span>{
+    <span class="hljs-keyword">if</span> (evt <span class="hljs-keyword">instanceof</span> IdleStateEvent) {
+        <span class="hljs-comment">// send heartbeat</span>
+        sendHeartBeat();
+    } <span class="hljs-keyword">else</span> {
+        <span class="hljs-keyword">super</span>.userEventTriggered(ctx, evt);
+    }
+}
+</code></pre>
+<p>检测到空闲超时之后,采取的行为是向服务端发送心跳包,具体是如何发送,以及处理响应的呢?伪代码如下</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sendHeartBeat</span><span class="hljs-params">()</span> </span>{
+    Invocation invocation = <span class="hljs-keyword">new</span> Invocation();
+    invocation.setInvocationType(InvocationType.HEART_BEAT);
+    channel.writeAndFlush(invocation).addListener(<span class="hljs-keyword">new</span> CallbackFuture() {
+        <span class="hljs-meta">@Override</span>
+        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">callback</span><span class="hljs-params">(Future future)</span> </span>{
+            RPCResult result = future.get();
+            <span class="hljs-comment">//超时 或者 写失败</span>
+            <span class="hljs-keyword">if</span> (result.isError()) {
+                channel.addFailedHeartBeatTimes();
+                <span class="hljs-keyword">if</span> (channel.getFailedHeartBeatTimes() &gt;= channel.getMaxHeartBeatFailedTimes()) {
+                    channel.reconnect();
+                }
+            } <span class="hljs-keyword">else</span> {
+                channel.clearHeartBeatFailedTimes();
+            }
+        }
+    });
+}
+</code></pre>
+<p>行为并不复杂,构造一个心跳包发送到服务端,接受响应结果</p>
+<ul>
+<li>响应成功,清空请求失败标记</li>
+<li>响应失败,心跳失败标记+1,如果超过配置的失败次数,则重新连接</li>
+</ul>
+<blockquote>
+<p>不仅仅是心跳,普通请求返回成功响应时也会清空标记</p>
+</blockquote>
+<h4>4.4 空闲超时逻辑 — 服务端</h4>
+<pre><code class="language-java"><span class="hljs-meta">@Override</span>
+<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">userEventTriggered</span><span class="hljs-params">(ChannelHandlerContext ctx, Object evt)</span> <span class="hljs-keyword">throws</span> Exception </span>{
+    <span class="hljs-keyword">if</span> (evt <span class="hljs-keyword">instanceof</span> IdleStateEvent) {
+        channel.close();
+    } <span class="hljs-keyword">else</span> {
+        <span class="hljs-keyword">super</span>.userEventTriggered(ctx, evt);
+    }
+}
+</code></pre>
+<p>服务端处理空闲连接的方式非常简单粗暴,直接关闭连接。</p>
+<h4>4.5 改进方案心跳总结</h4>
+<ol>
+<li>
+<p>为什么客户端和服务端配置的超时时间不一致?</p>
+<p>因为客户端有重试逻辑,不断发送心跳失败 n 次之后,才认为是连接断开;而服务端是直接断开,留给服务端时间得长一点。60 * 3 &lt; 200 还说明了一个问题,双方都拥有断开连接的能力,但连接的创建是由客户端主动发起的,那么客户端也更有权利去主动断开连接。</p>
+</li>
+<li>
+<p>为什么客户端检测的是读超时,而服务端检测的是读写超时?</p>
+<p>这其实是一个心跳的共识了,仔细思考一下,定时逻辑是由客户端发起的,所以整个链路中不通的情况只有可能是:服务端接收,服务端发送,客户端接收。也就是说,只有客户端的 pong,服务端的 ping,pong 的检测是有意义的。</p>
+</li>
+</ol>
+<blockquote>
+<p>主动追求别人的是你,主动说分手的也是你。</p>
+</blockquote>
+<p>利用 <code>IdleStateHandler</code> 实现心跳机制可以说是十分优雅的,借助 Netty 提供的空闲检测机制,利用客户端维护单向心跳,在收到 3 次心跳失败响应之后,客户端断开连接,交由异步线程重连,本质还是表现为客户端重连。服务端在连接空闲较长时间后,主动断开连接,以避免无谓的资源浪费。</p>
+<h3>5 心跳设计方案对比</h3>
+<table>
+<thead>
+<tr>
+<th style="text-align:center"></th>
+<th style="text-align:center">Dubbo 现有方案</th>
+<th style="text-align:center">Dubbo 改进方案</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td style="text-align:center"><strong>主体设计</strong></td>
+<td style="text-align:center">开启两个定时器</td>
+<td style="text-align:center">借助 IdleStateHandler,底层使用 schedule</td>
+</tr>
+<tr>
+<td style="text-align:center"><strong>心跳方向</strong></td>
+<td style="text-align:center">双向</td>
+<td style="text-align:center">单向(客户端 -&gt; 服务端)</td>
+</tr>
+<tr>
+<td style="text-align:center"><strong>心跳失败判定方式</strong></td>
+<td style="text-align:center">心跳成功更新标记,借助定时器定时扫描标记,如果超过心跳超时周期未更新标记,认为心跳失败。</td>
+<td style="text-align:center">通过判断心跳响应是否失败,超过失败次数,认为心跳失败</td>
+</tr>
+<tr>
+<td style="text-align:center"><strong>扩展性</strong></td>
+<td style="text-align:center">Dubbo 存在 mina,grizzy 等其他通信层实现,自定义定时器很容易适配多种扩展</td>
+<td style="text-align:center">多通信层各自实现心跳,不做心跳的抽象</td>
+</tr>
+<tr>
+<td style="text-align:center"><strong>设计性</strong></td>
+<td style="text-align:center">编码复杂度高,代码量大,方案复杂,不易维护</td>
+<td style="text-align:center">编码量小,可维护性强</td>
+</tr>
+</tbody>
+</table>
+<p>私下请教过<strong>美团点评的长连接负责人:俞超(闪电侠)</strong>,美点使用的心跳方案和 Dubbo 改进方案几乎一致,可以说该方案是标准实现了。</p>
+<h3>6 Dubbo 实际改动点建议</h3>
+<p>鉴于 Dubbo 存在一些其他通信层的实现,所以可以保留现有的定时发送心跳的逻辑。</p>
+<ul>
+<li><strong>建议改动点一:</strong></li>
+</ul>
+<p>双向心跳的设计是不必要的,兼容现有的逻辑,可以让客户端在连接空闲时发送单向心跳,服务端定时检测连接可用性。定时时间尽量保证:客户端超时时间 * 3 ≈ 服务端超时时间</p>
+<ul>
+<li><strong>建议改动点二:</strong></li>
+</ul>
+<p>去除处理重连和断连的定时任务,Dubbo 可以判断心跳请求是否响应失败,可以借鉴改进方案的设计,在连接级别维护一个心跳失败次数的标记,任意响应成功,清除标记;连续心跳失败 n 次,客户端发起重连。这样可以减少一个不必要的定时器,任何轮询的方式,都是不优雅的。</p>
+<p>最后再聊聊可扩展性这个话题。其实我是建议把定时器交给更加底层的 Netty 去做,也就是完全使用 <code>IdleStateHandler</code> ,其他通信层组件各自实现自己的空闲检测逻辑,但是 Dubbo 中 mina,grizzy 的兼容问题囿住了我的拳脚,但试问一下,如今的 2019 年,又有多少人在使用 mina 和 grizzy?因为一些不太可能用的特性,而限制了主流用法的优化,这肯定不是什么好事。抽象,功能,可扩展性并不是越多越好,开源产品的人力资源是有限的,框架使用者的理解能力也是有限的,能解决大多数人问题的设计,才是好的设计。哎,谁让我不会 mina,grizzy,还懒得去学呢[摊手]。</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-heartbeat-design.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-heartbeat-design.json
new file mode 100644
index 0000000..1d60ed2
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-heartbeat-design.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-heartbeat-design.md",
+  "__html": "<h1>Dubbo 现有心跳方案总结以及改进建议</h1>\n<h3>1 前言</h3>\n<p>设计一个好的心跳机制并不是一件容易的事,就我所熟知的几个 RPC 框架,它们的心跳机制可以说大相径庭,这篇文章我将探讨一下<strong>如何设计一个优雅的心跳机制,主要从 Dubbo 的现有方案以及一个改进方案来做分析</strong>。</p>\n<h3>2 预备知识</h3>\n<p>因为后续我们将从源码层面来进行介绍,所以一些服务治理框架的细节还需要提前交代一下,方便大家理解。</p>\n<h4>2.1 客户端如何得知请求失败了?</h4>\n<p>高性能的 RPC 框架几乎都会选择使用 Netty 来作为通信层的组件,非阻塞式通信的高效不需要我做过多的介绍。但也由于非阻塞的特性,导致其发送数据和接收数据是一个异步的过程,所以当存在服务端异常、网络问题时,客户端是接收不到响应的,那么我们如何判断一次 RP
 C 调用是失败的呢?</p>\n<p>误区一:Dubbo 调用不是默认同步的吗?</p>\n<p>Dubbo 在通信层是异步的,呈现给使用 [...]
+  "link": "/zh-cn/blog/dubbo-heartbeat-design.html",
+  "meta": {
+    "title": "Dubbo 现有心跳方案总结以及改进建议",
+    "keywords": "Dubbo, 心跳",
+    "description": "一种心跳,两种设计"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-integrate-with-hystrix.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-integrate-with-hystrix.html
new file mode 100644
index 0000000..672aa2f
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-integrate-with-hystrix.html
@@ -0,0 +1,198 @@
+<!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="Dubbo, Spring, Hystrix" />
+	<meta name="description" content="本文介绍在spring应用里,怎么把Dubbo和Hystrix结合起来使用。" />
+	<!-- 网页标签标题 -->
+	<title>Spring应用快速集成Dubbo + Hystrix</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>背景</h2>
+<p>Hystrix 旨在通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能。</p>
+<p>Dubbo是Alibaba开源的,目前国内最流行的java rpc框架。</p>
+<p>本文介绍在spring应用里,怎么把Dubbo和Hystrix结合起来使用。</p>
+<ul>
+<li><a href="https://github.com/Netflix/Hystrix">https://github.com/Netflix/Hystrix</a></li>
+<li><a href="https://github.com/apache/dubbo">https://github.com/apache/dubbo</a></li>
+</ul>
+<h2>Spring Boot应用</h2>
+<p>Demo地址: <a href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-spring-boot-hystrix">https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-spring-boot-hystrix</a></p>
+<h3>生成dubbo集成spring boot的应用</h3>
+<p>对于不熟悉dubbo 集成spring boot应用的同学,可以在这里直接生成dubbo + spring boot的工程: <a href="http://start.dubbo.io/">http://start.dubbo.io/</a></p>
+<h3>配置spring-cloud-starter-netflix-hystrix</h3>
+<p>spring boot官方提供了对hystrix的集成,直接在pom.xml里加入依赖:</p>
+<pre><code>        &lt;dependency&gt;
+            &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
+            &lt;artifactId&gt;spring-cloud-starter-netflix-hystrix&lt;/artifactId&gt;
+            &lt;version&gt;1.4.4.RELEASE&lt;/version&gt;
+        &lt;/dependency&gt;
+</code></pre>
+<p>然后在Application类上增加<code>@EnableHystrix</code>来启用hystrix starter:</p>
+<pre><code>@SpringBootApplication
+@EnableHystrix
+public class ProviderApplication {
+</code></pre>
+<h3>配置Provider端</h3>
+<p>在Dubbo的Provider上增加<code>@HystrixCommand</code>配置,这样子调用就会经过Hystrix代理。</p>
+<pre><code>@Service(version = &quot;1.0.0&quot;)
+public class HelloServiceImpl implements HelloService {
+    @HystrixCommand(commandProperties = {
+                    @HystrixProperty(name = &quot;circuitBreaker.requestVolumeThreshold&quot;, value = &quot;10&quot;),
+                    @HystrixProperty(name = &quot;execution.isolation.thread.timeoutInMilliseconds&quot;, value = &quot;2000&quot;) })
+    @Override
+    public String sayHello(String name) {
+        // System.out.println(&quot;async provider received: &quot; + name);
+        // return &quot;annotation: hello, &quot; + name;
+        throw new RuntimeException(&quot;Exception to show hystrix enabled.&quot;);
+    }
+}
+</code></pre>
+<h3>配置Consumer端</h3>
+<p>对于Consumer端,则可以增加一层method调用,并在method上配置<code>@HystrixCommand</code>。当调用出错时,会走到<code>fallbackMethod = &quot;reliable&quot;</code>的调用里。</p>
+<pre><code>    @Reference(version = &quot;1.0.0&quot;)
+    private HelloService demoService;
+
+    @HystrixCommand(fallbackMethod = &quot;reliable&quot;)
+    public String doSayHello(String name) {
+        return demoService.sayHello(name);
+    }
+    public String reliable(String name) {
+        return &quot;hystrix fallback value&quot;;
+    }
+</code></pre>
+<p>通过上面的配置,很简单地就完成了Spring Boot里Dubbo + Hystrix的集成。</p>
+<h2>传统Spring Annotation应用</h2>
+<p>Demo地址: <a href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-spring-hystrix">https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-spring-hystrix</a></p>
+<p>传统spring annotation应用的配置其实也很简单,和spring boot应用不同的是:</p>
+<ol>
+<li>显式配置Spring AOP支持:<code>@EnableAspectJAutoProxy</code></li>
+<li>显式通过<code>@Configuration</code>配置<code>HystrixCommandAspect</code> Bean。</li>
+</ol>
+<pre><code>    @Configuration
+    @EnableDubbo(scanBasePackages = &quot;com.alibaba.dubbo.samples.annotation.action&quot;)
+    @PropertySource(&quot;classpath:/spring/dubbo-consumer.properties&quot;)
+    @ComponentScan(value = {&quot;com.alibaba.dubbo.samples.annotation.action&quot;})
+    @EnableAspectJAutoProxy
+    static public class ConsumerConfiguration {
+
+        @Bean
+        public HystrixCommandAspect hystrixCommandAspect() {
+            return new HystrixCommandAspect();
+        }
+    }
+</code></pre>
+<h2>Hystrix集成Spring AOP原理</h2>
+<p>在上面的例子里可以看到,Hystrix对Spring的集成是通过Spring AOP来实现的。下面简单分析下实现。</p>
+<pre><code>@Aspect
+public class HystrixCommandAspect {
+    @Pointcut(&quot;@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand)&quot;)
+    public void hystrixCommandAnnotationPointcut() {
+    }
+    @Pointcut(&quot;@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser)&quot;)
+    public void hystrixCollapserAnnotationPointcut() {
+    }
+
+    @Around(&quot;hystrixCommandAnnotationPointcut() || hystrixCollapserAnnotationPointcut()&quot;)
+    public Object methodsAnnotatedWithHystrixCommand(final ProceedingJoinPoint joinPoint) throws Throwable {
+        Method method = getMethodFromTarget(joinPoint);
+        Validate.notNull(method, &quot;failed to get method from joinPoint: %s&quot;, joinPoint);
+        if (method.isAnnotationPresent(HystrixCommand.class) &amp;&amp; method.isAnnotationPresent(HystrixCollapser.class)) {
+            throw new IllegalStateException(&quot;method cannot be annotated with HystrixCommand and HystrixCollapser &quot; +
+                    &quot;annotations at the same time&quot;);
+        }
+        MetaHolderFactory metaHolderFactory = META_HOLDER_FACTORY_MAP.get(HystrixPointcutType.of(method));
+        MetaHolder metaHolder = metaHolderFactory.create(joinPoint);
+        HystrixInvokable invokable = HystrixCommandFactory.getInstance().create(metaHolder);
+        ExecutionType executionType = metaHolder.isCollapserAnnotationPresent() ?
+                metaHolder.getCollapserExecutionType() : metaHolder.getExecutionType();
+
+        Object result;
+        try {
+            if (!metaHolder.isObservable()) {
+                result = CommandExecutor.execute(invokable, executionType, metaHolder);
+            } else {
+                result = executeObservable(invokable, executionType, metaHolder);
+            }
+        } catch (HystrixBadRequestException e) {
+            throw e.getCause() != null ? e.getCause() : e;
+        } catch (HystrixRuntimeException e) {
+            throw hystrixRuntimeExceptionToThrowable(metaHolder, e);
+        }
+        return result;
+    }
+</code></pre>
+<ol>
+<li><code>HystrixCommandAspect</code>里定义了两个注解的AspectJ Pointcut:<code>@HystrixCommand</code>, <code>@HystrixCollapser</code>。所有带这两个注解的spring bean都会经过AOP处理</li>
+<li>在<code>@Around</code> AOP处理函数里,可以看到Hystrix会创建出<code>HystrixInvokable</code>,再通过<code>CommandExecutor</code>来执行</li>
+</ol>
+<h2>spring-cloud-starter-netflix-hystrix的代码分析</h2>
+<ol>
+<li>
+<p><code>@EnableHystrix</code> 引入了<code>@EnableCircuitBreaker</code>,<code>@EnableCircuitBreaker</code>引入了<code>EnableCircuitBreakerImportSelector</code></p>
+<pre><code>@EnableCircuitBreaker
+public @interface EnableHystrix {
+}
+
+@Import(EnableCircuitBreakerImportSelector.class)
+public @interface EnableCircuitBreaker {
+}
+</code></pre>
+</li>
+<li>
+<p><code>EnableCircuitBreakerImportSelector</code>继承了<code>SpringFactoryImportSelector&lt;EnableCircuitBreaker&gt;</code>,使spring加载<code>META-INF/spring.factories</code>里的<code>EnableCircuitBreaker</code>声明的配置</p>
+<p>在<code>META-INF/spring.factories</code>里可以找到下面的配置,也就是引入了<code>HystrixCircuitBreakerConfiguration</code>。</p>
+<pre><code>org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\
+org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration
+</code></pre>
+</li>
+<li>
+<p>在<code>HystrixCircuitBreakerConfiguration</code>里可以发现创建了<code>HystrixCommandAspect</code></p>
+<pre><code>@Configuration
+public class HystrixCircuitBreakerConfiguration {
+
+    @Bean
+    public HystrixCommandAspect hystrixCommandAspect() {
+        return new HystrixCommandAspect();
+    }
+</code></pre>
+</li>
+</ol>
+<p>可见<code>spring-cloud-starter-netflix-hystrix</code>实际上也是创建了<code>HystrixCommandAspect</code>来集成Hystrix。</p>
+<p>另外<code>spring-cloud-starter-netflix-hystrix</code>里还有metrics, health, dashboard等集成。</p>
+<h2>总结</h2>
+<ul>
+<li>对于dubbo provider的<code>@Service</code>是一个spring bean,直接在上面配置<code>@HystrixCommand</code>即可</li>
+<li>对于dubbo consumer的<code>@Reference</code>,可以通过加一层简单的spring method包装,配置<code>@HystrixCommand</code>即可</li>
+<li>Hystrix本身提供<code>HystrixCommandAspect</code>来集成Spring AOP,配置了<code>@HystrixCommand</code>和<code>@HystrixCollapser</code>的spring method都会被Hystrix处理</li>
+</ul>
+<h2>链接</h2>
+<ul>
+<li><a href="https://github.com/Netflix/Hystrix">https://github.com/Netflix/Hystrix</a></li>
+<li><a href="https://github.com/apache/dubbo">https://github.com/apache/dubbo</a></li>
+<li><a href="http://start.dubbo.io/">http://start.dubbo.io/</a></li>
+<li><a href="https://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html#_circuit_breaker_hystrix_clients">https://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html#_circuit_breaker_hystrix_clients</a></li>
+</ul>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-integrate-with-hystrix.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-integrate-with-hystrix.json
new file mode 100644
index 0000000..c736cc4
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-integrate-with-hystrix.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-integrate-with-hystrix.md",
+  "__html": "<h1>Spring应用快速集成Dubbo + Hystrix</h1>\n<h2>背景</h2>\n<p>Hystrix 旨在通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能。</p>\n<p>Dubbo是Alibaba开源的,目前国内最流行的java rpc框架。</p>\n<p>本文介绍在spring应用里,怎么把Dubbo和Hystrix结合起来使用。</p>\n<ul>\n<li><a href=\"https://github.com/Netflix/Hystrix\">https://github.com/Netflix/Hystrix</a></li>\n<li><a href=\"https://github.com/apache/dubbo\">https://github.com/apache/dubbo</a></li>\n</ul>\n<h2>Spring Boot应用</h2>\n [...]
+  "link": "/zh-cn/blog/dubbo-integrate-with-hystrix.html",
+  "meta": {
+    "title": "Spring应用快速集成Dubbo + Hystrix",
+    "keywords": "Dubbo, Spring, Hystrix",
+    "description": "本文介绍在spring应用里,怎么把Dubbo和Hystrix结合起来使用。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-invoke.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-invoke.html
new file mode 100644
index 0000000..8a82342
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-invoke.html
@@ -0,0 +1,193 @@
+<!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="Dubbo, Invoke, Async" />
+	<meta name="description" content="本文介绍了Dubbo基于异步通讯机制实现的几种同步和异步调用方式。" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo 关于同步/异步调用的几种方式</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>我们知道,Dubbo 缺省协议采用单一长连接,底层实现是 Netty 的 NIO 异步通讯机制;基于这种机制,Dubbo 实现了以下几种调用方式:</p>
+<ul>
+<li>同步调用</li>
+<li>异步调用</li>
+<li>参数回调</li>
+<li>事件通知</li>
+</ul>
+<h2>同步调用</h2>
+<p>同步调用是一种阻塞式的调用方式,即 Consumer 端代码一直阻塞等待,直到 Provider 端返回为止;</p>
+<p>通常,一个典型的同步调用过程如下:</p>
+<ol>
+<li>Consumer 业务线程调用远程接口,向 Provider 发送请求,同时当前线程处于<code>阻塞</code>状态;</li>
+<li>Provider 接到 Consumer 的请求后,开始处理请求,将结果返回给 Consumer;</li>
+<li>Consumer 收到结果后,当前线程继续往后执行。</li>
+</ol>
+<p>这里有 2 个问题:</p>
+<ol>
+<li>Consumer 业务线程是怎么进入<code>阻塞</code>状态的?</li>
+<li>Consumer 收到结果后,如何唤醒业务线程往后执行的?</li>
+</ol>
+<p>其实,Dubbo 的底层 IO 操作都是异步的。Consumer 端发起调用后,得到一个 Future 对象。对于同步调用,业务线程通过<code>Future#get(timeout)</code>,阻塞等待 Provider 端将结果返回;<code>timeout</code>则是 Consumer 端定义的超时时间。当结果返回后,会设置到此 Future,并唤醒阻塞的业务线程;当超时时间到结果还未返回时,业务线程将会异常返回。</p>
+<h2>异步调用</h2>
+<p>基于 Dubbo 底层的异步 NIO 实现异步调用,对于 Provider 响应时间较长的场景是必须的,它能有效利用 Consumer 端的资源,相对于 Consumer 端使用多线程来说开销较小。</p>
+<p>异步调用,对于 Provider 端不需要做特别的配置。下面的例子中,Provider 端接口定义如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">AsyncService</span> </span>{
+    <span class="hljs-function">String <span class="hljs-title">goodbye</span><span class="hljs-params">(String name)</span></span>;
+}
+</code></pre>
+<h3>Consumer 配置</h3>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"asyncService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"com.alibaba.dubbo.samples.async.api.AsyncService"</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:method</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"goodbye"</span> <span class="hljs-attr">async</span>=<span class="hljs-string">"true"</span>/&gt;</span>
+<span class="hljs-tag">&lt;/<span class="hljs-name">dubbo:reference</span>&gt;</span>
+</code></pre>
+<p>需要异步调用的方法,均需要使用 <code>&lt;dubbo:method/&gt;</code>标签进行描述。</p>
+<h3>Consumer 端发起调用</h3>
+<pre><code class="language-java">AsyncService service = ...;
+String result = service.goodbye(<span class="hljs-string">"samples"</span>);<span class="hljs-comment">// 这里的返回值为空,请不要使用</span>
+Future&lt;String&gt; future = RpcContext.getContext().getFuture();
+... <span class="hljs-comment">// 业务线程可以开始做其他事情</span>
+result = future.get(); <span class="hljs-comment">// 阻塞需要获取异步结果时,也可以使用 get(timeout, unit) 设置超时时间</span>
+</code></pre>
+<p>Dubbo Consumer 端发起调用后,同时通过<code>RpcContext.getContext().getFuture()</code>获取跟返回结果关联的<code>Future</code>对象,然后就可以开始处理其他任务;当需要这次异步调用的结果时,可以在任意时刻通过<code>future.get(timeout)</code>来获取。</p>
+<p>一些特殊场景下,为了尽快调用返回,可以设置是否等待消息发出:</p>
+<ul>
+<li><code>sent=&quot;true&quot;</code> 等待消息发出,消息发送失败将抛出异常;</li>
+<li><code>sent=&quot;false&quot;</code> 不等待消息发出,将消息放入 IO 队列,即刻返回。</li>
+</ul>
+<p>默认为<code>false</code>。配置方式如下:</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:method</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"goodbye"</span> <span class="hljs-attr">async</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">sent</span>=<span class="hljs-string">"true"</span> /&gt;</span>
+</code></pre>
+<p>如果你只是想异步,完全忽略返回值,可以配置 <code>return=&quot;false&quot;</code>,以减少 Future 对象的创建和管理成本:</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:method</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"goodbye"</span> <span class="hljs-attr">async</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">return</span>=<span class="hljs-string">"false"</span>/&gt;</span>
+</code></pre>
+<p>此时,<code>RpcContext.getContext().getFuture()</code>将返回<code>null</code>。</p>
+<p>整个异步调用的时序图如下:</p>
+<p><img src="../../img/blog/dubbo-async.svg" alt="异步调用"></p>
+<p>此示例代码位于:<a href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-async">https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-async</a></p>
+<h2>参数回调</h2>
+<p>参数回调有点类似于本地 Callback 机制,但 Callback 并不是 Dubbo 内部的类或接口,而是由 Provider 端自定义的;Dubbo 将基于长连接生成反向代理,从而实现从 Provider 端调用 Consumer 端的逻辑。</p>
+<h3>Provider 端定义 Service 和 Callback</h3>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">CallbackService</span> </span>{
+    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">addListener</span><span class="hljs-params">(String key, CallbackListener listener)</span></span>;
+}
+
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">CallbackListener</span> </span>{
+    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">changed</span><span class="hljs-params">(String msg)</span></span>;
+}
+</code></pre>
+<h4>Provider 端 Service 实现</h4>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CallbackServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">CallbackService</span> </span>{
+
+    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Map&lt;String, CallbackListener&gt; listeners = <span class="hljs-keyword">new</span> ConcurrentHashMap&lt;String, CallbackListener&gt;();
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">CallbackServiceImpl</span><span class="hljs-params">()</span> </span>{
+        Thread t = <span class="hljs-keyword">new</span> Thread(<span class="hljs-keyword">new</span> Runnable() {
+            <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span> </span>{
+                <span class="hljs-keyword">while</span> (<span class="hljs-keyword">true</span>) {
+                    <span class="hljs-keyword">try</span> {
+                        <span class="hljs-keyword">for</span> (Map.Entry&lt;String, CallbackListener&gt; entry : listeners.entrySet()) {
+                            <span class="hljs-keyword">try</span> {
+                                entry.getValue().changed(getChanged(entry.getKey()));
+                            } <span class="hljs-keyword">catch</span> (Throwable t) {
+                                listeners.remove(entry.getKey());
+                            }
+                        }
+                        Thread.sleep(<span class="hljs-number">5000</span>); <span class="hljs-comment">// timely trigger change event</span>
+                    } <span class="hljs-keyword">catch</span> (Throwable t) {
+                        t.printStackTrace();
+                    }
+                }
+            }
+        });
+        t.setDaemon(<span class="hljs-keyword">true</span>);
+        t.start();
+    }
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">addListener</span><span class="hljs-params">(String key, CallbackListener listener)</span> </span>{
+        listeners.put(key, listener);
+        listener.changed(getChanged(key)); <span class="hljs-comment">// send notification for change</span>
+    }
+
+    <span class="hljs-function"><span class="hljs-keyword">private</span> String <span class="hljs-title">getChanged</span><span class="hljs-params">(String key)</span> </span>{
+        <span class="hljs-keyword">return</span> <span class="hljs-string">"Changed: "</span> + <span class="hljs-keyword">new</span> SimpleDateFormat(<span class="hljs-string">"yyyy-MM-dd HH:mm:ss"</span>).format(<span class="hljs-keyword">new</span> Date());
+    }
+}
+</code></pre>
+<h4>Provider 端暴露服务</h4>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"callbackService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"com.alibaba.dubbo.samples.callback.impl.CallbackServiceImpl"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"com.alibaba.dubbo.samples.callback.api.CallbackService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"callbackService"</span> <span class="hljs-attr">connections</span>=<span class="hljs-string">"1"</span> <span class="hljs-attr">callbacks</span>=<span class="hljs-string">"1000"</span>&gt;</span>
+    <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:method</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"addListener"</span>&gt;</span>
+        <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:argument</span> <span class="hljs-attr">index</span>=<span class="hljs-string">"1"</span> <span class="hljs-attr">callback</span>=<span class="hljs-string">"true"</span>/&gt;</span>
+        <span class="hljs-comment">&lt;!--&lt;dubbo:argument type="com.demo.CallbackListener" callback="true" /&gt;--&gt;</span>
+    <span class="hljs-tag">&lt;/<span class="hljs-name">dubbo:method</span>&gt;</span>
+<span class="hljs-tag">&lt;/<span class="hljs-name">dubbo:service</span>&gt;</span>
+</code></pre>
+<p>这里,Provider 需要在方法中声明哪个参数是 Callback 参数。</p>
+<h4>Consumer 端实现 Callback 接口</h4>
+<pre><code class="language-java">CallbackService callbackService = ...;
+callbackService.addListener(<span class="hljs-string">"foo.bar"</span>, <span class="hljs-keyword">new</span> CallbackListener() {
+        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">changed</span><span class="hljs-params">(String msg)</span> </span>{
+            System.out.println(<span class="hljs-string">"callback1:"</span> + msg);
+        }
+});
+</code></pre>
+<p>Callback 接口的实现类在 Consumer 端,当方法发生调用时,Consumer 端会自动 export 一个 Callback 服务。而 Provider 端在处理调用时,判断如果参数是 Callback,则生成了一个 proxy,因此服务实现类里在调用 Callback 方法的时候,会被传递到 Consumer 端执行 Callback 实现类的代码。</p>
+<p>上述示例代码位于:<a href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-callback">https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-callback</a></p>
+<p>这种调用方式有点像消息的发布和订阅,但又有区别。比如当 Consumer 端 完成了Callback 服务的 export 后,如果后续重启了,这时 Provider 端就会调不通;同时 Provider 端如何清理掉这个 proxy 也是一个问题。</p>
+<h2>事件通知</h2>
+<p>事件通知允许 Consumer 端在调用之前、调用之后或出现异常时,触发 <code>oninvoke</code>、<code>onreturn</code>、<code>onthrow</code> 三个事件。</p>
+<p>可以通过在配置 Consumer 时,指定事件需要通知的方法,如:</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoCallback"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"com.alibaba.dubbo.samples.notify.impl.NotifyImpl"</span> /&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">check</span>=<span class="hljs-string">"false"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"com.alibaba.dubbo.samples.notify.api.DemoService"</span> <span class="hljs-attr">version</span>=<span class="hljs-string">"1.0.0"</span> <span class="hljs-attr">group</span>=<span class="hljs [...]
+    <span class="hljs-tag">&lt;<span class="hljs-name">dubbo:method</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"sayHello"</span> <span class="hljs-attr">onreturn</span>=<span class="hljs-string">"demoCallback.onreturn"</span> <span class="hljs-attr">onthrow</span>=<span class="hljs-string">"demoCallback.onthrow"</span>/&gt;</span>
+<span class="hljs-tag">&lt;/<span class="hljs-name">dubbo:reference</span>&gt;</span>
+</code></pre>
+<p>其中,NotifyImpl 的代码如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NotifyImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Notify</span></span>{
+
+    <span class="hljs-keyword">public</span> Map&lt;Integer, String&gt; ret = <span class="hljs-keyword">new</span> HashMap&lt;Integer, String&gt;();
+    
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onreturn</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> id)</span> </span>{
+        ret.put(id, name);
+        System.out.println(<span class="hljs-string">"onreturn: "</span> + name);
+    }
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onthrow</span><span class="hljs-params">(Throwable ex, String name, <span class="hljs-keyword">int</span> id)</span> </span>{
+        System.out.println(<span class="hljs-string">"onthrow: "</span> + name);
+    }
+}
+</code></pre>
+<p>这里要强调一点,自定义 Notify 接口中的三个方法的参数规则如下:</p>
+<ul>
+<li><code>oninvoke</code> 方法参数与调用方法的参数相同;</li>
+<li><code>onreturn</code>方法第一个参数为调用方法的返回值,其余为调用方法的参数;</li>
+<li><code>onthrow</code>方法第一个参数为调用异常,其余为调用方法的参数。</li>
+</ul>
+<p>上述配置中,<code>sayHello</code>方法为同步调用,因此事件通知方法的执行也是同步执行。可以配置 <code>async=true</code>让方法调用为异步,这时事件通知的方法也是异步执行的。特别强调一下,<code>oninvoke</code>方法不管是否异步调用,都是同步执行的。</p>
+<p>事件通知的示例代码请参考:<a href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-notify">https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-notify</a></p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-invoke.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-invoke.json
new file mode 100644
index 0000000..4825f68
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-invoke.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-invoke.md",
+  "__html": "<h1>Dubbo 关于同步/异步调用的几种方式</h1>\n<p>我们知道,Dubbo 缺省协议采用单一长连接,底层实现是 Netty 的 NIO 异步通讯机制;基于这种机制,Dubbo 实现了以下几种调用方式:</p>\n<ul>\n<li>同步调用</li>\n<li>异步调用</li>\n<li>参数回调</li>\n<li>事件通知</li>\n</ul>\n<h2>同步调用</h2>\n<p>同步调用是一种阻塞式的调用方式,即 Consumer 端代码一直阻塞等待,直到 Provider 端返回为止;</p>\n<p>通常,一个典型的同步调用过程如下:</p>\n<ol>\n<li>Consumer 业务线程调用远程接口,向 Provider 发送请求,同时当前线程处于<code>阻塞</code>状态;</li>\n<li>Provider 接到 Consumer 的请求后,开始处理请求,将结果返回给 Consumer;</li>\n<li>Consumer 收到结果后,当前线程继续往后执行。</li>\n</ol>\n<p>这里 [...]
+  "link": "/zh-cn/blog/dubbo-invoke.html",
+  "meta": {
+    "title": "Dubbo 关于同步/异步调用的几种方式",
+    "keywords": "Dubbo, Invoke, Async",
+    "description": "本文介绍了Dubbo基于异步通讯机制实现的几种同步和异步调用方式。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-k8s.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-k8s.html
new file mode 100644
index 0000000..e12dd07
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-k8s.html
@@ -0,0 +1,120 @@
+<!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="Dubbo, Kubernetes, K8S" />
+	<meta name="description" content="本文主要尝试将Dubbo服务注册到Kubernetes,同时无缝融入Kubernetes的多租户安全体系。" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo与Kubernetes集成</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>大体目标</h2>
+<p>Dubbo的provider不再关心服务注册的事宜,只需要把其Dubbo服务端口打开,由Kubernetes来进行服务的声明和发布;Dubbo的consumer在服务发现时直接发现kubernetes的对应服务endpoints,从而复用Dubbo已有的微服务通道能力。好处是无需依赖三方的软负载注册中心;同时无缝融入Kubernetes的多租户安全体系。Demo的代码参照: <a href="https://github.com/dubbo/dubbo-kubernetes">https://github.com/dubbo/dubbo-kubernetes</a></p>
+<h2>闲谈</h2>
+<p>Kubernates是建立在扩展性的具备二次开发的功能层次丰富的体系化系统</p>
+<ul>
+<li>首先其最核心的功能是管理容器集群,能管理容器化的集群(包括存储,计算),当然这个是建立在对容器运行时(CRI),网络接口(CNI),存储服务接口(CSI/FV)的基础上;</li>
+<li>其次是面向应用(包括无状态/有状态,批处理/服务型应用)的部署和路由能力,特别是基于微服务架构的应用管理,具备了其服务定义和服务发现,以及基于configmap的统一配置能力;</li>
+<li>在基础资源(主要是抽象底层IaaS的资源)和应用层的抽象模型之上是治理层,包含弹性扩容,命名空间/租户,等。当然,基于其原子内核的基础能力,在Kubernetes的核心之上搭建统一的日志中心和全方位监控等服务是水到渠成的,CNCF更是有其认定推荐。</li>
+</ul>
+<p>来张Kubernetes Architecture的一张图解释下上述描述。在2018年Kubernetes往事实的paas底座的标配迈出质的一步,有人说原因在于基于扩展的二次开发能力,有人说在于其声明式编程和背靠Google和Redhat的强大社区运作,我觉得回归本质是在于下图中的<strong>Layered架构和其问题域的领域建模抽象</strong>。</p>
+<p><img src="../../img/blog/k8s/1.png" alt="img"></p>
+<p>以微服务架构视角,Kubernetes在一定意义上是微服务框架(这时较叫微服务平台或toolkit集更合适),支持微服务的服务发现/注册的基本能力。借用如下图做一个简单描述。</p>
+<p><img src="../../img/blog/k8s/2.jpeg" alt="img"></p>
+<p>话题再展开一下,微服务领域涉及众多问题,大概可以用下图说明。</p>
+<p><img src="../../img/blog/k8s/3.jpeg" alt="img"></p>
+<p>Kubernetes解决得只是少部分,而像动态路由,稳定性控制(断路器,隔水舱等),分布式服务追踪等是个空白,这也就是servicemesh要解决的,是在CNCF的Trail Map占有重要一席;当然Dubbo是基本具备完备的微服务,也就是使得其集成到k8s体系下具有相当的意义。Dubbo在serviemesh中基于sidecar的方案是解决跨语言诉求的通用servicemesh方案,需要新开一个话题来展开说;而引用serviemsh的原始定义:</p>
+<blockquote>
+<p>A service mesh is a dedicated infrastructure layer for handling service-to-service communication. It’s responsible for the reliable delivery of requests through the complex topology of services that comprise a modern, cloud native application.</p>
+</blockquote>
+<blockquote>
+<p>首先服务网格是一个云原生环境下基础设施层,功能在于处理服务间通信,职责是负责实现请求的可靠传递,被使得被监控跟踪,被治理,最终使得微服务架构被赋予高可控的稳定性和快速的问题定位排查能力。</p>
+</blockquote>
+<p>可以得出现有Dubbo集成云原生基础设施Kubernetes的基础能力而并解决微服务相关核心问题也算是一种狭义上的servicemesh方案,只是是Java领域的罢了;当玩笑理解也行,哈哈。</p>
+<h2>思路/方案</h2>
+<p>Kubernetes是天然可作为微服务的地址注册中心,类似于Zookeeper, 阿里巴巴内部用到的VIPserver,Configserver。 具体来说,Kubernetes中的Pod是对于应用的运行实例,Pod的被调度部署/启停都会调用API-Server的服务来保持其状态到ETCD;Kubernetes中的service是对应微服务的概念,定义如下</p>
+<blockquote>
+<p>A Kubernetes Service is an abstraction layer which defines a logical set of Pods and enables external traffic exposure, load balancing and service discovery for those Pods.</p>
+</blockquote>
+<p>概括来说Kubernetes service具有如下特点</p>
+<ul>
+<li>每个Service都有一个唯一的名字,及对应IP。IP是kubernetes自动分配的,名字是开发者自己定义的。</li>
+<li>Service的IP有几种表现形式,分别是ClusterIP,NodePort,LoadBalance,Ingress。 ClusterIP主要用于集群内通信;NodePort,Ingress,LoadBalance用于暴露服务给集群外的访问入口。</li>
+</ul>
+<p>乍一看,Kubernetes的service都是唯一的IP,在原有的Dubbo/HSF固定思维下:Dubbo/HSF的service是由整个服务集群的IP聚合而成,貌似是有本质区别的,细想下来差别不大,因为Kubernetes下的唯一IP只是一个VIP,背后挂在了多个endpoint,那才是事实上的处理节点。此处只讨论集群内的Dubbo服务在同一个kubernetes集群内访问;至于kubernetes外的consumer访问kubernetes内的provider,涉及到网络地址空间的问题,一般需要GateWay/loadbalance来做映射转换,不展开讨论。针对Kubernetes内有两种方案可选: :</p>
+<ol>
+<li>DNS: 默认Kubernetes的service是靠DNS插件(最新版推荐是coreDNS), Dubbo上有个proposal是关于这个的。我的理解是static resolution的机制是最简单最需要支持的一种service discovery机制,具体也可以参考Envoy在此的观点,由于HSF/Dubbo一直突出其软负载的地址发现能力,反而忽略Static的策略。同时蚂蚁的SOFA一直是支持此种策略,那一个SOFA工程的工程片段做一个解释。这样做有两个好处,1)当软负载中心crash不可用造成无法获取地址列表时,有一定的机制Failover到此策略来处理一定的请求。 2)在LDC/单元化下,蚂蚁的负载中心集群是机房/区域内收敛部署的,首先保证软负载中心的LDC化了进而稳定可控,当单元需要请求中心时,此VIP的地址发现就排上用场了。</li>
+</ol>
+<p><img src="https://img.alicdn.com/tfs/TB1Kj1ktpkoBKNjSZFEXXbrEVXa-985-213.png" alt="img"></p>
+<ol start="2">
+<li>API:DNS是依靠DNS插件进行的,相当于额外的运维开销,所以考虑直接通过kubernetes的client来获取endpoint。事实上,通过访问Kubernetes的API server接口是可以直接获取某个servie背后的endpoint列表,同时可以监听其地址列表的变化。从而实现Dubbo/HSF所推荐的软负载发现策略。具体可以参考代码:</li>
+</ol>
+<p>以上两种思路都需要考虑以下两点:</p>
+<ol>
+<li>Kubernetes和Dubbo对于service的名字是映射一致的。Dubbo的服务是由serviename,group,version三个来确定其唯一性,而且servicename一般其服务接口的包名称,比较长。需要映射Kubernetes的servie名与dubbo的服务名。要么是像SOFA那样增加一个属性来进行定义,这是个大的改动,但最合理;要么是通过固定规则来引用部署的环境变量,可用于快速验证。</li>
+<li>端口问题:默认Pod与Pod的网络互通算是解决了,需要验证。</li>
+</ol>
+<h2>Demo验证</h2>
+<p>下面通过阿里云的容器镜像服务和EDAS中的Kubernetes服务来做一次Demo部署。访问阿里云 -&gt; 容器镜像服务。</p>
+<ol>
+<li>创建镜像仓库并绑定github代码库。如下图</li>
+</ol>
+<p><img src="https://img.alicdn.com/tfs/TB1m.tEtrorBKNjSZFjXXc_SpXa-1892-870.png" alt="img"></p>
+<ol start="2">
+<li>点击管理 <strong>进行创建好的仓库</strong>,通过镜像服务下的构建功能,把demo构建成image,并发布到指定仓库。如下图。</li>
+</ol>
+<p><img src="https://img.alicdn.com/tfs/TB1oYqvtcIrBKNjSZK9XXagoVXa-1872-888.png" alt="img"></p>
+<ol start="3">
+<li>切换到企业级分布式应用服务(EDAS)产品,在资源管理 -&gt; 集群 下创建Kubernetes集群并绑定ECS,如下图.</li>
+</ol>
+<p><img src="https://img.alicdn.com/tfs/TB1b1p2trZnBKNjSZFKXXcGOVXa-1858-833.png" alt="img"></p>
+<ol start="4">
+<li>应用管理 -》创建应用,<strong>类型为kubernetes应用</strong> 并且指定在容器镜像服务中的镜像。如下图。</li>
+</ol>
+<p><img src="https://img.alicdn.com/tfs/TB1b1p2trZnBKNjSZFKXXcGOVXa-1858-833.png" alt="img"></p>
+<p><img src="https://img.alicdn.com/tfs/TB18uzTtdcnBKNjSZR0XXcFqFXa-1820-861.png" alt=""></p>
+<ol start="5">
+<li>创建完成后,进行应用部署。如下图</li>
+</ol>
+<p><img src="https://img.alicdn.com/tfs/TB1fEpEtrorBKNjSZFjXXc_SpXa-1846-783.png" alt=""></p>
+<ul>
+<li>
+<p>补充应用名不能有大写字母,全部小写,否则有部署失败的问题。</p>
+</li>
+<li>
+<p>在创建应用时,选中镜像后,下一步的按钮无法点击,需要点击选择来继续。</p>
+</li>
+<li>
+<p>EDAS有两套独立的Kubernetes服务,一套是基于阿里云的容器服务,一套是Lark自己搞的。本人体验的是后者。</p>
+</li>
+<li>
+<p>Docker与IDE集成的开发联调,需要考虑集成IDEA的相关插件。</p>
+</li>
+<li>
+<p>部署时总是出错,感觉Kubernetes服务上哪里有问题。需要进一步排查。</p>
+<p>{&quot;kind&quot;:&quot;Pod&quot;,&quot;namespace&quot;:&quot;lzumwsrddf831iwarhehd14zh2-default&quot;,&quot;name&quot;:&quot;dubbo-k8s-demo-610694273-jq238&quot;,&quot;uid&quot;:&quot;12892e67-8bc8-11e8-b96a-00163e02c37b&quot;,&quot;apiVersion&quot;:&quot;v1&quot;,&quot;resourceVersion&quot;:&quot;850282769&quot;},&quot;reason&quot;:&quot;FailedSync&quot;,&quot;message&quot;:&quot;Error syncing pod&quot;,&quot;</p>
+</li>
+</ul>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-k8s.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-k8s.json
new file mode 100644
index 0000000..cf343f9
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-k8s.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-k8s.md",
+  "__html": "<h1>Dubbo与Kubernetes集成</h1>\n<h2>大体目标</h2>\n<p>Dubbo的provider不再关心服务注册的事宜,只需要把其Dubbo服务端口打开,由Kubernetes来进行服务的声明和发布;Dubbo的consumer在服务发现时直接发现kubernetes的对应服务endpoints,从而复用Dubbo已有的微服务通道能力。好处是无需依赖三方的软负载注册中心;同时无缝融入Kubernetes的多租户安全体系。Demo的代码参照: <a href=\"https://github.com/dubbo/dubbo-kubernetes\">https://github.com/dubbo/dubbo-kubernetes</a></p>\n<h2>闲谈</h2>\n<p>Kubernates是建立在扩展性的具备二次开发的功能层次丰富的体系化系统</p>\n<ul>\n<li>首先其最核心的功能是管理容器集群,能管理容器化的集群(包括存储,计算),当然这个是建立在对容器运行时(CRI),网络接口(CNI),存储服 [...]
+  "link": "/zh-cn/blog/dubbo-k8s.html",
+  "meta": {
+    "title": "Dubbo与Kubernetes集成",
+    "keywords": "Dubbo, Kubernetes, K8S",
+    "description": "本文主要尝试将Dubbo服务注册到Kubernetes,同时无缝融入Kubernetes的多租户安全体系。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-loadbalance.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-loadbalance.html
new file mode 100644
index 0000000..2ca5d4c
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-loadbalance.html
@@ -0,0 +1,251 @@
+<!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="Dubbo, LoadBalance" />
+	<meta name="description" content="本文介绍了负载均衡的相关概念以及 Dubbo 中的负载均衡策略实现。" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo的负载均衡</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>背景</h2>
+<p>Dubbo是一个分布式服务框架,能避免单点故障和支持服务的横向扩容。一个服务通常会部署多个实例。如何从多个服务 Provider 组成的集群中挑选出一个进行调用,就涉及到一个负载均衡的策略。</p>
+<h2>几个概念</h2>
+<p>在讨论负载均衡之前,我想先解释一下这3个概念。</p>
+<ol>
+<li>负载均衡</li>
+<li>集群容错</li>
+<li>服务路由</li>
+</ol>
+<p>这3个概念容易混淆。他们都描述了怎么从多个 Provider 中选择一个来进行调用。那他们到底有什么区别呢?下面我来举一个简单的例子,把这几个概念阐述清楚吧。</p>
+<p>有一个Dubbo的用户服务,在北京部署了10个,在上海部署了20个。一个杭州的服务消费方发起了一次调用,然后发生了以下的事情:</p>
+<ol>
+<li>根据配置的路由规则,如果杭州发起的调用,会路由到比较近的上海的20个 Provider。</li>
+<li>根据配置的随机负载均衡策略,在20个 Provider 中随机选择了一个来调用,假设随机到了第7个 Provider。</li>
+<li>结果调用第7个 Provider 失败了。</li>
+<li>根据配置的Failover集群容错模式,重试其他服务器。</li>
+<li>重试了第13个 Provider,调用成功。</li>
+</ol>
+<p>上面的第1,2,4步骤就分别对应了路由,负载均衡和集群容错。 Dubbo中,先通过路由,从多个 Provider 中按照路由规则,选出一个子集。再根据负载均衡从子集中选出一个 Provider 进行本次调用。如果调用失败了,根据集群容错策略,进行重试或定时重发或快速失败等。 可以看到Dubbo中的路由,负载均衡和集群容错发生在一次RPC调用的不同阶段。最先是路由,然后是负载均衡,最后是集群容错。 本文档只讨论负载均衡,路由和集群容错在其他的文档中进行说明。</p>
+<h2>Dubbo内置负载均衡策略</h2>
+<p>Dubbo内置了4种负载均衡策略:</p>
+<ol>
+<li>RandomLoadBalance:随机负载均衡。随机的选择一个。是Dubbo的<strong>默认</strong>负载均衡策略。</li>
+<li>RoundRobinLoadBalance:轮询负载均衡。轮询选择一个。</li>
+<li>LeastActiveLoadBalance:最少活跃调用数,相同活跃数的随机。活跃数指调用前后计数差。使慢的 Provider 收到更少请求,因为越慢的 Provider 的调用前后计数差会越大。</li>
+<li>ConsistentHashLoadBalance:一致性哈希负载均衡。相同参数的请求总是落在同一台机器上。</li>
+</ol>
+<h3>1.随机负载均衡</h3>
+<p>顾名思义,随机负载均衡策略就是从多个 Provider 中随机选择一个。但是 Dubbo 中的随机负载均衡有一个权重的概念,即按照权重设置随机概率。比如说,有10个 Provider,并不是说,每个 Provider 的概率都是一样的,而是要结合这10个 Provider 的权重来分配概率。</p>
+<p>Dubbo中,可以对 Provider 设置权重。比如机器性能好的,可以设置大一点的权重,性能差的,可以设置小一点的权重。权重会对负载均衡产生影响。可以在Dubbo Admin中对 Provider 进行权重的设置。</p>
+<p><strong>基于权重的负载均衡算法</strong></p>
+<p>随机策略会先判断所有的 Invoker 的权重是不是一样的,如果都是一样的,那么处理就比较简单了。使用random.nexInt(length)就可以随机生成一个 Invoker 的序号,根据序号选择对应的 Invoker 。如果没有在Dubbo Admin中对服务 Provider 设置权重,那么所有的 Invoker 的权重就是一样的,默认是100。 如果权重不一样,那就需要结合权重来设置随机概率了。算法大概如下: 假如有4个 Invoker。</p>
+<table>
+<thead>
+<tr>
+<th>invoker</th>
+<th>weight</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>A</td>
+<td>10</td>
+</tr>
+<tr>
+<td>B</td>
+<td>20</td>
+</tr>
+<tr>
+<td>C</td>
+<td>20</td>
+</tr>
+<tr>
+<td>D</td>
+<td>30</td>
+</tr>
+</tbody>
+</table>
+<p>A,B,C和D总的权重是10 + 20 + 20 + 30 = 80。将80个数分布在如下的图中:</p>
+<pre><code>+-----------------------------------------------------------------------------------+
+|          |                    |                    |                              |
++-----------------------------------------------------------------------------------+
+1          10                   30                   50                             80
+
+|-----A----|---------B----------|----------C---------|---------------D--------------|
+
+
+---------------------15
+
+-------------------------------------------37
+
+-----------------------------------------------------------54
+</code></pre>
+<p>上面的图中一共有4块区域,长度分别是A,B,C和D的权重。使用random.nextInt(10 + 20 + 20 + 30),从80个数中随机选择一个。然后再判断该数分布在哪个区域。比如,如果随机到37,37是分布在C区域的,那么就选择 Invoker C。15是在B区域,54是在D区域。</p>
+<p><strong>随机负载均衡源码</strong></p>
+<p>下面是随机负载均衡的源码,为了方便阅读和理解,我把无关部分都去掉了。</p>
+<pre><code>public class RandomLoadBalance extends AbstractLoadBalance {
+
+    private final Random random = new Random();
+
+    protected &lt;T&gt; Invoker&lt;T&gt; doSelect(List&lt;Invoker&lt;T&gt;&gt; invokers, URL url, Invocation invocation) {
+        int length = invokers.size();      // Invoker 总数
+        int totalWeight = 0;               // 所有 Invoker 的权重的和
+
+        // 判断是不是所有的 Invoker 的权重都是一样的
+        // 如果权重都一样,就简单了。直接用Random生成索引就可以了。
+        boolean sameWeight = true;
+        for (int i = 0; i &lt; length; i++) {
+            int weight = getWeight(invokers.get(i), invocation);
+            totalWeight += weight; // Sum
+            if (sameWeight &amp;&amp; i &gt; 0 &amp;&amp; weight != getWeight(invokers.get(i - 1), invocation)) {
+                sameWeight = false;
+            }
+        }
+
+        if (totalWeight &gt; 0 &amp;&amp; !sameWeight) {
+            // 如果不是所有的 Invoker 权重都相同,那么基于权重来随机选择。权重越大的,被选中的概率越大
+            int offset = random.nextInt(totalWeight);
+            for (int i = 0; i &lt; length; i++) {
+                offset -= getWeight(invokers.get(i), invocation);
+                if (offset &lt; 0) {
+                    return invokers.get(i);
+                }
+            }
+        }
+        // 如果所有 Invoker 权重相同
+        return invokers.get(random.nextInt(length));
+    }
+}
+</code></pre>
+<h3>2.轮询负载均衡</h3>
+<p>轮询负载均衡,就是依次的调用所有的 Provider。和随机负载均衡策略一样,轮询负载均衡策略也有权重的概念。 轮询负载均衡算法可以让RPC调用严格按照我们设置的比例来分配。不管是少量的调用还是大量的调用。但是轮询负载均衡算法也有不足的地方,存在慢的 Provider 累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上,导致整个系统变慢。</p>
+<h3>3.最少活跃调用数负载均衡</h3>
+<p>官方解释:</p>
+<blockquote>
+<p>最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差,使慢的机器收到更少。</p>
+</blockquote>
+<p>这个解释好像说的不是太明白。目的是让更慢的机器收到更少的请求,但具体怎么实现的还是不太清楚。举个例子:每个服务维护一个活跃数计数器。当A机器开始处理请求,该计数器加1,此时A还未处理完成。若处理完毕则计数器减1。而B机器接受到请求后很快处理完毕。那么A,B的活跃数分别是1,0。当又产生了一个新的请求,则选择B机器去执行(B活跃数最小),这样使慢的机器A收到少的请求。</p>
+<p>处理一个新的请求时,Consumer 会检查所有 Provider 的活跃数,如果具有最小活跃数的 Invoker 只有一个,直接返回该 Invoker:</p>
+<pre><code>if (leastCount == 1) {
+    // 如果只有一个最小则直接返回
+    return invokers.get(leastIndexs[0]);
+}
+</code></pre>
+<p>如果最小活跃数的 Invoker 有多个,且权重不相等同时总权重大于0,这时随机生成一个权重,范围在 (0,totalWeight) 间内。最后根据随机生成的权重,来选择 Invoker。</p>
+<pre><code>if (! sameWeight &amp;&amp; totalWeight &gt; 0) {
+    // 如果权重不相同且权重大于0则按总权重数随机
+    int offsetWeight = random.nextInt(totalWeight);
+    // 并确定随机值落在哪个片断上
+    for (int i = 0; i &lt; leastCount; i++) {
+        int leastIndex = leastIndexs[i];
+        offsetWeight -= getWeight(invokers.get(leastIndex), invocation);
+        if (offsetWeight &lt;= 0)
+            return invokers.get(leastIndex);
+    }
+}
+</code></pre>
+<h3>4.一致性Hash算法</h3>
+<p>使用一致性 Hash 算法,让相同参数的请求总是发到同一 Provider。 当某一台 Provider 崩溃时,原本发往该 Provider 的请求,基于虚拟节点,平摊到其它 Provider,不会引起剧烈变动。 算法参见:<a href="http://en.wikipedia.org/wiki/Consistent_hashing">http://en.wikipedia.org/wiki/Consistent_hashing</a>。</p>
+<p>缺省只对第一个参数Hash,如果要修改,请配置:</p>
+<pre><code>&lt;dubbo:parameter key=&quot;hash.arguments&quot; value=&quot;0,1&quot; /&gt;
+</code></pre>
+<p>缺省用160份虚拟节点,如果要修改,请配置:</p>
+<pre><code>&lt;dubbo:parameter key=&quot;hash.nodes&quot; value=&quot;320&quot; /&gt;
+</code></pre>
+<p>一致性Hash算法可以和缓存机制配合起来使用。比如有一个服务getUserInfo(String userId)。设置了Hash算法后,相同的userId的调用,都会发送到同一个 Provider。这个 Provider 上可以把用户数据在内存中进行缓存,减少访问数据库或分布式缓存的次数。如果业务上允许这部分数据有一段时间的不一致,可以考虑这种做法。减少对数据库,缓存等中间件的依赖和访问次数,同时减少了网络IO操作,提高系统性能。</p>
+<h2>负载均衡配置</h2>
+<p>如果不指定负载均衡,默认使用随机负载均衡。我们也可以根据自己的需要,显式指定一个负载均衡。 可以在多个地方类来配置负载均衡,比如 Provider 端,Consumer端,服务级别,方法级别等。</p>
+<h3>服务端服务级别</h3>
+<pre><code>&lt;dubbo:service interface=&quot;...&quot; loadbalance=&quot;roundrobin&quot; /&gt;
+</code></pre>
+<p>该服务的所有方法都使用roundrobin负载均衡。</p>
+<h3>客户端服务级别</h3>
+<pre><code>&lt;dubbo:reference interface=&quot;...&quot; loadbalance=&quot;roundrobin&quot; /&gt;
+</code></pre>
+<p>该服务的所有方法都使用roundrobin负载均衡。</p>
+<h3>服务端方法级别</h3>
+<pre><code>&lt;dubbo:service interface=&quot;...&quot;&gt;
+    &lt;dubbo:method name=&quot;hello&quot; loadbalance=&quot;roundrobin&quot;/&gt;
+&lt;/dubbo:service&gt;
+</code></pre>
+<p>只有该服务的hello方法使用roundrobin负载均衡。</p>
+<h3>客户端方法级别</h3>
+<pre><code>&lt;dubbo:reference interface=&quot;...&quot;&gt;
+    &lt;dubbo:method name=&quot;hello&quot; loadbalance=&quot;roundrobin&quot;/&gt;
+&lt;/dubbo:reference&gt;
+</code></pre>
+<p>只有该服务的hello方法使用roundrobin负载均衡。</p>
+<p>和Dubbo其他的配置类似,多个配置是有覆盖关系的:</p>
+<ol>
+<li>方法级优先,接口级次之,全局配置再次之。</li>
+<li>如果级别一样,则消费方优先,提供方次之。</li>
+</ol>
+<p>所以,上面4种配置的优先级是:</p>
+<ol>
+<li>客户端方法级别配置。</li>
+<li>客户端接口级别配置。</li>
+<li>服务端方法级别配置。</li>
+<li>服务端接口级别配置。</li>
+</ol>
+<h2>扩展负载均衡</h2>
+<p>Dubbo的4种负载均衡的实现,大多数情况下能满足要求。有时候,因为业务的需要,我们可能需要实现自己的负载均衡策略。本章只说明如何配置负载均衡算法。关于Dubbo扩展机制的更多内容,请前往<a href="https://lark.alipay.com/aliware_articles/vtpf9h/pe9pyr">Dubbo可扩展机制实战</a>。</p>
+<ol>
+<li>实现LoadBalance接口, 以下是Dubbo的LoadBalance接口:</li>
+</ol>
+<pre><code>@SPI(RandomLoadBalance.NAME)
+public interface LoadBalance {
+    @Adaptive(&quot;loadbalance&quot;)
+    &lt;T&gt; Invoker&lt;T&gt; select(List&lt;Invoker&lt;T&gt;&gt; invokers, URL url, Invocation invocation) throws RpcException;
+}
+</code></pre>
+<p>这是SPI的接口,select方法的参数如下:</p>
+<ul>
+<li>invokers: 所有的服务 Provider 列表。</li>
+<li>url: 一些配置信息,比如接口名,是否check,序列化方式。</li>
+<li>invocation: RPC调用的信息,包括方法名,方法参数类型,方法参数。 下面是我们自己实现的一个LoadBalance,实现很简单,选择第一个 Invoker:</li>
+</ul>
+<pre><code>package com.demo.dubbo;
+public class DemoLoadBalance implements LoadBalance {
+    @Override
+    public &lt;T&gt; Invoker&lt;T&gt; select(List&lt;Invoker&lt;T&gt;&gt; invokers, URL url, Invocation invocation) throws RpcException {
+        System.out.println(&quot;[DemoLoadBalance]Select the first invoker...&quot;);
+        return invokers.get(0);
+    }
+}
+</code></pre>
+<ol start="2">
+<li>添加资源文件 添加文件:<code>src/main/resource/META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.LoadBalance</code>。这是一个简单的文本文件。文件内容如下:</li>
+</ol>
+<pre><code>demo=my=com.demo.dubbo.DemoLoadBalance
+</code></pre>
+<ol start="3">
+<li>配置使用自定义LoadBalance</li>
+</ol>
+<pre><code>&lt;dubbo:reference id=&quot;helloService&quot; interface=&quot;com.demo.dubbo.api.IHelloService&quot; loadbalance=&quot;demo&quot; /&gt;
+</code></pre>
+<p>在Consumer端的<code>dubbo:reference</code>中配置<code>&lt;loadbalance=&quot;demo&quot;&gt;</code></p>
+<p>经过上面的3个步骤,我们编写了一个自定义的LoadBalance,并告诉Dubbo使用它了。启动Dubbo,我们就能看到Dubbo已经使用了自定义的DemoLoadBalance。</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-loadbalance.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-loadbalance.json
new file mode 100644
index 0000000..9f188b1
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-loadbalance.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-loadbalance.md",
+  "__html": "<h1>Dubbo的负载均衡</h1>\n<h2>背景</h2>\n<p>Dubbo是一个分布式服务框架,能避免单点故障和支持服务的横向扩容。一个服务通常会部署多个实例。如何从多个服务 Provider 组成的集群中挑选出一个进行调用,就涉及到一个负载均衡的策略。</p>\n<h2>几个概念</h2>\n<p>在讨论负载均衡之前,我想先解释一下这3个概念。</p>\n<ol>\n<li>负载均衡</li>\n<li>集群容错</li>\n<li>服务路由</li>\n</ol>\n<p>这3个概念容易混淆。他们都描述了怎么从多个 Provider 中选择一个来进行调用。那他们到底有什么区别呢?下面我来举一个简单的例子,把这几个概念阐述清楚吧。</p>\n<p>有一个Dubbo的用户服务,在北京部署了10个,在上海部署了20个。一个杭州的服务消费方发起了一次调用,然后发生了以下的事情:</p>\n<ol>\n<li>根据配置的路由规则,如果杭州发起的调用,会路由到比较近
 的上海的20个 Provider。</li>\n<li>根据配置的随机负载均衡 [...]
+  "link": "/zh-cn/blog/dubbo-loadbalance.html",
+  "meta": {
+    "title": "Dubbo的负载均衡",
+    "keywords": "Dubbo, LoadBalance",
+    "description": "本文介绍了负载均衡的相关概念以及 Dubbo 中的负载均衡策略实现。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-local-call.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-local-call.html
new file mode 100644
index 0000000..3c24ff3
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-local-call.html
@@ -0,0 +1,85 @@
+<!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="dubbo-local-call" />
+	<meta name="description" content="dubbo-local-call" />
+	<!-- 网页标签标题 -->
+	<title>dubbo-local-call</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h3>本地调用介绍</h3>
+<p>当一个应用既是一个服务的提供者,同时也是这个服务的消费者的时候,可以直接对本机提供的服务发起本地调用。从 <code>2.2.0</code> 版本开始,Dubbo 默认在本地以 <em>injvm</em> 的方式暴露服务,这样的话,在同一个进程里对这个服务的调用会优先走本地调用。</p>
+<p>与本地对象上方法调用不同的是,Dubbo 本地调用会经过 Filter 链,其中包括了 Consumer 端的 Filter 链以及 Provider 端的 Filter 链。通过这样的机制,本地消费者和其他消费者都是统一对待,统一监控,服务统一进行治理。</p>
+<p><img src="../../img/blog/dubbo-local-call-filter.png" alt="filter-chain"></p>
+<p>同时,相比于远程调用来说,Dubbo 本地调用性能较优,省去了请求、响应的编解码及网络传输的过程。</p>
+<p>要使用 Dubbo 本地调用不需做特殊配置,按正常 Dubbo 服务暴露服务即可。任一服务在暴露远程服务的同时,也会同时以 <em>injvm</em> 的协议暴露本地服务。<em>injvm</em> 是一个伪协议,不会像其他协议那样对外开启端口,只用于本地调用的目的。</p>
+<p>以下面的 XML 配置为例:</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"dubbo"</span> <span class="hljs-attr">port</span>=<span class="hljs-string">"20800"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoServiceTarget"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.apache.dubbo.samples.local.impl.DemoServiceImpl"</span>/&gt;</span>
+
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.samples.local.api.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoServiceTarget"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.samples.local.api.DemoService"</span>/&gt;</span>
+</code></pre>
+<p>这里同时配置了同一服务 <em>DemoService</em> 的提供者以及消费者。在这种情况下,该应用中的 <em>DemoService</em> 的消费方会优先使用 <em>injvm</em> 协议进行本地调用。上述的例子可以在 dubbo-samples 工程中找到源码:<a href="https://github.com/apache/dubbo-samples/blob/master/dubbo-samples-local">https://github.com/apache/dubbo-samples/blob/master/dubbo-samples-local</a></p>
+<h3>细粒度控制本地调用</h3>
+<p>本地调用是可以显示关闭的,通过这种方式,服务提供者可以做到对远端服务消费者和本地消费者一视同仁。具体做法是通过 <em>scope=&quot;remote&quot;</em> 来关闭 <em>injvm</em> 协议的暴露,这样,即使是本地调用者,也需要从注册中心上获取服务地址列表,然后才能发起调用,而这个时候的调用过程,与远端的服务消费者的过程是一致的。</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"target"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.apache.dubbo.samples.local.impl.DemoServiceImpl"</span>/&gt;</span>
+<span class="hljs-comment">&lt;!-- 服务提供者指定 scope="remote" --&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.samples.local.api.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"target"</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"remote"</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.samples.local.api.DemoService"</span>/&gt;</span>
+</code></pre>
+<p>同样的,服务消费者也支持通过 <em>scope</em> 来限定发起调用优先走本地,还是只走远程。比如,可以通过以下的方式强制消费端通过<strong>远程调用</strong>的方式来发起 dubbo 调用:</p>
+<pre><code class="language-xml"><span class="hljs-comment">&lt;!-- 服务消费者指定 scope="remote" --&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.samples.local.api.DemoService"</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"remote"</span>/&gt;</span>
+</code></pre>
+<p>如果同时服务提供方限定了 <em>scope=&quot;local&quot;</em> 的话,</p>
+<pre><code class="language-xml"><span class="hljs-comment">&lt;!-- 服务提供者指定 scope="remote" --&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.samples.local.api.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"target"</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"remote"</span>/&gt;</span>
+<span class="hljs-comment">&lt;!-- 服务消费者指定 scope="local" --&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.samples.local.api.DemoService"</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"local"</span>/&gt;</span>
+</code></pre>
+<p>那么该程序中的 dubbo 调用将会失败,原因是服务提供方只暴露了远程服务到注册中心上,并没有暴露 <em>injvm</em> 协议的服务,而出于同一个进程中的服务消费者查找不到 <em>injvm</em> 协议的服务,也不会去远程的注册中心上订阅服务地址。同样的,当服务提供者限定 <em>scope=&quot;local&quot;</em> 而服务消费者限定 <em>scope=&quot;remote&quot;</em> 也会因为相同的原因导致调用失败。出错信息如下:</p>
+<pre><code class="language-sh">[20/03/19 05:03:18:018 CST] main  INFO config.AbstractConfig:  [DUBBO] Using injvm service org.apache.dubbo.samples.local.api.DemoService, dubbo version: 2.7.1, current host: 169.254.146.168
+Exception <span class="hljs-keyword">in</span> thread <span class="hljs-string">"main"</span> org.springframework.beans.factory.BeanCreationException: Error creating bean with name <span class="hljs-string">'demoService'</span>: FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Failed to check the status of the service org.apache.dubbo.samples.local.api.DemoService. No provider available <span class="hljs-keyword">for</span> the service  [...]
+</code></pre>
+<h3>何时无法使用本地调用</h3>
+<p>默认情况下,本地调用是自动开启的,不需要做额外的配置。只有当需要关闭的时候,才需要通过 <em>scope</em> 的配置来显式的关闭。</p>
+<p>但是,特别需要指出的是,在下面的几种情况下,本地调用是无法使用的:</p>
+<p>第一,泛化调用的时候无法使用本地调用。</p>
+<p>第二,消费者明确指定 URL 发起直连调用。当然,如果消费者指定的是 <em>injvm</em> 的 URL,最终的调用也是走本地调用的,比如:</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.samples.local.api.DemoService"</span> <span class="hljs-attr">url</span>=<span class="hljs-string">"injvm://127.0.0.1/org.apache.dubbo.samples.local.api.DemoService"</span>/&gt;</span>
+</code></pre>
+<h3>强制打开本地调用</h3>
+<p>除了通过 <em>scope</em> 来控制本地调用的行为之外,也可以通过 <em>injvm</em> 这个配置来强制打开或者禁用本地调用。</p>
+<pre><code class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dubbo:consumer</span> <span class="hljs-attr">injvm</span>=<span class="hljs-string">"false"</span> <span class="hljs-attr">...</span>/&gt;</span>
+<span class="hljs-tag">&lt;<span class="hljs-name">dubbo:provider</span> <span class="hljs-attr">injvm</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">...</span>/&gt;</span>
+</code></pre>
+<p>但是通过 <em>injvm</em> 来配置本地调用的方式已经被废弃。通过 <em>scope</em> 的方式来控制是官方推荐的。</p>
+<h3>总结</h3>
+<p>本文介绍了本地调用的概念以及带来的好处,并进一步的揭示了 dubbo 本地调用实际上是在当前进程中暴露了 <em>injvm</em> 的协议,而该协议并不会对外暴露端口,然后讨论了如何通过 <em>scope</em> 来细粒度的控制本地调用的行为,并强调了通过 <em>invjm</em> 来配置的方式已经被废弃,在未来版本中可能会被删除。</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-local-call.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-local-call.json
new file mode 100644
index 0000000..dc1bb3a
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-local-call.json
@@ -0,0 +1,6 @@
+{
+  "filename": "dubbo-local-call.md",
+  "__html": "<h1>本地调用</h1>\n<h3>本地调用介绍</h3>\n<p>当一个应用既是一个服务的提供者,同时也是这个服务的消费者的时候,可以直接对本机提供的服务发起本地调用。从 <code>2.2.0</code> 版本开始,Dubbo 默认在本地以 <em>injvm</em> 的方式暴露服务,这样的话,在同一个进程里对这个服务的调用会优先走本地调用。</p>\n<p>与本地对象上方法调用不同的是,Dubbo 本地调用会经过 Filter 链,其中包括了 Consumer 端的 Filter 链以及 Provider 端的 Filter 链。通过这样的机制,本地消费者和其他消费者都是统一对待,统一监控,服务统一进行治理。</p>\n<p><img src=\"../../img/blog/dubbo-local-call-filter.png\" alt=\"filter-chain\"></p>\n<p>同时,相比于远程调用来说,Dubbo 本地调用性能较优,省去了请求、响应的编解码及网络传输的过程。</p>\n<p>要使用 Dubbo 本地 [...]
+  "link": "/zh-cn/blog/dubbo-local-call.html",
+  "meta": {}
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-meet-arthas.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meet-arthas.html
new file mode 100644
index 0000000..3082382
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meet-arthas.html
@@ -0,0 +1,325 @@
+<!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="Dubbo, Arthas" />
+	<meta name="description" content="使用Alibaba开源的应用诊断利器Arthas来排查Dubbo应用的问题。" />
+	<!-- 网页标签标题 -->
+	<title>当Dubbo遇上Arthas:排查问题的实践</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>Apache Dubbo是Alibaba开源的高性能RPC框架,在国内有非常多的用户。</p>
+<ul>
+<li>Github: <a href="https://github.com/apache/dubbo">https://github.com/apache/dubbo</a></li>
+<li>文档:<a href="http://dubbo.apache.org/zh-cn/">http://dubbo.apache.org/zh-cn/</a></li>
+</ul>
+<p>Arthas是Alibaba开源的应用诊断利器,9月份开源以来,Github Star数三个月超过6000。</p>
+<ul>
+<li>Github: <a href="https://github.com/alibaba/arthas">https://github.com/alibaba/arthas</a></li>
+<li>文档:<a href="https://alibaba.github.io/arthas/">https://alibaba.github.io/arthas/</a></li>
+<li>Arthas开源交流QQ群: 916328269</li>
+<li>Arthas开源交流钉钉群: 21965291</li>
+</ul>
+<p>当Dubbo遇上Arthas,会碰撞出什么样的火花呢?下面来分享Arthas排查Dubbo问题的一些经验。</p>
+<h3>dubbo-arthas-demo</h3>
+<p>下面的排查分享基于这个<code>dubbo-arthas-demo</code>,非常简单的一个应用,浏览器请求从Spring MVC到Dubbo Client,再发送到Dubbo Server。</p>
+<p>Demo里有两个spring boot应用,可以先启动<code>server-demo</code>,再启动<code>client-demo</code>。</p>
+<ul>
+<li><a href="https://github.com/hengyunabc/dubbo-arthas-demo">https://github.com/hengyunabc/dubbo-arthas-demo</a></li>
+</ul>
+<pre><code>  /user/{id}    -&gt;   UserService    -&gt;   UserServiceImpl 
+   Browser           Dubbo Client          Dubbo Server
+</code></pre>
+<p>Client端:</p>
+<pre><code class="language-java"><span class="hljs-meta">@RestController</span>
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserController</span> </span>{
+
+	<span class="hljs-meta">@Reference</span>(version = <span class="hljs-string">"1.0.0"</span>)
+	<span class="hljs-keyword">private</span> UserService userService;
+
+	<span class="hljs-meta">@GetMapping</span>(<span class="hljs-string">"/user/{id}"</span>)
+	<span class="hljs-function"><span class="hljs-keyword">public</span> User <span class="hljs-title">findUserById</span><span class="hljs-params">(@PathVariable Integer id)</span> </span>{
+		<span class="hljs-keyword">return</span> userService.findUser(id);
+	}
+</code></pre>
+<p>Server端:</p>
+<pre><code class="language-java"><span class="hljs-meta">@Service</span>(version = <span class="hljs-string">"1.0.0"</span>)
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">UserService</span> </span>{
+	<span class="hljs-meta">@Override</span>
+	<span class="hljs-function"><span class="hljs-keyword">public</span> User <span class="hljs-title">findUser</span><span class="hljs-params">(<span class="hljs-keyword">int</span> id)</span> </span>{
+		<span class="hljs-keyword">if</span> (id &lt; <span class="hljs-number">1</span>) {
+			<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"user id &lt; 1, id: "</span> + id);
+		}
+		<span class="hljs-keyword">for</span> (User user : users) {
+			<span class="hljs-keyword">if</span> (user.getId() == id) {
+				<span class="hljs-keyword">return</span> user;
+			}
+		}
+		<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RuntimeException(<span class="hljs-string">"Can not find user, id: "</span> + id);
+	}
+</code></pre>
+<h3>Arthas快速开始</h3>
+<ul>
+<li><a href="https://alibaba.github.io/arthas/install-detail.html">https://alibaba.github.io/arthas/install-detail.html</a></li>
+</ul>
+<pre><code class="language-bash">$ wget https://alibaba.github.io/arthas/arthas-boot.jar
+$ java -jar arthas-boot.jar
+</code></pre>
+<p>启动后,会列出所有的java进程,选择1,然后回车,就会连接上<code>ServerDemoApplication</code></p>
+<pre><code class="language-bash">$ java -jar arthas-boot.jar
+* [1]: 43523 ServerDemoApplication
+  [2]: 22342
+  [3]: 44108 ClientDemoApplication
+1
+[INFO] arthas home: /Users/hengyunabc/.arthas/lib/3.0.5/arthas
+[INFO] Try to attach process 43523
+[INFO] Attach process 43523 success.
+[INFO] arthas-client connect 127.0.0.1 3658
+  ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.
+ /  O  \ |  .--. <span class="hljs-string">''</span>--.  .--<span class="hljs-string">'|  '</span>--<span class="hljs-string">'  | /  O  \ '</span>   .-<span class="hljs-string">'
+|  .-.  ||  '</span>--<span class="hljs-string">'.'</span>   |  |   |  .--.  ||  .-.  |`.  `-.
+|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-<span class="hljs-string">'    |
+`--'</span> `--<span class="hljs-string">'`--'</span> <span class="hljs-string">'--'</span>   `--<span class="hljs-string">'   `--'</span>  `--<span class="hljs-string">'`--'</span> `--<span class="hljs-string">'`-----'</span>
+
+wiki: https://alibaba.github.io/arthas
+version: 3.0.5
+pid: 43523
+time: 2018-12-05 16:23:52
+
+$
+</code></pre>
+<h3>Dubbo线上服务抛出异常,怎么获取调用参数?</h3>
+<ul>
+<li><a href="https://alibaba.github.io/arthas/watch.html">https://alibaba.github.io/arthas/watch.html</a></li>
+</ul>
+<p>当线上服务抛出异常时,最着急的是什么参数导致了抛异常?</p>
+<p>在demo里,访问 <a href="http://localhost:8080/user/0">http://localhost:8080/user/0</a> ,<code>UserServiceImpl</code>就会抛出一个异常,因为user id不合法。</p>
+<p>在Arthas里执行 <code>watch com.example.UserService * -e -x 2 '{params,throwExp}'</code> ,然后再次访问,就可以看到watch命令把参数和异常都打印出来了。</p>
+<pre><code>$ watch com.example.UserService * -e -x 2 '{params,throwExp}'
+Press Ctrl+C to abort.
+Affect(class-cnt:1 , method-cnt:4) cost in 230 ms.
+ts=2018-12-05 16:26:44; [cost=3.905523ms] result=@ArrayList[
+    @Object[][
+        @Integer[0],
+    ],
+    java.lang.IllegalArgumentException: user id &lt; 1, id: 0
+	at com.example.UserServiceImpl.findUser(UserServiceImpl.java:24)
+	at com.alibaba.dubbo.common.bytecode.Wrapper1.invokeMethod(Wrapper1.java)
+	at com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:45)
+	at com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:71)
+	at com.alibaba.dubbo.config.invoker.DelegateProviderMetaDataInvoker.invoke(DelegateProviderMetaDataInvoker.java:48)
+	at com.alibaba.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:52)
+	at com.alibaba.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:61)
+</code></pre>
+<h3>怎样线上调试Dubbo服务代码?</h3>
+<ul>
+<li><a href="https://alibaba.github.io/arthas/redefine.html">https://alibaba.github.io/arthas/redefine.html</a></li>
+</ul>
+<p>在本地开发时,可能会用到热部署工具,直接改代码,不需要重启应用。但是在线上环境,有没有办法直接动态调试代码?比如增加日志。</p>
+<p>在Arthas里,可以通过<code>redefine</code>命令来达到线上不重启,动态更新代码的效果。</p>
+<p>比如我们修改下<code>UserServiceImpl</code>,用<code>System.out</code>打印出具体的<code>User</code>对象来:</p>
+<pre><code class="language-java">	<span class="hljs-function"><span class="hljs-keyword">public</span> User <span class="hljs-title">findUser</span><span class="hljs-params">(<span class="hljs-keyword">int</span> id)</span> </span>{
+		<span class="hljs-keyword">if</span> (id &lt; <span class="hljs-number">1</span>) {
+			<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"user id &lt; 1, id: "</span> + id);
+		}
+		<span class="hljs-keyword">for</span> (User user : users) {
+			<span class="hljs-keyword">if</span> (user.getId() == id) {
+				System.out.println(user);
+				<span class="hljs-keyword">return</span> user;
+			}
+		}
+		<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RuntimeException(<span class="hljs-string">"Can not find user, id: "</span> + id);
+	}
+</code></pre>
+<p>本地编绎后,把<code>server-demo/target/classes/com/example/UserServiceImpl.class</code>传到线上服务器,然后用<code>redefine</code>命令来更新代码:</p>
+<pre><code>$ redefine -p /tmp/UserServiceImpl.class
+redefine success, size: 1
+</code></pre>
+<p>这样子更新成功之后,访问 <a href="http://localhost:8080/user/1">http://localhost:8080/user/1</a> ,在<code>ServerDemoApplication</code>的控制台里就可以看到打印出了user信息。</p>
+<h3>怎样动态修改Dubbo的logger级别?</h3>
+<ul>
+<li><a href="https://alibaba.github.io/arthas/ognl.html">https://alibaba.github.io/arthas/ognl.html</a></li>
+<li><a href="https://alibaba.github.io/arthas/sc.html">https://alibaba.github.io/arthas/sc.html</a></li>
+<li><a href="https://commons.apache.org/proper/commons-ognl/language-guide.html">https://commons.apache.org/proper/commons-ognl/language-guide.html</a></li>
+</ul>
+<p>在排查问题时,需要查看到更多的信息,如果可以把logger级别修改为<code>DEBUG</code>,就非常有帮助。</p>
+<p><code>ognl</code>是apache开源的一个轻量级表达式引擎。下面通过Arthas里的<code>ognl</code>命令来动态修改logger级别。</p>
+<p>首先获取Dubbo里<code>TraceFilter</code>的一个logger对象,看下它的实现类,可以发现是log4j。</p>
+<pre><code class="language-bash">$ ognl <span class="hljs-string">'@com.alibaba.dubbo.rpc.protocol.dubbo.filter.TraceFilter@logger.logger'</span>
+@Log4jLogger[
+    FQCN=@String[com.alibaba.dubbo.common.logger.support.FailsafeLogger],
+    logger=@Logger[org.apache.log4j.Logger@2f19bdcf],
+]
+</code></pre>
+<p>再用<code>sc</code>命令来查看具体从哪个jar包里加载的:</p>
+<pre><code class="language-bash">$ sc -d org.apache.log4j.Logger
+ class-info        org.apache.log4j.Logger
+ code-source       /Users/hengyunabc/.m2/repository/org/slf4j/log4j-over-slf4j/1.7.25/log4j-over-slf4j-1.7.25.jar
+ name              org.apache.log4j.Logger
+ isInterface       <span class="hljs-literal">false</span>
+ isAnnotation      <span class="hljs-literal">false</span>
+ isEnum            <span class="hljs-literal">false</span>
+ isAnonymousClass  <span class="hljs-literal">false</span>
+ isArray           <span class="hljs-literal">false</span>
+ isLocalClass      <span class="hljs-literal">false</span>
+ isMemberClass     <span class="hljs-literal">false</span>
+ isPrimitive       <span class="hljs-literal">false</span>
+ isSynthetic       <span class="hljs-literal">false</span>
+ simple-name       Logger
+ modifier          public
+ annotation
+ interfaces
+ super-class       +-org.apache.log4j.Category
+                     +-java.lang.Object
+ class-loader      +-sun.misc.Launcher<span class="hljs-variable">$AppClassLoader</span>@5c647e05
+                     +-sun.misc.Launcher<span class="hljs-variable">$ExtClassLoader</span>@59878d35
+ classLoaderHash   5c647e05
+
+Affect(row-cnt:1) cost <span class="hljs-keyword">in</span> 126 ms.
+</code></pre>
+<p><strong>可以看到log4j是通过slf4j代理的。</strong></p>
+<p>那么通过<code>org.slf4j.LoggerFactory</code>获取<code>root</code> logger,再修改它的level:</p>
+<pre><code>$ ognl '@org.slf4j.LoggerFactory@getLogger(&quot;root&quot;).setLevel(@ch.qos.logback.classic.Level@DEBUG)'
+null
+$ ognl '@org.slf4j.LoggerFactory@getLogger(&quot;root&quot;).getLevel().toString()'
+@String[DEBUG]
+</code></pre>
+<p>可以看到修改之后,<code>root</code> logger的level变为<code>DEBUG</code>。</p>
+<h3>怎样减少测试小姐姐重复发请求的麻烦?</h3>
+<ul>
+<li><a href="https://alibaba.github.io/arthas/tt.html">https://alibaba.github.io/arthas/tt.html</a></li>
+</ul>
+<p>在平时开发时,可能需要测试小姐姐发请求过来联调,但是我们在debug时,可能不小心直接跳过去了。这样子就尴尬了,需要测试小姐姐再发请求过来。</p>
+<p>Arthas里提供了<code>tt</code>命令,可以减少这种麻烦,可以直接重放请求。</p>
+<pre><code class="language-bash">$ tt -t com.example.UserServiceImpl findUser
+Press Ctrl+C to abort.
+Affect(class-cnt:1 , method-cnt:1) cost <span class="hljs-keyword">in</span> 145 ms.
+ INDEX      TIMESTAMP              COST(ms)      IS-RET     IS-EXP    OBJECT       CLASS              METHOD
+----------------------------------------------------------------------------------------------------------------
+ 1000       2018-12-05 17:47:52    1.56523       <span class="hljs-literal">true</span>       <span class="hljs-literal">false</span>     0x3233483    UserServiceImpl    findUser
+ 1001       2018-12-05 17:48:03    0.286176      <span class="hljs-literal">false</span>      <span class="hljs-literal">true</span>      0x3233483    UserServiceImpl    findUser
+ 1002       2018-12-05 17:48:11    90.324335     <span class="hljs-literal">true</span>       <span class="hljs-literal">false</span>     0x3233483    UserServiceImpl    findUser
+</code></pre>
+<p>上面的<code>tt -t</code>命令捕获到了3个请求。然后通过<code>tt --play</code>可以重放请求:</p>
+<pre><code class="language-bash">$ tt --play -i 1000
+ RE-INDEX       1000
+ GMT-REPLAY     2018-12-05 17:55:50
+ OBJECT         0x3233483
+ CLASS          com.example.UserServiceImpl
+ METHOD         findUser
+ PARAMETERS[0]  @Integer[1]
+ IS-RETURN      <span class="hljs-literal">true</span>
+ IS-EXCEPTION   <span class="hljs-literal">false</span>
+ RETURN-OBJ     @User[
+                    id=@Integer[1],
+                    name=@String[Deanna Borer],
+                ]
+Time fragment[1000] successfully replayed.
+Affect(row-cnt:1) cost <span class="hljs-keyword">in</span> 4 ms.
+</code></pre>
+<h3>Dubbo运行时有哪些Filter? 耗时是多少?</h3>
+<ul>
+<li><a href="https://alibaba.github.io/arthas/trace.html">https://alibaba.github.io/arthas/trace.html</a></li>
+</ul>
+<p>Dubbo运行时会加载很多的Filter,那么一个请求会经过哪些Filter处理,Filter里的耗时又是多少呢?</p>
+<p>通过Arthas的<code>trace</code>命令,可以很方便地知道Filter的信息,可以看到详细的调用栈和耗时。</p>
+<pre><code class="language-bash">$ trace com.alibaba.dubbo.rpc.Filter *
+Press Ctrl+C to abort.
+Affect(class-cnt:19 , method-cnt:59) cost <span class="hljs-keyword">in</span> 1441 ms.
+`---ts=2018-12-05 19:07:26;thread_name=DubboServerHandler-30.5.125.152:20880-thread-10;id=3e;is_daemon=<span class="hljs-literal">true</span>;priority=5;TCCL=sun.misc.Launcher<span class="hljs-variable">$AppClassLoader</span>@5c647e05
+    `---[8.435844ms] com.alibaba.dubbo.rpc.filter.EchoFilter:invoke()
+        +---[0.124572ms] com.alibaba.dubbo.rpc.Invocation:getMethodName()
+        +---[0.065123ms] java.lang.String:equals()
+        `---[7.762928ms] com.alibaba.dubbo.rpc.Invoker:invoke()
+            `---[7.494124ms] com.alibaba.dubbo.rpc.filter.ClassLoaderFilter:invoke()
+                +---[min=0.00355ms,max=0.049922ms,total=0.057637ms,count=3] java.lang.Thread:currentThread()
+                +---[0.0126ms] java.lang.Thread:getContextClassLoader()
+                +---[0.02188ms] com.alibaba.dubbo.rpc.Invoker:getInterface()
+                +---[0.004115ms] java.lang.Class:getClassLoader()
+                +---[min=0.003906ms,max=0.014058ms,total=0.017964ms,count=2] java.lang.Thread:setContextClassLoader()
+                `---[7.033486ms] com.alibaba.dubbo.rpc.Invoker:invoke()
+                    `---[6.869488ms] com.alibaba.dubbo.rpc.filter.GenericFilter:invoke()
+                        +---[0.01481ms] com.alibaba.dubbo.rpc.Invocation:getMethodName()
+</code></pre>
+<h3>Dubbo动态代理是怎样实现的?</h3>
+<ul>
+<li><a href="https://alibaba.github.io/arthas/jad.html">https://alibaba.github.io/arthas/jad.html</a></li>
+<li>com.alibaba.dubbo.common.bytecode.Wrapper</li>
+</ul>
+<p>通过Arthas的<code>jad</code>命令,可以看到Dubbo通过javaassist动态生成的Wrappr类的代码:</p>
+<pre><code class="language-java">$ jad com.alibaba.dubbo.common.bytecode.Wrapper1
+
+ClassLoader:
++-sun.misc.Launcher$AppClassLoader@<span class="hljs-number">5</span>c647e05
+  +-sun.misc.Launcher$ExtClassLoader@<span class="hljs-number">59878</span>d35
+
+Location:
+/Users/hengyunabc/.m2/repository/com/alibaba/dubbo/<span class="hljs-number">2.5</span><span class="hljs-number">.10</span>/dubbo-<span class="hljs-number">2.5</span><span class="hljs-number">.10</span>.jar
+
+<span class="hljs-keyword">package</span> com.alibaba.dubbo.common.bytecode;
+
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Wrapper1</span>
+<span class="hljs-keyword">extends</span> <span class="hljs-title">Wrapper</span>
+<span class="hljs-keyword">implements</span> <span class="hljs-title">ClassGenerator</span>.<span class="hljs-title">DC</span> </span>{
+
+    <span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">invokeMethod</span><span class="hljs-params">(Object object, String string, Class[] arrclass, Object[] arrobject)</span> <span class="hljs-keyword">throws</span> InvocationTargetException </span>{
+        UserServiceImpl userServiceImpl;
+        <span class="hljs-keyword">try</span> {
+            userServiceImpl = (UserServiceImpl)object;
+        }
+        <span class="hljs-keyword">catch</span> (Throwable throwable) {
+            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(throwable);
+        }
+        <span class="hljs-keyword">try</span> {
+            <span class="hljs-keyword">if</span> (<span class="hljs-string">"findUser"</span>.equals(string) &amp;&amp; arrclass.length == <span class="hljs-number">1</span>) {
+                <span class="hljs-keyword">return</span> userServiceImpl.findUser(((Number)arrobject[<span class="hljs-number">0</span>]).intValue());
+            }
+            <span class="hljs-keyword">if</span> (<span class="hljs-string">"listUsers"</span>.equals(string) &amp;&amp; arrclass.length == <span class="hljs-number">0</span>) {
+                <span class="hljs-keyword">return</span> userServiceImpl.listUsers();
+            }
+            <span class="hljs-keyword">if</span> (<span class="hljs-string">"findUserByName"</span>.equals(string) &amp;&amp; arrclass.length == <span class="hljs-number">1</span>) {
+                <span class="hljs-keyword">return</span> userServiceImpl.findUserByName((String)arrobject[<span class="hljs-number">0</span>]);
+            }
+        }
+</code></pre>
+<h3>获取Spring context</h3>
+<p>除了上面介绍的一些排查技巧,下面分享一个获取Spring Context,然后“为所欲为”的例子。</p>
+<p>在Dubbo里有一个扩展<code>com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory</code>,把Spring Context保存到了里面。
+因此,我们可以通过<code>ognl</code>命令获取到。</p>
+<pre><code class="language-bash">$ ognl <span class="hljs-string">'#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next, #context.getBean("userServiceImpl").findUser(1)'</span>
+@User[
+    id=@Integer[1],
+    name=@String[Deanna Borer],
+]
+</code></pre>
+<ul>
+<li><code>SpringExtensionFactory@contexts.iterator.next</code> 获取到<code>SpringExtensionFactory</code>里保存的spring context对象</li>
+<li><code>#context.getBean(&quot;userServiceImpl&quot;).findUser(1)</code> 获取到<code>userServiceImpl</code>再执行一次调用</li>
+</ul>
+<p>只要充分发挥想像力,组合Arthas里的各种命令,可以发挥出神奇的效果。</p>
+<h2>总结</h2>
+<p>本篇文章来自杭州Dubbo Meetup的分享《当DUBBO遇上Arthas - 排查问题的实践》,希望对大家线上排查Dubbo问题有帮助。</p>
+<p>分享的PDF可以在 <a href="https://github.com/alibaba/arthas/issues/327">https://github.com/alibaba/arthas/issues/327</a> 里下载。</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-meet-arthas.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meet-arthas.json
new file mode 100644
index 0000000..26542a7
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meet-arthas.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-meet-arthas.md",
+  "__html": "<h1>当Dubbo遇上Arthas:排查问题的实践</h1>\n<p>Apache Dubbo是Alibaba开源的高性能RPC框架,在国内有非常多的用户。</p>\n<ul>\n<li>Github: <a href=\"https://github.com/apache/dubbo\">https://github.com/apache/dubbo</a></li>\n<li>文档:<a href=\"http://dubbo.apache.org/zh-cn/\">http://dubbo.apache.org/zh-cn/</a></li>\n</ul>\n<p>Arthas是Alibaba开源的应用诊断利器,9月份开源以来,Github Star数三个月超过6000。</p>\n<ul>\n<li>Github: <a href=\"https://github.com/alibaba/arthas\">https://github.com/alibaba/arthas</a></li>\n<li>文档:<a href=\"http [...]
+  "link": "/zh-cn/blog/dubbo-meet-arthas.html",
+  "meta": {
+    "title": "当Dubbo遇上Arthas:排查问题的实践",
+    "keywords": "Dubbo, Arthas",
+    "description": "使用Alibaba开源的应用诊断利器Arthas来排查Dubbo应用的问题。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.html
new file mode 100644
index 0000000..bac51fc
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.html
@@ -0,0 +1,41 @@
+<!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="Dubbo, Beijing, meetup" />
+	<meta name="description" content="首届Dubbo开发者沙龙在北京成功举办" />
+	<!-- 网页标签标题 -->
+	<title>首届Dubbo开发者沙龙在北京成功举办</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>首届Dubbo开发者沙龙在北京成功举办, 超过400位开发者参加。这是一个很好的开始!</p>
+<p>分享嘉宾及主体如下:</p>
+<ul>
+<li>罗毅: Dubbo 的现状现状与未来规划 <a href="https://github.com/dubbo/awesome-dubbo/raw/master/slides/meetup/201805%40Beijing/dubbo-present-and-future.pdf">PDF</a></li>
+<li>刘军: 第四届阿里中间件性能挑战赛 <a href="https://github.com/dubbo/awesome-dubbo/raw/master/slides/meetup/201805%40Beijing/introduction-to-4th-aliware-performance-challenge.pdf">PDF</a></li>
+<li>陈志轩: 通过 Dubbo 和 Spring-boot 快速构建微服务 <a href="https://github.com/dubbo/awesome-dubbo/raw/master/slides/meetup/201805%40Beijing/quickly-building-microservice-with-dubbo-and-springboot.pdf">PDF</a></li>
+<li>王欣: Dubbo 和微店的服务化实践历程分享 <a href="https://github.com/dubbo/awesome-dubbo/raw/master/slides/meetup/201805%40Beijing/dubbo-and-weidian's-practice-on-microservice-architecture.pdf">PDF</a></li>
+</ul>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.json
new file mode 100644
index 0000000..1c268af
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-meetup-beijing-may-12th-2018.md",
+  "__html": "<h2>首届Dubbo开发者沙龙在北京成功举办</h2>\n<p>首届Dubbo开发者沙龙在北京成功举办, 超过400位开发者参加。这是一个很好的开始!</p>\n<p>分享嘉宾及主体如下:</p>\n<ul>\n<li>罗毅: Dubbo 的现状现状与未来规划 <a href=\"https://github.com/dubbo/awesome-dubbo/raw/master/slides/meetup/201805%40Beijing/dubbo-present-and-future.pdf\">PDF</a></li>\n<li>刘军: 第四届阿里中间件性能挑战赛 <a href=\"https://github.com/dubbo/awesome-dubbo/raw/master/slides/meetup/201805%40Beijing/introduction-to-4th-aliware-performance-challenge.pdf\">PDF</a></li>\n<li>陈志轩: 通过 Dubbo 和 Spring-b [...]
+  "link": "/zh-cn/blog/dubbo-meetup-beijing-may-12th-2018.html",
+  "meta": {
+    "title": "首届Dubbo开发者沙龙在北京成功举办",
+    "keywords": "Dubbo, Beijing, meetup",
+    "description": "首届Dubbo开发者沙龙在北京成功举办"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-chengdu.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-chengdu.html
new file mode 100644
index 0000000..26f3fee
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-chengdu.html
@@ -0,0 +1,41 @@
+<!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="Dubbo, 成都, meetup" />
+	<meta name="description" content="第四届Dubbo开发者沙龙于8月26日在成都举行。" />
+	<!-- 网页标签标题 -->
+	<title>第四届Dubbo开发者沙龙于8月26日在成都举行</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p><img src="../../img/blog/meetup-chengdu/all-hands.webp" alt="img"></p>
+<h2>用户深度沟通交流</h2>
+<p>8.26上午10:00-12:00,邀请到货车帮,云图金控,前BBD,飞鱼星四家公司开源爱好者及重度用户参与面对面交流;据参与者反馈,解答了对Dubbo的诸多疑惑,特别是如何参与贡献社区,以及捐献代码所带来的价值点。希望后面可以更加深入参与Dubbo社区及活动中。</p>
+<h2>meetup活动信息</h2>
+<p>本次活动依旧爆满,总报名人数976,现场用户350+,直播PV 13207。</p>
+<h2>报名信息</h2>
+<p>Aliware Open Source•成都站-Apache Dubbo开发者沙龙于8月26日(周日)在成都高新区天府五街200号菁蓉国际广场8号楼2楼会议厅举办,技术GG们的思想盛宴,干货与福利一个都不会少。</p>
+<p>报名链接:<a href="http://www.huodongxing.com/event/7453091088400">http://www.huodongxing.com/event/7453091088400</a></p>
+<img src="../../img/blog/dubbo-chengdu-meetup-img.jpg"/></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/event [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-chengdu.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-chengdu.json
new file mode 100644
index 0000000..6e0a169
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-chengdu.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-meetup-chengdu.md",
+  "__html": "<h1>第四届Dubbo开发者沙龙于8月26日在成都举行</h1>\n<p><img src=\"../../img/blog/meetup-chengdu/all-hands.webp\" alt=\"img\"></p>\n<h2>用户深度沟通交流</h2>\n<p>8.26上午10:00-12:00,邀请到货车帮,云图金控,前BBD,飞鱼星四家公司开源爱好者及重度用户参与面对面交流;据参与者反馈,解答了对Dubbo的诸多疑惑,特别是如何参与贡献社区,以及捐献代码所带来的价值点。希望后面可以更加深入参与Dubbo社区及活动中。</p>\n<h2>meetup活动信息</h2>\n<p>本次活动依旧爆满,总报名人数976,现场用户350+,直播PV 13207。</p>\n<h2>报名信息</h2>\n<p>Aliware Open Source•成都站-Apache Dubbo开发者沙龙于8月26日(周日)在成都高新区天府五街200号菁蓉国际广场8号楼2楼会议厅举办,技术GG们的思想盛宴,干货与福利一个都不会少。</p>\n<p>报名链接: [...]
+  "link": "/zh-cn/blog/dubbo-meetup-chengdu.html",
+  "meta": {
+    "title": "第四届Dubbo开发者沙龙于8月26日在成都举行",
+    "keywords": "Dubbo, 成都, meetup",
+    "description": "第四届Dubbo开发者沙龙于8月26日在成都举行。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-hangzhou.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-hangzhou.html
new file mode 100644
index 0000000..e7eaf56
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-hangzhou.html
@@ -0,0 +1,43 @@
+<!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="Dubbo, 杭州, meetup" />
+	<meta name="description" content="第五届Dubbo开发者沙龙在杭州成功举办。" />
+	<!-- 网页标签标题 -->
+	<title>第五届Dubbo开发者沙龙在杭州成功举办</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>第五届Dubbo开发者沙龙在杭州成功举办,</p>
+<p>分享嘉宾</p>
+<ul>
+<li>李鼎: 如何参与Dubbo开源社区 <a href="https://github.com/dubbo/awesome-dubbo/blob/master/slides/meetup/201812%40hangzhou/how-to-involve-in-dubbo-community.pdf">slides</a></li>
+<li>曹胜利: Dubbo 2.7新特性介绍及演示 <a href="https://github.com/dubbo/awesome-dubbo/blob/master/slides/meetup/201812%40hangzhou/dubbo-2.7-introduction.pdf">slides</a></li>
+<li>陶杨:  Dubbo在考拉的应用实践 <a href="https://github.com/dubbo/awesome-dubbo/blob/master/slides/meetup/201812%40hangzhou/dubbo-practice-in-netease-koala.pdf">slides</a></li>
+<li>小马哥: Dubbo+Nacos服务治理重新实现 <a href="https://github.com/dubbo/awesome-dubbo/blob/master/slides/meetup/201812%40hangzhou/nacos-support-in-dubbo.pdf">slides</a></li>
+<li>赵奕豪: Sentinel:分布式服务的流量防卫兵 <a href="https://github.com/dubbo/awesome-dubbo/blob/master/slides/meetup/201812%40hangzhou/sentinel-support-for-dubbo.pdf">slides</a></li>
+<li>陈志轩: 当Dubbo遇上Arthas:排查问题的实践 <a href="https://github.com/dubbo/awesome-dubbo/blob/master/slides/meetup/201812%40hangzhou/troubleshooting-dubbo-with-arthas.pdf">slides</a></li>
+</ul>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-hangzhou.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-hangzhou.json
new file mode 100644
index 0000000..8bc4f38
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-hangzhou.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-meetup-hangzhou.md",
+  "__html": "<h1>第五届Dubbo开发者沙龙在杭州成功举办</h1>\n<p>第五届Dubbo开发者沙龙在杭州成功举办,</p>\n<p>分享嘉宾</p>\n<ul>\n<li>李鼎: 如何参与Dubbo开源社区 <a href=\"https://github.com/dubbo/awesome-dubbo/blob/master/slides/meetup/201812%40hangzhou/how-to-involve-in-dubbo-community.pdf\">slides</a></li>\n<li>曹胜利: Dubbo 2.7新特性介绍及演示 <a href=\"https://github.com/dubbo/awesome-dubbo/blob/master/slides/meetup/201812%40hangzhou/dubbo-2.7-introduction.pdf\">slides</a></li>\n<li>陶杨:  Dubbo在考拉的应用实践 <a href=\"https://github.com/dubbo/awe [...]
+  "link": "/zh-cn/blog/dubbo-meetup-hangzhou.html",
+  "meta": {
+    "title": "第五届Dubbo开发者沙龙在杭州成功举办",
+    "keywords": "Dubbo, 杭州, meetup",
+    "description": "第五届Dubbo开发者沙龙在杭州成功举办。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.html
new file mode 100644
index 0000000..f648390
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.html
@@ -0,0 +1,41 @@
+<!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="Dubbo, 上海, meetup" />
+	<meta name="description" content="第二届Dubbo开发者沙龙在上海成功举办。" />
+	<!-- 网页标签标题 -->
+	<title>第二届Dubbo开发者沙龙在上海成功举办</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>第二届Dubbo开发者沙龙在上海成功举办,超过700位开发者报名,现场参与人数300+,通过阿里云天池、云栖社区、大咖说引导线上直播观看次数10000+</p>
+<p>分享嘉宾及PPT:</p>
+<ul>
+<li>朱勇: Dubbo开源现状与未来规划 (中文) <a href="https://github.com/dubbo/awesome-dubbo/blob/master/slides/meetup/201806%40Shanghai/dubbo-status-and-roadmap.pdf">slides</a></li>
+<li>小马哥: Dubbo Cloud Native 之路的实践与思考 (中文) <a href="https://github.com/dubbo/awesome-dubbo/blob/master/slides/meetup/201806%40Shanghai/dubbo-cloud-native-practices-and-thoughts.pdf">slides</a></li>
+<li>郭平: Nacos - 贡献Dubbo生态,阿里巴巴注册中心和配置中心开源计划 (中文) <a href="https://github.com/dubbo/awesome-dubbo/blob/master/slides/meetup/201806%40Shanghai/nacos-open-source-initiative.pdf">slides</a></li>
+<li>潘志伟: Dubbo在互金行业的应用场景 (中文) <a href="https://github.com/dubbo/awesome-dubbo/blob/master/slides/meetup/201806%40Shanghai/dubbo-practices-on-internet-finance-industries.pdf">slides</a></li>
+</ul>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.json
new file mode 100644
index 0000000..bb0596a
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-meetup-shanghai-jun-23rd-2018.md",
+  "__html": "<h1>第二届Dubbo开发者沙龙在上海成功举办</h1>\n<p>第二届Dubbo开发者沙龙在上海成功举办,超过700位开发者报名,现场参与人数300+,通过阿里云天池、云栖社区、大咖说引导线上直播观看次数10000+</p>\n<p>分享嘉宾及PPT:</p>\n<ul>\n<li>朱勇: Dubbo开源现状与未来规划 (中文) <a href=\"https://github.com/dubbo/awesome-dubbo/blob/master/slides/meetup/201806%40Shanghai/dubbo-status-and-roadmap.pdf\">slides</a></li>\n<li>小马哥: Dubbo Cloud Native 之路的实践与思考 (中文) <a href=\"https://github.com/dubbo/awesome-dubbo/blob/master/slides/meetup/201806%40Shanghai/dubbo-cloud-native-practices-and-th [...]
+  "link": "/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.html",
+  "meta": {
+    "title": "第二届Dubbo开发者沙龙在上海成功举办",
+    "keywords": "Dubbo, 上海, meetup",
+    "description": "第二届Dubbo开发者沙龙在上海成功举办。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-shenzhen.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-shenzhen.html
new file mode 100644
index 0000000..c797ff1
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-shenzhen.html
@@ -0,0 +1,40 @@
+<!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="Dubbo, 深圳, meetup" />
+	<meta name="description" content="第三届Dubbo开发者沙龙在深圳成功举办。" />
+	<!-- 网页标签标题 -->
+	<title>第三届Dubbo开发者沙龙在深圳成功举办</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p>第三届Dubbo开发者沙龙在深圳成功举办,超过2000位开发者报名,现场参与人数700+,通过阿里云天池、云栖社区、大咖说引导线上直播观看次数17000+</p>
+<p>分享嘉宾</p>
+<ul>
+<li>陈志轩: Dubbo开源现状和2.7规划</li>
+<li>康彬: 乐信集团的微服务化之路</li>
+<li>林佳梁: Sentinel——企业用户的全方位流量哨兵</li>
+</ul>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-shenzhen.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-shenzhen.json
new file mode 100644
index 0000000..d7a6257
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-meetup-shenzhen.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-meetup-shenzhen.md",
+  "__html": "<h1>第三届Dubbo开发者沙龙在深圳成功举办</h1>\n<p>第三届Dubbo开发者沙龙在深圳成功举办,超过2000位开发者报名,现场参与人数700+,通过阿里云天池、云栖社区、大咖说引导线上直播观看次数17000+</p>\n<p>分享嘉宾</p>\n<ul>\n<li>陈志轩: Dubbo开源现状和2.7规划</li>\n<li>康彬: 乐信集团的微服务化之路</li>\n<li>林佳梁: Sentinel——企业用户的全方位流量哨兵</li>\n</ul>\n",
+  "link": "/zh-cn/blog/dubbo-meetup-shenzhen.html",
+  "meta": {
+    "title": "第三届Dubbo开发者沙龙在深圳成功举办",
+    "keywords": "Dubbo, 深圳, meetup",
+    "description": "第三届Dubbo开发者沙龙在深圳成功举办。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-mesh-in-thinking.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-mesh-in-thinking.html
new file mode 100644
index 0000000..c2ab14a
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-mesh-in-thinking.html
@@ -0,0 +1,115 @@
+<!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="Dubbo, Service Mesh, Cloud Native" />
+	<meta name="description" content="Dubbo是实现框架,融入service mesh理念就是我们今天分享的。" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo在Service Mesh下的思考和方案</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>开头</h2>
+<p>Service Mesh这个“热”词是2016年9月被“造”出来,而今年2018年更是被称为service Mesh的关键之年,各家大公司都希望能在这个思潮下领先一步。今天我也分享阿里中间件在这方面的观点,思考和实践。考虑到有些人没了解过Dubbo(集团内以HSF为主)和Servicemesh,先简单介绍下这两个词。Dubbo应该是国内最受欢迎的远程服务框架,在Github上有超过2w的star数,也是阿里分布式架构互联互通的核心所在。跟Dubbo一样,servicemesh也是面向服务互联互通这一问题域,是云原生技术栈的核心之一;大家可以简单理解service mesh就是云原生组织定义的微服务架构解决理念。Dubbo是实现框架,融入service mesh理念就是我们今天分享的。</p>
+<h2>现状和挑战</h2>
+<p><img src="../../img/blog/dubbomesh/1.png" alt="1.png | center | 826x206"></p>
+<p>当前Dubbo支撑的阿里分布式应用内支撑万级别的应用数,运行在20多万的服务器实例上,每天调用量是万亿级别,这应该是国内最大的分布式应用集群。</p>
+<p>挑战主要来自三方面</p>
+<ul>
+<li>首先, 数以万计的应用意味着有以十万级的服务,理顺错综复杂的服务拓扑关系,甚至及时诊断某个异常调用链路,需要考虑海量数据的拉取分析,是非常有挑战的,阿里通过EagleEye鹰眼链路系统提供可观察性和治理能力来解决;</li>
+<li>第二个挑战是机房级别容灾,阿里的机房是分布在天南海北,大家可以想象横跨数千公里的网络延迟会造成服务互通很大的影响,所以在保证一定恢复时间和一定数据容错的情况下做异地多活是有巨大挑战,阿里通过支持异地多活的单元化架构解决。</li>
+<li>第三个挑战是阿里业务众多,尤其像阿里生态中的高德,UC,优酷等所使用的开发语言跟淘系Java是不一样的,比如PHP,C,Nodejs,Dart等,要维护多个版本并保证各版本具有同样的功能是成本比较高的;这个挑战在云原生的新一代理念下更具挑战,毕竟。今天主题跟第三个挑战是息息相关,能解决一定的问题。</li>
+</ul>
+<p>这里讲个大鱼吃小鱼的故事来简单理解下云原生:软件会吃掉这个世界,也就是信息化不可避免,而开源会吃掉软件,最终云原生会吃掉开源。这正代表了云原生理念的颠覆性,从商业软件到开源到云原生,环环相套,以体系化和层次化的方式推荐各个方面的开源方案和标准,这会极大降低企业级架构服务的技术门槛,是企业信息化之路的一大利好,当然也是进化方向。这个故事跟今天的主题--开发者定义软件未来,是非常契合,也就是说这个趋势至少在企业级软件服务领域正在发生。云原生:Cloud Native is Patterns with A complete and trusted tool kit for modern architectures。</p>
+<p><span data-type="color" style="color:white">Service Mesh的典型方案</span></p>
+<h2>Service Mesh的典型方案</h2>
+<p><img src="../../img/blog/dubbomesh/2.png" alt="2.png | center | 826x206"></p>
+<p>讲完故事,回到servicemesh。</p>
+<p>传统形态下SDK代表着一个特定语言的库,由应用和微服务框架共处一进程内,在发布升级中共享生命周期。比较典型的代表是Twitter的finagle,Google的stubby/grpc,阿里巴巴的HSF/Dubbo.</p>
+<p>Serviemesh下推荐是右边Sidecar方案,Sidecar方案没有引入新的功能,只是改变了原有功能的位置,以独立的应用来存在,大家可以暂时以nginx来理解其网络代理能力也可以。</p>
+<p>在这张图中希望大家关注两个信息, 1)所有的sidecar形成逻辑网络被称为数据面,是业务服务的链路中是强依赖节点,承载了业务数据互联互通的基础;传统的ops管控服务被称为控制面,这部分跟传统是大同小异。 2)在sidecar形态下,网络会增加两跳,即应用与sidecar之间,他们之间的数据互通也是基于协议规范。后面会详细讲。</p>
+<h2>Sidecar模式的优劣</h2>
+<p><img src="../../img/blog/dubbomesh/3.png" alt="3.png | center | 826x206"></p>
+<p>接下来从开发和运维两个阶段来分开比较。</p>
+<ul>
+<li>多语言支持方面,既然sidecar是独立应用,用最合适的一种语言开发完成即可,就避免了需要针对不同语言的应用场景做不同的版本开发。当前阿里选择基于C语言的Envoy做二次开发来追求最小的footprint和性能,当然也曾经历一些弯路,比如曾经用Java开发过一个sidecar,但最终由于引入JRE体量大和GC带来的抖动等问题证明不可行。有必要强调的是:这里说的是sidecar自身开发现在避免了多语言多版本的问题,而真要支持任意服务自由采用任意语言实现这一理想,是需要站在从业务到数据面再到业务的整个链路上的数据交互做思考。</li>
+<li>性能方面,sidecar情形下由于会增加两跳,这两跳是业务应用与sidecar的两个进程之间的调用,这是本机,即便是经过优化,也是会增加进程切换以及数据转换的开销。经过我们的优化测试,在正常的业务访问下,相比SDK形态下最多增加1毫秒的开销,这在大多数业务情形下是基本无感知无影响。</li>
+<li>再看运维阶段的比较,一般SDK形态的服务框架都是只关心开发的诉求,对于如何运维都是不关心,而软件生命周期中运维是最长的,如何从中间件角度解决更多的运维问题是非常有意义的。阿里的中间件经常需要升级,以库的形式升级时就需要业务方应用重新打包,这个推动业务方变更的方式是比较被动,而且周期很长。</li>
+<li>当以镜像为基本原子单位进行发布部署时,阿里的中间件SDK体量大概是200兆,需要与业务一起打包,这样在业务应用升级时让分发的包就显得笨重,时效性相比sidecar形态就差一截。</li>
+</ul>
+<p>稍微总结下,sidecar具有两个明显优势,一个是多语言开发维护成本低 ,另一个是独立升级,当然代价是需要增加一点点的网络延迟。至此大家是不是觉得Sidecar基本完美? 别着急,需要大家再思考一个问题:SDK模式下中间件组件会随应用一起发布,拥有完全一致的生命周期;而在sidecar模式下,如何管理sidecar的生命周期?这里可以拿无线耳机来举个例子,无线耳机是独立了,但必须独立电源的驱动,所以充电是要的。是的,在大规模的集群中这个点会带来不小的复杂性。</p>
+<h2>关键点</h2>
+<p><img src="../../img/blog/dubbomesh/4.png" alt="4.png | center | 826x206"></p>
+<p>下面跟大家分享下我们对servicemesh理解的三个关键技术点。分别是sidecar运维,数据面与控制面的集成,协议。</p>
+<ul>
+<li>先说sidecar的运维,这是个难点,也是为什么sidecar方案以前没有被广泛应用的重要原因。前面说sidecar与应用现在成为两个不同的进程,要考虑多个事宜,一是要考虑如何把sidecar与应用部署在一起,二是考虑业务进程或sidecar进程一方需要升级重启时如何协同来保证请求的正常处理或转发,即优雅上下线的问题。这些事宜考虑清楚并解决后,算是具备servicemesh的前提条件。当然,kubernetes解决了这块的事情,提供了initiator类似插件的机制来对原子性的pod进行注入sidecar,并通过健康检查机制来保证两个进程的协同。简单地也可以这么理解:先把kubernetes容器调度平台的实施是servicemesh的前提条件。</li>
+<li>数据面中的sidecar的服务治理能力则是其核心竞争力,包括负载均衡策略,路由,安全,权重等等,这些能力是以规则形式通过控制面来统一下发给数据面。在传统微服务框架下数据面和控制面的集成是紧耦合,也就是数据面和控制面是一体的,举例来说用了Dubbo框架,只能选择Dubbo-Ops。而Envoy作为servicemesh思潮的带领者,提出了一整套的API规范,Istio可以实现其xDS接口,阿里巴巴也可以根据自己的架构设计实现类似的服务平台。</li>
+<li>协议 协议 协议, 重要的事说三遍。。。sidecar和Dubbo的内核是网络协议的处理器,而sidecar又是面向多语言场景的,所以自然协议处理能力是要强调的。先说下阿里Dubbo当下向Mesh方向发展时遇到难点。首先我们的服务接口都是通过Java Interface描述,其次涉及的传输模型DTO也是Java POJO定义,最后协议也是私有的。这会导致跨语言比较难,而sidecar形态需要面向多语言,这些问题更是首当其冲。考虑到这里有点稍微偏细节点,希望大家带着如下问题来先思考下:业务应用到sidecar之间的数据交换要考虑什么? Sidecar自身在处理网络字节流时又要考虑什么?是的,首先业务应用最好都不依赖特定协议库,也不依赖特接口定义库;Sidecar自身处理数据时跟nginx很接近,但最好具备协议转换适配的能力,比如把基于HTTP的请求转换为Dubbo请求,就能轻松集成Dubbo遗�
 �系统。</li>
+</ul>
+<h2>回看协议</h2>
+<p><img src="../../img/blog/dubbomesh/5.png" alt="5.png | center | 826x206"></p>
+<p>既然协议在跨语言场景下如此重要,有必要稍微回归下协议的历史轨迹。看历史一般是轻松有趣的过程,最重要的好处是能使我们头脑清晰而不迷茫。</p>
+<p>我们先从2008年说起,很近也就10年,阿里服务框架诞生这一年。当年各大公司还在炒作SOA思想的时候,阿里在不清楚SOA思想的情况下根据自身业务诉求实践拥抱了SOA的架构。阿里服务框架一直是从三个层面来定义,第一RPC通信 第二是提供丰富强大的治理能力 第三就是基于容器隔离的运维能力,使得中间件可以独立升级。这个理念直到今日都是非常先进,非常的赞。就像前面说的,Dubbo主要是面向Java领域的微服务架构解决方案,在以Java为主导的技术架构下是绝对首选,但因为其协议设计是私有特性,要想成为跨语言的协议标准是有一定难度。</p>
+<p>事实上,之前已经出现了很多通用的跨语言的服务集成规范。最早是91年的考吧,是分布式对象访问协议,2000年的SOAP是当年webservice思想下的协议,无论是考吧还是SOAP都是支持所有平台和语言的一套规范,但是设计地比较复杂笨重,且性能存在一定问题。</p>
+<p>REST是一种架构风格,相比SOAP的设计,有非常优秀的理念和最佳实践指导,并且万维网作为世界上最大型最成功的的分布式应用是REST最好的证明。但跟SOAP一样,REST跑在1上有性能瓶颈,这个也可能是当年阿里服务框架没有选择REST规范的原因。额外提下,REST思想虽然很早就有,但事实上REST的规范在Java领域JAX-RS API 直到最近两年在2.2版本下才算稳定成形,且越来越接近微服务框架。</p>
+<p>1996年的1在连接通道不支持多工复用,根本无法发挥TCP/UDP的网络能力;而到了2015年HTTP2则解决这些,能够最大限度的利用TCP层的网络宽带,且支持了streaming,push等交互模式,这些跟很多的私有或专有应用协议干得是一个事,但是标准化的大家都容易接受的事。这里必须提一下,伴随HTTP2而来的是grpc,原先Google早早推出了Protocolbuffer,但一直没把自家stubby开源,我猜测最大的原因是不想grpc跑在一个私有协议上,而是在等HTTP2.</p>
+<p>总结下来,协议技术一直在向着轻量级和标准规范化的方向发展。像SOAP,考吧这些重量级的不跨平台的协议必然消失在历史车轮里,私有或专有的协议也会向标准协议靠拢。在面向跨语言的场景下,有两种的协议规范是大概率胜出,一种是REST,一种是grpc,两者都是以HTTP为交换通道。</p>
+<h2>面向多语言协议的三层面</h2>
+<p><img src="../../img/blog/dubbomesh/6.png" alt="6.png | center | 826x206"></p>
+<p>展开来讲,在面向多语言的协议需要考虑三个层面。</p>
+<ul>
+<li>先从最右边的会话层,干得事是在tcp字节流的基础上形成交互模式,比如 一对一的标准请求响应模式, 以及onway, 一对多的streaming模式。Dubbo在这一层是有扩展能力的,目前除了支持自定义的Dubbo-Remoting,也支持基于HTTP通道能力,我们觉得未来的趋势是HTTP2,所以也会支持这块.这里在分享一句话跟大家一起思考,HTTP不是RPC,HTTP被翻译成超文本传输协议,但不是传输层。另外提一下,这一层是对于MQ,Streaming Compute,Cache等等都是通用的。</li>
+<li>再说展示层,干得事是在真正的服务调用过程中,业务对象以何种形式被格式化,比如HTTP头中的content-type就用于这个展示协议的描述,最常用的JSON,TXT,XML等。这一层对于sidecar来说,可以做透明处理,也就是说sidecar只需要解析出头部信息,前提是要求业务应用把需要在治理时用到的一些字段信息以字符串形式放到头部中。Dubbo当前是默认HEssion,跨语言能力比较弱,所以未来JSON是我们首选。</li>
+<li>最后,首先一个服务是干什么的,它的名字,方法,参数都是怎样的,等等基本元信息是需要统一描述的,即便像是REST这样基于URI,也是需要一种协议来定义,以前Dubbo是基于java interface来定义,现在我们在多语言的mesh环境下是考虑向OpenAPI specification方向考虑,支持swagger。
+我们相信在这几个层面,尤其是会话层和应用层,用不多几年一定会是标准化的,尤其是在云原生的趋势下。</li>
+</ul>
+<h3>方案之Kubernetes集成<span data-type="color" style="color:white">Du</span></h3>
+<p><img src="../../img/blog/dubbomesh/7.png" alt="7.png | center | 826x206">
+<span data-type="color" style="color:white">bbo Mesh方案之Kubernetes集成</span>
+其实,servicemesh在最近两年流行最大的原因是云原生理念的逐渐深入人心,从广义角度看,能够融入云原生的微服务框架都能称得上servicemesh。谈云原生,肯定绕不开kubernetes,所以我们在Dubbo Mesh的方案的第一个分享是 在kubernetes下的集成,目标是复用Kubernetes的基础服务,从而使得Dubbo能解决kubernetes环境下的微服务集成问题,同时能最大限度的利用dubbo已有的功能。核心思路是两点,</p>
+<ul>
+<li>Dubbo应用在构建阶段自动生成其deployment和service的声明文件。这个主要是解决Dubbo与kubernetes的服务映射。</li>
+<li>Dubbo地址注册针对kubernetes的扩展实现,通过Kubernetes的APIServer来拉取并监听某个服务的podIP。这样,在kubernetes集群内,Dubbo服务就能在其podID的虚拟网络内实现服务发现。</li>
+</ul>
+<h2>方案之跨语言协议支持</h2>
+<p><img src="../../img/blog/dubbomesh/8.png" alt="8.png | center | 826x206"></p>
+<p>前面讲了很多关于协议方面的东西,也为我们在Dubbo Mesh的方案的第二点分享是做了铺垫, 第二点的目标是Dubbo 协议的多语言支持。核心思路是</p>
+<ul>
+<li>积极兼容开源社区Envoy,这个使得Envoy上兼容支持Dubbo的私有协议。</li>
+<li>Dubbo支持HTTP/2作为传输通道,这个是为了Dubbo的协议通道能力向更加开放更加标准规范的方向做努力。</li>
+</ul>
+<h2>ServiceMesh之云原生的指导</h2>
+<p><img src="../../img/blog/dubbomesh/9.png" alt="9.png | center | 826x206"></p>
+<p>孤立地看待servicemesh其实和传统服务框架,价值还不算大,甚至成本相对更高。这时候,当我们把servicemesh设定到云原生的上下文中,就会发现不一样的意义。</p>
+<p>servicemesh是云原生理念的路径地图的第五步,如果没有前面的容器化,CICD等四部,真正拥抱servicemesh也只是空中楼阁。阿里在这方面的实践经验是,servicemesh的实施是需要结合软件开发的整个生命周期进行统筹,从软件在本地开发测试,到通过持续集成服务的自动化构建,再到以镜像方式分发到仓库并依托调度云平台的持续部署,最后持续监控。</p>
+<p>dubbo已经开源好多年,是非常符合云原生这个原则,正向servicemesh方向和云原生理念上努力,为企业信息化做出一点贡献。</p>
+<h2>总结</h2>
+<p>总结一下Dubbo Mesh是Dubbo在cloud native下的一种演进,这个演进是为了更加开放更加靠近标准协议规范的方向做的探索。通过分享希望大家能带走三点思考。</p>
+<ol>
+<li>servicemesh的多语言方案其实是走规范化标准化的协议之路,这样才能覆盖多语言的诉求。</li>
+<li>建议大家根据实际业务场景来慎重权衡sidecar模式下运维复杂性和收益回报。</li>
+<li>一定把servicemesh设定在云原生的上下文中才具意义,离开了Kubernetes谈servicemesh的实践是不建议的大跃进。
+最后希望大家一起共建共享的Dubbo开源社区,谢谢。</li>
+</ol>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-mesh-in-thinking.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-mesh-in-thinking.json
new file mode 100644
index 0000000..6d2d817
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-mesh-in-thinking.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-mesh-in-thinking.md",
+  "__html": "<h1>Dubbo在Service Mesh下的思考和方案</h1>\n<h2>开头</h2>\n<p>Service Mesh这个“热”词是2016年9月被“造”出来,而今年2018年更是被称为service Mesh的关键之年,各家大公司都希望能在这个思潮下领先一步。今天我也分享阿里中间件在这方面的观点,思考和实践。考虑到有些人没了解过Dubbo(集团内以HSF为主)和Servicemesh,先简单介绍下这两个词。Dubbo应该是国内最受欢迎的远程服务框架,在Github上有超过2w的star数,也是阿里分布式架构互联互通的核心所在。跟Dubbo一样,servicemesh也是面向服务互联互通这一问题域,是云原生技术栈的核心之一;大家可以简单理解service mesh就是云原生组织定义的微服务架构解决理念。Dubbo是实现框架,融入service mesh理念就是我们今天分享的。</p>\n<h2>现状和挑战</h2>\n<p><img src=\"../../img/blog/dubbomesh/1.png\" alt=\"1.png  [...]
+  "link": "/zh-cn/blog/dubbo-mesh-in-thinking.html",
+  "meta": {
+    "title": "Dubbo在Service Mesh下的思考和方案",
+    "keywords": "Dubbo, Service Mesh, Cloud Native",
+    "description": "Dubbo是实现框架,融入service mesh理念就是我们今天分享的。"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-mesh-service-mesh-exploring.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-mesh-service-mesh-exploring.html
new file mode 100644
index 0000000..73566f3
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-mesh-service-mesh-exploring.html
@@ -0,0 +1,147 @@
+<!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="Dubbo, Service Mesh" />
+	<meta name="description" content="本文介绍了Dubbo在Service Mesh方向的实践与探索" />
+	<!-- 网页标签标题 -->
+	<title>Dubbo Mesh | Service Mesh的实践与探索</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<p><img src="../../img/blog/meetup-chengdu/all-hands.webp" alt="img"></p>
+<p>近日,在Aliware Open Source•成都站-Apache Dubbo 开发者沙龙上,阿里巴巴中间件高级技术专家李云(至简)向开发者们分享了阿里巴巴中间件团队在Service Mmesh领域的探索和最新实践。本文是根据至简的现场分享所整理,为大家回顾分享中的精彩内容。</p>
+<h2>精彩观点导读</h2>
+<ul>
+<li>
+<p>我们去探索一项技术,并不会仅仅因为其先进性,而是因为我们目前遇到了一些无法解决的问题,而这项技术正好能解决这个问题。</p>
+</li>
+<li>
+<p>所有软件最重要的使命不是满足功能要求,而是演进,从而持续成长。</p>
+</li>
+<li>
+<p>微服务本质是对服务的拆分,微服务架构符合工程领域常用的“分而治之”范式。</p>
+</li>
+</ul>
+<h2>前言</h2>
+<p>我们去探索一项技术,并不会仅仅因为其先进性,而是因为我们目前遇到了一些无法解决的问题,而这项技术正好能解决这个问题。现在,阿里巴巴整个集团业务的体量很大,在技术上会遇到很多的挑战。而正是因为这些挑战,让我们思考通过哪些新技术可以去解决这些痛点,这也是我们在Service Mesh领域进行探索和实践的出发点。首先,我们先来看看自己遇到了哪些挑战。</p>
+<h2>微服务的5大挑战</h2>
+<h4>挑战一:微服务框架自身演进困难。</h4>
+<p>任何软件都会有他的生命进化曲线,从最初的萌芽,进入形成期,往上发展,再进入平台期,最后进入衰亡期。当然我们希望我们的软件可以在进入平台期后,能借助某次演进进入新的发展期。从这个维度看,所有软件最重要的使命不是满足功能要求,而是演进,从而持续成长。相反,当某个软件无法演进的时候,就会意味着死亡。但软件的演进并不是一个简单的事情,以微服务框架为例,为了进一步提升双11期间整个中间件平台的稳定性,我们会修改若干个功能,并以SDK的方式去提供给业务方,但业务代码和微服务框架SDK是强耦合的,这时候需要我们推动各个业务方和我们一同去做升级。虽然我们的初衷是实现平台稳定性的提升,帮助业务更好的发展,但这时由于大家的出发点和诉求有所不同,业务方和我们一起去做升级是比较困难的。所�
 �要发展微服务框架,首先遇到的挑战就是演进困难。
+<img src="../../img/blog/meetup-chengdu/challenges.jpg" alt="img"></p>
+<h4>挑战二:微服务框架SDK多语言并行开发与维护成本高。</h4>
+<p>以前我们都是通过对技术栈的统一来提升成本优势和团队效率,大家可以用一种语言去开发和维护,避免多语言时团队的不聚焦。但在软件和开源生态演进的过程中,多语言已经成为一种流行,因为不同语言都有其自身的优势,今天大家能看到的一个现象是云原生的生态中有多种开发语言,使用频率最高的语言已经不是Java了,而是Go,是因为Go的footprint很小。再以 Dubbo为例,除了Java,我们还提供C++,Node.js的SDK,以便让更多的开发者可以加入Dubbo生态,但所有的这些,如果没有社区力量的参与,是很难维持的。
+<img src="../../img/blog/meetup-chengdu/speaker.webp" alt="img"></p>
+<h4>挑战三:异构服务框架难以共存完成渐进式演进。</h4>
+<p>我们结合场景来看看这个挑战。阿里巴巴收购了一些企业,被收购企业的技术栈可能和阿里巴巴不同,比如有些用的是Go语言,有些用的是PHP,这时候为了统一技术栈,我们需要对这类技术平台推倒重来,但这个过程中,我们会面临一系列问题,首当其冲的就是推倒重来会带来巨大的技术风险,其次是可能会面临技术人员大批量流失的风险,这在社会责任的层面也是很难接受。所以我们在寻求一种可能的方案,去解决这类问题。</p>
+<h4>挑战四:是单一的语言限制了人才的多样性。</h4>
+<p>这里,我们不去争论某个编程语言的好与坏,每个语言都有其适用场景,你不能说我手里有个榔头,你面对的都是钉子。以前我们觉得统一技术栈可以集中开发力量,并且带来较高的运维便利性。但伴随着互联网带来的快节奏,以往的团队能力设置已经很难满足这类变化,对工程师个体提出了更高的要求,我们不仅仅需要是某一方面的专家,而且还需要具备多域的工作技能,DevOps和全栈工程师就是这类快节奏变化下最好的注脚。
+<img src="../../img/blog/meetup-chengdu/challenges-continued.jpg" alt="img"></p>
+<h4>挑战五:是点状的服务治理难以做到及时、有效和经济。</h4>
+<p>微服务和架构的核心是拆分,通过拆分,让每个模块可以独立运行,跟上业务的发展速度,持续推动业务的创新。但拆完后新的问题出来了,缺少横向的内容拉通所有独立的烟囱,从而在服务治理上带来极大的挑战。</p>
+<h2>分布式应用的发展趋势</h2>
+<p>微服务会成为大规模分布式应用的主流架构。任何复杂的工程问题都会归结为devide and conquer(分而治之),意思就是就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。微服务本质是对服务的拆分,与工程领域惯用的“分而治之”的思路是一致的。</p>
+<p>微服务架构下应用的开发是多语言的。没有一个语言是一家独大的,每种语言在特定场景下都有其自身的优势,我们希望这种优势能够将技术到产品的周期(time to market)缩短。技术的核心在于创造价值,无论是交付给客户,还是服务于整个社会。因此,微服务是需要不同语言的开发者发挥自身的优势,去进一步完善我们的微服务架构,释放技术价值。
+<img src="../../img/blog/meetup-chengdu/trends.jpg" alt="img"></p>
+<p>数据安全将成为公有云分布式应用的生命线。云原生时代,业务即便没上云,企业对自身数据的安全都是有诉求的,尤其是在金融行业,如果通过抓包就能获取一些敏感信息,这将会给企业带来巨大的风险。</p>
+<p>Cloud native成为distributionless(无分布式)的主要探索路径。分布式发展的终极形式是无分布式,在未来我们做开发,所有的代码在web上写好后,通过点击一个按钮,所有部署都会自动实现,所有的code review的工作可以在一个统一的工作台上全部实现。
+<img src="../../img/blog/meetup-chengdu/audience-shapshot" alt="img"></p>
+<p>以更快的速度,通过构建软件去探索新业务。工程师服务的是客户,通过技术输出来实现技术价值,以互联网的架构帮助赋能传统企业,帮助企业获得差异化竞争力。</p>
+<h2>什么是Service Mesh</h2>
+<p>Service Mesh是层次化、规范化、体系化、无侵入的分布式服务治理技术平台。</p>
+<h4>层次化</h4>
+<p>分为数据面和控制面两个概念,数据面是指所有数据流动的那个层面,控制面是用来控制这个数据面的,对服务去做处理。对数据面和控制面进行分层,带来的好处是,针对一个复杂的系统进行切分,可以获得更清晰的认识,这和devide and conque是同一个理念。</p>
+<h4>规范化</h4>
+<p>是指通过标准协议完成数据平面和控制平面的连接,同时,sidecar成为所有traffic互联、互通的约束标准。</p>
+<p><img src="../../img/blog/meetup-chengdu/what.jpg" alt="img"></p>
+<h4>体系化</h4>
+<p>包含两个维度,一是指observability全局考虑。目前在整个分布式治理过程中的最大挑战是:logging、metrics、tracing这三个observability领域的核心内容缺少体系性的关注。另一个是集中管理的维度,包括服务管理、限流、熔断、安全、灰度在内的服务模块都可以在获得体系化的呈现,每个服务都可以被看到,而非团队a只看限流,团队b只看logging,需要一种技术能力拉通所有的服务模块,这个体系化这个角度看,Service Mesh是一个理想的技术方案。</p>
+<h4>无侵入</h4>
+<p>是指我们希望通过无侵入,当新增一个业务的时候,不需要考虑一个SDK去初始化,而是可以通过sidecar的进程方式来解耦。</p>
+<h2>Service Mesh的形态</h2>
+<p>我们从三个维度对比的来看 ServiceMesh 的形态。</p>
+<p>图中左边是传统的微服务形态,调用者和被调用者是通过一个SDK的方式来实现共享服务的,以Dubbo为例,我们会在SDK里提供服务路由、服务发现等功能,虽然我们的开发者在做应用开发的时候并不会太关注SDK的构成,但这些功能是面临不断被变更的可能,有着比较重的逻辑。在右边Service Mesh的形态中,我们首先会对厚重的SDK进行分解,将复杂的逻辑下沉到sidecar,借助sidecar来实现服务的调用。</p>
+<p><img src="../../img/blog/meetup-chengdu/forms.jpg" alt="img"></p>
+<p>虽然在Service Mesh的形态,调用路径要长于传统的形态,路径越长消耗越大,对性能影响越大。但在当前的分布式应用的治理过程中,易用性已经成为一个比性能更重要的话题。当我们给客户部署一套微服务,即便性能很强,但没有处理好易用性问题的话,这将会给技术的推广带来巨大的阻碍,不仅是会影响外部的客户,也会影响内部的用户,如何实现喝着咖啡从容应对双11,必须先解决易用性的问题。在解决易用性问题后,沿着技术的发展路径再去解决性能问题。</p>
+<p>Service Mesh的形态中的control plan不会导致重复建设,但在shared service是有可能存在重复建设的。</p>
+<h2>Service Mesh下的应用架构</h2>
+<p>无论是单体应用,还是分布式应用,都可以建立在Service Mesh上,mesh上的sidecar支撑了所有的上层应用,业务开发者无须关心底层构成,可以用Java,也可以用Go等语言完成自己的业务开发。</p>
+<h2>Service Mesh的价值</h2>
+<ul>
+<li>
+<p>为单体应用向微服务架构演进提供了渐进的途径</p>
+</li>
+<li>
+<p>为异构(微)服务框架/平台提供了融合发展的可能</p>
+<ul>
+<li>被收购子公司与母公司的业务可以融合发展</li>
+</ul>
+</li>
+<li>
+<p>加速(微)服务框架/平台自身的演进</p>
+</li>
+<li>
+<p>让业务开发同学聚焦于业务逻辑本身</p>
+</li>
+<li>
+<p>业务开发时无需关心安全、灰度、限流、熔断等通用的技术内容</p>
+</li>
+<li>
+<p>培育了多语言业务开发的土壤</p>
+<ul>
+<li>助力人才发展中编程语言的多样性</li>
+</ul>
+</li>
+<li>
+<p>对(异构)微服务架构应用实现更为有效的全局一体化监管控</p>
+</li>
+</ul>
+<h2>Dubbo Mesh的发展思路</h2>
+<ul>
+<li>
+<p>迎合Kubernetes已成orchestrator王者的大势</p>
+</li>
+<li>
+<p>开源版本与阿里巴巴集团内版本统一</p>
+</li>
+<li>
+<p>与领域主流开源项目形成合力发展,源于开源、反哺开源</p>
+</li>
+</ul>
+<h2>Q&amp;A</h2>
+<h4>阿里巴巴是怎么从微服务过渡到sidecar模式,再过渡到Service Mesh?</h4>
+<p>整个过渡是渐进式的,我们会将控制平面的一些组件先下沉到与sidecar部署在一起,这一下沉能很好复用开源软件已有的能力而减少开发工作量。当这一步骤完成后,被下沉的控制面组件会重新拉回到上面的控制面,那时就会面临一定的服务端改造,一旦改造完成就有了一个全新、完整的Service Mesh。</p>
+<h4>Service Mesh中的服务注册发现,负载均衡,网关,熔断降级,超时,限流,消息总线,分布式配置,这些都是怎么实现的?</h4>
+<p>Dubbo Mesh在控制面会基于Istio去做,而Istio已经具备了Kubernetes下的服务注册与发现能力,我们要做的是扩充Istio的能力,让服务注册与发现能与ZooKeeper、Nacos进行对接去完成。基于开源的Envoy所实现的sidecar已实现了超时处理的功能,相应的内容可以读代码去了解。其他内容我们仍在规划中。</p>
+<h4>Dubbo Mesh目前性能怎么样? 增加一层sidecar导致Dubbo的RT有多少?</h4>
+<p>在使用iptables的情形下,一跳增加1.5毫秒,如果不采用iptables直接proxy方式的情形下应当性能更好(这一点与Lyft也邮件确认过了),我们接下来会做更多的性能测试,目前的焦点更多在于功能层面。</p>
+<h4>Dubbo Mesh是把双刃剑,经过的链路更复杂,运维和开发者问题排查有没有更有效的工具?</h4>
+<p>理论上,增加一跳并没有改变服务调用的拓扑结构,但确实会增加复杂度,这个应当通过设计实现去解决。好在因为是一体化的方案,所以解决这类问题时需要更具全局视野。</p>
+<h4>Service Mesh中控制面板也用C++吗?我看主流很多实现都是Go, 我相信大佬做过技术调研,有哪些优势?</h4>
+<p>控制面是复用Istio的,是Go语言的。我们力争不重复造轮子,而是以开放的心态去共建。</p>
+<h4>Client做解码和反序列化是吧,有计划支持HTTP2协议吗?</h4>
+<p>Envoy默认就支持了,不需我们开发。这也是借力开源的收益。</p>
+<h4>Dubbo Mesh已经支持UNIX Domain Socket了吗?</h4>
+<p>目前不支持,这个还处于意向阶段。</p>
+</section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3></h3><p></p></div><div class="col col-4"><dl><dt>ASF</dt><dd><a href="http://www.apache.org" target="_self">基金会</a></dd><dd><a href="http://www.apache.org/licenses/" target="_self">证书</a></dd><dd><a href="http://www.apache.org/events/current-event" target="_self">事件</a></dd><dd><a href=" [...]
+	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+	<script>
+		window.rootPath = '';
+  </script>
+  <script src="/build/blogDetail.js"></script>
+  <!-- Global site tag (gtag.js) - Google Analytics -->
+	<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+	<script>
+		window.dataLayer = window.dataLayer || [];
+		function gtag(){dataLayer.push(arguments);}
+		gtag('js', new Date());
+
+		gtag('config', 'UA-112489517-1');
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-mesh-service-mesh-exploring.json b/doc-archive/v2.7.3/zh-cn/blog/dubbo-mesh-service-mesh-exploring.json
new file mode 100644
index 0000000..f213869
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-mesh-service-mesh-exploring.json
@@ -0,0 +1,10 @@
+{
+  "filename": "dubbo-mesh-service-mesh-exploring.md",
+  "__html": "<h1>Dubbo Mesh | Service Mesh的实践与探索</h1>\n<p><img src=\"../../img/blog/meetup-chengdu/all-hands.webp\" alt=\"img\"></p>\n<p>近日,在Aliware Open Source•成都站-Apache Dubbo 开发者沙龙上,阿里巴巴中间件高级技术专家李云(至简)向开发者们分享了阿里巴巴中间件团队在Service Mmesh领域的探索和最新实践。本文是根据至简的现场分享所整理,为大家回顾分享中的精彩内容。</p>\n<h2>精彩观点导读</h2>\n<ul>\n<li>\n<p>我们去探索一项技术,并不会仅仅因为其先进性,而是因为我们目前遇到了一些无法解决的问题,而这项技术正好能解决这个问题。</p>\n</li>\n<li>\n<p>所有软件最重要的使命不是满足功能要求,而是演进,从而持续成长。</p>\n</li>\n<li>\n<p>微服务本质是对服务的拆分,微服务架构符合工程领域常用的“分而治之”范式。</p>\n</l [...]
+  "link": "/zh-cn/blog/dubbo-mesh-service-mesh-exploring.html",
+  "meta": {
+    "title": "Dubbo Mesh | Service Mesh的实践与探索",
+    "keywords": "Dubbo, Service Mesh",
+    "description": "本文介绍了Dubbo在Service Mesh方向的实践与探索"
+  }
+}
\ No newline at end of file
diff --git a/doc-archive/v2.7.3/zh-cn/blog/dubbo-network-interfaces.html b/doc-archive/v2.7.3/zh-cn/blog/dubbo-network-interfaces.html
new file mode 100644
index 0000000..9310546
--- /dev/null
+++ b/doc-archive/v2.7.3/zh-cn/blog/dubbo-network-interfaces.html
@@ -0,0 +1,406 @@
+<!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="网卡地址注册" />
+	<meta name="description" content="研究 Dubbo 网卡地址注册时的一点思考" />
+	<!-- 网页标签标题 -->
+	<title>研究 Dubbo 网卡地址注册时的一点思考</title>
+	<link rel="shortcut icon" href="/img/dubbo.ico"/>
+	<link rel="stylesheet" href="/build/blogDetail.css" />
+</head>
+<body>
+	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a h [...]
+<h2>1 如何选择合适的网卡地址</h2>
+<p>可能相当一部分人还不知道我这篇文章到底要讲什么,我说个场景,大家应该就明晰了。在分布式服务调用过程中,以 Dubbo 为例,服务提供者往往需要将自身的 IP 地址上报给注册中心,供消费者去发现。在大多数情况下 Dubbo 都可以正常工作,但如果你留意过 Dubbo 的 github issue,其实有不少人反馈:Dubbo Provider 注册了错误的 IP。如果你能立刻联想到:多网卡、内外网地址共存、VPN、虚拟网卡等关键词,那我建议你一定要继续将本文看下去,因为我也想到了这些,它们都是本文所要探讨的东西!那么“如何选择合适的网卡地址”呢,Dubbo 现有的逻辑到底算不算完备?我们不急着回答它,而是带着这些问题一起进行研究,相信到文末,其中答案,各位看官自有评说。</p>
+<h2>2 Dubbo 是怎么做的</h2>
+<p>Dubbo 获取网卡地址的逻辑在各个版本中也是千回百转,走过弯路,也做过优化,我们用最新的 2.7.2-SNAPSHOT 版本来介绍,在看以下源码时,大家可以怀着质疑的心态去阅读,在 dubbo github 的 master 分支可以获取源码。获取 localhost 的逻辑位于 <code>org.apache.dubbo.common.utils.NetUtils#getLocalAddress0()</code> 之中</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> InetAddress <span class="hljs-title">getLocalAddress0</span><span class="hljs-params">()</span> </span>{
+    InetAddress localAddress = <span class="hljs-keyword">null</span>;
+    <span class="hljs-comment">// 首先尝试获取 /etc/hosts 中 hostname 对应的 IP</span>
+    localAddress = InetAddress.getLocalHost();
+    Optional&lt;InetAddress&gt; addressOp = toValidAddress(localAddress);
+    <span class="hljs-keyword">if</span> (addressOp.isPresent()) {
+        <span class="hljs-keyword">return</span> addressOp.get();
+    }
+
+    <span class="hljs-comment">// 没有找到适合注册的 IP,则开始轮询网卡</span>
+    Enumeration&lt;NetworkInterface&gt; interfaces = NetworkInterface.getNetworkInterfaces();
+    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">null</span> == interfaces) {
+        <span class="hljs-keyword">return</span> localAddress;
+    }
+    <span class="hljs-keyword">while</span> (interfaces.hasMoreElements()) {
+        NetworkInterface network = interfaces.nextElement();
+        Enumeration&lt;InetAddress&gt; addresses = network.getInetAddresses();
+        <span class="hljs-keyword">while</span> (addresses.hasMoreElements()) {
+            <span class="hljs-comment">// 返回第一个匹配的适合注册的 IP</span>
+            Optional&lt;InetAddress&gt; addressOp = toValidAddress(addresses.nextElement());
+            <span class="hljs-keyword">if</span> (addressOp.isPresent()) {
+                <span class="hljs-keyword">return</span> addressOp.get();
+            }
+        }
+    }
+    <span class="hljs-keyword">return</span> localAddress;
+}
+</code></pre>
+<p>Dubbo 这段选取本地地址的逻辑大致分成了两步</p>
+<ol>
+<li>先去 /etc/hosts 文件中找 hostname 对应的 IP 地址,找到则返回;找不到则转 2</li>
+<li>轮询网卡,寻找合适的 IP 地址,找到则返回;找不到返回 null,在 getLocalAddress0 外侧还有一段逻辑,如果返回 null,则注册 127.0.0.1 这个本地回环地址</li>
+</ol>
+<p>首先强调下,这段逻辑并没有太大的问题,先别急着挑刺,让我们来分析下其中的一些细节,并进行验证。</p>
+<h3>2.1 尝试获取 hostname 映射 IP</h3>
+<p>Dubbo 首先选取的是 hostname 对应的 IP,在源码中对应的 <code>InetAddress.getLocalHost();</code>  在 <code>*nix</code> 系统实际部署 Dubbo 应用时,可以首先使用 <code>hostname</code> 命令获取主机名</p>
+<pre><code class="language-shell">xujingfengdeMacBook-Pro:~ xujingfeng$ hostname
+xujingfengdeMacBook-Pro.local
+</code></pre>
+<p>紧接着在 <code>/etc/hosts</code> 配置 IP 映射,为了验证 Dubbo 的机制,我们随意为 hostname 配置一个 IP 地址</p>
+<pre><code>127.0.0.1	localhost
+1.2.3.4 xujingfengdeMacBook-Pro.local
+</code></pre>
+<p>接着调用 <code>NetUtils.getLocalAddress0()</code> 进行验证,控制台打印如下:</p>
+<pre><code>xujingfengdeMacBook-Pro.local/1.2.3.4
+</code></pre>
+<h3>2.2 判定有效的 IP 地址</h3>
+<p>在 toValidAddress 逻辑中,Dubbo 存在以下逻辑判定一个 IP 地址是否有效</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> Optional&lt;InetAddress&gt; <span class="hljs-title">toValidAddress</span><span class="hljs-params">(InetAddress address)</span> </span>{
+    <span class="hljs-keyword">if</span> (address <span class="hljs-keyword">instanceof</span> Inet6Address) {
+        Inet6Address v6Address = (Inet6Address) address;
+        <span class="hljs-keyword">if</span> (isValidV6Address(v6Address)) {
+            <span class="hljs-keyword">return</span> Optional.ofNullable(normalizeV6Address(v6Address));
+        }
+    }
+    <span class="hljs-keyword">if</span> (isValidV4Address(address)) {
+        <span class="hljs-keyword">return</span> Optional.of(address);
+    }
+    <span class="hljs-keyword">return</span> Optional.empty();
+}
+</code></pre>
+<p>依次校验其符合 Ipv6 或者 Ipv4 的 IP 规范,对于 Ipv6 的地址,见如下代码:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isValidV6Address</span><span class="hljs-params">(Inet6Address address)</span> </span>{
+    <span class="hljs-keyword">boolean</span> preferIpv6 = Boolean.getBoolean(<span class="hljs-string">"java.net.preferIPv6Addresses"</span>);
+    <span class="hljs-keyword">if</span> (!preferIpv6) {
+        <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
+    }
+    <span class="hljs-keyword">try</span> {
+        <span class="hljs-keyword">return</span> address.isReachable(<span class="hljs-number">100</span>);
+    } <span class="hljs-keyword">catch</span> (IOException e) {
+        <span class="hljs-comment">// ignore</span>
+    }
+    <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
+}
+</code></pre>
+<p>首先获取 <code>java.net.preferIPv6Addresses</code> 参数,其默认值为 false,鉴于大多数应用并没有使用 Ipv6 地址作为理想的注册 IP,这问题不大,紧接着通过 isReachable 判断网卡的连通性。例如一些网卡可能是 VPN/虚拟网卡的地址,如果没有配置路由表,往往无法连通,可以将之过滤。</p>
+<p>对于 Ipv4 的地址,见如下代码:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isValidV4Address</span><span class="hljs-params">(InetAddress address)</span> </span>{
+    <span class="hljs-keyword">if</span> (address == <span class="hljs-keyword">null</span> || address.isLoopbackAddress()) {
+        <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
+    }
+    String name = address.getHostAddress();
+    <span class="hljs-keyword">boolean</span> result = (name != <span class="hljs-keyword">null</span>
+            &amp;&amp; IP_PATTERN.matcher(name).matches()
+            &amp;&amp; !Constants.ANYHOST_VALUE.equals(name)
+            &amp;&amp; !Constants.LOCALHOST_VALUE.equals(name));
+    <span class="hljs-keyword">return</span> result;
+}
+</code></pre>
+<p>对比 Ipv6 的判断,这里我们已经发现前后不对称的情况了</p>
+<ul>
+<li>Ipv4 相比 Ipv6 的逻辑多了 Ipv4 格式的正则校验、本地回环地址校验、ANYHOST 校验</li>
+<li>Ipv4 相比 Ipv6 的逻辑少了网卡连通性的校验</li>
+</ul>
+<p>大家都知道,Ipv4 将 127.0.0.1 定为本地回环地址, Ipv6 也存在回环地址:0:0:0:0:0:0:0:1 或者表示为 ::1。改进建议也很明显,我们放到文末统一总结。</p>
+<h3>2.3 轮询网卡</h3>
+<p>如果上述地址获取为 null 则进入轮询网卡的逻辑(例如 hosts 未指定 hostname 的映射或者 hostname 配置成了 127.0.0.1 之类的地址便会导致获取到空的网卡地址),轮询网卡对应的源码是 <code>NetworkInterface.getNetworkInterfaces()</code> ,这里面涉及的知识点就比较多了,支撑起了我写这篇文章的素材,Dubbo 的逻辑并不复杂,进行简单的校验,返回第一个可用的 IP 即可。</p>
+<p>性子急的读者可能忍不住了,多网卡!合适的网卡可能不止一个,Dubbo 怎么应对呢?按道理说,我们也替 Dubbo 说句公道话,客官要不你自己指定下?我们首先得对多网卡的场景达成一致看法,才能继续把这篇文章完成下去:我们只能<strong>尽可能</strong>过滤那些“<strong>不对</strong>”的网卡。Dubbo 看样子对所有网卡是一视同仁了,那么是不是可以尝试优化一下其中的逻辑呢?</p>
+<p>许多开源的服务治理框架在 stackoverflow 或者其 issue 中,注册错 IP 相关的问题都十分高频,大多数都是轮询网卡出了问题。既然事情发展到这儿,势必需要了解一些网络、网卡的知识,我们才能过滤掉那些明显不适合 RPC 服务注册的 IP 地址了。</p>
+<h2>3 Ifconfig 介绍</h2>
+<p>我并没有想要让大家对后续的内容望而却步,特地选择了这个大家最熟悉的 Linux 命令!对于那些吐槽:“天呐,都 2019 年了,你怎么还在用 net-tools/ifconfig,iproute2/ip 了解一下”的言论,请大家视而不见。无论你使用的是 mac,还是 linux,都可以使用它去 CRUD 你的网卡配置。</p>
+<h3>3.1 常用指令</h3>
+<p><strong>启动关闭指定网卡:</strong></p>
+<pre><code>ifconfig eth0 up
+ifconfig eth0 down
+</code></pre>
+<p><code>ifconfig eth0 up</code> 为启动网卡 eth0,<code>ifconfig eth0 down</code> 为关闭网卡 eth0。ssh 登陆 linux 服务器操作的用户要小心执行这个操作了,千万不要蠢哭自己。不然你下一步就需要去 google:“禁用 eth0 网卡后如何远程连接 Linux 服务器” 了。</p>
+<p><strong>为网卡配置和删除IPv6地址:</strong></p>
+<pre><code>ifconfig eth0 add 33ffe:3240:800:1005::2/64    #为网卡eth0配置IPv6地址
+ifconfig eth0 del 33ffe:3240:800:1005::2/64    #为网卡eth0删除IPv6地址
+</code></pre>
+<p><strong>用 ifconfig 修改 MAC 地址:</strong></p>
+<pre><code>ifconfig eth0 hw ether 00:AA:BB:CC:dd:EE
+</code></pre>
+<p><strong>配置 IP 地址:</strong></p>
+<pre><code>[root@localhost ~]# ifconfig eth0 192.168.2.10
+[root@localhost ~]# ifconfig eth0 192.168.2.10 netmask 255.255.255.0
+[root@localhost ~]# ifconfig eth0 192.168.2.10 netmask 255.255.255.0 broadcast 192.168.2.255
+</code></pre>
+<p><strong>启用和关闭arp协议:</strong></p>
+<pre><code>ifconfig eth0 arp    #开启网卡eth0 的arp协议
+ifconfig eth0 -arp   #关闭网卡eth0 的arp协议
+</code></pre>
+<p><strong>设置最大传输单元:</strong></p>
+<pre><code>ifconfig eth0 mtu 1500    #设置能通过的最大数据包大小为 1500 bytes
+</code></pre>
+<h3>3.2 查看网卡信息</h3>
+<p>在一台 ubuntu 上执行 <code>ifconfig -a</code></p>
+<pre><code class="language-shell">ubuntu@VM-30-130-ubuntu:~$ ifconfig -a
+eth0      Link encap:Ethernet  HWaddr 52:54:00:a9:5f:ae
+          inet addr:10.154.30.130  Bcast:10.154.63.255  Mask:255.255.192.0
+          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
+          RX packets:149673 errors:0 dropped:0 overruns:0 frame:0
+          TX packets:152271 errors:0 dropped:0 overruns:0 carrier:0
+          collisions:0 txqueuelen:1000
+          RX bytes:15205083 (15.2 MB)  TX bytes:21386362 (21.3 MB)
+
+lo        Link encap:Local Loopback
+          inet addr:127.0.0.1  Mask:255.0.0.0
+          UP LOOPBACK RUNNING  MTU:65536  Metric:1
+          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
+          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
+          collisions:0 txqueuelen:1
+          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
+          
+docker0   Link encap:Ethernet  HWaddr 02:42:58:45:c1:15
+          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
+          UP BROADCAST MULTICAST  MTU:1500  Metric:1
+          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
+          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
+          collisions:0 txqueuelen:0
+          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
+
+tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+          UP POINTOPOINT NOARP MULTICAST  MTU:1500  Metric:1
+          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
+          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
+          collisions:0 txqueuelen:100
+          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
+</code></pre>
+<p>为了防止黑客对我的 Linux 发起攻击,我还是偷偷对 IP 做了一点“改造”,请不要为难一个趁着打折+组团购买廉价云服务器的小伙子。对于部分网卡的详细解读:</p>
+<p>eth0 表示第一块网卡, 其中 HWaddr 表示网卡的物理地址,可以看到目前这个网卡的物理地址(MAC 地址)是 02:42:38:52:70:54</p>
+<p>inet addr 用来表示网卡的 IP 地址,此网卡的 IP 地址是 10.154.30.130,广播地址, Bcast: 172.18.255.255,掩码地址 Mask:255.255.0.0</p>
+<p>lo 是表示主机的回环地址,这个一般是用来测试一个网络程序,但又不想让局域网或外网的用户能够查看,只能在此台主机上运行和查看所用的网络接口。比如把 HTTPD 服务器的指定到回坏地址,在浏览器输入 127.0.0.1 就能看到你所架构的 WEB 网站了。但只有你能看得到,局域网的其它主机或用户则无从知晓。</p>
+<p>第一行:连接类型:Ethernet(以太网)HWaddr(硬件mac地址)</p>
+<p>第二行:网卡的IP地址、子网、掩码</p>
+<p>第三行:UP(代表网卡开启状态)RUNNING(代表网卡的网线被接上)MULTICAST(支持组播)MTU:1500(最大传输单元):1500字节(ifconfig 不加 -a 则无法看到 DOWN 的网卡)</p>
+<p>第四、五行:接收、发送数据包情况统计</p>
+<p>第七行:接收、发送数据字节数统计信息。</p>
+<p>紧接着的两个网卡 docker0,tun0 是怎么出来的呢?我在我的 ubuntu 上装了 docker 和 openvpn。这两个东西应该是日常干扰我们做服务注册时的罪魁祸首了,当然,也有可能存在 eth1 这样的第二块网卡。ifconfig -a 看到的东西就对应了 JDK 的 api :<code>NetworkInterface.getNetworkInterfaces()</code> 。我们简单做个总结,大致有三个干扰因素</p>
+<ul>
+<li>以 docker 网桥为首的虚拟网卡地址,毕竟这东西这么火,怎么也得单独列出来吧?</li>
+<li>以 TUN/TAP 为代表的虚拟网卡地址,多为 VPN 场景</li>
+<li>以 eth1 为代表的多网卡场景,有钱就可以装多网卡了!</li>
+</ul>
+<p>我们后续的篇幅将针对这些场景做分别的介绍,力求让大家没吃过猪肉,起码看下猪怎么跑的。</p>
+<h2>4 干扰因素一:Docker 网桥</h2>
+<p>熟悉 docker 的朋友应该知道 docker 会默认创建一个 docker0 的网桥,供容器实例连接。如果嫌默认的网桥不够直观,我们可以使用 bridge 模式自定义创建一个新的网桥:</p>
+<pre><code class="language-shell">ubuntu@VM-30-130-ubuntu:~$ docker network create kirito-bridge
+a38696dbbe58aa916894c674052c4aa6ab32266dcf6d8111fb794b8a344aa0d9
+ubuntu@VM-30-130-ubuntu:~$ ifconfig -a
+br-a38696dbbe58 Link encap:Ethernet  HWaddr 02:42:6e:aa:fd:0c
+          inet addr:172.19.0.1  Bcast:172.19.255.255  Mask:255.255.0.0
+          UP BROADCAST MULTICAST  MTU:1500  Metric:1
+          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
+          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
+          collisions:0 txqueuelen:0
+          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
+</code></pre>
+<p>使用 docker network 指令创建网桥之后,自动创建了对应的网卡,我只给出了 <code>ifconfig -a</code> 的增量返回部分,可以看出多了一个 br-a38696dbbe58 的网卡。</p>
+<p>我有意区分了“网桥”和“网卡”,可以使用 bridge-utils/brctl 来查看网桥信息:</p>
+<pre><code class="language-shell">ubuntu@VM-30-130-ubuntu:~$ sudo brctl show
+bridge name	bridge id		STP enabled	interfaces
+br-a38696dbbe58		8000.02426eaafd0c	no
... 43890 lines suppressed ...