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

iluo 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 3d584d7  publish blog 'dubbo-zk'
3d584d7 is described below

commit 3d584d7fe0424b435dd014f1379aafe7a7d0ae54
Author: beiwei.ly <beiwei...@alibaba-inc.com>
AuthorDate: Fri Aug 3 16:01:17 2018 +0800

    publish blog 'dubbo-zk'
---
 blog/zh-cn/dubbo-zk.md                             | 339 +++++++++++++++++++++
 ...7ba6acec73c8197d.js => 0abb2937d4e2bc4697f3.js} |   2 +-
 build/0b0bbf419be1d7b49571.js                      |   6 -
 ...f8eca3ff7556b8db.js => 197de76506a1ddd84a4b.js} |   0
 build/55de20a411cd16ffcaad.js                      |   6 +
 ...ed1d026d7ba627aa.js => 87c67c0d7caf73d7e493.js} |   0
 ...5d02abb36f898304.js => c5ce7257df274bc595ec.js} |   2 +-
 build/page.js                                      |   2 +-
 img/blog/dubbo-in-zk.jpg                           | Bin 0 -> 31272 bytes
 img/blog/zk-emsemble.png                           | Bin 0 -> 86220 bytes
 img/blog/zk-tree.png                               | Bin 0 -> 34214 bytes
 md_json/blog.json                                  |   4 +
 md_json/docs.json                                  |   8 +-
 site_config/blog.js                                |   7 +
 14 files changed, 363 insertions(+), 13 deletions(-)

diff --git a/blog/zh-cn/dubbo-zk.md b/blog/zh-cn/dubbo-zk.md
new file mode 100644
index 0000000..8a69062
--- /dev/null
+++ b/blog/zh-cn/dubbo-zk.md
@@ -0,0 +1,339 @@
+# 在 Dubbo 应用中使用 Zookeeper
+
+## Zookeeper 介绍
+
+### 基本概念
+
+在现代的分布式应用中,往往会出现节点和节点之间的协调问题,其中就包括了:选主、集群管理、分布式锁、分布式配置管理、统一命名服务、状态同步等诉求。[Apache
 
Zookeeper](https://zookeeper.apache.org),正如它的名字所暗示的那样,*动物园管理员*,就是为了解决这些诉求的一个分布式协调服务框架。
+
+为了保证高可用,ZooKeeper 本身也可以部署成集群模式,称之为 *ZooKeeper ensemble*。ZooKeeper 
集群中始终确保其中的一台为 leader 的角色,并通过 *ZAB (Zookeeper Atomic Broadcast Protocol) [^1]* 
协议确保所有节点上的信息的一致。客户端可以访问集群中的任何一台进行读写操作,而不用担心数据出现不一致的现象。
+
+![Diagram shows client-server architecture of 
ZooKeeper](../../img/blog/zk-emsemble.png)
+*Image Credit : ebook -Zookeeper-Distributed Process Coordination from 
O'Reilly*
+
+Zookeeper 中的数据存储方式与传统的 UNIX 文件系统相似,节点按照树状结构来组织,其中,节点被称之为 *znodes (ZooKeeper 
data nodes)*
+
+![zk-tree](../../img/blog/zk-tree.png)
+*Image Credit : ebook -Zookeeper-Distributed Process Coordination from 
O'Reilly*
+
+### 基本用法
+
+可以通过直接下载的方式 [^2]安装并运行 Zookeeper ,在 Mac 上也可以通过 Homebrew [^3]  `brew install 
zookeeper`  来安装,考虑到通用性,本文采用 docker 的方式来运行 Zookeeper。如果没有安装 docker,请先准备好 docker 
环境 [^4]。
+
+#### 1. 启动 Zookeeper
+
+执行命令将 Zookeeper 运行在 docker 容器中 
+
+```shell
+docker run --rm --name zookeeper -p 2181:2181 zookeeper
+```
+
+#### 2. 进入 Zookeeper 容器 
+
+```shell
+docker exec -it zookeeper bash
+```
+
+在 `bin` 目录下有启动 Zookeeper 的命令 `zkServer` 以及管理控制台 `zkCli`
+
+```shell
+bash-4.4# ls -l bin
+total 36
+-rwxr-xr-x    1 zookeepe zookeepe       232 Mar 27 04:32 README.txt
+-rwxr-xr-x    1 zookeepe zookeepe      1937 Mar 27 04:32 zkCleanup.sh
+-rwxr-xr-x    1 zookeepe zookeepe      1056 Mar 27 04:32 zkCli.cmd
+-rwxr-xr-x    1 zookeepe zookeepe      1534 Mar 27 04:32 zkCli.sh
+-rwxr-xr-x    1 zookeepe zookeepe      1759 Mar 27 04:32 zkEnv.cmd
+-rwxr-xr-x    1 zookeepe zookeepe      2696 Mar 27 04:32 zkEnv.sh
+-rwxr-xr-x    1 zookeepe zookeepe      1089 Mar 27 04:32 zkServer.cmd
+-rwxr-xr-x    1 zookeepe zookeepe      6773 Mar 27 04:32 zkServer.sh
+```
+
+#### 3. 通过 zkCli 进入 Zookeeper 管理界面
+
+由于是通过 Docker 启动,Zookeeper 进程已经启动,并通过 2181 端口对外提供服务。
+
+```shell
+bash-4.4# ps
+PID   USER     TIME  COMMAND
+    1 zookeepe  0:02 /usr/lib/jvm/java-1.8-openjdk/jre/bin/java 
-Dzookeeper.log.dir=. -Dzookeeper.root
+   32 root      0:00 bash
+   42 root      0:00 ps
+```
+
+因此可以直接通过 `zkCli` 来访问 Zookeeper 的控制台来进行管理。
+
+```shell
+bash-4.4# bin/zkCli.sh -server 127.0.0.1:2181
+Connecting to 127.0.0.1:2181
+...
+WATCHER::
+
+WatchedEvent state:SyncConnected type:None path:null
+
+[zk: 127.0.0.1:2181(CONNECTED) 0] help
+ZooKeeper -server host:port cmd args
+       stat path [watch]
+       set path data [version]
+       ls path [watch]
+       delquota [-n|-b] path
+       ls2 path [watch]
+       setAcl path acl
+       setquota -n|-b val path
+       history
+       redo cmdno
+       printwatches on|off
+       delete path [version]
+       sync path
+       listquota path
+       rmr path
+       get path [watch]
+       create [-s] [-e] path data acl
+       addauth scheme auth
+       quit
+       getAcl path
+       close
+       connect host:port
+```
+
+#### 4. zkCli 上的一些基本操作 
+
+创建 `/hello-zone` 节点:
+
+```shell
+[zk: 127.0.0.1:2181(CONNECTED) 19] create /hello-zone 'world'
+Created /hello-zone
+```
+
+列出 `/` 下的子节点,确认 `hello-zone` 被创建:
+
+```shell
+[zk: 127.0.0.1:2181(CONNECTED) 20] ls /
+[zookeeper, hello-zone]
+```
+
+列出 `/hello-zone` 的子节点,确认为空:
+
+```shell
+[zk: 127.0.0.1:2181(CONNECTED) 21] ls /hello-zone
+[]
+```
+
+获取存储在 `/hello-zone` 节点上的数据:
+
+```shell
+[zk: 127.0.0.1:2181(CONNECTED) 22] get /hello-zone
+world
+```
+
+
+
+## 在 Dubbo 中使用 Zookeeper
+
+Dubbo 使用 Zookeeper 用于服务的注册发现和配置管理,在 Zookeeper 中数据的组织由下图所示:
+
+![dubbo-in-zk](../../img/blog/dubbo-in-zk.jpg)
+
+首先,所有 Dubbo 相关的数据都组织在 `/duboo` 的根节点下。
+
+二级目录是服务名,如 `com.foo.BarService`。
+
+三级目录有两个子节点,分别是 `providers` 和 `consumers`,表示该服务的提供者和消费者。
+
+四级目录记录了与该服务相关的每一个应用实例的 URL 信息,在 `providers` 下的表示该服务的所有提供者,而在 `consumers` 
下的表示该服务的所有消费者。举例说明,`com.foo.BarService` 的服务提供者在启动时将自己的 URL 信息注册到 
`/dubbo/com.foo.BarService/providers` 下;同样的,服务消费者将自己的信息注册到相应的 `consumers` 
下,同时,服务消费者会订阅其所对应的 `providers` 节点,以便能够感知到服务提供方地址列表的变化。
+
+### 准备示例代码
+
+本文的代码可以在 
https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-zookeeper 中找到。
+
+#### 1. 接口定义
+
+定义一个简单的 `GreetingService` 接口,里面只有一个简单的方法 `sayHello` 向调用者问好。
+
+```java
+public interface GreetingService {
+    String sayHello(String name);
+}
+```
+
+#### 2. 服务端:服务实现
+
+实现 `GreetingService` 接口,并通过 `@Service` 来标注其为 Dubbo 的一个服务。
+
+```java
+@Service
+public class AnnotatedGreetingService implements GreetingService {
+    public String sayHello(String name) {
+        return "hello, " + name;
+    }
+}
+```
+
+#### 3. 服务端:组装
+
+定义 ProviderConfiguration 来组装 Dubbo 服务。
+
+```java
+@Configuration
+@EnableDubbo(scanBasePackages = "com.alibaba.dubbo.samples.impl")
+@PropertySource("classpath:/spring/dubbo-provider.properties")
+static class ProviderConfiguration {}
+```
+
+dubbo-provider.properties 是在 Spring 应用中外置配置的方式,内容如下:
+
+```properties
+dubbo.application.name=demo-provider
+dubbo.registry.address=zookeeper://$DOCKER_HOST:2181
+dubbo.protocol.name=dubbo
+dubbo.protocol.port=20880
+```
+
+由于 Zookeeper 运行在 Docker 容器中,需要注意的是:
+
+* 本文假定 Dubbo 应用运行在宿主机上,也就是 Docker 容器外,需要将 Zookeeper 的地址替换成环境变量 
*${DOCKER_HOST}* 所指定的 IP 地址,相关信息请查阅 Docker 官方文档
+* 如果 Dubbo 应用也是 Docker 化的应用,只需要用 Zookeeper 的容器名,在本文中容器名是 **zookeeper**
+* 当然,如果不用容器方式启动 Zookeeper,只需要简单的将这里的 *$DOCKER_HOST* 换成 **localhost** 即可
+
+#### 4. 服务端:启动服务
+
+在 `main` 方法中通过启动一个 Spring Context 来对外提供 Dubbo 服务。
+
+```java
+public class ProviderBootstrap {
+    public static void main(String[] args) throws Exception {
+        AnnotationConfigApplicationContext context = new 
AnnotationConfigApplicationContext(ProviderConfiguration.class);
+        context.start();
+        System.in.read();
+    }
+}
+```
+
+启动服务端的 `main` 方法,将会看到下面的输出,代表服务端启动成功,并在注册中心(ZookeeperRegistry)上注册了 
`GreetingService` 这个服务:
+
+```sh
+[03/08/18 10:50:33:033 CST] main  INFO zookeeper.ZookeeperRegistry:  [DUBBO] 
Register: 
dubbo://192.168.99.1:20880/com.alibaba.dubbo.samples.api.GreetingService?anyhost=true&application=demo-provider&dubbo=2.6.2&generic=false&interface=com.alibaba.dubbo.samples.api.GreetingService&methods=sayHello&pid=12938&side=provider&timestamp=1533264631849,
 dubbo version: 2.6.2, current host: 192.168.99.1
+```
+
+通过 Zookeeper 管理终端观察服务提供方的注册信息:
+
+```sh
+$ docker exec -it zookeeper bash
+bash-4.4# bin/zkCli.sh -server localhost:218
+Connecting to localhost:2181
+...
+Welcome to ZooKeeper!
+JLine support is enabled
+...
+[zk: localhost:2181(CONNECTED) 0] ls 
/dubbo/com.alibaba.dubbo.samples.api.GreetingService/providers
+[dubbo%3A%2F%2F192.168.99.1%3A20880%2Fcom.alibaba.dubbo.samples.api.GreetingService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.6.2%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.samples.api.GreetingService%26methods%3DsayHello%26pid%3D12938%26side%3Dprovider%26timestamp%3D1533264631849]
+```
+
+可以看到刚刚启动的 Dubbo 的服务在 `providers` 节点下注册了自己的 URL 
地址:*dubbo://192.168.99.1:20880/com.alibaba.dubbo.samples.api.GreetingService?anyhost=true&application=demo-provider&dubbo=2.6.2&generic=false&interface=com.alibaba.dubbo.samples.api.GreetingService&methods=sayHello&pid=12938&side=provider&timestamp=1533264631849*
+
+#### 5. 客户端:引用服务
+
+通过 `@Reference` 来在客户端声明服务的引用,运行时将会通过该引用发起全程调用,而服务的目标地址将会从 Zookeeper 的 
`provider` 节点下查询。
+
+```java
+@Component("annotatedConsumer")
+public class GreetingServiceConsumer {
+    @Reference
+    private GreetingService greetingService;
+    
+    public String doSayHello(String name) {
+        return greetingService.sayHello(name);
+    }
+}
+```
+
+#### 6. 客户端:组装
+
+定义 ConsumerConfiguration 来组装 Dubbo 服务。
+
+```java
+@Configuration
+@EnableDubbo(scanBasePackages = "com.alibaba.dubbo.samples.action")
+@PropertySource("classpath:/spring/dubbo-consumer.properties")
+@ComponentScan(value = {"com.alibaba.dubbo.samples.action"})
+static class ConsumerConfiguration {}
+```
+
+dubbo-consumer.properties 是在 Spring 应用中外置配置的方式,内容如下:
+
+```properties
+dubbo.application.name=demo-consumer
+dubbo.registry.address=zookeeper://$DOCKER_HOST:2181
+dubbo.consumer.timeout=3000
+```
+
+与 **3. 服务端:组装** 相同,需要根据自己的运行环境来修改 *dubbo.registry.address* 中定义的 
*$DOCKER_HOST*。请参阅步骤 3 的说明部分。
+
+#### 7. 客户端:发起远程调用
+
+运行 `main` 向已经启动的服务提供方发起一次远程调用。Dubbo 会先向 Zookeeper 
订阅服务地址,然后从返回的地址列表中选取一个,向对端发起调用:
+
+```java
+public class ConsumerBootstrap {
+    public static void main(String[] args) {
+public class ConsumerBootstrap {
+
+    public static void main(String[] args) throws IOException {
+        AnnotationConfigApplicationContext context = new 
AnnotationConfigApplicationContext(ConsumerConfiguration.class);
+        context.start();
+        GreetingServiceConsumer greetingServiceConsumer = 
context.getBean(GreetingServiceConsumer.class);
+        String hello = greetingServiceConsumer.doSayHello("zookeeper");
+        System.out.println("result: " + hello);
+        System.in.read();
+    }
+}
+```
+
+运行结果如下:
+
+```shell
+[03/08/18 01:42:31:031 CST] main  INFO zookeeper.ZookeeperRegistry:  [DUBBO] 
Register: 
consumer://192.168.99.1/com.alibaba.dubbo.samples.api.GreetingService?application=demo-consumer&category=consumers&check=false&default.timeout=3000&dubbo=2.6.2&interface=com.alibaba.dubbo.samples.api.GreetingService&methods=sayHello&pid=82406&side=consumer&timestamp=1533274951195,
 dubbo version: 2.6.2, current host: 192.168.99.1 #1
+[03/08/18 01:42:31:031 CST] main  INFO zookeeper.ZookeeperRegistry:  [DUBBO] 
Subscribe: 
consumer://192.168.99.1/com.alibaba.dubbo.samples.api.GreetingService?application=demo-consumer&category=providers,configurators,routers&default.timeout=3000&dubbo=2.6.2&interface=com.alibaba.dubbo.samples.api.GreetingService&methods=sayHello&pid=82406&side=consumer&timestamp=1533274951195,
 dubbo version: 2.6.2, current host: 192.168.99.1 #2
+...
+result: hello, zookeeper
+```
+
+说明:
+
+1. **Register**: consumer://192.168.99.1/...&**category=consumers**&:消费者向 
Zookeeper 注册自己的信息,并放在 `consumers` 节点下
+2. **Subscribe**: 
consumer://192.168.99.1/...&**category=providers,configurators,routers**&:消费者同时向
 Zookeeper 订阅了 `providers`、`configurators`、`routers` 节点,其中 `configurations` 与 
Dubbo 配置相关,`routers` 与路由规则相关,值得注意的是 `providers` 
节点的订阅,当有新的服务提供方加入后,由于订阅的关系,新的地址列表会推送给订阅方,服务的消费者也因此动态感知到了地址列表的变化。
+
+通过 Zookeeper 管理终端观察服务提供方的注册信息:
+
+```sh
+$ docker exec -it zookeeper bash
+bash-4.4# bin/zkCli.sh -server localhost:218
+Connecting to localhost:2181
+...
+Welcome to ZooKeeper!
+JLine support is enabled
+...
+[zk: localhost:2181(CONNECTED) 4] ls 
/dubbo/com.alibaba.dubbo.samples.api.GreetingService/consumers
+[consumer%3A%2F%2F192.168.99.1%2Fcom.alibaba.dubbo.samples.api.GreetingService%3Fapplication%3Ddemo-consumer%26category%3Dconsumers%26check%3Dfalse%26default.timeout%3D3000%26dubbo%3D2.6.2%26interface%3Dcom.alibaba.dubbo.samples.api.GreetingService%26methods%3DsayHello%26pid%3D82406%26side%3Dconsumer%26timestamp%3D1533274951195]
+```
+
+可以看到 Dubbo 的服务消费者在 `consumers` 节点下注册了自己的 URL 
地址:*consumer://192.168.99.1/com.alibaba.dubbo.samples.api.GreetingService?application=demo-consumer&category=providers,configurators,routers&default.timeout=3000&dubbo=2.6.2&interface=com.alibaba.dubbo.samples.api.GreetingService&methods=sayHello&pid=82406&side=consumer&timestamp=1533274951195*
 
+
+## 总结
+
+本文侧重介绍了如何在 Dubbo 应用中使用 Zookeeper 做为注册中心,当然,本文也提到了 Zookeeper 在 Dubbo 
的应用场景下还承担了配置中心和服务治理的职责。本文中的 Zookeeper 是单节点、Standalone 的模式,在生产环境中为了高可用的诉求,往往会组件 
Zookeeper 集群,也就是 *Zookeeper ensemble* 模式。
+
+通过本文的学习,读者可以掌握到:
+
+* Zookeeper 的基本概念和基本用法
+* Zookeeper 在 Dubbo 应用中的作用
+* 通过实战了解 Zookeeper 与 Dubbo 的交互
+* Dubbo 在 Zookeeper 中服务注册、消费信息的存储方式
+
+
+
+[^1]: 
https://www.ixiacom.com/company/blog/apache-zab—zookeeper-atomic-broadcast-protocol
+[^2]: https://www.apache.org/dyn/closer.cgi/zookeeper/
+[^3]: https://brew.sh
+[^4]: https://www.docker.com/community-edition
+
diff --git a/build/1cb17ba6acec73c8197d.js b/build/0abb2937d4e2bc4697f3.js
similarity index 78%
rename from build/1cb17ba6acec73c8197d.js
rename to build/0abb2937d4e2bc4697f3.js
index 2b2ff4b..bdd543b 100644
--- a/build/1cb17ba6acec73c8197d.js
+++ b/build/0abb2937d4e2bc4697f3.js
@@ -3,4 +3,4 @@ webpackJsonp([4],[,,,,,,,function(e,t,n){"use strict";function 
r(e){return e&&e.
   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))e.push(n.apply(null,r));else if("object"===o)for(var a in 
r)i.call(r,a)&&r[a]&&e.push(a)}}return e.join(" ")}var i={}.hasOwnProperty;void 
0!==e&&e.exports?e.exports=n:(r=[],void 0!==(o=function(){return 
n}.apply(t,r))&&(e.exports=o))}()},function(e,t,n){"use strict";function 
r(e,t,r){var o=r.configurable,l= [...]
\ 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))e.push(n.apply(null,r));else if("object"===o)for(var a in 
r)i.call(r,a)&&r[a]&&e.push(a)}}return e.join(" ")}var i={}.hasOwnProperty;void 
0!==e&&e.exports?e.exports=n:(r=[],void 0!==(o=function(){return 
n}.apply(t,r))&&(e.exports=o))}()},function(e,t,n){"use strict";function 
r(e,t,r){var o=r.configurable,l= [...]
\ No newline at end of file
diff --git a/build/0b0bbf419be1d7b49571.js b/build/0b0bbf419be1d7b49571.js
deleted file mode 100644
index c94f059..0000000
--- a/build/0b0bbf419be1d7b49571.js
+++ /dev/null
@@ -1,6 +0,0 @@
-webpackJsonp([1],[,,,,,,,,function(s,n,a){"use strict";function e(s){return 
s&&s.__esModule?s:{default:s}}function t(s,n){if(!(s instanceof n))throw new 
TypeError("Cannot call a class as a function")}function l(s,n){if(!s)throw new 
ReferenceError("this hasn't been initialised - super() hasn't been 
called");return!n||"object"!=typeof n&&"function"!=typeof n?s:n}function 
o(s,n){if("function"!=typeof n&&null!==n)throw new TypeError("Super expression 
must either be null or a function, not "+ [...]
-  Copyright (c) 2016 Jed Watson.
-  Licensed under the MIT License (MIT), see
-  http://jedwatson.github.io/classnames
-*/
-!function(){"use strict";function a(){for(var 
s=[],n=0;n<arguments.length;n++){var e=arguments[n];if(e){var t=typeof 
e;if("string"===t||"number"===t)s.push(e);else 
if(Array.isArray(e))s.push(a.apply(null,e));else if("object"===t)for(var o in 
e)l.call(e,o)&&e[o]&&s.push(o)}}return s.join(" ")}var l={}.hasOwnProperty;void 
0!==s&&s.exports?s.exports=a:(e=[],void 0!==(t=function(){return 
a}.apply(n,e))&&(s.exports=t))}()},function(s,n,a){"use strict";function 
e(s,n,e){var t=e.configurable,p= [...]
\ No newline at end of file
diff --git a/build/de65f8eca3ff7556b8db.js b/build/197de76506a1ddd84a4b.js
similarity index 100%
rename from build/de65f8eca3ff7556b8db.js
rename to build/197de76506a1ddd84a4b.js
diff --git a/build/55de20a411cd16ffcaad.js b/build/55de20a411cd16ffcaad.js
new file mode 100644
index 0000000..1445dec
--- /dev/null
+++ b/build/55de20a411cd16ffcaad.js
@@ -0,0 +1,6 @@
+webpackJsonp([1],[,,,,,,,,function(s,n,a){"use strict";function e(s){return 
s&&s.__esModule?s:{default:s}}function t(s,n){if(!(s instanceof n))throw new 
TypeError("Cannot call a class as a function")}function o(s,n){if(!s)throw new 
ReferenceError("this hasn't been initialised - super() hasn't been 
called");return!n||"object"!=typeof n&&"function"!=typeof n?s:n}function 
l(s,n){if("function"!=typeof n&&null!==n)throw new TypeError("Super expression 
must either be null or a function, not "+ [...]
+  Copyright (c) 2016 Jed Watson.
+  Licensed under the MIT License (MIT), see
+  http://jedwatson.github.io/classnames
+*/
+!function(){"use strict";function a(){for(var 
s=[],n=0;n<arguments.length;n++){var e=arguments[n];if(e){var t=typeof 
e;if("string"===t||"number"===t)s.push(e);else 
if(Array.isArray(e))s.push(a.apply(null,e));else if("object"===t)for(var l in 
e)o.call(e,l)&&e[l]&&s.push(l)}}return s.join(" ")}var o={}.hasOwnProperty;void 
0!==s&&s.exports?s.exports=a:(e=[],void 0!==(t=function(){return 
a}.apply(n,e))&&(s.exports=t))}()},function(s,n,a){"use strict";function 
e(s,n,e){var t=e.configurable,p= [...]
\ No newline at end of file
diff --git a/build/2796ed1d026d7ba627aa.js b/build/87c67c0d7caf73d7e493.js
similarity index 100%
rename from build/2796ed1d026d7ba627aa.js
rename to build/87c67c0d7caf73d7e493.js
diff --git a/build/49955d02abb36f898304.js b/build/c5ce7257df274bc595ec.js
similarity index 55%
rename from build/49955d02abb36f898304.js
rename to build/c5ce7257df274bc595ec.js
index ca38086..cff5452 100644
--- a/build/49955d02abb36f898304.js
+++ b/build/c5ce7257df274bc595ec.js
@@ -3,4 +3,4 @@ webpackJsonp([0],[,,,,,,,,,,function(s,n,a){"use 
strict";function e(s){return s&
   Licensed under the MIT License (MIT), see
   http://jedwatson.github.io/classnames
 */
-!function(){"use strict";function a(){for(var 
s=[],n=0;n<arguments.length;n++){var e=arguments[n];if(e){var t=typeof 
e;if("string"===t||"number"===t)s.push(e);else 
if(Array.isArray(e))s.push(a.apply(null,e));else if("object"===t)for(var o in 
e)l.call(e,o)&&e[o]&&s.push(o)}}return s.join(" ")}var l={}.hasOwnProperty;void 
0!==s&&s.exports?s.exports=a:(e=[],void 0!==(t=function(){return 
a}.apply(n,e))&&(s.exports=t))}()},function(s,n,a){"use strict";function 
e(s,n,e){var t=e.configurable,r= [...]
\ No newline at end of file
+!function(){"use strict";function a(){for(var 
s=[],n=0;n<arguments.length;n++){var e=arguments[n];if(e){var t=typeof 
e;if("string"===t||"number"===t)s.push(e);else 
if(Array.isArray(e))s.push(a.apply(null,e));else if("object"===t)for(var o in 
e)l.call(e,o)&&e[o]&&s.push(o)}}return s.join(" ")}var l={}.hasOwnProperty;void 
0!==s&&s.exports?s.exports=a:(e=[],void 0!==(t=function(){return 
a}.apply(n,e))&&(s.exports=t))}()},function(s,n,a){"use strict";function 
e(s,n,e){var t=e.configurable,r= [...]
\ No newline at end of file
diff --git a/build/page.js b/build/page.js
index b91cc45..63766c6 100644
--- a/build/page.js
+++ b/build/page.js
@@ -1 +1 @@
-!function(n){function o(t){if(e[t])return e[t].exports;var 
r=e[t]={i:t,l:!1,exports:{}};return 
n[t].call(r.exports,r,r.exports,o),r.l=!0,r.exports}var 
t=window.webpackJsonp;window.webpackJsonp=function(o,e,a){for(var 
i,d,l=0,c=[];l<o.length;l++)d=o[l],r[d]&&c.push(r[d][0]),r[d]=0;for(i in 
e)Object.prototype.hasOwnProperty.call(e,i)&&(n[i]=e[i]);for(t&&t(o,e,a);c.length;)c.shift()()};var
 e={},r={5:0};o.e=function(n){function 
t(){d.onerror=d.onload=null,clearTimeout(l);var o=r[n];0!==o&&(o [...]
\ No newline at end of file
+!function(n){function o(t){if(e[t])return e[t].exports;var 
r=e[t]={i:t,l:!1,exports:{}};return 
n[t].call(r.exports,r,r.exports,o),r.l=!0,r.exports}var 
t=window.webpackJsonp;window.webpackJsonp=function(o,e,a){for(var 
i,d,l=0,c=[];l<o.length;l++)d=o[l],r[d]&&c.push(r[d][0]),r[d]=0;for(i in 
e)Object.prototype.hasOwnProperty.call(e,i)&&(n[i]=e[i]);for(t&&t(o,e,a);c.length;)c.shift()()};var
 e={},r={5:0};o.e=function(n){function 
t(){d.onerror=d.onload=null,clearTimeout(l);var o=r[n];0!==o&&(o [...]
\ No newline at end of file
diff --git a/img/blog/dubbo-in-zk.jpg b/img/blog/dubbo-in-zk.jpg
new file mode 100644
index 0000000..f715e52
Binary files /dev/null and b/img/blog/dubbo-in-zk.jpg differ
diff --git a/img/blog/zk-emsemble.png b/img/blog/zk-emsemble.png
new file mode 100644
index 0000000..cd51fb2
Binary files /dev/null and b/img/blog/zk-emsemble.png differ
diff --git a/img/blog/zk-tree.png b/img/blog/zk-tree.png
new file mode 100644
index 0000000..fc9c031
Binary files /dev/null and b/img/blog/zk-tree.png differ
diff --git a/md_json/blog.json b/md_json/blog.json
index 46823e9..2b9d325 100644
--- a/md_json/blog.json
+++ b/md_json/blog.json
@@ -21,6 +21,10 @@
       "__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-an
 [...]
     },
     {
+      "filename": "dubbo-zk.md",
+      "__html": "<h1>在 Dubbo 应用中使用 Zookeeper</h1>\n<h2>Zookeeper 
介绍</h2>\n<h3>基本概念</h3>\n<p>在现代的分布式应用中,往往会出现节点和节点之间的协调问题,其中就包括了:选主、集群管理、分布式锁、分布式配置管理、统一命名服务、状态同步等诉求。<a
 href=\"https://zookeeper.apache.org\";>Apache 
Zookeeper</a>,正如它的名字所暗示的那样,<em>动物园管理员</em>,就是为了解决这些诉求的一个分布式协调服务框架。</p>\n<p>为了保证高可用,ZooKeeper
 本身也可以部署成集群模式,称之为 <em>ZooKeeper ensemble</em>。ZooKeeper 集群中始终确保其中的一台为 leader 
的角色,并通过 <em>ZAB (Zookeeper Atomic Broadcast Protocol) <sup 
class=\"footnote-ref\"><a href=\"#fn1\" id=\"fnref1\ [...]
+    },
+    {
       "filename": "dubbo2-js.md",
       "__html": "<h1>从跨语言调用到dubbo2.js</h1>\n<blockquote>\n<p><a 
href=\"https://github.com/dubbo/dubbo2.js\";>dubbo2.js</a> 是 <a 
href=\"https://www.qianmi.com/\";>千米网</a> 贡献给 dubbo 社区的一款 nodejs dubbo 客户端,它提供了 
nodejs 对原生 dubbo 协议的支持,使得 nodejs 和 java 这两种异构语言的 rpc 
调用变得便捷,高效。</p>\n</blockquote>\n<h2>微服务跨语言调用</h2>\n<p>微服务架构已成为目前互联网架构的趋势,关于微服务的讨论,几乎占据了各种技术大会的绝大多数版面。国内使用最多的服务治理框架非阿里开源的
 dubbo 莫属,千米网也选择了 dubbo 作为微服务治理框架。另一方面,和大多数互联网公司一样,千米的开发语言是多样的,大多数后端业务由 java 
支撑,而每个业务线有各自开发语言的选择权,便出现了 nodejs,pyth [...]
     },
diff --git a/md_json/docs.json b/md_json/docs.json
index 93ea2b2..913d377 100644
--- a/md_json/docs.json
+++ b/md_json/docs.json
@@ -626,11 +626,11 @@
     },
     {
       "filename": "user/references/xml/dubbo-protocol.md",
-      "__html": "<style>\ntable {\n  width: 100%;\n  max-width: 65em;\n  
border: 1px solid #dedede;\n  margin: 15px auto;\n  border-collapse: 
collapse;\n  empty-cells: show;\n}\ntable th,\ntable td {\n  height: 35px;\n  
border: 1px solid #dedede;\n  padding: 0 10px;\n}\ntable th {\n  font-weight: 
bold;\n  text-align: center !important;\n  background: rgba(158,188,226,0.2);\n 
 white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n  background: 
rgba(158,188,226,0.12);\n}\ntable td:nth-c [...]
+      "__html": "<style>\ntable {\n  width: 100%;\n  max-width: 65em;\n  
border: 1px solid #dedede;\n  margin: 15px auto;\n  border-collapse: 
collapse;\n  empty-cells: show;\n}\ntable th,\ntable td {\n  height: 35px;\n  
border: 1px solid #dedede;\n  padding: 0 10px;\n}\ntable th {\n  font-weight: 
bold;\n  text-align: center !important;\n  background: rgba(158,188,226,0.2);\n 
 white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n  background: 
rgba(158,188,226,0.12);\n}\ntable td:nth-c [...]
     },
     {
       "filename": "user/references/xml/dubbo-provider.md",
-      "__html": "<style>\ntable {\n  width: 100%;\n  max-width: 65em;\n  
border: 1px solid #dedede;\n  margin: 15px auto;\n  border-collapse: 
collapse;\n  empty-cells: show;\n}\ntable th,\ntable td {\n  height: 35px;\n  
border: 1px solid #dedede;\n  padding: 0 10px;\n}\ntable th {\n  font-weight: 
bold;\n  text-align: center !important;\n  background: rgba(158,188,226,0.2);\n 
 white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n  background: 
rgba(158,188,226,0.12);\n}\ntable td:nth-c [...]
+      "__html": "<style>\ntable {\n  width: 100%;\n  max-width: 65em;\n  
border: 1px solid #dedede;\n  margin: 15px auto;\n  border-collapse: 
collapse;\n  empty-cells: show;\n}\ntable th,\ntable td {\n  height: 35px;\n  
border: 1px solid #dedede;\n  padding: 0 10px;\n}\ntable th {\n  font-weight: 
bold;\n  text-align: center !important;\n  background: rgba(158,188,226,0.2);\n 
 white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n  background: 
rgba(158,188,226,0.12);\n}\ntable td:nth-c [...]
     },
     {
       "filename": "user/references/xml/dubbo-reference.md",
@@ -1244,11 +1244,11 @@
     },
     {
       "filename": "user/references/xml/dubbo-protocol.md",
-      "__html": "<style>\ntable {\n  width: 100%;\n  max-width: 65em;\n  
border: 1px solid #dedede;\n  margin: 15px auto;\n  border-collapse: 
collapse;\n  empty-cells: show;\n}\ntable th,\ntable td {\n  height: 35px;\n  
border: 1px solid #dedede;\n  padding: 0 10px;\n}\ntable th {\n  font-weight: 
bold;\n  text-align: center !important;\n  background: rgba(158,188,226,0.2);\n 
 white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n  background: 
rgba(158,188,226,0.12);\n}\ntable td:nth-c [...]
+      "__html": "<style>\ntable {\n  width: 100%;\n  max-width: 65em;\n  
border: 1px solid #dedede;\n  margin: 15px auto;\n  border-collapse: 
collapse;\n  empty-cells: show;\n}\ntable th,\ntable td {\n  height: 35px;\n  
border: 1px solid #dedede;\n  padding: 0 10px;\n}\ntable th {\n  font-weight: 
bold;\n  text-align: center !important;\n  background: rgba(158,188,226,0.2);\n 
 white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n  background: 
rgba(158,188,226,0.12);\n}\ntable td:nth-c [...]
     },
     {
       "filename": "user/references/xml/dubbo-provider.md",
-      "__html": "<style>\ntable {\n  width: 100%;\n  max-width: 65em;\n  
border: 1px solid #dedede;\n  margin: 15px auto;\n  border-collapse: 
collapse;\n  empty-cells: show;\n}\ntable th,\ntable td {\n  height: 35px;\n  
border: 1px solid #dedede;\n  padding: 0 10px;\n}\ntable th {\n  font-weight: 
bold;\n  text-align: center !important;\n  background: rgba(158,188,226,0.2);\n 
 white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n  background: 
rgba(158,188,226,0.12);\n}\ntable td:nth-c [...]
+      "__html": "<style>\ntable {\n  width: 100%;\n  max-width: 65em;\n  
border: 1px solid #dedede;\n  margin: 15px auto;\n  border-collapse: 
collapse;\n  empty-cells: show;\n}\ntable th,\ntable td {\n  height: 35px;\n  
border: 1px solid #dedede;\n  padding: 0 10px;\n}\ntable th {\n  font-weight: 
bold;\n  text-align: center !important;\n  background: rgba(158,188,226,0.2);\n 
 white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n  background: 
rgba(158,188,226,0.12);\n}\ntable td:nth-c [...]
     },
     {
       "filename": "user/references/xml/dubbo-reference.md",
diff --git a/site_config/blog.js b/site_config/blog.js
index 83e83fa..3b5e104 100644
--- a/site_config/blog.js
+++ b/site_config/blog.js
@@ -52,6 +52,13 @@ export default {
     postsTitle: '所有文章',
     list: [
       {
+        title: '在 Dubbo 应用中使用 Zookeeper',
+        author: '@beiwei30',
+        dateStr: 'August 3rd, 2018',
+        desc: '介绍了 Zookeeper 的基本概念、用法,以及如何在 Dubbo 应用中使用 Zookeeper 作为注册中心。',
+        link: '/blog/dubbo-zk.md',
+      },
+      {
         title: '通过QoS对服务进行动态控制',
         author: 'Huxing Zhang',
         dateStr: 'August 2nd, 2018',

Reply via email to