微服务的一种开源实现方式——dubbo+zookeeper
转自: http://blog.csdn.NET/zhdd99/article/details/52263609
微服务架构成了当下的技术热点,实现微服务是要付出很大成本的,但也许是因为微服务的优点太过于吸引人,以至于大部分开发者都将它当成未来的发展趋势。
微服务架构的演进过程
dubbo的用户手册中介绍了服务化架构的进化过程,如下图:

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

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

图三、网站的基础组件架构图
可惜蚂蚁金融云中的产品并不是开源的,一个企业想拥有属于自己的网站架构,就要选出最适合的开源的服务框架实现这些组件,从而使后续开发者更关注于业务逻辑实现。
这些组件的实现方式以后有时间的话会一一讲解,这篇文章接下来先介绍一下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、接口:
- public interface TestService {
- String sayHello(String name);
- }
2、实现类:
- @Service("testService")
- public class TestServiceImpl implements TestService {
- @Override
- public String sayHello(String name) {
- return String.format("Hi! Client_%s! ", name);
- }
- }
3、然后在dubboservice中引入dubbo,zookeeper所用的依赖,坐标如下:
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>dubbo</artifactId>
- <version>2.5.3</version>
- </dependency>
- <dependency>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper</artifactId>
- <version>3.4.5</version>
- </dependency>
- <dependency>
- <groupId>com.github.sgroschupf</groupId>
- <artifactId>zkclient</artifactId>
- <version>0.1</version>
- </dependency>
4、将Hello World服务在spring的配置文件中暴露出来,如图:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
- xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
- http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
- http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
- http://code.alibabatech.com/schema/dubbo
- http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
- <context:property-placeholder location="classpath:/META-INF/app.properties" />
- <!--提供方应用信息,用于计算依赖关系-->
- <dubbo:application name="dubboservice_provider" />
- <!--使用zookeeper注册中心暴露服务地址-->
- <dubbo:registry protocol="zookeeper" address="10.139.99.231:2181,10.139.106.145:2181,10.139.103.116:2181"/>
- <!--声明需要暴露的服务接口-->
- <dubbo:service interface="org.zhdd.test.dubboservice.service.TestService" ref="testService"/>
- </beans>
5、将dubboservice项目启动,我们便向注册中心提供了一个简易的后端通用服务。
然后在dubboclient项目中实现对后端服务的引用,和对外的路由
1、除了在dubboclient中引入dubbo,zookeeper所用的依赖之外,我们还需要引入dubboservice中所用到的服务依赖,如下:
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>dubbo</artifactId>
- <version>2.5.3</version>
- </dependency>
- <dependency>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper</artifactId>
- <version>3.4.5</version>
- </dependency>
- <dependency>
- <groupId>com.github.sgroschupf</groupId>
- <artifactId>zkclient</artifactId>
- <version>0.1</version>
- </dependency>
- <!--
- 服务提供方的接口依赖
- -->
- <dependency>
- <groupId>org.zhdd.test</groupId>
- <artifactId>dubboservice-service</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
2、在spring的配置文件中声明所引用的服务:
- <!--提供方应用信息,用于计算依赖关系-->
- <dubbo:application name="dubboservice_consumer" />
- <!--使用zookeeper注册中心暴露服务地址-->
- <dubbo:registry protocol="zookeeper" address="10.139.99.231:2181,10.139.106.145:2181,10.139.103.116:2181"/>
- <!--声明需要暴露的服务接口-->
- <dubbo:reference interface="org.zhdd.test.dubboservice.service.TestService" id="testService"/>
3、新建一个controller,将引用的服务通过controller暴露出去,代码如下:
- @Controller
- public class HelloController {
- @Autowired
- private TestService testService;
- @RequestMapping("/hello/{name}")
- @ResponseBody
- public String hello(@PathVariable String name){
- String rslt=testService.sayHello(name);
- return rslt;
- }
- }

这样我们就成功部署了一个简易的微服务架构。
我们可以通过zookeeper的查看工具更直观的查看dubbo在zookeeper中的注册和订阅信息,此时的注册和订阅信息如下:

后续:
dubbo与zookeeper的复杂配置还有很多,本文只介绍了dubbo与zookeeper最基本的用法。要想了解更多的信息可以通过官方文档进行学习:
dubbo中文文档:http://dubbo.io/
zookeeper文档:http://zookeeper.apache.org/
微服务的一种开源实现方式——dubbo+zookeeper的更多相关文章
- 【推荐】微服务分布式企业框架Springmvc+mybatis+shiro+Dubbo+ZooKeeper+Redis
摘要: 主要定位于互联网企业架构,已内置企业信息化系统的基础功能和高效的代码生成工具,包括:系统权限组件.数据权限组件.数据字典组件.核心工具 组件.视图操作组件.工作流组件.代码 ...
- 微服务架构-选择Spring Cloud,放弃Dubbo
Spring Cloud 在国内中小型公司能用起来吗?从 2016 年初一直到现在,我们在这条路上已经走了一年多. 在使用 Spring Cloud 之前,我们对微服务实践是没有太多的体会和经验的.从 ...
- 【架构】linkerd:来自Twitter为微服务而生的开源RPC解决方案
大家要如何以规模化方式运维微服务应用程序?实践当中会出现哪些问题,我们又该如何加以解决?在大规模与非预测性工作负载场景当中,我们需要满足哪些条件才能运行一款大型微服务应用程序,而又能够确保不必受到功能 ...
- 【开源】.net微服务开发引擎Anno开源啦
1.Anno是什么? Anno是一个微服务框架引擎.入门简单.安全.稳定.高可用.全平台可监控.依赖第三方框架少.底层通讯RPC(Remote Procedure Call)采用稳定可靠经过无数成功项 ...
- SpringCloud微服务:基于Nacos组件,整合Dubbo框架
源码地址:GitHub·点这里 || GitEE·点这里 一.基础组件简介 1.Dubbo框架 Dubbo服务化治理的核心框架,之前几年在国内被广泛使用,后续由于微服务的架构的崛起,更多的公司转向微服 ...
- 11.实战交付一套dubbo微服务到k8s集群(3)之dubbo微服务底包镜像制作
1.下载jre镜像并推送到harbor [root@hdss7- ~]# docker pull registry.cn-hangzhou.aliyuncs.com/yfhub/jre8:8u112 ...
- 实战交付一套dubbo微服务到k8s集群(4)之dubbo微服务底包镜像制作
1.下载jre镜像 在运维主机(mfyxw50.mfyxw.com)操作 [root@mfyxw50 ~]# docker pull registry.cn-hangzhou.aliyuncs.com ...
- SpringCloud之旅第一篇-微服务概念
一.单体架构的问题 微服务为什么会出现?在学习Springboot的时候知道Springboot极大的简化了我们的开发,我们可以快速的进行业务开发,Springboot单体应用在项目的开发初期能够满足 ...
- 微服务与Spring Cloud基本概念、Spring Cloud版本命名方式与版本选择
微服务是什么?Spring Cloud是什么?Spring Cloud版本命名方式?Spring Cloud版本选择? 一.微服务是什么 微服务是一种架构风格,是一种将单体应用开发为一组小型服务的方法 ...
随机推荐
- @Autowired中无法注入RestTemplate的问题
1.在启动类中添加 @Beanpublic RestTemplate restTemplate(){ return new RestTemplate();} 即可解决无法注入RestTemplate的 ...
- zabbix全方位监控MySQL +cacti监控mysql
http://www.linuxidc.com/Linux/2015-02/112690.htm http://john88wang.blog.51cto.com/2165294/1596272?ut ...
- 自己定义ViewpagerIndicator (仿猫眼,加入边缘回弹滚动效果)
一.概述 今天主要来分享个自己定义viewpagerindicator.效果主要是仿 猫眼电影 顶部的栏目切换.也就是我们常说的indicator,难度简单,为了让滑动时效果更炫酷,我在滑动到左边第一 ...
- iOS-UITextView-文本输入视图的使用
#import "ViewController.h" @interface ViewController ()<UITextViewDelegate> { UIView ...
- .NET 复制A对象值到B对象
1.最基础的ModelCopy using System; using System.Collections.Generic; using System.ComponentModel; public ...
- 假期(MySQL相关)
""" 一.初始数据库: - 数据库管理软件的由来 四个字:存储数据(简单暴力) - 数据库概述 :什么是数据:简单的说就是描述事物的记录称为数据:可以是数字,文字,图片 ...
- Robot Framework 使用技巧 快捷键
ctrl+alt+space 自动带出相关关键字,以及相关用法,里边有对应参数的说明. Ctrl+鼠标悬浮 直接显示关键字的相关用法 F5 关键字说明 (方法名函数名) ...
- WebView播放H5课件时,锁屏解锁后,页面重新绘制的问题
难题描述:H5页面播放 ,锁屏,解锁后,重新加载了页面,三星不会出现(onpause onstop ,onresume),但在小米.魅族会调用 onpause onstop ondestroy,onr ...
- windows 下 opencv 3.x 的安装及常见问题的解决
1. 下载与配置 下载地址:Releases - OpenCV library(选择合适的平台和版本) 配置步骤见:VS 2013 统一修改所有工程的目录配置(以 boost.opencv3 的安装为 ...
- P1552 派遣 左偏树
左偏树就是一个应该用堆维护的区间,然后需要进行合并操作而发明的算法,其实这个算法没什么难的,和树剖有点像,维护几个数值,然后递归回来的时候就可以修改. 题干: 题目背景 在一个忍者的帮派里,一些忍者们 ...