This is an automated email from the ASF dual-hosted git repository. jerrick 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 469b327 add compatible 469b327 is described below commit 469b3273df1925b34ab0b4d27270b0aefd572a0c Author: zhuyong <yong.z...@alibaba-inc.com> AuthorDate: Tue Sep 4 16:46:27 2018 +0800 add compatible --- ...bbo-basic-usage-dubbo-provider-configuration.md | 2 +- blog/zh-cn/dubbo-compatible.md | 197 ++++++++++++++++++++ blog/zh-cn/dubbo-contribue-to-opensource.md | 2 +- blog/zh-cn/dubbo-meetup-chengdu.md | 4 +- blog/zh-cn/dubbo-meetup-shanghai-jun-23rd-2018.md | 4 +- blog/zh-cn/dubbo-meetup-shenzhen.md | 4 +- blog/zh-cn/introduction-to-dubbo-spi.md | 1 - blog/zh-cn/optimization-branch-prediction.md | 1 - build/blog.js | 2 +- site_config/blog.js | 7 + ...o-basic-usage-dubbo-provider-configuration.html | 3 +- ...o-basic-usage-dubbo-provider-configuration.json | 2 +- zh-cn/blog/dubbo-compatible.html | 198 +++++++++++++++++++++ zh-cn/blog/dubbo-compatible.json | 7 + zh-cn/blog/dubbo-contribue-to-opensource.html | 3 +- zh-cn/blog/dubbo-contribue-to-opensource.json | 2 +- zh-cn/blog/dubbo-meetup-chengdu.html | 2 +- zh-cn/blog/dubbo-meetup-chengdu.json | 2 +- .../blog/dubbo-meetup-shanghai-jun-23rd-2018.html | 2 +- .../blog/dubbo-meetup-shanghai-jun-23rd-2018.json | 2 +- zh-cn/blog/dubbo-meetup-shenzhen.html | 2 +- zh-cn/blog/dubbo-meetup-shenzhen.json | 2 +- zh-cn/blog/index.html | 2 +- zh-cn/blog/introduction-to-dubbo-spi.html | 3 +- zh-cn/blog/introduction-to-dubbo-spi.json | 2 +- zh-cn/blog/optimization-branch-prediction.html | 3 +- zh-cn/blog/optimization-branch-prediction.json | 2 +- 27 files changed, 433 insertions(+), 30 deletions(-) diff --git a/blog/zh-cn/dubbo-basic-usage-dubbo-provider-configuration.md b/blog/zh-cn/dubbo-basic-usage-dubbo-provider-configuration.md index 09a9a45..e4349f5 100644 --- a/blog/zh-cn/dubbo-basic-usage-dubbo-provider-configuration.md +++ b/blog/zh-cn/dubbo-basic-usage-dubbo-provider-configuration.md @@ -5,7 +5,7 @@ description: 主要讲述如何配置dubbo,按照配置方式上可以分为 --- # Dubbo基本用法之Provider配置 ---- + ## Dubbo基本用法 diff --git a/blog/zh-cn/dubbo-compatible.md b/blog/zh-cn/dubbo-compatible.md new file mode 100644 index 0000000..dd64448 --- /dev/null +++ b/blog/zh-cn/dubbo-compatible.md @@ -0,0 +1,197 @@ +--- +title: Dubbo 2.7.x repackage后的兼容实现方案 +keywords: Dubbo, repackage, 兼容 +description: 本文简单描述了2.7.x repackage后对老版本的兼容性实现方案。 +--- + +# Dubbo 2.7.x repackage后的兼容实现方案 + +Dubbo至加入Apache孵化器以来,一个很强的诉求就是需要rename groupId和package name,这两项工作在项目毕业前需要完成。其中rename package相对来说复杂一些,除了要修改所有类的包名为`org.apache.dubbo`外,更多的是需要考虑如何老版本的兼容性。 + +常见的兼容性包括但不限于以下几种情况: + +* 用户API + * 编程API + * Spring注解 +* 扩展SPI + * 扩展Filter + +2.7.x里就是通过增加了一个新的模块`dubbo-compatible`来解决以上兼容性问题。 + +## 编程使用API + +编程使用API是最直接最原始的使用方式,其他方式诸如Spring schema、注解等方式都是基于原始API的;因此非常有必要对API编程形式进行兼容。 + +所有编程相关API的兼容代码均在`com.alibaba.dubbo.config`包下,下面我们看看几个常见API的兼容实现。 + +### ApplicationConfig + +```java +package com.alibaba.dubbo.config; + +@Deprecated +public class ApplicationConfig extends org.apache.dubbo.config.ApplicationConfig { + + public ApplicationConfig() { + super(); + } + + public ApplicationConfig(String name) { + super(name); + } +} +``` + +### ProtocolConfig + +```java +package com.alibaba.dubbo.config; + +@Deprecated +public class ProtocolConfig extends org.apache.dubbo.config.ProtocolConfig { + + public ProtocolConfig() { + } + + public ProtocolConfig(String name) { + super(name); + } + + public ProtocolConfig(String name, int port) { + super(name, port); + } +} +``` + +可以看到: + +1. 兼容类是直接通过继续repacakge后的类,达到最大程度的代码复用; +2. 构造函数也需要保持兼容; + +整个兼容包中,除了上述API以外,包括一些常用的类比如`Constants`、`URL`以及绝大部分的兼容类都是通过简单的继承,让用户基于老的API实现的类能正确运行。 + +## Spring注解 + +Spring注解诸如`@EnableDubbo`、`@Service`以及`@Reference`,由于不能使用继承,故这些注解类是通过代码拷贝来实现的;用于处理这些注解的Spring BeanPostProcessor以及Parser等相关的类,也是通过拷贝来实现; + +这类兼容代码分别位于兼容包的以下几个package中: + +* com.alibaba.dubbo.config.annotation +* com.alibaba.dubbo.config.spring.context.annotation +* org.apache.dubbo.config.spring + +所以这里要特别强调的是,这类代码在2.7.x里存在2份,因此有修改的同时需要同步修改。 + +## 扩展SPI + +Dubbo的SPI扩展机制,可以通过[Dubbo可扩展机制实战](http://dubbo.apache.org/zh-cn/blog/introduction-to-dubbo-spi.html)这篇博客详细了解。 + +以Filter扩展为例,简单来说就是: + +1. MyFilter需要实现Filter接口 +2. 在META-INF/dubbo下,增加META-INF/dubbo/com.alibaba.dubbo.rpc.Filter,内容为: + + ``` + myFilter=com.test.MyFilter + ``` + +看似简单的两点,对Dubbo框架来说,需要: + +1. 正确加载配置文件META-INF/dubbo/com.alibaba.dubbo.rpc.Filter +2. 正确加载MyFilter类并执行invoke方法 + +下面分别介绍Dubbo框架怎么实现以上几点。 + +### 正确加载META-INF/dubbo/com.alibaba.dubbo.rpc.Filter + +Dubbo SPI机制在查找配置文件时,是根据扩展点的类名来查找的,以Filter为例,在包名变为org.apache.dubbo后,查询的目录变成: + +* META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter +* META-INF/dubbo/org.apache.dubbo.rpc.Filter +* META-INF/services/org.apache.dubbo.rpc.Filter + +但是用户之前按老的包实现的Filter,其配置是放在类似`META-INF/dubbo/com.alibaba.dubbo.rpc.Filter`的,如果框架不做特殊处理,是不会加载老配置的。 + +因此在`ExtensionLoader`这个类里,做了特殊的处理: + +```java + // synchronized in getExtensionClasses + private Map<String, Class<?>> loadExtensionClasses() { + final SPI defaultAnnotation = type.getAnnotation(SPI.class); + if (defaultAnnotation != null) { + String value = defaultAnnotation.value(); + if ((value = value.trim()).length() > 0) { + String[] names = NAME_SEPARATOR.split(value); + if (names.length > 1) { + throw new IllegalStateException("more than 1 default extension name on extension " + type.getName() + + ": " + Arrays.toString(names)); + } + if (names.length == 1) cachedDefaultName = names[0]; + } + } + + Map<String, Class<?>> extensionClasses = new HashMap<String, Class<?>>(); + loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName()); + loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName().replace("org.apache", "com.alibaba")); + loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName()); + loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName().replace("org.apache", "com.alibaba")); + loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName()); + loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName().replace("org.apache", "com.alibaba")); + return extensionClasses; + } +``` + +可以看到,除了加载新配置外,老配置文件也会进行扫描。 + +### 正确加载MyFilter类 + +`com.alibaba.dubbo.rpc.Filter`接口除了要继承自`org.apache.dubbo.rpc.Filter`以外,其唯一的方法invoke也需要做特殊处理。我们看看它的方法签名: + +`Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException;` + +这里参数、返回值、异常都会被实现类`MyFilter`用到,因此这些类也需要有兼容类;而参数、返回值不同,对于接口来说是不同的方法,因此: + +* 需要在com.alibaba.dubbo.rpc.Filter里,定义老的invoke方法,MyFilter会覆盖这个方法; +* org.apache.dubbo.rpc.Filter里的invoke方法,需要找一个地方来实现桥接,框架调用Filter链执行到新的invoke方法时,新的参数如何转换成老参数,老返回值如何转换成新的返回值; + +这里就用到了JDK8的新特性:接口default方法。 + +```java +@Deprecated +public interface Filter extends org.apache.dubbo.rpc.Filter { + + Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException; + + default org.apache.dubbo.rpc.Result invoke(org.apache.dubbo.rpc.Invoker<?> invoker, + org.apache.dubbo.rpc.Invocation invocation) + throws org.apache.dubbo.rpc.RpcException { + Result.CompatibleResult result = (Result.CompatibleResult) invoke(new Invoker.CompatibleInvoker<>(invoker), + new Invocation.CompatibleInvocation(invocation)); + return result.getDelegate(); + } +} +``` + +可以看到,default方法里,对参数进行了包装,然后调用老的invoke方法,并将返回值进行解包后返回给Dubbo框架。这里Result.CompatibleResult、Invocation.CompatibleInvocation以及Invoker.CompatibleInvoker都用到了代理模式。 + +感兴趣的同学可以详细看一下以下几个类: + +* com.alibaba.dubbo.rpc.Invocation +* com.alibaba.dubbo.rpc.Invoker +* com.alibaba.dubbo.rpc.Result + +## 后续todo list + +目前兼容包仅仅是对常见的API及SPI做了支持,列表如下: + +* com.alibaba.dubbo.rpc.Filter / Invocation / Invoker / Result / RpcContext / RpcException +* com.alibaba.dubbo.config.*Config +* com.alibaba.dubbo.config.annotation.Reference / Service +* com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo +* com.alibaba.dubbo.common.Constants / URL +* com.alibaba.dubbo.common.extension.ExtensionFactory +* com.alibaba.dubbo.common.serialize.Serialization / ObjectInput / ObjectOutput +* com.alibaba.dubbo.cache.CacheFactory / Cache +* com.alibaba.dubbo.rpc.service.EchoService / GenericService + +大家如果在试用的过程中发现有任何问题请及时提出;同时如果对其他扩展点有兼容需求,也请大家提出来,也非常欢迎大家自己解决并贡献出来。 \ No newline at end of file diff --git a/blog/zh-cn/dubbo-contribue-to-opensource.md b/blog/zh-cn/dubbo-contribue-to-opensource.md index 57916d8..68d7985 100644 --- a/blog/zh-cn/dubbo-contribue-to-opensource.md +++ b/blog/zh-cn/dubbo-contribue-to-opensource.md @@ -5,7 +5,7 @@ description: 本文将会以 incubator-dubbo 项目为例向你阐释,给开 --- # 以Dubbo为例,聊聊如何向开源项目做贡献 ---- + Github 上有众多优秀的开源项目,大多数 IT 从业者将其当做了予取予求的工具库,遇到什么需求,先去 Github 搜一把,但有没有想过有一天自己也可以给开源事业做一些贡献呢?本文将会以 incubator-dubbo 项目为例,向你阐释,给开源项目做贡献并不是一件难事。 diff --git a/blog/zh-cn/dubbo-meetup-chengdu.md b/blog/zh-cn/dubbo-meetup-chengdu.md index 99c2af2..15d3aa6 100644 --- a/blog/zh-cn/dubbo-meetup-chengdu.md +++ b/blog/zh-cn/dubbo-meetup-chengdu.md @@ -4,8 +4,8 @@ keywords: Dubbo, 成都, meetup description: 第四届Dubbo开发者沙龙将于8月26日在成都举行。 --- -第四届Dubbo开发者沙龙将于8月26日在成都举行 ---- +# 第四届Dubbo开发者沙龙将于8月26日在成都举行 + Aliware Open Source•成都站-Apache Dubbo开发者沙龙将于8月26日(周日)在成都高新区天府五街200号菁蓉国际广场8号楼2楼会议厅举办,技术GG们的思想盛宴,干货与福利一个都不会少。 diff --git a/blog/zh-cn/dubbo-meetup-shanghai-jun-23rd-2018.md b/blog/zh-cn/dubbo-meetup-shanghai-jun-23rd-2018.md index 9f58089..612f285 100644 --- a/blog/zh-cn/dubbo-meetup-shanghai-jun-23rd-2018.md +++ b/blog/zh-cn/dubbo-meetup-shanghai-jun-23rd-2018.md @@ -1,5 +1,5 @@ -第二届Dubbo开发者沙龙在上海成功举办 ---- +# 第二届Dubbo开发者沙龙在上海成功举办 + 第二届Dubbo开发者沙龙在上海成功举办,超过700位开发者报名,现场参与人数300+,通过阿里云天池、云栖社区、大咖说引导线上直播观看次数10000+ diff --git a/blog/zh-cn/dubbo-meetup-shenzhen.md b/blog/zh-cn/dubbo-meetup-shenzhen.md index 29a9fba..7c14e41 100644 --- a/blog/zh-cn/dubbo-meetup-shenzhen.md +++ b/blog/zh-cn/dubbo-meetup-shenzhen.md @@ -1,5 +1,5 @@ -第三届Dubbo开发者沙龙在深圳成功举办 ---- +# 第三届Dubbo开发者沙龙在深圳成功举办 + 第三届Dubbo开发者沙龙在深圳成功举办,超过2000位开发者报名,现场参与人数700+,通过阿里云天池、云栖社区、大咖说引导线上直播观看次数17000+ diff --git a/blog/zh-cn/introduction-to-dubbo-spi.md b/blog/zh-cn/introduction-to-dubbo-spi.md index a97ab54..29ac721 100644 --- a/blog/zh-cn/introduction-to-dubbo-spi.md +++ b/blog/zh-cn/introduction-to-dubbo-spi.md @@ -5,7 +5,6 @@ description: 本文介绍了Dubbo框架的核心,SPI扩展机制。 --- # Dubbo可扩展机制实战 ---- ## 1. Dubbo的扩展机制 在Dubbo的官网上,Dubbo描述自己是一个高性能的RPC框架。今天我想聊聊Dubbo的另一个很棒的特性, 就是它的可扩展性。 diff --git a/blog/zh-cn/optimization-branch-prediction.md b/blog/zh-cn/optimization-branch-prediction.md index eb9e615..d0f737d 100644 --- a/blog/zh-cn/optimization-branch-prediction.md +++ b/blog/zh-cn/optimization-branch-prediction.md @@ -3,7 +3,6 @@ title: 提前if判断帮助CPU分支预测 --- # 优化技巧:提前if判断帮助CPU分支预测 ---- ## 分支预测 diff --git a/build/blog.js b/build/blog.js index 29e02b2..bd221da 100644 --- a/build/blog.js +++ b/build/blog.js @@ -3,4 +3,4 @@ Licensed under the MIT License (MIT), see http://jedwatson.github.io/classnames */ -!function(){"use strict";function n(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof r;if("string"===o||"number"===o)e.push(r);else if(Array.isArray(r)&&r.length){var a=n.apply(null,r);a&&e.push(a)}else if("object"===o)for(var u in r)i.call(r,u)&&r[u]&&e.push(u)}}return e.join(" ")}var i={}.hasOwnProperty;void 0!==e&&e.exports?(n.default=n,e.exports=n):(r=[],void 0!==(o=function(){return n}.apply(t,r))&&(e.exports=o))}()},function(e,t,n){"use strict";funct [...] \ No newline at end of file +!function(){"use strict";function n(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof r;if("string"===o||"number"===o)e.push(r);else if(Array.isArray(r)&&r.length){var a=n.apply(null,r);a&&e.push(a)}else if("object"===o)for(var u in r)i.call(r,u)&&r[u]&&e.push(u)}}return e.join(" ")}var i={}.hasOwnProperty;void 0!==e&&e.exports?(n.default=n,e.exports=n):(r=[],void 0!==(o=function(){return n}.apply(t,r))&&(e.exports=o))}()},function(e,t,n){"use strict";funct [...] \ No newline at end of file diff --git a/site_config/blog.js b/site_config/blog.js index f5aa1eb..eb18d80 100644 --- a/site_config/blog.js +++ b/site_config/blog.js @@ -157,6 +157,13 @@ export default { postsTitle: '所有文章', list: [ { + title: 'Dubbo 2.7.x repackage后的兼容实现方案', + author:'@jerrick', + dateStr: 'Sep 4th, 2018', + desc: '本文简单描述了2.7.x repackage后对老版本的兼容性实现方案。', + link: '/zh-cn/blog/dubbo-compatible.html', + }, + { title: 'Dubbo与Kubernetes集成', author:'@kongming', dateStr: 'Sep 4th, 2018', diff --git a/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.html b/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.html index 3238454..4740475 100644 --- a/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.html +++ b/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.html @@ -12,8 +12,7 @@ <link rel="stylesheet" href="/build/blogDetail.css" /> </head> <body> - <div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="-1082635303"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-t [...] -<hr> + <div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="-188396933"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-to [...] <h2>Dubbo基本用法</h2> <p>本章节主要讲述如何配置dubbo,按照配置方式上分,可以分为:XML配置,properties方式配置,注解方式配置,API调用方式配置。 按照功能角度进行划分,可以分为Dubbo Provider和Dubbo Consumer。接下来章节中,分别对dubbo provider和Dubbo consumer进行讲解。</p> diff --git a/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.json b/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.json index d594b40..e2b56ef 100644 --- a/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.json +++ b/zh-cn/blog/dubbo-basic-usage-dubbo-provider-configuration.json @@ -1,6 +1,6 @@ { "filename": "dubbo-basic-usage-dubbo-provider-configuration.md", - "__html": "<h1>Dubbo基本用法之Provider配置</h1>\n<hr>\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><?xml version="1.0" encoding="UTF-8"?>\n<beans xmlns=&qu [...] + "__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><?xml version="1.0" encoding="UTF-8"?>\n<beans xmlns="htt [...] "title": "Dubbo基础用法之Provider配置", "keywords": "Dubbo, Provider, Configuration", "description": "主要讲述如何配置dubbo,按照配置方式上可以分为:XML配置,properties方式配置,注解方式配置,API调用方式配置。" diff --git a/zh-cn/blog/dubbo-compatible.html b/zh-cn/blog/dubbo-compatible.html new file mode 100644 index 0000000..3aa3306 --- /dev/null +++ b/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="" data-reactid="1" data-react-checksum="1373077449"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-to [...] +<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<String, Class<?>> loadExtensionClasses() { + <span class="hljs-keyword">final</span> SPI defaultAnnotation = type.getAnnotation(SPI.class); + <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() > <span class="hljs-number">0</span>) { + String[] names = NAME_SEPARATOR.split(value); + <span class="hljs-keyword">if</span> (names.length > <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<String, Class<?>> extensionClasses = <span class="hljs-keyword">new</span> HashMap<String, Class<?>>(); + 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<?> 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<?> 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<?> 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<>(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" data-reactid="19"><div class="footer-body" data-reactid="20"><img src="/img/dubbo_gray.png" data-reactid="21"/><img class="apache" src="/img/apache_logo.png" data-reactid="22"/><div class="cols-container" data-reactid="23"><div class="col col-12" data-reactid="24"><h3 data-reactid="25">Disclaimer</h3><p data-reactid="26">Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubatio [...] + <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/zh-cn/blog/dubbo-compatible.json b/zh-cn/blog/dubbo-compatible.json new file mode 100644 index 0000000..bb651bd --- /dev/null +++ b/zh-cn/blog/dubbo-compatible.json @@ -0,0 +1,7 @@ +{ + "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是最直接最原始的使用方式,其他方 [...] + "title": "Dubbo 2.7.x repackage后的兼容实现方案", + "keywords": "Dubbo, repackage, 兼容", + "description": "本文简单描述了2.7.x repackage后对老版本的兼容性实现方案。" +} \ No newline at end of file diff --git a/zh-cn/blog/dubbo-contribue-to-opensource.html b/zh-cn/blog/dubbo-contribue-to-opensource.html index b1922a9..69e7874 100644 --- a/zh-cn/blog/dubbo-contribue-to-opensource.html +++ b/zh-cn/blog/dubbo-contribue-to-opensource.html @@ -12,8 +12,7 @@ <link rel="stylesheet" href="/build/blogDetail.css" /> </head> <body> - <div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="-1828827822"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-t [...] -<hr> + <div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="-763474956"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-to [...] <p>Github 上有众多优秀的开源项目,大多数 IT 从业者将其当做了予取予求的工具库,遇到什么需求,先去 Github 搜一把,但有没有想过有一天自己也可以给开源事业做一些贡献呢?本文将会以 incubator-dubbo 项目为例,向你阐释,给开源项目做贡献并不是一件难事。</p> <h2>1 为何要给开源贡献力量</h2> <p>为开源项目做贡献得到的收益是多方面的,为了让你有足够的信心加入到开源项目中,我在文章最开始列举出它的诸多好处。</p> diff --git a/zh-cn/blog/dubbo-contribue-to-opensource.json b/zh-cn/blog/dubbo-contribue-to-opensource.json index 533664c..e0d8f69 100644 --- a/zh-cn/blog/dubbo-contribue-to-opensource.json +++ b/zh-cn/blog/dubbo-contribue-to-opensource.json @@ -1,6 +1,6 @@ { "filename": "dubbo-contribue-to-opensource.md", - "__html": "<h1>以Dubbo为例,聊聊如何向开源项目做贡献</h1>\n<hr>\n<p>Github 上有众多优秀的开源项目,大多数 IT 从业者将其当做了予取予求的工具库,遇到什么需求,先去 Github 搜一把,但有没有想过有一天自己也可以给开源事业做一些贡献呢?本文将会以 incubator-dubbo 项目为例,向你阐释,给开源项目做贡献并不是一件难事。</p>\n<h2>1 为何要给开源贡献力量</h2>\n<p>为开源项目做贡献得到的收益是多方面的,为了让你有足够的信心加入到开源项目中,我在文章最开始列举出它的诸多好处。</p>\n<h3>1.1 巩固技能</h3>\n<p>无论你是提交代码,撰写文档,提交 Issue,组织活动,当你切身参与到一个开源项目中,相关的技能都会得到历练,并且在开源项目中找到自己的位置。一方面,日常工作中我们中的大多数人接触到的是业务场景,并没有太多机会接触到基� ��架构组件,开源项目为我们提供了一个平台,在这里,你可以尽情挑选自己熟悉的项目为它添砖加瓦(以 Dubbo 为例,并不是所有 IT 公司都有能力自研服务 [...] + "__html": "<h1>以Dubbo为例,聊聊如何向开源项目做贡献</h1>\n<p>Github 上有众多优秀的开源项目,大多数 IT 从业者将其当做了予取予求的工具库,遇到什么需求,先去 Github 搜一把,但有没有想过有一天自己也可以给开源事业做一些贡献呢?本文将会以 incubator-dubbo 项目为例,向你阐释,给开源项目做贡献并不是一件难事。</p>\n<h2>1 为何要给开源贡献力量</h2>\n<p>为开源项目做贡献得到的收益是多方面的,为了让你有足够的信心加入到开源项目中,我在文章最开始列举出它的诸多好处。</p>\n<h3>1.1 巩固技能</h3>\n<p>无论你是提交代码,撰写文档,提交 Issue,组织活动,当你切身参与到一个开源项目中,相关的技能都会得到历练,并且在开源项目中找到自己的位置。一方面,日常工作中我们中的大多数人接触到的是业务场景,并没有太多机会接触到基础架� ��组件,开源项目为我们提供了一个平台,在这里,你可以尽情挑选自己熟悉的项目为它添砖加瓦(以 Dubbo 为例,并不是所有 IT 公司都有能力自研服务治理框架); [...] "title": "以Dubbo为例,聊聊如何向开源项目做贡献", "keywords": "Dubbo, opensource", "description": "本文将会以 incubator-dubbo 项目为例向你阐释,给开源项目做贡献并不是一件难事" diff --git a/zh-cn/blog/dubbo-meetup-chengdu.html b/zh-cn/blog/dubbo-meetup-chengdu.html index f5531f5..47f6fe1 100644 --- a/zh-cn/blog/dubbo-meetup-chengdu.html +++ b/zh-cn/blog/dubbo-meetup-chengdu.html @@ -12,7 +12,7 @@ <link rel="stylesheet" href="/build/blogDetail.css" /> </head> <body> - <div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="-570890930"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-to [...] + <div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="-857807540"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-to [...] <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"/> diff --git a/zh-cn/blog/dubbo-meetup-chengdu.json b/zh-cn/blog/dubbo-meetup-chengdu.json index 74e178e..c0eb249 100644 --- a/zh-cn/blog/dubbo-meetup-chengdu.json +++ b/zh-cn/blog/dubbo-meetup-chengdu.json @@ -1,6 +1,6 @@ { "filename": "dubbo-meetup-chengdu.md", - "__html": "<h2>第四届Dubbo开发者沙龙将于8月26日在成都举行</h2>\n<p>Aliware Open Source•成都站-Apache Dubbo开发者沙龙将于8月26日(周日)在成都高新区天府五街200号菁蓉国际广场8号楼2楼会议厅举办,技术GG们的思想盛宴,干货与福利一个都不会少。</p>\n<p>报名链接:<a href=\"http://www.huodongxing.com/event/7453091088400\">http://www.huodongxing.com/event/7453091088400</a></p>\n<img src=\"../../img/blog/dubbo-chengdu-meetup-img.jpg\"/>\n", + "__html": "<h1>第四届Dubbo开发者沙龙将于8月26日在成都举行</h1>\n<p>Aliware Open Source•成都站-Apache Dubbo开发者沙龙将于8月26日(周日)在成都高新区天府五街200号菁蓉国际广场8号楼2楼会议厅举办,技术GG们的思想盛宴,干货与福利一个都不会少。</p>\n<p>报名链接:<a href=\"http://www.huodongxing.com/event/7453091088400\">http://www.huodongxing.com/event/7453091088400</a></p>\n<img src=\"../../img/blog/dubbo-chengdu-meetup-img.jpg\"/>\n", "title": "第四届Dubbo开发者沙龙将于8月26日在成都举行", "keywords": "Dubbo, 成都, meetup", "description": "第四届Dubbo开发者沙龙将于8月26日在成都举行。" diff --git a/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.html b/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.html index d4149d0..434e2f3 100644 --- a/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.html +++ b/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.html @@ -12,7 +12,7 @@ <link rel="stylesheet" href="/build/blogDetail.css" /> </head> <body> - <div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="545233117"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-tog [...] + <div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="184588507"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-tog [...] <p>第二届Dubbo开发者沙龙在上海成功举办,超过700位开发者报名,现场参与人数300+,通过阿里云天池、云栖社区、大咖说引导线上直播观看次数10000+</p> <p>分享嘉宾及PPT:</p> <ul> diff --git a/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.json b/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.json index aecba96..2d52fbb 100644 --- a/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.json +++ b/zh-cn/blog/dubbo-meetup-shanghai-jun-23rd-2018.json @@ -1,4 +1,4 @@ { "filename": "dubbo-meetup-shanghai-jun-23rd-2018.md", - "__html": "<h2>第二届Dubbo开发者沙龙在上海成功举办</h2>\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 [...] + "__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 [...] } \ No newline at end of file diff --git a/zh-cn/blog/dubbo-meetup-shenzhen.html b/zh-cn/blog/dubbo-meetup-shenzhen.html index fefabf7..5b2d061 100644 --- a/zh-cn/blog/dubbo-meetup-shenzhen.html +++ b/zh-cn/blog/dubbo-meetup-shenzhen.html @@ -12,7 +12,7 @@ <link rel="stylesheet" href="/build/blogDetail.css" /> </head> <body> - <div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="-550964757"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-to [...] + <div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="-825626135"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-to [...] <p>第三届Dubbo开发者沙龙在深圳成功举办,超过2000位开发者报名,现场参与人数700+,通过阿里云天池、云栖社区、大咖说引导线上直播观看次数17000+</p> <p>分享嘉宾</p> <ul> diff --git a/zh-cn/blog/dubbo-meetup-shenzhen.json b/zh-cn/blog/dubbo-meetup-shenzhen.json index bbdddcd..f5b13cb 100644 --- a/zh-cn/blog/dubbo-meetup-shenzhen.json +++ b/zh-cn/blog/dubbo-meetup-shenzhen.json @@ -1,4 +1,4 @@ { "filename": "dubbo-meetup-shenzhen.md", - "__html": "<h2>第三届Dubbo开发者沙龙在深圳成功举办</h2>\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" + "__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" } \ No newline at end of file diff --git a/zh-cn/blog/index.html b/zh-cn/blog/index.html index 97200b2..9482c53 100644 --- a/zh-cn/blog/index.html +++ b/zh-cn/blog/index.html @@ -12,7 +12,7 @@ <link rel="stylesheet" href="/build/blog.css" /> </head> <body> - <div id="root"><div class="blog-list-page" data-reactroot="" data-reactid="1" data-react-checksum="1174953479"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-togg [...] + <div id="root"><div class="blog-list-page" data-reactroot="" data-reactid="1" data-react-checksum="-1324957944"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-tog [...] <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> diff --git a/zh-cn/blog/introduction-to-dubbo-spi.html b/zh-cn/blog/introduction-to-dubbo-spi.html index 59f902e..631742c 100644 --- a/zh-cn/blog/introduction-to-dubbo-spi.html +++ b/zh-cn/blog/introduction-to-dubbo-spi.html @@ -12,8 +12,7 @@ <link rel="stylesheet" href="/build/blogDetail.css" /> </head> <body> - <div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="-307969909"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-to [...] -<hr> + <div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="1372176173"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-to [...] <h2>1. Dubbo的扩展机制</h2> <p>在Dubbo的官网上,Dubbo描述自己是一个高性能的RPC框架。今天我想聊聊Dubbo的另一个很棒的特性, 就是它的可扩展性。 如同罗马不是一天建成的,任何系统都一定是从小系统不断发展成为大系统的,想要从一开始就把系统设计的足够完善是不可能的,相反的,我们应该关注当下的需求,然后再不断地对系统进行迭代。在代码层面,要求我们适当的对关注点进行抽象和隔离,在软件不断添加功能和特性时,依然能保持良好的结构和可维护性,同时允许第三方开发者对其功能进行扩展。在某些时候,软件设计者对扩展性的追求甚至超过了性能。</p> diff --git a/zh-cn/blog/introduction-to-dubbo-spi.json b/zh-cn/blog/introduction-to-dubbo-spi.json index 3306599..19d6f5c 100644 --- a/zh-cn/blog/introduction-to-dubbo-spi.json +++ b/zh-cn/blog/introduction-to-dubbo-spi.json @@ -1,6 +1,6 @@ { "filename": "introduction-to-dubbo-spi.md", - "__html": "<h1>Dubbo可扩展机制实战</h1>\n<hr>\n<h2>1. Dubbo的扩展机制</h2>\n<p>在Dubbo的官网上,Dubbo描述自己是一个高性能的RPC框架。今天我想聊聊Dubbo的另一个很棒的特性, 就是它的可扩展性。\n如同罗马不是一天建成的,任何系统都一定是从小系统不断发展成为大系统的,想要从一开始就把系统设计的足够完善是不可能的,相反的,我们应该关注当下的需求,然后再不断地对系统进行迭代。在代码层面,要求我们适当的对关注点进行抽象和隔离,在软件不断添加功能和特性时,依然能保持良好的结构和可维护性,同时允许第三方开发者对其功能进行扩展。在某些时候,软件设计者对扩展性的追求甚至超过了性能。</p>\n<p>在谈到软件设计时,可扩展性一直被谈起,那到底什么才是可扩展性,什么样的框架才算有良好的可扩展性呢?它必须要做到以下两点 :</p>\n<ol>\n<li>作为框架的维护者,在添加一个新功能时,只需要添加一些新代码,而不用大量的修改现有的代码,即符合开闭原则。</li>\n<li>作为框架的使用者,在添加一个新功能时,不需 [...] + "__html": "<h1>Dubbo可扩展机制实战</h1>\n<h2>1. Dubbo的扩展机制</h2>\n<p>在Dubbo的官网上,Dubbo描述自己是一个高性能的RPC框架。今天我想聊聊Dubbo的另一个很棒的特性, 就是它的可扩展性。\n如同罗马不是一天建成的,任何系统都一定是从小系统不断发展成为大系统的,想要从一开始就把系统设计的足够完善是不可能的,相反的,我们应该关注当下的需求,然后再不断地对系统进行迭代。在代码层面,要求我们适当的对关注点进行抽象和隔离,在软件不断添加功能和特性时,依然能保持良好的结构和可维护性,同时允许第三方开发者对其功能进行扩展。在某些时候,软件设计者对扩展性的追求甚至超过了性能。</p>\n<p>在谈到软件设计时,可扩展性一直被谈起,那到底什么才是可扩展性,什么样的框架才算有良好的可扩展性呢?它必须要做到以下两点:</p>\ n<ol>\n<li>作为框架的维护者,在添加一个新功能时,只需要添加一些新代码,而不用大量的修改现有的代码,即符合开闭原则。</li>\n<li>作为框架的使用者,在添加一个新功能时,不需要去修改框架 [...] "title": "Dubbo可扩展机制实战", "keywords": "Dubbo, SPI", "description": "本文介绍了Dubbo框架的核心,SPI扩展机制。" diff --git a/zh-cn/blog/optimization-branch-prediction.html b/zh-cn/blog/optimization-branch-prediction.html index a36cf20..cdbc91b 100644 --- a/zh-cn/blog/optimization-branch-prediction.html +++ b/zh-cn/blog/optimization-branch-prediction.html @@ -12,8 +12,7 @@ <link rel="stylesheet" href="/build/blogDetail.css" /> </head> <body> - <div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="-1756630036"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-t [...] -<hr> + <div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="814740110"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/dubbo_colorful.png" data-reactid="5"/></a><span class="language-switch language-switch-normal" data-reactid="6">En</span><div class="header-menu" data-reactid="7"><img class="header-menu-tog [...] <h2>分支预测</h2> <p>在stackoverflow上有一个非常有名的问题:<a href="https://stackoverflow.com/questions/11227809/why-is-it-faster-to-process-a-sorted-array-than-an-unsorted-array">为什么处理有序数组要比非有序数组快?</a>,可见分支预测对代码运行效率有非常大的影响。</p> <p>现代CPU都支持分支预测(branch prediction)和指令流水线(instruction pipeline),这两个结合可以极大提高CPU效率。对于像简单的if跳转,CPU是可以比较好地做分支预测的。但是对于switch跳转,CPU则没有太多的办法。switch本质上是据索引,从地址数组里取地址再跳转。</p> diff --git a/zh-cn/blog/optimization-branch-prediction.json b/zh-cn/blog/optimization-branch-prediction.json index f415008..05ea9f9 100644 --- a/zh-cn/blog/optimization-branch-prediction.json +++ b/zh-cn/blog/optimization-branch-prediction.json @@ -1,5 +1,5 @@ { "filename": "optimization-branch-prediction.md", - "__html": "<h1>优化技巧:提前if判断帮助CPU分支预测</h1>\n<hr>\n<h2>分支预测</h2>\n<p>在stackoverflow上有一个非常有名的问题:<a href=\"https://stackoverflow.com/questions/11227809/why-is-it-faster-to-process-a-sorted-array-than-an-unsorted-array\">为什么处理有序数组要比非有序数组快?</a>,可见分支预测对代码运行效率有非常大的影响。</p>\n<p>现代CPU都支持分支预测(branch prediction)和指令流水线(instruction pipeline),这两个结合可以极大提高CPU效率。对于像简单的if跳转,CPU是可以比较好地做分支预测的。但是对于switch跳转,CPU则没有太多的办法。switch本质上是据索引,从地址数组里取地址再跳转。</p>\n<p>要提高代码执行效率,一个重要的原则就是尽量避免CPU把流水线清空,那么提高分支预测的成功率就非常重要。</p>\ [...] + "__html": "<h1>优化技巧:提前if判断帮助CPU分支预测</h1>\n<h2>分支预测</h2>\n<p>在stackoverflow上有一个非常有名的问题:<a href=\"https://stackoverflow.com/questions/11227809/why-is-it-faster-to-process-a-sorted-array-than-an-unsorted-array\">为什么处理有序数组要比非有序数组快?</a>,可见分支预测对代码运行效率有非常大的影响。</p>\n<p>现代CPU都支持分支预测(branch prediction)和指令流水线(instruction pipeline),这两个结合可以极大提高CPU效率。对于像简单的if跳转,CPU是可以比较好地做分支预测的。但是对于switch跳转,CPU则没有太多的办法。switch本质上是据索引,从地址数组里取地址再跳转。</p>\n<p>要提高代码执行效率,一个重要的原则就是尽量避免CPU把流水线清空,那么提高分支预测的成功率就非常重要。</p>\n<p>那么 [...] "title": "提前if判断帮助CPU分支预测" } \ No newline at end of file