grpc基础-1.初识grpc

说到grpc,大部分是在微服务之间的服务调用中使用

所以就得了解单体架构和微服务架构

单体架构

  1. 只能对整体扩容,伸缩
  2. 一荣俱荣,一损俱损
  3. 代码耦合,项目的开发者往往需要知道整个系统的流程

微服务架构

可以按照服务进行单独扩容,升级

各个服务之间可独立开发,独立部署

传统rpc

服务端

package main

import (
  "fmt"
  "net"
  "net/http"
  "net/rpc"
)

type Server struct {
}
type Req struct {
  Num1 int
  Num2 int
}
type Res struct {
  Num int
}

func (s Server) Add(req Req, res *Res) error {
  res.Num = req.Num1 + req.Num2
  return nil
}

func main() {
  // 注册rpc服务
  rpc.Register(new(Server))
  rpc.HandleHTTP()
  listen, err := net.Listen("tcp", ":8080")
  if err != nil {
    fmt.Println(err)
    return
  }
  http.Serve(listen, nil)
}

客户端

package main

import (
  "fmt"
  "net/rpc"
)

type Req struct {
  Num1 int
  Num2 int
}
type Res struct {
  Num int
}

func main() {
  req := Req{1, 2}
  client, err := rpc.DialHTTP("tcp", ":8080")
  if err != nil {
    fmt.Println(err)
    return
  }
  var res Res
  client.Call("Server.Add", req, &res)
  fmt.Println(res)
}

原生rpc的问题:

  1. 编写相对复杂,需要自己去关注实现过程
  2. 没有代码提示,容易写错

grpc模式

编写protobuf文件

syntax = "proto3"; // 指定proto版本
package hello_grpc;     // 指定默认包名

// 指定golang包名
option go_package = "/hello_grpc";

//定义rpc服务
service HelloService {
  // 定义函数
  rpc SayHello (HelloRequest) returns (HelloResponse) {}
}

// HelloRequest 请求内容
message HelloRequest {
  string name = 1;
  string message = 2;
}

// HelloResponse 响应内容
message HelloResponse{
  string name = 1;
  string message = 2;
}

proto文件没有高亮的话去下载一个grpc的插件

在grpc_proto目录下执行

protoc -I . --go_out=plugins=grpc:. .\hello.proto

或者在根目录下执行

protoc -I . --go_out=plugins=grpc:.\grpc_proto .\grpc_proto\hello.proto

我们可以编写一个bat文件,方便转换

set.bat

protoc -I . --go_out=plugins=grpc:.\grpc_proto .\grpc_proto\hello.proto

服务端

  1. 编写一个结构体,名字叫什么不重要
  2. 重要的是得实现protobuf中的所有方法
  3. 监听端口
  4. 注册服务
package main

import (
  "context"
  "fmt"
  "google.golang.org/grpc"
  "google.golang.org/grpc/grpclog"
  "grpc_study/grpc_proto/hello_grpc"
  "net"
)

// HelloServer1 得有一个结构体,需要实现这个服务的全部方法,叫什么名字不重要
type HelloServer1 struct {
}

func (HelloServer1) SayHello(ctx context.Context, request *hello_grpc.HelloRequest) (pd *hello_grpc.HelloResponse, err error) {
  fmt.Println("入参:", request.Name, request.Message)
  pd = new(hello_grpc.HelloResponse)
  pd.Name = "你好"
  pd.Message = "ok"
  return
}

func main() {
  // 监听端口
  listen, err := net.Listen("tcp", ":8080")
  if err != nil {
    grpclog.Fatalf("Failed to listen: %v", err)
  }
  
  // 创建一个gRPC服务器实例。
  s := grpc.NewServer()
  server := HelloServer1{}
  // 将server结构体注册为gRPC服务。
  hello_grpc.RegisterHelloServiceServer(s, &server)
  fmt.Println("grpc server running :8080")
  // 开始处理客户端请求。
  err = s.Serve(listen)
}

客户端

  1. 建立连接
  2. 调用方法
package main

import (
  "context"
  "fmt"
  "google.golang.org/grpc"
  "google.golang.org/grpc/credentials/insecure"
  "grpc_study/grpc_proto/hello_grpc"
  "log"
)

func main() {
  addr := ":8080"
  // 使用 grpc.Dial 创建一个到指定地址的 gRPC 连接。
  // 此处使用不安全的证书来实现 SSL/TLS 连接
  conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
  if err != nil {
    log.Fatalf(fmt.Sprintf("grpc connect addr [%s] 连接失败 %s", addr, err))
  }
  defer conn.Close()
  // 初始化客户端
  client := hello_grpc.NewHelloServiceClient(conn)
  result, err := client.SayHello(context.Background(), &hello_grpc.HelloRequest{
    Name:    "枫枫",
    Message: "ok",
  })
  fmt.Println(result, err)
}

如果需要经常操作这个连接对象,我们可以复用

func initClient() hello_grpc.HelloServiceClient {
  addr := ":8080"
  conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
  if err != nil {
    log.Fatalf(fmt.Sprintf("grpc connect addr [%s] 连接失败 %s", addr, err))
  }
  client := hello_grpc.NewHelloServiceClient(conn)
  return client
}

func main() {
  client := initClient()
  result, err := client.SayHello(context.Background(), &hello_grpc.HelloRequest{
    Name:    "枫枫",
    Message: "ok",
  })
  result, err = client.SayHello(context.Background(), &hello_grpc.HelloRequest{
    Name:    "哈哈哈",
    Message: "ok1",
  })
  
  fmt.Println(result, err)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值