Dubbo 技术详解,我非常喜欢Dubbo的设计

您所在的位置:网站首页 kk框架 Dubbo 技术详解,我非常喜欢Dubbo的设计

Dubbo 技术详解,我非常喜欢Dubbo的设计

#Dubbo 技术详解,我非常喜欢Dubbo的设计| 来源: 网络整理| 查看: 265

Dubbo 技术详解

Dubbo 是阿里巴巴开源的一款高性能、轻量级分布式服务框架,基于 Java 的 RPC 协议,支持多种协议和多种注册中心。其官方网站为 https://dubbo.apache.org/zh/。

本文将从以下几个方面对 Dubbo 进行详细讲解:

Dubbo 实现原理及代码示例Dubbo 拓展协议分类及代码示例Dubbo 拓展实现原理及代码示例Dubbo 服务发现实现原理及代码示例Dubbo 实现原理及代码示例

Dubbo 实现思路主要是将服务提供者发布到注册中心,消费者通过相应的接口调用服务,并通过 Dubbo 进行远程调用。

Dubbo 的实现,可以按照下面几个层次进行划分,如下图所示[1]:

Service 层:服务接口层,该层是服务消费者和服务提供者都需要实现的,主要是定义服务接口和方法。public interface HelloService { String sayHello(String name); }Config 层:配置层,主要负责 Dubbo 的配置,如各协议配置默认值、服务提供者和服务消费者配置等。 Proxy 层:服务代理层,主要用于封装服务接口,实现客户端的远程调用。public class HelloServiceProxy implements HelloService { private GenericService genericService; public HelloServiceProxy(GenericService genericService) { super(); this.genericService = genericService; } @Override public String sayHello(String name) { Object result = genericService.$invoke("sayHello", new String[]{String.class.getName()}, new Object[]{name}); return String.valueOf(result); } }Registry 层:注册中心层,负责服务的注册与发现。@Service(interfaceName = "com.example.demo.service.HelloService") public class HelloServiceImpl implements HelloService { @Override public String sayHello(String name) { return "Hello, " + name + "!"; } }Cluster 层:集群层,负责将多个服务提供者组合成一个服务提供组,并提供服务的均衡负载和容错处理。 Monitor 层:监控层,负责对 RPC 调用进行监控,以便于日志输出、统计服务调用次数等。 Protocol 层:协议层,主要是定义 RPC 调用的格式和方式,Dubbo 支持多种协议,如 dubbo 协议、rmi 协议、hessian 协议等。public class HelloServiceProtocol implements Protocol { @Override public int getDefaultPort() { return 8080; } @Override public Exporter export(Invoker invoker) throws RpcException { return null; } @Override public Invoker refer(Class type, URL url) throws RpcException { if (GenericService.class.equals(type)) { return new HelloServiceInvoker(type, url); } return null; } @Override public void destroy() { } }Filter 层:过滤器层,负责在 RPC 调用前后进行一些预处理工作,如权限校验、数据加密解密等。public class LogFilter implements Filter { @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { String serviceName = invoker.getInterface().getSimpleName(); String methodName = invocation.getMethodName(); long start = System.currentTimeMillis(); Result result = invoker.invoke(invocation); long end = System.currentTimeMillis(); LOG.info("Invoke {}.{}, dataSize:{}, time:{}ms", serviceName, methodName, result.getData().length, end - start); return result; } }Invoker 层:调用层,负责将服务接口和协议组合为一个可执行的对象,并提供服务的执行方法。public class HelloServiceInvoker extends AbstractInvoker { public HelloServiceInvoker(Class type, URL url) { super(type, url); } @Override protected Result doInvoke(Invocation invocation) throws Throwable { String methodName = invocation.getMethodName(); Object[] arguments = invocation.getArguments(); if ("sayHello".equals(methodName)) { String name = (String) arguments[0]; String result = "Hello, " + name + "!"; return new RpcResult(result); } return new RpcResult(); } }Extension 层:扩展层,通过 SPI 机制来支持 Dubbo 的扩展,如负载均衡、序列化、压缩等。// 在 resources/META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.LoadBalance 文件中配置名称为 "random" 的 LoadBalance 实现类。 @SPI("random") public interface LoadBalance { /** * Select one invoker in list. *

* 随机选择一个服务提供者调用。 *

* * @param invokers invokers. * @param url refer url * @param invocation invocation. * @return selected invoker. * @throws RpcException 当发生异常时抛出。 */ Invoker select(List invokers, URL url, Invocation invocation) throws RpcException; }Dubbo 拓展协议分类及代码示例

Dubbo 支持的协议包括:

Dubbo 协议:用于服务之间的通信。 RMI 协议:使用 Java 的 RMI(Remote Method Invocation)机制进行通 Hessian 协议:使用 Hessian 进行序列化和反序列化,适合传输较小的数据量。xml复制代码 HTTP 和 WebService 协议:基于 HTTP 协议进行通讯,使用 SOAP 消息格式进行数据交互。xml复制代码 Dubbo 拓展实现原理及代码示例

Dubbo 支持 SPI(Service Provider Interface)机制来进行功能拓展,其实现方式主要包括以下三点:

ExtensionLoader:用于加载指定接口的拓展实现。ExtensionLoader extensionLoader = ExtensionLoader.getExtensionLoader(Filter.class); Filter filter = extensionLoader.getExtension("log"); Result result = filter.invoke(invoker, invocation);Adaptive:通过 @Adaptive 注解使得 Dubbo 可以在运行时动态选择对应的拓展实现。@Adaptive("loadbalance") public interface LoadBalance { Invoker select(List invokers, URL url, Invocation invocation) throws RpcException; }Configurable:用于将不同服务的配置封装成 Config 对象,方便进行参数配置和管理。@Configuration public class DubboConfiguration { @Bean public ApplicationConfig applicationConfig() { ApplicationConfig applicationConfig = new ApplicationConfig(); applicationConfig.setName("dubbo-demo-provider"); return applicationConfig; } @Bean public ProtocolConfig protocolConfig() { ProtocolConfig protocolConfig = new ProtocolConfig(); protocolConfig.setName("dubbo"); protocolConfig.setPort(20880); return protocolConfig; } @Bean public RegistryConfig registryConfig() { RegistryConfig registryConfig = new RegistryConfig(); registryConfig.setAddress("zookeeper://127.0.0.1:2181"); return registryConfig; } }Dubbo 服务发现实现原理及代码示例

Dubbo 服务发现的实现原理是基于注册中心实现的,具体来说,Dubbo 通过注册中心将提供者的服务地址信息注册到注册中心,消费者通过注册中心获取服务提供者的地址信息,再进行调用。

在 Dubbo 中,服务发现由类org.apache.dubbo.registry.RegistryService定义,并且有三种方式进行实现:Zookeeper、Redis 和 Multicast。

其中,Zookeeper 是 Dubbo 默认的注册中心实现方式。在 Dubbo 中,服务的注册与发现是通过类org.apache.dubbo.registry.Registry和org.apache.dubbo.registry.RegistryFactory完成的。

下面是一个基于 Zookeeper 注册中心实现的服务发现示例代码:

// 配置服务注册中心地址 RegistryConfig registry = new RegistryConfig(); registry.setAddress("zookeeper://127.0.0.1:2181"); // 配置服务消费者 ReferenceConfig reference = new ReferenceConfig(); reference.setRegistry(registry); reference.setInterface(HelloService.class); reference.setVersion("1.0.0"); // 获取服务对象并调用方法 HelloService helloService = reference.get(); String result = helloService.sayHello("world");

在上面的示例中,首先通过RegistryConfig配置服务注册中心的地址,然后通过ReferenceConfig配置服务的消费者,包括注册中心的配置、服务接口、以及版本号等。最后获取服务对象后,就可以调用服务提供者的方法。



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3