dubbo+zookeeper构建微服务架构

喜欢ヅ旅行 2022-01-27 23:09 413阅读 0赞

微服务架构成了当下的技术热点,实现微服务是要付出很大成本的,但也许是因为微服务的优点太过于吸引人,以至于大部分开发者都将它当成未来的发展趋势。

  1. 微服务架构的演进过程
  2. dubbo的用户手册中介绍了服务化架构的进化过程,如下图:

图一、服务化架构的演进过程

  1. 1.orm 单一应用架构
  2. 一个高内聚版本,所有功能部署在一起。数据访问框架(orm)成为关键。这个架构很少被人使用,几乎接近灭绝了吧。
  3. 优点:成本低,适合功能少又简单 缺点:很多,比如无法适应高流量,二次开发难,部署成本高
  4. 2.mvc架构 垂直应用架构
  5. 当访问量渐渐增大,慢慢演化成用的很多的mvc架构。虽然还是所有的功能都是部署在同一个进程中,但是可以通过双机或者前置负载均衡来实现负载分流。这样应用也可以拆分成不同的几个应用,以提升性能和效率。
  6. 此时,mvc架构用于分离前后端逻辑。一方面,有一定的模块化。另一方面,加速和方便了开发。
  7. 3.rpc架构 分布式服务架构
  8. mvc垂直应用分成不同应用时,越来越多的情况下。不可避免的事应用a与应用b之间的交互。此时将核心和公共的 业务功能抽出来,作为单独的服务,并实现前后端逻辑分离。
  9. 此时则就需要提高业务的复用及整合的分布式rpc框架,例如dubbo等。
  10. 4.soa架构 流动计算架构
  11. rpc架构中的服务越来越多时,服务的生命周期的管控,容量的评估等各种问题会出现,使服务化成为瓶颈。需要增加一个调度中心来进行对服务管控,监督等。
  12. 5.微服务架构
  13. soa的基础上,人们又提出了微服务架构,它就是将功能分散到各个离散的服务中然后实现对方案的解耦。服务更原子,自治更小,然后高密度部署服务。
  14. 微服务的技术关注点
  15. 要实现一个微服务的架构,我们需要关注的技术点包括:服务注册、发现、负载均衡和健康检查,前端路由(网关),容错,服务框架的选择,动态配置管理等模块。这些模块可以组成一个简化的微服务架构图如下:

图二、简化的微服务架构图

  1. 笔者使用蚂蚁金融云有一年的时间,蚂蚁金服通过蚂蚁金融云输出了积累多年的技术组件。给其他企业的服务化体系和框架建设提供了很好的设计思路。除了微服务所需要的基础组件之外,还提供了分布式消息组件,分库分表组件,分布式调度组件等企业开发常用的中间件。根据蚂蚁金融云的设计思路,一个网站的基础组件架构图如下:

图三、网站的基础组件架构图

  1. 可惜蚂蚁金融云中的产品并不是开源的,一个企业想拥有属于自己的网站架构,就要选出最适合的开源的服务框架实现这些组件,从而使后续开发者更关注于业务逻辑实现。
  2. 这些组件的实现方式以后有时间的话会一一讲解,这篇文章接下来先介绍一下dubbo+zookeeper来实现微服务中的前端服务、后端通用服务、服务注册中心中所涉及到的功能。
  3. 使用dubbo+zookeeper实现简化的微服务架构
  4. dubbo是一个分布式服务框架,是阿里巴巴SOA服务化治理方案的核心框架。zookeeper是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。zookeeper可以作为dubbo服务的注册中心,两者结合起来可以实现微服务中的 服务注册、发现、负载均衡和健康检查,容错,动态配置管理的功能。由于dubbo没有提供前端路由的功能,所以我们还需实现一个具备监控、安全认证、限流、服务反向路由功能的网关组件才能实现完整的微服务。这个组件实现起来比较复杂,在这篇文章中不做介绍,我们先用springMVCdubbo服务暴露成浏览器可访问的http接口。
  5. 第一步:zookeeper集群的部署
  6. 使用zookeeper作为dubbo的注册中心,部署起来并不麻烦。为了保持注册中心的高可用性,在生产环境下我们需要配置多个zookeeper协同运行。在集群模式下,zookeeper会基于Paxos算法从集群中选择一台作为leader,其他机器作为follower,注册中心的数据都以leader为准。一台zk机器成为leader的条件是超过这台机器是可用的,且被超过半数的机器选举为leader。基于这种实现方式,我们选择zk集群的数量时最好为奇数个,最少为3个,这样只要有超过半数的zk机器存活那注册中心就是可用的。
  7. 注:如果我们选择2台机器作为zk的集群,那只要有一台zk挂掉,另一台机器就无法得到超过半数的选票,那么这个zk集群就直接失效了。因此选2台机器作为zk集群的稳定性在理论上不如一台机器作为注册中心的稳定性。
  8. 3台机器作为zk集群为例,每台zk的具体部署方式为:
  9. 1、下载安装包并解压到安装目录,zookeeper安装包的下载地址为:http://www.apache.org/dist/zookeeper/
  10. 2、进入解压目录的conf文件夹,配置zookeeper启动的基本参数。
  11. conf文件夹下有一个 zoo_sample.cfg的文件,是zk启动的配置样例,zookeeper进程在启动的时候会找zoo.cfg文件作为默认的配置文件,所以我们复制一个名称为zoo.cfg的文件,并编辑其中的配置信息如下:

图四、zookeeper的配置文件

  1. 图中用红框标出来的地方是zk启动需要额外注意的参数:
  2. dataDir为内存数据库快照的存放位置,
  3. clientPort zk进程的监听端口
  4. server.A=B:C:D
  5. A为数字,标识这条配置为第几个zk服务器,即机器id
  6. Bhost名,标识这个服务器的主机地址
  7. CDzk集群的成员用于选举leader时的通讯端口
  8. 3、在dataDir路径下创建myid文件,标识这台机器对应的机器id
  9. 4、运行zookeeper进程,在zookeeper目录下的bin文件夹中,运行
  10. ./zkServer.sh start
  11. ps: 停止方法——运行 ./zkServer.sh stop
  12. 5、服务验证
  13. zk进程启动后,默认会从三台机器中选出一个leader2follower,在bin目录下运行./zkServer.sh status可以查看zk进程的运行状态

图五、三台机器zookeeper的运行状态

  1. 如图所示,集群选择zoo2作为leader,其他机器作为 follower 的方式运行。
  2. 第二步:开发前端服务和后端通用服务
  3. 第二步需要创建两个项目:
  4. 我们使用springMVC模块代替一下服务前端路由,与前端服务合成一个项目,作为服务的调用者。
  5. 开发一个后端通用服务接口,作为服务的提供者。
  6. 如果开发者是用maven做的项目管理,给大家推荐一个十分实用的多模块项目结构,模块的分层和依赖关系如下:

图六:项目模块划分

  1. 如果项目的数据层操作比较复杂,可以在DAO层前面加一个领域层,模块依赖关系如下:

图七:项目模块划分(带领域层)

  1. 按照图中的maven模块结构,我们生成服务提供方和服务调用方两个项目,如图:

图八、服务提供方项目结构

图九、服务调用方项目结构

  1. 我们将服务提供方命名为dubboservice,服务调用方命名为dubboclient
  2. 首先在dubboservice项目中实现一个简单的Hello World 服务。
  3. 1、接口:
  4. public interface TestService {
  5. String sayHello(String name);
  6. }
  7. 2、实现类:
  8. @Service("testService")
  9. public class TestServiceImpl implements TestService {
  10. @Override
  11. public String sayHello(String name) {
  12. return String.format("Hi! Client_%s! ", name);
  13. }
  14. }
  15. 3、然后在dubboservice中引入dubbozookeeper所用的依赖,坐标如下:
  16. <dependency>
  17. <groupId>com.alibaba</groupId>
  18. <artifactId>dubbo</artifactId>
  19. <version>2.5.3</version>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.apache.zookeeper</groupId>
  23. <artifactId>zookeeper</artifactId>
  24. <version>3.4.5</version>
  25. </dependency>
  26. <dependency>
  27. <groupId>com.github.sgroschupf</groupId>
  28. <artifactId>zkclient</artifactId>
  29. <version>0.1</version>
  30. </dependency>
  31. 4、将Hello World服务在spring的配置文件中暴露出来,如图:

<?xml version=”1.0” encoding=”UTF-8”?>

  1. <!--提供方应用信息,用于计算依赖关系-->
  2. <dubbo:application name="dubboservice_provider" />
  3. <!--使用zookeeper注册中心暴露服务地址-->
  4. <dubbo:registry protocol="zookeeper" address="10.139.99.231:2181,10.139.106.145:2181,10.139.103.116:2181"/>
  5. <!--声明需要暴露的服务接口-->
  6. <dubbo:service interface="org.zhdd.test.dubboservice.service.TestService" ref="testService"/>
  7. 5、将dubboservice项目启动,我们便向注册中心提供了一个简易的后端通用服务。
  8. 然后在dubboclient项目中实现对后端服务的引用,和对外的路由
  9. 1、除了在dubboclient中引入dubbo,zookeeper所用的依赖之外,我们还需要引入dubboservice中所用到的服务依赖,如下:
  10. <dependency>
  11. <groupId>com.alibaba</groupId>
  12. <artifactId>dubbo</artifactId>
  13. <version>2.5.3</version>
  14. </dependency>
  15. <dependency>
  16. <groupId>org.apache.zookeeper</groupId>
  17. <artifactId>zookeeper</artifactId>
  18. <version>3.4.5</version>
  19. </dependency>
  20. <dependency>
  21. <groupId>com.github.sgroschupf</groupId>
  22. <artifactId>zkclient</artifactId>
  23. <version>0.1</version>
  24. </dependency>
  25. <!--
  26. 服务提供方的接口依赖
  27. -->
  28. <dependency>
  29. <groupId>org.zhdd.test</groupId>
  30. <artifactId>dubboservice-service</artifactId>
  31. <version>1.0.0-SNAPSHOT</version>
  32. </dependency>
  33. 2、在spring的配置文件中声明所引用的服务:
  34. <!--提供方应用信息,用于计算依赖关系-->
  35. <dubbo:application name="dubboservice_consumer" />
  36. <!--使用zookeeper注册中心暴露服务地址-->
  37. <dubbo:registry protocol="zookeeper" address="10.139.99.231:2181,10.139.106.145:2181,10.139.103.116:2181"/>
  38. <!--声明需要暴露的服务接口-->
  39. <dubbo:reference interface="org.zhdd.test.dubboservice.service.TestService" id="testService"/>
  40. 3、新建一个controller,将引用的服务通过controller暴露出去,代码如下:
  41. @Controller
  42. public class HelloController {
  43. @Autowired
  44. private TestService testService;
  45. @RequestMapping("/hello/{name}")
  46. @ResponseBody
  47. public String hello(@PathVariable String name){
  48. String rslt=testService.sayHello(name);
  49. return rslt;
  50. }
  51. }
  52. 4、启动项目,这个时候dubboclient 就成功引用到了dubboservice的服务
  53. 我们通过浏览器访问dubboclient暴露出来的接口,确保dubboclient可以正常调用到dubboservice的具体实现,如图所示:
  54. 这样我们就成功部署了一个简易的微服务架构。
  55. 我们可以通过zookeeper的查看工具更直观的查看dubbo在zookeeper中的注册和订阅信息,此时的注册和订阅信息如下:

后续:

  1. dubbozookeeper的复杂配置还有很多,本文只介绍了dubbozookeeper最基本的用法。要想了解更多的信息可以通过官方文档进行学习:
  2. dubbo中文文档:http://dubbo.io/
  3. zookeeper文档:http://zookeeper.apache.org/

作者:zhdd99
来源:CSDN
原文:https://blog.csdn.net/zhdd99/article/details/52263609
版权声明:本文为博主原创文章,转载请附上博文链接! 微服务架构成了当下的技术热点,实现微服务是要付出很大成本的,但也许是因为微服务的优点太过于吸引人,以至于大部分开发者都将它当成未来的发展趋势。

微服务架构的演进过程

dubbo的用户手册中介绍了服务化架构的进化过程,如下图:

图一、服务化架构的演进过程

1.orm – 单一应用架构
一个高内聚版本,所有功能部署在一起。数据访问框架(orm)成为关键。这个架构很少被人使用,几乎接近灭绝了吧。
优点:成本低,适合功能少又简单 缺点:很多,比如无法适应高流量,二次开发难,部署成本高

2.mvc架构 - 垂直应用架构
当访问量渐渐增大,慢慢演化成用的很多的mvc架构。虽然还是所有的功能都是部署在同一个进程中,但是可以通过双机或者前置负载均衡来实现负载分流。这样应用也可以拆分成不同的几个应用,以提升性能和效率。
此时,mvc架构用于分离前后端逻辑。一方面,有一定的模块化。另一方面,加速和方便了开发。

3.rpc架构 - 分布式服务架构
当mvc垂直应用分成不同应用时,越来越多的情况下。不可避免的事应用a与应用b之间的交互。此时将核心和公共的 业务功能抽出来,作为单独的服务,并实现前后端逻辑分离。
此时则就需要提高业务的复用及整合的分布式rpc框架,例如dubbo等。

4.soa架构 - 流动计算架构
当rpc架构中的服务越来越多时,服务的生命周期的管控,容量的评估等各种问题会出现,使服务化成为瓶颈。需要增加一个调度中心来进行对服务管控,监督等。

5.微服务架构
在soa的基础上,人们又提出了微服务架构,它就是将功能分散到各个离散的服务中然后实现对方案的解耦。服务更原子,自治更小,然后高密度部署服务。

微服务的技术关注点

要实现一个微服务的架构,我们需要关注的技术点包括:服务注册、发现、负载均衡和健康检查,前端路由(网关),容错,服务框架的选择,动态配置管理等模块。这些模块可以组成一个简化的微服务架构图如下:

图二、简化的微服务架构图

笔者使用蚂蚁金融云有一年的时间,蚂蚁金服通过蚂蚁金融云输出了积累多年的技术组件。给其他企业的服务化体系和框架建设提供了很好的设计思路。除了微服务所需要的基础组件之外,还提供了分布式消息组件,分库分表组件,分布式调度组件等企业开发常用的中间件。根据蚂蚁金融云的设计思路,一个网站的基础组件架构图如下:

图三、网站的基础组件架构图

可惜蚂蚁金融云中的产品并不是开源的,一个企业想拥有属于自己的网站架构,就要选出最适合的开源的服务框架实现这些组件,从而使后续开发者更关注于业务逻辑实现。

这些组件的实现方式以后有时间的话会一一讲解,这篇文章接下来先介绍一下dubbo+zookeeper来实现微服务中的前端服务、后端通用服务、服务注册中心中所涉及到的功能。

使用dubbo+zookeeper实现简化的微服务架构

dubbo是一个分布式服务框架,是阿里巴巴SOA服务化治理方案的核心框架。zookeeper是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。zookeeper可以作为dubbo服务的注册中心,两者结合起来可以实现微服务中的 服务注册、发现、负载均衡和健康检查,容错,动态配置管理的功能。由于dubbo没有提供前端路由的功能,所以我们还需实现一个具备监控、安全认证、限流、服务反向路由功能的网关组件才能实现完整的微服务。这个组件实现起来比较复杂,在这篇文章中不做介绍,我们先用springMVC将dubbo服务暴露成浏览器可访问的http接口。

第一步:zookeeper集群的部署

使用zookeeper作为dubbo的注册中心,部署起来并不麻烦。为了保持注册中心的高可用性,在生产环境下我们需要配置多个zookeeper协同运行。在集群模式下,zookeeper会基于Paxos算法从集群中选择一台作为leader,其他机器作为follower,注册中心的数据都以leader为准。一台zk机器成为leader的条件是超过这台机器是可用的,且被超过半数的机器选举为leader。基于这种实现方式,我们选择zk集群的数量时最好为奇数个,最少为3个,这样只要有超过半数的zk机器存活那注册中心就是可用的。

注:如果我们选择2台机器作为zk的集群,那只要有一台zk挂掉,另一台机器就无法得到超过半数的选票,那么这个zk集群就直接失效了。因此选2台机器作为zk集群的稳定性在理论上不如一台机器作为注册中心的稳定性。

以3台机器作为zk集群为例,每台zk的具体部署方式为:

1、下载安装包并解压到安装目录,zookeeper安装包的下载地址为:http://www.apache.org/dist/zookeeper/

2、进入解压目录的conf文件夹,配置zookeeper启动的基本参数。

在conf文件夹下有一个 zoo_sample.cfg的文件,是zk启动的配置样例,zookeeper进程在启动的时候会找zoo.cfg文件作为默认的配置文件,所以我们复制一个名称为zoo.cfg的文件,并编辑其中的配置信息如下:

图四、zookeeper的配置文件

图中用红框标出来的地方是zk启动需要额外注意的参数:

dataDir为内存数据库快照的存放位置,

clientPort 为zk进程的监听端口

server.A=B:C:D

A为数字,标识这条配置为第几个zk服务器,即机器id

B为host名,标识这个服务器的主机地址

C和D为zk集群的成员用于选举leader时的通讯端口

3、在dataDir路径下创建myid文件,标识这台机器对应的机器id

4、运行zookeeper进程,在zookeeper目录下的bin文件夹中,运行

./zkServer.sh start

ps: 停止方法——运行 ./zkServer.sh stop

5、服务验证

zk进程启动后,默认会从三台机器中选出一个leader,2个follower,在bin目录下运行./zkServer.sh status可以查看zk进程的运行状态

图五、三台机器zookeeper的运行状态

如图所示,集群选择zoo2作为leader,其他机器作为 follower 的方式运行。

第二步:开发前端服务和后端通用服务

第二步需要创建两个项目:

我们使用springMVC模块代替一下服务前端路由,与前端服务合成一个项目,作为服务的调用者。

开发一个后端通用服务接口,作为服务的提供者。

如果开发者是用maven做的项目管理,给大家推荐一个十分实用的多模块项目结构,模块的分层和依赖关系如下:

图六:项目模块划分

如果项目的数据层操作比较复杂,可以在DAO层前面加一个领域层,模块依赖关系如下:

图七:项目模块划分(带领域层)

按照图中的maven模块结构,我们生成服务提供方和服务调用方两个项目,如图:

图八、服务提供方项目结构

图九、服务调用方项目结构

我们将服务提供方命名为dubboservice,服务调用方命名为dubboclient。

首先在dubboservice项目中实现一个简单的Hello World 服务。

1、接口:

  1. public interface TestService {
  2. String sayHello(String name);
  3. }

2、实现类:

  1. @Service("testService")
  2. public class TestServiceImpl implements TestService {
  3. @Override
  4. public String sayHello(String name) {
  5. return String.format("Hi! Client_%s! ", name);
  6. }
  7. }

3、然后在dubboservice中引入dubbo,zookeeper所用的依赖,坐标如下:

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>dubbo</artifactId>
  4. <version>2.5.3</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.zookeeper</groupId>
  8. <artifactId>zookeeper</artifactId>
  9. <version>3.4.5</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>com.github.sgroschupf</groupId>
  13. <artifactId>zkclient</artifactId>
  14. <version>0.1</version>
  15. </dependency>

4、将Hello World服务在spring的配置文件中暴露出来,如图:

<?xml version=”1.0” encoding=”UTF-8”?>

  1. <!--提供方应用信息,用于计算依赖关系-->
  2. <dubbo:application name="dubboservice_provider" />
  3. <!--使用zookeeper注册中心暴露服务地址-->
  4. <dubbo:registry protocol="zookeeper" address="10.139.99.231:2181,10.139.106.145:2181,10.139.103.116:2181"/>
  5. <!--声明需要暴露的服务接口-->
  6. <dubbo:service interface="org.zhdd.test.dubboservice.service.TestService" ref="testService"/>

5、将dubboservice项目启动,我们便向注册中心提供了一个简易的后端通用服务。

然后在dubboclient项目中实现对后端服务的引用,和对外的路由

1、除了在dubboclient中引入dubbo,zookeeper所用的依赖之外,我们还需要引入dubboservice中所用到的服务依赖,如下:

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>dubbo</artifactId>
  4. <version>2.5.3</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.zookeeper</groupId>
  8. <artifactId>zookeeper</artifactId>
  9. <version>3.4.5</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>com.github.sgroschupf</groupId>
  13. <artifactId>zkclient</artifactId>
  14. <version>0.1</version>
  15. </dependency>
  16. <!--
  17. 服务提供方的接口依赖
  18. -->
  19. <dependency>
  20. <groupId>org.zhdd.test</groupId>
  21. <artifactId>dubboservice-service</artifactId>
  22. <version>1.0.0-SNAPSHOT</version>
  23. </dependency>

2、在spring的配置文件中声明所引用的服务:

  1. <!--提供方应用信息,用于计算依赖关系-->
  2. <dubbo:application name="dubboservice_consumer" />
  3. <!--使用zookeeper注册中心暴露服务地址-->
  4. <dubbo:registry protocol="zookeeper" address="10.139.99.231:2181,10.139.106.145:2181,10.139.103.116:2181"/>
  5. <!--声明需要暴露的服务接口-->
  6. <dubbo:reference interface="org.zhdd.test.dubboservice.service.TestService" id="testService"/>

3、新建一个controller,将引用的服务通过controller暴露出去,代码如下:

  1. @Controller
  2. public class HelloController {
  3. @Autowired
  4. private TestService testService;
  5. @RequestMapping("/hello/{name}")
  6. @ResponseBody
  7. public String hello(@PathVariable String name){
  8. String rslt=testService.sayHello(name);
  9. return rslt;
  10. }
  11. }

4、启动项目,这个时候dubboclient 就成功引用到了dubboservice的服务

我们通过浏览器访问dubboclient暴露出来的接口,确保dubboclient可以正常调用到dubboservice的具体实现,如图所示:

这样我们就成功部署了一个简易的微服务架构。

我们可以通过zookeeper的查看工具更直观的查看dubbo在zookeeper中的注册和订阅信息,此时的注册和订阅信息如下:

后续:

dubbo与zookeeper的复杂配置还有很多,本文只介绍了dubbo与zookeeper最基本的用法。要想了解更多的信息可以通过官方文档进行学习:

dubbo中文文档:http://dubbo.io/

zookeeper文档:http://zookeeper.apache.org/

作者:zhdd99
来源:CSDN
原文:https://blog.csdn.net/zhdd99/article/details/52263609
版权声明:本文为博主原创文章,转载请附上博文链接!

发表评论

表情:
评论列表 (有 0 条评论,413人围观)

还没有评论,来说两句吧...

相关阅读

    相关 如何构建服务架构

    相信很多人对微服务架构都会产生这样一些疑问,例如我要何时使用微服务架构?又如何将应用程序分解为微服务?分解后,要如何去搭建微服务架构?同时,在微服务架构中,因为会涉及到多个组件

    相关 dubbo+zookeeper构建服务架构

    微服务架构成了当下的技术热点,实现微服务是要付出很大成本的,但也许是因为微服务的优点太过于吸引人,以至于大部分开发者都将它当成未来的发展趋势。 微服务架构的演进过程