gRPC框架

1、gRPC 与 Protobuf 介绍

  • 微服务架构中,由于每个服务对应的代码库是独立运行的,无法直接调用,彼此间
    的通信就是个大问题
  • gRPC 可以实现微服务, 将大的项目拆分为多个小且独立的业务模块, 也就是服务,
    各服务间使用高效的protobuf 协议进行RPC 调用, gRPC 默认使用protocol buffers,
    这是 google 开源的一套成熟的结构数据序列化机制(当然也可以使用其他数据格
    式如JSON)
  • 可以用 proto files 创建 gRPC 服务,用 message 类型来定义方法参数和返回类型

参考文章:gRPC教程

2、Mac下安装Protobuf和gRPC

参考文章:https://cloud.tencent.com/developer/article/2163004

brew命令安装

1. 安装的是 gRPC 的核心库
brew install grpc

2. 安装的是protocol编译器
brew install protobuf

3. 各个语言的代码生成工具,对于 Golang 来说,称为 protoc-gen-go
brew install protoc-gen-go
brew install protoc-gen-go-grpc

查看安装是否成功

apple@appledeMacBook-Pro ~ % protoc --version
libprotoc 25.1
apple@appledeMacBook-Pro ~ % protoc-gen-go --version
protoc-gen-go v1.31.0
apple@appledeMacBook-Pro ~ % protoc-gen-go-grpc --version
protoc-gen-go-grpc 1.3.0

如果查不到指令,检查一下环境变量

export GOPATH="/Users/apple/go"
export PATH=$PATH:$GOPATH/bin

3、Demo1

3.1 目录结构

实现服务端和客户端的数据传输

├── client
│   └── client.go
├── go.mod
├── go.sum
├── proto
│   └──  user.proto
└── server
    └── server.go

3.2 user.proto编写

// 编译指令:protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative proto/user.proto

// 版本号
syntax = "proto3";

// 生成文件所在的目录
option go_package="/proto";

// 制定生成 user.pb.go 的包名
package proto;

// 定义message服务端响应的数据格式,相当于结构体,
message UserInfoResponse {
    // 定义字段,相当于结构体的属性
    int32 id = 1;
    string name = 2;
    int32 age = 3;
    // 字段修饰符,repeated表示可以重复出现,就是可变数组,类似于切片类型
    repeated string hobbies = 4;
}

// 定义message客户端请求的数据格式,相当于结构体,
message UserInfoRequest {
    // 定义字段,相当于结构体的属性
    string name = 1;
}

// 定义一个service服务,相当于接口
service UserInfoService {
    // 定义一个rpc方法,相当于接口方法
    // 定义请求参数为UserInfoRequest,返回值为UserInfoResponse
    rpc GetUserInfo(UserInfoRequest) returns (UserInfoResponse);
}

执行编译指令

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative proto/user.proto

这是一个使用 Protocol Buffers(protobuf)和 Go gRPC 插件生成代码的示例命令。该命令根据 proto/user.proto 文件生成对应的 Go 代码。

这个命令的参数含义如下:

--go_out=.:指定生成的 Go 代码输出目录为当前目录。
--go_opt=paths=source_relative:设置生成的 Go 代码中的导入路径为相对于源文件的相对路径。
--go-grpc_out=.:指定生成的 Go gRPC 代码输出目录为当前目录。
--go-grpc_opt=paths=source_relative:设置生成的 Go gRPC 代码中的导入路径为相对于源文件的相对路径。
proto/user.proto:指定要生成代码的 protobuf 文件路径。

最后会在proto目录下生成user.pb.go和user_grpc.pb.go

  • user.pb.go:这个文件包含了用户自定义的消息类型的定义,它描述了在通信过程中需要传输的数据结构,比如用户信息、请求参数等。
  • user_grpc.pb.go:这个文件包含了用户自定义的服务接口的定义,它描述了可以远程调用的方法和参数,以及返回值等。

3.3 server服务端

package main

import (
	"context"
	"fmt"
	pb "main/proto"
	"net"

	"google.golang.org/grpc"
)

// 定义服务端实现约定的接口
type UserInfoService struct {
	pb.UnimplementedUserInfoServiceServer
}

// 实现服务端需要实现的接口
func (s *UserInfoService) GetUserInfo(ctx context.Context, req *pb.UserInfoRequest) (resp *pb.UserInfoResponse, err error) {

	// 服务端接收参数name,再进行业务操作
	name := req.Name

	if name == "zs" {
		resp = &pb.UserInfoResponse{
			Id:      1,
			Name:    name,
			Age:     18,
			Hobbies: []string{"swimming", "running"},
		}
	}

	err = nil
	return
}

func main() {
	// 1. 监听
	addr := "127.0.0.1:8080"
	lis, err := net.Listen("tcp", addr)
	if err != nil {
		fmt.Println("监听异常, err = ", err)
		return
	}

	fmt.Println("开始监听:", addr)

	// 2. 实例化gRPC
	s := grpc.NewServer()

	// 3. 在gRPC上注册微服务,第二个参数要接口类型的变量
	pb.RegisterUserInfoServiceServer(s, &UserInfoService{})

	// 4. 启动gRPC服务端
	s.Serve(lis)
}

3.4 client客户端

package main

import (
	"context"
	"fmt"
	pb "main/proto"

	"google.golang.org/grpc"
	//"google.golang.org/grpc/credentials/insecure"
)

func main() {
	// 1. 创建与gRPC服务器的连接
	addr := "127.0.0.1:8080"
	conn, err := grpc.Dial(addr, grpc.WithInsecure())
	if err != nil {
		fmt.Println("连接异常, err = ", err)
		return
	}
	defer conn.Close()

	// 2. 实例化gRPC客户端
	client := pb.NewUserInfoServiceClient(conn)

	// 3. 组装参数
	req := new(pb.UserInfoRequest)
	req.Name = "zs"

	// 4. 调用接口
	resp, err := client.GetUserInfo(context.Background(), req)
	if err != nil {
		fmt.Println("响应异常, err = ", err)
		return
	}
	fmt.Println("响应结果, resp = ", resp)
}

3.5 编译

先执行服务端,再执行客户端
在这里插入图片描述

4、Demo2

4.1 目录结构

├── client
│   └── client.go
├── go.mod
├── go.sum
├── proto
│   └── hello.proto
└── server
    └── server.go

4.2 hello.proto

// 编译指令:protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative proto/hello.proto

syntax = "proto3";

option go_package="/proto";

package Business;

service Hello {
  rpc Say (SayRequest) returns (SayResponse);
}

message SayResponse {
  string Message = 1;
}

message SayRequest {
  string Name = 1;
}

4.3 server服务端

package main

import (
	"context"
	"fmt"
	"google.golang.org/grpc"
	"main/proto"
	"net"
)

type server struct {
	proto.UnimplementedHelloServer
}

func (s *server) Say(ctx context.Context, req *proto.SayRequest) (*proto.SayResponse, error) {
	fmt.Println("request:", req.Name)
	return &proto.SayResponse{Message: "Hello " + req.Name}, nil
}

func main() {
	listen, err := net.Listen("tcp", ":8001")
	if err != nil {
		fmt.Printf("failed to listen: %v", err)
		return
	}
	s := grpc.NewServer()
	proto.RegisterHelloServer(s, &server{})
	//reflection.Register(s)

	defer func() {
		s.Stop()
		listen.Close()
	}()

	fmt.Println("Serving 8001...")
	err = s.Serve(listen)
	if err != nil {
		fmt.Printf("failed to serve: %v", err)
		return
	}
}

4.4 client客户端

package main

import (
	"bufio"
	"context"
	"fmt"
	"main/proto"
	"os"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
)

func main() {

	var serviceHost = "127.0.0.1:8001"

	conn, err := grpc.Dial(serviceHost, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		fmt.Println(err)
	}
	defer conn.Close()

	client := proto.NewHelloClient(conn)
	rsp, err := client.Say(context.TODO(), &proto.SayRequest{
		Name: "BOSIMA",
	})

	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(rsp)

	fmt.Println("按回车键退出程序...")
	in := bufio.NewReader(os.Stdin)
	_, _, _ = in.ReadLine()
}

4.5 编译

在这里插入图片描述

  • 17
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
grpc框架是一种非常适合Java开发者使用的框架,它可以通过下载后解压并直接安装来使用,非常方便。在使用grpc框架时,可以使用java_outer_classname参数来指定包含message描述的Java文件的类名。 要在Java中使用grpc框架,可以按照以下步骤进行操作: 1. 下载并安装grpc框架。 2. 解压安装包并配置环境变量。 3. 在Java代码中引入所需的依赖库。 4. 编写服务端代码,监听指定的端口,并处理客户端请求。 5. 编写客户端代码,连接到服务端,并发送请求。 6. 运行代码,如果没有异常,则会输出相关的信息。 一个示例的Java代码可以是这样的: ```java package com.example.grpc; public class HelloWorldApp { public static void main(String[] args) throws Exception { int port = 8000; GrpcServer server = new GrpcServer(port); server.start(); HelloWorldClient client = new HelloWorldClient("localhost", port); String reply = client.sayHello("HanMeiMei"); System.out.println(reply); server.shutdown(); } } ``` 在上述代码中,我们首先创建了一个GrpcServer实例来监听指定的端口,并启动服务端。然后创建了一个HelloWorldClient实例来连接到服务端,并发送了一个名为"HanMeiMei"的请求。最后,我们打印出服务端返回的响应信息。 这样,我们就可以使用grpc框架在Java中进行开发了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [java grpc框架](https://download.csdn.net/download/wwq6873513/10720487)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [在JAVA中使用gRPC](https://blog.csdn.net/fly_time2012/article/details/113108060)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闲谈社

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值