本文参考:【优极限】最透彻的Dubbo教程(dubbo经典之作完整版),阿里分布式框架dubbo零基础实战教学_手把手地啊你读懂底层源码【完整版】_哔哩哔哩_bilibili
1、 互联网架构演变
(1)单一应用架构
把系统中所有的功能、模块耦合在一个应用中的架构方式。程序在一个服务器上。
优点:项目易于管理、部署简单
缺点:测试成本高、可伸缩性差、可靠性差、迭代困难、跨语言程度差、团队协作
(2)RPC架构
远程过程调用。通过网络从远程计算机程序上请求服务,比如Thrift,程序可能分布在两个以上服务器上。
优点:应用直接调用服务,服务之间是隔离的
缺点:服务过多时,管理成本高昂。服务治理,服务注册、发现,服务容错,服务跟踪,服务网关,IP暴露等都是此架构无法避免的问题。
(3)SOA架构
面向服务架构。就是在RPC基础上增加了ESB服务中介,主要提供了一个服务与服务之间的交互。
如上图所示,应用如果调用用户、购物车等服务,则直接跟ESB打交道,ESB再跟用户、购物车、订单等服务打交道。
ESB包含的功能:负载均衡,流量控制,加密处理,服务的监控,监控告急等。
(4)微服务架构
一个大型的复杂软件应用,由一个或多个微服务组成。系统中各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好的完成该任务。对比SOA架构,使用注册中心代替ESB服务总线。注册中心相比服务总线来说,更加轻量级。
如上图所示,用户、购物车、订单等服务均注册到注册中心,假如应用访问订单服务,则从注册中心发现服务,然后再调用订单服务。如果订单需要购物车的服务,则从注册中心发现服务,然后再调用购物车服务。
2、Dubbo服务
dubbo和spring cloud都是微服务的具体实现,dubbo是RPC的框架。
角色:Provider、Consumer、Registry、Monitor
启动时,Provider会把提供的所有服务都放到Registry(注册到注册中心)
消费时,Consumer从Registry中找服务,因为Provider不止一个,Consumer不可能一个个的去找。找到后,订阅想要的服务。消费时,调用Provider的远程服务。所以,找服务从注册中心找,消费时找对应的Provider。
监控中心,监控Dubbo运行过程中的参数。
打个比方,注册中心相当于手机中的通讯录,存的是名字。然后拨打号码时,就是拨打11位的号码,这个就是provider的具体服务。
3、Multicast注册中心
它是dubbo自带的注册中心,只使用demo测试,实际开发需要使用Zookeeper注册中心。
步骤如下:
(1)提供方启动时广播自己的地址
(2)消费方启动时广播订阅请求
(3)提供方收到订阅请求时,单播自己的地址给订阅者,如果设置了unicast=false,则广播给订阅者(提供方和消费方在同一台服务器需要该设置)
(4)消费方收到提供方地址时,连接该地址进行RPC调用。
4、Zookeeper注册中心
(1)zookeeper说明
Zookeeper是一个分布式的应用程序协调服务,它是一个为分布式应用提供一致性服务的软件,包括:配置维护、域名服务、分布式同步、组服务等。它的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
本次我们将Zookeeper作为Dubbo服务的注册中心。
(2)windows版本下载使用
下载地址:官网下Apache Downloads
修改conf/zoo_sample.cfg为zoo.cfg
其中:
dataDir=D:\\programs\\apache-zookeeper-3.8.2\\data
logDir=D:\\programs\\apache-zookeeper-3.8.2\\logs
启动命令:
直接zkServer.cmd,不需要带start参数
Zookeeper使用,参考:
zookeeper:简介及常用命令_zookeeper常用命令_LazyKing-qi的博客-CSDN博客
5、Dubbo使用示例
(1)maven工程说明
dubbo-demo是最外层的主工程。
dubbo-api是接口定义层,定义了服务提供者的服务接口
dubbo-provider是服务提供层,负责将服务注册到注册中心(zk),然后对外提供RPC服务。
dubbo-consumer是服务消费层,负责从注册中心拿到服务列表,然后调用相应的RPC服务。
(2)dubbo-demo工程
最外层工程。
pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>dubbo-api</module>
<module>dubbo-provider</module>
<module>dubbo-consumer</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>dubbo-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<dubbo.version>2.7.3</dubbo.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- dubbo依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- zookeeper注册中心引入curator客户端 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
</project>
(3)dubbo-api工程
接口定义层。
- pom.xml
<?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-demo</artifactId>
<groupId>com.example</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- dubbo依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<type>pom</type>
</dependency>
</dependencies>
</project>
- User.java
package com.example.api;
import java.io.Serializable;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class User implements Serializable {
private Integer id;
private String name;
}
- UserServiceI.java
package com.example.api;
public interface UserServiceI {
User selectUserById(Integer id);
}
(4)dubbo-provider工程
- pom.xml
<?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-demo</artifactId>
<groupId>com.example</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>dubbo-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
- application.yml
# 防止端口冲突
server:
port: 8081
dubbo:
application:
# 应用名称
name: provider
registry:
# 注册中心地址
address: zookeeper://172.25.36.203:2181
# 超时时间,单位毫秒
timeout: 6000
# 元中心地址
metadata-report:
address: zookeeper://172.25.36.203:2181
protocol:
# 协议名称
name: dubbo
# 协议端口
port: 20880
scan:
# 扫描包的位置
base-packages: com.example.provider.service
- 将172.25.36.203替换成本机地址。
- UserServiceImpl.java
package com.example.provider.service;
import com.example.api.User;
import com.example.api.UserServiceI;
import org.apache.dubbo.config.annotation.Service;
@Service
public class UserServiceImpl implements UserServiceI {
@Override
public User selectUserById(Integer id) {
User user = new User();
user.setId(id);
user.setName("张三");
return user;
}
}
使用dubbo的Service注解。
- ProviderApplication.java
-
package com.example.provider; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); } }
(5)dubbo-consumer工程
- pom.xml
<?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-demo</artifactId>
<groupId>com.example</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>dubbo-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
- application.yml
# 防止端口冲突
server:
port: 8082
dubbo:
application:
# 应用名称
name: consumer
registry:
# 注册中心地址
address: zookeeper://172.25.36.203:2181
将172.25.36.203替换成本机地址。
- UserInit.java
借用@PostConstruct注解,使得consumer工程启动时调用RPC服务。
package com.example.consumer;
import com.example.api.UserServiceI;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class UserInit {
// 会拉去注册中心的服务缓存在本地,即使注册中心宕机,之前的服务也能用,但是新的服务无法发现
@Reference(parameters = {"unicast", "false"}) // 同一台机器使用广播
private UserServiceI userService;
@PostConstruct
public void init(){
System.out.println(userService.selectUserById(2));
}
}
- ConsumerApplication.java
package com.example.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
(6)工程运行
- 打开zookeeper服务(windows下直接)
- 运行dubbo-provider工程
- 运行dubbo-consumer工程
此时查看zk上的信息,
6、公司开发dubbo说明
比如某个团队开发了用户中心服务,会把服务的接口(类似于dubbo-api工程)打包成jar包,放到公司的maven库中。
另一个团队开发用到用户中心服务,则在pom文件中依赖该工程,配置注册中心的地址,然后通过@Reference进行自动注入,开启RPC远程调用。
7、总结
(1)dubbo使用的架构
最基本的使用需要3个角色
注册中心提供服务注册服务,
provider将服务注册到注册中心,
consumer从注册中心获取服务,并且通过RPC调用provider上的服务
(2)调用RPC服务注解
在需要调用的服务接口上使用@Reference即可直接调用远程服务,它和@Autowired类似均实现了自动注入的过程。