¶一、发展演变
单一应用架构
当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。
适用于小型网站,小型管理系统,将所有功能都部署到一个功能里,简单易用。
缺点: 1、性能扩展比较难
2、协同开发问题
3、不利于升级维护
垂直应用架构
当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。
通过切分业务来实现各个模块独立部署,降低了维护和部署的难度,团队各司其职更易管理,性能扩展也更方便,更有针对性。
缺点: 公用模块无法重复利用,开发性的浪费
分布式服务架构
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的****分布式服务框架(RPC)****是关键。
流动计算架构
当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)[ Service Oriented Architecture]是关键。
¶二、RPC的概念
¶1、RPC概念
RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同。
¶2、RPC基本原理
RPC两个核心模块:通讯,序列化。
¶三、Dubbo核心概念
¶1、简介
Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
官网:
¶2、基本概念
- 组件角色
服务提供者(Provider):暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者(Consumer): 调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
注册中心(Registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者
监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
- 调用关系说明
l 服务容器负责启动,加载,运行服务提供者。
l 服务提供者在启动时,向注册中心注册自己提供的服务。
l 服务消费者在启动时,向注册中心订阅自己所需的服务。
l 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
l 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
l 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
¶四、Dubbo环境搭建
¶1、安装注册中心Zookeeper(windows)
¶1.1 下载zookeeper
官网下载网址 https://archive.apache.org/dist/zookeeper/zookeeper-3.4.13/
¶1.2 解压zookeeper
解压后运行zkServer.cmd
,初次运行会报错,原因是没有zoo.cfg
配置文件。
¶1.3 修改zoo.cfg配置文件
将conf
下的zoo_sample.cfg
复制一份改名为zoo.cfg
即可。
注意几个重要位置:
1 | dataDir=../data #临时数据存储的目录(可写相对路径) |
修改完成后再次启动zkServer.cmd
¶1.4 测试是否搭建完成
点击运行zkCli.cmd
1 | ls / #列出zookeeper根下保存的所有节点 |
Zookeeper是一个树型的目录服务,支持变更推送,可作为 Dubbo 服务的注册中心。
¶2、安装管理控制台dubbo-admin
¶2.1下载dubbo-admin
下载地址:https://github.com/apache/incubator-dubbo-ops
2.2 进入dubbo-admin目录,修改dubbo-admin配置
修改src\main\resources\application.properties
指定zookeeper地址。
1 | spring.guest.password=guest |
¶2.3 运行打包
在dubbo-admin/
目录里执行命令运行打包dubbo-admin
1 | mvn clean package -Dmaven.test.skip=true |
¶2.4 运行dubbo-admin
在dubbo-admin/target
目录里执行命令运行dubbo-admin
1 | java -jar dubbo-admin-0.0.1-SNAPSHOT.jar #注意要先启动zookeeper |
¶2.5 访问监控管理控制台
默认使用root/root
登陆
¶五、Spring中使用Dubbo
某个电商系统,订单服务需要调用用户服务获取某个用户的所有地址;
我们现在 需要创建两个服务模块进行测试
模块 | 功能 |
---|---|
订单服务web模块 | 创建订单等 |
用户服务service模块 | 查询用户地址等 |
测试预期结果:
订单服务web模块在A服务器,用户服务模块在B服务器,A可以远程调用B的功能。
¶1. 创建如下三个maven工程
1 | . |
¶1.1 gmall-interface模块
1 | . |
pom.xml
1 | "1.0" encoding="UTF-8" xml version= |
com.qcmoke.gmall.bean.UserAddress.java
1 | package com.qcmoke.gmall.bean; |
com.qcmoke.gmall.service.OrderService.java
1 | package com.qcmoke.gmall.service; |
com.qcmoke.gmall.service.UserService.java
1 | package com.qcmoke.gmall.service; |
¶1.2 order-service-consumer模块
1 | . |
pom.xml
1 | "1.0" encoding="UTF-8" xml version= |
com.qcmoke.gmall.service.impl.UserServiceImpl.java
1 | package com.qcmoke.gmall.service.impl; |
provider.xml
1 | "1.0" encoding="UTF-8" xml version= |
com.qcmoke.gmall.MainApplication.java
1 | package com.qcmoke.gmall; |
¶1.3 user-service-provider模块
1 | . |
pom.xml
1 | "1.0" encoding="UTF-8" xml version= |
com.qcmoke.gmall.service.impl.OrderServiceImpl.java
1 | package com.qcmoke.gmall.service.impl; |
consumer.xml
1 | "1.0" encoding="UTF-8" xml version= |
com.qcmoke.gmall.MainApplication.java
1 | package com.qcmoke.gmall; |
¶1.4 测试
启动zookeeper,然后启动dubbo-admin,再启动user-service-provider,最后启动order-service-consumer。
查看order-service-consumer的输出结果。
¶2. 安装监控中心
¶1、下载 dubbo-ops
https://github.com/apache/incubator-dubbo-ops
¶2、打包dubbo-monitor-simple
进入incubator-dubbo-ops-master/dubbo-monitor-simple
下运行以下命令
1 | mvn package |
¶3. 进入target/
目录
解压dubbo-monitor-simple-2.0.0-assembly.tar.gz
得到dubbo-monitor-simple-2.0.0
,并将之移动到非target的目录去。
修改dubbo-monitor-simple-2.0.0/conf/dubbo.properties
的以下三处必要配置:
1 | # 注册中心的地址 |
¶4、运行启动监控中心monitor
运行dubbo-monitor-simple-2.0.0/assembly.bin/start.bat
注意:前提要先启动zookeeper和dubbo-admin
¶5、启动访问monitor管理页面
¶6、服务中配置monitor
在服务的ioc容器中配置如下已能够和监控中心建立连接关系。
1 | <!-- 连接监控中心 |
修改order-service-consumer模块的consumer.xml
1 | "1.0" encoding="UTF-8" xml version= |
修改user-service-provider的provider.xml
1 | "1.0" encoding="UTF-8" xml version= |
¶7、测试monitor
启动顺序:zookeepe—>dubbo-admin—>monitor—>user-service-provider—>order-service-consumer
¶六、SpringBoot中使用Dubbo
¶1、概述
对于服务提供者:
1 | 1.引入依赖 |
对于服务消费者:
1 | 1.引入依赖 |
¶3、三个maven模块
1 | . |
¶1.1 gmall-interface
和“SpringBoot中使用Dubbo”中的内容一样,这里不再阐述。
¶1.2 boot-user-service-provider模块
pom.xml
1 | "1.0" encoding="UTF-8" xml version= |
com.qcmoke.gmall.ProviderBootApplication.java
1 | package com.qcmoke.gmall; |
com.qcmoke.gmall.service.impl.UserServiceImpl.java
1 | package com.qcmoke.gmall.service.impl; |
application.properties
1 | # 服务唯一名称 |
¶1.3 boot-order-service-consumer模块
pom.xml
1 | "1.0" encoding="UTF-8" xml version= |
com.qcmoke.gmall.ConsumerBootApplication.java
1 | package com.qcmoke.gmall; |
com.qcmoke.gmall.service.impl.OrderServiceImpl.java
1 | package com.qcmoke.gmall.service.impl; |
com.qcmoke.gmall.controller.OrderController.java
1 | package com.qcmoke.gmall.controller; |
application.properties
1 | server.port=8081 |
¶1.4 测试
启动顺序:zookeepe—>dubbo-admin—>monitor—>boot-user-service-providerr—>boot-order-service-consumer
访问http://127.0.0.1:8081/initOrder?uid=1
¶七、dubbo配置
¶1、配置优先原则
★ JVM 启动 -D 参数优先,这样可以使用户在部署和启动时进行参数重写,比如在启动时需改变协议的端口。
★ XML 次之,如果在 XML 中有配置,则 dubbo.properties 中的相应配置项无效。
★ Properties 最后,相当于缺省值,只有 XML 没有配置时,dubbo.properties 的相应配置项才会生效,通常用于共享公共配置,比如应用名。
对boot-user-service-provider模块做一下修改:
application.properties(想当于xml):
1 | # 服务唯一名称 |
dubbo.properties:
1 | dubbo.protocol.port=20882 |
由于application.properties优先级更高,启动后会发现dubbo.properties的20882端口会被application.properties的20881端口覆盖。
¶2、重试次数
失败自动切换,当出现失败,重试其它服务器,但重试会带来更长延迟。可通过 retries=“2” 来设置重试次数(不含第一次)。
重试次数配置如下:
1 | 服务提供者: |
1 | 服务消费者: |
¶3、超时时间配置
由于网络或服务端不可靠,会导致调用出现一种不确定的中间状态(超时)。为了避免超时导致客户端资源(线程)挂起耗尽,必须设置超时时间。
1 | 消费端: |
1 | 服务端: |
如果消费端和服务端都配置同样的超时配置,那么消费端的配置优于服务端配置
¶4、配置原则
配置的覆盖规则:
-
方法级配置别优于接口级别,即小Scope优先
-
Consumer端配置 优于 Provider配置 优于 全局配置,
-
最后是Dubbo Hard Code的配置值(见配置文档)
dubbo推荐在Provider上尽量多配置Consumer端属性:
(1)作服务的提供者,比服务使用方更清楚服务性能参数,如调用的超时时间,合理的重试次数,等等
(2)在Provider配置后,Consumer不配置则会使用Provider的配置值,即Provider配置可以作为Consumer的缺省值。否则,Consumer会使用Consumer端的全局设置,这对于Provider不可控的,并且往往是不合理的
¶5、版本号
当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。
可以按照以下的步骤进行版本迁移:
在低压力时间段,先升级一半提供者为新版本
再将所有消费者升级为新版本
然后将剩下的一半提供者升级为新版本
1 | 老版本服务提供者配置: |
对user-service-provider模块做修改:
provider.xml
1 | "1.0" encoding="UTF-8" xml version= |
添加实现类com.qcmoke.gmall.service.impl.UserServiceImpl2.java
1 | package com.qcmoke.gmall.service.impl; |
对order-service-consumer模块做修改:
consumer.xml
1 | "1.0" encoding="UTF-8" xml version= |
运行两个服务后观察消费者的输出:
1 | 用户id:1 |
¶八、熔断与降级
整合hystrix,可实现服务的熔断与降级。
Hystrix 旨在通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能。
¶1. 使用hystrix
¶1.1 创建提供者模块
- boot-user-service-provider-hystrix
除了添加dubbo依赖和gmall-interface外,还有添加如下netflix依赖:
1 | <dependency> |
完整pom.xml
1 | "1.0" encoding="UTF-8" xml version= |
创建启动类并在类上增加@EnableHystrix
注解。
HystrixProviderBootApplication.java
1 | package com.qcmoke.gmall; |
配置application.properties
1 | server.port=8081 |
UserServiceImpl.java
1 | package com.qcmoke.gmall.service.impl; |
¶1.2 创建消费者模块
- boot-order-service-consumer-hystrix
pom.xml
1 | "1.0" encoding="UTF-8" xml version= |
application.properties
1 | server.port=80 |
HystrixConsumerBootApplication.java
1 | package com.qcmoke.gmall; |
UserController.java
1 | package com.qcmoke.gmall.controller; |
测试:
先启动提供者,然后启动消费者
访问http://127.0.0.1/getUserAddressList?uid=1
返回结果:
1 | [{"id":null,"userAddress":null,"userId":null,"consignee":null,"phoneNum":null,"isDefault":null}] |