Dubbo开发详解

发布时间:2023-05-19

一、Dubbo是什么

Dubbo是一个高性能、轻量级、简单易用的开源Java RPC框架,是阿里巴巴SOA服务化治理方案的核心框架,提供了RPC通信、服务治理、容错、负载均衡等核心功能。 Dubbo采用了SOA的设计思想,将一个大型的系统拆分为多个小的、可重用的服务,并通过RPC远程调用的方式进行服务通信。Dubbo提供了一个注册中心,可以将小的服务都注册在注册中心中,方便服务消费方进行查找和使用。 Dubbo追求简单化,不但对服务端提供了简单的注解和API进行服务的发布和使用,对客户端也提供了简单易用、优雅的调用方式。

二、Dubbo的核心概念

  1. 服务提供方(Provider) 服务提供方即服务的实现者。在Dubbo中,服务提供方向注册中心注册自己提供的服务,等待服务消费方进行调用。
    @DubboService
    public class DemoServiceImpl implements DemoService {
        public String sayHello(String name) {
            return "Hello, " + name;
        }
    }
    
  2. 服务消费方(Consumer) 服务消费方即服务的调用者。在Dubbo中,服务消费方通过引入服务接口的依赖和进行相应的配置,即可远程调用服务。
    @Reference(url = "dubbo://127.0.0.1:20880")
    private DemoService demoService;
    
  3. 注册中心(Registry) 注册中心是服务提供方和服务消费方之间进行联系的桥梁。Dubbo支持多种注册中心,包括Zookeeper、Redis等。
    dubbo.registry.address=zookeeper://127.0.0.1:2181
    
  4. 协议(Protocol) 协议是服务提供方和服务消费方之间进行通讯的方式。Dubbo支持多种协议,包括Dubbo、HTTP等协议。
    dubbo.protocol.name=dubbo
    dubbo.protocol.port=20880
    
  5. 服务配置(Service Configuration) 服务配置是服务提供方对服务进行配置的方式,其中包括服务版本号、负载均衡方式、超时时间等。
    @Service(version = "1.0.0", loadbalance = "roundrobin", timeout = 1000)
    public class DemoServiceImpl implements DemoService {
        public String sayHello(String name) {
            return "Hello, " + name;
        }
    }
    

三、Dubbo的使用方式

  1. XML配置方式 通过配置文件对Dubbo进行配置,包括服务提供方、服务消费方、注册中心等。示例代码如下:
    <!-- 服务提供方配置 -->
    <dubbo:service interface="com.zhiyang.demo.DemoService" ref="demoService" version="1.0.0">
        <dubbo:method name="sayHello" timeout="1000" />
    </dubbo:service>
    <!-- 服务消费方配置 -->
    <dubbo:reference id="demoService" interface="com.zhiyang.demo.DemoService" version="1.0.0" />
    <!-- 注册中心配置 -->
    <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" />
    
  2. 注解配置方式 通过注解对Dubbo进行配置。在服务提供方上使用@DubboService注解,标注服务实现类,并在服务消费方上使用@Reference注解,进行服务依赖注入。示例代码如下:
    @DubboService(interfaceClass = DemoService.class, version = "1.0.0")
    public class DemoServiceImpl implements DemoService {
        public String sayHello(String name) {
            return "Hello, " + name;
        }
    }
    public class DemoConsumer {
        @Reference(interfaceClass = DemoService.class, version = "1.0.0")
        private DemoService demoService;
        public void sayHello(String name) {
            demoService.sayHello(name);
        }
    }
    

四、Dubbo的容错机制

  1. 重试机制 当服务调用失败时,Dubbo可以通过重新发送请求到可用的服务提供方进行重试。可以通过配置retries参数来控制重试次数。
    <dubbo:reference retries="3" />
    
  2. 失败快速返回 当服务调用失败时,Dubbo可以直接返回空结果或者抛出异常,防止故障服务拖垮整个系统。可以通过配置timeout参数来控制调用超时时间。
    <dubbo:reference timeout="1000" />
    
  3. 容错机制 当服务调用失败时,Dubbo可以通过容错机制来处理异常情况。Dubbo提供了多种容错方式,包括Failover、Failfast、Failsafe和Failback。其中,Failover是Dubbo默认的容错方式,当调用失败时,会尝试重新调用其他服务提供方,直到调用成功。
    <dubbo:reference cluster="failover" />
    

五、Dubbo的负载均衡方式

  1. Random负载均衡 随机选择一个可用的服务提供方进行调用,每个服务提供方的调用次数大致相同。
    <dubbo:reference loadbalance="random" />
    
  2. RoundRobin负载均衡 轮询选择一个可用的服务提供方进行调用,每个服务提供方被调用的频率大致相同。
    <dubbo:reference loadbalance="roundrobin" />
    
  3. LeastActive负载均衡 根据服务提供方的活跃数进行选择,活跃数越小的服务提供方被选择的概率越高。
    <dubbo:reference loadbalance="leastactive" />
    

六、Dubbo的扩展机制

Dubbo提供了丰富的扩展点,通过扩展机制可以对Dubbo进行自定义的扩展和实现。Dubbo的扩展机制基于Java SPI机制。 示例代码如下:

public interface HelloService {
    String sayHello(String name);
}
public class HelloServiceImpl implements HelloService {
    public String sayHello(String name) {
        return "Hello, " + name;
    }
}
// 扩展过滤器
public class CustomFilter implements Filter {
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        System.out.println("CustomFilter invoked");
        return invoker.invoke(invocation);
    }
}
// 扩展服务
public class CustomProtocol extends AbstractProtocol {
    @Override
    public int getDefaultPort() {
        return 8080;
    }
}
// 在resources/META-INF/dubbo目录下创建文件,文件名为org.apache.dubbo.rpc.Filter,文件内容为CustomFilter
// 在resources/META-INF/dubbo目录下创建文件,文件名为org.apache.dubbo.rpc.Protocol,文件内容为CustomProtocol
// 使用自定义的服务扩展点
<dubbo:protocol name="custom" />
// 使用自定义的过滤器扩展点
<dubbo:reference filter="custom" />

七、Dubbo的优化技巧

  1. 合理设置线程池大小 线程池大小的设置应该根据实际业务情况进行调整。
    <dubbo:protocol name="dubbo" threadpool="fixed" threads="200" />
    
  2. 使用本地缓存 在调用远程服务时,Dubbo会进行网络通信,建立远程连接等操作,会带来一定的性能损失。使用本地缓存可以有效提高调用性能。
    @Service(cache = "lru")
    public class DemoServiceImpl implements DemoService {
        public String sayHello(String name) {
            return "Hello, " + name;
        }
    }
    
  3. 使用异步调用 通过异步调用可以提高服务消费方的吞吐量,减少调用方的等待时间。
    CompletableFuture<String> future = RpcContext.getContext().asyncCall(() -> demoService.sayHello("World"));
    future.thenAccept(result -> System.out.println(result));
    

八、总结

本文对Dubbo进行了详细的介绍,包括Dubbo的核心概念、使用方式、容错机制、负载均衡方式、扩展机制和优化技巧等方面。通过深入的了解和使用Dubbo,可以帮助我们构建稳定、高效、可靠的分布式系统。