版权声明:谁不是在与生活苦战。狼性的年级,就不要做个俗人 https://blog.csdn.net/Axela30W/article/details/85233671
一、背景:
摘自Dubbo官网:http://dubbo.apache.org
- 当流量非常低时,只有一个应用程序,所有特性一起部署,以减少部署节点和成本。此时,数据访问框架(ORM)是简化CRUD工作负载的关键。
- 当流量增加时,添加单片应用程序实例并不能很好地加速访问,提高访问效率的方法之一是将单片应用程序分割成离散应用程序。此时,用于加速前端页面开发的Web框架(MVC)是关键。
- 随着垂直应用的不断增多,应用之间的交互不可避免,一些核心业务被提取出来,作为独立的服务,逐渐形成一个稳定的服务中心,这样前端应用可以更快地响应多变的市场需求。此时,用于业务重用和集成的分布式服务框架(RPC)是关键。
- 当服务数量不断增加时,容量评估变得困难,而且规模较小的服务常常造成资源的浪费。为了解决这些问题,需要增加调度中心,根据业务量管理集群容量,提高集群的利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键。
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
Dubbo的主要功能: - 透明化的远程方法调用,就像调用本地方法一样调用远程方法。不同服务之间方法的相互调用(说的更直白一点就是借口调用),一个服务可能是服务提供者也可能服务消费者
- 负载均衡及容错机制,负载均衡策略默认是随机,可配置选择。
- 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。常用Zookeeper做注册中心。
二:核心角色
Dubbo官网的Quick start模块有入门实例,不过是基于xml配置方式的。这里介绍基于SpringBoot注解方式。
核心角色组成:
有微服务基础的应该一看就懂了这张图。这里的各个角色类比于SpringCloud的Eureka注册中心,路由,监控等组件。
三、代码
整个项目模块分为3部分:
- dubbo-api: the common service api:通用api
- dubbo-provider: the provider codes:服务提供者
- dubbo-consumer: the consumer codes:服务消费者
父pom.xml主要依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.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>
这里加入了Zookeeper依赖,启动的时候会发现它以默认参数启动了注册中心服务,就不需要再本机手动启动Zookeeper服务了。
1、dubbo-api
pom文件继承父pom(另两个模块同理):
<?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.mistra</groupId>
<artifactId>dubbo.api</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>dubbo-api</name>
<description>Dubbo api for Spring Boot</description>
<parent>
<groupId>com.mistra</groupId>
<artifactId>dubbo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
</project>
次公共模块定义好一个Service就好了
public interface MistraService {
/**
*
* @param name
* @return
*/
String welcome(String name);
}
2、dubbo-provider
resources文件夹下定义配置文件application.properties
spring.application.name = dubbo-provider
server.port = 9090
dubbo.application.name = dubbo-provider
mistra.service.version = 1.0.0
dubbo.protocol.name = dubbo
dubbo.protocol.port = 20880
dubbo.registry.address = zookeeper://localhost:2181
dubbo.provider.timeout = 1000
定义服务实现类
@Service(version = "${mistra.service.version}")
public class MistraServiceImpl implements MistraService {
@Override
public String welcome(String name) {
return "Hello" + name;
}
}
注意,此处的@Service注解来源于dubbo包,而非spring包,version标注了此服务的版本信息
SpringBoot的启动类除了原来的@SpringBootApplication,还需要加上@EnableDubbo
@SpringBootApplication
@EnableDubbo
public class DubboConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(DubboConsumerApplication.class, args);
}
}
3、dubbo-consumer
resources文件夹下定义配置文件application.properties
spring.application.name = dubbo-consumer
server.port = 9091
dubbo.application.name = dubbo-consumer
mistra.service.version = 1.0.0
dubbo.protocol.name = dubbo
dubbo.protocol.port = 20880
dubbo.registry.address = zookeeper://localhost:2181
dubbo.consumer.timeout = 5000
定义一个controller
@RestController
public class ConsumerController {
@Reference(version = "${mistra.service.version}")
private MistraService mistraService;
@RequestMapping("/sayHello/{name}")
public String sayHello(@PathVariable("name") String name) {
return mistraService.welcome(name);
}
}
@Reference注解是dubbo包下定义的,注入service时要依赖配置文件配置的版本号
SpringBoot启动类写法同上。
四、测试
正常启动顺序是先启动服务提供者模块,再启动服务消费者模块。浏览器访问正常。
如果先启动了服务消费者模块,后启动服务提供者模块,调用方法的时候会报空指针异常。应该启动消费者服务订阅服务的时候没找到对应的服务。
代码地址:GitHub