{"id":10005968,"date":"2022-07-22T11:37:47","date_gmt":"2022-07-22T03:37:47","guid":{"rendered":"https:\/\/ityet.com\/?p=10005968"},"modified":"2022-07-22T11:37:47","modified_gmt":"2022-07-22T03:37:47","slug":"%e4%ba%94%e5%88%86%e9%92%9f%e7%bb%99%e4%bd%a0%e7%9a%84-grpc-%e6%9c%8d%e5%8a%a1%e5%8a%a0%e4%b8%8a-http-%e6%8e%a5%e5%8f%a3","status":"publish","type":"post","link":"https:\/\/itmax.cn\/?p=10005968","title":{"rendered":"\u4e94\u5206\u949f\u7ed9\u4f60\u7684 gRPC \u670d\u52a1\u52a0\u4e0a HTTP \u63a5\u53e3"},"content":{"rendered":"<h2>gRPC \u670d\u52a1\u8981\u52a0 HTTP \u63a5\u53e3\uff1f<\/h2>\n<p>go-zero \u7ed9\u5927\u5bb6\u5e26\u6765\u6781\u7b80\u7684 RESTful \u548c gRPC \u670d\u52a1\u5f00\u53d1\u4f53\u9a8c\u7684\u540c\u65f6\uff0c\u793e\u533a\u53c8\u7ed9\u6211\u4eec\u63d0\u51fa\u4e86\u65b0\u7684\u671f\u671b\uff1a<\/p>\n<ul>\n<li>\u6211\u60f3\u53ea\u5199\u4e00\u6b21\u4ee3\u7801<\/li>\n<li>\u65e2\u8981 gRPC \u63a5\u53e3<\/li>\n<li>\u4e5f\u8981 HTTP \u63a5\u53e3<\/li>\n<li>\u65e2\u8981\u3002\u3002\u3002\u4e5f\u8981\u3002\u3002\u3002<\/li>\n<\/ul>\n<p>\u4e5f\u6709\u9053\u7406\u561b\uff01\u4f60\u770b\u7528\u6237\u600e\u4e48\u8bf4\uff1a<\/p>\n<blockquote>\n<p>\u7528\u6237A\uff1a\u4e00\u5957\u903b\u8f91\uff0capi\u548crpc\u4e00\u8d77<\/p>\n<p>\u7528\u6237B\uff1ago-zero\u8981\u662f\u80fd\u7b80\u5316\u8fd9\u4e00\u6b65\u6211\u611f\u89c9\u4f1a\u6210\u4e3ago\u751f\u6001\u4e2d\u6700\u597d\u7684\u5fae\u670d\u52a1\u6846\u67b6\u6ca1\u6709\u4e4b\u4e00<\/p>\n<\/blockquote>\n<p>\u4e8e\u662f\uff0c\u6211\u9677\u5165\u4e86\u6df1\u6df1\u7684\u601d\u8003\uff1a\u7528\u6237\u4ece\u6765\u662f\u4e0d\u4f1a\u9519\u7684\uff0c\u4f46\u662f\u6211\u4eec\u8981\u4e0d\u8981\u63d0\u4f9b\u5462\uff1f<\/p>\n<p>\u4e8e\u662f\uff0c\u4f60\u770b\u5230\u4e86\u8fd9\u7bc7\u6587\u7ae0\u3002\u3002\u3002<\/p>\n<h2>\u6211\u4eec\u5148\u63d0\u4f9b gRPC \u670d\u52a1<\/h2>\n<p>\u5bf9\u4e8e\u8fd9\u79cd\u670d\u52a1\uff0c\u6211\u4eec\u592a\u719f\u4e86\u3002\u65b0\u5efa\u4e00\u4e2a\u76ee\u5f55\uff0c\u5c31\u53eb <code>grpc-restufl<\/code> \u5427\uff0c\u91cc\u9762\u653e\u4e2a <code>sum.proto<\/code> \u6587\u4ef6<\/p>\n<pre><code class=\"protobuf\">syntax = &quot;proto3&quot;;\n\npackage sum;\noption go_package=&quot;.\/pb&quot;;\n\nmessage Numbers {\n    int64 a = 1;\n    int64 b = 2;\n}\n\nmessage SumRequest {\n    Numbers numbers =1;\n}\n\nmessage SumResponse {\n    int64 result = 1;\n}\n\nservice Sum {\n    rpc Add(SumRequest) returns (SumResponse) {}\n}<\/code><\/pre>\n<p>\u4e00\u952e\u751f\u6210\uff0c\u4f60\u61c2\u7684\u3002\u3002\u3002<\/p>\n<pre><code class=\"shell\">$ goctl rpc protoc --go_out=. --go-grpc_out=. --zrpc_out=. sum.proto<\/code><\/pre>\n<p>\u770b\u770b\u90fd\u6709\u4e86\u5565<\/p>\n<pre><code class=\"shell\">.\n\u251c\u2500\u2500 etc\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 sum.yaml\n\u251c\u2500\u2500 go.mod\n\u251c\u2500\u2500 internal\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 config\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 config.go\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 logic\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 addlogic.go\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 server\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 sumserver.go\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 svc\n\u2502\u00a0\u00a0     \u2514\u2500\u2500 servicecontext.go\n\u251c\u2500\u2500 pb\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 sum.pb.go\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 sum_grpc.pb.go\n\u251c\u2500\u2500 sum\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 sum.go\n\u251c\u2500\u2500 sum.go\n\u2514\u2500\u2500 sum.proto<\/code><\/pre>\n<p>\u5b9e\u73b0\u4e00\u4e0b\u4e1a\u52a1\u903b\u8f91\uff0c\u5c06 <code>internal\/logic\/addlogic.go<\/code> \u91cc\u7684 <code>Add<\/code> \u65b9\u6cd5\u4fee\u6539\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"go\">func (l *AddLogic) Add(in *pb.SumRequest) (*pb.SumResponse, error) {\n    return &amp;pb.SumResponse{\n        Result: in.Numbers.A+in.Numbers.B,\n    }, nil\n}<\/code><\/pre>\n<p>\u53ef\u4ee5\u8dd1\u4e86\uff0c\u4e1a\u52a1\u903b\u8f91\u4e5f\u662f\u6709\u4e86\u7684\uff08\u867d\u7136\u5f88\u7b80\u5355\uff0c\u6f14\u793a\u561b\u3002\u3002\u3002\uff09<\/p>\n<pre><code class=\"shell\">$ go mod tidy &amp;&amp; go run sum.go\nStarting rpc server at 127.0.0.1:8080...<\/code><\/pre>\n<p>\u5bf9\u4e8e\u719f\u6089 go-zero \u7684\u540c\u5b66\u6765\u8bf4\uff0c\u81f3\u6b64\u65e0\u4eae\u70b9\uff08\u65b0\u77e5\u8bc6\uff09\uff0c\u63a5\u4e0b\u6765 GET \u65b0\u6280\u80fd\uff5e<\/p>\n<h2>\u63d0\u4f9b HTTP \u63a5\u53e3<\/h2>\n<h3>\u66f4\u65b0 go-zero<\/h3>\n<p>\u9996\u5148\uff0c\u6211\u4eec\u66f4\u65b0 go-zero \u81f3 <code>master<\/code> \u7248\uff0c\u56e0\u4e3a <code>gateway<\/code> \u8fd8\u6ca1\u6b63\u5f0f\u53d1\u7248\uff0c\u516b\u6708\u521d\u4f1a\u6b63\u5f0f\u8ddf\u5927\u5bb6\u89c1\u9762<\/p>\n<pre><code class=\"shell\">$ go get -u github.com\/zeromicro\/go-zero@master<\/code><\/pre>\n<h3>\u4fee\u6539 proto \u6587\u4ef6<\/h3>\n<p>\u4fee\u6539 <code>sum.proto<\/code>\uff0c\u6211\u65b0\u5efa\u4e86\u4e00\u4e2a <code>sum-api.proto<\/code>\uff0c\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"protobuf\">syntax = &quot;proto3&quot;;\n\npackage sum;\noption go_package=&quot;.\/pb&quot;;\n\nimport &quot;google\/api\/annotations.proto&quot;;\n\nmessage Numbers {\n    int64 a = 1;\n    int64 b = 2;\n}\n\nmessage SumRequest {\n    Numbers numbers =1;\n}\n\nmessage SumResponse {\n    int64 result = 1;\n}\n\nservice Sum {\n    rpc Add(SumRequest) returns (SumResponse) {\n        option (google.api.http) = {\n            post: &quot;\/v1\/sum&quot;\n            body: &quot;*&quot;\n        };\n    }\n}<\/code><\/pre>\n<h3>\u751f\u6210 proto descriptor \u6587\u4ef6<\/h3>\n<pre><code class=\"shell\">protoc --include_imports --proto_path=. --descriptor_set_out=sum.pb sum-api.proto<\/code><\/pre>\n<h3>\u4fee\u6539\u914d\u7f6e\u6587\u4ef6<\/h3>\n<p>\u4fee\u6539\u540e\u7684 <code>internal\/config\/config.go<\/code> \u5982\u4e0b\uff08\u90e8\u5206\uff09\uff1a<\/p>\n<pre><code class=\"go\">type Config struct {\n    zrpc.RpcServerConf\n    Gateway gateway.GatewayConf\n}<\/code><\/pre>\n<p>\u4fee\u6539\u540e\u7684 <code>etc\/sum.yaml<\/code> \u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"yaml\">Gateway:\n  Name: gateway\n  Port: 8081\n  Upstreams:\n    - Grpc:\n        Endpoints:\n          - localhost:8080\n      ProtoSet: sum.pb<\/code><\/pre>\n<h3>\u4fee\u6539 main \u51fd\u6570<\/h3>\n<p>\u521b\u5efa <code>gateway<\/code> \u5e76\u7528 <code>ServiceGroup<\/code> \u6765\u7ba1\u7406 <code>gRPC server<\/code> \u548c <code>gateway server<\/code>\uff0c\u90e8\u5206\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"go\">    gw := gateway.MustNewServer(c.Gateway)\n    group := service.NewServiceGroup()\n    group.Add(s)\n    group.Add(gw)\n    defer group.Stop()\n\n    fmt.Printf(&quot;Starting rpc server at %s...\/n&quot;, c.ListenOn)\n    fmt.Printf(&quot;Starting gateway at %s:%d...\/n&quot;, c.Gateway.Host, c.Gateway.Port)\n    group.Start()<\/code><\/pre>\n<h2>\u5927\u529f\u544a\u6210<\/h2>\n<p>\u8ba9\u6211\u4eec\u6765\u542f\u52a8\u670d\u52a1<\/p>\n<pre><code class=\"shell\">$ go run sum.go\nStarting rpc server at 127.0.0.1:8080...\nStarting gateway at 0.0.0.0:8081...<\/code><\/pre>\n<p>\u7528 <code>curl<\/code> \u6d4b\u8bd5\u4e00\u4e0b<\/p>\n<pre><code class=\"shell\">$ curl -i -H &quot;Content-Type: application\/json&quot; -d '{&quot;numbers&quot;:{&quot;a&quot;:2,&quot;b&quot;:3}}' localhost:8081\/v1\/sum\nHTTP\/1.1 200 OK\nContent-Type: application\/json; charset=utf-8\nTraceparent: 00-ad5b7df7a834a1c05ee64999e3310811-195ba1f4f9956cc4-00\nDate: Mon, 18 Jul 2022 14:33:11 GMT\nContent-Length: 20\n\n{\n  &quot;result&quot;: &quot;5&quot;\n}<\/code><\/pre>\n<p>\u518d\u770b\u6211\u4eec\u7684 <code>gateway<\/code> \u548c <code>gRPC<\/code> \u7684\u65e5\u5fd7\u91cc\u7684\u94fe\u8def\u4fe1\u606f\u548c\u5ba2\u6237\u7aef\u6536\u5230\u7684\u90fd\u80fd\u5bf9\u5e94\u4e0a\uff0c\u8d5e\uff01<\/p>\n<pre><code class=\"json\">{&quot;@timestamp&quot;:&quot;2022-07-18T22:33:11.437+08:00&quot;,&quot;caller&quot;:&quot;serverinterceptors\/statinterceptor.go:76&quot;,&quot;content&quot;:&quot;127.0.0.1:61635 - \/sum.Sum\/Add - {\/&quot;numbers\/&quot;:{\/&quot;a\/&quot;:2,\/&quot;b\/&quot;:3}}&quot;,&quot;duration&quot;:&quot;0.0ms&quot;,&quot;level&quot;:&quot;info&quot;,&quot;span&quot;:&quot;b3c85cd32a76f8c9&quot;,&quot;trace&quot;:&quot;ad5b7df7a834a1c05ee64999e3310811&quot;}\n{&quot;@timestamp&quot;:&quot;2022-07-18T22:33:11.438+08:00&quot;,&quot;caller&quot;:&quot;handler\/loghandler.go:197&quot;,&quot;content&quot;:&quot;[HTTP] 200 - POST \/v1\/sum - 127.0.0.1:61662 - curl\/7.79.1&quot;,&quot;duration&quot;:&quot;0.7ms&quot;,&quot;level&quot;:&quot;info&quot;,&quot;span&quot;:&quot;195ba1f4f9956cc4&quot;,&quot;trace&quot;:&quot;ad5b7df7a834a1c05ee64999e3310811&quot;}<\/code><\/pre>\n<h2>\u7ed3\u675f\u8bed<\/h2>\n<p>\u4f60\u770b\uff0c\u7ed9\u6211\u4eec\u7684 <code>gRPC<\/code> \u670d\u52a1\u52a0\u4e0a <code>HTTP<\/code> \u63a5\u53e3\u662f\u4e0d\u662f\u4e94\u5206\u949f\u5c31\u53ef\u4ee5\u5b8c\u6210\u4e86\uff1f\u662f\u4e0d\u662f\uff1f<\/p>\n<p>\u53e6\u5916\uff0c\u4e0d\u8981\u5c0f\u770b\u8fd9\u4e2a\u7b80\u5355\u7684 <code>gateway<\/code>\uff0c\u914d\u7f6e\u91cc\u5982\u679c\u662f\u5bf9\u63a5\u540e\u9762\u7684 <code>gRPC<\/code> \u670d\u52a1\u53d1\u73b0\u7684\u8bdd\uff0c\u4f1a\u81ea\u52a8\u8d1f\u8f7d\u5747\u8861\u7684\uff0c\u5e76\u4e14\u8fd8\u53ef\u4ee5\u81ea\u5b9a\u4e49\u4e2d\u95f4\u4ef6\uff0c\u60f3\u600e\u4e48\u63a7\u5236\u5c31\u600e\u4e48\u63a7\u5236\u3002<\/p>\n<p>\u662f\u4e0d\u662f\u6709\u70b9\u5fc3\u52a8\u4e86\u5462\uff1f<\/p>\n<p>\u5bf9\u4e86\uff0c\u8fd9\u4e2a\u793a\u4f8b\u7684\u5b8c\u6574\u4ee3\u7801\u5728\uff1a<\/p>\n<p><a href=\"https:\/\/link.segmentfault.com\/?enc=cISNa9PX6FzNeOeOtVJu7A%3D%3D.drOo%2B5tmi4EN087LfcJwvYLSkWIoyqAkHwsvXh1s8OVxTPf71hCHTztSiDxO1Rcf\" rel=\"nofollow\">https:\/\/github.com\/kevwan\/grpc-restful<\/a><\/p>\n<h2>\u9879\u76ee\u5730\u5740<\/h2>\n<p><a href=\"https:\/\/link.segmentfault.com\/?enc=BnozektRSCWt360WqKZe8Q%3D%3D.olkbbAB4JWMOi%2BG5Hpc1vKo2c1L5m%2FDyBVruOSEpFN0yIYqUhFrNLFVzgR%2BycUBo\" rel=\"nofollow\">https:\/\/github.com\/zeromicro\/go-zero<\/a><\/p>\n<p>\u6b22\u8fce\u4f7f\u7528 <code>go-zero<\/code> \u5e76 <strong>star<\/strong> \u652f\u6301\u6211\u4eec\uff01<\/p>\n<h2>\u5fae\u4fe1\u4ea4\u6d41\u7fa4<\/h2>\n<p>\u5173\u6ce8\u300e<strong>\u5fae\u670d\u52a1\u5b9e\u8df5<\/strong>\u300f\u516c\u4f17\u53f7\u5e76\u70b9\u51fb <strong>\u4ea4\u6d41\u7fa4<\/strong> \u83b7\u53d6\u793e\u533a\u7fa4\u4e8c\u7ef4\u7801\u3002<\/p>\n<p><a href=\"https:\/\/segmentfault.com\/a\/1190000042206715\">https:\/\/segmentfault.com\/a\/1190000042206715<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>gRPC \u670d\u52a1\u8981\u52a0 HTTP \u63a5\u53e3\uff1f go-zero \u7ed9\u5927\u5bb6\u5e26\u6765\u6781\u7b80\u7684 RESTful \u548c gRPC \u670d\u52a1\u5f00\u53d1 [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[],"tags":[],"class_list":["post-10005968","post","type-post","status-publish","format-standard","hentry"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10005968","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10005968"}],"version-history":[{"count":0,"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10005968\/revisions"}],"wp:attachment":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10005968"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10005968"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10005968"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}