Dubbo vs gRPC vs Feign: Complete Multi-Dimension Comparison with Interview Q&A

This comprehensive guide compares Dubbo, gRPC, and Feign across eight critical dimensions including protocols, serialization, performance, cross-language support, service discovery, circuit breaking, streaming, and hybrid architecture coordination, with detailed interview questions and answers for each.

CodeSmart Hoops
CodeSmart Hoops
CodeSmart Hoops
Dubbo vs gRPC vs Feign: Complete Multi-Dimension Comparison with Interview Q&A

Interview Self-Test Questions

Q1 : Summarize Feign, Dubbo, gRPC positioning in one sentence each; state essential differences. Reference: Section 2: Positioning

Q2 : Default protocols and serialization for each; protocol-layer pros and cons. Reference: Section 4: Protocol & Serialization Comparison

Q3 : Why Dubbo dubbo protocol outperforms Feign in high-frequency internal Java calls? Analyze protocol and serialization layers. Reference: Section 5: Performance Comparison

Q4 : Why gRPC over Dubbo for cross-language? What improvements does Dubbo triple bring? Reference: Section 6: Cross-Language Capability

Q5 : How each implements service discovery? What components do they depend on? Reference: Section 8: Service Discovery Comparison

Q6 : Circuit breaking and fallback solutions for each? Why is gRPC fallback less elegant than Dubbo mock? Reference: Section 9: Circuit Breaking & Fallback Comparison

Q7 : gRPC's four streaming modes? Why Feign and classic Dubbo don't support streaming? Reference: Section 10: Streaming Capability

Q8 : Key coordination points when Feign, Dubbo, gRPC coexist in Spring Cloud Alibaba? Name at least 4. Reference: Section 15: Hybrid Architecture Practice

Reference Answers

Q1: Positioning & Essential Differences

Reference Section: [Section 2: Positioning]

Feign : Declarative HTTP REST client; wraps HTTP calls into method calls via interfaces + annotations; essentially HTTP REST; governance relies on Spring Cloud ecosystem.

Dubbo : High-performance RPC framework for Java; built-in service governance (registry, load balancing, fault tolerance, monitoring); defaults to custom binary dubbo protocol.

gRPC : Google's cross-language RPC framework; based on HTTP/2 + Protobuf; strong contract + code generation + native streaming.

Essential differences:

Positioning : Feign solves "how to call simply" (client wrapper), Dubbo solves "how to call fast and govern in Java" (full stack), gRPC solves "how to call reliably with strong contract across languages" (cross-language standard).

Protocol : Feign uses text HTTP/1.1; Dubbo uses custom TCP binary (or triple on HTTP/2); gRPC uses HTTP/2.

Serialization : Feign uses JSON; Dubbo uses Hessian2; gRPC uses Protobuf.

Governance : Feign depends on external components; Dubbo bundles full stack; gRPC is low-level, requires custom build or service mesh integration.

One-liner memory aid: Feign calls simply, Dubbo calls fast and governs, gRPC crosses languages with strong contract .

Q2: Default Protocols & Serialization; Protocol Pros/Cons

Reference Section: [Section 4: Protocol & Serialization Comparison]

Feign : Default protocol HTTP/1.1 (text); default serialization JSON (Jackson/Gson).

Dubbo : Default protocol dubbo protocol (custom TCP binary); new versions push triple (HTTP/2); default serialization Hessian2.

gRPC : Default protocol HTTP/2; default serialization Protobuf.

Protocol-layer pros/cons:

Feign + HTTP/1.1 :

Pros: Universal, readable, debuggable (curl/Postman direct), browser-friendly, aligns with REST semantics.

Cons: Text headers large, no multiplexing (HTTP/1.1 head-of-line blocking), high connection overhead, no streaming support.

Dubbo + dubbo protocol :

Pros: Single TCP long connection + NIO, compact binary, low latency, high throughput.

Cons: Custom protocol not directly consumable by browsers/standard gateways, packet capture unreadable, weak cross-language.

Triple protocol (HTTP/2-based) addresses "gateway traversal, cross-language, streaming" gaps and is gRPC-compatible.

gRPC + HTTP/2 :

Pros: Multiplexing (multiple requests per TCP), HPACK header compression, compact Protobuf, native streaming.

Cons: Packet capture unreadable (needs Protobuf decode), browser requires gRPC-Web, slightly higher initial connection cost.

Key distinction: dubbo protocol is "single TCP long connection + message serialization", not true multiplexing; triple and gRPC achieve true multiplexing via HTTP/2 streams .

Q3: Why Dubbo dubbo Protocol Outperforms Feign in High-Frequency Internal Java Calls

Reference Section: [Section 5: Performance Comparison]

Order-of-magnitude estimate (same datacenter, 1KB payload): Feign single-call latency 2–5ms, Dubbo 0.5–1.5ms; single-connection QPS Feign thousands, Dubbo tens of thousands.

Protocol Layer:

Connection Model : Feign defaults to HTTP/1.1, each request needs connection establishment or pool reuse; pool contention becomes bottleneck at high concurrency. Dubbo dubbo protocol uses single TCP long connection + NIO, eliminating handshake overhead, thorough connection reuse.

Protocol Header Overhead : HTTP/1.1 headers are text and repetitive (Host, Content-Type every request), no compression; dubbo protocol headers are fixed-length binary (fixed bytes), compact and efficient.

Head-of-Line Blocking : HTTP/1.1 processes one request per connection at a time (pool mitigates but doesn't eliminate); Dubbo single-connection NIO async can pipeline multiple requests (serialized by message boundary, still more efficient than HTTP short connections).

Serialization Layer:

Size : Same object, JSON ~1.7–2x Hessian2 size (Protobuf smaller than Hessian2). Larger size means more NIC interrupts, higher bandwidth, more frequent GC.

Parse Speed : JSON parsing needs state machine/reflection; Hessian2 binary reads directly by field number, faster parsing, lower CPU.

Object Complexity Amplification : Simple objects show small gap; complex nested large objects under high-frequency calls amplify serialization gap into significant CPU and latency differences.

Note : Gap only significant at high frequency (thousands to tens of thousands per second); low frequency (few per second) business won't perceive. Performance comparison "depends on scenario, not absolute".

Q4: Why gRPC for Cross-Language? Dubbo Triple Improvements

Reference Section: [Section 6: Cross-Language Capability]

Why gRPC is recommended:

First-party multi-language support : gRPC officially provides code generators for 10+ languages (Java, Go, Python, C++, Node, C#, Ruby, PHP, Kotlin, Swift, etc.), high maturity, comprehensive docs.

Strong contract : .proto defines once, each language generates its own; contract clear, version evolution controlled (field numbers + reserved rules).

Protocol standard : HTTP/2 + Protobuf is industry standard; cross-language teams need no custom adapters.

Mature ecosystem : Service mesh (Istio/Envoy), tracing (OpenTelemetry), gateways (gRPC-Web) all natively support.

Dubbo cross-language shortcomings:

Classic dubbo protocol primarily serves Java; cross-language relies on community SDKs (dubbo-go, dubbo-python) with varying maturity.

Default Hessian2 serialization weak cross-language support; Python side parsing Java object fields prone to compatibility issues.

Dubbo triple protocol improvements:

Based on HTTP/2, protocol layer compatible with gRPC.

With Protobuf serialization, triple services consumable by any gRPC client directly.

Provides Multi-Language SDKs (Go, Rust, Python, Node), progressively filling cross-language gaps.

Retains Dubbo built-in governance (registry, routing, fault tolerance) while gaining cross-language ability.

But in practice, triple cross-language is "good enough" yet cross-language teams often still choose gRPC directly — because triple's cross-language ecosystem is less complete than gRPC's first-class support. So "forcing Dubbo cross-language" is less hassle-free than just using gRPC.

Q5: Service Discovery Implementation & Dependencies

Reference Section: [Section 8: Service Discovery Comparison]

Feign:

Mechanism: Resolves instances via service name ( @FeignClient(name="user-service")), LoadBalancer picks instance.

Dependencies: Spring Cloud LoadBalancer (client-side LB) + Nacos/Eureka/Consul (service registry).

Instance list pushed by registry, cached client-side. Spring Cloud 2020+ removed Ribbon, defaults to LoadBalancer.

Note: Must explicitly include spring-cloud-starter-loadbalancer, else "no available instance" error.

Dubbo:

Mechanism: Built-in registry subscription; Provider registers, Consumer subscribes, instance changes pushed.

Dependencies: Registry (Nacos/Zookeeper/Redis/Eureka, SPI extensible).

Config: dubbo.registry.address=nacos://127.0.0.1:8848.

Features: Subscription granularity down to interface level; built-in empty-push protection and local cache (registry down, local cache still serves already-subscribed instances).

gRPC:

Mechanism: Custom NameResolver resolves service name to EquivalentAddressGroup list; LoadBalancer picks instance.

Dependencies: Custom NameResolver against Nacos/Consul/DNS, or Istio sidecar takeover (xDS mode, gRPC client dials xds:// authority).

Engineering wrapper: Commonly use grpc-spring-boot-starter (e.g., net.devh) wrapping Nacos NameResolver, transparent to business.

Built-in LB strategies: round_robin, pick_first; complex strategies need custom or service mesh.

Comparison: Feign assembles via Spring Cloud components; Dubbo works out-of-the-box; gRPC requires custom build or service mesh.

Q6: Circuit Breaking & Fallback Solutions; Why gRPC Fallback Less Elegant Than Dubbo Mock

Reference Section: [Section 9: Circuit Breaking & Fallback Comparison]

Feign:

Sentinel integration: feign.sentinel.enabled=true.

Resilience4j integration: spring.cloud.openfeign.circuitbreaker.enabled=true.

Fallback implementation: fallback / fallbackFactory attributes declare fallback class; auto-fallback when downstream unavailable.

Recommend FallbackFactory (can access triggering exception), see [SpringCloud OpenFeign Application & Full Analysis].

Dubbo:

Sentinel integration: Official dubbo-sentinel module, covers Provider/Consumer both ends, auto-instrumentation.

Fallback implementation: mock attribute — mock="return null" (return null), mock="throw" (throw exception), mock="com.xxx.UserServiceMock" (custom Mock class).

Granularity: Method-level, combinable with Sentinel for circuit breaking + fallback combo.

gRPC:

Integration: Via ClientInterceptor / ServerInterceptor.

Sentinel provides SentinelGrpcClientInterceptor; Resilience4j can wrap interceptors.

Fallback implementation: Must write fallback logic in interceptor's onClose / onCancel callbacks, or upper-layer business catches StatusRuntimeException and handles.

Why gRPC fallback less elegant than Dubbo mock:

Built-in vs hand-written : Dubbo mock is declarative attribute, one-line config; gRPC needs hand-written interceptor or business try-catch, lots of boilerplate.

Declaration location : Dubbo on @DubboReference annotation, one line; gRPC interceptor separated from business call, fallback logic scattered.

Granularity control : Dubbo mock per-method, per-return-value; gRPC interceptor is generic, per-method distinction requires manual MethodDescriptor checks.

Exception info : Dubbo Fallback can access invocation context via mock class; gRPC interceptor gets Status, must manually parse trailer.

Thus governance experience: Dubbo declarative mock > Feign FallbackFactory > gRPC hand-written interceptor fallback .

Q7: gRPC Four Streaming Modes; Why Feign & Classic Dubbo Don't Support Streaming

Reference Section: [Section 10: Streaming Capability]

gRPC four streaming modes (declared in .proto with stream keyword):

Unary : rpc Unary (Req) returns (Resp); — request-response, most common.

Server Streaming : rpc ServerStream (Req) returns (stream Resp); — client sends once, server responds multiple times. Suits large query batch returns, real-time push.

Client Streaming : rpc ClientStream (stream Req) returns (Resp); — client sends multiple, server responds once. Suits chunked upload, batch write aggregation.

Bidirectional Streaming : rpc BiStream (stream Req) returns (stream Resp); — both sides send/receive multiple. Suits real-time chat, collaborative editing, IoT bidirectional control.

Why Feign doesn't support streaming:

Feign runs HTTP/1.1 + request-response model, one question one answer; protocol layer is Unary semantics.

HTTP/1.1 maps one request to one response; cannot receive multiple responses within a single request.

Streaming needs HTTP/2 stream concept or multiplexing; Feign not based on HTTP/2 by default.

Large file/real-time push scenarios Feign can only combine with SSE/WebSocket extra mechanisms; no native support.

Why classic Dubbo dubbo protocol doesn't support streaming:

Dubbo protocol is "request-response" message model; one call maps to one return; protocol frame structure doesn't support continuous push.

Dubbo protocol design goal is "efficient homogeneous internal call"; never abstracted stream concept.

Dubbo triple protocol (HTTP/2-based) supports streaming, API similar to gRPC ( StreamObserver style), and interoperates with gRPC.

Therefore streaming scenarios prefer gRPC , second Dubbo triple ; Feign and classic dubbo protocol both lack streaming support.

Q8: Key Coordination Points for Feign/Dubbo/gRPC Coexistence in Spring Cloud Alibaba

Reference Section: [Section 15: Hybrid Architecture Practice]

Key coordination points:

Port isolation : HTTP/REST (e.g., 8080), Dubbo (e.g., 20880), gRPC (e.g., 9090) each use separate ports, no interference. One app can expose all three ports simultaneously.

Unified but isolated service discovery : All three register to Nacos, but use different namespaces or groups to distinguish, preventing Feign from mistakenly calling Dubbo instances (Feign uses HTTP port, Dubbo uses 20880, instance addresses not interchangeable).

Timeout & retry to avoid cascade amplification : Each sets own timeouts; avoid retry stacking . Principle: only outermost layer (gateway) or innermost (before DB) set retries; middle layers disable retries. Dubbo Consumer retries defaults to 2, use cautiously; Feign defaults no retry; gRPC defaults no retry.

Unified circuit breaking via Sentinel : All three integrate Sentinel, configure rules centrally in Sentinel console, avoiding fragmented governance from separate circuit breakers. Dubbo uses dubbo-sentinel, Feign uses feign-sentinel, gRPC uses SentinelGrpcClientInterceptor.

Unified distributed tracing : Use OpenTelemetry/SkyWalking auto-instrumentation for all three protocols, ensuring cross-protocol trace continuity, avoiding broken traces.

Contract & serialization coordination : Triple protocol cross-language requires Protobuf serialization (not default Hessian2), otherwise Python/Go cannot consume. gRPC uses Protobuf naturally; Dubbo triple cross-language also needs Protobuf switch.

Unified config center : All three configs centralized in Nacos Config, avoiding scattered local configs.

Unified metrics : Call metrics from all three protocols reported to Prometheus+Grafana, tagged by protocol dimension for horizontal performance comparison.

Typical configuration approach: Feign calls external HTTP gateway services; Dubbo calls homogeneous Java high-frequency internal services; gRPC calls cross-language algorithm services; all three register to same Nacos, governance unified via Sentinel, tracing unified via SkyWalking, ports 8080/20880/9090 isolated.

References

Apache Dubbo Official Docs: https://cn.dubbo.apache.org/zh-cn/

gRPC Official Docs: https://grpc.io/

Protocol Buffers Language Guide: https://protobuf.dev/programming-guides/proto3/

Dubbo Triple Protocol Design: https://cn.dubbo.apache.org/zh-cn/overview/reference/protocols/triple/

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

microservicesRPCservice discoverystreamingDubboserializationgRPCFeignSpring Cloud Alibabaservice governancecircuit breakerperformance comparisoncross-languageprotocol comparison
CodeSmart Hoops
Written by

CodeSmart Hoops

A working programmer who loves coding and basketball. By day I debug code; by night I dissect tactics. I write articles to document my journey, focusing on Java, AI, Python and other programming topics, with occasional posts about basketball, English, and books. Hope it's helpful—thanks for following and support.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.