質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.39%
Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

解決済

1回答

2868閲覧

Net::HTTPでNet::OpenTimeout (execution expired)が発生

take-hull

総合スコア16

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

0クリップ

投稿2022/09/03 08:28

編集2022/09/07 05:33

前提

いつも拝見させていただいております。
ありがとうございます。

現在Ruby on Railsを用いてGoogle Books ApiにGETリクエストを送りresponseを加工してNuxt.jsにJsonデータを返却する機能を作っています。

Railsの中で以下のmodelに定義したメソッドを使用してGoogle Books ApiにGETリクエストを送る機能を作りました。
ローカル環境では正常に作動しているのですが、
aws(ecs、EC2)にデプロイしたところ表題の通りエラーが発生しました。

数日詰まっているため、皆様の知恵を貸していただきたくて質問しました。

https://ja.stackoverflow.com/questions/90909/nethttp%e3%81%a7netopentimeout-execution-expired%e3%81%ab%e5%af%be%e5%87%a6%e3%81%97%e3%81%9f%e3%81%84
追記
こちらのサイトでも同様の質問を行っております。
解決した場合は双方のサイトにご報告し、私と同様の問題を抱える方の助けになるよう解決策をシェアいたします。

※9月4日追記
教えていただいた事及び調査結果から、現状は「RailsのEc2コンテナからGoogleApiに対しgetリクエストが届かない」事が判明しています。
下記の「Net::HTTPでGoogle Books ApiにGETリクエストを送り、レスポンスを得たい」という目的を達成するまで補足情報に調査経過を記載します。
情報に誤りがあった場合はご指摘いただけると幸いです。

※9月5日補足情報に(私なりの)解決策を提示しました。

実現したいこと

●何が起きているか知りたい。
●Net::HTTPでGoogle Books ApiにGETリクエストを送り、レスポンスを得たい。

発生している問題・エラーログ

●aws環境のログ

Started GET "/api/v1/books/search/?keyword=%E3%83%86%E3%82%B9%E3%83%88" for 000.000.00.000 at 2022-09-03 16:11:58 +0900 Processing by Api::V1::BooksController#search as HTML Parameters: {"keyword"=>"........."} https://www.googleapis.com/books/v1/volumes?q=.........&country=JP https://www.googleapis.com/books/v1/volumes?q=%E3%83%86%E3%82%B9%E3%83%88&country=JP https://www.googleapis.com/books/v1/volumes?q=%E3%83%86%E3%82%B9%E3%83%88&country=JP #<Net::HTTP:0x00007f7e4c5fd008> #<Net::HTTP::Get:0x00007f7e4c5fcdb0> Completed 500 Internal Server Error in 60002ms (ActiveRecord: 0.0ms | Allocations: 2006) ↓関係していそうなlogデータ Net::OpenTimeout (execution expired): /usr/local/lib/ruby/3.0.0/net/http.rb:987:in `initialize' /usr/local/lib/ruby/3.0.0/net/http.rb:987:in `open' /usr/local/lib/ruby/3.0.0/net/http.rb:987:in `block in connect' /usr/local/lib/ruby/3.0.0/timeout.rb:107:in `timeout' /usr/local/lib/ruby/3.0.0/net/http.rb:985:in `connect' /usr/local/lib/ruby/3.0.0/net/http.rb:970:in `do_start' /usr/local/lib/ruby/3.0.0/net/http.rb:959:in `start' /usr/local/lib/ruby/3.0.0/net/http.rb:1512:in `request' ↑関係していそうなlogデータ /app/models/google_book.rb:61:in `search'

●ローカル環境のログ

Started GET "/api/v1/books/search/?keyword=%E3%83%86%E3%82%B9%E3%83%88" for 000.00.0.0 at 2022-09-03 16:03:24 +0900 Processing by Api::V1::BooksController#search as HTML Parameters: {"keyword"=>"........."} https://www.googleapis.com/books/v1/volumes?q=.........&country=JP https://www.googleapis.com/books/v1/volumes?q=%E3%83%86%E3%82%B9%E3%83%88&country=JP https://www.googleapis.com/books/v1/volumes?q=%E3%83%86%E3%82%B9%E3%83%88&country=JP #<Net::HTTP:0x00007fd7a0119e58> #<Net::HTTP::Get:0x00007fd7a0119930> #<Net::HTTPOK:0x00007fd7a0125550> 200 OK Completed 200 OK in 692ms (Views: 0.7ms | ActiveRecord: 0.0ms | Allocations: 4250)

該当のソースコード

models/google_book.rb

1require 'google_books_api' 2 3class GoogleBook 4 include ActiveModel::Model 5 include ActiveModel::Attributes 6 include ActiveModel::Validations 7 8 attribute :google_books_api_id, :string 9 attribute :authors 10 attribute :image, :string 11 attribute :published_at, :date 12 attribute :title, :string 13 attribute :publisher, :string 14 15 16 validates :google_books_api_id, presence: true 17 validates :title, presence: true 18 19 class << self 20 #lib以下に作成したモジュールを使用する 21 include GoogleBooksApi 22 23 def new_from_item(item) 24 @item = item 25 @volume_info = @item['volumeInfo'] 26 new( 27 google_books_api_id: @item['id'], 28 authors: @volume_info['authors'], 29 image: image_url, 30 published_at: @volume_info['publishedDate'], 31 title: @volume_info['title'], 32 publisher: @volume_info['publisher'], 33 ) 34 end 35 36 def new_from_id(google_books_api_id) 37 url = url_of_creating_from_id(google_books_api_id) 38 item = get_json_from_url(url) 39 new_from_item(item) 40 end 41 42 43#エラー発生個所↓ 44#以下のメソッドをコントローラーで使用します。 45#フロントエンドからパラメーターとして送られてくる「keyword」を 46#引数に取っています。 47 48 def search(keyword) 49 #フロントエンドからのリクエストをuriに変換 50 #url_of_searching_from_keywordメソッドは以下のmoduleで定義 51 url = url_of_searching_from_keyword(keyword) 52 #ログに書き込み 53 Rails.logger.debug(url) 54 55 #urlをエンコード 56 enc = Addressable::URI.encode(url) 57 #ログに書き込み 58 Rails.logger.debug(enc) 59 60 #uriに変換 61 uri = URI.parse(enc) 62 #ログに書き込み 63 Rails.logger.debug(uri) 64 65 #hostとポート番号をターミナルに出力 66 #puts uri.host => www.googleapis.com 67 #puts uri.port => 443 68 69 require 'net/https' 70 http = Net::HTTP.new(uri.host, uri.port) 71 Rails.logger.debug(http) 72 http.use_ssl = true 73 http.verify_mode = OpenSSL::SSL::VERIFY_NONE 74 75   76 request = Net::HTTP::Get.new(uri.request_uri) 77 ×#getリクエストが為されているかをlogに書き込む 78  訂正#getリクエストするための objectが作られているかをlogに書き込む 79 Rails.logger.debug(request) 80   81  #↓ここがおかしい(レスポンスが返ってこない) 82 response = http.request(request) 83  #↑ここまでの処理を機能させたい 84

lib/google_books_api.rb

1 2module GoogleBooksApi 3 4 def url_of_searching_from_keyword(keyword) 5 "https://www.googleapis.com/books/v1/volumes?q=#{keyword}&country=JP" 6 end

試したこと

①httpからhttps通信に
当初
response = Net::HTTP.get(uri)
というコードを使用していましたが、これを上記modelの通りssl化しました。

②Rails.logger.debugによるデバッグで問題発生箇所を特定

コードを分解し、Rails.logger.debugでどこまで処理が実行されているか確認
したところ
Production.logのlogで
Net::HTTP::Get:0x00007f7e4af86658
というログを発見したため、RailsからGoogle Books Apiへのgetリクエスト自体は送られていると思われます。

補足情報(FW/ツールのバージョンなど)

現在もエラーの原因を調査中ですが、他の方の知恵や対処法(デバック方法)を知りたくて質問させていただきました(以前ご指摘いただいてビックリしたのですが丸投げする意図は全っっっっくありません)。
どうか、皆様の力を貸してください。
足りない情報やご意見がありましたら、コメントを頂けると助かります!

Ruby 3.0.2
Rails 6.1.6

調査経過
9月4日
Rails
models/google_books.rb

###疎通確認用################################################## require 'net/ping' ## Pingの宛て先はuri.host(www.googleapis.com) pinger = Net::Ping::External.new(uri.host) ## Pingが通るかどうかテストします Rails.logger.debug(pinger.ping?) ローカル環境 => logへの記録はtrue aws環境 => logへの記録無し ##############################################################

NuxtとRailsが入っているクラスター内でping

[ec2-user@ip-00-00-0-000 ~]$ ping www.googleapis.com --- www.googleapis.com ping statistics --- 56 packets transmitted, 56 received, 0% packet loss, time 55082ms rtt min/avg/max/mdev = 1.332/1.408/2.085/0.143 ms

docker execでRailsが入っているコンテナに侵入しping

/ # ping www.googleapis.com --- www.googleapis.com ping statistics --- 55 packets transmitted, 0 packets received, 100% packet loss

現状は「RailsのEc2コンテナからGoogleApiに対しgetリクエストが届かない」
現在awsのセキュリティグループ、ネットワークALC、Route53を調査中

9月5日
公式の設定例に従ってRails側のネットワークモードを「awsvpc」にしておりましたが、
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/bestpracticesguide/networking-outbound.html
↑の記事によればawsvpcはインターネットゲートウェイが使えない事が分かりました。
イメージ説明
その為、Rails側のタスク定義でネットワークモードを以下のとおり「bridge」で作り直しました。
イメージ説明
結果としてはawsのコンソールにおいて「portが重複しているため、サービスを作成できない」旨のエラーメッセージが発生しサービスを作成できませんでした。
いくつか記事を見たところ
https://aws.amazon.com/jp/premiumsupport/knowledge-center/dynamic-port-mapping-ecs/
を発見し、動的ポートマッピングというものを行えば良いのではないか?と気づきました。
イメージ説明
そして、記事に則りネットワーク周り等を作り直しました。
作り直したものは
●アプリケーションロードバランサー(バックエンド用)
●ターゲットグループ(バックエンド用)
●Rails側のタスク定義
●Rails側のサービス
です。
そして、ロードバランサーを作り直したため、Route53を再設定しました(Aレコード)。
その後、以下によればRails側のセキュリティグループで上記ロードバランサーをインバウンドルールに追加する必要がある事が分かり、以下に沿ってRails側のセキュリティグループのインバウンドルールを編集しました。
イメージ説明
セキュリティを全てを見せる事は出来ないので、抜粋しますが以下の様になります。
イメージ説明
以上の作業を行い、
Rails側の本番用のurlをブラウザに入力し、アクセスしたところ、head200を返すだけのヘルスチェック用アクションにブラウザからアクセスできるようになりました(真白な画面が表示されます)。
また、クラスターにssh接続をした後、Rails側のコンテナにdocker exec で侵入し、外部(GoogleApi)に向けてpingとcurlコマンドを打ったところ、無事レスポンスが返ってくる事を確認しました。
しかし、次は以前ネットワークモードをawsvpcにした状態で正常に作動していたRdsとの接続において、別のエラーが発生し、NuxtとRailsの疎通が不可能になりました。
幾つか記事を読んだところ、以下の記事を発見し、
https://qiita.com/fkana/items/a4b3c4d5d8ca27cd20ec
https://zatoima.github.io/aws-ec2-psql-install.html
Rails側のセキュリティが怪しい、と気づきました。
その後、Rails側のセキュリティグループに以下のインバウンドルールを設定しました。
イメージ説明
その結果、表題の
「Net::HTTPでGoogle Books ApiにGETリクエストを送り、レスポンスを得たい」
という目的が達成されました。
ただし、私自身awsの設定やセキュリティの知見はありません。
上記の画像はアクセスの許容範囲が広い設定であるため、セキュリティの問題を孕んでおり、あくまで暫定的な処置になると思われます(アクセスの範囲を絞る必要がある?)。

以上で表題の問題は一旦解決となりますが、何かご意見やご指摘のある方は是非、コメントを頂けると大変助かります。
コメントや回答を下さった皆様(特に辛抱強く何度もコメントを下さったwinterboumさん)、本当にありがとうございました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

winterboum

2022/09/03 09:33

エラーログ読めないです。 私には力不足の可能性があるので回答は期待しないでほしいですが、力ある人もこれだと読む気起きないかもなので。
take-hull

2022/09/03 10:00

winterboumさん >エラーログ読めないです。 >私には力不足の可能性があるので回答は期待しないでほしいですが、力ある人もこれだと読>む気起きないかもなので 先日はありがとうございました。 基本的な部分が抜け落ちていました。 表題のエラーが発生した際にベテランの方がどういった点に着目するのか、どこが重要な場所なのかが分かりませんし、不足しているよりかは、と思いlogを全文掲載しました。 読む気が起きなくなるという点についてはおっしゃる通りだと思います。 しかし、現状はできる事をやるしかないので、誰かの目につけば良い、という程度の考えで過度な期待はせず、可能な限り自力で解決できるよう調査を進めております。 不備がありましたら今後もご指摘いただければ幸いです。
otn

2022/09/03 15:14

プログラムを動かす前に環境の確認はしてないのでしょうか? 例えば、pingが通るかとか、wgetかcurコマンドlでHTTPアクセスしてみるとか。
take-hull

2022/09/03 15:45 編集

otnさん >プログラムを動かす前に環境の確認はしてないのでしょうか? コメントありがとうございます。 最初にインフラ構築を行い、webサーバーとapiサーバーで最低限の疎通確認を行ったのみでした・・・。 手探りで作っていたというのが正直な所でして、他の方であれば当たり前にやる事を怠っていたり、基礎的な知識が欠落している事を日々痛感しています。 不快に思われたならばお詫びいたします。申し訳ありません。
otn

2022/09/05 10:21

よくあることなので、別に不快では無いです。不快ならコメントしませんし。 うまく行くことに根拠のある確信がある場合は、一か八か、最終結果だけ確認しても良いですが、 確信が無い場合とか、確信があったのにエラーになるなど意図通りの結果にならなかった場合は、 最初から一歩ずつ順番に確認して、どこで間違えたのかを調べます。
take-hull

2022/09/05 10:49

otnさん コメントありがとうございます。 >よくあることなので、別に不快では無いです。不快ならコメントしませんし。 確かにwgetやcurl等、ネットワーク回りのヒントを頂いてますね・・・失礼しました。 >確信が無い場合とか、確信があったのにエラーになるなど意図通りの結果にならなかった場合は、 >最初から一歩ずつ順番に確認して、どこで間違えたのかを調べます。 肝に銘じます。ありがとうございます!
guest

回答1

0

ベストアンサー

Net::OpenTimeout ですから、コネクションできていません。
request = Net::HTTP::Get.new(uri.request_uri) は リクエストするための object が作られるだけで、アクセスはしていません。
ので 「#getリクエストが為されているかをlogに書き込む」とありますが、このlogがあってもリクエストはまだしていません。
response = http.request(request) で初めてアクセスに行きます。

可能性としては、 EC2のセキュリティ設定で

  1. www.googleapis.com へのアクセスができるようになっていない
  2. www.googleapis.com への https プロトコルが通るようになっていない

あたりかな、

投稿2022/09/03 13:45

winterboum

総合スコア23520

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

take-hull

2022/09/04 05:04 編集

winterboumさん 解答していただいてありがとうございます。 セキュリティグループの設定を見直し、結果を確認してから返信しようとしていたため、返信が遅れてしまいました。申し訳ありません。 >Net::OpenTimeout ですから、コネクションできていません。 net-pingを用いてuri.host(www.googleapis.com)との疎通確認を行った所、production.logにlogが記録されていないため、おっしゃる通りwww.googleapis.com へのアクセスができるようになっていないのだと思います。 Rails側のセキュリティグループでhttpsを許可しているのですが、十分な知識が無く、設定に不備がある可能性があるため、調査を継続し、(時間がかかるかもしれませんが・・・)問題点や解決策が分かり次第他サイトを含め皆様と情報共有致します。 なお、問題自体は未解決の状態ですが、以前の質問を含め質問のマナー、logの参照、デバッグ、セキュリティの確認等手取り足取り教えていただいたおかげで 「何が起きているか分からず手が付けられない」 状態から ×「RailsがGoogleApiに対してgetリクエストを送れていない」 9月4日訂正「RailsがGoogleApiに対してgetリクエストが届かない」 という所まで把握出来ましたので、頂いた回答をベストアンサーとさせて頂きます。
winterboum

2022/09/03 23:41

getリクエストを送れていない ではないですよ getリクエストが届かない です
take-hull

2022/09/04 05:03

winterboumさん >getリクエストが届かない >です 重ね重ね申し訳ありません。 コメントや回答を頂けて本当に助かっています。 「Net::HTTPでGoogle Books ApiにGETリクエストを送り、レスポンスを得る」 という目的を達成するまで途中経過を補足情報に記載しますが、誤った情報をシェアするのはユーザーの不利益なりますので、もし今後見かける機会がありましたら指摘していただけると大変助かります・・・。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.39%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問