来源:https://zhuanlan.zhihu.com/p/148139089
gRPC系列(一) 什么是RPC?
初步印象
RPC的语义是远程过程调用,在一般的印象中,就是将一个服务调用封装在一个本地方法中,让调用者像使用本地方法一样调用服务,对其屏蔽实现细节。而具体的实现是通过调用方和服务方的一套约定,基于TCP长连接进行数据交互达成。
上面的解释似云里雾里,仅仅了解到这种程度是远远不够的,还需要更进一步,以相对底层和抽象的视角来理解RPC。
三个特点
广义上来讲,所有本应用程序外的调用都可以归类为RPC,不管是分布式服务,第三方服务的HTTP接口,还是读写Redis的一次请求。从抽象的角度来讲,它们都一样是RPC,由于不在本地执行,都有三个特点:
- 需要事先约定调用的语义(接口语法)
- 需要网络传输
- 需要约定网络传输中的内容格式
以一次Redis调用为例,执行redis.set("rpc", 1)这个调用,其中:
set及其参数("rpc", 1),就是对调用语义的约定,由redis的API给出
- RedisServer会监听一个服务端口,通过TCP传输内容,用异步事件驱动实现高并发
- 底层库会约定数据如何进行编解码,如何标识命令和参数,如何表示结果,如何表示数据的结尾等等
这三个特点都是因为调用不在本地而不得不衍生出来的问题,也因此决定了RPC的形态。所有的RPC解决方案都是在解决这三个问题,不断地在提出更加优良的解决方案,试图达到更好的性能,更低的使用成本。 本文也将围绕这三个特点来展开内容。
常规的RPC一般都是基于一个大的内部服务,进行分布式拆分,由于其语义上以本地方法的作为入口,那么天然的就更倾向于具备高性能、支持复杂参数和返回值、跨语言等特性。
以下内容略。。
添加的headr信息: key: my-header value: "test01"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
func main() { conn, err := grpc.Dial("localhost:12000", grpc.WithTransportCredentials(insecure.NewCredentials())) c := pb.NewHelloHTTPClient(conn) req := &pb.HelloHTTPRequest{Name: "test"} res, err := c.SayHello(context.Background(), req, grpc.PerRPCCredentials(extraMetadata{MyHeader: "test01"})) } type extraMetadata struct { MyHeader string `json:"my-header"` } func (c extraMetadata) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { return map[string]string{ "my-header": c.MyHeader, }, nil } func (c extraMetadata) RequireTransportSecurity() bool { return false } |
使用官方的metadata
|
|
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> { conn, err := grpc.Dial(<span class="hljs-string">"localhost:12000"</span>, grpc.WithTransportCredentials(insecure.NewCredentials())) header := metadata.New(<span class="hljs-keyword">map</span>[<span class="hljs-type">string</span>]<span class="hljs-type">string</span>{ <span class="hljs-string">"my-header"</span>: <span class="hljs-string">"test01"</span>, }) <span class="hljs-keyword">var</span> ctx = metadata.NewOutgoingContext(context.Background(), header) res, err := c.SayHello(ctx, req) } |
「三年博客,如果觉得我的文章对您有用,请帮助本站成长」
共有 0 - gRPC系列