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