初识Dubbo
Posted Java Miraculous
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初识Dubbo相关的知识,希望对你有一定的参考价值。
Apache Dubbo是阿里巴巴开发的、一款高性能的、轻量级的、开源的RPC框架,它提供了6大核心能力:面向接口代理的高性能RPC调用,智能容错和负载均衡,服务自动注册和发现,高度可扩展能力,运行期流量调度,可视化的服务治理与运维。说实话,就算你以前没听说过Dubbo,但是看见这些描述就觉得这玩意很屌,接下来就对它进行详细的介绍。
一、诞生背景
互联网发展初期,java应用都是单体单机的,意思就是所有的功能都写到一个java应用里,然后把这个应用部署到一台机器上,随着互联网的兴起,网络流量的增加,原来一台机器已经支撑不了大流量了,这时候就会用集群,把这个应用部署到多台机器上,这样解决了问题,再后来,java应用里的业务逻辑越来越复杂,比如你要上一个电商网站购物,这时候你首先需要注册一个账号登录上去,然后去浏览商品,然后选择心仪的商品添加到购物车里,然后去提交订单,付款等,想象一下,这些功能都写到一个java应用里会有什么问题?首先,这个应用的代码量肯定多的超乎你的认知,发版时候应用的启动时间会很长吧,然后如果发版出现问题,其他没有改动的功能也会不可用,所有人在一个工程里开发代码也会非常不方便等等,基于这些问题,后来开发人员把每个模块独立成一个应用,比如登录注册,就叫会员系统,商品列表以及搜索就叫商品系统,添加购物车就叫购物车系统等等,这就是所谓的分布式架构。但是分布式架构会面临很多的问题,比如:一次请求只需要一台机器进行处理,那这台机器怎么选出来?如果我新增了一台机器,调用者怎么发现这台机器?如果请求打到某台机器上,但是调用出错怎么办?服务关机宕机或者恢复后怎么办?基于这些问题,Dubbo就应运而生了。
二、Dubbo的工作流程图
流程说明:
1.提供者(Provider)绑定指定端口并启动服务
2.提供者连接注册中心(Registry),把本机IP、端口、应用信息和提供的服务信息发送到注册中心
3.消费者(Consumer),连接注册中心,并发送应用信息、要调用的服务信息发送给注册中心
4.注册中心根据消费者要调用的服务信息匹配对应的提供者列表,并把这些提供者ip端口发送至Consumer 应用缓存起来
5.消费者在发起远程调用时从缓存的提供者列表里选择一个发起调用
6.提供者状态变更(新增或者下线)会实时通知注册中心、然后注册中心实时推送至消费者,然后消费者会将本地缓存的提供者列表更新
为什么这么设计?
1.消费者与提供者解耦,双方都可以动态增减节点
2.注册中心本身也可以做集群,可以动态增减节点,并且在任意一台宕机后,可以自动切换到另一台
3.消费者和提供者双方都不直接依赖注册中心,因为消费者本地缓存了一份提供者列表,所以就算注册中心宕机也不会影响服务的调用
三、写一个小Demo演示下Dubbo的调用
首先用idea创建一个普通的基于maven的java工程,然后里面新建三个模块,分别是Consumer,Provider,Sdk,其中Consumer代表消费者,Provider代表提供者,Sdk的话放一些实体类和接口,这样Consumer和Provider都可以依赖Sdk
大概说下这三个模块,Provider就是提供者(接口的实现类都写到这里面),Consumer就是消费者(谁调用你接口就在这里面写他的业务),Sdk模块就相当于Provider提供给Consumer的jar包,写过dubbo的应该都懂。
本次咱的演示采用编码的方式,如果你们用过dubbo的话应该知道dubbo都是配置的标签,但是你可曾知道?标签解析后终归是要封装成api的(刚学了spring,这点不要忘了),直接用api去演示更加直接,关于项目怎么创建,这里就不细说了,回头我会把demo上传到云上,你们自行下载,这里主要说下关键的消费者和提供者的代码。
提供者:
package com.ayo.dubbo.provider;
import com.ayo.dubbo.service.UserService;
import com.ayo.dubbo.serviceImpl.UserServiceImpl;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.junit.Test;
import java.io.IOException;
/**
* @Authror ayo
* @Date 2020/11/26 15:11
*/
public class Provider {
@Test
public void testProvider() throws IOException {
//1、创建serviceConfig实例
ServiceConfig<UserService> serviceConfig = new ServiceConfig<UserService>();
//2、设置应用程序配置
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-provider");
serviceConfig.setApplication(applicationConfig);
//3、设置服务注册中心信息
RegistryConfig registryConfig = new RegistryConfig("zookeeper://127.0.0.1:2181");
serviceConfig.setRegistry(registryConfig);
//4、设置接口与实现类
serviceConfig.setInterface(UserService.class);
serviceConfig.setRef(new UserServiceImpl());
//5、设置服务分组与版本
serviceConfig.setGroup("member");
serviceConfig.setVersion("1.0.0");
//6、导出服务
serviceConfig.export();
//7.挂起线程,避免服务停止
System.out.println("Provider is start!");
System.in.read();
}
}
消费者:
package com.ayo.dubbo.consumer;
import com.ayo.dubbo.service.UserService;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.junit.Test;
/**
* @Authror ayo
* @Date 2020/11/26 15:10
*/
public class Consumer {
public void testConsumer(){
//1.创建服务引用对象实例
ReferenceConfig<UserService> referenceConfig = new ReferenceConfig<UserService>();
//2.设置应用程序信息
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-consumer");
referenceConfig.setApplication(applicationConfig);
//3.设置服务注册中心
RegistryConfig registryConfig = new RegistryConfig("zookeeper://127.0.0.1:2181");
referenceConfig.setRegistry(registryConfig);
//3.设置服务接口和超时时间
referenceConfig.setInterface(UserService.class);
referenceConfig.setTimeout(5000);
//4.设置服务分组与版本
referenceConfig.setVersion("1.0.0");
referenceConfig.setGroup("member");
//5.引用服务
UserService userService = referenceConfig.get();
//6.调用服务
System.out.println(userService.say("李易峰"));
}
}
zk的话本地下载一个启动起来就行了:
然后先运行提供者,再运行消费者:
dubbo演示完毕,但是你了解它的运行原理吗?demo都会写,不会写的网上搜下就会写了,但如果你去阿里或者美团面试的时候,可不是说你把demo写出来就让你过了,面试官想知道的是你对dubbo的实现原理以及它的运行原理了解有多少,从下一篇文章开始,将逐步分析dubbo的原理,今天先勾起你的好奇心!
以上是关于初识Dubbo的主要内容,如果未能解决你的问题,请参考以下文章
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段