① 什么是分布式系统
《分布式系统原理与范型》定义:“分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统”。
分布式系统(distributed system)是建立在网络之上的软件系统。
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。
② 架构发展演变
如下图所示:
当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。
适用于小型网站,小型管理系统,将所有功能都部署到一个功能里,简单易用。
缺点: 1、性能扩展比较难 ;2、协同开发问题; 3、不利于升级维护。
当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。
通过切分业务来实现各个模块独立部署,降低了维护和部署的难度,团队各司其职更易管理,性能扩展也更方便,更有针对性。
缺点: 公用模块无法重复利用,开发性的浪费。
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。
当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)[ Service Oriented Architecture]是关键。
即,通常分布式应用就是面向服务的分布式架构。
③ RPC
RPC(Remote Procedure Call)是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同。
参考博文:进程间通信和线程间通信总结
时序图如下:
可以发现RPC两个核心模块:通讯和序列化。
常见的RPC框架有:Dubbo、GRPC(谷歌)、Thrift(Facebook)、HSF(High Speed Service Framework 阿里)、JSF(京东)及Motan(新浪)。
参考:分布式微服务架构中核心理念
Apache Dubbo (incubating) 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现
。
官网地址:http://dubbo.apache.org/
官网开发文档:http://dubbo.apache.org/zh-cn/docs/user/preface/
Dubbo的官方用户文档提供了很详细的使用说明与实例,遇到问题请一定参考官网文档!
① 结构示意图
如下所示(012345表示执行顺序,实线表示同步,虚线表示异步):
特性如下:
② 几个概念
服务提供者(Provider):暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者(Consumer): 调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务。服务消费者从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
注册中心(Registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
③ 调用关系说明
Dubbo推荐使用Zookeeper作为注册中心,当然Dubbo还支持其他作为注册中心如Multicast 注册中心,Redis注册中心和Simple 注册中心(本身就是一个普通的 Dubbo 服务)。
① 核心概念
Zookeeper 是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用。
官网地址:http://zookeeper.apache.org/
下载地址:https://archive.apache.org/dist/zookeeper/
② 流程说明:
③ 支持以下功能:
时,记录失败注册和订阅请求,后台定时重试;
设置 zookeeper 登录信息
设置 zookeeper 的根节点,不设置将使用无根树*
号通配符
,可订阅服务的所有分组和所有版本的提供者更多详情参考:Dubbo官网文档。
④ Windows下简单搭建Zookeeper
将下载好的Zookeeper解压到本地目录下,并修改zoo.cfg配置文件。
步骤如下:
解压运行bin/zkServer.cmd ,初次运行会报错,没有zoo.cfg配置文件;
将conf下的zoo_sample.cfg复制一份改名为zoo.cfg即可。
注意几个重要位置:
dataDir=./ 临时数据存储的目录(可写相对路径)
clientPort=2181 zookeeper的默认端口号
修改完成后再次启动zookeeper
使用zkCli.cmd测试
ls /:列出zookeeper根下保存的所有节点
create –e /myzookeeper 123:创建一个myzookeeper 节点,值为123
get /myzookeeper :获取/myzookeeper 节点的值
dubbo本身并不是一个服务软件。它其实就是一个jar(2.6之后为jar,之前为war需要在Tomcat下运行)包能够帮你的java程序连接到zookeeper,并利用zookeeper消费、提供服务。所以你不用在Linux上启动什么dubbo服务。
但是为了让用户更好的管理监控众多的dubbo服务,官方提供了一个可视化的监控程序,不过这个监控即使不装也不影响使用。
安装步骤如下:
进入Dubbo的GitHub项目项目地址;
在最下方Dubbo eco system中点击进入Dubbo-OPS;
进入目录,修改dubbo-admin配置
修改 src\main\resources\application.properties 指定zookeeper地址:
dubbo.registry.address=zookeeper://127.0.0.1:2181
打包dubbo-adminmvn clean package -Dmaven.test.skip=true
D:\Java_Tomcat_MySQL_jdk_zip\incubator-dubbo-ops-master\dubbo-admin>mvn clean package -Dmaven.test.skip=true
//D:\Java_Tomcat_MySQL_jdk_zip\incubator-dubbo-ops-master 为项目路径
Dubbo OPS项目与管理后台jar包下载:点击下载。
① 简单需求
某个电商系统,订单服务需要调用用户服务获取某个用户的所有地址。
我们现在 需要创建两个服务模块进行测试 :
模块 | 功能 |
---|---|
订单服务模块 | 创建订单等 |
用户服务模块 | 查询用户地址等 |
测试预期结果:订单服务模块在A服务器,用户服务模块在B服务器,A可以远程调用B的功能。
② 创建服务提供者和消费者
如下所示,创建两个maven工程,分别表示provider和consumer:
那消费者如何调用provider的方法呢?这里如果将provider依赖进consumer,则就成了单体应用。
或者可以这样,将provider的bean和service拷贝到consumer中,如下所示:
该种方式项目实例参考SpringBoot整合Dubbo和Zookeeper。
这种方式是有问题:第一,暂且不说现在OrderServiceImpl调用UserService肯定失败(实现类在另外一个项目);第二,UserService可能会被多个模块调用,原则上不应该每个调用UserService的模块都添加bean和UserService接口,添麻烦。而且也不符合Dubbo的服务化最佳实践。
这里将bean和接口抽离出来放在一个公共API项目中,provider和consumer依赖该项目。如下所示:
现在需要解决的问题就是远程调用,OrderServiceImpl如何调用userService.getUserAddressList(userId);
。
③ Dubbo改造服务提供者
第一步:引入依赖:
com.alibaba
dubbo
2.6.2
org.apache.curator
curator-framework
2.12.0
dubbo 2.6以前的版本引入zkclient操作zookeeper ,dubbo 2.6及以后的版本引入curator操作zookeeper。
下面两个zk客户端根据dubbo版本2选1即可:
com.101tec
zkclient
0.10
org.apache.curator
curator-framework
2.12.0
第二步,配置服务
在provider类路径下添加配置文件provider.xml:
第三步,编写主类进行测试
public class MainApplication {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("provider.xml");
ioc.start();
System.in.read();
}
}
使用Dubbo Admin管理后台查看,可以发现已经新增了一个服务提供者:
④ Dubbo改造服务消费者
第一步:引入依赖:
com.alibaba
dubbo
2.6.2
org.apache.curator
curator-framework
2.12.0
第二步,配置服务
在消费者class资源路径下配置consumer.xml:
第三步,编写主类进行测试
public class MainApplication {
@SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("consumer.xml");
OrderService orderService = applicationContext.getBean(OrderService.class);
orderService.initOrder("1");
System.out.println("调用完成....");
System.in.read();
}
}
在保证Zookeeper服务端,Dubbo Admin和服务器提供者启动并正常运行前提下,运行该消费者主类,将会从服务提供者那里获取数据!
使用Dubbo Admin后台查看:
截止现在,Dubbo+Zookeeper简单整合实践,源码下载地址。
Simple Monitor 挂掉不会影响到 Consumer 和 Provider 之间的调用,所以用于生产环境不会有风险。
Simple Monitor 采用磁盘存储统计信息,请注意安装机器的磁盘限制,如果要集群,建议用mount共享磁盘。
① 安全并运行Monitor
和安装Dubbo Admin时步骤类似,进入incubator-dubbo-ops-master\dubbo-monitor-simple
目录下,使用maven命令进行打包:
mvn clean package -Dmaven.test.skip=true
这里运行jar前,需要查看一下配置文件。将dubbo-monitor-simple-2.0.0-assembly.tar.gz复制并解压到指定文件夹下,查看其conf目录下的配置文件:
// Zookeeper注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
//监控中心于其他服务通信端口
dubbo.protocol.port=7070
//监控中心web页面访问端口
dubbo.jetty.port=8080
之后,进入dubbo-monitor-simple-2.0.0\assembly.bin
目录,运行start.bat。
此时监控中心还没有消费者。
② 修改服务提供者/消费者配置
在consumer.xml中添加如下配置:
在provider.xml中如下配置:
这两种有什么区别?参考官方文档:
重新启动provider和consumer,提供者向消费者索取服务再次查看Monitor,将会发现com.alibaba.dubbo.monitor.MonitorService对应的consumer有两个:provider和consumer都是MonitorService的消费者!
项目GitHub地址:点击下载