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/incubator-dubbo-website.git
The following commit(s) were added to refs/heads/asf-site by this push:
new c60d1a7 Add 2.7.0 user docs
c60d1a7 is described below
commit c60d1a776100eb10e6fbac5584e179d4ed2c06fb
Author: ken.lj <[email protected]>
AuthorDate: Mon Jan 28 11:59:00 2019 +0800
Add 2.7.0 user docs
---
... to 2.7.x.md => Guides-for-upgrading-to-27x.md} | 20 +-
blog/zh-cn/download.md | 4 +-
docs/zh-cn/user/SUMMARY.md | 7 +-
docs/zh-cn/user/configuration/annotation.md | 122 ++++----
docs/zh-cn/user/configuration/config-center.md | 153 ++++++++++
.../configuration/configuration-load-process.md | 54 +---
docs/zh-cn/user/configuration/index.md | 1 -
.../{properties.md => properties deprecated.md} | 0
docs/zh-cn/user/configuration/xml.md | 42 ++-
.../{async-call.md => async-call-deprecated.md} | 0
docs/zh-cn/user/demos/async-call.md | 131 +++++++--
docs/zh-cn/user/demos/async-execute-on-provider.md | 95 ++++++
.../{config-rule.md => config-rule-deprecated.md} | 0
docs/zh-cn/user/demos/config-rule.md | 190 +++++++++---
...{routing-rule.md => routing-rule deprecated.md} | 0
docs/zh-cn/user/demos/routing-rule.md | 317 ++++++++++++---------
docs/zh-cn/user/version-upgrading.md | 5 +
img/apollo-configcenter-application.jpg | Bin 0 -> 156394 bytes
img/apollo-configcenter-dubbo.jpg | Bin 0 -> 198809 bytes
img/apollo-configcenter-enhance.jpg | Bin 0 -> 244562 bytes
img/apollo-configcenter-governance.jpg | Bin 0 -> 213599 bytes
img/zk-configcenter-governance.jpg | Bin 0 -> 301240 bytes
img/zk-configcenter.jpg | Bin 0 -> 247992 bytes
23 files changed, 807 insertions(+), 334 deletions(-)
diff --git a/blog/zh-cn/Guides for upgrading to 2.7.x.md
b/blog/zh-cn/Guides-for-upgrading-to-27x.md
similarity index 94%
rename from blog/zh-cn/Guides for upgrading to 2.7.x.md
rename to blog/zh-cn/Guides-for-upgrading-to-27x.md
index 0452cd0..9578e4b 100644
--- a/blog/zh-cn/Guides for upgrading to 2.7.x.md
+++ b/blog/zh-cn/Guides-for-upgrading-to-27x.md
@@ -139,7 +139,7 @@ dubbo.protocol.port=20880
- 条件路由
- ```yaml
+ ```yaml
---
scope: application
force: true
@@ -147,8 +147,8 @@ dubbo.protocol.port=20880
enabled: true
key: governance-conditionrouter-consumer
conditions:
- - method=sayHello => address=*:20880
- - method=sayHi => address=*:20881
+ - application=app1 => address=*:20880
+ - application=app2 => address=*:20881
...
```
@@ -156,17 +156,17 @@ dubbo.protocol.port=20880
- 标签路由
- ```yaml
+ ```yaml
---
force: false
runtime: true
enabled: true
key: governance-tagrouter-provider
tags:
- - name: tag1
- addresses: ["127.0.0.1:20880"]
- - name: tag2
- addresses: ["127.0.0.1:20881"]
+ - name: tag1
+ addresses: ["127.0.0.1:20880"]
+ - name: tag2
+ addresses: ["127.0.0.1:20881"]
...
```
@@ -189,9 +189,9 @@ dubbo.protocol.port=20880
-关于治理规则更多详细说明,请参考[路由规则]()和[覆盖规则]()用户文档。
+关于治理规则更多详细说明,请参考[路由规则](/docs/zh-cn/user/demos/routing-rule.md)和[覆盖规则](/docs/zh-cn/user/demos/config-rule.md)用户文档。
-也可继续了解[使用示例]()。
+也可继续了解[使用示例](https://github.com/apache/incubator-dubbo-samples/tree/samples-for-2.7.0-SNAPSHOT/dubbo-samples-governance)。
diff --git a/blog/zh-cn/download.md b/blog/zh-cn/download.md
index 37daac7..c6d493f 100644
--- a/blog/zh-cn/download.md
+++ b/blog/zh-cn/download.md
@@ -1,8 +1,8 @@
# 下载中心
-## [Dubbo-RPC](https://github.com/apache/incubator-dubbo)
+## 版本与升级
-> Release Notes: https://github.com/apache/incubator-dubbo/releases
+请点击了解各[版本详情和升级注意事项](../../docs/zh-cn/user/version-upgrading.md)
### 2.6.5 (2018-11-23)
diff --git a/docs/zh-cn/user/SUMMARY.md b/docs/zh-cn/user/SUMMARY.md
index 0cc3f96..b484b8f 100644
--- a/docs/zh-cn/user/SUMMARY.md
+++ b/docs/zh-cn/user/SUMMARY.md
@@ -9,9 +9,9 @@
* [4 成熟度](./maturity.md)
* [5 配置](./configuration/index.md)
* [5.1 XML 配置](./configuration/xml.md)
- * [5.2 属性配置](./configuration/properties.md)
- * [5.3 API 配置](./configuration/api.md)
- * [5.4 注解配置](./configuration/annotation.md)
+ * [5.2 API 配置](./configuration/api.md)
+ * [5.3 Annotation 配置](./configuration/annotation.md)
+ * [5.4 配置加载流程](./configuration/configuration-load-process.md)
* [6 示例](./demos/index.md)
* [6.1 启动时检查](./demos/preflight-check.md)
* [6.2 集群容错](./demos/fault-tolerent-strategy.md)
@@ -95,5 +95,6 @@
* [16 容量规划](./capacity-plan.md)
* [17 性能测试报告](./perf-test.md)
* [18 测试覆盖率报告](./coveragence.md)
+* [19 版本与升级](./version-upgrading.md)
diff --git a/docs/zh-cn/user/configuration/annotation.md
b/docs/zh-cn/user/configuration/annotation.md
index bd9b030..fe9ad07 100644
--- a/docs/zh-cn/user/configuration/annotation.md
+++ b/docs/zh-cn/user/configuration/annotation.md
@@ -1,50 +1,40 @@
# 注解配置
-需要 `2.5.7` 及以上版本支持
+需要 `2.6.3` 及以上版本支持
+点此查看[完整示例](https://github.com/apache/incubator-dubbo-samples/tree/master/dubbo-samples-annotation)
## 服务提供方
### `Service`注解暴露服务
```java
-import org.apache.dubbo.config.annotation.Service;
-
-@Service(timeout = 5000)
-public class AnnotateServiceImpl implements AnnotateService {
- // ...
+@Service
+public class AnnotationServiceImpl implements AnnotationService {
+ @Override
+ public String sayHello(String name) {
+ return "annotation: hello, " + name;
+ }
}
```
-### javaconfig形式配置公共模块
-
-```java
-@Configuration
-public class DubboConfiguration {
-
- @Bean
- public ApplicationConfig applicationConfig() {
- ApplicationConfig applicationConfig = new ApplicationConfig();
- applicationConfig.setName("provider-test");
- return applicationConfig;
- }
-
- @Bean
- public RegistryConfig registryConfig() {
- RegistryConfig registryConfig = new RegistryConfig();
- registryConfig.setAddress("zookeeper://127.0.0.1:2181");
- registryConfig.setClient("curator");
- return registryConfig;
- }
-}
+### 增加应用共享配置
+
+```properties
+# dubbo-provider.properties
+dubbo.application.name=annotation-provider
+dubbo.registry.address=zookeeper://127.0.0.1:2181
+dubbo.protocol.name=dubbo
+dubbo.protocol.port=20880
```
-### 指定dubbo扫描路径
+### 指定Spring扫描路径
```java
-@SpringBootApplication
-@DubboComponentScan(basePackages = "org.apache.dubbo.test.service.impl")
-public class ProviderTestApp {
- // ...
+@Configuration
+@EnableDubbo(scanBasePackages =
"org.apache.dubbo.samples.simple.annotation.impl")
+@PropertySource("classpath:/spring/dubbo-provider.properties")
+static public class ProviderConfiguration {
+
}
```
@@ -54,63 +44,49 @@ public class ProviderTestApp {
### `Reference`注解引用服务
```java
-public class AnnotationConsumeService {
+@Component("annotationAction")
+public class AnnotationAction {
- @org.apache.dubbo.config.annotation.Reference
- public AnnotateService annotateService;
+ @Reference
+ private AnnotationService annotationService;
- // ...
+ public String doSayHello(String name) {
+ return annotationService.sayHello(name);
+ }
}
```
-### javaconfig形式配置公共模块
+### 增加应用共享配置
-```java
-@Configuration
-public class DubboConfiguration {
+```properties
+# dubbo-consumer.properties
+dubbo.application.name=annotation-consumer
+dubbo.registry.address=zookeeper://127.0.0.1:2181
+dubbo.consumer.timeout=3000
+```
- @Bean
- public ApplicationConfig applicationConfig() {
- ApplicationConfig applicationConfig = new ApplicationConfig();
- applicationConfig.setName("consumer-test");
- return applicationConfig;
- }
+### 指定Spring扫描路径
- @Bean
- public ConsumerConfig consumerConfig() {
- ConsumerConfig consumerConfig = new ConsumerConfig();
- consumerConfig.setTimeout(3000);
- return consumerConfig;
- }
+```java
+@Configuration
+@EnableDubbo(scanBasePackages =
"org.apache.dubbo.samples.simple.annotation.action")
+@PropertySource("classpath:/spring/dubbo-consumer.properties")
+@ComponentScan(value = {"org.apache.dubbo.samples.simple.annotation.action"})
+static public class ConsumerConfiguration {
- @Bean
- public RegistryConfig registryConfig() {
- RegistryConfig registryConfig = new RegistryConfig();
- registryConfig.setAddress("zookeeper://127.0.0.1:2181");
- registryConfig.setClient("curator");
- return registryConfig;
- }
}
```
-### 指定dubbo扫描路径
+### 调动服务
```java
-@SpringBootApplication
-@DubboComponentScan(basePackages = "org.apache.dubbo.test.service")
-public class ConsumerTestApp {
- // ...
+public static void main(String[] args) throws Exception {
+ AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext(ConsumerConfiguration.class);
+ context.start();
+ final AnnotationAction annotationAction = (AnnotationAction)
context.getBean("annotationAction");
+ String hello = annotationAction.doSayHello("world");
}
-```
-
-## 注意
-
-如果你曾使用旧版annotation配置,请删除所有相关配置,我们将在下个版本删除所有旧版配置项。
-
-```xml
-<dubbo:annotation package="org.apache.dubbo.test.service" />
```
-
diff --git a/docs/zh-cn/user/configuration/config-center.md
b/docs/zh-cn/user/configuration/config-center.md
new file mode 100644
index 0000000..73259b6
--- /dev/null
+++ b/docs/zh-cn/user/configuration/config-center.md
@@ -0,0 +1,153 @@
+# 动态配置中心
+
+配置中心(v2.7.0)在Dubbo中承担两个职责:
+
+1. 外部化配置。启动配置的集中式存储 (简单理解为dubbo.properties的外部化存储)。
+2. 服务治理。服务治理规则的存储与通知。
+
+
+
+启用动态配置(以Zookeeper为例):
+
+```xml
+<dubbo:config-center address="zookeeper://127.0.0.1:2181"/>
+```
+
+或者
+
+```properties
+dubbo.configCenter.address=zookeeper://127.0.0.1:2181
+```
+
+或者
+
+```java
+ConfigCenterConfig configCenter = new ConfigCenterConfig();
+configCenter.setAddress("zookeeper://127.0.0.1:2181");
+```
+
+>
为了兼容2.6.x版本配置,在使用Zookeeper作为注册中心,且没有显示配置配置中心的情况下,Dubbo框架会默认将此Zookeeper用作配置中心,但将只作服务治理用途。
+
+
+## 外部化配置
+
+外部化配置目的之一是实现配置的集中式管理,这部分业界已经有很多成熟的专业配置系统如Apollo,
Nacos等,Dubbo所做的主要是保证能配合这些系统正常工作。
+
+外部化配置和其他本地配置在内容和格式上并无区别,可以简单理解为`dubbo.properties`的外部化存储,配置中心更适合将一些公共配置如注册中心、元数据中心配置等抽取以便做集中管理。
+
+```properties
+# 将注册中心地址、元数据中心地址等配置集中管理,可以做到统一环境、减少开发侧感知。
+dubbo.registry.address=zookeeper://127.0.0.1:2181
+dubbo.registry.simplified=true
+
+dubbo.metadataReport.address=zookeeper://127.0.0.1:2181
+
+dubbo.protocol.name=dubbo
+dubbo.protocol.port=20880
+
+dubbo.application.qos.port=33333
+```
+
+
+- 优先级
+
+外部化配置默认较本地配置有更高的优先级,因此这里配置的内容会覆盖本地配置值,关于[各配置形式间的覆盖关系](./configuration-load-process.md)有单独一章说明,你也可通过以下选项调整配置中心的优先级:
+
+ ```properties
+ -Ddubbo.configCenter.highestPriority=false
+ ```
+
+- 作用域
+
+外部化配置有全局和应用两个级别,全局配置是所有应用共享的,应用级配置是由每个应用自己维护且只对自身可见的。
+
+
+当前已支持的扩展实现有Zookeeper、Apollo。
+
+
+#### Zookeeper
+
+```xml
+<dubbo:config-center address="zookeeper://127.0.0.1:2181"/>
+```
+
+
+
+默认所有的配置都存储在`/dubbo/config`节点,具体节点结构图如下:
+
+
+
+- namespace,用于不同配置的环境隔离。
+- config,Dubbo约定的固定节点,不可更改,所有配置和服务治理规则都存储在此节点下。
+- dubbo/application,分别用来隔离全局配置、应用级别配置:dubbo是默认group值,application对应应用名
+- dubbo.properties,此节点的node value存储具体配置内容
+
+
+
+#### Apollo
+
+```xml
+<dubbo:config-center protocol="apollo" address="127.0.0.1:2181"/>
+```
+
+Apollo中的一个核心概念是命名空间 -
namespace(和上面zookeeper的namespace概念不同),在这里全局和应用级别配置就是通过命名空间来区分的。
+
+默认情况下,Dubbo会从名叫`dubbo`的命名空间中读取全局配置(`<dubbo:config-center namespace="your
namespace">`)
+
+
+
+而应用自有的配置,会从`application`命名空间读取
+
+
+
+
+
+> 注意:当前dubbo.properties是作为一个key存储在Apollo
namespace中,为更好的适应Apollo的设计理念,在接下来的版本中可能会调整为
+>
+> 
+
+
+
+#### 自己加载外部化配置
+
+所谓Dubbo对配置中心的支持,本质上就是把`.properties`从远程拉取到本地,然后和本地的配置做一次融合。理论上只要Dubbo框架能拿到需要的配置就可以正常的启动,它并不关心这些配置是自己加载到的还是应用直接塞给它的,所以Dubbo还提供了以下API,让用户将自己组织好的配置塞给Dubbo框架(配置加载的过程是用户要完成的),这样Dubbo框架就不再直接和Apollo或Zookeeper做读取配置交互。
+
+```java
+// 应用自行加载配置
+Map<String, String> dubboConfigurations = new HashMap<>();
+dubboConfigurations.put("dubbo.registry.address",
"zookeeper://127.0.0.1:2181");
+dubboConfigurations.put("dubbo.registry.simplified", "true");
+
+//将组织好的配置塞给Dubbo框架
+ConfigCenterConfig configCenter = new ConfigCenterConfig();
+configCenter.setExternalConfig(dubboConfigurations);
+```
+
+
+
+## 服务治理
+
+#### Zookeeper
+
+默认节点结构:
+
+
+
+- namespace,用于不同配置的环境隔离。
+- config,Dubbo约定的固定节点,不可更改,所有配置和服务治理规则都存储在此节点下。
+- dubbo,所有服务治理规则都是全局性的,dubbo为默认节点
+- configurators/tag-router/condition-router,不同的服务治理规则类型,node value存储具体规则内容
+
+
+
+#### Apollo
+
+所有的服务治理规则都是全局性的,默认从公共命名空间`dubbo`读取和订阅:
+
+
+
+不同的规则以不同的key后缀区分:
+
+- configurators,[覆盖规则]()
+- tag-router,[标签路由]()
+- condition-router,[条件路由
\ No newline at end of file
diff --git a/blog/zh-cn/Configuration Conclude.md
b/docs/zh-cn/user/configuration/configuration-load-process.md
similarity index 66%
rename from blog/zh-cn/Configuration Conclude.md
rename to docs/zh-cn/user/configuration/configuration-load-process.md
index 9a3879c..a21e0bb 100644
--- a/blog/zh-cn/Configuration Conclude.md
+++ b/docs/zh-cn/user/configuration/configuration-load-process.md
@@ -1,12 +1,12 @@
-# 配置方式总结
+# 配置加载流程
-我们这篇文章主要讲在**应用启动阶段,Dubbo框架如何将所需要的配置采集起来**(包括应用配置、注册中心配置、服务配置等),以完成服务的暴露和引用流程。
+此篇文档主要讲在**应用启动阶段,Dubbo框架如何将所需要的配置采集起来**(包括应用配置、注册中心配置、服务配置等),以完成服务的暴露和引用流程。
-根据驱动方式的不同(比如Spring或裸API编程)配置形式上肯定会有所差异,这个我们接下来会对[每种方式分别展开介绍](#几种编程配置方式)。除了外围驱动方式上的差异,Dubbo的配置读取总体上遵循了以下几个原则:
+根据驱动方式的不同(比如Spring或裸API编程)配置形式上肯定会有所差异,具体请参考[XML配置](./xml.md)、[Annotation配置](./annotation.md)、[API配置](./api.md)三篇文档。除了外围驱动方式上的差异,Dubbo的配置读取总体上遵循了以下几个原则:
-1. Dubbo支持了多层级的配置,并预定按优先级自动实现配置间的覆盖,最终被汇总到数据总线URL驱动后续的服务暴露、引用等流程。
+1. Dubbo支持了多层级的配置,并按预定优先级自动实现配置间的覆盖,最终所有配置汇总到数据总线URL后驱动后续的服务暴露、引用等流程。
2.
ApplicationConfig、ServiceConfig、ReferenceConfig可以被理解成配置来源的一种,是直接面向用户编程的配置采集方式。
-3. 配置格式以Properties为主,在key的命名上有一套自己的[规范](#配置格式)
+3. 配置格式以Properties为主,在配置内容上遵循约定的`path-based`的命名[规范](#配置格式)
@@ -25,42 +25,7 @@

-
-
-### 外部化配置
-
-外部化配置即Config
Center是2.7.0中新引入的一种配置源,目的是能实现配置的集中式管理,对于配置集中管理业界已经有很多成熟的专业配置系统如Apollo,
Nacos等,Dubbo所做的只是保证能配合这些系统正常工作。
-
-2.7.0版本开始支持`Zookeeper`、`Apollo`两种配置存储。
-
-以Zookeeper为例,外部化配置就是存储在`/dubbo/config/dubbo/dubbo.properties`路径下的`.properties`文件:
-
-```properties
-# 将注册中心地址、元数据中心地址等配置集中管理,可以做到统一环境、减少开发侧感知。
-dubbo.registry.address=zookeeper://127.0.0.1:2181
-dubbo.registry.simplified=true
-
-dubbo.metadataReport.address=zookeeper://127.0.0.1:2181
-
-dubbo.protocol.name=dubbo
-dubbo.protocol.port=20880
-
-dubbo.application.qos.port=33333
-```
-
-
-
-所谓Dubbo对这些配置中心的支持,本质上就是把`.properties`从远程拉取到本地,然后和本地的配置做一次融合。所以理论上只要Dubbo框架能拿到需要的配置就可以正常的工作,所以Dubbo还提供了以下API,让用户将自己组织好的配置塞给Dubbo框架(至于配置从哪里来是用户要完成的事情),这样Dubbo框架就不再直接和Apollo或Zookeeper做读取配置交互。
-
-```java
-Map<String, String> dubboConfigurations = new HashMap<>();
-dubboConfigurations.put("dubbo.registry.address",
"zookeeper://127.0.0.1:2181");
-dubboConfigurations.put("dubbo.registry.simplified", "true");
-
-ConfigCenterConfig configCenter = new ConfigCenterConfig();
-configCenter.setExternalConfig(dubboConfigurations);
-```
-
+点此查看[外部化配置详情](./config-center.md)
## 配置格式
@@ -105,7 +70,14 @@ dubbo.protocols.hessian.name=hessian
dubbo.protocols.hessian.port=8089
```
+- 扩展配置
+```properties
+dubbo.application.parameters.item1=value1
+dubbo.application.parameters.item2=value2
+dubbo.registry.parameters.item3=value3
+dubbo.reference.org.apache.dubbo.samples.api.DemoService.parameters.item4=value4
+```
## 几种编程配置方式
diff --git a/docs/zh-cn/user/configuration/index.md
b/docs/zh-cn/user/configuration/index.md
deleted file mode 100644
index fa1492d..0000000
--- a/docs/zh-cn/user/configuration/index.md
+++ /dev/null
@@ -1 +0,0 @@
-# 配置
diff --git a/docs/zh-cn/user/configuration/properties.md
b/docs/zh-cn/user/configuration/properties deprecated.md
similarity index 100%
rename from docs/zh-cn/user/configuration/properties.md
rename to docs/zh-cn/user/configuration/properties deprecated.md
diff --git a/docs/zh-cn/user/configuration/xml.md
b/docs/zh-cn/user/configuration/xml.md
index ea55c79..3d69fa7 100644
--- a/docs/zh-cn/user/configuration/xml.md
+++ b/docs/zh-cn/user/configuration/xml.md
@@ -2,20 +2,34 @@
有关 XML 的详细配置项,请参见:[配置参考手册](../references/xml/introduction.md)。如果不想使用 Spring
配置,而希望通过 API
的方式进行调用,请参见:[API配置](./api.md)。想知道如何使用配置,请参见:[快速启动](../quick-start.md)。
+请在此查看文档描述的[完整示例](https://github.com/apache/incubator-dubbo-samples/tree/master/dubbo-samples-basic)
## provider.xml 示例
``` xml
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
- xsi:schemaLocation="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">
- <dubbo:application name="hello-world-app" />
- <dubbo:registry address="multicast://224.5.6.7:1234" />
- <dubbo:protocol name="dubbo" port="20880" />
- <dubbo:service interface="org.apache.dubbo.demo.DemoService"
ref="demoServiceLocal" />
- <dubbo:reference id="demoServiceRemote"
interface="org.apache.dubbo.demo.DemoService" />
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
+ xmlns="http://www.springframework.org/schema/beans"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://dubbo.apache.org/schema/dubbo
http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
+ <dubbo:application name="demo-provider"/>
+ <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
+ <dubbo:protocol name="dubbo" port="20890"/>
+ <bean id="demoService"
class="org.apache.dubbo.samples.basic.impl.DemoServiceImpl"/>
+ <dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService"
ref="demoService"/>
+</beans>
+```
+
+## consumer.xml示例
+```xml
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
+ xmlns="http://www.springframework.org/schema/beans"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://dubbo.apache.org/schema/dubbo
http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
+ <dubbo:application name="demo-consumer"/>
+ <dubbo:registry group="aaa" address="zookeeper://127.0.0.1:2181"/>
+ <dubbo:reference id="demoService" check="false"
interface="org.apache.dubbo.samples.basic.api.DemoService"/>
</beans>
```
@@ -58,9 +72,9 @@
`<dubbo:argument/>` | 参数配置 | 用于指定方法参数配置
-## 配置覆盖关系
+## 不同粒度配置的覆盖关系
-以 timeout 为例,显示了配置的查找顺序,其它 retries, loadbalance, actives 等类似:
+以 timeout 为例,下图显示了配置的查找顺序,其它 retries, loadbalance, actives 等类似:
* 方法级优先,接口级次之,全局配置再次之。
* 如果级别一样,则消费方优先,提供方次之。
@@ -69,9 +83,9 @@

-建议由服务提供方设置超时,因为一个方法需要执行多长时间,服务提供方更清楚,如果一个消费方同时引用多个服务,就不需要关心每个服务的超时设置。
+(建议由服务提供方设置超时,因为一个方法需要执行多长时间,服务提供方更清楚,如果一个消费方同时引用多个服务,就不需要关心每个服务的超时设置)。
-理论上 ReferenceConfig 的非服务标识配置,在 ConsumerConfig,ServiceConfig, ProviderConfig
均可以缺省配置。
+理论上 ReferenceConfig
中除了`interface`这一项,其他所有配置项都可以缺省不配置,框架会自动使用ConsumerConfig,ServiceConfig,
ProviderConfig等提供的缺省配置。
[^1]: `2.1.0` 开始支持,注意声明:`xmlns:p="http://www.springframework.org/schema/p"`
[^2]: 引用缺省是延迟初始化的,只有引用被注入到其它 Bean,或被 `getBean()`
获取,才会初始化。如果需要饥饿加载,即没有人引用也立即生成动态代理,可以配置:`<dubbo:reference ... init="true" />`
diff --git a/docs/zh-cn/user/demos/async-call.md
b/docs/zh-cn/user/demos/async-call-deprecated.md
similarity index 100%
copy from docs/zh-cn/user/demos/async-call.md
copy to docs/zh-cn/user/demos/async-call-deprecated.md
diff --git a/docs/zh-cn/user/demos/async-call.md
b/docs/zh-cn/user/demos/async-call.md
index b15cb58..b42a182 100644
--- a/docs/zh-cn/user/demos/async-call.md
+++ b/docs/zh-cn/user/demos/async-call.md
@@ -1,17 +1,56 @@
# 异步调用
-基于 NIO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小。 [^1]
+从v2.7.0开始,Dubbo的所有异步编程接口开始以[CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html)为基础
+
+基于 NIO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小。

+
+## 使用CompletableFuture签名的接口
+
+需要服务提供者事先定义CompletableFuture签名的服务,具体参见[服务端异步执行](./async-execute-on-provider)接口定义:
+
+```java
+public interface AsyncService {
+ CompletableFuture<String> sayHello(String name);
+}
+```
+
+注意接口的返回类型是`CompletableFuture<String>`。
+
+XML引用服务:
+
+```xml
+<dubbo:reference id="asyncService" timeout="10000"
interface="com.alibaba.dubbo.samples.async.api.AsyncService"/>
+```
+
+调用远程服务:
+
+```java
+// 调用直接返回CompletableFuture
+CompletableFuture<String> future = asyncService.sayHello("async call request");
+// 增加回调
+future.whenComplete((v, t) -> {
+ if (t != null) {
+ t.printStackTrace();
+ } else {
+ System.out.println("Response: " + v);
+ }
+});
+// 早于结果输出
+System.out.println("Executed before response return.");
+```
+
+
+
+## 使用RpcContext
+
在 consumer.xml 中配置:
```xml
-<dubbo:reference id="fooService" interface="com.alibaba.foo.FooService">
- <dubbo:method name="findFoo" async="true" />
-</dubbo:reference>
-<dubbo:reference id="barService" interface="com.alibaba.bar.BarService">
- <dubbo:method name="findBar" async="true" />
+<dubbo:reference id="asyncService"
interface="org.apache.dubbo.samples.governance.api.AsyncService">
+ <dubbo:method name="sayHello" async="true" />
</dubbo:reference>
```
@@ -19,29 +58,68 @@
```java
// 此调用会立即返回null
-fooService.findFoo(fooId);
-// 拿到调用的Future引用,当结果返回后,会被通知和设置到此Future
-Future<Foo> fooFuture = RpcContext.getContext().getFuture();
-
-// 此调用会立即返回null
-barService.findBar(barId);
+asyncService.sayHello("world");
// 拿到调用的Future引用,当结果返回后,会被通知和设置到此Future
-Future<Bar> barFuture = RpcContext.getContext().getFuture();
-
-// 此时findFoo和findBar的请求同时在执行,客户端不需要启动多线程来支持并行,而是借助NIO的非阻塞完成
-
-// 如果foo已返回,直接拿到返回值,否则线程wait住,等待foo返回后,线程会被notify唤醒
-Foo foo = fooFuture.get();
-// 同理等待bar返回
-Bar bar = barFuture.get();
-
-// 如果foo需要5秒返回,bar需要6秒返回,实际只需等6秒,即可获取到foo和bar,进行接下来的处理。
+CompletableFuture<String> helloFuture =
RpcContext.getContext().getCompletableFuture();
+// 为Future添加回调
+helloFuture.whenComplete((retValue, exception) -> {
+ if (exception == null) {
+ System.out.println(retValue);
+ } else {
+ exception.printStackTrace();
+ }
+});
```
-你也可以设置是否等待消息发出: [^2]
+或者,你也可以这样做异步调用:
+
+```java
+CompletableFuture<String> future = RpcContext.getContext().asyncCall(
+ () -> {
+ asyncService.sayHello("oneway call request1");
+ }
+);
+
+future.get();
+```
+
+
+
+## 重载服务接口
+
+如果你只有这样的同步服务定义,而又不喜欢RpcContext的异步使用方式。
+
+```java
+public interface GreetingsService {
+ String sayHi(String name);
+}
+```
+
+那还有一种方式,就是利用Java 8提供的default接口实现,重载一个带有带有CompletableFuture签名的方法。
+
+有两种方式来实现:
+
+1. 提供方或消费方自己修改接口签名
+
+```java
+public interface GreetingsService {
+ String sayHi(String name);
+
+ // AsyncSignal is totally optional, you can use any parameter type as long
as java allows your to do that.
+ default CompletableFuture<String> sayHi(String name, AsyncSignal signal) {
+ return CompletableFuture.completedFuture(sayHi(name));
+ }
+}
+```
+
+1. Dubbo官方提供compiler
hacker,编译期自动重写同步方法,请[在此](https://github.com/dubbo/dubbo-async-processor#compiler-hacker-processer)讨论和跟进具体进展。
+
+
+
+你也可以设置是否等待消息发出: [^1]
-* `sent="true"` 等待消息发出,消息发送失败将抛出异常。
-* `sent="false"` 不等待消息发出,将消息放入 IO 队列,即刻返回。
+- `sent="true"` 等待消息发出,消息发送失败将抛出异常。
+- `sent="false"` 不等待消息发出,将消息放入 IO 队列,即刻返回。
```xml
<dubbo:method name="findFoo" async="true" sent="true" />
@@ -53,5 +131,4 @@ Bar bar = barFuture.get();
<dubbo:method name="findFoo" async="true" return="false" />
```
-[^1]: `2.0.6` 及其以上版本支持
-[^2]: 异步总是不等待返回
\ No newline at end of file
+[^1]: 异步总是不等待返回
\ No newline at end of file
diff --git a/docs/zh-cn/user/demos/async-execute-on-provider.md
b/docs/zh-cn/user/demos/async-execute-on-provider.md
new file mode 100644
index 0000000..1c0374d
--- /dev/null
+++ b/docs/zh-cn/user/demos/async-execute-on-provider.md
@@ -0,0 +1,95 @@
+# 异步执行
+
+Provider端异步执行将阻塞的业务从Dubbo内部线程池切换到业务自定义线程,避免Dubbo线程池的过度占用,有助于避免不同服务间的互相影响。异步执行无益于节省资源或提升RPC响应性能,因为如果业务执行需要阻塞,则始终还是要有线程来负责执行。
+
+> 注意:Provider端异步执行和Consumer端异步调用是相互独立的,你可以任意正交组合两端配置
+>
+> - Consumer同步 - Provider同步
+> - Consumer异步 - Provider同步
+> - Consumer同步 - Provider异步
+> - Consumer异步 - Provider异步
+
+
+
+## 定义CompletableFuture签名的接口
+
+服务接口定义:
+
+```java
+public interface AsyncService {
+ CompletableFuture<String> sayHello(String name);
+}
+```
+
+服务实现:
+
+```java
+public class AsyncServiceImpl implements AsyncService {
+ @Override
+ public CompletableFuture<String> sayHello(String name) {
+ RpcContext savedContext = RpcContext.getContext();
+ // 建议为supplyAsync提供自定义线程池,避免使用JDK公用线程池
+ return CompletableFuture.supplyAsync(() -> {
+ System.out.println(savedContext.getAttachment("consumer-key1"));
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return "async response from provider.";
+ });
+ }
+}
+```
+
+通过`return CompletableFuture.supplyAsync()
`,业务执行已从Dubbo线程切换到业务线程,避免了对Dubbo线程池的阻塞。
+
+
+
+## 使用AsyncContext
+
+Dubbo提供了一个类似Serverlet
3.0的异步接口`AsyncContext`,在没有CompletableFuture签名接口的情况下,也可以实现Provider端的异步执行。
+
+服务接口定义:
+
+```java
+public interface AsyncService {
+ String sayHello(String name);
+}
+```
+
+服务暴露,和普通服务完全一致:
+
+```xml
+<bean id="asyncService"
class="org.apache.dubbo.samples.governance.impl.AsyncServiceImpl"/>
+<dubbo:service
interface="org.apache.dubbo.samples.governance.api.AsyncService"
ref="asyncService"/>
+```
+
+服务实现:
+
+```java
+public class AsyncServiceImpl implements AsyncService {
+ public String sayHello(String name) {
+ final AsyncContext asyncContext = RpcContext.startAsync();
+ new Thread(() -> {
+ // 如果要使用上下文,则必须要放在第一句执行
+ asyncContext.signalContextSwitch();
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ // 写回响应
+ asyncContext.write("Hello " + name + ", response from provider.");
+ }).start();
+ return null;
+ }
+}
+```
+
+
+
+
+
+
+
diff --git a/docs/zh-cn/user/demos/config-rule.md
b/docs/zh-cn/user/demos/config-rule-deprecated.md
similarity index 100%
copy from docs/zh-cn/user/demos/config-rule.md
copy to docs/zh-cn/user/demos/config-rule-deprecated.md
diff --git a/docs/zh-cn/user/demos/config-rule.md
b/docs/zh-cn/user/demos/config-rule.md
index b3688e4..c26cb3c 100644
--- a/docs/zh-cn/user/demos/config-rule.md
+++ b/docs/zh-cn/user/demos/config-rule.md
@@ -1,48 +1,174 @@
# 配置规则
-向注册中心写入动态配置覆盖规则 [^1]。该功能通常由监控中心或治理中心的页面完成。
+查看[老版本配置规则](./config-rule deprecated.md)。
-```java
-RegistryFactory registryFactory =
ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
-Registry registry =
registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
-registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&timeout=1000"));
+覆盖规则是Dubbo设计的在无需重启应用的情况下,动态调整RPC调用行为的一种能力。2.7.0版本开始,支持从**服务**和**应用**两个粒度来调整动态配置。
+
+## 概览
+
+请在[服务治理控制台](http://47.91.207.147/#/governance/config)查看或修改覆盖规则。
+
+- 应用粒度
+
+ ```yaml
+ #
将应用demo(key:demo)在20880端口上提供(side:provider)的所有服务(scope:application)的权重修改为1000(weight:1000)。
+ ---
+ scope: application
+ key: demo
+ enabled: true
+ configs:
+ - addresses: ["0.0.0.0:20880"]
+ side: provider
+ parameters:
+ weight: 1000
+ ...
+ ```
+
+
+
+- 服务粒度
+
+ ```yaml
+ #
所有消费(side:consumer)DemoService服务(key:org.apache.dubbo.samples.governance.api.DemoService)的应用实例(addresses:[0.0.0.0]),超时时间修改为6000ms
+ ---
+ scope: service
+ key: org.apache.dubbo.samples.governance.api.DemoService
+ enabled: true
+ configs:
+ - addresses: [0.0.0.0]
+ side: consumer
+ parameters:
+ timeout: 6000
+ ...
+
+ ```
+
+
+
+## 规则详解
+
+#### 配置模板
+
+```yaml
+---
+scope: application/service
+key: app-name/group+service+version
+enabled: true
+configs:
+- addresses: ["0.0.0.0"]
+ providerAddresses: ["1.1.1.1:20880", "2.2.2.2:20881"]
+ side: consumer
+ applications/services: []
+ parameters:
+ timeout: 1000
+ cluster: failfase
+ loadbalance: random
+- addresses: ["0.0.0.0:20880"]
+ side: provider
+ applications/services: []
+ parameters:
+ threadpool: fixed
+ threads: 200
+ iothreads: 4
+ dispatcher: all
+ weight: 200
+...
```
其中:
-* `override://` 表示数据采用覆盖方式,支持 `override` 和 `absent`,可扩展,**必填**。
-* `0.0.0.0` 表示对所有 IP 地址生效,如果只想覆盖某个 IP 的数据,请填入具体 IP,**必填**。
-* `com.foo.BarService` 表示只对指定服务生效,**必填**。
-* `category=configurators` 表示该数据为动态配置类型,**必填**。
-* `dynamic=false` 表示该数据为持久数据,当注册方退出时,数据依然保存在注册中心,**必填**。
-* `enabled=true` 覆盖规则是否生效,可不填,缺省生效。
-* `application=foo` 表示只对指定应用生效,可不填,表示对所有应用生效。
-* `timeout=1000` 表示将满足以上条件的 `timeout` 参数的值覆盖为 1000。如果想覆盖其它参数,直接加在 `override` 的
URL 参数上。
+- `scope`表示配置作用范围,分别是应用(application)或服务(service)粒度。**必填**。
+- `key` 指定规则体作用在哪个服务或应用。**必填**。
+ - scope=service时,key取值为[{group}:]{service}[:{version}]的组合
+- scope=application时,key取值为application名称
+- `enabled=true` 覆盖规则是否生效,可不填,缺省生效。
+- `configs` 定义具体的覆盖规则内容,可以指定n(n>=1)个规则体。**必填**。
+ - side,
+ - applications
+ - services
+ - parameters
+ - addresses
+ - providerAddresses
+
-示例:
+
+对于绝大多数配置场景,只需要理清楚以下问题基本就知道配置该怎么写了:
+
+1. 要修改整个应用的配置还是某个服务的配置。
+
+ - 应用:`scope: application, key: app-name`(还可使用`services`指定某几个服务)。
+ - 服务:`scope: service, key:group+service+version `。
+
+2. 修改是作用到消费者端还是提供者端。
+
+ - 消费者:`side: consumer` ,作用到消费端时(你还可以进一步使用`providerAddress`,
`applications`选定特定的提供者示例或应用)。
+ - 提供者:`side: provider`。
+
+3. 配置是否只对某几个特定实例生效。
+
+ - 所有实例:`addresses: ["0.0.0.0"] `或`addresses: ["0.0.0.0:*"] `具体由side值决定。
+ - 指定实例:`addersses[实例地址列表]`。
+
+4. 要修改的属性是哪个。
+
+
+
+#### 示例
1. 禁用提供者:(通常用于临时踢除某台提供者机器,相似的,禁止消费者访问请使用路由规则)
- ```
-
override://10.20.153.10/com.foo.BarService?category=configurators&dynamic=false&disbaled=true
- ```
-
-2. 调整权重:(通常用于容量评估,缺省权重为 100)
+ ```yaml
+ ---
+ scope: application
+ key: demo-provider
+ enabled: true
+ configs:
+ - addresses: ["10.20.153.10:20880"]
+ side: provider
+ parameters:
+ disabled: true
+ ...
+ ```
+
+2. 调整权重:(通常用于容量评估,缺省权重为 200)
+
+ ```yaml
+ ---
+ scope: application
+ key: demo-provider
+ enabled: true
+ configs:
+ - addresses: ["10.20.153.10:20880"]
+ side: provider
+ parameters:
+ weight: 200
+ ...
+ ```
- ```
-
override://10.20.153.10/com.foo.BarService?category=configurators&dynamic=false&weight=200
- ```
-
3. 调整负载均衡策略:(缺省负载均衡策略为 random)
- ```
-
override://10.20.153.10/com.foo.BarService?category=configurators&dynamic=false&loadbalance=leastactive
- ```
-
+ ```yaml
+ ---
+ scope: application
+ key: demo-consumer
+ enabled: true
+ configs:
+ - side: consumer
+ parameters:
+ loadbalance: random
+ ...
+ ```
+
4. 服务降级:(通常用于临时屏蔽某个出错的非关键服务)
- ```
-
override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null
- ```
-
-[^1]: `2.2.0` 以上版本支持
\ No newline at end of file
+ ```yaml
+ ---
+ scope: service
+ key: org.apache.dubbo.samples.governance.api.DemoService
+ enabled: true
+ configs:
+ - side: consumer
+ parameters:
+ force: return null
+ ...
+ ```
\ No newline at end of file
diff --git a/docs/zh-cn/user/demos/routing-rule.md
b/docs/zh-cn/user/demos/routing-rule deprecated.md
similarity index 100%
copy from docs/zh-cn/user/demos/routing-rule.md
copy to docs/zh-cn/user/demos/routing-rule deprecated.md
diff --git a/docs/zh-cn/user/demos/routing-rule.md
b/docs/zh-cn/user/demos/routing-rule.md
index adfde20..ab27dfd 100644
--- a/docs/zh-cn/user/demos/routing-rule.md
+++ b/docs/zh-cn/user/demos/routing-rule.md
@@ -1,193 +1,248 @@
# 路由规则
-路由规则 [^1] 决定一次 dubbo 服务调用的目标服务器,分为条件路由规则和脚本路由规则,并且支持可扩展 [^2]。
+在此查看[老版本路由规则(2.6.x or before)](./routing-rule.md)
-## 写入路由规则
-向注册中心写入路由规则的操作通常由监控中心或治理中心的页面完成
-```java
-RegistryFactory registryFactory =
ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
-Registry registry =
registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
-registry.register(URL.valueOf("condition://0.0.0.0/com.foo.BarService?category=routers&dynamic=false&rule="
+ URL.encode("host = 10.20.153.10 => host = 10.20.153.11")));
-```
+路由规则在发起一次RPC调用前起到过滤目标服务器地址的作用,过滤后的地址列表,将作为消费端最终发起RPC调用的备选地址。
+
+- 条件路由。支持以服务或Consumer应用为粒度配置路由规则。
+- 标签路由。以Provider应用为粒度配置路由规则。
+
+后续我们计划在2.6.x版本的基础上继续增强脚本路由功能,老版本脚本路由规则配置方式请参见开篇链接。
+
+## 条件路由
+
+您可以随时在服务治理控制台[Dubbo-OPS](https://github.com/apache/incubator-dubbo-ops)写入路由规则
+
+### 简介
+
+- 应用粒度
+
+ ```yaml
+ # app1的消费者只能消费所有端口为20880的服务实例
+ # app2的消费者只能消费所有端口为20881的服务实例
+ ---
+ scope: application
+ force: true
+ runtime: true
+ enabled: true
+ key: governance-conditionrouter-consumer
+ conditions:
+ - application=app1 => address=*:20880
+ - application=app2 => address=*:20881
+ ...
+ ```
+
+- 服务粒度
+
+ ```yaml
+ # DemoService的sayHello方法只能消费所有端口为20880的服务实例
+ # DemoService的sayHi方法只能消费所有端口为20881的服务实例
+ ---
+ scope: service
+ force: true
+ runtime: true
+ enabled: true
+ key: org.apache.dubbo.samples.governance.api.DemoService
+ conditions:
+ - method=sayHello => address=*:20880
+ - method=sayHi => address=*:20881
+ ...
+ ```
+
+
+
+### 规则详解
-其中:
+#### 各字段含义
-* `condition://` 表示路由规则的类型,支持条件路由规则和脚本路由规则,可扩展,**必填**。
-* `0.0.0.0` 表示对所有 IP 地址生效,如果只想对某个 IP 的生效,请填入具体 IP,**必填**。
-* `com.foo.BarService` 表示只对指定服务生效,**必填**。
-* `group=foo` 对指定服务的指定group生效,不填表示对未配置group的指定服务生效
-* `version=1.0`对指定服务的指定version生效,不填表示对未配置version的指定服务生效
-* `category=routers` 表示该数据为动态配置类型,**必填**。
-* `dynamic=false` 表示该数据为持久数据,当注册方退出时,数据依然保存在注册中心,**必填**。
-* `enabled=true` 覆盖规则是否生效,可不填,缺省生效。
-* `force=false` 当路由结果为空时,是否强制执行,如果不强制执行,路由结果为空的路由规则将自动失效,可不填,缺省为 `false`。
-* `runtime=false`
是否在每次调用时执行路由规则,否则只在提供者地址列表变更时预先执行并缓存结果,调用时直接从缓存中获取路由结果。如果用了参数路由,必须设为
`true`,需要注意设置会影响调用的性能,可不填,缺省为 `false`。
-* `priority=1` 路由规则的优先级,用于排序,优先级越大越靠前执行,可不填,缺省为 `0`。
-* `rule=URL.encode("host = 10.20.153.10 => host = 10.20.153.11")`
表示路由规则的内容,**必填**。
+- `scope`表示路由规则的作用粒度,service - 务粒度,application - 应用粒度,scope的取值会决定key的取值。**必填**。
+- `Key`明确规则体作用在哪个服务或应用。**必填**。
+ - scope=service时,key取值为[{group}:]{service}[:{version}]的组合
+- scope=application时,key取值为application名称
+- `enabled=true` 当前路由规则是否生效,可不填,缺省生效。
+- `force=false` 当路由结果为空时,是否强制执行,如果不强制执行,路由结果为空的路由规则将自动失效,可不填,缺省为 `false`。
+- `runtime=false`
是否在每次调用时执行路由规则,否则只在提供者地址列表变更时预先执行并缓存结果,调用时直接从缓存中获取路由结果。如果用了参数路由,必须设为
`true`,需要注意设置会影响调用的性能,可不填,缺省为 `false`。
+- `priority=1` 路由规则的优先级,用于排序,优先级越大越靠前执行,可不填,缺省为 `0`。
+- `conditions` 定义具体的路由规则内容。**必填**。
-## 条件路由规则
+#### Conditions规则体
-基于条件表达式的路由规则,如:`host = 10.20.153.10 => host = 10.20.153.11`
+ `conditions`部分是规则的主体,由1到任意多条规则组成,下面我们就每个规则的配置语法做详细说明:
-### 规则:
+1. **格式**
-* `=>` 之前的为消费者匹配条件,所有参数和消费者的 URL 进行对比,当消费者满足匹配条件时,对该消费者执行后面的过滤规则。
-* `=>` 之后为提供者地址列表的过滤条件,所有参数和提供者的 URL 进行对比,消费者最终只拿到过滤后的地址列表。
-* 如果匹配条件为空,表示对所有消费方应用,如:`=> host != 10.20.153.11`
-* 如果过滤条件为空,表示禁止访问,如:`host = 10.20.153.10 =>`
+- `=>` 之前的为消费者匹配条件,所有参数和消费者的 URL 进行对比,当消费者满足匹配条件时,对该消费者执行后面的过滤规则。
+- `=>` 之后为提供者地址列表的过滤条件,所有参数和提供者的 URL 进行对比,消费者最终只拿到过滤后的地址列表。
+- 如果匹配条件为空,表示对所有消费方应用,如:`=> host != 10.20.153.11`
+- 如果过滤条件为空,表示禁止访问,如:`host = 10.20.153.10 =>`
-### 表达式:
+1. **表达式**
参数支持:
-* 服务调用信息,如:method, argument 等,暂不支持参数路由
-* URL 本身的字段,如:protocol, host, port 等
-* 以及 URL 上的所有参数,如:application, organization 等
+- 服务调用信息,如:method, argument 等,暂不支持参数路由
+- URL 本身的字段,如:protocol, host, port 等
+- 以及 URL 上的所有参数,如:application, organization 等
条件支持:
-* 等号 `=` 表示"匹配",如:`host = 10.20.153.10`
-* 不等号 `!=` 表示"不匹配",如:`host != 10.20.153.10`
+- 等号 `=` 表示"匹配",如:`host = 10.20.153.10`
+- 不等号 `!=` 表示"不匹配",如:`host != 10.20.153.10`
值支持:
-* 以逗号 `,` 分隔多个值,如:`host != 10.20.153.10,10.20.153.11`
-* 以星号 `*` 结尾,表示通配,如:`host != 10.20.*`
-* 以美元符 `$` 开头,表示引用消费者参数,如:`host = $host`
+- 以逗号 `,` 分隔多个值,如:`host != 10.20.153.10,10.20.153.11`
+- 以星号 `*` 结尾,表示通配,如:`host != 10.20.*`
+- 以美元符 `$` 开头,表示引用消费者参数,如:`host = $host`
-### 示例:
+1. **Condition示例**
-0. 排除预发布机:
+- 排除预发布机:
- ```
- => host != 172.22.3.91
- ```
-1. 白名单 [^3]:
-
- ```
- host != 10.20.153.10,10.20.153.11 =>
- ```
-2. 黑名单:
+```
+=> host != 172.22.3.91
+```
+
+- 白名单 [^3]:
+
+```
+host != 10.20.153.10,10.20.153.11 =>
+```
+
+- 黑名单:
- ```
- host = 10.20.153.10,10.20.153.11 =>
- ```
-3. 服务寄宿在应用上,只暴露一部分的机器,防止整个集群挂掉:
+```
+host = 10.20.153.10,10.20.153.11 =>
+```
- ```
- => host = 172.22.3.1*,172.22.3.2*
- ```
-4. 为重要应用提供额外的机器:
+- 服务寄宿在应用上,只暴露一部分的机器,防止整个集群挂掉:
- ```
- application != kylin => host != 172.22.3.95,172.22.3.96
- ```
-5. 读写分离:
+```
+=> host = 172.22.3.1*,172.22.3.2*
+```
- ```
- method = find*,list*,get*,is* => host = 172.22.3.94,172.22.3.95,172.22.3.96
- method != find*,list*,get*,is* => host = 172.22.3.97,172.22.3.98
- ```
-
-6. 前后台分离:
+- 为重要应用提供额外的机器:
+
+```
+application != kylin => host != 172.22.3.95,172.22.3.96
+```
- ```
- application = bops => host = 172.22.3.91,172.22.3.92,172.22.3.93
- application != bops => host = 172.22.3.94,172.22.3.95,172.22.3.96
- ```
-
-7. 隔离不同机房网段:
+- 读写分离:
- ```
- host != 172.22.3.* => host != 172.22.3.*
- ```
-
-8. 提供者与消费者部署在同集群内,本机只访问本机的服务:
+```
+method = find*,list*,get*,is* => host = 172.22.3.94,172.22.3.95,172.22.3.96
+method != find*,list*,get*,is* => host = 172.22.3.97,172.22.3.98
+```
- ```
- => host = $host
- ```
-
-## 脚本路由规则
+- 前后台分离:
-脚本路由规则 [^4] 支持 JDK 脚本引擎的所有脚本,比如:javascript, jruby, groovy 等,通过
`type=javascript` 参数设置脚本类型,缺省为 javascript。
+```
+application = bops => host = 172.22.3.91,172.22.3.92,172.22.3.93
+application != bops => host = 172.22.3.94,172.22.3.95,172.22.3.96
+```
+- 隔离不同机房网段:
```
-"script://0.0.0.0/com.foo.BarService?category=routers&dynamic=false&rule=" +
URL.encode("(function route(invokers) { ... } (invokers))")
+host != 172.22.3.* => host != 172.22.3.*
```
-基于脚本引擎的路由规则,如:
+- 提供者与消费者部署在同集群内,本机只访问本机的服务:
-```javascript
-(function route(invokers) {
- var result = new java.util.ArrayList(invokers.size());
- for (i = 0; i < invokers.size(); i ++) {
- if ("10.20.153.10".equals(invokers.get(i).getUrl().getHost())) {
- result.add(invokers.get(i));
- }
- }
- return result;
-} (invokers)); // 表示立即执行方法
```
+=> host = $host
+```
+
+
## 标签路由规则
-标签路由规则 [^5] ,当应用选择装配标签路由(TagRouter)之后,一次 dubbo 调用能够根据请求携带的 tag 标签智能地选择对应 tag
的服务提供者进行调用。
+### 简介
-### 服务提供者
+标签路由通过将某一个或多个服务的提供者划分到同一个分组,约束流量只在指定分组中流转,从而实现流量隔离的目的,可以作为蓝绿发布、灰度发布等场景的能力基础。
-1. 给应用装配标签路由器:
+#### Provider
-```Java
-@Bean
-public ApplicationConfig applicationConfig() {
- ApplicationConfig applicationConfig = new ApplicationConfig();
- applicationConfig.setName("provider-book");
- applicationConfig.setQosEnable(false);
- // instruct tag router
- Map<String,String> parameters = new HashMap<>();
- parameters.put(Constants.ROUTER_KEY, "tag");
- applicationConfig.setParameters(parameters);
- return applicationConfig;
-}
-```
+标签主要是指对Provider端应用实例的分组,目前有两种方式可以完成实例分组,分别是`动态规则打标`和`静态规则打标`,其中动态规则相较于静态规则优先级更高,而当两种规则同时存在且出现冲突时,将以动态规则为准。
-2. 给应用设置具体的标签:
+- 动态规则打标,可随时在[服务治理控制台]()下发标签归组规则
-```java
-@Bean
-public ProviderConfig providerConfig(){
- ProviderConfig providerConfig = new ProviderConfig();
- providerConfig.setTag("red");
- return providerConfig;
-}
-```
+ ```yaml
+ # governance-tagrouter-provider应用增加了两个标签分组tag1和tag2
+ # tag1包含一个实例 127.0.0.1:20880
+ # tag2包含一个实例 127.0.0.1:20881
+ ---
+ force: false
+ runtime: true
+ enabled: true
+ key: governance-tagrouter-provider
+ tags:
+ - name: tag1
+ addresses: ["127.0.0.1:20880"]
+ - name: tag2
+ addresses: ["127.0.0.1:20881"]
+ ...
+ ```
+
+
+
+- 静态打标
+
+ ```xml
+ <dubbo:provider tag="tag1"/>
+ ```
-应用未装配 tag 属性或服务提供者未设置 tag 属性,都将被认为是默认的应用,这些默认应用将会在调用无法匹配 provider 时当作降级方案。
+or
-### 服务消费者
+ ```xml
+ <dubbo:service tag="tag1"/>
+ ```
-```Java
-RpcContext.getContext().setAttachment(Constants.REQUEST_TAG_KEY,"red");
+or
+
+ ```properties
+ java -jar xxx-provider.jar -Ddubbo.provider.tag={the tag you want}
+ ```
+
+
+
+#### Consumer
+
+```java
+RpcContext.getContext().setAttachment(Constants.REQUEST_TAG_KEY,"tag1");
```
请求标签的作用域为每一次 invocation,使用 attachment 来传递请求标签,注意保存在 attachment
中的值将会在一次完整的远程调用中持续传递,得益于这样的特性,我们只需要在起始调用时,通过一行代码的设置,达到标签的持续传递。
> 目前仅仅支持 hardcoding 的方式设置 requestTag。注意到 RpcContext 是线程绑定的,优雅的使用 TagRouter
> 特性,建议通过 servlet 过滤器(在 web 环境下),或者定制的 SPI 过滤器设置 requestTag。
-### 规则描述
-1. request.tag=red 时优先选择 tag=red 的 provider。若集群中不存在与请求标记对应的服务,可以降级请求 tag=null
的 provider,即默认 provider。
-2. request.tag=null 时,只会匹配 tag=null 的 provider。即使集群中存在可用的服务,若 tag
不匹配就无法调用,这与规则1不同,携带标签的请求可以降级访问到无标签的服务,但不携带标签/携带其他种类标签的请求永远无法访问到其他标签的服务。
+### 规则详解
+
+#### 格式
+
+- `Key`明确规则体作用到哪个应用。**必填**。
+- `enabled=true` 当前路由规则是否生效,可不填,缺省生效。
+- `force=false` 当路由结果为空时,是否强制执行,如果不强制执行,路由结果为空的路由规则将自动失效,可不填,缺省为 `false`。
+- `runtime=false`
是否在每次调用时执行路由规则,否则只在提供者地址列表变更时预先执行并缓存结果,调用时直接从缓存中获取路由结果。如果用了参数路由,必须设为
`true`,需要注意设置会影响调用的性能,可不填,缺省为 `false`。
+- `priority=1` 路由规则的优先级,用于排序,优先级越大越靠前执行,可不填,缺省为 `0`。
+- `tags` 定义具体的标签分组内容,可定义任意n(n>=1)个标签并为每个标签指定实例列表。**必填**。
+ - name, 标签名称
+- addresses, 当前标签包含的实例列表
+
+
+
+#### 降级约定
+
+1. `request.tag=tag1` 时优先选择 标记了`tag=tag1` 的 provider。若集群中不存在与请求标记对应的服务,默认将降级请求
tag为空的provider;如果要该表这种默认行为,即找不到匹配tag1的provider返回异常,需设置`request.tag.force=true`。
+
+2. `request.tag`未设置时,只会匹配tag为空的provider。即使集群中存在可用的服务,若 tag
不匹配也就无法调用,这与约定1不同,携带标签的请求可以降级访问到无标签的服务,但不携带标签/携带其他种类标签的请求永远无法访问到其他标签的服务。
+
-
[^1]: `2.2.0` 以上版本支持
[^2]: 路由规则扩展点:[路由扩展](http://dubbo.apache.org/zh-cn/docs/dev/impls/router.html)
-[^3]: 注意:一个服务只能有一条白名单规则,否则两条规则交叉,就都被筛选掉了
-[^4]: 注意:脚本没有沙箱约束,可执行任意代码,存在后门风险
-[^5]: 该特性在 `2.7.0` 以上版本支持
\ No newline at end of file
+[^3]: 注意:一个服务只能有一条白名单规则,否则两条规则交叉,就都被筛选掉了
\ No newline at end of file
diff --git a/docs/zh-cn/user/version-upgrading.md
b/docs/zh-cn/user/version-upgrading.md
new file mode 100644
index 0000000..595f11d
--- /dev/null
+++ b/docs/zh-cn/user/version-upgrading.md
@@ -0,0 +1,5 @@
+# 版本与升级
+
+## 2.7.0
+* [2.6.x及低版本升级指南](/blog/zh-cn/Guides-for-upgrading-to-27x.md)
+* [Release Notes](https://github.com/apache/incubator-dubbo/releases)
diff --git a/img/apollo-configcenter-application.jpg
b/img/apollo-configcenter-application.jpg
new file mode 100644
index 0000000..5b40d86
Binary files /dev/null and b/img/apollo-configcenter-application.jpg differ
diff --git a/img/apollo-configcenter-dubbo.jpg
b/img/apollo-configcenter-dubbo.jpg
new file mode 100644
index 0000000..8dbeeb4
Binary files /dev/null and b/img/apollo-configcenter-dubbo.jpg differ
diff --git a/img/apollo-configcenter-enhance.jpg
b/img/apollo-configcenter-enhance.jpg
new file mode 100644
index 0000000..e491317
Binary files /dev/null and b/img/apollo-configcenter-enhance.jpg differ
diff --git a/img/apollo-configcenter-governance.jpg
b/img/apollo-configcenter-governance.jpg
new file mode 100644
index 0000000..dfdc7b7
Binary files /dev/null and b/img/apollo-configcenter-governance.jpg differ
diff --git a/img/zk-configcenter-governance.jpg
b/img/zk-configcenter-governance.jpg
new file mode 100644
index 0000000..9c5b9f3
Binary files /dev/null and b/img/zk-configcenter-governance.jpg differ
diff --git a/img/zk-configcenter.jpg b/img/zk-configcenter.jpg
new file mode 100644
index 0000000..68a0841
Binary files /dev/null and b/img/zk-configcenter.jpg differ