2017-09-21 8 views
0

まず最初に、私は一般的に並行性についての初心者ですが、最近それについて多くのことを読んでいることを認めなければなりません。私はゴランがその地域で強いと聞いたからです。私はどのように(並行して)サーバがこの言語で書かれているのか尋ねたかったのです。Golangの同時サーバ

つまり、複数の要求/接続を同時に処理できるサーバーを作成する方法にはさまざまな方法があります。スレッド、非同期プログラミング(例えばPythonではasync/asyncio)を使用することができ、Golangには軽量スレッドであるゴルーチンがあります。

しかし、Pythonとasync/asyncioを使用する場合、1つのプロセスと1つのスレッドを持つことができ、同時実行性を処理できます。しかし、コードは複雑です(少なくとも背景なしの私にとっては)。

私の質問: Golangに並行サーバーを作成する方法は何ですか?あらゆる接続のためのちょうど新しいgoroutineか、または非同期の方法がありますか? 「ベストプラクティス」とは何ですか?

高度に使用されているサーバーにたくさんのgoroutinesを持たせるのは費用がかかりませんか? Golangでうまく書かれたサーバーを行うには?

+0

ゴルーチンは軽量で非常に安価です(スレッドと比較して)。 Goランタイムは、何十万ものゴルーチンを効率的に処理することができます。 – icza

+0

この可能な重複:[Goウェブサーバーのプロセス管理](https://stackoverflow.com/questions/37529511/process-management-for-the-go-webserver/37531953#37531953)も参照してください。 – icza

答えて

1

初心者の方には、https://golang.org/pkg/net/http/を使用し、httpハンドラを作成するだけです。 Goルーチンを初期化する必要はありません。http.Serverがそれを行います。

このコードは、通話をブロックすることで簡単に進むことができます。この段階では、Goがあなたのために実行するので、並行性について考える必要はありません。たとえば、

record, err := someDb.GetRecordByID(123) 

のようなコールを実際に実行すると、実際には現在のフローをブロックするが、他のGoルーチンにスレッドを解放する非同期コールです。データが返され、スレッド(以前と異なる可能性があります)が利用可能になると、フローは継続します。

1つのHTTPリクエスト内で同時呼び出しが必要な場合は、Goルーチンを起動できます。しかし、それ以降の段階のためにそれを残してGo lang tour on concurrencyを先にしてください。

HTTPリクエストの負荷の高いソリューションが本当に必要な場合は、標準httpパッケージの代わりにhttps://github.com/valyala/fasthttpを使用することを検討してください。

1

HTTP @ iczaのコメント&アレクサンダーの答えは公正なアイデアを与えます。ゴルーチンを追加するだけでは、通常のスレッドよりも軽いので高価ではありません。それらは可変サイズのスタックを持つことができます(おそらく2kほどの低さで開始します)。&は、したがって、動作オーバヘッドを減らして非常にうまくスケールアップできます。

またhttpには、Gorilla muxのようなサードパーティライブラリがあり、あなたが探索できるバッファローのような他のフレームワークと同じように、より良い生活を実現できます。私は後者を使用していないが、それは人生が楽になると聞いた。

独自のカスタムサーバー(httpとは異なるもの)を作成しようとしている場合は、もう一度Goを選択するとよいでしょう。プログラムは、(あなたが他の端末からこのようのnetcatを使用することができますこのプログラムを実行してみてくださいするには)https://golang.org/pkg/net/#example_Listenerのような単純な起動

$ nc localhost 2000 
Hellow 
Hellow 

そして最後に移動中のチャネルが世話をしてルーチン間の共有データが&通信はるかに簡単かつ安全に行うことができます同期の側面のお役に立てれば。

+0

ありがとう、間違いなく助けて! :) – Aliquis

1

私の質問: Golangで同時サーバーを書くために移動するための方法は何ですか?すべての接続のためのちょうど新しいgoroutineか、または 非同期の方法がありますか? 「ベストプラクティス」とは何ですか?

Golang httpパッケージは、あなたのために並行処理を要求します。私はそのコードが同期のように見えますし、async/awaitキーワードを追加する必要はありません。ここにあなたの開始方法があります

func helloHandler(w http.ResponseWriter, r *http.Request) { 
    fmt.Fprintf(w, "Hello") 
} 

http.HandleFunc("/hello", helloHandler) 
log.Fatal(http.ListenAndServe(":8080", nil))