广告
返回顶部
首页 > 资讯 > 后端开发 > GO >Go gRPC进阶教程服务超时设置
  • 1004
分享到

Go gRPC进阶教程服务超时设置

2024-04-02 19:04:59 1004人浏览 独家记忆
摘要

目录前言客户端请求设置超时时间服务端判断请求是否超时运行结果总结前言 grpc默认的请求的超时时间是很长的,当你没有设置请求超时时间时,所有在运行的请求都占用大量资源且可能运行很长的

前言

grpc默认的请求的超时时间是很长的,当你没有设置请求超时时间时,所有在运行的请求都占用大量资源且可能运行很长的时间,导致服务资源损耗过高,使得后来的请求响应过慢,甚至会引起整个进程崩溃。

为了避免这种情况,我们的服务应该设置超时时间。

前面的入门教程

Go grpc环境安装教程示例详解

Go gRPC教程实现Simple RPC

Go gRPC服务端流式RPC教程示例

Go gRPC服务客户端流式RPC教程

Go gRPC服务双向流式RPC教程

提到当客户端发起请求时候,需要传入上下文context.Context,用于结束超时或取消的请求。

本篇以简单RPC为例,介绍如何设置gRPC请求的超时时间。

客户端请求设置超时时间

修改调用服务端方法

1.把超时时间设置为当前时间+3秒

	clientDeadline := time.Now().Add(time.Duration(3 * time.Second))
	ctx, cancel := context.WithDeadline(ctx, clientDeadline)
	defer cancel()

2.响应错误检测中添加超时检测

       // 传入超时时间为3秒的ctx
	res, err := grpcClient.Route(ctx, &req)
	if err != nil {
		//获取错误状态
		statu, ok := status.FromError(err)
		if ok {
			//判断是否为调用超时
			if statu.Code() == codes.DeadlineExceeded {
				log.Fatalln("Route timeout!")
			}
		}
		log.Fatalf("Call Route err: %v", err)
	}
	// 打印返回值
	log.Println(res.Value)

完整的client.go代码

package main
import (
	"context"
	"log"
	"time"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	pb "go-grpc-example/6-grpc_deadlines/proto"
)
// Address 连接地址
const Address string = ":8000"
var grpcClient pb.SimpleClient
func main() {
	// 连接服务器
	conn, err := grpc.Dial(Address, grpc.WithInsecure())
	if err != nil {
		log.Fatalf("net.Connect err: %v", err)
	}
	defer conn.Close()
	ctx := context.Background()
	// 建立gRPC连接
	grpcClient = pb.NewSimpleClient(conn)
	route(ctx, 2)
}
// route 调用服务端Route方法
func route(ctx context.Context, deadlines time.Duration) {
	//设置3秒超时时间
	clientDeadline := time.Now().Add(time.Duration(deadlines * time.Second))
	ctx, cancel := context.WithDeadline(ctx, clientDeadline)
	defer cancel()
	// 创建发送结构体
	req := pb.SimpleRequest{
		Data: "grpc",
	}
	// 调用我们的服务(Route方法)
	// 传入超时时间为3秒的ctx
	res, err := grpcClient.Route(ctx, &req)
	if err != nil {
		//获取错误状态
		statu, ok := status.FromError(err)
		if ok {
			//判断是否为调用超时
			if statu.Code() == codes.DeadlineExceeded {
				log.Fatalln("Route timeout!")
			}
		}
		log.Fatalf("Call Route err: %v", err)
	}
	// 打印返回值
	log.Println(res.Value)
}

服务端判断请求是否超时

当请求超时后,服务端应该停止正在进行的操作,避免资源浪费。

// Route 实现Route方法
func (s *SimpleService) Route(ctx context.Context, req *pb.SimpleRequest) (*pb.SimpleResponse, error) {
	data := make(chan *pb.SimpleResponse, 1)
	go handle(ctx, req, data)
	select {
	case res := <-data:
		return res, nil
	case <-ctx.Done():
		return nil, status.Errorf(codes.Canceled, "Client cancelled, abandoning.")
	}
}
func handle(ctx context.Context, req *pb.SimpleRequest, data chan<- *pb.SimpleResponse) {
	select {
	case <-ctx.Done():
		log.Println(ctx.Err())
		runtime.Goexit() //超时后退出该Go协程
	case <-time.After(4 * time.Second): // 模拟耗时操作
		res := pb.SimpleResponse{
			Code:  200,
			Value: "hello " + req.Data,
		}
		// //修改数据库前进行超时判断
		// if ctx.Err() == context.Canceled{
		// 	...
		// 	//如果已经超时,则退出
		// }
		data <- &res
	}
}

一般地,在写库前进行超时检测,发现超时就停止工作。

完整server.go代码

package main
import (
	"context"
	"log"
	"net"
	"runtime"
	"time"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	pb "go-grpc-example/6-grpc_deadlines/proto"
)
// SimpleService 定义我们的服务
type SimpleService struct{}
const (
	// Address 监听地址
	Address string = ":8000"
	// Network 网络通信协议
	Network string = "tcp"
)
func main() {
	// 监听本地端口
	listener, err := net.Listen(Network, Address)
	if err != nil {
		log.Fatalf("net.Listen err: %v", err)
	}
	log.Println(Address + " net.Listing...")
	// 新建gRPC服务器实例
	grpcServer := grpc.NewServer()
	// 在gRPC服务器注册我们的服务
	pb.ReGISterSimpleServer(grpcServer, &SimpleService{})
	//用服务器 Serve() 方法以及我们的端口信息区实现阻塞等待,直到进程被杀死或者 Stop() 被调用
	err = grpcServer.Serve(listener)
	if err != nil {
		log.Fatalf("grpcServer.Serve err: %v", err)
	}
}
// Route 实现Route方法
func (s *SimpleService) Route(ctx context.Context, req *pb.SimpleRequest) (*pb.SimpleResponse, error) {
	data := make(chan *pb.SimpleResponse, 1)
	go handle(ctx, req, data)
	select {
	case res := <-data:
		return res, nil
	case <-ctx.Done():
		return nil, status.Errorf(codes.Canceled, "Client cancelled, abandoning.")
	}
}
func handle(ctx context.Context, req *pb.SimpleRequest, data chan<- *pb.SimpleResponse) {
	select {
	case <-ctx.Done():
		log.Println(ctx.Err())
		runtime.Goexit() //超时后退出该Go协程
	case <-time.After(4 * time.Second): // 模拟耗时操作
		res := pb.SimpleResponse{
			Code:  200,
			Value: "hello " + req.Data,
		}
		// //修改数据库前进行超时判断
		// if ctx.Err() == context.Canceled{
		// 	...
		// 	//如果已经超时,则退出
		// }
		data <- &res
	}
}

运行结果

服务端:

:8000 net.Listing...
goroutine still running

客户端:

Route timeout! 

总结

超时时间的长短需要根据自身服务而定,例如返回一个hello grpc,可能只需要几十毫秒,然而处理大量数据的同步操作则可能要很长时间。需要考虑多方面因素来决定这个超时时间,例如系统间端到端的延时,哪些RPC是串行的,哪些是可以并行的等等。

教程源码地址:https://GitHub.com/Bingjian-Zhu/go-grpc-example

参考:Https://grpc.io/blog/deadlines/

以上就是Go gRPC进阶服务超时设置的详细内容,更多关于Go gRPC超时设置的资料请关注编程网其它相关文章!

您可能感兴趣的文档:

--结束END--

本文标题: Go gRPC进阶教程服务超时设置

本文链接: https://www.lsjlt.com/news/151643.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Go gRPC进阶教程服务超时设置
    目录前言客户端请求设置超时时间服务端判断请求是否超时运行结果总结前言 gRPC默认的请求的超时时间是很长的,当你没有设置请求超时时间时,所有在运行的请求都占用大量资源且可能运行很长的...
    99+
    2022-11-13
  • Go gRPC服务进阶middleware使用教程
    目录前言go-grpc-middleware简介grpc_zap日志记录grpc_auth认证grpc_recovery恢复总结前言 之前介绍了gRPC中TLS认证和自定义方法认证,...
    99+
    2022-11-13
  • Go gRPC服务proto数据验证进阶教程
    目录前言创建proto文件,添加验证规则把grpc_validator验证拦截器添加到服务端其他类型验证规则设置总结前言 上篇介绍了go-grpc-middleware的grpc_z...
    99+
    2022-11-13
  • 超云服务器 BIOS 设置教程
    1. 进入 BIOS 界面 首先,开机后按下 DEL 或 F2 键进入 BIOS 界面。 2. 设置启动顺序 在 BIOS 界面中,找到 Boot 选项卡,进入后设置启动顺序。一般情况下,我们需要将启动顺序设置为 UEFI 模式,然后将需...
    99+
    2023-10-27
    服务器 教程 BIOS
  • 超云服务器bios设置教程
    首先,让我们了解超云服务器的基本设置。超云服务器提供了很多选项,包括主板类型、CPU型号、内存类型、存储类型等,用户可以根据自己的需求和使用环境进行选择。 其次,超云服务器的配置非常重要。在安装超云服务器之前,需要确保您的主板、CPU、内...
    99+
    2023-10-28
    服务器 教程 bios
  • 阿里云服务器实时时间设置教程
    在阿里云服务器上,用户需要实时查看和设置服务器的时间,以便于进行各项操作。本文将详细介绍如何在阿里云服务器上实时设置服务器的时间。 在阿里云服务器上,用户需要实时查看和设置服务器的时间,以便于进行各项操作。阿里云服务器的实时时间设置非常简单...
    99+
    2023-11-02
    阿里 实时 服务器
  • 设置服务器ssh远程连接时超时关闭的时间
    我们通过ssh远程连接服务器时,如果一段时间客户端没有使用,就会与服务器断开连接。这个断开的时间我们是可以自己的设置的。 以linux centos系统为例, 具体设置方法如下: 1、通过下面的命令编译sshd配置文件 vim /etc/s...
    99+
    2023-08-22
    服务器 ssh linux 设置ssh远程连接断开时间
  • 怎么使用云服务器进行多开游戏功能设置方法教程
    在云服务器上创建多个云端账号,每个账号对应一个游戏客户端。 在客户端上,通过设置同一设备登录多个账号。例如,可以在每个云端账号上创建一个独立的游戏,每个云端账号只能登录一次。 通过在游戏中添加新的游戏角色,将多个游戏角色组成一个游戏客户端...
    99+
    2023-10-27
    功能 服务器 方法
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作