我有一个与许多其他 GRPC 服务器通信的 GRPC 服务器。因此,我的服务器是许多其他 GRPC 服务器的客户端,我想测试我的服务器实现,但我一直坚持如何模拟 GRPC 客户端。
我有一个来自我的 GRPC 服务器的方法,如下所示:
func (s UserBackendServer) UpdateUser(ctx context.Context, req *api.UpdateUserRequest) (*api.User, error) {
conn, err := grpc.DialContext(ctx, s.userSvcAddr,
grpc.WithInsecure(),
grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))
if err != nil {
return nil, fmt.Errorf("could not connect shipping service: %+v", err)
}
defer conn.Close()
user, err := api.NewUserServiceClient(conn).
UpdateUser(ctx, &api.UpdateUserRequest{
User: nil,
UserId: "",
})
return user, nil
}
在这种类型的实现中,我不能模拟 UserServiceClient 因为我在方法中创建了一个:(
我想了两种方法来解决这个问题
UserBackendServer
在结构内有客户端引用
type UserBackendServer struct {
projectID string
userSvcClient api.UserServiceClient
}
func (s UserBackendServer) UpdateUser(ctx context.Context, req *api.UpdateUserRequest) (*api.User, error) {
conn, err := grpc.DialContext(ctx, s.userSvcAddr,
grpc.WithInsecure(),
grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))
if err != nil {
return nil, fmt.Errorf("could not connect shipping service: %+v", err)
}
defer conn.Close()
user, err := s.userSvcClient.UpdateUser(ctx, &api.UpdateUserRequest{
User: nil,
UserId: "",
})
return user, nil
}
有了这个实现,我就有了与客户端保持持续活动连接的副作用(我有 10 个客户端可以与之通信)。生产环境好吗?拥有始终连接的客户端会导致内存泄漏或过多的并发连接吗?
- 使用将客户端作为参数的方法
func (s UserBackendServer) UpdateUser(ctx context.Context, req *api.UpdateUserRequest) (*api.User, error) {
conn, err := grpc.DialContext(ctx, s.userSvcAddr,
grpc.WithInsecure(),
grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))
if err != nil {
return nil, fmt.Errorf("could not connect shipping service: %+v", err)
}
defer conn.Close()
client := api.NewUserServiceClient(conn)
updateUser(ctx, req.UserId, req.User, client)
user, err := s.userSvcClient.UpdateUser(ctx, &api.UpdateUserRequest{
User: nil,
UserId: "",
})
return user, nil
}
func updateUser(ctx context.Context, userId string, user *api.User, client api.UserServiceClient) (*api.User, error){
userUpdated, err := client.UpdateUser(ctx, &api.UpdateUserRequest{
User: nil,
UserId: "",
})
return userUpdated, err
}
编写所有这些小功能似乎有点麻烦,我无法对服务器功能进行单元测试。
一号战略可行吗?如果连接保持在服务器结构中,您是否有关于限制或如何重试失败连接的经验