こんにちは、Habrahabr。
おそらく
JMeterに精通しているでしょう。 要するに-負荷テストを実施するための非常に便利なツールであり、優れた機能と多くの便利な機能を備えています。 しかし、記事は彼に関するものではありません。
どこから始まったの
私たちのプロジェクトにはかなりロードされたノードがあり、JMeterは長い間助けてくれました。 プロファイリングと最適化は利益をもたらしましたが、すべてが小さな問題にぶつかりました。 JMeterは非常に大きなトラフィックを作成できませんでした。より正確には、必要なモードの10秒後にOutOfMemoryが発生し、テストが停止しました。場合によっては問題はありませんでしたが、リクエストの送信速度は著しく低下しましたが、CPU負荷は400%でしたが、解決されましたプログラムを再起動します。 使用するのは非常に不快でした。
したがって、問題があり、それを解決する必要があります。最初に思いついたのは、最小要件を満たす独自のミニテストを行うことです。 Goの味を試してみるのは長い間興味深いものでした。 そこで、go-meterアプリケーションが誕生しました。 書いているとき、多くの質問がありました、答えはそうでなかったか、または問題を説明しませんでしたので、私は私の経験と動作するコードの例を共有することに決めました。
まえがき
どのような言語が意味をなさないかを書くことは、基本的な要素を明らかにする
言語の ツアーを常に見ることができると思います。 環境をインストールして構成する方法も価値がありません。すべてが完全に理解可能な言語で
文書に書かれてい
ます 。
なぜGoを選んだのですか? 私にとって非常に重要な基準がいくつかあります。それは、高速で、クロスプラットフォームで動作し、管理しやすい、珍しいフローがあります。 もちろん、あなたはこれを他の言語で書くことができると言います。 私はあなたに同意しますが、仕事は書くことだけでなく、何か新しいことを学ぶことでもありました。
さあ始めましょう
ためらうことなく、テストプロファイルをJSON形式で保存することが決定されました。アプリケーションを起動した後、プロファイルが読み取られ、テストが開始されます。 テスト中、コンソールに概要テーブルが表示されます(応答時間、1秒あたりのリクエスト数、エラーの割合、警告、成功したリクエスト)。 JSONを使用すると、すべてが簡単になります。そのためには、各要素の構造を作成し、ファイルを開いて読み取る必要があります。
func (this *Settings) Load(fileName string) error { file, e := ioutil.ReadFile(fileName); if e != nil { return e } e = json.Unmarshal(file, this); if e != nil { return e } return nil }
さらに進みましょう。 開始後、Nスレッドを開始する必要があります。各スレッドを処理した後、データを集約し、コンソールに美しく出力します。 このため、この興味深い言語にはチャンネルがあります。 異なるストリーム間の一種の「パイプ」。 同期は不要で、ロックは必要ありません。すべて自動で行われます。 これは、スレッドがリクエストを送信し、結果を決定し、これをメインスレッドに報告します。メインスレッドは、すべてのスレッドが完了し、受信したすべてのデータを出力するまで待機します。 Streamsは、構造の転送によって私たちと通信します:
type Status struct { IsError bool IsWarning bool IsSuccess bool Duration *time.Duration Size int64 IsFinished bool Error *error FinishedAt *time.Time StartedAt *time.Time }
各スレッドは、指定されたリソースに対してM時間のHTTP要求を実行します。 POSTリクエストがある場合、ユーザーが望む特定のデータを送信します:
func StartThread(setts *settings.Settings, source *Source, c chan *Status){ iteration := setts.Threads.Iteration
プログラムの起動時にスレッドを開始し、それらからのデータをリッスンするだけです。
c := make(chan *Status, iteration * setts.Threads.Count) for i := 0; i < setts.Threads.Count; i++{ go StartThread(&setts, source, c) } for i := iteration * setts.Threads.Count; i>0 ; i-- { counter(<-c) } fmt.Println("Completed")
結論の代わりに
私の意見では、これらは最も興味深い瞬間です。 すべてのソースは
GitHubで利用でき
ます 。そこでは、使用例とともに作業サイクル全体を見ることができます。 実際、この奇跡の言語は興味を持ってこのタスクに対処しました.JMeterの場合の3倍のトラフィックを生成するとき、プロセッサの負荷が15%を超えることはめったにありません。
興味深い場合は、MongoDBとRedisのストレージを使用してHTTP Restfull Webサービスを作成するプロセスについて説明します。
ご清聴ありがとうございました!