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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

メモリリーク

メモリリークは、プログラムファイルがメモリの解放に失敗した時に起こります。

Tomcat

TomcatはApache Software Foundation (ASF)で開発されたオープンソースのWebコンテナです。

Amazon EC2

Amazon EC2は“Amazon Elastic Compute Cloud”の略称です。Amazon Web Services(AWS)の一部であり、仮想化されたWebサーバーのコンピュータリソースをレンタルできるサービスです。

Q&A

解決済

2回答

15053閲覧

APサーバーが落ちた時の対処方法【再起動はトラブル予防の一環?】

ami613

総合スコア20

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

メモリリーク

メモリリークは、プログラムファイルがメモリの解放に失敗した時に起こります。

Tomcat

TomcatはApache Software Foundation (ASF)で開発されたオープンソースのWebコンテナです。

Amazon EC2

Amazon EC2は“Amazon Elastic Compute Cloud”の略称です。Amazon Web Services(AWS)の一部であり、仮想化されたWebサーバーのコンピュータリソースをレンタルできるサービスです。

0グッド

3クリップ

投稿2020/08/24 07:49

編集2020/09/30 06:54

前提

Java、AWS等を学習している者です。
SpringBootで作成したwarを、EC2にインストールしたTomcatに載せています。
catalina.outに下記の様なエラーが出ていて、サーバーにリクエストできなくなっていました。

発生しているエラー

OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(~略~) failed; error='Not enough space' (errno=12) # # There is insufficient memory for the Java Runtime Environment to continue. # Native memory allocation (mmap) failed to map 16384 bytes for committing reserved memory. # An error report file with more information is saved as: # /tmp/hs_err_pid~略~.log

考えていること

エラー文を読むと、メモリが足りなくなって落ちていることがわかりました。
根本原因は引き続き調査するとして、対処療法的な?回避策として、下記の様な記事がありました。

システム監視における再起動の役割

曰く、再起動は“トラブル予防の一環” とのこと。
毎日cronで再起動すれば、上記のエラーも解消されそうな気がしていて、試してみるつもりです。
このように定期的に再起動することは、実際の開発現場でもあることなのでしょうか?

また、更に調べると、

Tomcatのサービスが異常終了していたら起動コマンドを実行するスクリプト

cronで毎分、Tomcatのステータスをチェックし、異常時には再起動するようです。
こういったことも、実際の開発現場であることでしょうか?

個人的には、まずはAPサーバーを落ちないように設計することが第一と考え、
その保険として上記のような保険があると良いのかなと思いました。

しかし私は経験に乏しく、
「これって本当に対処法としてありなのか?」
「現実としてやっている開発現場はあるのか?」
といった疑問があり、質問させていただきました。

何卒よろしくお願い致します。

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

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

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

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

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

guest

回答2

0

24時間365日稼働するシステムではなく、夜間にサーバーを再起動してもいいシステムであれば私なら再起動しますね。そのほうが日中に溜まったメモリとか変なプロセスとか一回真っ新に出来るからです。

でも、日中にOutOfMemoryErrorでサーバーが落ちる時は、そもそもの実装が悪いことが多いですね。

投稿2020/10/19 22:58

deaf_tadashi

総合スコア200

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

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

ami613

2020/10/20 01:53

deaf_tadashi様 ご回答ありがとうございます! > 24時間365日稼働するシステムではなく、夜間にサーバーを再起動してもいいシステムであれば私なら再起動しますね。 > そのほうが日中に溜まったメモリとか変なプロセスとか一回真っ新に出来るからです。 なるほど、再起動にはやはりそういった恩恵があるのですね。 > でも、日中にOutOfMemoryErrorでサーバーが落ちる時は、そもそもの実装が悪いことが多いですね。 ご指摘いただきありがとうございます。 実装の部分でも、改善を進めていきたいと思っております。 ご回答、ありがとうございました!
guest

0

ベストアンサー

なかなかレスが付かないようなので…

事象を正確に解析するには最低限以下の情報があった方がいいかと思いました。

  • EC2インスタンスのスペック(搭載メモリ量)
  • Javaのバージョン、JVMのパラメータ
  • Tomcatのバージョン

編集前の質問内容に「インスタンスタイプは無料枠のもの」とあったのでt2.microと仮定しますが、
メモリ1GBでは最近のJavaでTomcatを動かすにはある程度チューニングが必要かと思います。
(正直チューニングしても実用的とは言い難いです)

まずは最低限のJVMのパラメータを設定して動かしてみてください。
↓TomcatのJavaオプションにこれを追加してみてください。
-Xms512m -Xmx512m -XX:CompressedClassSpaceSize=32m
(XmsとXmxはOSの空きメモリと相談してなるべく大きな値にしてください)

Tomcatのデフォルト状態では運用に必須とはいえないアプリも含まれていますので、
これらを無効化するか、
TomcatにwarをデプロイするのではなくSpringBoot組み込みのTomcatを使う(FatJARから起動する)ことで
消費メモリを抑えることはできます。

手前味噌ですが古いJVMの話ですが似たような事例について記載しています。
メモリが少ない環境でのJava8使用の注意点

上記の設定は本当に必要最小限の設定です。
実運用上はもう少し詳細なJVM設定が必要になります。
最適なJVM設定は搭載メモリだけで決まるわけではなく、そのアプリがどのようにメモリを使うかによって変わります。
これも手前味噌ですがJVMのメモリチューニング例です。
実録 緊急JVMチューニング

ご参考になれば幸いです。


最後に定期再起動の件ですが、個人的には最初から再起動を前提にすべきではないと考えます。
この手の運用はある程度運用が進んでから発覚した問題の対処である場合が多く、やむを得ない場合が多いかと思います。

https://www.sherpasuite.net/column/management/193/

FullGC回避という目的であれば第一選択はJVMのチューニングですが、必要であれば選択肢に入るとは思います。
ただし最近のJVMではG1GCというGC時間をコントロールする機構を持ったGCが標準になっていますので、こちらの記事がいつ頃書かれたものかはわかりませんが、以前よりもチューニングの余地はあるかと思います。

むしろFullGC時間の回避ではなくメモリリークのためやむを得ず再起動するというケースの方が多いのではないかと思いました。
現在ではクラウド上で運用するJavaシステムも多く、そういった場合の第一選択はメモリ増強です。
しかしながら、それだけでは対処できなかったり、メモリサイズを簡単に増やせない環境では
再起動運用を行なうことで調査や対処の時間を稼ぐことになります。

いずれにせよ、最初から完璧なシステムを作ることは非常に難しく運用開始後に問題が見つかることは十分あり得るという見地から、
システム監視を適切に行ない障害になる前の異常を検知することが重要だと考えています。


2020/10/20 10:52への回答

  • OutOfMemoryError → 無限ループなどで落ちるエラー(=復旧させるにはまずソースコードを疑うエラー)
  • os::commit_memory() failed → 環境要因で落ちるエラー(=復旧させるにはまず環境を疑うエラー)

必ずしもそうとはならないかもしれませんが、最初の切り分けとしてはよいかと思います。
環境起因の場合は「最後のトドメを刺したのがたまたまアプリだった」という可能性もあります。

余談に近いですが、環境のメモリ起因では「OSによって強制的にプロセスを落とされる」パターンがあります。
これはJVM自身は十分なメモリを確保していてもOSが動作していくためのメモリが不足した場合に発動するものです。
この場合はOSのログにしか手がかりはありません。
いきなりJavaプロセスが消えた、という場合はまずはこれも疑う必要があります。
(LinuxであればOOM Killerによるものです)

メモリ関連で落ちるエラーを総称して「OutOfMemoryError」と呼ぶのでしょうか?

OutOfMemoryErrorjava.lang.OutOfMemoryError を指しています。
メモリ不足でオブジェクト作成ができなかった場合などでthrowされるエラー(≠例外)です。
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/OutOfMemoryError.html

投稿2020/10/19 15:03

編集2020/10/20 04:10
chonaso

総合スコア11

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

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

mike2mike4

2020/10/19 15:19

私は定期再起動したほうがいいと思います。というのも、私が運用で関わってきた「マトモに動いている」マシンは定期再起動してましたし、いつ再起動したか分からないサーバーというのがあって、プリンタサーバーでしたが、ドライバが設定中に全消失して真っ青になった経験があるからです(再起動したら直った)。十分な監視リソースが割けないところ結構多いと思います。
ami613

2020/10/20 03:32 編集

chonaso様 ご回答ありがとうございます! > 事象を正確に解析するには最低限以下の情報があった方がいいかと思いました。 以降、質問する際には留意致します。 今回はインラインで記載させていただきます。 - EC2インスタンスのスペック(搭載メモリ量) → 1GB(ご推察の通りです) - Javaのバージョン → 11 - JVMのパラメータ → デフォルト - Tomcatのバージョン → 9 すぐに対応できるものとして、 JVMのパラメータ追加、 必須ではないアプリの削除(manager等入れっぱなしでした)を行います。 それでも同じエラーが出る場合は、FatJARから起動することも検討したいと思います。 また、類似事例のご紹介ありがとうございます!(熟読しています) 私はこの辺りの知識が大変乏しく、本当に参考になります。 Java言語での開発に1プログラマとして立ち会った経験は(少ないですが)あるのですが、 環境構築から始めたことがなく、大苦戦しながら現在キャッチアップしているところです...。 重ねての質問で恐縮なのですが、記事で「OutOfMemoryError」という記載がありました。 今回は「os::commit_memory(~略~) failed; error='Not enough space' (errno=12)」というエラーだったのですが、これらの特性をざっくり分けると、 - OutOfMemoryError → 無限ループなどで落ちるエラー(=復旧させるにはまずソースコードを疑うエラー) - os::commit_memory(~略~) failed → 環境要因で落ちるエラー(=復旧させるにはまず環境を疑うエラー) というような認識でいたのですが、これは間違いでしょうか? メモリ不足関連で落ちるエラーを総称して「OutOfMemoryError」と呼ぶのでしょうか? 初歩的な質問ですみません!<(_ _)> 最後に定期再起動の件、こちらも大変参考になりました。 まずはJVMのチューニング、そして監視ですね。 貴ブログも参考にさせていただきながら、勉強させていただきたいと思っております。 ご回答、ありがとうございました!
ami613

2020/10/21 01:45 編集

chonaso様 ご返信いただき、誠にありがとうございます。 なるほど、一言に「落ちた」といっても、様々な可能性があるのですね。 今回の件で、本当にまだまだ学ぶことが多いと痛感しました。 抽象的な質問に対し、ここまでわかりやすく教えていただき、本当にありがとうございました。 「とりあえずサーバーの定期再起動で良いのかな」と考えていたのですが、 JVMチューニングという方法を知り、更に学習を深めていきたいと思っています。 本当にありがとうございました!
chonaso

2020/10/21 09:21

> こういった領域の知識・ご経験はどのようにご習得されたのでしょうか? 独学ですが、実践の場に恵まれていました。 ただし「JVMのチューニングや監視を学びたい」というものではなく、必要に迫られて身についたものです。 (Java開発のキャリアはあります) これまで多くのJavaシステムの運用に携わってきましたが、不安定なシステムや経済条件が厳しいサービスも多く、サーバ増強のみに頼らず工夫して凌ぐことが求められる状況がよくありました。 大手SIerが面倒を見ているシステムはいざ知らず、中小システムはJVMに関する設定が全くない状態あるいは改善の余地が大きい状態で稼働しているシステムも多かったため、そういったシステムの安定稼働を目指す上での施策の一つがJava周りの最適化でした。 実際にはアプリケーションそのものの改善、OSやミドルウェアの設定見直しなどをセットで行ないます。 これらはITエンジニアとしての興味の部分もありますが、サービス継続、あるいは事業継続がモチベーションです。 というのでは学習の上での参考にはならないと思いますので、まずはJVMのメモリ管理やGCの動作について理解してください。 JVMチューニングに限らず、Javaに関する要素を知っていれば、今起きている問題に対して切り分けたり仮説を検証するなどして原因に近づくことができます。 原因を正確に捉えることができれば、対処法は今ならググればだいたい出てきますので。 JVMチューニング周りは開発とは無関係な部分も多く、Javaのバージョンやハードウェア構成によって挙動が異なるため取っつきにくいですが頑張ってください。
ami613

2020/10/23 04:38

ご返信ありがとうございます! > こういった領域の知識・ご経験はどのようにご習得されたのでしょうか? この質問ですが、した後に不躾と思い削除していました。 ご返信を頂き、誠にありがとうございます。 まずはJVMのメモリ管理やGCの動作から、コツコツ理解していきたいと思っています。 今回の件は、本当にたくさんの気付き・学びがありました。 重ねてお礼申し上げます、ありがとうございました<(_ _)>
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問