MST

星途 面试题库

面试题:微服务架构中gRPC错误处理机制基础

在gRPC微服务架构里,简述gRPC内置的错误码体系,以及如何在服务端设置特定的错误码返回给客户端?
48.0万 热度难度
后端开发微服务架构

知识考点

AI 面试

面试题答案

一键面试

gRPC内置错误码体系

  1. OK (0):表示操作成功。这是最常见的成功状态码。
  2. CANCELLED (1):操作被取消,通常是由调用方主动取消操作导致,比如客户端在请求过程中调用了取消请求的方法。
  3. UNKNOWN (2):未知错误。当遇到无法归类的错误时使用,可能是程序内部逻辑错误或其他未预料到的情况。
  4. INVALID_ARGUMENT (3):表示客户端传递的参数无效。例如参数类型错误、参数缺失或参数值不符合预期范围等。
  5. DEADLINE_EXCEEDED (4):操作超时。无论是客户端设置的截止时间(deadline)到了,还是服务端处理请求的时间过长超过了内部限制,都会返回此错误码。
  6. NOT_FOUND (5):请求的资源不存在。比如请求获取某个特定ID的资源,但该资源在数据库中未找到。
  7. ALREADY_EXISTS (6):试图创建一个已经存在的资源。例如创建一个唯一标识的用户,但该用户ID已在系统中存在。
  8. PERMISSION_DENIED (7):调用方没有权限执行该操作。可能是未进行身份验证,或者经过身份验证但权限不足。
  9. RESOURCE_EXHAUSTED (8):资源耗尽。可能是系统内存、文件句柄等资源不足,无法继续处理请求。
  10. FAILED_PRECONDITION (9):前置条件失败。例如在执行某个操作前需要满足特定条件(如文件必须存在、用户必须处于特定状态等),但这些条件未满足。
  11. ABORTED (10):操作被中止,通常是由于并发冲突导致。比如在分布式系统中,对同一个资源的并发修改操作可能会导致其中某些操作被中止。
  12. OUT_OF_RANGE (11):操作数超出范围。例如索引超出数组界限、数值超出允许的取值范围等。
  13. UNIMPLEMENTED (12):请求的方法未实现。服务端可能尚未实现客户端请求调用的特定方法。
  14. INTERNAL (13):内部错误。这表示服务端内部发生错误,通常是代码逻辑错误、数据库连接问题等,不应该由客户端导致。
  15. UNAVAILABLE (14):服务当前不可用。可能是服务正在重启、网络故障或过载等原因导致无法处理请求。
  16. DATA_LOSS (15):发生数据丢失错误,通常是由于存储系统故障或数据损坏等严重问题导致。

在服务端设置特定错误码返回给客户端

在不同的编程语言中,设置特定错误码返回给客户端的方式略有不同,但基本思路类似。以Go语言为例:

  1. 导入必要的包
import (
    "google.golang.org/grpc/codes"
    "google.golang.org/grpc/status"
)
  1. 设置错误码并返回
func (s *YourServiceServer) YourMethod(ctx context.Context, in *YourRequest) (*YourResponse, error) {
    // 检查参数
    if in.SomeField == "" {
        return nil, status.Error(codes.InvalidArgument, "SomeField cannot be empty")
    }

    // 其他业务逻辑
    // 如果发生错误,例如资源未找到
    if!resourceExists {
        return nil, status.Error(codes.NotFound, "The requested resource was not found")
    }

    // 操作成功返回
    return &YourResponse{Result: "success"}, nil
}

在Java中:

  1. 导入必要的类
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
  1. 设置错误码并返回
public class YourServiceImpl extends YourServiceGrpc.YourServiceImplBase {
    @Override
    public void yourMethod(YourRequest request, StreamObserver<YourResponse> responseObserver) {
        // 检查参数
        if (request.getSomeField().isEmpty()) {
            responseObserver.onError(Status.INVALID_ARGUMENT.withDescription("SomeField cannot be empty").asRuntimeException());
            return;
        }

        // 其他业务逻辑
        // 如果发生错误,例如资源未找到
        if (!resourceExists) {
            responseObserver.onError(Status.NOT_FOUND.withDescription("The requested resource was not found").asRuntimeException());
            return;
        }

        // 操作成功返回
        YourResponse response = YourResponse.newBuilder().setResult("success").build();
        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
}