Day 23:Java与Agent集成 - gRPC调用Java服务

Day 23:Java与Agent集成 - gRPC调用Java服务

🤖 系列:Java工程师转AI Agent 3个月学习计划

👤 作者:宸丶一 | 28岁Java程序员

🎯 今日目标: Java服务封装成gRPC,Python Agent调用Java服务

💬 个人格言: 代码改不改变世界我不知道,但先让我准时下班。


前言

说实话,之前一直没搞懂gRPC和REST到底有啥区别。这次自己写了个计算器服务,跑起来之后才明白:gRPC真的快太多了。

最近一直体验小米的MiMo Code,用AI编程助手写代码,感觉就像有个助手在旁边帮你干活,还挺爽的。


学习目标

  1. 理解Java服务封装成gRPC
  2. 掌握gRPC客户端调用Java服务
  3. 理解gRPC在Agent架构中的价值

一、gRPC核心概念

Proto文件 = Interface + DTO

protobuf 复制代码
// Proto文件(像Java的Interface + DTO)
service CalculatorService {
    rpc Add (AddRequest) returns (AddResponse);
}

message AddRequest {
    double left = 1;
    double right = 2;
}

message AddResponse {
    double result = 1;
    string message = 2;
}

类比Java

java 复制代码
// Java Interface + DTO
public interface CalculatorService {
    AddResponse add(AddRequest request);
}

gRPC架构

#mermaid-svg-MWd9KCHrkFtwE2d4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MWd9KCHrkFtwE2d4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MWd9KCHrkFtwE2d4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MWd9KCHrkFtwE2d4 .error-icon{fill:#552222;}#mermaid-svg-MWd9KCHrkFtwE2d4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MWd9KCHrkFtwE2d4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MWd9KCHrkFtwE2d4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MWd9KCHrkFtwE2d4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MWd9KCHrkFtwE2d4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MWd9KCHrkFtwE2d4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MWd9KCHrkFtwE2d4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MWd9KCHrkFtwE2d4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MWd9KCHrkFtwE2d4 .marker.cross{stroke:#333333;}#mermaid-svg-MWd9KCHrkFtwE2d4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MWd9KCHrkFtwE2d4 p{margin:0;}#mermaid-svg-MWd9KCHrkFtwE2d4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-MWd9KCHrkFtwE2d4 .cluster-label text{fill:#333;}#mermaid-svg-MWd9KCHrkFtwE2d4 .cluster-label span{color:#333;}#mermaid-svg-MWd9KCHrkFtwE2d4 .cluster-label span p{background-color:transparent;}#mermaid-svg-MWd9KCHrkFtwE2d4 .label text,#mermaid-svg-MWd9KCHrkFtwE2d4 span{fill:#333;color:#333;}#mermaid-svg-MWd9KCHrkFtwE2d4 .node rect,#mermaid-svg-MWd9KCHrkFtwE2d4 .node circle,#mermaid-svg-MWd9KCHrkFtwE2d4 .node ellipse,#mermaid-svg-MWd9KCHrkFtwE2d4 .node polygon,#mermaid-svg-MWd9KCHrkFtwE2d4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MWd9KCHrkFtwE2d4 .rough-node .label text,#mermaid-svg-MWd9KCHrkFtwE2d4 .node .label text,#mermaid-svg-MWd9KCHrkFtwE2d4 .image-shape .label,#mermaid-svg-MWd9KCHrkFtwE2d4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-MWd9KCHrkFtwE2d4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MWd9KCHrkFtwE2d4 .rough-node .label,#mermaid-svg-MWd9KCHrkFtwE2d4 .node .label,#mermaid-svg-MWd9KCHrkFtwE2d4 .image-shape .label,#mermaid-svg-MWd9KCHrkFtwE2d4 .icon-shape .label{text-align:center;}#mermaid-svg-MWd9KCHrkFtwE2d4 .node.clickable{cursor:pointer;}#mermaid-svg-MWd9KCHrkFtwE2d4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MWd9KCHrkFtwE2d4 .arrowheadPath{fill:#333333;}#mermaid-svg-MWd9KCHrkFtwE2d4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MWd9KCHrkFtwE2d4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MWd9KCHrkFtwE2d4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MWd9KCHrkFtwE2d4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MWd9KCHrkFtwE2d4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MWd9KCHrkFtwE2d4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MWd9KCHrkFtwE2d4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MWd9KCHrkFtwE2d4 .cluster text{fill:#333;}#mermaid-svg-MWd9KCHrkFtwE2d4 .cluster span{color:#333;}#mermaid-svg-MWd9KCHrkFtwE2d4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MWd9KCHrkFtwE2d4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MWd9KCHrkFtwE2d4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-MWd9KCHrkFtwE2d4 .icon-shape,#mermaid-svg-MWd9KCHrkFtwE2d4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MWd9KCHrkFtwE2d4 .icon-shape p,#mermaid-svg-MWd9KCHrkFtwE2d4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MWd9KCHrkFtwE2d4 .icon-shape .label rect,#mermaid-svg-MWd9KCHrkFtwE2d4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MWd9KCHrkFtwE2d4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MWd9KCHrkFtwE2d4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MWd9KCHrkFtwE2d4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Java Service
Python Agent
Protobuf/HTTP2
Protobuf/HTTP2
gRPC Client
Stub
Stub
gRPC Server

核心组件

  • Proto文件:定义接口和数据格式(Interface + DTO)

  • gRPC Server:提供服务实现(Spring Boot服务)

  • gRPC Client:调用服务(RestTemplate/OpenFeign)

  • Stub:自动生成的代理对象

  • Protobuf:二进制序列化,更快更小

  • HTTP/2:多路复用,更高效

    public class AddRequest {
    private double left;
    private double right;
    }

    public class AddResponse {
    private double result;
    private String message;
    }


二、gRPC vs REST

对比表格

对比项 REST gRPC
数据格式 JSON(文本) Protobuf(二进制)
传输协议 HTTP/1.1 HTTP/2
性能 50-100ms/次 0.4-2ms/次
类型安全 强(Proto严格定义)
代码生成 手动写HTTP调用 自动生成客户端/服务端
跨语言 一般 原生支持(任意语言互调)

gRPC vs REST 对比

#mermaid-svg-I95Gu7DqYKYUsJE2{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-I95Gu7DqYKYUsJE2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-I95Gu7DqYKYUsJE2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-I95Gu7DqYKYUsJE2 .error-icon{fill:#552222;}#mermaid-svg-I95Gu7DqYKYUsJE2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-I95Gu7DqYKYUsJE2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-I95Gu7DqYKYUsJE2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-I95Gu7DqYKYUsJE2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-I95Gu7DqYKYUsJE2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-I95Gu7DqYKYUsJE2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-I95Gu7DqYKYUsJE2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-I95Gu7DqYKYUsJE2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-I95Gu7DqYKYUsJE2 .marker.cross{stroke:#333333;}#mermaid-svg-I95Gu7DqYKYUsJE2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-I95Gu7DqYKYUsJE2 p{margin:0;}#mermaid-svg-I95Gu7DqYKYUsJE2 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-I95Gu7DqYKYUsJE2 .cluster-label text{fill:#333;}#mermaid-svg-I95Gu7DqYKYUsJE2 .cluster-label span{color:#333;}#mermaid-svg-I95Gu7DqYKYUsJE2 .cluster-label span p{background-color:transparent;}#mermaid-svg-I95Gu7DqYKYUsJE2 .label text,#mermaid-svg-I95Gu7DqYKYUsJE2 span{fill:#333;color:#333;}#mermaid-svg-I95Gu7DqYKYUsJE2 .node rect,#mermaid-svg-I95Gu7DqYKYUsJE2 .node circle,#mermaid-svg-I95Gu7DqYKYUsJE2 .node ellipse,#mermaid-svg-I95Gu7DqYKYUsJE2 .node polygon,#mermaid-svg-I95Gu7DqYKYUsJE2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-I95Gu7DqYKYUsJE2 .rough-node .label text,#mermaid-svg-I95Gu7DqYKYUsJE2 .node .label text,#mermaid-svg-I95Gu7DqYKYUsJE2 .image-shape .label,#mermaid-svg-I95Gu7DqYKYUsJE2 .icon-shape .label{text-anchor:middle;}#mermaid-svg-I95Gu7DqYKYUsJE2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-I95Gu7DqYKYUsJE2 .rough-node .label,#mermaid-svg-I95Gu7DqYKYUsJE2 .node .label,#mermaid-svg-I95Gu7DqYKYUsJE2 .image-shape .label,#mermaid-svg-I95Gu7DqYKYUsJE2 .icon-shape .label{text-align:center;}#mermaid-svg-I95Gu7DqYKYUsJE2 .node.clickable{cursor:pointer;}#mermaid-svg-I95Gu7DqYKYUsJE2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-I95Gu7DqYKYUsJE2 .arrowheadPath{fill:#333333;}#mermaid-svg-I95Gu7DqYKYUsJE2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-I95Gu7DqYKYUsJE2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-I95Gu7DqYKYUsJE2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-I95Gu7DqYKYUsJE2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-I95Gu7DqYKYUsJE2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-I95Gu7DqYKYUsJE2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-I95Gu7DqYKYUsJE2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-I95Gu7DqYKYUsJE2 .cluster text{fill:#333;}#mermaid-svg-I95Gu7DqYKYUsJE2 .cluster span{color:#333;}#mermaid-svg-I95Gu7DqYKYUsJE2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-I95Gu7DqYKYUsJE2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-I95Gu7DqYKYUsJE2 rect.text{fill:none;stroke-width:0;}#mermaid-svg-I95Gu7DqYKYUsJE2 .icon-shape,#mermaid-svg-I95Gu7DqYKYUsJE2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-I95Gu7DqYKYUsJE2 .icon-shape p,#mermaid-svg-I95Gu7DqYKYUsJE2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-I95Gu7DqYKYUsJE2 .icon-shape .label rect,#mermaid-svg-I95Gu7DqYKYUsJE2 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-I95Gu7DqYKYUsJE2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-I95Gu7DqYKYUsJE2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-I95Gu7DqYKYUsJE2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} gRPC
REST
慢100倍
HTTP/1.1
JSON文本
手动序列化/反序列化
短连接
性能: 50-100ms/次
HTTP/2
Protobuf二进制
自动序列化/反序列化
长连接+多路复用
性能: 0.4-2ms/次

核心差异

  • 数据格式:JSON(文本) vs Protobuf(二进制)
  • 传输协议:HTTP/1.1 vs HTTP/2
  • 性能:50-100ms vs 0.4-2ms
  • 类型安全:弱 vs 强

性能实测

复制代码
REST API (JSON): 50-100ms/次
gRPC (Protobuf): 0.4-2ms/次

gRPC比REST快 100-200 倍(本地)/ 3-10 倍(网络)

三、实战

gRPC调用时序

gRPC Server Stub Channel gRPC Client gRPC Server Stub Channel gRPC Client #mermaid-svg-Sf4DYtWndPjSGbQP{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Sf4DYtWndPjSGbQP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Sf4DYtWndPjSGbQP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Sf4DYtWndPjSGbQP .error-icon{fill:#552222;}#mermaid-svg-Sf4DYtWndPjSGbQP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Sf4DYtWndPjSGbQP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Sf4DYtWndPjSGbQP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Sf4DYtWndPjSGbQP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Sf4DYtWndPjSGbQP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Sf4DYtWndPjSGbQP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Sf4DYtWndPjSGbQP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Sf4DYtWndPjSGbQP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Sf4DYtWndPjSGbQP .marker.cross{stroke:#333333;}#mermaid-svg-Sf4DYtWndPjSGbQP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Sf4DYtWndPjSGbQP p{margin:0;}#mermaid-svg-Sf4DYtWndPjSGbQP .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Sf4DYtWndPjSGbQP text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-Sf4DYtWndPjSGbQP .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-Sf4DYtWndPjSGbQP .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-Sf4DYtWndPjSGbQP .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-Sf4DYtWndPjSGbQP .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-Sf4DYtWndPjSGbQP #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-Sf4DYtWndPjSGbQP .sequenceNumber{fill:white;}#mermaid-svg-Sf4DYtWndPjSGbQP #sequencenumber{fill:#333;}#mermaid-svg-Sf4DYtWndPjSGbQP #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-Sf4DYtWndPjSGbQP .messageText{fill:#333;stroke:none;}#mermaid-svg-Sf4DYtWndPjSGbQP .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Sf4DYtWndPjSGbQP .labelText,#mermaid-svg-Sf4DYtWndPjSGbQP .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-Sf4DYtWndPjSGbQP .loopText,#mermaid-svg-Sf4DYtWndPjSGbQP .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-Sf4DYtWndPjSGbQP .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-Sf4DYtWndPjSGbQP .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-Sf4DYtWndPjSGbQP .noteText,#mermaid-svg-Sf4DYtWndPjSGbQP .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-Sf4DYtWndPjSGbQP .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Sf4DYtWndPjSGbQP .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Sf4DYtWndPjSGbQP .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Sf4DYtWndPjSGbQP .actorPopupMenu{position:absolute;}#mermaid-svg-Sf4DYtWndPjSGbQP .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-Sf4DYtWndPjSGbQP .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Sf4DYtWndPjSGbQP .actor-man circle,#mermaid-svg-Sf4DYtWndPjSGbQP line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-Sf4DYtWndPjSGbQP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 全程耗时: 0.4-2ms 创建连接 localhost:50051创建代理对象stub.Add(request)发送请求 (Protobuf)HTTP/2 请求执行计算返回响应 (Protobuf)接收响应返回结果

1. gRPC服务端

python 复制代码
class CalculatorServiceServicer(calculator_pb2_grpc.CalculatorServiceServicer):
    def Add(self, request, context):
        result = request.left + request.right
        return calculator_pb2.AddResponse(
            result=result,
            message=f'{request.left} + {request.right} = {result}'
        )

2. gRPC客户端

python 复制代码
channel = grpc.insecure_channel('localhost:50051')
stub = calculator_pb2_grpc.CalculatorServiceStub(channel)
request = calculator_pb2.AddRequest(left=10, right=5)
response = stub.Add(request)
print(f'✅ {response.message}')

3. 运行结果

复制代码
=== gRPC客户端调用Java服务 ===

1. 加法:10 + 5 = 
✅ 10.0 + 5.0 = 15.0

2. 减法:10 - 5 = 
✅ 10.0 - 5.0 = 5.0

3. 乘法:10 × 5 = 
✅ 10.0 × 5.0 = 50.0

4. 除法:10 ÷ 5 = 
✅ 10.0 ÷ 5.0 = 2.0

5. 除法(除数为0):10 ÷ 0 = 
❌ 除法错误:除数不能为0

🎉 所有调用完成!

四、今日收获

知识层面

  • 理解了gRPC的核心概念
  • 掌握了gRPC客户端调用
  • 理解了gRPC在Agent架构中的价值

技能层面

  • 能定义Proto文件
  • 能实现gRPC服务端和客户端
  • 能理解gRPC和REST的区别

思维层面

  • 学会了用Java类比理解gRPC
  • 理解了"Proto文件 = Interface + DTO"
  • 理解了"Stub = Proxy对象"

五、思考题答案

1. gRPC和REST的核心区别?

答案

  • gRPC用二进制Protobuf,REST用文本JSON
  • gRPC用HTTP/2,REST用HTTP/1.1
  • gRPC类型安全,REST弱类型

2. 为什么gRPC比REST快?

答案

  • Protobuf二进制更小(小3-5倍)
  • HTTP/2多路复用(不用排队)
  • 类型安全(不需要反序列化JSON)

3. Proto文件的作用?

答案

  • Proto文件 = Interface + DTO
  • 自动生成客户端和服务端代码
  • 跨语言支持(任意语言互调)

4. 什么场景用gRPC,什么场景用REST?

答案

  • gRPC:内部服务调用、高性能场景、跨语言
  • REST:对外API、前端调用、简单场景

5. Agent调用Java服务为什么推荐gRPC?

答案

  • Python Agent调Java服务
  • gRPC更快(0.42ms vs 50ms)
  • gRPC类型安全(不会传错参数)
  • gRPC跨语言(Python调Java)

六、明日计划

明天继续深入分析Provider目录的具体实现!


📝 小小腾老师的评分

维度 得分 评价
gRPC掌握程度 ⭐⭐⭐⭐ 能独立实现,但HTTP/2原理还需要深入
代码实践 ⭐⭐⭐⭐⭐ 代码清晰,注释详细
思考题 ⭐⭐⭐⭐⭐ 答案准确,理解到位

总分:92.5分(优秀)

老师说:今天表现很棒!理解了gRPC的核心概念,掌握了gRPC客户端调用,理解了gRPC在Agent架构中的价值。继续保持!