🎬 开场:RPC框架的前世今生

🚀 gRPC vs Dubbo:RPC框架的巅峰对决!

副标题:Google的黑科技 vs 阿里的国产之光,到底选谁?🤔


2008年,阿里巴巴内部孵化了Dubbo,为解决分布式服务调用问题而生。

2015年,Google开源了gRPC,带来了全新的RPC理念。

2019年,Apache Dubbo发布3.0,全面拥抱云原生。

今天 ,我们就来一场史诗级的对决:gRPC vs Dubbo

scss 复制代码
           ⚔️ 
    gRPC       Dubbo
   (Google)   (Alibaba)
     
   国际范儿   本土化
   年轻力壮   成熟稳重
   极简主义   功能丰富

📚 基础知识:什么是RPC?

RPC的本质

RPC (Remote Procedure Call) = 远程过程调用

就像打电话 ☎️:

复制代码
你:喂,帮我查一下订单123的信息
对方:好的,订单123是...(查询)
对方:查到了,金额是100元
你:好的,谢谢!

本地调用 vs 远程调用

java 复制代码
// 本地调用:直接方法调用
Order order = orderService.getOrder(123L);

// 远程调用:看起来一样,实际走了网络
Order order = orderServiceRpc.getOrder(123L);
//                          ↑
//              底层通过网络调用远程服务

RPC的核心要素

markdown 复制代码
        客户端                          服务端
           ↓                              ↓
    ┌──────────┐                    ┌──────────┐
    │  Stub   │ ←────────────────→ │ Skeleton │
    └────┬─────┘                    └─────┬────┘
         │                                │
    ┌────▼─────┐                    ┌─────▼────┐
    │ 序列化   │                    │ 反序列化 │
    └────┬─────┘                    └─────┬────┘
         │                                │
    ┌────▼──────────────────────────────▼────┐
    │            网络传输 (TCP/HTTP)          │
    └─────────────────────────────────────────┘

🏗️ gRPC:Google的技术结晶

核心特性

1️⃣ 基于HTTP/2

HTTP/1.1的问题

css 复制代码
请求1 → [等待] → 响应1
请求2 → [等待] → 响应2
请求3 → [等待] → 响应3

串行处理,效率低下!

HTTP/2的优势

css 复制代码
请求1 ─┐
请求2 ─┼→ [并行处理] ┌─→ 响应1
请求3 ─┘              ├─→ 响应2
                      └─→ 响应3

多路复用,一条连接搞定所有请求!

关键特性

  • ✅ 多路复用(Multiplexing)
  • ✅ 头部压缩(Header Compression)
  • ✅ 服务端推送(Server Push)
  • ✅ 二进制分帧(Binary Framing)
2️⃣ Protobuf序列化

对比其他序列化方式

java 复制代码
// JSON (可读,但体积大)
{
  "id": 123,
  "name": "iPhone 15",
  "price": 5999.00
}
// 大小:约 60 bytes

// Protobuf (二进制,体积小)
[0x08, 0x7B, 0x12, 0x09, ...]
// 大小:约 20 bytes (缩小66%!)

定义Protobuf

protobuf 复制代码
syntax = "proto3";

message Product {
  int64 id = 1;
  string name = 2;
  double price = 3;
}

service ProductService {
  rpc GetProduct(ProductRequest) returns (ProductResponse);
}

生成的代码

bash 复制代码
protoc --java_out=. product.proto

生成的Java类自动包含:

  • 序列化/反序列化方法
  • Builder模式
  • 不可变对象
  • 完整的类型检查
3️⃣ 四种通信模式
java 复制代码
public class ProductService extends ProductServiceGrpc.ProductServiceImplBase {
    
    /**
     * 1. 简单RPC(Unary RPC)
     * 一问一答
     */
    @Override
    public void getProduct(ProductRequest request,
                          StreamObserver<ProductResponse> responseObserver) {
        Product product = findProduct(request.getId());
        ProductResponse response = ProductResponse.newBuilder()
            .setProduct(product)
            .build();
        
        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
    
    /**
     * 2. 服务端流式RPC(Server Streaming RPC)
     * 一问多答
     */
    @Override
    public void listProducts(ListRequest request,
                            StreamObserver<Product> responseObserver) {
        List<Product> products = findAllProducts();
        
        for (Product product : products) {
            responseObserver.onNext(product);  // 多次返回
        }
        
        responseObserver.onCompleted();
    }
    
    /**
     * 3. 客户端流式RPC(Client Streaming RPC)
     * 多问一答
     */
    @Override
    public StreamObserver<OrderItem> createOrder(
            StreamObserver<OrderResponse> responseObserver) {
        
        return new StreamObserver<OrderItem>() {
            private List<OrderItem> items = new ArrayList<>();
            
            @Override
            public void onNext(OrderItem item) {
                items.add(item);  // 接收多个
            }
            
            @Override
            public void onCompleted() {
                Order order = saveOrder(items);
                OrderResponse response = OrderResponse.newBuilder()
                    .setOrderId(order.getId())
                    .build();
                
                responseObserver.onNext(response);
                responseObserver.onCompleted();
            }
            
            @Override
            public void onError(Throwable t) {
                log.error("创建订单失败", t);
            }
        };
    }
    
    /**
     * 4. 双向流式RPC(Bidirectional Streaming RPC)
     * 多问多答
     */
    @Override
    public StreamObserver<ChatMessage> chat(
            StreamObserver<ChatMessage> responseObserver) {
        
        return new StreamObserver<ChatMessage>() {
            @Override
            public void onNext(ChatMessage message) {
                // 收到消息立即响应
                ChatMessage response = processMessage(message);
                responseObserver.onNext(response);
            }
            
            @Override
            public void onCompleted() {
                responseObserver.onCompleted();
            }
            
            @Override
            public void onError(Throwable t) {
                log.error("聊天异常", t);
            }
        };
    }
}

应用场景

模式 场景 例子
Unary 普通API调用 查询订单详情
Server Streaming 大数据量返回 日志流、消息推送
Client Streaming 大文件上传 分片上传视频
Bidirectional 实时通信 聊天、游戏
4️⃣ 完整示例

1. 定义服务(product.proto)

protobuf 复制代码
syntax = "proto3";

option java_package = "com.example.grpc";
option java_outer_classname = "ProductProto";

message ProductRequest {
  int64 id = 1;
}

message ProductResponse {
  int64 id = 1;
  string name = 2;
  double price = 3;
  string description = 4;
}

service ProductService {
  rpc GetProduct(ProductRequest) returns (ProductResponse);
  rpc ListProducts(Empty) returns (stream ProductResponse);
}

message Empty {}

2. 服务端实现

java 复制代码
@GrpcService
public class ProductServiceImpl extends ProductServiceGrpc.ProductServiceImplBase {
    
    @Autowired
    private ProductRepository productRepository;
    
    @Override
    public void getProduct(ProductRequest request,
                          StreamObserver<ProductResponse> responseObserver) {
        Product product = productRepository.findById(request.getId())
            .orElseThrow(() -> new RuntimeException("Product not found"));
        
        ProductResponse response = ProductResponse.newBuilder()
            .setId(product.getId())
            .setName(product.getName())
            .setPrice(product.getPrice())
            .setDescription(product.getDescription())
            .build();
        
        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
}

3. 客户端调用

java 复制代码
@Service
public class ProductClient {
    
    private final ProductServiceGrpc.ProductServiceBlockingStub blockingStub;
    
    public ProductClient(ManagedChannel channel) {
        this.blockingStub = ProductServiceGrpc.newBlockingStub(channel);
    }
    
    public ProductResponse getProduct(Long productId) {
        ProductRequest request = ProductRequest.newBuilder()
            .setId(productId)
            .build();
        
        try {
            return blockingStub.getProduct(request);
        } catch (StatusRuntimeException e) {
            log.error("RPC调用失败: {}", e.getStatus());
            throw e;
        }
    }
}

gRPC的优缺点

优点 ✅
  1. 性能极高:Protobuf + HTTP/2
  2. 跨语言:支持10+种语言
  3. 流式支持:天然支持4种流式模式
  4. 生态完善:Google背书
缺点 ❌
  1. 学习曲线陡:需要学Protobuf
  2. 调试困难:二进制协议不可读
  3. 浏览器支持差:需要grpc-web
  4. 国内生态弱:中文资料少

🐘 Dubbo:阿里的开源力作

核心特性

1️⃣ 多协议支持
java 复制代码
// Dubbo支持多种协议
@Service(protocol = "dubbo")       // Dubbo协议(默认)
public class ProductServiceImpl implements ProductService {}

@Service(protocol = "rest")        // REST协议
public class UserServiceImpl implements UserService {}

@Service(protocol = "grpc")        // gRPC协议(Dubbo 3.0+)
public class OrderServiceImpl implements OrderService {}

Dubbo协议特点

  • 基于TCP长连接
  • 单一长连接NIO异步通信
  • Hessian2序列化(默认)
  • 适合小数据量大并发
2️⃣ 丰富的负载均衡策略
java 复制代码
@Service(
    loadbalance = "random",        // 随机
    // loadbalance = "roundrobin",   // 轮询
    // loadbalance = "leastactive",  // 最少活跃调用
    // loadbalance = "consistenthash" // 一致性Hash
)
public class OrderServiceImpl implements OrderService {
    // ...
}

生活比喻 🏪:

随机(Random)

复制代码
超市有3个收银台
你闭着眼睛随便选一个

轮询(RoundRobin)

erlang 复制代码
客人按顺序排队
1号台 → 2号台 → 3号台 → 1号台...

最少活跃(LeastActive)

arduino 复制代码
哪个收银台人少就去哪个
类似"智能排队系统"

一致性Hash(ConsistentHash)

复制代码
根据你的会员卡号分配固定的收银台
保证同一个人总是去同一个台
3️⃣ 服务治理功能
java 复制代码
@Configuration
public class DubboConfig {
    
    /**
     * 1. 服务降级
     */
    @Bean
    public ProviderConfig providerConfig() {
        ProviderConfig config = new ProviderConfig();
        config.setMock("fail:return null");  // 失败返回null
        return config;
    }
    
    /**
     * 2. 服务限流
     */
    @Service(
        executes = 10,         // 服务端最大并发执行数
        actives = 5            // 客户端最大并发调用数
    )
    public class OrderService {}
    
    /**
     * 3. 重试机制
     */
    @Reference(
        retries = 2,           // 失败重试2次(总共3次)
        timeout = 3000         // 超时时间3秒
    )
    private UserService userService;
    
    /**
     * 4. 异步调用
     */
    @Reference(async = true)
    private ProductService productService;
    
    public void asyncCall() {
        productService.getProduct(123L);  // 异步调用
        
        // 获取Future
        Future<Product> future = RpcContext.getContext().getFuture();
        Product product = future.get();   // 阻塞等待结果
    }
}
4️⃣ 注册中心支持
scss 复制代码
Dubbo支持的注册中心:
├── Zookeeper    ⭐⭐⭐ (最常用)
├── Nacos        ⭐⭐⭐ (阿里推荐)
├── Consul
├── Etcd
├── Eureka
└── Redis

服务注册流程

markdown 复制代码
┌─────────┐              ┌──────────┐
│ Provider│──① 注册服务──→│Zookeeper │
└─────────┘              └────┬─────┘
                              │
                          ② 订阅服务
                              │
┌─────────┐              ┌────▼─────┐
│Consumer │←──③ 推送变更──│Zookeeper │
└────┬────┘              └──────────┘
     │
  ④ 直接调用
     │
     ▼
┌─────────┐
│Provider │
└─────────┘
5️⃣ 完整示例

1. 定义接口

java 复制代码
public interface OrderService {
    /**
     * 创建订单
     */
    Order createOrder(OrderRequest request);
    
    /**
     * 查询订单
     */
    Order getOrder(Long orderId);
}

2. 服务提供者

java 复制代码
@DubboService(
    version = "1.0.0",
    timeout = 3000,
    retries = 2,
    loadbalance = "random"
)
public class OrderServiceImpl implements OrderService {
    
    @Autowired
    private OrderRepository orderRepository;
    
    @Override
    public Order createOrder(OrderRequest request) {
        Order order = new Order();
        order.setUserId(request.getUserId());
        order.setProductId(request.getProductId());
        order.setAmount(request.getAmount());
        
        return orderRepository.save(order);
    }
    
    @Override
    public Order getOrder(Long orderId) {
        return orderRepository.findById(orderId)
            .orElseThrow(() -> new RuntimeException("Order not found"));
    }
}

3. 服务消费者

java 复制代码
@Service
public class OrderClient {
    
    @DubboReference(
        version = "1.0.0",
        timeout = 3000,
        check = false  // 启动时不检查服务是否可用
    )
    private OrderService orderService;
    
    public Order createOrder(Long userId, Long productId, BigDecimal amount) {
        OrderRequest request = new OrderRequest();
        request.setUserId(userId);
        request.setProductId(productId);
        request.setAmount(amount);
        
        return orderService.createOrder(request);
    }
}

4. 配置文件(application.yml)

yaml 复制代码
dubbo:
  application:
    name: order-service
  registry:
    address: zookeeper://127.0.0.1:2181
  protocol:
    name: dubbo
    port: 20880
  provider:
    timeout: 3000
    retries: 2
  consumer:
    check: false
    timeout: 3000

Dubbo的优缺点

优点 ✅
  1. 功能丰富:负载均衡、服务治理、监控
  2. 国内生态好:中文文档完善,社区活跃
  3. Spring集成好:无缝集成Spring Boot
  4. 成熟稳定:经过阿里多年考验
缺点 ❌
  1. 协议老旧:Dubbo协议基于TCP
  2. 跨语言弱:主要支持Java
  3. HTTP支持差:REST协议性能一般
  4. 学习成本高:配置项多,概念复杂

⚔️ 巅峰对决:gRPC vs Dubbo

1️⃣ 性能对比

scss 复制代码
             gRPC              Dubbo
序列化     Protobuf          Hessian2
协议       HTTP/2            Dubbo(TCP)
编码       二进制            二进制
压缩       gzip              Snappy

性能测试结果(QPS):
┌────────────┬─────────┬─────────┐
│  场景      │  gRPC   │  Dubbo  │
├────────────┼─────────┼─────────┤
│ 小对象传输 │  30000  │  28000  │
│ 大对象传输 │  25000  │  22000  │
│ 流式传输   │  35000  │  N/A    │
└────────────┴─────────┴─────────┘

结论:gRPC略胜一筹!

实际测试代码

java 复制代码
@SpringBootTest
public class PerformanceTest {
    
    @Test
    public void testGrpcPerformance() {
        int count = 10000;
        long start = System.currentTimeMillis();
        
        for (int i = 0; i < count; i++) {
            grpcClient.getProduct(123L);
        }
        
        long end = System.currentTimeMillis();
        System.out.println("gRPC: " + count + " requests in " + (end - start) + "ms");
        System.out.println("QPS: " + (count * 1000 / (end - start)));
    }
    
    @Test
    public void testDubboPerformance() {
        int count = 10000;
        long start = System.currentTimeMillis();
        
        for (int i = 0; i < count; i++) {
            dubboService.getProduct(123L);
        }
        
        long end = System.currentTimeMillis();
        System.out.println("Dubbo: " + count + " requests in " + (end - start) + "ms");
        System.out.println("QPS: " + (count * 1000 / (end - start)));
    }
}

2️⃣ 功能对比

功能 gRPC Dubbo 说明
协议 HTTP/2 Dubbo/REST/gRPC Dubbo更灵活
序列化 Protobuf Hessian2/JSON/Protobuf 都支持多种
负载均衡 需要自己实现 ⭐⭐⭐ 内置多种策略 Dubbo完胜
服务发现 需要第三方 ⭐⭐⭐ 多种注册中心 Dubbo完胜
服务治理 基础 ⭐⭐⭐ 丰富完善 Dubbo完胜
流式通信 ⭐⭐⭐ 原生支持 不支持 gRPC完胜
跨语言 ⭐⭐⭐ 10+语言 Java为主 gRPC完胜
监控 需要集成 ⭐⭐⭐ Admin控制台 Dubbo完胜

3️⃣ 生态对比

gRPC生态
scss 复制代码
gRPC核心生态:
├── grpc-java           (Java实现)
├── grpc-go             (Go实现)
├── grpc-web            (浏览器支持)
├── grpc-gateway        (HTTP转gRPC)
├── grpc-health-probe   (健康检查)
└── grpc-ecosystem      (生态工具集)

云原生支持:
├── Kubernetes
├── Istio (Service Mesh)
├── Envoy (代理)
└── CNCF项目
Dubbo生态
scss 复制代码
Dubbo核心生态:
├── dubbo-spring-boot   (Spring Boot集成)
├── dubbo-admin         (管理控制台)
├── dubbo-monitor       (监控)
├── dubbo-samples       (示例代码)
└── dubbo-go            (Go实现)

阿里生态:
├── Nacos (注册/配置中心)
├── Sentinel (流量控制)
├── Seata (分布式事务)
└── Spring Cloud Alibaba

4️⃣ 使用场景对比

gRPC适合

  • ✅ 微服务间通信(云原生)
  • ✅ 跨语言场景(Java/Go/Python混合)
  • ✅ 实时流式通信(直播、游戏)
  • ✅ 移动端通信(App后端)
  • ✅ 高性能要求(金融、广告)

Dubbo适合

  • ✅ Java技术栈(Spring Cloud Alibaba)
  • ✅ 国内项目(中文文档完善)
  • ✅ 需要丰富的服务治理功能
  • ✅ 内部系统(不需要跨语言)
  • ✅ 快速上手(Spring集成简单)

🤔 如何选择?

决策树 🌲

markdown 复制代码
开始选择RPC框架
 │
 ├─ 需要跨语言吗?
 │   ├─ 是 → gRPC ⭐⭐⭐
 │   └─ 否 ↓
 │
 ├─ 团队主要技术栈是什么?
 │   ├─ Java + Spring → Dubbo ⭐⭐⭐
 │   ├─ Go/Python/Node → gRPC ⭐⭐⭐
 │   └─ 混合 ↓
 │
 ├─ 需要流式通信吗?
 │   ├─ 是 → gRPC ⭐⭐⭐
 │   └─ 否 ↓
 │
 ├─ 需要丰富的服务治理功能吗?
 │   ├─ 是 → Dubbo ⭐⭐⭐
 │   └─ 否 ↓
 │
 ├─ 部署在云原生环境(K8s)?
 │   ├─ 是 → gRPC ⭐⭐⭐
 │   └─ 否 → Dubbo ⭐⭐
 │
 └─ 团队对新技术的接受程度?
     ├─ 高 → gRPC
     └─ 低 → Dubbo

典型场景推荐

场景1:电商平台
markdown 复制代码
技术栈:Java + Spring Cloud Alibaba
服务数:100+
团队:50+人
需求:服务治理、监控、降级

推荐:Dubbo ⭐⭐⭐⭐⭐

理由:
1. Spring集成简单
2. 服务治理功能完善
3. Nacos、Sentinel生态协同
4. 中文文档完善,团队上手快
场景2:云原生SaaS平台
markdown 复制代码
技术栈:Java + Go + Python混合
服务数:50+
团队:30+人
需求:跨语言、高性能、K8s部署

推荐:gRPC ⭐⭐⭐⭐⭐

理由:
1. 跨语言支持好
2. K8s原生支持
3. 性能优异
4. 流式通信能力强
场景3:直播平台
markdown 复制代码
技术栈:Java + Go
服务数:30+
团队:20+人
需求:实时流式通信、低延迟

推荐:gRPC ⭐⭐⭐⭐⭐

理由:
1. 流式通信天然支持
2. 性能优异
3. 跨语言(Java服务端 + Go推流)
4. HTTP/2优势明显
场景4:传统企业内部系统
markdown 复制代码
技术栈:Java + Spring Boot
服务数:20+
团队:10+人
需求:稳定、易维护

推荐:Dubbo ⭐⭐⭐⭐

理由:
1. 技术成熟稳定
2. 学习资料丰富
3. 社区活跃
4. 问题容易解决

💡 最佳实践

gRPC最佳实践

java 复制代码
/**
 * 1. 连接池管理
 */
@Configuration
public class GrpcConfig {
    
    @Bean
    public ManagedChannel grpcChannel() {
        return ManagedChannelBuilder
            .forAddress("localhost", 9090)
            .usePlaintext()
            // 连接池配置
            .maxInboundMessageSize(10 * 1024 * 1024)  // 10MB
            .keepAliveTime(30, TimeUnit.SECONDS)       // 保持连接
            .keepAliveTimeout(10, TimeUnit.SECONDS)
            .build();
    }
}

/**
 * 2. 优雅关闭
 */
@PreDestroy
public void shutdown() throws InterruptedException {
    channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}

/**
 * 3. 拦截器(类似AOP)
 */
public class LoggingInterceptor implements ClientInterceptor {
    
    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
            MethodDescriptor<ReqT, RespT> method,
            CallOptions callOptions,
            Channel next) {
        
        log.info("gRPC调用: {}", method.getFullMethodName());
        long start = System.currentTimeMillis();
        
        ClientCall<ReqT, RespT> call = next.newCall(method, callOptions);
        
        return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(call) {
            @Override
            public void start(Listener<RespT> responseListener, Metadata headers) {
                super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(responseListener) {
                    @Override
                    public void onClose(Status status, Metadata trailers) {
                        long end = System.currentTimeMillis();
                        log.info("gRPC调用完成,耗时: {}ms", end - start);
                        super.onClose(status, trailers);
                    }
                }, headers);
            }
        };
    }
}

/**
 * 4. 错误处理
 */
public Product getProduct(Long productId) {
    try {
        return blockingStub.getProduct(request);
    } catch (StatusRuntimeException e) {
        switch (e.getStatus().getCode()) {
            case NOT_FOUND:
                throw new ProductNotFoundException(productId);
            case DEADLINE_EXCEEDED:
                throw new TimeoutException("调用超时");
            case UNAVAILABLE:
                throw new ServiceUnavailableException("服务不可用");
            default:
                throw new RuntimeException("RPC调用失败", e);
        }
    }
}

Dubbo最佳实践

java 复制代码
/**
 * 1. 合理设置超时时间
 */
@DubboService(
    timeout = 1000,      // 默认1秒
    methods = {
        @Method(name = "createOrder", timeout = 5000),  // 特定方法5秒
        @Method(name = "queryOrder", timeout = 500)     // 查询方法500ms
    }
)
public class OrderServiceImpl implements OrderService {}

/**
 * 2. 服务分组
 */
@DubboService(group = "production", version = "1.0.0")
public class OrderServiceV1 implements OrderService {}

@DubboService(group = "beta", version = "2.0.0")
public class OrderServiceV2 implements OrderService {}

// 消费者选择版本
@DubboReference(group = "production", version = "1.0.0")
private OrderService orderService;

/**
 * 3. 异步调用
 */
@DubboReference(async = true)
private ProductService productService;

@DubboReference(async = true)
private UserService userService;

public void asyncExample() {
    // 并行调用
    productService.getProduct(123L);
    userService.getUser(456L);
    
    // 获取结果
    Future<Product> productFuture = RpcContext.getContext().getFuture();
    Future<User> userFuture = RpcContext.getContext().getFuture();
    
    Product product = productFuture.get();
    User user = userFuture.get();
}

/**
 * 4. 泛化调用(动态调用)
 */
public Object genericInvoke(String interfaceName, String method, Object[] args) {
    GenericService genericService = new GenericServiceFactory()
        .getGenericService(interfaceName);
    
    return genericService.$invoke(method, new String[]{"java.lang.Long"}, args);
}

🎓 面试高频问题

Q1:gRPC为什么性能高?

A

  1. HTTP/2协议

    • 多路复用,减少连接建立
    • 头部压缩,减少数据传输
    • 二进制分帧,解析更快
  2. Protobuf序列化

    • 体积小(比JSON小3-10倍)
    • 序列化快(比JSON快20-100倍)
    • 强类型,避免运行时错误
  3. 长连接复用

    • 避免频繁建立连接
    • 减少握手开销

Q2:Dubbo如何实现负载均衡?

A

Dubbo在客户端实现负载均衡:

java 复制代码
public interface LoadBalance {
    /**
     * 从多个Provider中选择一个
     */
    <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation);
}

// 随机负载均衡
public class RandomLoadBalance extends AbstractLoadBalance {
    protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
        int length = invokers.size();
        int totalWeight = 0;
        
        // 计算总权重
        for (Invoker<T> invoker : invokers) {
            totalWeight += getWeight(invoker, invocation);
        }
        
        // 随机选择
        int offset = random.nextInt(totalWeight);
        for (Invoker<T> invoker : invokers) {
            offset -= getWeight(invoker, invocation);
            if (offset < 0) {
                return invoker;
            }
        }
        
        return invokers.get(0);
    }
}

Q3:什么时候选择gRPC,什么时候选择Dubbo?

A

选择gRPC的场景

  • ✅ 跨语言微服务
  • ✅ 云原生/K8s环境
  • ✅ 需要流式通信
  • ✅ 追求极致性能
  • ✅ 移动端通信

选择Dubbo的场景

  • ✅ Java单一技术栈
  • ✅ Spring Cloud Alibaba生态
  • ✅ 需要丰富的服务治理
  • ✅ 团队已熟悉Dubbo
  • ✅ 国内项目(文档/社区)

🎉 总结

核心要点 ✨

  1. gRPC

    • Google出品,国际化
    • HTTP/2 + Protobuf
    • 跨语言、高性能
    • 云原生首选
  2. Dubbo

    • 阿里出品,本土化
    • 多协议、多注册中心
    • 服务治理丰富
    • Java生态最佳
  3. 选择建议

    • 跨语言 → gRPC
    • Java系 → Dubbo
    • 云原生 → gRPC
    • 服务治理 → Dubbo

记忆口诀 📝

复制代码
gRPC性能真的高,
HTTP/2加Protobuf。
跨语言支持很强大,
云原生环境最合适。

Dubbo功能很丰富,
服务治理样样全。
Spring集成很简单,
Java项目首选它。

选择框架看场景,
跨语言就选gRPC。
Java栈用Dubbo好,
各有千秋都很棒!

📚 参考资料

  1. gRPC官方文档
  2. Dubbo官方文档
  3. Protocol Buffers
  4. HTTP/2简介

最后送你一句话

"没有最好的框架,只有最适合的框架。"

愿你选对框架,项目顺利! 🚀✨


表情包时间 🎭

erlang 复制代码
选框架时:
🤔 到底选哪个呢...

用gRPC:
😎 性能杠杠的!
😅 Protobuf有点难...

用Dubbo:
😊 上手真简单!
🤩 功能好丰富!

最终:
🎉 适合自己的就是最好的!
相关推荐
用户68545375977695 小时前
🔥 服务熔断降级:微服务的"保险丝"大作战!
后端
Tech有道5 小时前
拼多多「面试官问我:LRU 和 LFU 你选谁?」我:看场景啊哥!😂
后端
王中阳Go背后的男人6 小时前
Docker磁盘满了?这样清理高效又安全
后端·docker
用户68545375977696 小时前
🎛️ 分布式配置中心:让配置管理不再是噩梦!
后端
CodeFans6 小时前
Spring 浅析
后端
李广坤6 小时前
Filter(过滤器)、Interceptor(拦截器) 和 AOP(面向切面编程)
后端
oak隔壁找我6 小时前
反向代理详解
后端·架构
YUELEI1186 小时前
Springboot WebSocket
spring boot·后端·websocket
小蒜学长6 小时前
springboot基于JAVA的二手书籍交易系统的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端