gRPC在Kotlin中的使用:何时使用及如何避免失误

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

gRPC在Kotlin中的使用:何时使用才不会后悔



想象一下:您正在用Kotlin编写微服务,一切运行正常,但服务间的请求开始变得迟缓。您曾经钟爱的REST API开始令人烦恼——序列化开销太大,HTTP开销太多。您开始搜索"微服务间快速通信方式",然后发现了gRPC。紧接着问题就来了:"这会不会过度设计?还是保持现状?"



让我们来分析一下。Kotlin中的gRPC不仅仅是"又一个协议"。它是一种完全不同的服务间通信方式。它比REST更快、更严格、更强大,但也更复杂。在本文中,我将介绍何时gRPC是您最好的朋友,何时最好使用传统的REST。当然,我还会展示Kotlin的真实代码。



什么是gRPC,为什么它在Kotlin世界中如此流行?



gRPC是Google开发的远程过程调用(RPC)框架。它使用Protocol Buffers(protobuf)进行数据序列化,并使用HTTP/2进行传输。如果说REST就像寄信(每个请求都是一封独立的信),那么gRPC就像直接打电话:快速、双向且延迟极低。



对于Kotlin开发者来说,gRPC尤其有趣,因为:



  • Kotlin协程与gRPC的异步流完美结合。
  • protobuf的强类型化——运行时错误更少。
  • 支持双向流式传输——非常适合聊天、游戏和实时应用。


但说实话:gRPC并非处处都需要。现在我将展示如何判断您的项目是否需要它。



何时在Kotlin中使用gRPC:5个铁定适用的场景



1. 对性能要求高的微服务



如果您的微服务每秒处理数万个请求,gRPC在速度上比REST快2-5倍。这得益于protobuf的二进制格式和HTTP/2的多路复用。



示例:您有一个用Kotlin编写的推荐服务,需要在毫秒内返回个性化内容。使用JSON的REST会显得"笨重"——每个请求都包含字段名、括号和其他文本垃圾。而Protobuf只传输数字和字符串,没有多余包装。



// 在.proto文件中的定义service Recommender {    rpc GetRecommendations (UserRequest) returns (RecommendationsResponse);}

message UserRequest { string user_id = 1; int32 max_results = 2;}

message RecommendationsResponse { repeated Item items = 1;}


Kotlin客户端的代码将非常简洁:



val stub = RecommenderGrpc.newBlockingStub(channel)val request = UserRequest.newBuilder()    .setUserId("user_123")    .setMaxResults(10)    .build()

val response = stub.getRecommendations(request)println("获取到 ${response.itemsCount} 条推荐")


2. 实时数据流式传输



gRPC支持四种流式传输类型:服务端流、客户端流、双向流和简单的一元调用。在Kotlin中,结合协程尤其方便——您可以将数据作为Flow进行流式传输。



示例:一个日志服务器,实时向客户端发送新记录。



// Kotlin服务端代码class LogServiceImpl : LogServiceGrpcKt.LogServiceCoroutineImplBase() {    override fun streamLogs(request: LogRequest): Flow<LogEntry> = flow {        val logSource = getLogSource(request.logType)        logSource.collect { logEntry ->            emit(logEntry)        }    }}

// 客户端代码val stub = LogServiceGrpcKt.LogServiceCoroutineStub(channel)stub.streamLogs(LogRequest.newBuilder().setLogType("error").build()) .collect { log -> println("新日志:${log.message}") }


尝试用REST和WebSocket实现同样的功能——会变得臃肿且缓慢。



3. 多语言系统

博客

书籍推荐