tag:crieit.net,2005:https://crieit.net/tags/cron/feed 「cron」の記事 - Crieit Crieitでタグ「cron」に投稿された最近の記事 2021-01-11T02:06:56+09:00 https://crieit.net/tags/cron/feed tag:crieit.net,2005:PublicArticle/16540 2021-01-06T01:15:51+09:00 2021-01-11T02:06:56+09:00 https://crieit.net/posts/aws-lambda-cron 📝 AWS Lambda で cron みたいに定期実行する <p>コンテナをホットスタンバイさせるために EC2 でインスタンス起動して cron で ping 飛ばしていたのですが、コスト的に勿体ないなーと思っていました。しかし、「AWS Lambda 使えばいいじゃん」という指摘を受け、確かにってなったので cron で定期実行していた ping 処理を AWS Lambda + EventBridge で置き換えました。</p> <p>実は <a target="_blank" rel="nofollow noopener" href="https://devcenter.heroku.com/articles/scheduler">Heroku Scheduler</a> とか使って同様のことをしていた時期もあったのですが、10分毎しか実行できない制約があったりして使い勝手が悪かったので、後々も使っていけそうな知見な気がしたのでメモがてら記事で残しておくことにしました。</p> <p>まず、AWS Console から Lambda サービスを選択して関数を新たに作成します。</p> <p><img src="https://i.gyazo.com/b4b591876af8519f9b22cfa35131327c.png" alt="AWS Lambda のトップ画面から関数を新たに作成する" /><br /> <strong>1. AWS Lambda のトップ画面から関数作成のための画面に遷移する</strong></p> <p><img src="https://i.gyazo.com/00a4e4415827a6e745f47e2ca5d39e1d.png" alt="必要な情報を入力して AWS Lambda の関数を作成する" /><br /> <strong>2. 必要な情報を入力して Lambda の関数を作成する</strong></p> <p>関数が作成でき次第、ping 処理を書いていきます。http リクエストを行うためのライブラリとして Node.js の標準モジュール(https) を利用します。</p> <p>Lambda 関数作成直後の <code>index.js</code> は下記のような記述になっていると思います。</p> <pre><code class="javascript">// index.js exports.handler = async (event) => { // TODO implement const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!'), }; return response; }; </code></pre> <p>こちらを Node.js の標準モジュール(https) を利用する形で下記のように書き換えます。</p> <pre><code class="javascript">// index.js // "https://www.google.com/" に HTTP リクエストを実行する (ping) const https = require('https'); const httpRequest = async (url) => { return new Promise((resolve, reject) => { const req = https.request(url, (res) => { let body = ''; res.on('data', (chunk) => { body += chunk; }); res.on('end', () => { console.log(`response: ${body}`); resolve(body); }); }) req.on('error', (e) => { console.error(e); reject(e); }); req.end(); }); } exports.handler = async (event) => { const body = await httpRequest("https://www.google.com/"); return { statusCode: 200, body }; }; </code></pre> <p>その後、右上にある <code>Deploy</code> ボタンをクリックして関数にソースコードを反映します。実際に関数が意図したとおりに動作するか、<code>Test</code> ボタンをクリックして動作検証してみます。</p> <p><img src="https://i.gyazo.com/ebbf0c5d9188faea7c49f04da63067fa.png" alt="1. <code>Test</code> ボタンをクリックします" /><br /> <strong>1. <code>Test</code> ボタンをクリックします</strong></p> <p><img src="https://i.gyazo.com/cc4099af0014d6f5ea0701c0e630af63.png" alt="2. 動作検証時のパラメーターを入力してテスト環境を作成する" /><br /> <strong>2. 動作検証時のパラメーターを入力してテスト環境を作成する</strong></p> <p><img src="https://i.gyazo.com/8cee96e8065baa486c966c6596b2f36c.png" alt="3. 2. のテスト環境で関数の動作検証を行い正常に実行できていることを確認する" /><br /> <strong>3. 2. のテスト環境で関数の動作検証を行い正常に実行できていることを確認する</strong></p> <p>正常に関数が実行できていること確認できれば、後は定期実行可能にすれば作業完了です。定期実行するためのスケジューラには EventBridge を利用します。<code>Add trigger</code> ボタンから EventBridge を追加します。</p> <p><img src="https://i.gyazo.com/f2b87343ebe5a32901b60721c8ef98e8.png" alt="1. <code>Add trigger</code> ボタンからトリガー追加画面に遷移する" /><br /> <strong>1. <code>Add trigger</code> ボタンからトリガー追加画面に遷移する</strong></p> <p><img src="https://i.gyazo.com/de52cedffde5acbf38bec0ad55f7a98c.png" alt="2. EventBridge トリガーを追加して定期実行の設定を行う" /><br /> <strong>2. EventBridge トリガーを追加して定期実行の設定を行う</strong></p> <p><img src="https://i.gyazo.com/c519d210f18b58ff4f9aeded662ee995.png" alt="3. EventBridge トリガーの追加が無事に完了したことを確認する" /><br /> <strong>3. EventBridge トリガーの追加が無事に完了したことを確認する</strong></p> <p>また <code>2.</code> では 1分毎に実行するスケジュールを設定しましたが、<a target="_blank" rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/scheduled-events.html">EventBridge の書式</a> を用いてより複雑なスケジュール設定を行うことも可能です。</p> <p>最後に本当に定期実行されていて、関数の実行も正常に行われていそう確認します。<code>Monitoring</code> タブをクリックして、関数の実行状況を確認していきます。</p> <p><img src="https://i.gyazo.com/54672fc613642b52471db2f51d006b37.png" alt="1. <code>Monitoring</code> タブをクリックする" /><br /> <strong>1. <code>Monitoring</code> タブをクリックする</strong></p> <p><img src="https://i.gyazo.com/b76a3b7bc3de06c47756b7eed62559d1.png" alt="2. Lambda 関数が定期実行されていることを確認する" /><br /> <strong>2. Lambda 関数が定期実行されていることを確認する</strong></p> <p><img src="https://i.gyazo.com/836da1ed016618aa791397bcd609e9a3.png" alt="3. Lambda 関数の実行結果が正しいことも確認する" /><br /> <strong>3. Lambda 関数の実行結果が正しいことも確認する</strong></p> <p>これで作業完了です。お疲れさまでした。</p> nikaera tag:crieit.net,2005:PublicArticle/16414 2020-12-23T23:56:50+09:00 2020-12-24T00:00:19+09:00 https://crieit.net/posts/node-script-triggered-cron-20201223 cron から node スクリプトをキックする <p>cron から nodeスクリプト をキックする方法について長らく嵌まっていたのでメモ。</p> <h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2> <p>とあるサーバで <code>markdown-pdf</code> によるPDF生成を行いたくて、自前の nodeスクリプト を作成・運用していました。</p> <p>ただし、そのサーバは一定期間ごとに再起動をかけているため、その度に自前の nodeスプリプト のプロセスが切れてしまいます。そこで cron で「再起動後に nodeスクリプト をキックする」ようなジョブを書いたのですが……。</p> <pre><code class="bash">@reboot root node /PATH/TO/NODE-SCRIPT/index.js & 30 2 * * 0 root reboot </code></pre> <p>しかし、上手く行きませんでした。</p> <h2 id="調査・対処"><a href="#%E8%AA%BF%E6%9F%BB%E3%83%BB%E5%AF%BE%E5%87%A6">調査・対処</a></h2> <p><code>/var/log/cron</code> で確認すると、 cronジョブ 自体は実行されていそうなのですが、 <code>ps aux | grep "node"</code> で確認すると、 node のプロセスはありません。起動できていないようです。</p> <p>その原因が分からず悩まされていたのですが、ふと node のパスがおかしいのでは、と気付き以下のように修正。</p> <pre><code class="bash">@reboot root /usr/local/bin/node /PATH/TO/NODE-SCRIPT/index.js & 30 2 * * 0 root reboot </code></pre> <p>※ちなみにこのサーバは <code>n</code> を使って node がインストールされています。</p> <p>これで試験したところ、再起動後にスクリプトが起動・動作していることを確認できました。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://tomokazu-kozuma.com/periodically-run-a-script-with-cron/">crontabでスクリプトを定期実行する - ブロックチェーンエンジニアとして生きる</a></li> </ul> arm-band