GRPC-сервер не освобождает соединение с БД - PullRequest
0 голосов
/ 06 ноября 2019

Я работаю над проектом Go, который использует gRPC в качестве сервера и Voltdb в качестве БД. У меня проблема при отправке большого количества запросов на чтение / запись БД на сервер gRPC. Запрос был обработан, но он не освобождает соединение с БД после завершения оператора. Поэтому, когда соединение в пуле заканчивается, я получаю эту ошибку:

Отклонено соединение с /127.0.0.1:63015, поскольку достигнут предел соединения 9940

файл прото

syntax = "proto3";
package grpc;

import "google/protobuf/struct.proto";

option java_multiple_files = true;
option java_package = "com.io.test";

service TestService {
    rpc updateUser (UserRequest) returns (Status) {};
}
message UserRequest {
    string userId = 1;
    string name = 2;
}
message Status {
    string code = 1;
}

Реализация Grpc в Go

package service

import (
    "context"
    "log"
    api "testgrpc/pkg/api/grpc"
    "testgrpc/pkg/db"
    "testgrpc/pkg/model"
)

var voltDbClient *db.VoltDBClient

func init() {
    voltDbClient = db.NewVoltDBClient()
}

type GrpcService struct {
}

func NewGrpcService() *GrpcService {
    return &GrpcService{}
}
func (sv *GrpcService) UpdateUser(ctx context.Context, req *api.UserRequest) (*api.Status, error) {
    user, err := voltDbClient.FindByID(req.GetUserId())
    if user == nil || err != nil {
        log.Print("error while reading")
    } else {
        log.Println(user.(*model.User).UserId)
        log.Println(user.(*model.User).Name)
    }
    err = voltDbClient.Put(req.GetUserId(), req.GetName())
    if err != nil {
        log.Print("error while writing")
    }
    return &api.Status{Code: "0"}, nil
}

Клиент БД

package db

import (
    "database/sql"
    "log"

    "testgrpc/pkg/model"

    _ "github.com/VoltDB/voltdb-client-go/voltdbclient"
)

var Db *sql.DB

func init() {
    if Db == nil {
        var err error
        Db, err = sql.Open("voltdb", "localhost:21212")
        if err != nil {
            log.Fatal(err)
        }
        //limit max connection to reproduce issue
        Db.SetMaxOpenConns(20)
    }
}

type VoltDBClient struct {
}

func NewVoltDBClient() *VoltDBClient {
    return &VoltDBClient{}
}

//Put add or update record
func (dbClient *VoltDBClient) Put(key interface{}, value interface{}) error {
    res, err := Db.Exec("GROUPINFO.upsert", key, value)
    if err != nil {
        log.Println(err)
        return err
    }
    rowCnt, err := res.RowsAffected()
    if err != nil {
        log.Println(err)
        return err
    }
    log.Printf("affected = %d\n", rowCnt)
    return nil
}

//FindByID find a record by ID
func (dbClient *VoltDBClient) FindByID(key interface{}) (interface{}, error) {
    rows, err := Db.Query("GROUPSELECT", key)
    if err != nil {
        log.Println(err)
        return nil, err
    }
    for rows.Next() {
        user := model.User{UserId: "", Name: ""}
        err := rows.Scan(&user.UserId, &user.Name)
        if err != nil {
            log.Println(err)
            return nil, err
        }
        return &user, nil
    }
    return nil, nil
}

Примечание: я попытался запустить проект без grpc, операторы чтения / записи работают хорошо.

...