RPC介绍

Remote Procedure Call,远程过程调用

解决问题

而一旦踏入公司尤其是大型互联网公司就会发现,公司的系统都由成千上万大大小小的服务组成,各服务部署在不同的机器上,由不同的团队负责。这时就会遇到两个问题:
1)要搭建一个新服务,免不了需要依赖他人的服务,而现在他人的服务都在远端,怎么调用?
2)其它团队要使用我们的服务,我们的服务该怎么发布以便他人调用?

过程

  1. 服务消费方(client)调用以本地调用方式调用服务;
  2. client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
  3. client stub找到服务地址,并将消息发送到服务端;
  4. server stub收到消息后进行解码;
  5. server stub根据解码结果调用本地的服务;
  6. 本地服务执行并将结果返回给server stub;
  7. server stub将返回结果打包成消息并发送至消费方;
  8. client stub接收到消息,并进行解码;
  9. 服务消费方得到最终结果。

RPC的目标就是要2~8这些步骤都封装起来,让用户对这些细节透明。

实现方式

RPC可以通过HTTP来实现(grpc基于http2.0),也可以通过Socket自己实现一套协议来实现.

grpc框架

4种通信方式

  • 简单rpc:一个请求对象对应一个返回对象

rpc simpleHello(Person) returns (Result) {}

  • 服务端流式rpc :一个请求对象,服务端可以传回多个结果对象

rpc serverStreamHello(Person) returns (stream Result) {}

  • 客户端流式rpc:客户端传入多个请求对象,服务端返回一个响应结果

rpc clientStreamHello(stream Person) returns (Result) {}

  • 双向流式rpc:可以传入多个对象,返回多个响应对象

rpc biStreamHello(stream Person) returns (stream Result) {}

案例

simple.proto

syntax = "proto3";
package testRPC;service testRPC {rpc simple (emit) returns (on) {}rpc serverStream (emit) returns (stream on){}rpc clientStream (stream emit) returns (on){}rpc bothStream (stream emit) returns (stream on){}
}message emit{string type = 1;string name = 2;
}message on{string type = 1;int32 age = 2;
}

service

package mainimport ("net""google.golang.org/grpc"pb "google.golang.org/grpc/examples/test/proto""google.golang.org/grpc/reflection""fmt""golang.org/x/net/context""io"
)const (port = ":50051"
)type server struct {
}func (s *server) Simple(ctx context.Context, in *pb.Emit) (*pb.On, error) {return &pb.On{Type: "Hello " + in.Type, Age: 10}, nil
}
func (s *server) ServerStream(in *pb.Emit, stream pb.TestRPC_ServerStreamServer) (error) {for i := 1; i < 10; i++ {if err := stream.Send(&pb.On{Type: "Hello " + in.Type, Age: int32(i)}); err != nil {return err}}return nil
}
func (s *server) ClientStream(stream pb.TestRPC_ClientStreamServer) (error) {var pointCount int32for {_, err := stream.Recv()if err == io.EOF {return stream.SendAndClose(&pb.On{Type: "end",Age:  pointCount,})}pointCount++}
}func (s *server) BothStream(stream pb.TestRPC_BothStreamServer) (error) {for {emit, err := stream.Recv()if err == io.EOF {return nil}fmt.Println(string(emit.Type))for i := 1; i < 3; i++ {if err := stream.Send(&pb.On{Type: emit.Type, Age: int32(i)}); err != nil {return err}}}return nil
}func main() {lis, _ := net.Listen("tcp", port)s := grpc.NewServer()pb.RegisterTestRPCServer(s, &server{})reflection.Register(s)if err := s.Serve(lis); err != nil {fmt.Println("error")}
}

client

package mainimport ("google.golang.org/grpc"pb "google.golang.org/grpc/examples/test/proto""golang.org/x/net/context""time""log""io"
)const (address = "localhost:50051"
)func main() {conn, _ := grpc.Dial(address, grpc.WithInsecure())defer conn.Close()rpcClient := pb.NewTestRPCClient(conn)testSimple(rpcClient)testServerStream(rpcClient)testClientStream(rpcClient)testBothStream(rpcClient)}func testSimple(client pb.TestRPCClient) {ctx, cancel := context.WithTimeout(context.Background(), time.Second)defer cancel()// simpler, _ := client.Simple(ctx, &pb.Emit{Type: "11"})log.Printf("Greeting: %s", r)
}func testServerStream(client pb.TestRPCClient) {ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)defer cancel()stream, err := client.ServerStream(ctx, &pb.Emit{Type: "Hello "})if err != nil {log.Fatalf("%v.ListFeatures(_) = _, %v", client, err)}for {feature, err := stream.Recv()if err == io.EOF {break}if err != nil {log.Fatalf("%v.ListFeatures(_) = _, %v", client, err)}log.Println(feature)}
}func testClientStream(client pb.TestRPCClient) {ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)defer cancel()stream, err := client.ClientStream(ctx)if err != nil {log.Fatalf("%v.RecordRoute(_) = _, %v", client, err)}var points []pb.Emitfor i := 0; i < 10; i++ {points = append(points, pb.Emit{Type: "t", Name: string(i)})}for _, point := range points {if err := stream.Send(&point); err != nil {log.Fatalf("%v.Send(%v) = %v", stream, point, err)}}reply, err := stream.CloseAndRecv()if err != nil {log.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil)}log.Printf("Route summary: %v", reply)
}func testBothStream(client pb.TestRPCClient) {ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)defer cancel()stream, err := client.BothStream(ctx)if err != nil {log.Fatalf("%v.RecordRoute(_) = _, %v", client, err)}var points []pb.Emitfor i := 0; i < 10; i++ {points = append(points, pb.Emit{Type: "xiaoming"+string(i), Name: "xiaohong"})}waitc := make(chan struct{})go func() {for {on, err := stream.Recv()if err == io.EOF {// read done.close(waitc)return}if err != nil {log.Fatalf("Failed to receive a note : %v", err)}log.Printf("Got message %s = %d)", on.Type, on.Age)}}()for _, point := range points {if err := stream.Send(&point); err != nil {log.Fatalf("Failed to send a note: %v", err)}}stream.CloseSend()<-waitc
}

【go网络编程】-RPC编程相关推荐

  1. 网络编程 -- RPC实现原理 -- RPC -- 迭代版本V3 -- 远程方法调用 整合 Spring

    网络编程 -- RPC实现原理 -- 目录 啦啦啦 V3--RPC -- 远程方法调用 及 null的传输 + Spring 服务提供商: 1. 配置 rpc03_server.xml 注入 服务提供 ...

  2. 网络编程 -- RPC实现原理 -- RPC -- 迭代版本V4 -- 远程方法调用 整合 Spring 自动注册...

    网络编程 -- RPC实现原理 -- 目录 啦啦啦 V4--RPC -- 远程方法调用 + Spring 自动注册 服务提供商: 1. 配置 rpc04_server.xml 注入 服务提供商 rpc ...

  3. note-PythonCookbook-第十一章 网络与WEB编程

    第十一章 网络与WEB编程 11.1 作为客户端与HTTP服务交互 requests模块 11.2 创建 TCP 服务器 简单的应答服务器 from socketserver import BaseR ...

  4. RPC编程:RPC概述和架构演变

    RPC编程系列文章第一篇 一:引言 1:本系列文章的目标 2:RPC的概念 二:架构的演变过程 1:单体架构 1):概念 2):特点 3):优缺点 2:单体架构水平扩展 1):水平拓展的含义 2):水 ...

  5. RPC编程:Hessian RPC一个老的RPC框架(一)

    RPC编程:Hessian RPC一个老的RPC框架 一:Hessian RPC 1:Hession RPC一个老的RPC框架 2:老,为什么还要研究? 3:Hession RPC概念 二:Hessi ...

  6. Windows RPC编程详解(好好学习)

    一.什么是远程过程调用 什么是远程过程调用 RPC(Remote Procedure Call)? 你可能对这个概念有点陌生, 而你可能非常熟悉 NFS, 是的, NFS 就是基于 RPC 的. 为了 ...

  7. 软件工程网络15结对编程作业

    软件工程网络15结对编程作业 1.项目成员 学号:201521123014 博客地址:http://www.cnblogs.com/huangsh/ 学号: 201521123102 博客地址:htt ...

  8. 推荐一本书《网络机器人java编程指南》

    如果对搜索引擎感兴趣,推荐给大家一本书,Jeff Heaton的<网络机器人java编程指南>.中文版,E文不好的这下不用头痛了.有需要的,可以留言给我. Jeff Heaton is a ...

  9. 转:java网络编程-HTTP编程

    转自: java网络编程-HTTP编程_Stillsings的博客-CSDN博客HTTP编程Java HTTP编程支持模拟成浏览器的方式去访问网页URL, Uniform Resource Locat ...

  10. java的网络功能与编程_Java的网络功能与编程(转载)

    Java的 网络 功能与编程 徐迎晓 (上海大学计算中心25#) 摘  要:Java语言是Internet上最热门的编程语言,本文针对 Java的 网络 功能,对Java从 网络 上获取图象.声音. ...

最新文章

  1. R语言使用ggplot2包使用geom_violin函数绘制分组小提琴图(配置显示均值、标准偏差)实战
  2. linux安装node js的二进制文件安装方式的注意事项
  3. jquery焦点事件
  4. ios NSString 正则表达式 其它字符
  5. SpringBoot - 构建监控体系02_定义度量指标和 Actuator 端点
  6. animiz动画制作软件_实用动画制作软件分享——万彩动画大师
  7. 关于C# this 指针
  8. Web前端笔试面试题汇总(转自github)
  9. Apple Catching POJ - 2385(基础的动态规划算法)
  10. java的整型_java 整型
  11. 修图必备:Photosho 2022 for Mac
  12. 使用vs2005经验与教训(关于masterpage,menu,gridview及对exce的l操作)
  13. 常用的几种视频格式(最详细的解释)
  14. HDU 6287 口算训练(分解质因子 + 二分下标)
  15. 1.3中国计算机网络发展情况
  16. AUTOSAR架构中的配置文件
  17. 刚刚开始学AT89S52单片机遇到的一些小问题 + 个人解决办法
  18. SyntaxError: Missing parentheses in call to 'print' 问题原因
  19. 史上最简单的 MySQL 教程(十四)「列属性 之 主键」
  20. 嵌入式系统基础及知识及接口技术总结

热门文章

  1. WinSock网络编程实用宝典(一)
  2. Linux文件的切分和结合
  3. Win32汇编ListBox最简Demo
  4. Windows下使用MinGw和gcc构建第一个C程序、g++构建第一个C++程序
  5. Java SSH 集成框架开发中的错误解决
  6. 利用Web Services开发分布式应用
  7. 《Data-Intensive Text Processing with mapReduce》读书笔记之一:前言
  8. CSS样式中” 大于号”
  9. 批处理相对路径51CTO自动领豆(Python)
  10. 路要怎么走?关于程序员成长的一点思考