2017-05-02 3 views
2

私は以下が良いか悪いのかを理解しようとしています。Goで複数のデータベースに接続するとよいでしょうか?

これが正常/正常な習慣であることが判明した場合、私のプロジェクトに複数のデータベースコネクタを実装しやすくなります。

状況:私は、APIサーバを作成し、コールがAPIに行われるたびに、コードのこの部分は実行されます。

ctx := context.Background() 

client, err := datastore.NewClient(ctx, "foobar") 
if err != nil { 
    log.Fatalf("Failed to create client: %v", err) 
} 

サービスは、毎秒多くのリクエストを取得し、私ならば、私はわからないんだけど起動時またはAPIが呼び出されるたびにnewClient()関数を1回だけ実行する必要があります。

PS:
別のコネクタがMySQLの場合、同じことが起こります。

db, err = sql.Open("mysql", "yourusername:[email protected]/yourdatabase") 
if err != nil { 
    panic(err.Error())  
} 
+0

使用するライブラリは、ドキュメントに接続プーリングの実装方法を示す必要があります。 – zerkms

答えて

2

は私がdatastore.Clientわからないんだけど、database.DBは、接続のプールを管理し、同時使用のために安全であり、そしてあなたが本当に呼び出してはいけません:APIが要求を受けるたびに、次のコードが実行されますクエリを実行するたびにdb.Openと入力します。実際には、Open'sの文書の最後の段落にはっきりと記載されています。

返されたDBは、複数のゴルーチンによって同時使用するのが安全であり、 はアイドル状態の接続プールを維持します。したがって、Open関数 は一度だけ呼び出される必要があります。 DBを閉じる必要はほとんどありません。

更新

あなたはdatastoreのドキュメントのBasic Operationsセクションのサンプルコード内のコメントを見てみる場合は、推奨される使用を見つけることができます。

データストアクライアントを作成します。典型的なアプリケーションでは、 という単一のクライアントを作成し、すべてのデータストア の操作で再利用します。

+0

ありがとう、@ mkopriva(もう一度、笑)。私はすでにこれが答えであることを恐れていた。今私は複数のデータベースを扱う方法を理解する必要があるので、 - P –

0

私はGoogle Datastoreでの経験はありませんが、database/sqlパッケージと同じように設計されていると思います。その場合、接続が遅延して初期化され、パラメータが検証されないため、すべての要求に対してsql.Openを使用するのはひどいことではありません。しかし同時に使用することが安全であるため、再利用するほうがはるかに優れています。

データベースの終了時にClose()を行うのは慣習的ですが、sql.DBオブジェクトは長期間使用できるように設計されています。 Open()およびClose()データベースを頻繁に開かないでください。代わりに、アクセスする必要のある個別のデータストアごとに1つのsql.DBオブジェクトを作成し、そのデータストアへのアクセスが完了するまで保存します。必要に応じてそれを渡すか、何とかグローバルに利用できるようにしますが、開いたままにしておきます。そして、短命の関数からOpen()とClose()をしないでください。代わりに、その短命関数にsql.DBを引数として渡します。

sql.DBを長期間使用するオブジェクトとして扱わない場合、再利用や接続の共有、使用可能なネットワークリソースの不足、TCPの多くによる散発的な障害などの問題が発生する可能性があります接続はTIME_WAIT状態のままです。このような問題は、設計時にデータベース/ SQLを使用していないという兆候です。それは接続数の制限なしで接続プールによって支えられて、デフォルトでhttp://go-database-sql.org/accessing.html

:から

。だから、十分な同時性のgoroutinesでそれを飢えさせるかもしれません。ただし、プールのサイズをかなり簡単に制限することができます。http://go-database-sql.org/connection-pool.html

0

これは基本的な回答ですが、ここではそれが価値があります。

datastoreのすべてのニーズに、パッケージgithub.com/mjibson/goonを使用してください。 GetPutのような通話は本当にうまくまとめられ、マーシャル/アンマーシャルはstructsになります。それはまた、memcacheを介して任意の主要なクエリを自動的に実行して物事をスピードアップします。

実際の質問に戻る。 goonでは、各要求時にこれらの2つの行のいずれかを実行するのが適切です。

g := goon.FromContext(c) // if you have Context 
g := goon.NewGoon(req) // if you have http.Request 
関連する問題