版本选择:3.0.2.1版本
Dubbo3.0相比2.x,资源利用率显著提升,吞吐量有所提升。
dubbo是一个微服务框架,架构演变衍生而来。起负载均衡,集群容错作用。
架构演变过程
单一应用架构 --> 垂直应用架构 --> 分布式服务架构 --> 流动计算架构
- 单一应用架构:网站访问流量小,只需单一应用将所有功能部署在一起,简单方便。数据访问框架(ORM)是关键。
- 垂直应用架构:访问量增大,单一应用靠增加机器带来的速度提升很小,需要对应用进行拆分以提升效率。加速前端页面开发的Web框架(MVC)是关键。
- 分布式服务架构:垂直应用越来越多,应用之间互相交互,将核心业务抽取成模块作为独立服务,形成服务中心。哪个业务功能访问量大,只需单独针对此服务进行扩容即可。用于提高业务复和整合的分布式服务框架(RPC)是关键。
- 流动计算架构:服务越来越多,容量的评估和小服务资源浪费等问题逐渐显现,此时需要一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,资源调用和服务治理中心(SOA)是关键。
SOA:服务治理
- 动态路由
- 动态修改配置
- 服务的调用关系
Dubbo架构图
Container:服务运行容器
Provider:暴露服务的服务提供者
Consumer:调用远程服务的服务消费者
Monitor:监控中心,统计服务调用次数和调用时间
Registry:注册中心(如zookeeper),服务服务注册与发现
0. 服务容器负责启动,加载,运行服务提供者。
1. 服务提供者(生产者)在启动时,向注册中心注册自己提供的服务。
2. 服务消费者在启动时,向注册中心订阅自己所需的服务。
3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
基于Spring项目搭建
pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework</artifactId>
<scope>5.2.8.RELEASE</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>5.2.8.RELEASE</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<scope>5.2.8.RELEASE</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<scope>3.0.2.1</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<scope>3.0.2.1</scope>
</dependency>
生产者
provider.properties
dubbo.application.name=dubbo_provider
dubbo.registry.address=zookeeper://${zookeeper.address:127.0.0.1}:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
ProviderConfiguration
package cn.dubbo.config;
@Configuration
// 启用Dubbo注解,扫描@DubboService和@DubboRef注解
@EnableDubbo(scanBasePackages="cn.dubbo")
@PropertySource("classpath:/provider.properties")
public class ProviderConfiguration {
}
UserServiceImpl
@DubboService
public class UserServiceImpl implements UserService {
@Override
public String query(String name) {
return "hello, " + name;
}
}
AnnotationProvider
public class AnnotationProvider {
public static void main(String[] args) {
new AnnotationConfigApplicationContext(ProviderConfiguration.class);
new CountDownLatch(1).await();
}
}
消费者
consumer.properties
dubbo.application.name=dubbo_consumer
dubbo.registry.address=zookeeper://${zookeeper.address:127.0.0.1}:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=29015
ConsumerConfiguration
package cn.dubbo.config;
@Configuration
// 启用Dubbo注解,扫描@DubboService和@DubboRef注解
@EnableDubbo(scanBasePackages="cn.dubbo")
@PropertySource("classpath:/consumer.properties")
public class ConsumerConfiguration {
}
AnnotationConsumer
public class AnnotationConsumer {
public static void main(String[] args) {
new AnnotationConfigApplicationContext(ConsumerConfiguration.class);
new CountDownLatch(1).await();
}
}
UserController
package cn.dubbo.controller;
@RestController
public class UserController {
// check=false,如果服务找不到不会报错
@DubboReference(check = false)
private UserService service;
@RequestMapping(value = "hello/{name}",method = RequestMethod.GET)
public String Hello(@PathVariable String name){
return service.query(name);
}
}
基于Springboot项目搭建
pom.xml
<!-- Spring Boot Dubbo 依赖 -->
<dependency>
<groupId>io.dubbo.springboot</groupId>
<artifactId>spring-boot-starter-dubbo</artifactId>
<version>1.0.0</version>
</dependency>
<!-- zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
</dependency>
创建生产者
创建项目dubbo-server
application.properties
server.port=8081
## Dubbo 服务提供者配置
spring.dubbo.application.name=provider
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
spring.dubbo.protocol.name=dubbo
spring.dubbo.protocol.port=20880
spring.dubbo.scan=com.example.dubbo.service
DubboService
package com.example.dubbo.service;
public interface DubboService {
String hello(String name);
}
DubboServiceImpl (注意此处@Service 注解标识为 Dubbo 服务)
package com.example.dubbo.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.example.dubbo.service.DubboService;
// 注册为 Dubbo 服务
@Service
public class DubboServiceImpl implements DubboService {
@Override
public String hello(String name) {
return name + ",你好!";
}
}
创建消费者
创建项目dubbo-client
application.properties
server.port=8082
## Dubbo 服务消费者配置
spring.dubbo.application.name=consumer
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
spring.dubbo.scan=com.example.dubbo.service
UserDubboConsumerService
package com.example.dubbo.service;
@Component
public class UserDubboConsumerService {
@Reference
DubboService service;
public String hello(String name) {
return service.hello(name);
}
}
UserController
package com.example.dubbo.controller;
@RestController
public class UserController {
@Resource
private UserDubboConsumerService service;
@RequestMapping(value = "hello/{name}",method = RequestMethod.GET)
public String Hello(@PathVariable String name){
return service.hello(name);
}
}
服务发布
public class ProviderApi {
public static void main(String[] args) throws IOException {
UserServiceImpl userService = new UserServiceImpl();
// 1、应用信息
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("dubbo_provider");
// 2、注册信息
RegistryConfig registry = new RegistryConfig();
registry.setAddress("zookeeper://127.0.0.1:2181");
// 3、协议信息
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setName("dubbo");
protocolConfig.setPort(20880);
protocolConfig.setThreads(200);
// 4、服务发布
ServiceConfig<UserServcie> serviceConfig = new ServiceConfig<UserServcie>();
serviceConfig.setApplication(applicationConfig);
serviceConfig.setRegistry(registry);
serviceConfig.setProtocol(protocolConfig);
serviceConfig.setInterface(UserService.class); // 接口
serviceConfig.setRef(userService); // 接口实现
serviceConfig.setVersion("1.0.0");
serviceConfig.export(); //服务发布、暴露服务
}
}
服务引用
@Test
public void referenceService() {
UserServiceImpl userService = new UserServiceImpl();
// 1、应用信息
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("dubbo_consumer");
// 2、注册信息
RegistryConfig registry = new RegistryConfig();
registry.setAddress("zookeeper://127.0.0.1:2181");
// 3、引用API
ReferenceConfig<UserServcie> refConfig = new ReferenceConfig<UserServcie>();
refConfig.setApplication(applicationConfig);
refConfig.setRegistry(registryConfig);
refConfig.setInterface(UserService.class);
// 4、服务引用:引用过程很重,如果想用API方式去引用服务,这个对象需要缓存
UserService userService = refConfig.get();
userService.query("Lucifer");
}