目录
Dubbo介绍
Dubbo架构
Hello World!示例
注册中心ZooKeeper
ZooKeeper介绍
Zookeeper 在Linux系统的安装
Dubbo对ZooKeeper的使用
Dubbo的四种配置方式
XML配置
属性配置
API配置
注解配置
集群容错机制
集群负载均衡
日志适配
监控管理后台
服务降级
Dubbo是阿里巴巴在2011年开源的分布式服务框架,是SOA(Service-Oriented Architecture 面向服务的架构)服务化治理方案的核心框架。Dubbo主要提供三方面的功能:远程接口调用;负载均衡和容错;自动服务注册和发现。官方曾停止维护Dubbo很长一段时间,如今又开始维护,并将它贡献Apache开源基金会。也有很多其他第三方组织在更新和维护它,如当当在Dubbo的基础上开源了Dubbox。
节点角色说明:
Provider |
暴露服务的服务提供方。 |
Consumer |
调用远程服务的服务消费方。 |
Registry |
服务注册与发现的注册中心。 |
Monitor |
统计服务的调用次调和调用时间的监控中心。 |
Container |
服务运行容器。 |
调用关系说明:
项目依赖
org.apache.zookeeper
zookeeper
3.4.10
org.slf4j
slf4j-log4j12
log4j
log4j
io.netty
netty
com.101tec
zkclient
0.10
org.springframework
spring-context
5.1.0.RELEASE
com.alibaba
dubbo
2.6.3
org.springframework
spring-context
org.apache.curator
curator-framework
4.0.1
org.apache.curator
curator-recipes
4.0.1
接口类
package com.dubbo.api;
public interface IHelloService {
String sayHello(String name);
}
服务类
package com.dubbo;
import com.dubbo.api.IHelloService;
public class HelloServiceImpl implements IHelloService{
public String sayHello(String name) {
// TODO Auto-generated method stub
return name;
}
}
服务端配置文件(暴露服务)
服务启动类
package com.dubbo;
import java.io.IOException;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Server {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
AbstractApplicationContext context = new ClassPathXmlApplicationContext("classpath:provider.xml");
System.in.read();
context.close();
}
}
消费端配置文件(引用远程服务)
消费端启动类
package com.dubbo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.dubbo.api.IHelloService;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:consumer.xml");
IHelloService iHelloService = (IHelloService) context.getBean("helloService"); // 获取远程服务代理
String hello = iHelloService.sayHello("Hello World!"); // 执行远程方法
System.out.println(hello);
context.close();
}
}
官方推荐使用 ZooKeeper 注册中心。注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小。
ZooKeeper是一个开源的分布式协调服务,是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为Dubbo服务的注册中心,工业强度较高,可用于生产环境。
ZooKeeper是用Java编写的,运行在Java环境上,因此在部署ZooKeeper的机器上需要安装Java运行环境。
1.从官网下载JDK安装包https://www.oracle.com/technetwork/java/javase/downloads/jdk10-downloads-4416644.html
2.解压JDK压缩包
tar -zxvf jdk-10.0.2_linux-x64_bin.tar.gz -C /usr/local/java/
3.修改环境变量
vim /etc/profile
在文件末尾添加环境变量
export JAVA_HOME=/usr/local/java/jdk-10.0.2
export PATH=$PATH:$JAVA_HOME/bin
4.重启配置文件使修改立即生效
source /etc/profile
5.从官网下载ZooKeeper安装包https://zookeeper.apache.org/releases.html
6.解压ZooKeeper压缩包
tar -zxvf zookeeper-3.4.6.tar.gz -C /usr/local/ZooKeeper/
7.进入 ZooKeeper 目录,创建 data 文件夹。
mkdir data
8.进入conf目录 ,把 zoo_sample.cfg 改名为 zoo.cfg
cd conf
mv zoo_sample.cfg zoo.cfg
9.打开zoo.cfg , 修改 dataDir 属性
dataDir=/usr/local/ZooKeeper/data
10.配置环境变量
export ZOOKEEPER_HOME=/usr/local/ZooKeeper
export PATH=$PATH:$ZOOKEEPER_HOME/bin
11.进入bin目录,启动服务
./zkServer.sh start
Dubbo支持zkclient和curator这两种ZooKeeper客户端实现,默认使用zkclient。若使用curator,按如下配置
将同一ZooKeeper分成多组注册中心
连接ZooKeeper集群
向多个ZooKeeper注册中心注册
服务暴露
引用服务
通过一下方式进行异步调用
Future helloFuture = RpcContext.getContext().getFuture();
服务隔离(分组隔离)
或者将服务消费者分组
Dubbo的配置有三大类服务发现、服务治理、性能调优
Dubbo使用Spring的Schema进行扩展标签和解析配置,所以可以Spring的XML配置方式来配置。
标签优先级
方法级 > 接口级 > 全局配置
消费者 > 提供者
Dubbo支持使用properties文件配置,它会自动加载classpath根目录下的dubbo.properties文件
dubbo.application.name=dubbo-server
dubbo.application.owner=test
dubbo.registry.address=zookeeper://127.0.0.1:2181
各配置优先级策略
JVM启动-D参数 > XML > Properties
API属性与XML配置项是一一对应的,如:ApplicationConfig.setName("dubbo-server")对应
服务提供者示例
//当前应用的配置
ApplicationConfig application = new ApplicationConfig();
application.setName("dubbo-server");
//连接注册中心的配置
Registryconfig registry = new Registryconfig();
registry.setAddress("zookeeper://127.0.0.1:2181");
registry.setUsername("test");
registry,setPassword("123456");
//服务提供者协议的配置
ProtocolConfig protocol - new ProtocolConfig();
protocol.setName("dubbo");
protocol.setPort(20880);
protocol.setThreads(200);
//下面为服务提供者暴露服务配置
IHelloservice helloservice = new HelloServiceImpl();//服务实现
//注意:Serviceconfig为重对象,内部封装了与注册中心的连接和开启服务端口。
//请务必自行缓存,否则可能造成内存和连接泄露
Serviceconfig service = new ServiceConfig();
service.setApplication(application);
service.setRegistry(registry); /多个注册中心可以用setRegistries()
service.setProtocol(protocol); //多个协议可以用setProtocols()
service.setInterface(IHelloService.Class);
service.setRef(helloService);
service.setVersion("1.0.0");
//暴露及注册服务
service.export();
服务消费者示例
//当前应用的配置
ApplicationConfig application = new ApplicationConfig();
application.setName("dubbo-client");
//连接注册中心的配置
Registryconfig registry = new Registryconfig();
registry.setAddress("zookeeper://127.0.0.1:2181");
registry.setUsername("test");
registry,setPassword("123456");
//引用远程服务
//注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供者的连接
//请务必自行缓存,否则可能造成内存和连接泄露
ReferenceConfig reference = new ReferenceConfig();
reference.setApplication(application);
reference.setRegistry(registry); //多个注册中心可以用setregistries()
reference.setInterface(IHelloservice.class);
reference.setVersion("1.0.0") ;
//和本地Bean一样使用IHelloService
注意:此代理对象内部封装了所有通信细节,对象较重,请缓存复用
IHelloService helloService reference.get();
将Hello World!改为注解方式,SpringBoot作为启动类
服务端配置类
@Configuration
public class DubboConfiguration {
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("dubbo-server");
return applicationConfig;
}
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress("zookeeper://127.0.0.1:2181");
registryConfig.setClient("curator");
return registryConfig;
}
}
服务类
@Service(timeout = 5000)
public class HelloServiceImpl implements IHelloService{
public String sayHello(String name) {
// TODO Auto-generated method stub
return name;
}
}
服务端启动类
@SpringBootApplication
DubboComponentScan(basePackages = "com.dubbo")
public class Server {
public static void main(String[] args) {
// TODO Auto-generated method stub
SpringApplication.run(Server , args);
}
}
消费端配置类
@Configuration
public class DubboConfiguration {
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("dubbo-client");
return applicationConfig;
}
@Bean
public ConsumerConfig consumerConfig() {
ConsumerConfig consumerConfig = new ConsumerConfig();
consumerConfig.setTimeout(3000);
return consumerConfig;
}
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress("zookeeper://127.0.0.1:2181");
registryConfig.setClient("curator");
return registryConfig;
}
}
消费类
public class Client {
@Reference
public IHelloService helloServiceimpl;
public void doSomething() {
helloServiceimpl.sayHello("hello world");
}
}
消费端启动类
@SpringBootApplication
DubboComponentScan(basePackages = "com.dubbo")
public class ClientApp {
public static void main(String[] args) {
// TODO Auto-generated method stub
SpringApplication.run(ClientApp , args);
}
}
集群容错机制是为了提高服务的可用性,如果单个服务节点因故障无法提供服务,可以根据配置好的集群容错模式,调用其它可用的节点。
配置方法
服务提供者配置
服务消费者配置
六种容错模式
(1)Failover Cluster
Dubbo集群容错默认模式,调用失败时会自动切换,重新尝试调用其它节点上可用的服务。可通过retries属性设置重试次数(不含第一次)
(2)Failfast Cluster模式
快速失败模式。调用只执行一次,失败立即报错。
(3)Failsafe Cluster模式
失败安全模式,调用失败,直接忽略失败的调用,记录失败的调用到日志文件,以便后续审计。
(4)Failback Cluster
失败自动恢复,后台记录失败的请求,定时重发。适用于消息通知操作。
(5)forking Cluster模式
并行调用多个服务器,只要有一个成功便返回。可通过forks属性(forks="2")来设置最大的并行数。
(6)Broadcast Cluster模式
广播调用所有提供者,逐个调用,任意一台报错则报错。
Dubbo内置4种负载均衡策略
(1)随机模式(Random):按权重设置随机概率
(2)轮询模式(RoundRobin):按公约后的权重设置轮询概率。
(3)最少活跃调用数(LeastActive):响应慢的提供者收到更少的请求。活跃数相同 则随机。
(4)一致性Hash(ConsistentHash):相同参数的请求总是发给同一提供者。提供者挂掉时,请求会基于虚拟节点平摊到其它提供者上。
配置方法
服务端配置
也可以在客户端配置
Dubbo内置了log4j、slf4j、jcl、jdk四种日志框架
配置方法
一、使用官方开源管理后台
(1)下载Tomcat安装包并解压
(2)将dubbo-admin.war包解压至webapps/ROOT目录
(3)编辑dubbo.properties配置文件
vi webapps/ROOT/WEB-INF/dubbo.properties
dubbo.properties
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest
(4)启动Tomcat访问http://127.0.0.1:8080/
二、dubbo-monitor开源管理后台
Dubbo Monitor是针对Dubbo开发的监控系统,,使用关系型数据库方式记录日志。官网地址https://github.com/handuyishe/dubbo-monitor
(1)创建数据库:首先创建名称为monitor数据库,编码格式UTF-8。然后将项目sql文件夹下面的create.sql导入到数据库,生成dubbo_invoke表代表成功导入。
(2)编辑项目中application.properties,配置如下:
####Dubbo Settings
dubbo.application.name=dubbo-monitor
dubbo.application.owner=handu.com
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.port=6060
####Database Settings
db.url=jdbc:mysql://:/monitor?prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8
db.username=root
db.password=root
db.maxActive=500
####System Manager
manager.username=admin
manager.password=admin
(3)打包运行项目 执行maven命令:mvn clean package target文件夹下生成的dubbo-monitor.war即为项目部署文件,将其放置到对应服务器目录下,启动服务器即可。例如:tomcat的webapps文件夹下。
mvn clean package target
(4)访问项目 启动web服务器后,访问地址:http://IP:[port]/dubbo-moniotor,采用配置文件中manager.username和manager.password设置值进行登录。
三、DubboKeeper开源管理后台
(1)官网下载源码https://github.com/dubboclub/dubbokeeper
(2)编译打包:由于监控数据的存储和展示显示进行了分离,那么打包有所变动。在下载源码的根目录会发现install-xxx.bat(sh),这个可以根据你想要的不同存储执行对应的脚本。执行完之后在target目录下面会发现xxx-dubbokeeper-ui,xxx-dubbokeeper-server以及xxx-dubbokeeper-server.tar.gz。其中xxx-dubbokeeper-ui下会有一个war包,将该war包部署到tomcat或者jetty里面(或者其他servlet容器),那么就部署好了监控展示应用了。
(3)监控数据暂时端调整:将上面的war包解压出来后对其中WEB-INF/classes/dubbo.properties文件中的配置项进行调整。
#monitor的应用名,可根据自己情况自定义
dubbo.application.name=monitor-ui
#应用的拥有者
dubbo.application.owner=bieber
#连接的dubbo注册中心地址,保持部署监控数据存储的zk地址一样
dubbo.registry.address=zookeeper://localhost:2181
#use netty4
dubbo.reference.client=netty4
#peeper config
#监控的zookeeper连接列表,多个通过‘,’(英文逗号)隔开。
peeper.zookeepers=localhost:2181
#监控的zookeeper连接会话超时时间
peeper.zookeeper.session.timeout=60000
#被监控端同步监控数据周期时间,可不配置,默认是一分钟同步一次
monitor.collect.interval=60000
#logger
#dubbokeeper的日志目录
monitor.log.home=/usr/dev/op_disk/monitor-log
重启Tomcat,访问http://127.0.0.1:8080/dubbokeeper-ui-1.0.1
(4)监控数据存储端配置调整以及启动:通过上面编译后会得到xxx-dubbokeeper-server目录,在改名了的xxx-server下面包含三个子目录:bin,conf以及lib。
bin:启动存储端的脚本,实行start-xx.sh(bat)则启动该应用
conf:存储端的相关配置,具体配置下面会介绍
lib:应用依赖的相关jar包
启动服务之前需先初始化数据库:创建一个数据库,数据库名可以自定义一个,编码采用utf-8。初始化脚本如下
CREATE TABLE `application` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL DEFAULT '',
`type` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `应用名词索引` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
监控服务的配置参数如下
#dubbo应用名称
dubbo.application.name=mysql-monitor
#dubbo应用所有者
dubbo.application.owner=bieber
#dubbo的注册中心地址,保存和被监控应用一个注册中心
dubbo.registry.address=zookeeper://localhost:2181
#监控数据收集协议
dubbo.protocol.name=dubbo
#监控数据收集协议端口
dubbo.protocol.port=20884
#被监控端同步监控数据周期时间,可不配置,默认是一分钟同步一次
monitor.collect.interval=100
#use netty4
dubbo.provider.transporter=netty4
#监控数据持久化周期,默认是一分钟,单位是秒
monitor.write.interval=6000
#mysql相关信息
#mysql数据库地址
dubbo.monitor.mysql.url=jdbc:mysql://localhost:3306/dubbokeeper
#mysql数据库用户名
dubbo.monitor.mysql.username=root
#mysql数据库用户密码
dubbo.monitor.mysql.password=root
#mysql数据库链接池最大连接数
dubbo.monitor.mysql.pool.max=10
#mysql数据库链接池最小连接数
dubbo.monitor.mysql.pool.min=10
(5)执行start-xx.sh(bat)启动DubboKeeper监控服务程序。
服务降级是在服务器压力剧增时,根据实时的业务情况及流量对一些服务和页面有策略地进行降级,以释放服务器资源并保证核心任务的正常运行。
Dubbo使用mock配置来实现服务降级。mock支持两种配置:
(1)配置Boolean值。默认为false,如果配置为true,则默认使用mock的类名,即类名+Mock后缀
然后在项目中提供Mock实现类
public class HelloServiceMock implements IHelloService {
public String sayHello(String name) {
// TODO Auto-generated method stub
return "容错数据";
}
}
(2)配置为return null,忽略异常