Go gRPC Series IX: контроль тайм-аута gRPC (сроки)

Go

предисловие

Привет всем, я Jianyu В предыдущих главах было представлено основное использование gRPC. Тогда подумайте об этом, действительно ли нормально позволять ему бегать голым вот так?

Тогда должна быть проблема. Сегодня я расскажу об использовании gRPC Deadlines, обязательного навыка. Содержание также относительно простое.

Deadlines

Крайние сроки означают крайние сроки, подчеркивая TL; DR (слишком долго, не читать) в gRPC и рекомендуяВсегда устанавливайте крайний срок,Зачем?

зачем устанавливать

Если крайние сроки не установлены, будет использоваться значение по умолчанию DEADLINE_EXCEEDED (на этот раз очень большое)

Если есть блокирующее ожидание, будет зарезервировано большое количество текущих запросов, и все запросы могут достичь максимального времени ожидания.

Это подвергает службу риску исчерпания ресурсов, таких как память, что увеличивает задержку для службы или, в худшем случае, может привести к сбою всего процесса.

gRPC

Client

func main() {
    ...
	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Duration(5 * time.Second)))
	defer cancel()

	client := pb.NewSearchServiceClient(conn)
	resp, err := client.Search(ctx, &pb.SearchRequest{
		Request: "gRPC",
	})
	if err != nil {
		statusErr, ok := status.FromError(err)
		if ok {
			if statusErr.Code() == codes.DeadlineExceeded {
				log.Fatalln("client.Search err: deadline")
			}
		}

		log.Fatalf("client.Search err: %v", err)
	}

	log.Printf("resp: %s", resp.GetResponse())
}
  • context.WithDeadline: возвращает окончательный крайний срок контекста. Первый параметр — это родительский контекст, а второй параметр — скорректированный крайний срок. Если родительское время предшествует дочернему, родительское время имеет преимущественную силу, в противном случае дочернее время является окончательным сроком.
func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {
	if cur, ok := parent.Deadline(); ok && cur.Before(d) {
		// The current deadline is already sooner than the new one.
		return WithCancel(parent)
	}
	c := &timerCtx{
		cancelCtx: newCancelCtx(parent),
		deadline:  d,
	}
	propagateCancel(parent, c)
	dur := time.Until(d)
	if dur <= 0 {
		c.cancel(true, DeadlineExceeded) // deadline has already passed
		return c, func() { c.cancel(true, Canceled) }
	}
	c.mu.Lock()
	defer c.mu.Unlock()
	if c.err == nil {
		c.timer = time.AfterFunc(dur, func() {
			c.cancel(true, DeadlineExceeded)
		})
	}
	return c, func() { c.cancel(true, Canceled) }
}
  • context.WithTimeout: еще один очень распространенный метод — удобная операция. На самом деле это оболочка для WithDeadline.
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
	return WithDeadline(parent, time.Now().Add(timeout))
}
  • status.FromError: возвращает конкретный код ошибки GRPCStatus, если он недопустим, возвращается напрямую.codes.Unknown

Server

type SearchService struct{}

func (s *SearchService) Search(ctx context.Context, r *pb.SearchRequest) (*pb.SearchResponse, error) {
	for i := 0; i < 5; i++  {
		if ctx.Err() == context.Canceled {
			return nil, status.Errorf(codes.Canceled, "SearchService.Search canceled")
		}

		time.Sleep(1 * time.Second)
	}

	return &pb.SearchResponse{Response: r.GetRequest() + " Server"}, nil
}

func main() {
	...
}

На стороне сервера, потому что клиент установил крайний срок. Сервер обязан это обнаружить

В противном случае, если Клиент закончился, Сервер все равно будет там тупо выполняться, что является большой тратой ресурсов.

Так что здесь необходимо использоватьctx.Err() == context.CanceledСудя по всему, для симуляции сцены мы добавили цикл и сон 🤔

проверять

Перезапускаем server.go и client.go и получаем результат:

$ go run client.go
2018/10/06 17:45:55 client.Search err: deadline
exit status 1

Суммировать

Эта глава относительно проста, вам необходимо знать следующие моменты знаний:

  • Как установить сроки
  • Зачем устанавливать сроки

Вы должны четко понимать, что дедлайны gRPC очень важны, иначе эта небольшая особенность убьет ваше производство.

?

Если у вас есть какие-либо вопросы или ошибки, добро пожаловать вissuesЗадавайте вопросы или вносите исправления, если вам нравится или вам помогают, добро пожаловатьStar, является своеобразным поощрением и продвижением автора.

мой блог

Изучите го с жареной рыбой:GitHub.com/Vicious Genetics/Нет...

мой публичный аккаунт

image

Ссылаться на

Пример кода для этой серии