Skip to content

Apache Dubbo 2.x 版本指南

官方介绍

Apache Dubbo 2.x 是阿里巴巴开源的高性能 Java RPC 框架,现已成为 Apache 软件基金会的顶级项目。Dubbo 2.x 提供了完整的分布式服务治理解决方案,包括高性能的 RPC 调用、智能负载均衡、服务自动注册与发现、服务治理等功能。2.x 版本在稳定性和功能性方面表现出色,被广泛应用于大型分布式系统中。

Dubbo 2.x 以其高性能、高可用性和高扩展性著称,是构建微服务架构的重要组件之一。


版本特性

核心特性

  • 高性能 RPC: 基于 NIO 的异步通信,支持多种序列化协议
  • 服务治理: 完善的服务注册、发现和治理机制
  • 负载均衡: 多种负载均衡算法,支持故障转移和快速失败
  • 集群容错: 提供 Failover、Failfast、Failsafe 等多种容错策略
  • 智能路由: 支持条件路由、脚本路由等高级路由功能
  • 监控统计: 内置服务调用统计和性能监控

2.x 版本演进

  • 2.5.x: 初始开源版本,提供了基础的 RPC 功能
  • 2.6.x: 增强了服务治理功能,完善了 SPI 机制
  • 2.7.x: 重构了内部架构,增强了对 Spring Boot 的支持
  • 2.8.x: 优化性能,增加了更多的协议支持

官方获取地址

xml
<!-- Maven 依赖 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.7.15</version>
</dependency>

或者通过官方网站下载:

环境要求

  • Java: JDK 1.8 或更高版本
  • 依赖管理: Maven 3.2+ 或 Gradle 4.0+
  • 注册中心: Zookeeper、Nacos、Redis 等
  • 操作系统: 跨平台支持(Linux、Windows、macOS)

部署方法

1. 项目初始化

bash
# 创建 Maven 项目
mvn archetype:generate -DgroupId=com.example \
    -DartifactId=dubbo-provider \
    -DarchetypeArtifactId=maven-archetype-quickstart \
    -DinteractiveMode=false

2. 添加依赖

xml
<dependencies>
    <!-- Dubbo 核心依赖 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.7.15</version>
    </dependency>
    
    <!-- 注册中心依赖,以 Zookeeper 为例 -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>5.2.0</version>
    </dependency>
    
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>5.2.0</version>
    </dependency>
</dependencies>

3. 配置文件说明

Dubbo 2.x 使用以下配置文件:

dubbo-provider.xml

xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo
       http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息 -->
    <dubbo:application name="dubbo-provider"/>

    <!-- 使用 zookeeper 注册中心 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>

    <!-- 用 dubbo 协议在 20880 端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="com.example.api.DemoService" ref="demoServiceImpl"/>

    <!-- 服务实现 -->
    <bean id="demoServiceImpl" class="com.example.service.DemoServiceImpl"/>
</beans>

dubbo-consumer.xml

xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo
       http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- 消费方应用信息 -->
    <dubbo:application name="dubbo-consumer"/>

    <!-- 使用 zookeeper 注册中心 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>

    <!-- 生成远程服务代理 -->
    <dubbo:reference id="demoService" interface="com.example.api.DemoService"/>
</beans>

4. 使用注解配置

ProviderConfig.java

java
package com.example.config;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@EnableDubbo(scanBasePackages = "com.example.service")
@PropertySource("classpath:dubbo.properties")
public class ProviderConfig {

    @Bean
    public ApplicationConfig applicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("dubbo-provider");
        return applicationConfig;
    }

    @Bean
    public RegistryConfig registryConfig() {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress("zookeeper://127.0.0.1:2181");
        return registryConfig;
    }

    @Bean
    public ProtocolConfig protocolConfig() {
        ProtocolConfig protocolConfig = new ProtocolConfig();
        protocolConfig.setName("dubbo");
        protocolConfig.setPort(20880);
        return protocolConfig;
    }
}

二次开发

定义服务接口

src/main/java/com/example/api/DemoService.java

java
package com.example.api;

public interface DemoService {
    String sayHello(String name);
    int calculate(int a, int b);
}

实现服务

src/main/java/com/example/service/DemoServiceImpl.java

java
package com.example.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.example.api.DemoService;

@Service(version = "1.0.0", timeout = 5000)
public class DemoServiceImpl implements DemoService {

    @Override
    public String sayHello(String name) {
        return "Hello " + name + ", Welcome to Dubbo 2.x!";
    }

    @Override
    public int calculate(int a, int b) {
        return a + b;
    }
}

消费者端调用

src/main/java/com/example/consumer/Consumer.java

java
package com.example.consumer;

import com.alibaba.dubbo.config.annotation.Reference;
import com.example.api.DemoService;
import org.springframework.stereotype.Component;

@Component
public class Consumer {

    @Reference(version = "1.0.0")
    private DemoService demoService;

    public void test() {
        String result = demoService.sayHello("World");
        System.out.println(result);
        
        int sum = demoService.calculate(10, 20);
        System.out.println("Calculate result: " + sum);
    }
}

自定义过滤器

src/main/java/com/example/filter/CustomFilter.java

java
package com.example.filter;

import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.*;
import com.alibaba.dubbo.rpc.protocol.dubbo.FutureAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Activate(group = {Constants.PROVIDER, Constants.CONSUMER})
public class CustomFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(CustomFilter.class);

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        long startTime = System.currentTimeMillis();
        
        try {
            logger.info("Dubbo 2.x - Invoking method: " + invocation.getMethodName());
            
            Result result = invoker.invoke(invocation);
            
            long duration = System.currentTimeMillis() - startTime;
            logger.info("Dubbo 2.x - Method execution took: " + duration + " ms");
            
            return result;
        } catch (Exception e) {
            logger.error("Dubbo 2.x - Error invoking method: " + invocation.getMethodName(), e);
            throw e;
        }
    }
}

配置示例

服务提供者配置

dubbo.properties

properties
# 应用配置
dubbo.application.name=dubbo-provider
dubbo.application.owner=developer

# 注册中心配置
dubbo.registry.address=zookeeper://127.0.0.1:2181

# 协议配置
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
dubbo.protocol.host=0.0.0.0

# 服务配置
dubbo.service.loadbalance=random
dubbo.service.timeout=5000
dubbo.service.retries=3

# 提供者配置
dubbo.provider.timeout=5000
dubbo.provider.retries=3
dubbo.provider.loadbalance=random
dubbo.provider.cluster=failover

服务消费者配置

consumer.properties

properties
# 应用配置
dubbo.application.name=dubbo-consumer
dubbo.application.owner=developer

# 注册中心配置
dubbo.registry.address=zookeeper://127.0.0.1:2181

# 消费者配置
dubbo.consumer.timeout=5000
dubbo.consumer.retries=3
dubbo.consumer.check=false
dubbo.consumer.loadbalance=random
dubbo.consumer.cluster=failover

高级配置示例

dubbo-advanced.xml

xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo
       http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- 服务提供者配置 -->
    <dubbo:provider timeout="5000" retries="3" connections="100" loadbalance="random"/>

    <!-- 服务消费者配置 -->
    <dubbo:consumer timeout="5000" retries="3" check="false" loadbalance="roundrobin"/>

    <!-- 协议配置 -->
    <dubbo:protocol name="dubbo" port="20880" threads="200" accepts="500" payload="88388608"/>

    <!-- 监控配置 -->
    <dubbo:monitor protocol="registry"/>

    <!-- 元数据中心配置 -->
    <dubbo:metadata-report address="zookeeper://127.0.0.1:2181"/>
</beans>

Demo 示例

完整的 Provider 示例

src/main/java/com/example/provider/ProviderApplication.java

java
package com.example.provider;

import com.alibaba.dubbo.container.Main;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ProviderApplication {
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("dubbo-provider.xml");
        context.start();
        
        System.out.println("Dubbo 2.x Provider started successfully!");
        System.out.println("Press Ctrl+C to stop...");
        
        synchronized (ProviderApplication.class) {
            while (true) {
                try {
                    ProviderApplication.class.wait();
                } catch (InterruptedException e) {
                    System.out.println("Dubbo 2.x Provider stopped.");
                    break;
                }
            }
        }
    }
}

完整的 Consumer 示例

src/main/java/com/example/consumer/ConsumerApplication.java

java
package com.example.consumer;

import com.example.api.DemoService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ConsumerApplication {
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("dubbo-consumer.xml");
        context.start();
        
        DemoService demoService = (DemoService) context.getBean("demoService");
        
        // 测试调用
        String result = demoService.sayHello("Dubbo 2.x User");
        System.out.println("Response: " + result);
        
        int sum = demoService.calculate(100, 200);
        System.out.println("Calculation result: " + sum);
        
        System.out.println("Dubbo 2.x Consumer test completed!");
    }
}

使用 Spring Boot 的示例

pom.xml

xml
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>2.7.0</version>
    </dependency>
    
    <dependency>
        <groupId>com.alibaba.boot</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.8</version>
    </dependency>
</dependencies>

application.properties

properties
# Dubbo 配置
dubbo.application.name=dubbo-springboot-provider
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880

Spring Boot Provider

java
package com.example.springboot.provider;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableDubbo
public class DubboProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(DubboProviderApplication.class, args);
        System.out.println("Dubbo 2.x Spring Boot Provider started!");
    }
}

常见问题和解决方案

1. 连接超时问题

properties
# 增加连接超时时间
dubbo.protocol.connect.timeout=10000
dubbo.consumer.timeout=10000

2. 注册中心连接问题

确保 Zookeeper 或其他注册中心服务正常运行:

bash
# 检查 Zookeeper 状态
echo stat | nc localhost 2181

3. 端口冲突问题

properties
# 修改默认端口
dubbo.protocol.port=20881

4. 序列化问题

xml
<!-- 指定序列化方式 -->
<dubbo:protocol name="dubbo" serialization="hessian2"/>

性能优化

连接池配置

properties
# 连接池配置
dubbo.protocol.connections=100
dubbo.consumer.connections=20

线程池配置

xml
<!-- 线程池配置 -->
<dubbo:protocol name="dubbo" threads="200" threadpool="fixed" queues="1000"/>

序列化优化

properties
# 使用高效的序列化方式
dubbo.protocol.serialization=kryo

Docker 部署示例

Dockerfile

dockerfile
FROM openjdk:8-jre-slim

LABEL maintainer="Your Name <your.email@example.com>"

WORKDIR /app

COPY target/*.jar app.jar

EXPOSE 20880

ENTRYPOINT ["java", "-jar", "/app/app.jar"]

Docker Compose 配置

yaml
version: '3.8'
services:
  zookeeper:
    image: zookeeper:3.7
    ports:
      - "2181:2181"
    environment:
      ZOO_MY_ID: 1
      ZOO_SERVERS: server.1=zookeeper:2888:3888;2181

  dubbo-provider:
    build: .
    ports:
      - "20880:20880"
    environment:
      - DUBBO_REGISTRY_ADDRESS=zookeeper://zookeeper:2181
    depends_on:
      - zookeeper
    networks:
      - dubbo-net

  dubbo-monitor:
    image: apache/dubbo-admin
    ports:
      - "8080:8080"
    environment:
      - admin.registry.address=zookeeper://zookeeper:2181
      - admin.config-center=zookeeper://zookeeper:2181
      - admin.metadata-report.address=zookeeper://zookeeper:2181
    depends_on:
      - zookeeper
    networks:
      - dubbo-net

networks:
  dubbo-net:
    driver: bridge

Kubernetes 部署示例

Deployment 配置

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dubbo-provider
  labels:
    app: dubbo-provider
spec:
  replicas: 3
  selector:
    matchLabels:
      app: dubbo-provider
  template:
    metadata:
      labels:
        app: dubbo-provider
    spec:
      containers:
      - name: dubbo
        image: dubbo-provider:latest
        ports:
        - containerPort: 20880
        env:
        - name: DUBBO_REGISTRY_ADDRESS
          value: "zookeeper://zookeeper-service:2181"
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "500m"
        livenessProbe:
          exec:
            command:
            - sh
            - -c
            - "netstat -tulpn | grep :20880"
          initialDelaySeconds: 60
          periodSeconds: 30
        readinessProbe:
          exec:
            command:
            - sh
            - -c
            - "netstat -tulpn | grep :20880"
          initialDelaySeconds: 30
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: dubbo-provider-service
spec:
  selector:
    app: dubbo-provider
  ports:
    - protocol: TCP
      port: 20880
      targetPort: 20880
  type: ClusterIP

监控和管理

使用 Dubbo Admin

Dubbo Admin 是一个用于管理和监控 Dubbo 服务的管理界面:

yaml
# docker-compose.yml
version: '3'
services:
  dubbo-admin:
    image: apache/dubbo-admin
    ports:
      - "8080:8080"
    environment:
      admin.registry.address: zookeeper://zookeeper:2181
      admin.config-center: zookeeper://zookeeper:2181
      admin.metadata-report.address: zookeeper://zookeeper:2181

总结

Apache Dubbo 2.x 是一个功能强大且成熟的 RPC 框架,提供了完整的分布式服务治理解决方案。它的高性能、高可用性和丰富的功能使其成为构建大规模分布式系统的理想选择。通过服务注册与发现、负载均衡、集群容错等机制,Dubbo 2.x 帮助开发者轻松构建可靠的微服务架构。