предисловие
Привет всем, я 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/Нет...