“没有最好的技术,只有最合适的技术。”我想这句话也同样适用于微服务领域, 没有最好的服务框架,只有最适合自己的服务改造 。在 Dubbo 的未来规划中,除了保持自身技术上的领先性,关注性能、大流量、大规模集群领域的挑战外,围绕 Dubbo 核心来发展生态,将 Dubbo 打造成一个服务化改造的整体方案也是重点之一。 从本期开始,我们将推出“服务化改造”系列文章,通过在一些外围系统和服务化基础组件上的开发实践,分享Dubbo 生态下的服务化改造收获和总结。
» 8月26日,Aliware Open Source 将首次在成都举办 Apache Dubbo 的meetup活动,Dubbo 、Sentinel和 Nacos 的小哥哥和小姐姐都会在现场进行技术分享,欢迎成都的朋友报名参加我们的活动喔,公众号后台发送“ 成都meetup ”,获取报名链接。
一、改造背景
在现代的分布式应用中,往往会出现节点和节点之间的协调问题,其中就包括了: 选主,集群管理,分布式锁,分布式配置管理,统一命名服务,状态同步 等诉求。Apache ZooKeeper,正如它的名字所暗示的那样,动物园管理员,就是为了解决这些诉求的一个分布式 协调 服务框架。
为了保证系统的高可用,ZooKeeper本身也可以部署成集群模式,称之为ZooKeeper Ensemble。ZooKeeper集群中始终确保其中的一台为leader的角色,并通过ZAB(Zookeeper Atomic Broadcast Protocol) [1] 协议确保所有节点上的信息的一致。客户端可以访问集群中的任何一台进行读写操作,而不用担心数据出现不一致的现象。
O'Reilly的ebook-Zookeeper-Distributed Process Coordination
Zookeeper中的数据存储方式与传统的UNIX文件系统相似,节点按照树状结构来组织,其中,节点被称之为znodes(ZooKeeper数据节点)
O'Reilly的ebook-Zookeeper-Distributed Process Coordination
二、基本用法
可以通过直接下载的方式 [2] 安装并运行ZooKeeper,在Mac上也可以通过Homebrew [3] brew install zookeeper 来安装,考虑到通用性,本文采用 docker 的方式来运行ZooKeeper。如果没有安装docker,请先准备好docker环境 [4] 。
1、启动 ZooKeeper
执行命令将 ZooKeeper,运行在docker容器中
docker run --rm --name zookeeper -p 2181:2181 zookeeper
2、进入 Zookeeper 容器
docker exec -it zookeeper bash
在 bin 目录下有启动 ZooKeeper 的命令 zkServer 以及管理控制台 zkCli
bash-4.4# ls -l bintotal 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端口对外提供服务。
bash-4.4# psPID 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 的控制台来进行管理。
bash-4.4# bin/zkCli.sh -server 127.0.0.1:2181Connecting to 127.0.0.1:2181... WATCHER:: WatchedEvent state:SyncConnected type:None path:null[zk: 127.0.0.1:2181(CONNECTED) 0] helpZooKeeper -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 节点:
[zk: 127.0.0.1:2181(CONNECTED) 19] create /hello-zone 'world'Created /hello-zone
列出 / 下的子节点,确认 hello-zone 被创建:
[zk: 127.0.0.1:2181(CONNECTED) 19] create /hello-zone 'world'Created /hello-zone
列出 /hello-zone 的子节点,确认为空:
[zk: 127.0.0.1:2181(CONNECTED) 21] ls /hello-zone[]
获取存储在 /hello-zone 节点上的数据:
[zk: 127.0.0.1:2181(CONNECTED) 22] get /hello-zone world
三、在 Dubbo 中使用ZooKeeper
Dubbo使用 ZooKeeper 用于服务的注册发现和配置管理,在 ZooKeeper 中数据的组织由下图所示:
首先,所有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 向调用者问好。
public interface GreetingService {
String sayHello(String name);}
2、服务端:服务实现
实现 GreetingService 接口,并通过 @Service 来标注其为Dubbo的一个服务。
@Servicepublic class AnnotatedGreetingService implements GreetingService {
public String sayHello(String name) {
return "hello, " + name;
}}
3、服务端:组装
定义 ProviderConfiguration 来组装Dubbo服务。
@Configuration@EnableDubbo(scanBasePackages = "com.alibaba.dubbo.samples.impl")@PropertySource("classpath:/spring/dubbo-provider.properties")static class ProviderConfiguration {}
dubbo-provider.properties是在Spring应用中外置配置的方式,内容如下:
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服务。
public class ProviderBootstrap {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class);
context.start();
System.in.read();
}}
服务启动端的的 main 方法,将会看到下面的输出,代表服务端启动成功,并在注册中心( ZooKeeper Registry)注册上了 GreetingService 这个服务 :
[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×tamp=1533264631849, dubbo version: 2.6.2, current host: 192.168.99.1
通过 ZooKeeper 管理终端观察服务提供方的注册信息:
$ 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 0.2&通用=假接口=com.alibaba.dubbo.samples.api.GreetingService&方法= sayHello的&PID = 12938&侧=提供商时间戳=1533264631849
5、客户端:引用服务
通过 @Reference 来在客户端声明服务的引用,运行时将会通过该引用发起全程调用,而服务的目标地址将会从 ZooKeeper 的 provider 节点下查询。
@Component("annotatedConsumer")public class GreetingServiceConsumer {
@Reference
private GreetingService greetingService;
public String doSayHello(String name) {
return greetingService.sayHello(name);
}}
6、客户端:组装
定义ConsumerConfiguration来组装Dubbo服务。
@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应用中外置配置的方式,内容如下:
dubbo.application.name=demo-consumer dubbo.registry.address=zookeeper://$DOCKER_HOST:2181 dubbo.consumer.timeout=3000
与服务端:组装相同,需要根据自己的运行环境来修改dubbo.registry.address中定义的$ DOCKER_HOST。请参阅步骤3的说明部分。
7、客户端:发起远程调用
运行 main 向已经启动的服务提供方发起一次远程调用。Dubbo会先向 ZooKeeper 订阅服务地址,然后从返回的地址列表中选取一个,向对端发起调用:
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();
}
}
运行结果如下:
[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✓=false&default.timeout=3000&dubbo=2.6.2&interface=com.alibaba.dubbo.samples.api.GreetingService&methods=sayHello&pid=82406&side=consumer×tamp=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×tamp=1533274951195, dubbo version: 2.6.2, current host: 192.168.99.1 #2... result: hello, zookeeper
#说明:
a. 注册:消费者://192.168.99.1/...& category= consumers &:消费者向 ZooKeeper 注册自己的信息,并放在 consumers 节点下
b. 订阅:消费者://192.168.99.1/...& 类别=提供商,配置器,路由器:消费者同时向动物园管理员订阅了 providers 、 configurators 、 routers 节点,其中 configurations 与多宝配置相关, routers 与路由规则相关,值得注意的英文 providers 节点的订阅,当有新的服务提供方加入后,由于订阅的关系,新的地址列表会推送给订阅方,服务的消费者也因此动态感知到了地址列表的变化。
通过 ZooKeeper 管理终端观察服务提供方的注册信息:
$ 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= provider,configurators,routers&default。超时= 3000&达博= 2.6.2&接口= com.alibaba.dubbo.samples.api.GreetingService&方法=sayHello的&PID =82406&侧=消费者的时间戳=1533274951195
五、总结
本文侧重介绍了如何在Dubbo应用中使用Zookeeper做为注册中心,当然,本文也提到了Zookeeper在Dubbo的应用场景下还承担了配置中心和服务治理的职责。本文中的Zookeeper是单节点,Standalone的模式,在生产环境中为了高可用的诉求,往往会组件Zookeeper集群,也就是Zookeeper ensemble模式。
通过本文的学习,读者可以掌握到:
-
ZooKeeper 的基本概念和基本用法
-
ZooKeeper 在Dubbo应用中的作用
-
通过实战了解 ZooKeeper 与Dubbo的交互
-
Dubbo在 ZooKeeper 中服务注册,消费信息的存储方式
当然,自从阿里巴巴开源 Nacos 后, Dubbo生态中又多了一项动态服务发现的选项, Nacos + Dubbo的组合正进一步释放 Dubbo 在云原生及ServiceMesh时代中,在大规模微服务治理、流量治理、服务集成与服务共享等服务平台能力建设上的威力。详情请见文末 “今日推文”。
参考链接:
[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
今日推文
点击下方图片即可阅读
» 阿里巴巴发布 Nacos v0.1.0版本,回顾自研 10 年路
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 马蜂窝火车票系统服务化改造初探
- 明星分分合合的洪荒点击量,微博Mesh服务化改造如何支撑?(附PPT下载)
- 浅谈服务化和微服务化(上)
- 微服务化之服务拆分与服务发现
- 微服务化之服务拆分与服务发现
- 微服务时代组件化和服务化的抉择
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Usability for the Web
Tom Brinck、Darren Gergle、Scott D. Wood / Morgan Kaufmann / 2001-10-15 / USD 65.95
Every stage in the design of a new web site is an opportunity to meet or miss deadlines and budgetary goals. Every stage is an opportunity to boost or undercut the site's usability. Thi......一起来看看 《Usability for the Web》 这本书的介绍吧!
HTML 压缩/解压工具
在线压缩/解压 HTML 代码
随机密码生成器
多种字符组合密码