一. Dubbo概述
1. 什么是Dubbo?
一款分布式服务框架,高性能和透明化的RPC远程服务调用方案,SOA服务治理方案。
每天为2千多个服务提供大于30亿次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点以及别的公司的业务中。
2. Dubbo优缺点
优点: ① 透明化的远程方法调用 像调用本地方法一样调用远程方法;只需简单配置,没有任何API侵入。 ② 软负载均衡及容错机制 可在内网替代nginx lvs等硬件负载均衡器。 ③ 服务注册中心自动注册 & 配置管理 不需要写死服务提供者地址,注册中心基于接口名自动查询提供者ip。 使用类似zookeeper等分布式协调服务作为服务注册中心,可以将绝大部分项目配置移入zookeeper集群。 ④ 服务接口监控与治理 -Dubbo-admin与Dubbo-monitor提供了完善的服务接口管理与监控功能,针对不同应用的不同接口,可以进行 多版本,多协议,多注册中心管理。
缺点: 只支持Java语言
3. Dubbo架构原理
角色区分:
① Provider: 暴露服务的服务提供方(生产者)
② Consumer: 调用远程服务的服务消费方(消费者)
③ Registry: 服务注册与发现的注册中心(zookeeper,redis等)
④ Monitor: 统计服务的调用次数和调用时间的监控中心(dubbo-admin)
调用流程:
0>服务容器负责启动,加载,运行服务提供者。
1>服务提供者在启动时,向注册中心注册自己提供的服务。
2>服务消费者在启动时,向注册中心订阅自己所需的服务。
3>注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者
4>服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用
5>服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
4. Dubbo与SpringCloud的区别
相同点:SpringCloud 和Dubbo可以实现RPC远程调用框架,可以实现服务治理。
不同点:SpringCloud是一套目前比较网站微服务框架了,整合了分布式常用解决方案遇到了问题注册中心Eureka、负载均衡器Ribbon ,客户端调用工具Rest和Feign,分布式配置中心Config,服务保护Hystrix,网关Zuul Gateway ,服务链路Zipkin,消息总线Bus等。 从架构上分析,Dubbo内部实现功能没有SpringCloud强大,只是实现服务治理,缺少分布式配置中心、网关、链路、总线等,如果需要用到这些组件,需要整合其他框架。从更新迭代速度分析,Dubbo目前更新速度没有SpringCloud快,到SpringCloud2.0后SpringCloud会越来完善和稳定。从开发背景角度分析,Dubbo的开发背景是阿里巴巴, 在中国也推出了非常多的优秀的开源框架,但是在SpringCloud的背景是Spring家族,Spring是专注于企业级开源框架开发,在中国,或者在整个世界上Spring框架都应用的非常广泛。所有相对来说SpringCloud的背景比Dubbo更加强大。
二. Dubbo实战(SpringBoot整合Dubbo)
准备工作:本地需要安装zookeeper,并用ZooInspector工具连接成功。
项目结构图:(基于maven的聚合项目)
dubbo-parent为根目录,pom类型;dubbo-api-service为服务接口目录,其下的dubbo-member-service为会员接口服务;dubbo-member-service-impl,dubbo-order-service-impl为别为会员,订单接口实现(springboot项目)。
本案例即为模拟订单服务调用会员服务,下面开始搭建:
首先配置各个服务pom依赖关系:
dubbo-parent
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>dubbo-parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>dubbo-api-service</module>
<module>dubbo-member-service-impl</module>
<module>dubbo-order-service-impl</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<curator-framework.version>4.0.1</curator-framework.version>
<zookeeper.version>3.4.13</zookeeper.version>
<dubbo.starter.version>0.2.0</dubbo.starter.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.starter.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator-framework.version}</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
dubbo-api-service
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-parent</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-service</artifactId>
<packaging>pom</packaging>
<modules>
<module>dubbo-member-service</module>
</modules>
</project>
dubbo-member-service
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-service</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-member-service</artifactId>
</project>
dubbo-member-service-impl
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-parent</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-member-service-impl</artifactId>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-member-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
dubbo-order-service-impl
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-parent</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-order-service-impl</artifactId>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-member-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
在会员服务接口dubbo-member-service新建MemberService
package com.example.service;
public interface MemberService {
String getUser(Long userId);
}
dubbo-member-service-impl新建MemberServiceImpl,实现MemberService
package com.example.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.example.service.MemberService;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @Service 发布服务,表示将该接口注册到注册中心上去
* @author zhaobin
* @date 2019/11/26
*/
@Service
public class MemberServiceImpl implements MemberService {
public String getUser(@RequestParam Long userId) {
System.out.println("会员服务实现,userId为:" + userId);
return "会员服务实现,userId为:" + userId;
}
// dubbo服务发布的时候,采用dubbo注解方式,使用@Service注解进行注入,注意是dubbo提供的@Service注解
}
会员实现启动类:
package com.example;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @EnableDubbo 开启Dubbo服务
* @author zhaobin
* @date 2019/11/26
*/
@EnableDubbo
@SpringBootApplication
public class AppMember {
public static void main(String[] args) {
SpringApplication.run(AppMember.class, args);
}
}
会员实现配置类
server:
port: 8081
dubbo:
application:
name: member
protocol:
# 使用dubbo协议
name: dubbo
# 发布dubbo端口号为20880
port: 20880
registry:
address: zookeeper://127.0.0.1:2181
scan:
# dubbo实现类扫包范围
base-packages: com.example.impl
dubbo-order-service-impl新建OrderController
package com.example.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.example.service.MemberService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @Reference Dubbo提供 - 调用服务
*/
@RestController
public class OrderController {
@Reference // 不能用@Autowired注解
private MemberService memberService;
@RequestMapping("/orderToMember")
public String orderToMember(@RequestParam Long userId) {
System.out.println("订单服务实现");
return memberService.getUser(userId);
}
}
订单实现启动类
package com.example;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDubbo
@SpringBootApplication
public class AppOrder {
public static void main(String[] args) {
SpringApplication.run(AppOrder.class, args);
}
}
订单实现配置类
server:
port: 8082
dubbo:
application:
name: order
# protocol: # 不注册服务,不用加
# name: dubbo
# port: 20880
registry:
address: zookeeper://localhost:2181
consumer:
timeout: 5000
至此,项目环境搭建完毕,分别启动member-impl和order-impl,可以看到zk客户端注册了生产者和消费者的信息
此时,订单服务访问接口 http://localhost:8082/orderToMember,可以成功从会员服务拿到信息
三. 搭建DubboAdmin监控平台
下载dubbo-admin.zip,解压到tomcat的webapps目录下,并修改dubbo.properties的连接地址即可,启动tomcat:
可以看到服务的信息,以及调用链;DubboAdmin底层实现连接ZooKeeper信息,进行解析转化成页面进行展示。
【小结】:Dubbo在zookeeper注册采用持久节点+临时节点,下图红色箭头的为持久节点,因为接口一般都不会变,蓝色箭头为临时节点,当项目停了,下面的子文件就不存在了,见右图。