Day 23:Java与Agent集成 - gRPC调用Java服务
🤖 系列:Java工程师转AI Agent 3个月学习计划
👤 作者:宸丶一 | 28岁Java程序员
🎯 今日目标: Java服务封装成gRPC,Python Agent调用Java服务
💬 个人格言: 代码改不改变世界我不知道,但先让我准时下班。
前言
说实话,之前一直没搞懂gRPC和REST到底有啥区别。这次自己写了个计算器服务,跑起来之后才明白:gRPC真的快太多了。
最近一直体验小米的MiMo Code,用AI编程助手写代码,感觉就像有个助手在旁边帮你干活,还挺爽的。
学习目标
- 理解Java服务封装成gRPC
- 掌握gRPC客户端调用Java服务
- 理解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架构中的价值。继续保持!