RubyでHTTPリクエストを並列化する
この記事は、「Speee Advent Calendar 2016」の13日目です。 12日目は、_miyachikより、「HAProxyを使用した汎用的ABテスト基盤への挑戦」です。
RubyでHTTPリクエストを並列化したくないですか?
例えば、リクエストしてからレスポンスが返るまで、1リクエストにつき100msかかるとします。 それを順次実行で10回行うと1000msかかってしまいます。 その10回はほとんどCPUを使用してないのにもかかわらず、ロックされてしまうので、他からリソースが使われない限り、リソースが非常に無駄になりがちです。
上記ケースにて、HTTPリクエストを並列化すると、10回リクエストしても100msで全ての通信が完了します。
どんな時に並列化したくなる?
- microservicesへのアクセス
- クローラー
今回はクローラーで並列化したい前提とします。 例えば、クローラーを使って、ページ内のaタグのURLを全て取得したいとします。
直列での実行
require 'open-uri' 10.times.map do |num| open("http://example.com/articles/#{num}") do |file| # アクセスに100msかかる想定 urls = Nokogiri::HTML.parse(html).xpath('//a/@href').map(&:value) end end
上記のようなコードだと100msかかるページに10回アクセスするので、HTTPリクエスト時間だけで1000msは確実にかかってしまいます。
並列での実行
並列化する方法として様々な方法がありますが、 今回はTyphoeusというGemを使って、HTTPリクエストの並列化を実現しようと思います。
require 'typhoeus' hydra = Typhoeus::Hydra.new requests = 10.times.map do |num| request = Typhoeus::Request.new("http://example.com/articles/#{num}") hydra.queue request request end hydra.run urls = requests.map { |request| urls = Nokogiri::HTML.parse(request.response.body).xpath('//a/@href').map(&:value) }
Typhoeus を使うと上記のようなコードを書くだけで、HTTPリクエストの並列化が実現できます。
Typhoeus
あまり、Typhoeus についての記事がないので、 使い方について説明します。
※ほとんどはGitHubのREADMEを読めば理解できると思われる
基本的な考え方としてはTyphoeus::HydraオブジェクトにTyphoeus::Requestを突っ込む感じです。
簡単な使い方
単一のリクスエストもこのように実行することが可能です。
Typhoeus.get("www.example.com", followlocation: true)
並列化された実行もこのように実行できます。
hydra = Typhoeus::Hydra.new 10.times.map{ hydra.queue(Typhoeus::Request.new("www.example.com", followlocation: true)) } hydra.run # runが実行された時点でURLに対してアクセスする
Requestの結果Responseを扱いたい場合
Request後の動作を定義することも可能です。 Request完了時の動作については以下のように定義します。
hydra = Typhoeus::Hydra.hydra request = Typhoeus::Request.new("www.example.com", followlocation: true) request.on_complete do |response| if response.success? # 成功した場合の処理 elsif response.timed_out? # タイムアウトした時の処理 log("got a time out") elsif response.code == 0 # なにかしらの問題があり、HTTP Requestの結果を取得できなかった場合の処理 log(response.return_message) else # その他の処理 log("HTTP request failed: " + response.code.to_s) end end hydra.queue(request) hydra.run # 結果を後で参照することも可能 puts request.response.body
responseの値の参照方法
response = request.response response.code response.total_time response.headers response.body
最大並列数の設定
- 並列数を設定することが可能
Typhoeus::Hydra.new(max_concurrency: 20)
※デフォルトは200
- get以外でのアクセスも可能
Typhoeus.get("www.example.com") Typhoeus.head("www.example.com") Typhoeus.put("www.example.com/posts/1", body: "whoo, a body") Typhoeus.patch("www.example.com/posts/1", body: "a new body") Typhoeus.post("www.example.com/posts", body: { title: "test post", content: "this is my test"}) Typhoeus.delete("www.example.com/posts/1") Typhoeus.options("www.example.com")
その他の並列化の方法
自分でスレッドを生成したり、ParallelなどのGemを使って、 複数スレッド、複数プロセスを立ち上げる方法がありますが、どちらにしても通信にしか使わないのにも関わらず、 スレッドやプロセスを立ち上げるのは非常にコストが高いです。 ※100並列をプロセスで実現しようとするとRubyプロセスが100個必要のため、Rubyプロセス100個分のメモリが必要
最後に
ドキュメントは以下のページにまとまっているので、大体見ればわかるものになってると思います。 Documentation for typhoeus/typhoeus (master)
また、今回の方法だと複数プロセスで実行できるわけではないので、CPUが複数個ある場合かつ CPUを使いたい場合はプロセスを立ち上げるなどの工夫が必要だと思います。
明日はkana_nakanoから「エンジニア採用を6ヶ月間やってみて(仮)」です お楽しみにー
決断することの重要性について
A案とB案があって、どっちがいいみたいな話になった時に ズルズルとなにも決まらずに話し続けているみたいなことを見ることが多い気がしている。 そんな時、「A案にするぞ!ついてこい!」っていう感じにしてみると案外うまくいくことが良い気がしている。
そういった時の決められない人の心情って自分は責任は取りたくない or 責任を取れる立場じゃないと思っているとかで 強く言えなかったりして、結局は責任を取ってくれる人を求めているんじゃないかなーって思う。 もしくは自分の意見がありながらもなにも言わない人にっていうのは本当はA案が悪いってわかってて、 B案が正しいって思っているのであれば、「A案にするぞ!ついてこい!」って言った時に「ちょっと待った、B案がいい」って 言ってくれるので、それはそれでB案を強く言ってくれる人になったりするので、そうなれば、B案を推した人が責任を 取らざるおえない状況となり、その場合も前に進んでうまくいったりする。
なので、今回の状況になった時に大事なのは最適な選択肢が選ぶことではなく、できるだけ進めるために動くことかなって思ったりしている。 ※時と場合によるが。
食とは
食について語るのにあたって、俺にとって食とはなにかを話さないわけにはいかない。
そしてこれはポエム以外のなにものでもない。
この記事を見始めた人が得られるものがあるか期待するかもしれないけど、
一切ないので、それを認識した上で見て欲しい。
俺にとって食とは生きることであり、そして楽しむことでもある。 調理師の親を持つ自分にとって、食とは楽しむのが当たり前のものだった。
食とは当たり前の存在だった。 高校生の頃は普通にラーメン屋巡りもしたし、マックとかも行ったりした。 だけど食というものが当たり前ではなくなり、特別なものとなる存在がきた
運命の出会い
当時の職場の上司に横浜市の関内にあるシシリヤというお店を紹介され、
ふと行ってみることにした。
気の知れた友人と共に店舗に行き、普通に入り、上司にオススメされたマルゲリータ×サルシッチャ(マルゲリータにハーブの入ったソーセージを載せたもの)の注文。
話をしながら待ってみる。
ピザが焼き上がり、手前に来たので、匂いを嗅いでみるとすごく香ばしい匂いがする。
おいしそうなので、すぐに口に入れた。
すると、口に入れた瞬間、小麦の甘みが口の中に広がり、その後チーズの旨味が広がっていく。
その後トマトソースの香りが抜けていって、くどさが残らない旨さが広がる。
食べた瞬間、「なんだこのバランスは!?」と思った。
この瞬間、「この世にはこんなおいしいものがあるのか!!!」と思った。
この時から色々なお店に行き始め、20代のうちに紹介できるお店を10店舗見つけるという
目標を持つことになった。
気分が乗れば、見つけたおいしいお店とかを紹介しようと思う。
英語力0のエンジニアが英語を学び始めて2ヶ月の話
2月から英語を勉強を開始した。と言っても全然きちんと時間を取ってやってない。
英語に苦手意識ない人はこの記事を読んでもあんまためにならないと思う。
スペック
どれぐらいできないか
- GitHubはコードの部分はなんとか。文章は全部Google翻訳にかけて読んでる
- 検索ページに英語のサイト(Stack Overflowなど)があってもできるだけ日本語の記事を探してどうしよもない時に読む(Google翻訳)
- 文法はまったくわからない
- 単語もかなり怪しい
- TOEIC未経験
きっかけ
以下の記事を見た同僚がDMM英会話やろうぜって言ってきたので一緒に始めた。要するにノリ
エンジニアが0から英語を勉強する為にした事 - ギークに憧れて
目的
- 英語の苦手意識をなくすこと。
DMM英会話実際どうよ?
僕みたいなレベルの人が英語力つけるのには向かない。
素直に文法と単語勉強しろ。
ただ、勉強するモチベーションのためにDMM英会話を使うのはありだと思う。(実際そう使っている)
日々、自分の英語力が上がっているのを感じるのが楽しくなる。
あとは英語に対する抵抗がなくなってきた。おかげでエンジニアライフが楽になった気がする。
DMM英会話以外なにやってんの?
音読パッケージを買った。まだ聞いてるだけ。
その他の最近の英語の活動
- 会社内でEnglishランチということで英語で会話するランチをやっている。 案外楽しいので続けていられてる。
よかったらリンクから飛んで試してみてください。
今すぐMagic Trackpad 2を買うべき3の理由
Magic Trackpad 2を買いました
感圧タッチがいい感じです! めちゃめちゃいい感じですねー。
かっこいい
前のMagic Trackpadはシルバーでメカ感があったけど 今回購入したMagic Trackpad2は白のデザインになってて、 今風でかっこいい
自慢できる
今はまだ持っている人が少ないので、持ってると他の人に見せて自慢ができる! そして自慢はすごく楽しいので、自慢するためだけでも買う価値あり。
Kinesisとの連携が完璧
皆さん、キーボードはKinesisを使ってるはずですよね。 そしてKinesisには真ん中にスペースが空いてる!!!
こうする!!!!
最強になりますね。
今までのMagic Trackpadだとハードウェアでタッチしている感じだったので、すごく押しづらかったのですが、
感圧タッチのMagic Trackpad2だと感圧タッチなので押しづらいなんてことあありません!むしろ押しやすい!!!
もうみなさん買わない理由はないですよね?
今すぐ15000円出して買いましょう。
アップル(Apple) MJ2R2J/A Magic Trackpad 2
- 出版社/メーカー: Apple Computer
- メディア: エレクトロニクス
- この商品を含むブログを見る
2015年、振り返り。
今更ながら、2015年の振り返りをしようと思う。
やったこと
PHPプロダクトをRuby化
Speeeが開発組織改革を行って、現場に起こった変化 - nisshieeのブログ
Splathon
Speee×pixivでスプラトゥーンをやったらくっそ盛り上がった話 - technicaを書いたら やりたいっていう企業さんが居てくれて、結局やることになった。 Splathon(企業対抗スプラトゥーン大会)を開催しました - technica 思ったよりも準備がくそ大変だったけど参加者の人に楽しんでもらえてよかった。
Qiitaの記事を書く
今までの書いてたけど、積極的に書くようにした。 ある程度ストックされた記事は以下の2つ
お前らのSSH Keysの作り方は間違っている - Qiita gcp - お前らにISUCONの負け方を教えてやる - Qiita
お菓子神社設立
- 「3年くらいお菓子神社運営してきた」を見てからお菓子神社を作りたいなーってずっと思ってたけど設立することができた。
- 「お菓子神社を5ヶ月運用してみて得た知見を共有」にある程度まとめてある。
RubyWorld Conferenceにブースを出す
- 「RubyWorld Conferenceで斬新なお菓子神社を運営してきた話 - technica」に書いてある。
- ステッカーやフライヤーの準備をしたり、企画を考えたりと初めてやることが多かったけど、無事にやり切ることができた。
扁桃腺の切除
- 扁桃腺を切除した。
- 質問されそうな部分を書いてみる。
どのぐらいの期間痛いの?
- 切ってから10日間は激痛だった。
- 痛みがほとんど収まることはないので、注意
どのぐらいお金かかるの?
- 僕の場合は高額療養費制度を使って9万いかないぐらいだった。
- 検査も合わせて10万ぐらいと思っておけば問題ない。
まとめ
- 2015年は新しく始めることが多かった。2016年は飛躍する年にしたいと思う。