TECH PLAY

株式会社ラクス

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

935

はじめに 皆さん、こんにちは、今年の4月に入社したプログラミング未経験者のr_yxkxrx13です。 プログラミング超初心者!! という方は、プログラミングの学習を始める前に何を準備して取り組めば分からない…ということが多いと思います。 プログラミング未経験である私が今まで取り組んだプログラミングの学習方法を紹介したいと思います。 はじめに プログラミング学習方法 コンピュータとネットワークの基礎学習サイト プログラミング学習サイト 書籍学習 プログラミング学習の取り組み方 終わりに プログラミング学習方法 私が今まで取り組んできたプログラミング学習方法は、「コンピュータ基礎/ネットワークの基礎学習サイト」、 「プログラミング学習サイト」、「書籍学習」の3つです。 学習サイトとは、ブラウザ上に無料で気軽に利用できるサイトのことで、インターネットにたくさん出ています。 まずはそのようなサイトを利用して学習を始めるのが良いと思います。 また書籍学習で基礎知識の理解を深めながら、プログラミングの練習をすると良いと思います。 私が利用した学習サイトと書籍について説明します。 コンピュータとネットワークの基礎学習サイト プログラミング学習の初めに「コンピュータ基礎/ネットワーク」を学習しました。 プログラミングの基礎なので、基礎知識と概念を理解しておくと良いと思います。 【5分で覚えるIT基礎の基礎】コンピュータの仕組み---目次 | 日経クロステック(xTECH) 「コンピュータの仕組み」をテーマに基礎知識の全体像と概要を分かりやすく解説されています。 初心者のためのネットワーク技術 - ネットワークエンジニアを目指して 「ネットワーク技術」をテーマに基礎知識を分かりやすく解説されています。 プログラミング学習サイト プログラミングの参考本では、決まった書き方やコードの意味がたくさんあり、全部覚えられない…。 とつまづいてしまうことはあると思います。 私の経験の1つですが、正直に言って、全てを一気に覚えることは無理があります。 逆に理解度が低くなってしまうので意味がありません。 まずプログラミングを書く練習をたくさんすると、自然に覚えられるようになってきます。 また1行ずつコードの意味を コメントアウト してみると、理解が深まってきます。 そこで、ブラウザ上で実際にプログラミングを作る環境と似た環境で練習できるサイトを紹介します。 Progate (画像出典: Progate ) Progateは、ブラウザ(インターネット)上でプログラミングが学べるサービスです。 イラストを中心に分かりやすく解説されたスライドで、自分のペースに学習や復習ができます。 また以下のようにブラウザ上でコードを書いて結果を確認することができます。 複雑な環境設定などの準備は不要なので、気軽にプログラミング学習を始めれます! 初心者レベルから実践レベルまで対応されていて、 さらにレッスンの種類もたくさんあり、分かりやすく楽しみながら学べるサイトです。 ドットインストール (画像出典: ドットインストール ) ドットインストールは、約3分間の短いレッスン動画でプログラミングを学べるサイトです。 動画の音声が聞き取りづらくても動画画面の下に字幕があるので、見返すことができます。 また右側に学習メモの機能があり、新しい知識や疑問をメモすることができます。 動画を見ながら、実際に作ってみることを重点において学習すると良いでしょう。 CodeResume (画像出典: CodeResume ) CodeResumeは、ブラウザ上でプログラミングが学習できるプラットフォームです。 練習問題の画面では、以下の図のように解答欄にコードを書き込んで、 コンパイル と実行で結果を確認できるようになっています。 またタイマー機能も付いているので、時間を意識して考えて解く力が身についてくると思います。 書籍学習 学習サイトだけでは学習範囲が限られていますが、書籍での学習も有効な学習方法だと思います。 私が利用した書籍の中からオススメの書籍を紹介します。 スッキリわかる Java 入門 第2版 (スッキリシリーズ) スッキリわかるJava入門 第2版 (スッキリシリーズ) 作者: 中山 清喬 , 国本 大悟 発売日: 2014/08/07 メディア: 単行本(ソフトカバー) 本書は、 Java の基本を丁寧にイラストと同時に説明されていますので、非常にわかりやすい内容になっています。 Java の複雑な開発準備や必要なツールって分からない…。という方、安心して下さい。 Webブラウザ を持つ携帯電話やパソコンで、準備された クラウド 開発実行環境「dokojava」を使って、手軽にプログラミングの練習ができるようになっています。 また「dokojava」の他に、実際に開発現場で使われている「Ecplise」のインストール方法や使い方まで書かれています。 Java の学習を始める時は、まずこの本を読んでおくことをオススメします! スッキリわかる Java 入門 実践編 第2版 (スッキリシリーズ) スッキリわかる Java入門 実践編 第2版 (スッキリシリーズ) 作者: 中山 清喬 発売日: 2014/09/22 メディア: 単行本(ソフトカバー) 本書は、 Java 入門の実践編で開発や設計手法、ツールの知識について、分かりやすく解説されています。 Java の応用技術まで紹介されているので、 Java の基本をマスターした方は、さらにステップアップで学びたい時に読むことをオススメします! Java ルールブック 〜読みやすく効率的なコードの原則 Javaルールブック ~読みやすく効率的なコードの原則 作者: 大谷 晋平 , 米林 正明 , 片山 暁雄 , 横田 健彦 発売日: 2011/02/15 メディア: 単行本(ソフトカバー) コードの書き方について大変参考になる本です。 正しい書き方と間違った書き方の例を挙げて分かりやすく解説されています。 正しいコードの書き方を身につけると、シンプルで見やすいコードが書けるようになります。 リーダブルコード リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice) 作者: Dustin Boswell , Trevor Foucher 発売日: 2012/06/23 メディア: 単行本(ソフトカバー) Java ルールブックと同様にコードの書き方について、さらに具体的に丁寧に解説されています。 プログラミング学習の取り組み方 ここまでは学習サイトや書籍を紹介してきましたが、 以下については私が有効だと感じた具体的な学習方法と心構えについて説明します。 学習内容を読むだけにしない 学習内容を読んで満足するだけでは理解が深まりません。 学習内容を読んで実際に操作して動作を確認してみる、疑問になったことを納得するまで深く掘り出すことが大切です。 コードを1行1行にコメントをつける プログラミングの経験が長い方が書いたコードは、必要な情報だけコメントしています。 プログラミング未経験の方は、まだコードの意味や書き方に慣れていないので、 まずコードの意味を理解することから始めると良いでしょう。 慣れてきたら、少しずつコメントを減らして、コードを読める・書けるようにすると良いと思います。 コードが完成したら デバッグ をする プログラムを実行して結果が正しくても完成とは限らないです。 本当に問題がないかどうか、 デバッグ をして修正箇所がないか確認をするように心掛けましょう。 処理の流れを把握できるようになってきたら、 デバッグ 機能に頼らず、自分の目で確認してみましょう。 エラーの原因と対策方法を見つける プログラムのバグ(故障・エラー)を見つける力と対策方法の知識を身につけることが大切です。 例えば、プログラムが完成してバグに気付かないまま、共同者のプログラムを合わせると、 トラブルを起こしてしまう可能性があります。 このようなトラブルが起きた時、どこにバグがあるか、どのように対策をすれば解決できるか、 実際にプログラミングの練習でテストしてみると良いでしょう。 またプログラムを作成する時は、バグがないプログラムを完成するように心掛けて書くようにしましょう。 サンプルプログラムを鵜呑みにしない コードが書けない…という方は、インターネットや書籍にサンプルプログラムを参考にしていますが、 丸ごとコピーして修正するやり方は良くないことです。 サンプルプログラムを書き写して目的に合わせて修正し、動作の理解を深めることが良いでしょう。 プログラミングの練習をできるだけ毎日やる スポーツと同じように、プログラミングを書く練習を毎日取り組むと、自然にコードの意味や書き方が分かるようになってきます。 最初は慣れなくて大変ですが、書籍や学習サイトを参考にしながら、書く練習をすると良いでしょう。 プログラミングのツールを試してみる プログラミングのツールは、代表的なものだけではなく、あまり知られていないものや最近新しくできたツールを 試しに使ってみて比較することも大切です。 プログラミングの進化が続いているので、新たな知識をたくさん吸収すると良いでしょう。 簡単なものを開発してみる 私の場合は、HTML/ CSS の学習をしながら、自分のホームページを制作しました。 学習で学んだことを活かして、ホームページやアプリを開発してみると、楽しくやりがいがあると実感できます。 プログラマー と情報交換をする プログラミング経験者は、技術情報やプログラミングの学習などたくさんの情報を持っています。 疑問や悩みまで相談できるので、 プログラマー の仲間を作ることも大切です。 終わりに プログラミング未経験者向けの学習方法と取り組み方を紹介しました。 紹介した学習方法の他にもたくさんありますので、 自分に合った方法を見つけて、是非プログラミングの学習を始めてみてください!
アバター
はじめに 皆さん初めまして、新卒一年目のFM_Harmonyと申します。 今回はマルチブラウザという観点から、 最近の JavaScript について調べました。 jQuery の登場や、主要なブラウザが標準仕様への準拠を進めたことで、エンジニアが JavaScript の動作環境を気にすることが、以前に比べ減りました。しかし調べていくと、今後は トランスパイル や AltJS による対応が、 JavaScript において必要になっていくのだということが分かりました。 このまとめが、 最近Webアプリケーション開発に関わりはじめた方 や、 今後の JavaScript について興味のある方 にとって、少しでも参考になれば幸いです。 目次 はじめに 目次 本題の前に マルチブラウザ?クロスブラウザ? これまでのマルチブラウザ対策 JavaScriptとブラウザ マルチブラウザ対策としてのjQuery 各ブラウザの対応 これからのマルチブラウザ対策 ES6とIE11 トランスパイル AltJS まとめ 注釈 本題の前に マルチブラウザ? クロスブラウザ ? この記事では、「 複数のブラウザに対応すること 」を マルチブラウザ という言葉で表現します。サポート期間の終了したブラウザは、対応しないというのがその理由です。マルチブラウザは クロスブラウザ と混同される概念ですが、簡単に言うと次のように分けられることが多いようです。 マルチブラウザ アプリケーションの作成元が 推奨するブラウザ で、動作することを保証する クロスブラウザ すべてのブラウザ で動作することを保証する 例えば、 Google Chrome ( Chrome )は自動的にアップデートが行われます。そのため、古いバージョンが使われることはまずありません。ゆえに、この記事ではマルチブラウザという言葉を使うことにします。 クロスブラウザ とマルチブラウザの違い これまでのマルチブラウザ対策 JavaScript とブラウザ JavaScript には、 ブラウザごとに異なる実装 が存在しています。これが、マルチブラウザ対策が必要な理由です。私たちが普段 JavaScript と呼んでいるものは、 ECMA *1 Script (ES)という標準仕様を実装した言語を指します。そして、それは ブラウザごとに異なる環境 (エンジン)で動作します。また、その実装に ブラウザ独自の拡張 を行うことが、ある程度許容されています。ゆえに、 JavaScript を扱うときはブラウザごとの違いに注意しなければならなかったのです。 エンジニアはブラウザの違いを意識しなければならない マルチブラウザ対策としての jQuery しかし、現在では開発中にブラウザ間の差異を意識することは、まず無いでしょう。一昔前まで、エンジニアはブラウザごとに JavaScript の記述を変える必要がありました。ユーザがどのブラウザを使っているか検知し、記述を変えていたのです。 ところが、 jQuery というライブラリの登場により状況は変わります。このライブラリが、 ブラウザ間の違いを吸収する ことにより、アプリケーションをマルチブラウザ化する難易度が格段に下がりました。そのため、マルチブラウザ対策として、 jQuery を用いることが多々ありました。 エンジニアはブラウザの違いを意識せずに済む 各ブラウザの対応 ですが、ここ数年の間に各ブラウザがESへの対応を積極的に行ったことで、 jQuery によってマルチブラウザ対策を行う必然性が薄れていきました。特に今年に入って、 IE が IE11より前のブラウザに対するサポートを終了 したため、 ES5までの標準仕様 であれば、どのブラウザでも利用できるようになりました。機能面でのマルチブラウザ対策を考える必要は、基本的に無くなったといっても良いでしょう。 各ブラウザのES5への対応   (出典: http://kangax.github.io/compat-table/es5/ ) これからのマルチブラウザ対策 ES6とIE11 少し話は変わりますが、現在メジャーな標準仕様は ECMAScript2015 (ES6)とされています。この仕様には、アロー関数やPromiseといったエンジニアにとって魅力的な構文が多く含まれています。そのため、今後ES6に準拠した JavaScript の記述が増えていくと思われます。(参考: ECMAScript 6: New Features: Overview and Comparison ) しかしES6は、IE11において仕様の 11% しか実装されていません。他のブラウザでは、 ほぼ100%実装されている のにもかかわらずです。IE11のサポートは2025年まで続く *2 ため、マルチブラウザ対策として 古い記述 を残す必要があります。 各ブラウザのES6への対応   (出典: http://kangax.github.io/compat-table/es6/ ) トランスパイル ここで登場するのが、 トランスパイル という技術です。先ほども述べましたが、ES5はIE11や Chrome など主要なブラウザでの実装が完了しています。そこで、実際の開発はES6に準拠したコードで行い、アプリケーションに組み込む段階で、コードを 機械的 にES5へ変換するという手法が考えられました。この変換する技術をトランスパイルといいます。コードを変換する トランスパイラ として代表的なものに、 babel があります。 トランスパイルのイメージ(babel公式サイトより)   (画像出典: Babel · The compiler for next generation JavaScript ) AltJS また、トランスパイルと近い考え方に、 AltJS *3 を利用するというものがあります。AltJSとは、その名の通り JavaScript の代替言語です。代表的なものに TypeScript や CoffeeScript などが存在します。これらの言語には、ES6に対応した実装が多く含まれており、ES6に準拠した JavaScript の代わりとして使うことができます。そして、 JavaScript に変換してアプリケーションに組み込むことができるのです。 AltJSの一つ、TypeScript  (画像出典: TypeScript: JavaScript With Syntax For Types. ) まとめ jQuery や各ブラウザの対応によって、 JavaScript の機能面でのマルチブラウザ対策は難易度が下がりました。一方で Ecma はES6以降、標準仕様を 毎年改定する と発表しています。それに伴い、今後さまざまな仕様やそれに伴った記述が増えていくことでしょう。ですが、IE11におけるES6の現状を見ても、他のブラウザに比べて IE の対応が遅れることは、間違いないと思います。 ES6やその先の ECMAScript に対応した記述を、開発効率向上のために導入するならば、マルチブラウザ対策として、 トランスパイルやAltJSから避けることができません。 ESの更新が活発な今だからこそ、これらを導入してはいかがですか? エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com 注釈 *1 : European Computer Manufacturers Associationの略 *2 : Windows10のサポートが終了するのが2025年のため *3 : Alternative JavaScript の略
アバター
はじめに みなさん こんにちは、Thuatと申します。今年 ラク スに入社しました1年目です。 この記事ではセッション管理としてRedisを使用するケースを紹介します。 Redisとは? Redis は簡単に言うと、メモリ上のKey- Value ストアです。 メモリ上にデータを格納しますので高速に動作します。 以下はインストールから簡単なデータの登録・取得までの手順になります。 Redisをインストールする $ wget http://download.redis.io/releases/redis-4.0.1.tar.gz $ tar xzf redis-4.0.1.tar.gz $ cd redis-4.0.1 $ make Redisサーバーを起動する $ src/redis-server 33507:C 25 Sep 23:21:32.201 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 33507:C 25 Sep 23:21:32.202 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=33507, just started 33507:C 25 Sep 23:21:32.202 # Warning: no config file specified, using the default config. In order to specify a config file use src/redis-server /path/to/redis.conf 33507:M 25 Sep 23:21:32.203 * Increased maximum number of open files to 10032 (it was originally set to 256). _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 4.0.1 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 33507 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 33507:M 25 Sep 23:21:32.206 # Server initialized 33507:M 25 Sep 23:21:32.206 * DB loaded from disk: 0.000 seconds 33507:M 25 Sep 23:21:32.206 * Ready to accept connections Redisのポートはデフォルトで6379になります。 クライアントからGET/SETする Redisにあらかじめ組込まれているクライアントツールからデータをGET/SETしてみましょう。 シンタックス は以下になります。 set key value get key $ src/redis-cli 127.0.0.1:6379> set key1 10000 OK 127.0.0.1:6379> get key1 "10000" 127.0.0.1:6379> Value は JSON でも保存できます。 127.0.0.1:6379> set user_info '{"username":"taro", "age":20}' OK 127.0.0.1:6379> get user_info "{\"username\":\"taro\", \"age\":20}" 127.0.0.1:6379> Redisは メモリ上にデータを格納しますので、デフォルトはサーバーを停止、再起動した場合は、データが失われます。 Redisはどのような時に利用すればよいでしょうか。 最適な ユースケース はキャッシュやセッション管理です。 セッション管理としてRedisを使用する セッションとは? セッションはクライアントとサーバの通信の状態をWebサーバー上に保持されます。クライアントはセッションIDをURLやクッキー経由でサーバに渡します。 Key- Value 構造としてメモリ、ファイル又はDBに格納します。KeyはセッションID、 Value はセッションに保存したいデータです。 デフォルトではセッションは Webサーバーのメモリ上に保持されます。 Webサーバー単独でセッション管理を行う場合はWebサーバーのロードバランサを構成できません。 セッションをDBに格納する設定にすると、ロードバランサを構成することができますが、パフォーマンスに影響します。 セッションについては、 https://blog.takanabe.tokyo/2014/12/%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%81%AE%E5%91%A8%E8%BE%BA%E7%9F%A5%E8%AD%98%E3%81%BE%E3%81%A8%E3%82%81/ を参照ください。 Redisを使ってセッションを管理する データをセッションではなくて Redisで管理する方法を紹介します。 Redisにはセッションのように タイムアウト 時間を設定できます。 タイムアウト 時間を超えた場合はRedisに保存したデータが自動的に削除されます。 以下の機能を Java で実現してみます。 ユーザのデータを JSON で保存する タイムアウト は3分に設定する Java でのRedisクライアントは多くありますが一番人気はJedisです。 https://github.com/xetorthio/jedis/wiki/Getting-started プロジェクトのLibrariesにjedis-2.9.0.jarを追加してください。 http://search.maven.org/remotecontent?filepath=redis/clients/jedis/2.9.0/jedis-2.9.0.jar jedis-2.9.0.jar を追加する フォルダの構成は以下のようになります Userクラスを作成します。 package jp.co.jedis; public class User { private String username; private String address; public User(String username, String address) { this.username = username; this.address = address; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "{'username':'"+this.username + "' , 'address':'"+ this.address + "'}"; } } UserActionクラスを作成します。 ユーザーのデータをRedisに保存するためのクラスです。 3分後、自動にExpireされるように設定します。 KeyはユニークなUUID、 Value は JSON でのユーザーのデータです。 package jp.co.jedis; import java.util.UUID; import redis.clients.jedis.Jedis; public class UserAction { private static final int TIMEOUT = 3*60; //3分 public static void main(String[] args) { String userToken = UUID.randomUUID().toString(); System.out.println("user token: " + userToken); Jedis jedis = new Jedis("localhost"); User user = new User("tanaka", "Tokyo-shibuya"); //3分後、無効になる jedis.setex(userToken, TIMEOUT, user.toString()); jedis.close(); } } Eclipse で実行してみましょう。 Redisのクライアントで確認しましょう。 127.0.0.1:6379> get a62a05d0-1efe-4d09-99f1-4289ff1511a6 -> 3分以内の場合 "{'username':'tanaka' , 'address':'Tokyo-shibuya'}" 127.0.0.1:6379> get a62a05d0-1efe-4d09-99f1-4289ff1511a6 -> 3分以上の場合 (nil) 127.0.0.1:6379> a62a05d0-1efe-4d09-99f1-4289ff1511a6 は生成されたKey、ユニークなUUIDです。 セッション管理としてRedisを使用するメリットは以下になります。 メモリ上に格納するのでパフォーマンスがよい Webサーバーの負荷が減る 別サーバーでセッション管理するので、Webサーバーのロードバランサを問題なく構成することができる ロードバランサを構成するには以下のような構成となります。 最後に セッション管理としてRedisを使用する方法や Java でRedisにアクセスする方法を紹介しました。 Redisはまだたくさんオプションがあります。 例えば接続数ハンドル、 トランザクション 、 クラスタ ーなどをもっと知りたい方は https://github.com/xetorthio/jedis/wiki を参照ください。 参考資料 https://blog.takanabe.tokyo/2014/12/%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%81%AE%E5%91%A8%E8%BE%BA%E7%9F%A5%E8%AD%98%E3%81%BE%E3%81%A8%E3%82%81/ Redis Home · redis/jedis Wiki · GitHub エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com
アバター
はじめに 皆さんこんにちは、rs_tukkiです。今年新卒で ラク スに入社しましたピッカピカの一年生です。 普段仕事や授業に取り組んでいると、「あれ、この単語どういう意味だろう?」と思っても、さも知ってて当然かのように話が進むせいでなかなか聞けなかったりすることありますよね。大丈夫です。 私も割と多いです。 そんな「今更聞けない」言葉ですが、皆さん、こんな単語をご存知でしょうか。 「 クラウド 」 …はい、おそらく、知らない方はいないはずです。ですが、 「 クラウド サービスとか、最近よく聞くけどどんなサービスなの?」 「なんかデータを預けるとか聞いたことがあるけど、いざ質問されるとわからないな」 という方も多いでしょう。 そこで今回は、 ラク スのシステムの根幹を担う「 クラウド 」が、どんなサービスなのかということについて、一から解説していこうと思います。 目次 はじめに クラウドとは? 概要 クラウドという名前が生まれた背景 クラウドの使用例 クラウド使用によるメリット・デメリット 個人向けクラウドサービスのメリット 個人向けクラウドサービスのデメリット 企業向けクラウドサービスのメリット 企業向けクラウドサービスのデメリット クラウドサービスの分類 SaaS(Software as a Service) PaaS(Platform as a Service) IaaS(Infrastructure as a Service) おわりに クラウド とは? 概要 さて、 クラウド についてネットで調べてみると、たまにこういう記述が見つかります。 「 クラウド の定義はとても曖昧です」 「定義や意味は曖昧である」 …さすがにこれでは元も子もないですね。 ですが、なんとか一言で「 クラウド 」を説明するのであれば、おそらく 「ユーザ一人ひとりがソフトやサーバを用意しなくても、ネットワークを通じてそれらを使うことが出来る、という考え方」 とするのが正しいと思います。 私たちが今までサービスを利用するには、専用のソフトウェアをインストールしたり、サーバを一から作る必要がありました。それが、 クラウド によって「どこにあるか分からないけど、ネットワークの中から、必要な時に必要な量を取り出して利用する」ようになったのです。 クラウド という名称ですが、どこにあるかは分からない、けどどこかにある、というイメージが雲(=cloud)の中を手探りで操作しているように見えた、とか、ソフトやサーバを一極集中させていることから、ユーザがそこに群がっている(=crowd)ように見えた、など単語の意味自体には諸説あるようです。 クラウド という名前が生まれた背景 「 クラウド 」という言葉を最初に使用し始めたのは、当時の米 Google 社 SEO エリック・シュミット 氏だと言われています。これは2006年8月のことですが、実は有名な クラウド サービスの一つである Gmail は、2004年には既に稼働が始まっていました。 つまり クラウド という言葉は、技術の登場と同時に誕生したのではなく 「元々存在していた技術に名前を付けたもの」 ということになります。 なぜ、わざわざ名前を付けるようなことをしたのでしょうか。 それは、当時多くのサービスが「 クラウド ではなかった」からなのです。例えば、ワードやエクセル、パワーポイントなどのアプリケーション。これらは、当然自分のパソコンの中にインストールしなければ使えませんし、作成したデータも(USBなどの外部領域を使わないのであれば)一般的には、そのパソコンの中に保存しています。 このような非 クラウド なサービスでも問題はないのですが、 Gmail などの誕生を機に「この形式でサービスを作れば、より便利になるんじゃないか」という流れが生まれました。そのため、「ユーザがそれぞれの領域にソフトやデータを確保する」という今までの使い方に対して、これからは「ネットワークにソフトやデータを配置して、場所は分からないけど簡単に使えるようにしよう」、ということを簡単に表す言葉として、「 クラウド 」が使われ始めたのです。 クラウド の使用例 さて、実際の クラウド の使用例についてですが、先ほど挙げた Gmail などのメールサービスをもとに説明します。 私たちがメールを送る際は、パソコン上でメールを作成や送受信を行うための「メールソフト」と、実際に送受信を制御するための「メールサーバ」が必要です。 メールソフトは Outlook や Becky! 、 Thunderbird などのソフトをインストールすればいいのですが、メールサーバの構築を クラウド なしで実現しようとすると結構大変です。企業であれば社内のメールサーバを持っているところもあるものの、個人で構築するのは手間ですし、あまり意味はありません。 一方、 Gmail や Hotmail などの、 クラウド サービスとして提供されているメールサービスでは、私たちユーザが用意するものは「インターネットに接続できるブラウザ」だけで十分です。ソフトのインストールも、サーバの構築も必要なく、 「どこにあるかはわからないけど、どこかにあるソフトとサーバを使わせてもらう」 ことで、メールの送受信を実現しているのです。 クラウド 使用によるメリット・デメリット ただ、 クラウド サービスは便利なだけではなく、当然デメリットも存在します。個人向け、企業向けの クラウド サービスごとに、主な例を挙げて説明します。 個人向け クラウド サービスのメリット どこからでも、どんな端末からでもアクセスできる 企業、個人問わず、 クラウド サービスにおいて最もメリットを体感できるのはこれだと思います。わざわざSDカードや USBメモリ を使ってデータを移し替えなくても、データはインターネット上のサーバに保存されていますから、他のデ バイス でもログインするだけでデータの共有が可能になります。買い物に行くとき、自宅のパソコンで欲しい商品を調べてメモしておいて、それを スマートフォン で確認する、といったことが可能になります。 更新作業が不要 パソコンでも スマートフォン でも、インストールして使用するタイプのソフトは、定期的なアップデートが必要でした。ですが、 クラウド サービスはソフトの更新をサーバ側で行ってくれるため、煩雑な更新作業や、それに伴うシステムの不具合に悩まされる必要もなくなるのです。 個人向け クラウド サービスのデメリット データ漏洩・紛失の可能性 クラウド はインターネット上にデータを保管するわけなので当然と言えば当然なのですが、ログイン情報の流出や、その他サーバ側の不手際によって、簡単に個人情報が流出してしまう可能性があるわけです。前者はともかく、後者は使用者にとってはどうしようもないので、信頼のおけるサービスを使うようにしましょう。 また、サーバ障害、サービス自体の廃止など、 クラウド 上に保存しておいたデータがいつのまにかなくなっていることも考えられます。大切なデータは、自分の手元にバックアップを取るようにした方が無難です。 企業向け クラウド サービスのメリット どこからでも、どんな端末からでもアクセスできる 先ほど個人向けでも説明した内容と同じです。ネット環境さえあれば、たとえ出張先でも使えます。 コスト削減 ここでいう「コスト」とは、「初期コスト」と「保守・管理コスト」の2種類に分けられます。 クラウド を用いず、自社でサーバやシステムを用意しようとすると、どうしても最初の環境整備や、稼働開始後の保守・管理に費用や人員を割かなければいけません。しかし、 クラウド サービスにおいては、特に小規模のシステムで初期費用が抜群に軽減されるほか、煩雑なアップデート作業も管理会社が請け負ってくれるため、そのためのコストも削減が見込めるのです。 企業向け クラウド サービスのデメリット データ漏洩の可能性 個人向けでも説明した内容ですが、企業向けの クラウド サービスでは扱うデータの性質上、よりハッキングの攻撃対象になりやすいというリスクがあります。当然企業向けの有料サービスであれば管理会社が何らかの対策はしてあるでしょうが、その面もきちんと確認しておくのが堅実かと思います。 クラウド サービスの分類 ここまで説明してきた クラウド サービスの提供形態ですが、実は更に細かく分類することができます。 SaaS (Software as a Service) SaaS は、 クラウド によってソフトウェアを提供するサービスのことです。先ほど例として挙げた Gmail や、 Google Drive などのサービスは代表的な SaaS と言えるでしょう。 その他、個人向けでは DropBox 、企業向けでは Salesforce など、普段から皆さんがよく使っている「 クラウド サービス」は、ほとんどがこの SaaS だと思います。 PaaS(Platform as a Service) PaaSとは、 クラウド によって開発環境を提供するサービスのことです。有名なところだと Google App Engine や Microsoft Azureなどがあります。 SaaS とは違い、PaaSとIaaSはエンジニア以外が使うことはあまりないと思います。利用者は提供された開発環境の上で ウェブサービス を開発し、更に提供しているのです。 IaaS(Infrastructure as a Service) IaaSとは、 クラウド によってサーバを提供するサービスのことです。各種 レンタルサーバ などはIaaSに含まれます。 PaaSより更に範囲が狭まって、サーバのみの提供となっていますが、開発環境から自分で用意できるため、自分の好きなプラットフォームで開発したい、という人はこちらを使うことになります。 おわりに 最近よく聞くけど、改めて考えてみるとイメージのつかめない「 クラウド 」という言葉について解説しました。 私自身大学で クラウド システムを用いたゲームを開発していたことがあるので すが、意外と知らないことが多く苦戦しました 改めて勉強し直すいい機会になったと思います。 今回の記事で、少しでも皆さんの「?」が解消出来たら幸いです! エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com
アバター
はじめに 皆さんはじめまして。新人エンジニアの sts -250rrです。 本年度新卒として入社し、1年目の私ですがよろしくお願いいたします。 Git初心者である方の中には、Gitの大枠がどんなものかは知っているし、使ったこともある。 でも 機械的 に git status , git add -A としていたり、 git commit をしていた。 というような方もおられるのではないでしょうか? (私はその口でした・・・) 各コマンドの正しい知識を持たずに 機械的 にコマンドを実行するのでは、 業務を行う上で正しい操作ができないことも考えられます。チームの開発ではなおさら御法度といえるでしょう。 私自身含め、そのような方が今後Gitで失敗をしてしまわないように手助けができればと思います。 本記事では、ローカル環境で作業をする際のGitの構成である リポジトリ やワークツリー・インデックスに関してまとめ、利用するコマンドがどのような操作であるのかを再確認していきます。 それらを把握したうえで、よく利用するGitコマンドをシーン別に分けて紹介し、コマンドによる操作のイメージを持っていただきたいと思います。 加えて、コミットの流れやコミットで失敗してしまったときの対処法も載せておきましたので、困ったときの参考になると幸いです。 はじめに リポジトリ・ワークツリー・インデックスって? シーン別:よく使うGitコマンド 編集を確認したいとき 編集したものをリポジトリにコミットしたいとき addやコミットを取り消したいとき コミットするときの流れ コミットで失敗したとき おわりに リポジトリ ・ワークツリー・インデックスって? Gitではローカルで作業する際に以下のような構成でプロジェクトを管理しています。 この部分の構成を理解していると、addやcommitによってどのような操作がなされるのかがわかってくるかと思います。 リモー トリポジ トリ[Remote repository] サーバに配置されており、複数人でプロジェクトを共有する場所。 *本記事での話題の対象ではありません。 ローカル リポジトリ [local repository] ローカル環境内でのプロジェクトのファイルや ディレクト リの変更履歴を記録する場所。 ヘッド[HEAD]:最新のコミット状態を示す。 インデックス[index] ローカル リポジトリ にコミットを行う準備をする場所。ワークツリーから登録された内容を git commit でコミットする。 インデックスが存在することで、ワークツリー内の必要のないファイルはコミットしないといったことができる。 ワークツリー[work tree] 実際に作業を行っている ディレクト リであり、編集を行った最新のファイルが存在する。 ここでの作業内容を git add することでインデックスに変更を登録する。 これらローカル内の3つの構成により、Gitではプロジェクトの管理が行われています。 この部分が理解できれば add や commit 、それらの操作を取り消す reset といった操作が理解しやすくなったのではないでしょうか。 シーン別:よく使うGitコマンド 前節まででローカル環境でのGitの構成の大枠は掴んでいただけたでしょうか? 本節では、多様なgitコマンドの中からよく使うコマンドを3つのシーンに分けてまとめています。 逆引きのように利用していただけると幸いです。 編集を確認したいとき log git log :最新までのコミットログを確認。 git log --oneline :コミットログを簡潔に確認。 status git status :ローカルで編集されたファイルの一覧を表示。 diff git diff :インデックスとワークツリーの全ての差分を表示。 git diff ファイル名 :インデックスとワークツリーのしてファイルの差分を表示。 編集したものを リポジトリ にコミットしたいとき add git add -A :ワークツリーの内容をすべてインデックスに登録。 git add <ファイル名> :編集した1ファイルのみをインデックスに登録。 git add <ファイル名1> <ファイル名2> :複数の編集をインデックスに登録。 commit git commit :インデックスの内容を全てコミットする。 git commit -m 'message' :コミットと同時に1行メッセージを書く。 addやコミットを取り消したいとき reset git reset :git addの内容を取り消す。 git reset --soft HEAD^ :直前のコミットのみを取り消す。 git reset --hard HEAD^ :現時点のインデックスやワークツリーごと直前のコミットを取り消す。 コミットするときの流れ 本節では実際コミットをするまでの流れを以下のTest. java ファイルと共に確認していきます。 public class Test { public static void main( String [] args) { } } Test. java にある編集を加えました。編集は正しく反映されているでしょうか? 自身の編集が完了したら git status で現在の状態を確認します。 $ git status On branch master Changes not staged for commit: (use " git add <file>... " to update what will be committed) (use " git checkout -- <file>... " to discard changes in working directory) modified : src/test/ Test .java no changes added to commit (use " git add " and / or "git commit -a") Test. java に変更があったようです。ソース内ではどのような変更があったのか git diff で確認します。 $ git diff diff --git a/src/test/ Test .java b/src/test/ Test .java index 8e11c08..b625295 100644 --- a/src/test/ Test .java +++ b/src/test/ Test .java @@ -2 , 5 + 2 , 6 @@ package test; public class Test { public static void main( String [] args) { + System .out.println( " Test " );^ M } } 出力部分が追加されたようですね。ではこの編集をインデックスに登録しましょう。 確実にインデックスに追加したい自身の編集ファイルのみ git add src/test/Test.java で登録しましょう。 再度、現在の状態を確認します。 $ git status On branch master Changes to be committed: (use " git reset HEAD <file>... " to unstage) modified : src/test/ Test .java Changes not staged for commit: (use " git add <file>... " to update what will be committed) (use " git checkout -- <file>... " to discard changes in working directory) インデックスに登録されている様子が確認できました。 それではコミットしていきましょう。 $ git commit -m ' Test出力の追加 ' [master 2eb4313] Test出力の追加 1 file changed, 1 insertion(+) 問題なくコミットできたようです。 最後にコミットの履歴のログを確認しておきましょう。 $ git log --oneline 2eb4313 ( HEAD -> master) Test出力の追加 8823cc3 Test .javaの作成 97fde21 first commit ここまでの作業が完了すればローカルでの編集内容が履歴として記録されることになります。 以降は同様に編集→コミットしていけばよいわけですね。 個人的にコミットまでの注意点は git diff で変更差分を確認すること。 git add で必要のないファイルまでインデックスに登録しないこと この2点だと思っています。 この点を意識できているかどうかだけでも、Gitに対する理解が深まるのではないでしょうか。 コミットで失敗したとき 次に、今までやってきた「addやcommitをやり直したい」そんなときの流れを簡単に確認します。 例として、前節で行ったコミットが間違えていたのでなかったことにしましょう。 git reset のオプションを指定して直前のコミットをなかったことにします。 $ git reset --soft HEAD ^ ログやステータスを確認してコミットが取り消されていることと現在の状態を確認します。 $ git log --oneline 8823cc3 ( HEAD -> master) Test .javaの作成 97fde21 first commit $ git status On branch master Changes to be committed: (use " git reset HEAD <file>... " to unstage) modified : src/test/ Test .java 直前のコミット Test出力の追加 が取り消されています。 ここまでで、直前のコミットを取り消し、編集内容がインデックスに登録されているという状態が確認できました。 次にこのadd自体も取り消してみましょう。 この場合はオプション無しの git reset です。 $ git reset Unstaged changes after reset: M src/test/ Test .java $ git status On branch master Changes not staged for commit: (use " git add <file>... " to update what will be committed) (use " git checkout -- <file>... " to discard changes in working directory) modified : src/test/ Test .java no changes added to commit (use " git add " and / or "git commit -a") addされた内容がインデックスの登録から外れた様子も確認できました。 ここまでで直前のコミットを取り消し、編集内容も取り消しました。つまり、2つ前のコミットの状態まで戻ったことになります。ここからは引き続き作業を行っていきましょう。 おわりに 最初にも述べたように 機械的 に行う commit や add はGitを利用していく上で良いことではありません。 自身が利用するツールに関してはどのような利用方法があるのか、どのような操作であるのかを確認して利用していくと良いかと思います。 自身の学習を踏まえた記事ではありますが、読んで頂いた方々の参考になれば幸いです。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com
アバター
デベロッパ ーのkyosimotoです。 Ansibleをバージョンアップ作業の自動化ツールとして導入するための手順、おすすめ構成などについて紹介させていただきます。 目次 目次 なぜAnsible どんな感じ? Ansibleの基本 実行方法 実行イメージ マシン要件 ファイル構成 ディレクトリ構成(サンプル) playbook(サンプル) ファイル構成のポイント 検証環境の準備 検証環境の説明 検証用仮想マシンの構築手順 仮想サーバにSSH接続する Ansible実行環境の構築 Ansibleのインストール SSH接続設定 検証用仮想マシンのミドルウェアセットアップ WEBサーバの構築 (Apache2.2 + PHP7.1) DBサーバの構築(PostgreSQL9.6) WEB/DBサーバの連携チェック プロジェクトディレクトリ作成 バージョンアッププロジェクト用のディレクトリ作成 Inventoryの作成 Inventoryの作成(補足) Playbookの作成 ansible.cfgの作成 Roleの作成 ミドルウェアの起動 (補足)ミドルウェアの起動 ミドルウェアの停止 ミドルウェアのバージョンアップ playbookの実行 最後に なぜAnsible 私は担当サービスのバージョンアップ作業を自動化するため、シェルベースの スクリプト を開発・運用してきました。 スクリプト 導入により、ほとんどの作業は自動化され、運用コストは大幅に削減されました。 半面、バージョンアップ スクリプト の属人化が課題となっており、リリース時のトラブルが起きた場合に、作業担当者による 原因調査と復旧作業が難しい状態となっています。 シェルスクリプト で作成したバージョンアップ スクリプト には、 フレームワーク のような拘束力が無く、長い運用の中でイレギュラーケースに対応したコードやフラグが追加され、複雑化の道をすすみ続ける可能性があります。 さらには、今のところこの複雑化した スクリプト をポジティブに学習したいという人はいません。問題が起きたとしても、開発担当者に聞けばすぐに解決できるからです。 私は属人化を解消するためには、 シェルスクリプト による実装をやめ、学習コストが低く複雑なコードを生まない自動化ツールの導入が必要と考えており、この要件にマッチしたAnsibleを導入提案することになりました。 どんな感じ? 今のところメリットと感じているのは下記3点です。 学習コストが低い 設定ファイルは YAML という形式で記述します。設定ファイルがシンプルで、初めての人でも内容をすぐに理解できると思います。 運用作業用のモジュールが充実していますので、プログラミング書くことも読むこともほとんどありません。 導入コストが低い 管理対象サーバには余計なツールやデーモンをインストールする必要がありません。 SSH と Python さえ使えれば、Ansibleからの操作が可能ですので、運用チームへも提案しやすいと思います。 運用コストが低い 少しの工夫で設定ファイルをそのまま手順書として扱うことができます。 Ansibleの基本 実行方法 Ansibleの実行コマンドは以下の通りです。 $ ansible-playbook -i { Inventory } { Playbook } Inventoryには、サーバ名や IPアドレス などの管理対象ノードの情報、Playbookには管理対象ノードで実行するタスクを記述します。 実行イメージ Ansibleは、上記コマンドを実行するとPlaybookの内容を Python のプログラムに変換します。 変換されたプログラムファイルは、Inventory(インベントリ)に記述された管理対象ノードに転送後に実行されます。 マシン要件 対象 要件 コン トロール マシン ・ Python 2 (version 2.6 or 2.7)、またはPython3(version 3.5以上)がインストールされている。 ・ Windows はサポート対象外。   (詳細) 管理対象ノード ・ SSH 接続できる。 ・ Python 2.6以上がインストールされている。   (詳細) ファイル構成 私のお勧めするファイル構成サンプルを紹介します。 ディレクト リ構成(サンプル) myapp_verup product.ini # inventory (本番環境のホスト名/IPを記述) staging.ini # inventory (ステージングのホスト名/IPを記述) development.ini # inventory (社内検証環境のホスト名/IPを記述) versionup.yml # playbook (バージョンアップ手順を記述) roles/ # 具体的バージョンアップ手順を実装するディレクトリ apacheを停止する/ apacheを起動する/ apacheをバージョンアップする/ cronを停止する/ cronを起動する/ postgresqlを停止する/ postgresqlを起動する/ postgresqlをバージョンアップする/ アプリケーションをバージョンアップする/ playbook(サンプル) 以下、playbookファイルの内容です。 - myapp_verup/versionup.yml --- - hosts : all roles : - cronを停止する - hosts : webservers roles : - apacheを停止する - apacheをバージョンアップする - phpをバージョンアップする - アプリケーションをバージョンアップする - hosts : dbservers roles : - postgresqlを停止する - postgresqlをバージョンアップする - postgresqlを起動する。 - hosts : webservers roles : - apacheを起動する - hosts : all roles : - cronを起動する ファイル構成のポイント ファイル構成を考える上で、お勧めするポイントは下記2点です。 playbookを日本語で記述する playbookのタスクを日本語化することで、設定ファイルの可読性が上がる、playbookがそのまま手順書/ドキュメントになるという点でメリットが大きいと考えています。 バージョンアップ作業に集中する。 バージョンアップ作業以外のタスクを含めないようにします。 例えば、サーバ構成管理や冪等性のための実装を行うと、Ansibleの設定は複雑化します。 複雑化は属人化を進行させますし、(Serverspecなど)ツールを使ったテストなども検討する必要がでてくるでしょう。 検証環境の準備 ここからは、Ansibleの検証用環境の構築手順について記載します。 検証環境の説明 仮想マシン の構築に Vagrant + Virtualbox を利用します。 検証用に構築するサーバは以下の通りです。 ホスト名 IPアドレス OS MW/Tool control 192.168.33.100 CentOS 6.9 Ansible web 192.168.33.101 CentOS 6.9 Apache2.2 + PHP7.1 db 192.168.33.102 CentOS 6.9 PostgreSQL9.6 別の ディストリビューション で検証したい場合は、 Vagrant Cloud よりboxイメージを検索し、後述する「 vagrant init」コマンドの引数に指定してください。 検証用 仮想マシン の構築手順 # Vagrantの作業用ディレクトリを作成します。 $ cd $ mkdir -p vagrant_work/ansible_test $ cd vagrant_work/ansible_test # Vagrantの作業用ディレクトリを初期化します。 $ vagrant init bento/centos-6. 9 # 出力されたVagrantfileをエディタで修正します。 $ vi Vagrantfile ----- # config.vm.box = "bento/centos-6.9" # この行をコメントアウトし、以下の設定をコピペする。 config.vm.define " control " do | node | node.vm.box = "bento/centos-6.9" node.vm.hostname = "control" node.vm.network :private_network, ip: " 192.168.33.100 " end config.vm.define " web " do | node | node.vm.box = "bento/centos-6.9" node.vm.hostname = "web" node.vm.network :private_network, ip: " 192.168.33.101 " end config.vm.define " db " do | node | node.vm.box = "bento/centos-6.9" node.vm.hostname = "db" node.vm.network :private_network, ip: " 192.168.33.102 " end --- -- # 仮想サーバを起動します $ vagrant up # 仮装サーバが起動するまでしばらく待ちます。 仮想サーバに SSH 接続する $ vagrant ssh control # パスワードは「vagrant」 Windows の場合は、ターミナルソフトで接続します。 ホスト 192.168.33.100 user vagrant password vagrant Ansible実行環境の構築 Ansibleのインストールと SSH 設定の手順について記載します。 Ansibleのインストール # Vagrantの作業ディレクトリより仮想サーバにSSH接続します。 $ vagrant ssh control # パスワードは「vagrant」 # EPELリポジトリを追加 $ sudo yum install -y epel-release # Ansibleのインストール $ sudo yum install -y ansible # Ansibleのバージョン確認 $ ansible --version ansible 2 . 3 . 2 . 0 config file = /etc/ansible/ansible.cfg configured module search path = Default w/o overrides python version = 2 . 6 . 6 ( r266:84292, Aug 18 2016 , 15:13:37 ) [ GCC 4 . 4 . 7 20120313 (Red Hat 4 . 4 .7-17) ] SSH 接続設定 接続先サーバへの SSH 接続を簡単にするため SSH 設定を記述します。 $ vi ~/.ssh/config ------------ Host * StrictHostKeyChecking no UserKnownHostsFile=/dev/null Host web HostName 192.168.33.101 User vagrant Host db HostName 192.168.33.102 User vagrant ------------ # 設定ファイルのパーミッションを変更します。 $ vi ~/.ssh/config ------------ Host * StrictHostKeyChecking no UserKnownHostsFile=/dev/null Host web HostName 192.168.33.101 User vagrant Host db HostName 192.168.33.102 User vagrant ------------ # 設定ファイルのパーミッションを変更します。 $ chmod 600 ~/.ssh/config # SSHの公開鍵を登録します。 $ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/vagrant/.ssh/id_rsa): # Enterキー入力 Enter passphrase (empty for no passphrase): # Enterキー入力 Enter same passphrase again: # Enterキー入力 Your identification has been saved in /home/vagrant/.ssh/id_rsa. Your public key has been saved in /home/vagrant/.ssh/id_rsa.pub. The key fingerprint is: # 秘密鍵と公開鍵が作成されます。 ~/.ssh/id_rsa ~/.ssh/id_rsa.pujb # 作成したSSH公開鍵を接続先サーバにコピーします。 $ ssh-copy-id web # パスワードは「vagrant」 $ ssh-copy-id db # パスワードは「vagrant」 # 接続先サーバにパスワードなしでアクセスできることを確認します。 $ ssh web $ hostname web $ exit $ ssh db $ hostname db $ exit 検証用 仮想マシン の ミドルウェア セットアップ バージョンアップ手順の検証用に、予め ミドルウェア をセットアップします。 WEBサーバの構築 (Apache2.2 + PHP7.1) # WEBサーバにSSH接続 $ ssh web # Apacheをインストール $ sudo yum install -y httpd # PHPをインストール $ sudo yum install -y epel-release $ sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6. rpm $ sudo yum -y --enablerepo=remi-php71,epel install php php-cli php-common php-mbstring php-mcrypt php-pdo php-xml php-json php-devel php-pecl-zip php-pgsql $ sudo service httpd restart $ sudo chkconfig httpd on # テストページを作成してApache+PHPの連携確認 $ sudo vi /var/www/html/phpinfo.php -------------- < ?php phpinfo () ; -------------- # ブラウザから http://192.168.33.101/phpinfo.php にアクセスできることを確認 # SSH接続を終了 $ exit DBサーバの構築(PostgreSQL9.6) # DBサーバにSSH接続 $ ssh db # PostgreSQLのインストール $ sudo yum install -y https://yum.postgresql.org/ 9 . 6 /redhat/rhel-6.9-x86_64/pgdg-redhat96-9.6-3.noarch. rpm $ sudo yum -y install postgresql96-server # PostgreSQLの初期設置 $ sudo service postgresql-9. 6 initdb $ sudo vi /var/lib/pgsql/ 9 . 6 /data/pg_hba.conf -------------- # 末尾に追加 host all all 192 . 168 . 33 . 101 / 32 trust -------------- $ sudo vi /var/lib/pgsql/ 9 . 6 /data/postgresql.conf # 接続設定追加(59行目あたり) -------------- #listen_addresses = 'localhost' listen_addresses = ' * ' -------------- # PostgreSQLの再起動 $ sudo service postgresql-9. 6 start $ sudo chkconfig postgresql-9. 6 on # データベース&テーブル作成 $ sudo su - postgres -c " psql " # ココからはSQLモード > \c test > create database test ; > create table t_staff ( id int, name text ) ; > insert into t_staff values ( 1 , ' あああああ ' ) , ( 2 , ' いいいいい ' ) ; > \q # SSH接続を終了 $ exit WEB/DBサーバの連携チェック # WEBサーバにSSH接続 $ ssh web # WEBサーバとDBサーバ間の疎通確認 $ sudo vi /var/www/html/ test .php --------- < ?php $connectString = " host=192.168.33.102 port=5432 dbname=test user=postgres " ; $conn = pg_connect ($connectString) ; $result = pg_query ($conn , " select * from t_staff " ) ; var_dump ( pg_fetch_all ($result)) ; --------- # ブラウザから下記URLにアクセスして、DBレコードが出力されることを確認 http:// 192 . 168 . 33 . 101 / test .php プロジェクト ディレクト リ作成 ファイル構成の項目で紹介したAnsibleプロジェクトを作成していきましょう。 バージョンアッププロジェクト用の ディレクト リ作成 # HOMEディレクトリにプロジェクトディレクトリを作成します。 $ mkdir ~/myapp_verup # フォルダを作成します $ cd ~/myapp_verup $ mkdir -p roles/apacheを停止する/tasks $ mkdir -p roles/apacheを起動する/tasks $ mkdir -p roles/apacheをバージョンアップする/tasks $ mkdir -p roles/cronを停止する/tasks $ mkdir -p roles/cronを起動する/tasks $ mkdir -p roles/postgresqlを停止する/tasks $ mkdir -p roles/postgresqlを起動する/tasks $ mkdir -p roles/postgresqlをバージョンアップする/tasks $ mkdir -p roles/アプリケーションをバージョンアップする/tasks Inventoryの作成 Inventoryでは、管理対象ノードのホスト名、または IPアドレス とグループの定義を行います。 ファイルはINIファイル形式で記述します。 myapp_verup/development.ini [webservers] 192.168.33.101 [dbservers] 192.168.33.102 Inventoryの作成(補足) Inventoryを本番環境用、ステージング環境用、開発環境用に分けて管理することで バージョンアップ対象の切り替えできるようにします。 以下サンプルです。 myapp_verup/product.ini (本番環境用) # 本番環境用のInventory [webservers] 192.168.34.101 192.168.34.102 192.168.34.103 [dbservers] 192.168.34.104 192.168.34.105 myapp_verup/staging.ini (ステージング環境用) # ステージング環境用のInventory # セクション名(グループ名)は同じでIPアドレスのみ異なる。 [webservers] 192.168.35.101 192.168.35.102 192.168.35.103 [dbservers] 192.168.35.104 192.168.35.105 Playbookの作成 Playbookには、バージョンアップ手順を記述します。 (どのサーバでどんなタスクをどのような順番で実行するかを記述します) myapp_verup/versionup.yml --- - hosts : all roles : - cronを停止する - hosts : webservers roles : - apacheを停止する - apacheをバージョンアップする - phpをバージョンアップする - アプリケーションをバージョンアップする - hosts : dbservers roles : - postgresqlを停止する - postgresqlをバージョンアップする - postgresqlを起動する - hosts : webservers roles : - apacheを起動する - hosts : all roles : - cronを起動する ファイルは YAML 形式となりますので、拡張子は「yml」、1行目は「---」としてください。 2行目以降にバージョンアップ手順を記述します。書き方のルールは以下の通りです。 セクション 解説 hosts inventoryに定義したグループ名を記述します。 "all"の場合、inventoryに記述した全サーバを対象に処理を実行します。 roles hostsセクションに指定したサーバで実行するタスクを記載します。 タスクは「◯◯を停止する」「◯◯を起動する」「◯◯をバージョンアップする」くらいの粒度で記述しておき、具体的な処理内容をroles配下のタスク名と同名の ディレクト リ配下に実装します。 ansible.cfgの作成 Ansibleの動作設定を記述するファイルで、INI形式で記述します。 - myapp_verup/ansible.cfg [defaults] # 実行時のログを出力するファイルを指定します。 log_path=/tmp/ansible.log [privilege_escalation] # タスクの実行ユーザをrootに設定します become = true become_user = root Roleの作成 Playbookのrolesディレクティブに記述したタスクの実態をroles ディレクト リの配下作成します。 例えば、「Cronを起動する」というタスクは、roles/Cronを起動する/tasks/main.yml に、処理内容を記述します。 ミドルウェア の起動 service コマンドが準備されている ミドルウェア (デーモン)であれば、「service」モジュールを使って以下のように記述します。 myapp_verup/roles/cronを起動する/tasks/main.yml --- - name : crondを起動する service : name : crond state : started myapp_verup/roles/ apache を起動する/tasks/main.yml --- - name : Apacheを起動する service : name : httpd state : started myapp_verup/roles/ postgresql を起動する/tasks/main.yml --- - name : PostgreSQLを起動する service : name : postgresql-9.6 state : started ※「service」モジュールの使い方は こちら (補足) ミドルウェア の起動 service コマンドが提供されていない ミドルウェア の場合は、「shell」モジュールと「wait_for」モジュールで実装することもできます。 --- - name : 起動コマンドを実行する shell : /usr/local/myapp/apache/bin/apachectl start - name : 80番ポートの疎通確認が終わるまで待機する wait_for : host : localhost port : 80 state : started delay : 1 timeout : 60 shell モジュールは終了 ステータスコード が0以外は、すべてエラーとして処理を中断しますので注意が必要です。 ステータスコード が0以外でも処理を継続する場合には、下記サンプルを参考にしてください。 --- - name : スクリプトを実行する shell : /usr/local/myapp/bin/hoge.sh register : exitStatus failed_when : exitStatus.rc not in [ 0 , 100 ] # 終了ステータスが0 or 100の場合はエラーにしない ※「shell」モジュールの使い方は こちら ※「wait_for」モジュールの使い方は こちら ミドルウェア の停止 service コマンドが準備されている ミドルウェア (デーモン)であれば、「service」モジュールを使って以下のように記述します。 myapp_verup/roles/cronを停止する/tasks/main.yml --- - name : crondを停止する service : name : crond state : stopped myapp_verup/roles/ apache を停止する/tasks/main.yml --- - name : Apacheを停止する service : name : httpd state : stopped myapp_verup/roles/ postgresql を停止する/tasks/main.yml --- - name : PostgreSQLを停止する service : name : postgresql-9.6 state : stopped ミドルウェア のバージョンアップ RPM が yum コマンドでバージョンアップできる場合は、「 yum 」モジュールを利用して「latest」の状態に更新します。 myapp_verup/roles/ apache をバージョンアップする/tasks/main.yml --- - name : RPMを更新する yum : name : httpd state : latest myapp_verup/roles/ php をバージョンアップする/tasks/main.yml --- - name : RPMを更新する yum : name={{ item }} state=latest enablerepo=remi,epel with_items : - php - php-cli - php-common - php-mbstring - php-mcrypt - php-pdo - php-xml - php-json - php-devel - php-pecl-zip - php-pgsql myapp_verup/roles/ postgresql をバージョンアップする/tasks/main.yml --- - name : RPMを更新する yum : name=postgresql96-server state=latest リポジトリ 管理されていない(カスタム RPM をつかっている)場合は、以下設定を参考にしてください。 myapp_verup └ roles └ Apacheをバージョンアップする ├ tasks │  └ main.yml ├ files │  └ myapp_apache2. 2 . 99 . rpm # カスタムPRMを格納 ├ templates │  └ httpd.conf.j2 # テンプレートファイルを格納。拡張子は「.j2」にする。(テンプレートエンジン「Jinja2」を利用) └ vars   └ main.yml # RPMのファイル名やチェックサム値などを記述する ※ ディレクト リ構成については公式ページの Best Practices の「Directory Layout」を参考にしています。 myapp_verup/roles/ Apache をバージョンアップする/tasks/main.yml --- - name : RPMファイルを転送する copy : src=files/{{ rpm_file_name }} dest=/tmp - name : RPMファイルの状態を取得する stat : path : /tmp/{{ rpm_file_name }} register : file_status - name : チェックサム値を確認する fail : msg='MD5 value did not match' when : file_status.stat.md5 != rpm_file_md5 - name : "RPMを更新する ({{ rpm_file_name }})" shell : rpm -Uvh --force --nodeps /tmp/{{ rpm_file_name }} args : chdir : "/tmp" register : verup_result - name : ステータスコードを確認する fail : msg="Failed upgrade rpm." when : verup_result.rc != 0 - name : httpd.confを差し替える template : src=httpd.conf.j2 dest=/usr/local/vanguard/apache/conf/httpd.conf owner=root group=root mode=644 ※「copy」モジュールの使い方は こちら ※「stat」モジュールの使い方は こちら ※「fail」モジュールの使い方は こちら ※「template」モジュールの使い方は こちら myapp_verup/roles/ Apache をバージョンアップする/templates/ httpd .conf.j2 ...中略... # サーバ毎に異なる設定は 2重波括弧と変数名を記述しておきます。 ServerName {{ apache_server_name }}:80 ...中略... ※ 上記変数部分は、例えばInventoryファイルに記述した変数の値に自動で 置き換えることができます。 ...中略... [web:vars] apache_server_name = myapp.example.com ...中略... myapp_verup/roles/ Apache をバージョンアップする/vars/main.yml --- # RPMファイル名を記述します。 # この値はtask/main.ymlで参照されます。 rpm_file_name : "vg_httpd-2.4.25-centos6.x86_64.rpm" # RPMファイルのチェックサム値を記述します。 # この値はtask/main.ymlで参照されます。 rpm_file_md5 : "4f8009b1cbcf5dbc7f082773d2f0d661" playbookの実行 $ cd ~/myapp_verup $ ansible-playbook -i development.ini versionup.yml 実行結果は以下の通りです。 日本語で書いたタスクがそのままターミナル上のログに出力されていることが確認できます。 (/tmp/ansible.log にも出力されます。) 最後に 本記事は、運用チーム向けにAnsibleを使ったバージョンアップ自動化提案後に書いた記事です。 本番運用が開始されれば、いろいろと課題はでてくると思いますので、知見がたまりましたら 改めて情報を共有させていただこうと思います。 以上、ありがとうございました。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
はじめに  こんにちは、mickey-STRANGEです。昨年に新卒で ラク スに入社しました2年目です。  新卒に毛が生えた程度の新米エンジニアですが、今回はその数少ない毛の中から学生時代に意識したことのなかったものという観点で 脆弱性 のお話を選び、記事にしました。新しくWeb開発企業に入社した新卒の方の学習の手助けになればと思います。 目次 はじめに 脆弱性とは? CSRF(クロスサイトリクエストフォージェリ) 概要 対策 確定処理の前に認証を行う リファラを確認する ワンタイムトークンを利用する おわりに 脆弱性 とは?   脆弱性 とは、セキュリティの面からみたシステムの欠陥のことです。 脆弱性 をついて攻撃されてしまうと、ユーザには本来許されていない操作ができてしまったり、サーバにウィルスを仕込まれてしまったりという被害が出ます。  この記事では 脆弱性 の中でも、私が実際に理解に時間のかかった CSRF ( クロスサイトリクエストフォージェリ ) という 脆弱性 の概要と対策をご紹介したいと思います。 CSRF ( クロスサイトリクエストフォージェリ ) 概要  サービスの利用者に意図しないHTTPリク エス トを送信させ、利用者の意図しない処理をサービスに実行させる攻撃です。と、1文で書いてはみるものの、これだけで理解は出来ないと思います(私が勉強したときは理解出来ませんでした)ので、shop. example.com という架空の通販サイトで簡単な例を挙げてみましょう。  shop. example.com ではユーザはIDとパスワードでログインします。利用ユーザがパスワードを変更しようとしたとき(ユーザが新しいパスワードを入力して確定ボタンを押したとき)に送信されるリク エス トが下のようなものだったとします。 URL  http://shop.example.com/password/change パラメータ  new_pass:【新しいパスワード】  new_pass_conf:【新しいパスワード(確認入力用)】  このリク エス トと同じものを作成して送信させる悪意のあるWebページを攻撃者が用意します。 偽装リク エス トを送信さえできればよいのでWebページの用意は難しいことではありません。具体的なコードは示しませんが、 javascript を使って数行で実現出来ます。GETでよければ他の手段でもっと単純に、コードとしては1行でも十分に実現できてしまいます。 (確定処理でGETを使用すること自体が論外ですが。)  さて、shop. example.com のユーザAさんが、攻撃者の用意した悪意のあるWebページを開いてしまったとしましょう。  するとAさんのブラウザから上記リク エス トと同じものが勝手に送信されてしまいます。正規にパスワード変更画面で確定ボタンを押したときのリク エス トと違うところがあるとすれば、パラメータのパスワード部分は攻撃者しか知らないものである、ということだけです。 このときAさんのブラウザに「shop. example.com にログインしている状態のセッション情報」が残っていた場合、その情報もブラウザが同時に送信してしまいます。 そのリク エス トを受け取ったサーバ側のプログラムは Aさんが操作を再開して、パスワードの変更確定ボタンを押した と誤認し、パスワード変更の処理を行ってしまいます。パスワード変更の処理が完了するとAさんはもうログイン出来なくなってしまいます。   CSRF は ログイン済みのユーザに、意図しない操作を強制的に実行させてしまう攻撃 であるといえます。  今回の例ではパスワード変更ですが、これが購入や決済の確定処理で起きてしまうと取り返しがつかないということは簡単に想像出来ると思います。では CSRF がどのような 脆弱性 か分かったところで、 CSRF 攻撃を防ぐためにどのような仕組みを入れればよいかを考えてみようと思います。 対策  では CSRF の対策を考えてみましょう。 上記の通り、 CSRF においてサーバは リクエスト通りに1つの機能を正しく完了している という特徴があります。つまり対策として考えられるのは 受け取ったリクエストに対して処理を実行するかしないかを確認する ことになります。 確定処理の前に認証を行う  一番分かりやすい方法はユーザに確認してもらうことです。重要な処理の前にはユーザにもう一度認証を行う、つまりログインIDとパスワードの入力をしてもらうことになります。今回のパスワード変更の例ですと、以下のようになります。(数字がユーザ操作、→がサーバ処理です。) 1.新しいパスワードを入力して確定ボタン 2.認証画面でログインIDとパスワードを入力  →変更処理を行う  この順番で操作してもらうようになっていれば、今回の例のように1番のリク エス トを偽装されても処理を行ってしまうことはありません。  しかし、この方法で対策するとユーザの操作が増えてしまいます。大事な処理の前だけとしても、ユーザの操作量が増えてしまったり、直感的に進めない画面が表示されると「このサイトは使いにくい、面倒だ」と感じてしまうかもしれません。ユーザに負担をお願いしたくない、ということで次にプログラム側だけで出来る対策を考えてみます。 リファラ を確認する  ユーザ操作を増やさずに出来る CSRF 対策は「送られてきたリク エス トが正しいものか確認する」ことです。ここで正しいリク エス トとは、 サイト内にある確定ボタンを押すことで送信されたリクエスト ということになります。それを確認するために、 リファラ というHTTPヘッダの1つを利用します。   リファラ とは、 リクエスト元のページのURL を示すHTTPヘッダです。処理の前に リファラ の値が http://shop.example.com から始まっているかを確認すれば、偽装リク エス トかどうか判定することが可能です。 1.新しいパスワードを入力して確定ボタン  →リファラのチェックを行う  →変更処理を行う  しかし、この方法ではまだ完璧な対策ではありません。 リファラ はその特性上、プライバシー面に問題を抱えており、ブラウザので リファラ を送信しない設定が可能です。また、前述のとおり、 リファラ はHTTPヘッダの1つです。改竄されてしまっては元も子もありません。 ワンタイム トーク ンを利用する  ワンタイム トーク ンとは、リク エス トが正しいものか判断するための文字列をリク エス トの中に仕込む手法です。  今回のパスワード変更の例ですと、以下のような流れになります。 0.パスワード変更画面を開く  →乱数文字列(トークン)を生成 1.新しいパスワードを入力して確定ボタン(トークンを付与したリクエストを送信)  →サーバ側で保持しておいたトークンとリクエストで送信されたトークンの比較を行う  →変更処理を行う  パスワード変更画面を開く際に トーク ン(乱数文字列)を作成し、セッションなどのサーバ側の領域で一時保存しておきます。また、確定のリク エス トの時にその トーク ンをパラメータに追加して送信させ、サーバ側で トーク ンの照合を行います。サーバ側で保存していた トーク ンと一致すれば処理を行う、一致しなければ不正なリク エス トとして処理を行わない、といった判断が可能となります。  偽装リク エス トがもし トーク ンを勝手に付与したリク エス トを送信してもサーバ側で同じ トーク ンを保持していないので判別できますし、 リファラ とは違いヘッダではなくパラメータなのでユーザ依存で失敗したりすることがありません。今回紹介した中ではこの手法が最も適切だといえるでしょう。 おわりに   CSRF の概要と対策についてご紹介いたしました。いかがでしたでしょうか。 XSS ( クロスサイトスクリプティング )と名前が似ていることで勘違いしやすい 脆弱性 で、自分が理解しづらかった CSRF について記事にしてみました。  Web開発に関する勉強を始めたばかりの方の手助けになれば幸いです。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
みなさんこんにちは。 ぺちぱー 歴5年のフジサワでございます。 今回は、 PHP 開発にはかかせない、PhpStormとGitを連携させて使用する方法をご紹介します。 有償ツールということもあってか、意外とPhpStormを使用したGitの利用方法について詳しくまとめられている記事が少ないので、いっそまとめてしまおうと思い至りました。 本記事では以下の環境をベースに解説しています。 OS: Windows 10 Home Edition PhpStorm: 2017.2.3 なお、今回の記事では、「開発する上でよく使う機能」のうち、基本的な一部の機能しかご紹介していません。 他の機能については、また改めて記事にまとめ、投稿させて頂きます。 目次 PhpStormのGit関連のUIについて まずはここから [git clone] 新しいブランチを作成する [git branch] 変更内容をコミットする [git commit] ローカルの変更をリモートにプッシュする [git push] 作業中のブランチを切り替える [git checkout] ブランチを最新化する [git fetch/merge] 別のブランチの変更を取り込む [git merge] 不要になったブランチを削除する [git branch -D] ブランチ間の差分を見る [git diff] コミット前のソースを元に戻す おわりに PhpStormのGit関連のUIについて まず初めに、PhpStorm上でGitを利用するためのUIについて簡単に解説します。 ① VCS メニュー:[ VCS ] - [Git]配下にcommitやpushといったGitの操作メニューが表示されます。 ②VersionContorolタブ:Git関連の情報を表示するペインの表示切替タブ ③各種Git情報タブ  LocalChanges: プロジェクト中の未コミットファイルや非Git管理下のファイルを表示する。  Log:コミットツリーを表示する。  Console:PhpStorm上から実行した諸々の操作履歴   ※ GUI 上からの操作はすべてGitクライアントにコマンドとして実行されており、ここにコマンド履歴が表示されます。    トラブルシューティング の際はこのログを見ると、エラーや何が実行されているのか分かるので便利です。 ④Git Branches:[Git:[現在のブランチ]]ブランチの切り替えや新規作成など、ブランチ関連の操作はここから実行します。 まずはここから [git clone] 何はともあれ、 リポジトリ をcloneしなければ何も始まりません。 まずは、 リポジトリ をcloneする方法について見てみましょう。 ①PhpStorm起動時のウィザードから[Check out from Version Control] - [Git]を選択する。 ② リポジトリ のURLや ディレクト リの情報を入力して[clone]ボタンを押す。  Git Repository URL: clone対象の リポジトリ のURL  Parent Directory: clone先の親 ディレクト リ  Directory Name: clone先の ディレクト リ名 なお、すでに何かしらのプロジェクトを開いている場合は、以下の手順でもcloneを実行することが可能です。 [ VCS ] - [Check out from Version Control] - [Git]を選択する。 新しいブランチを作成する [git branch] プロジェクトに対して何か変更を加えるため、新しいブランチを作成しましょう。 ①画面右下の[Git Branches]を押下し、表示されるポップアップから[New Branch]を選択する。 ②作成したいブランチの名前を入力し[OK]ボタンを押下する。 ブランチの作成に成功すると、完了メッセージが表示され、現在作業中のブランチが切り替わります。 変更内容をコミットする [git commit] ソースコード に加えた変更をコミットする方法を見てみましょう。 今回はサンプルとして、プロジェクト中のfile-A. php とfile-C. php に変更を加えました。 ①[ VCS ] - [Git] - [Commit FIle...] または ツールバー から[Commit]ボタンを選択する。 ②コミット対象のファイルにチェックを入れ、コミットメッセージを入力する。 ③ダイアログ右下の[commit]を押下し、コミットを実行する。 ここで[commit and push..]を選択することで、コミットとプッシュを一度に実行できますが、ここではコミットのみ実行します。 ④[Verstion Control]から[Log]タブを選択し、ブランチツリーを確認する。 先ほどコミットした内容がブランチツリーに反映されました。 なお、作業 ディレクト リ内の未コミットのファイルは以下の手順で確認することができます。 ①[Verstion Control]から[Local Changes]タブを選択し、作業 ディレクト リの状態を表示する。 ファイル名を右クリックし、[Show Diff]を選択することで、最新のコミットとの差分を表示することができます。 ローカルの変更をリモートにプッシュする [git push] それでは、ローカルの変更をリモートに反映するため、プッシュを実行しましょう。 ①[ VCS ] - [Git] - [Push...]を選択する。 ダイアログが表示され、これからプッシュする差分の情報などが表示されます。 ②[Push]ボタン - [Push]を選択し、プッシュを実行する。 作業中のブランチを切り替える [git checkout] 次に、作業中のブランチを切り替える方法について確認します。 ①画面右下の[Git Branches]を押下し、表示されるポップアップから切り替えたいブランチ名を選択し、[checkout]を選択する。 上の例は、既にローカルブランチとして存在するブランチに切り替える場合を説明したものです。 まだローカルブランチとして存在しないブランチに切り替える場合は、次の通りです。 ①画面右下の[Git Branches]を押下し、表示されるポップアップから切り替えたいブランチ名を選択し、[Checkout as new branch]を選択する。 ②作成するブランチ名を入力する。 ローカルブランチとして展開する際に、任意の名前を付けることが可能ですが、特別な理由がない限り、基本的にはデフォルトで入力されている名前をそのまま使用すれば良いでしょう。 [OK]ボタンを押下すると、ブランチの切り替えが完了します。 さて、PhpStormでGitを利用するうえで、混乱が生じやすいLocalBrancesとRemoteBranchesについて簡単に補足しておきます。 LocalBranches … ローカル上に存在するブランチ。コミットはこのブランチに対して実行される。 RemoteBranches … リモート追跡ブランチ。リモー トリポジ トリとの同期に使用するブランチで、fetchを実行するとリモー トリポジ トリの最新の状態が反映される。 ブランチを最新化する [git fetch/merge] 別の開発者によって、リモー トリポジ トリ側でブランチに加えられた変更内容を取り込む方法を見てみましょう。 ここではmasterブランチに変更が加えられた場合を例に、最新化する手順を確認します。 ①[ VCS ] - [Git] - [fetch]を選択し、RemoteBranchesにリモー トリポジ トリの変更を取り込む。 ②作業 ディレクト リを、最新化したいブランチに切り替える。 ③[Git Branches]から、最新化したいブランチに対応したリモートブランチを選択し、[Merge]を選択する。 上記の操作は、指定したブランチの変更内容を、現在checkoutしているブランチに取り込む操作です。 これでリモート側の変更をローカルに反映することができました。 少々、fetchとmergeの仕組みはわかりにくいので、簡単に解説します。 fetch前とfetch後で、ブランチツリーがどのように変化しているかを確認してみましょう。 ブランチツリー上でコミット履歴にマウスオーバーすると、そのコミットを指しているブランチの一覧を表示することができます。 fetch前の状態を見ると、ローカルブランチとmasterとリモート追跡ブランチのorgin/masterが同じコミットを指していることがわかります。 fetch後の状態をみると、ローカルブランチのmasterが指すコミットは変わりませんが、origin/masterが別の開発者によって行われたコミットを指している状態になっていることが分かります。 この状態では、まだ作業 ディレクト リの ソースコード に変化はありません。 では、fetchの後、mergeを実行するとどうなるでしょうか。 ブランチツリーの変化と ソースコード の変化を見てみましょう。 mergeを実行すると、ローカルブランチmasterの指すコミットが、origin/masterと同じコミットを指すようになりました。 この時、 ソースコード の方はどう変化しているでしょうか。 ご覧の通り、リモート側の変更が ソースコード に反映されています。 なお、一連の作業は[ VCS ] - [Git] - [Pull...]で一括実行することも可能です。 別のブランチの変更を取り込む [git merge] それでは、別のブランチに行われた変更を取り込む方法を見てみましょう。 例では、[master]から派生した別のブランチ[merge-test]に行われた変更を取り込む流れを確認します。 ①[ VCS ] - [Git] - [fetch]を選択し、RemoteBranchesにリモー トリポジ トリの変更を取り込む。 ②作業 ディレクト リを、最新化したいブランチに切り替える。 ③[Git Branches]から、マージしたいブランチを選択し、[Merge]を選択する。 マージが実行されると、デフォルトの設定では以下のようにマー ジログ が追加されます。(fast-forwardについては割愛) ブランチツリー上も、[master]ブランチと[merge-test]ブランチが統合されていることが分かります。 ここでお気づきの方もいると思いますが、「あるブランチを最新化する」という操作と、「別のブランチの変更を取り込む」という操作は、Git上では本質的には同じです。 同じブランチ同士のマージか、異なるブランチ同士のマージかという違いだけで、いずれもブランチ間のマージが行われています。 不要になったブランチを削除する [git branch -D] マージを実行したので、[merge-test]ブランチは不要になりました。 ここでは、ブランチの削除方法を見てみましょう。 ①[Git Branches]から、削除したいブランチを選択し、[Delete]を選択する。 なお、この操作はローカルブランチ、リモート追跡ブランチのいずれにも実行することが可能です。 リモート追跡ブランチを削除すると、自動的にリモー トリポジ トリ上のブランチを削除することができます。 ブランチ間の差分を見る [git diff] 続いて、ブランチ間の差分を確認する方法を見てみましょう。 ここでは、[master]ブランチと[new-branch]の差分を比較してみます。 ①[Git Branches]から、比較したいブランチを選択し、[Compare]を選択する。 ②ダイアログから[Files]タブを選択し、差分ファイル一覧を表示する。 ③確認したいファイルの名前をダブルクリックし、差分を表示する。 コミット前のソースを元に戻す ソースコード の修正をリセットしたい。そんな時はRevertを使用しましょう。 ①[Verstion Control]から[Local Changes]タブを選択し、作業 ディレクト リの状態を表示する。 ②修正を元に戻したいファイルを右クリックする。 ③ コンテキストメニュー から[revert]を選択する。 おわりに さて、いかがでしたでしょうか。 冒頭にも記載している通り、今回はPhpStormでGitを利用するための一部の基本的な機能しかご紹介していません。 別の機会に、rebaseやstash、conflictの解消方法などの重要な機能についても投稿させていただく予定です。 ではまた。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
はじめに はじめまして。新卒入社で3年目のNIR-AMAUQAです。 今回は少し前に触ったnodemailerについて記事を書こうと思います。 具体的にはnode.jsからnodemailerというモジュールを使って、メールを送信してみようと思います。 以前nodemailerを触る機会があったんですが、調査している時に日本語の資料が少なかったり、 見つけても古いバージョンのものが多かったので、記事にしてみようと思いました。 node.jsについて分からない人はこちらをどうぞ Node.js を5分で大雑把に理解する - Qiita いまアツいJavaScript!ゼロから始めるNode.js入門〜5分で環境構築編〜 nodemailerとは 2010年から作られているnode.jsからメール送信を可能にするモジュールで、多くのユーザに利用されています。 ソフトウェアのライセンスはMITです。 Nodemailer :: Nodemailer 目次 はじめに node.jsについて分からない人はこちらをどうぞ nodemailerとは 目次 nodemailerをインストール サンプルプログラムを作成 詳細説明 SMTPサーバ設定 メールヘッダ作成 メール送信処理 実行してみる まとめ nodemailerをインストール では早速、nodemailerをインストールしたいと思います。 npmでインストールする際にモジュール名のみだと最新版をインストールします。 $ npm install nodemailer グローバルの場合は $ npm install nodemailer -g インストールの確認 $ npm list --depth=0 以下のように表示されていれば成功(2017/09/06 時点での最新が4.1.0です。) nodemailer@4.1.0 グローバルの場合は上記のコマンドと同じく末尾に -g を入れて下さい。 もし過去バージョンをインストールしたい場合は以下の書き方でバージョンを指定できます。 @ の後ろにバージョン番号を書いてください。 $ npm install nodemailer@4.0.1 サンプルプログラムを作成 //モジュールの読み込み var nodemailer = require( "nodemailer" ); //SMTPサーバの設定 var smtp = nodemailer.createTransport( { host: 'localhost' , port: 25 } ); //メール情報の作成 var message = { from: 'Fromアドレス' , to: 'Toアドレス' , subject: 'nodemailer test mail' , text: 'テストメールです。' } ; // メール送信 try { smtp.sendMail(message, function (error, info) { // エラー発生時 if (error) { console.log( "send failed" ); console.log(error.message); return ; } // 送信成功 console.log( "send successful" ); console.log(info.messageId); } ); } catch (e) { console.log( "Error" ,e); } 詳細説明 SMTP サーバ設定 //SMTPサーバの設定 var smtp = nodemailer.createTransport( { host: 'localhost' , port: 25 } ); ここで SMTP サーバの設定を行います。 今回はローカルのメールサーバを利用した最も簡単な例です。 nodemailerの記事で探すと Gmail などの SMTP サーバを利用しているものが多いので、 外部の SMTP サーバを利用したい方はそちらを参考にしてください。 nodemailerでGmailから送信するための方法 - Qiita メールヘッダ作成 //メール情報の作成 var message = { from: 'Fromアドレス' , to: 'Toアドレス' , subject: 'nodemailer test mail' , text: 'テストメールです。' } ; こちらも最もシンプルなメールヘッダの例になります。 私の調べた限りではReturn-Pathの設定はできないようです。 ただし、envelopeの設定はできるのでバウンスメールなどをコン トロール したい場合は以下のようにすれば可能です。 //メール情報の作成 var message = { from: 'Fromアドレス' , // 表示名つきにする場合は'表示名<Fromアドレス>' to: 'Toアドレス' ,   envelope: { from: 'envelopeFromアドレス' , // バウンスメールの戻り先アドレス to: 'envelopeToアドレス'     // 実際の送信先 } , subject: 'nodemailer test mail' , text: 'テストメールです。' } ; envelopeを付与した場合は to: 'Toアドレス' はなくても送信可能ですが、メールヘッダのToが無くなってしまうので書いておくのが無難かと思います。 メール送信処理 // メール送信 try { smtp.sendMail(message, function (error, info) { // エラー発生時 if (error) { console.log( "send failed" ); console.log(error.message); return ; } // 送信成功 console.log( "send successful" ); console.log(info.messageId); } ); } catch (e) { console.log( "Error" ,e); } メッセージの送信に失敗するとerrorオブジェクトが返ってきます。 送信先 を消してメール送信に失敗した場合の例 $ node サンプルファイル名.js send failed No recipients defined メール送信に成功すると様々な情報が返されます。 公式のリファレンスによれば以下の情報が返されているそうです。 info.messageId info.envelope info.accepted info.rejected info.pending response 英語が苦手な私が訳すと誤解させる恐れがありますので 詳しくは公式のリファレンス *1 で確認お願いします。 実行してみる 以下のようになればメール送信成功です。 $ node サンプルファイル名.js send successful <Message-IDが出力されている> まとめ 今回はnode.jsにnodemailerを入れてメールを送信してみました。 想定していたよりも手軽にメール送信できました。 node.jsのモジュールに関して日本語の記事が増えてくれると嬉しいので、 私のために 記事を書いてくれると嬉しいです。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com *1 : https://nodemailer.com/usage/#sending-mail
アバター
はじめに はじめまして。開発エンジニアのamdaba_sk( ペンネ ーム未定)です。 ラク スに新卒で入社し、今年で2年目になります。 先日 ラク スオフィス内にあります共用本棚に「知識ゼロから学ぶ ソフトウェアテスト 【改訂版】」を見つけました。 ちょうどテストコードの書き方に悩んでいたところで 勝手に 自主的にこれを読みましたので、少し内容をまとめてみようと思います。 少しネットで「 ソフトウェアテスト 」検索するとたくさんの記事がヒットしますが、めげずに書きます。 目次 はじめに 目次 ソフトウェアのテストを分類してみる 工程による分類 開発者側の工程に対応するテスト 顧客側の工程に対応するテスト 品質の観点による分類 実行方法による分類 技法による分類 テストケース作成技法をまとめてみる ホワイトボックステスト(制御パステスト) ブラックボックステスト 同値分割と境界値分析 例えば… デシジョンテーブル 例えば… 状態遷移テスト ランダムテスト おわりに 参考 ソフトウェアのテストを分類してみる ○○テストという言葉はたくさんありますが、まずは大きく 工程・品質の観点・実行方法・技法 に区別されます。 工程による分類 開発の工程に対応させた分類です。 開発者側の工程に対応するテスト 単体テスト ソフトウェアを構成する最小の要素に対するテスト 言語や 開発プロセス によって「単体」の定義が異なる 統合(結合)テスト 単体同士を組み合わせた全体に対するテスト システムテスト ソフトウェアの全機能に対するテスト 運用時と同じインフラ、ハードウェア、 ミドルウェア を用いて行う 顧客側の工程に対応するテスト 受入テスト 顧客が納品されたソフトウェアに対して行うテスト 自社開発など、行われない場合も多い 品質の観点による分類 どういった品質を確かめる目的で行われるのかという視点に基づく分類です。 機能テスト 機能が正しく実装されているかどうかのテスト 性能テスト・負荷テスト ストレスなく使用できる程度の実行速度がでるかどうかのテスト 負荷テストでは必要な性能を満たせる限界を見極める ユーザビリティ テスト 「使いやすい」かどうかを確認するテスト セキュリティテスト 外部からの攻撃に耐えられるかどうかのテスト etc... 実行方法による分類 その名の通り、テストの実行方法による分類です。 動的テスト テストのためにソフトウェアを実行するテスト方法 静的テスト ソフトウェアを実行せずに行うテスト コードレビュー、静的解析、etc... 技法による分類 テストのためにはどのような操作をして何を確認するかを定めた「テストケース」を作成します。テストケース作成に用いる技法による分類です。 ホワイトボックステスト ブラックボックステスト (グレーボックステスト) テストケース作成技法をまとめてみる ホワイトボックステスト (制御 パステ スト) ホワイトボックステスト はプログラムの論理構造が正しいかどうかのテストです。デバッガでステップ実行などしながら、それぞれの行、それぞれのブロックで実行される文は正しく書かれているか、if分やswitch文の条件は適切か、きちんと終了まで実行されるかを確認します。 このテストの実行によって カバレッジ 率 が算出され、プログラムの品質を計る一つの指標となります。 ホワイトボックステスト で焦点となるのはあくまでプログラムの論理構造なので、以下のような不具合は見つけられません。 要求仕様自体の誤りや不備 データに関するバグ マルチタスク や割込みに関するバグ ブラックボックステスト ブラックボックステスト は名前の通りプログラムを一種の ブラックボックス として扱うテストで、様々な入力に対して妥当な出力が返されるかどうかを確認します。 ですが多くのプログラムでは可能な入力の組み合わせは膨大で、それらをすべて試すことは不可能です。そこで効果的な入力をもれなく選び取る方法が考案されています。 同値分割と境界値分析 同値分割と境界値分析は、 ブラックボックステスト 手法の中でも基本的な手法です。 同値分割 では入力全体の集合を「 同値クラス 」という部分集合に分割します。 同値クラス は、同じ 同値クラス の入力であればプログラムの動きに本質的な違いが出ないような入力の集合です。多くはプログラムが期待する入力値である「有効同値」、そしてそれ以外のあらゆる入力値である「無効同値」に分けられます。 それぞれの入力項目ですべての 同値クラス の入力を行えば、あらゆる入力に対してテストされたことになります。 境界値分析 では 同値クラス 同士の境界に注目します。 同値クラス の境界は条件文によって分けられることが多く、これを書き間違えることでバグになります。 そこで境界をまたぐもっとも近い入力の組を入力とすることで処理の切り替えがきちんとなされていることを確かめます。 例えば… 1から10までの 自然数 を受け付ける入力項目に対して 0を入力 1 (無効同値①、境界値)⇒ 入力エラーになる 1を入力(有効同値、境界値)⇒ 正常に処理される 2 5を入力(有効同値)⇒ 正常に処理される 10を入力(有効同値、境界値)⇒ 正常に処理される 11を入力(無効同値②、境界値)⇒ 入力エラーになる デシジョンテーブル 同値分割や境界値分析は、入力項目が複数 ありさ らにそれらが相関している時には大変ややこしくなります。 デシジョンテーブル ではそれらの入力の組み合わせを表にして、各組み合わせに対して期待される出力をまとめていく方法です。 複雑な状態が絡み合う機能のテストで有効です。 例えば… 入力項目が2つあって、両方に1から10までの 自然数 が入力された場合のみ処理がされる場合 条件 組み合わせ 入力項目Aが1-10の範囲内 Yes Yes No No 入力項目Bが1-10の範囲内 Yes No Yes No 動作 処理実行 エラー エラー エラー 状態遷移テスト ソフトウェアによっては「状態」が複数存在し、操作することでそれらの状態間を行き来する場合があります。状態によって受け付ける入力や出力を変化させています。 状態遷移テスト はそういった場合に、入力に対して正しく状態遷移(出力)するかどうかをテストします。 ランダムテスト ランダムテストはこれまでの ブラックボックステスト 手法とは毛色が違っていて、事前にテストケースなどを作成せずにやみくもに入力や操作を行うテスト手法です。 結構なバグがこれで見つかるようですが、機能要求に対するテストでは あまり有効でない とのことです。ただし、セキュリティに対するファジングテストという形でランダムテストが活用されています。 おわりに 参考図書、参考ページをもとに、 ソフトウェアテスト の分類と、その中でテストケース作成技法についてまとめてみました。簡単ではありましたが、この記事を読んでくれた方が ソフトウェアテスト の勉強をするきっかけになれたなら幸いです。 参考 高橋 寿一 (著) 知識ゼロから学ぶ ソフトウェアテスト 【改訂版】 http://gihyo.jp/dev/serial/01/tech_station/0001?page=1 http://b.hatena.ne.jp/entry/qiita.com/ktarow/items/8c3d94d6c21a0c86b799 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com 0はいろいろな意味で特別なので、仕様的に境界値でなくともテストした方が良いです。 ↩ 実際はここは仕様に合わせて具体的に書きます。 ↩
アバター
先日、仕事で JMeter を使わせていただく機会がありました。Y-Kanohと申します。 とはいえ、新卒2年目の私には何のことかさっぱりで...先輩に教えていただきながらの作業でした。 せっかくブログを書く機会があるので、同じ境遇の人が、「え、LatencyとSample Timeってどう違うの?」「実際にテストしたらコンピュータがフリーズした!!」「2時間たっても終わらないけど、どうすれば...(焦)」とならないように、簡単な例を用いて JMeter の使い方を紹介します。 そもそもJMeterって? スレッドグループの追加 送信するHTTPリクエストの追加と設定 スレッドグループの設定 Ramp-Up期間 スレッド数とループ回数 テスト計画作成の注意点 リスナーの追加 テスト計画の実行と結果の見方 おわりに   そもそも JMeter って? JMeter は Apache ソフトウェア財団が開発している オープンソース の負荷検証ツールです。 サーバに対して指定した量のリク エス トを送り、そのレスポンスを受けることで、パフォーマンス計測することができます。 JMeter は Apacheの公式サイト からダウンロードできます。 ( Java を入れていない方は、インストールしてからご使用ください。) JMeter は GUI モードとNon- GUI モードがありますが、ここでは GUI モードの説明をします。 今回は例として、サーバ192.168.99.100のtest.htmlに2つのパラメータ「param1」と「param2」を送信する例を考えます。 スレッドグループの追加 以下が JMeter の起動画面です。 ダウンロードしたファイルの bin ディレクト リにある jmeter.bat ( Windows ) もしくは jmeter ( Unix )を実行することで開きます。 まず、テスト計画を作成するため、スレッドグループを作成します。 左上の「テスト計画」を右クリックし、 追加 > Threads(Users) > スレッドグループ を選択してください。 新しいスレッドグループが作成されます。 スレッドグループの設定画面でも設定することがあるのですが、今はひとまず置いておきましょう。 送信するHTTPリク エス トの追加と設定 次にスレッドグループで送信するリク エス トを設定します。 今回は一番基本的なHTTPリク エス トを送るため、 左画面のスレッドグループ名を右クリックし、 追加 > サンプラー > HTTPリクエスト を選択し、 作成された「HTTPリク エス ト」にてWebサーバとリク エス トの設定を行います。 まず、リク エス トを送信するWebサーバの設定。 「 プロトコル 」にはhttpを入力し、「サーバ名またはIP」には負荷検証を行うサーバを指定します。 次に、HTTPリク エス トの設定です。 「メソッド」には、送信メソッドを指定します。とりあえず、今回は「GET」を指定。 「パス」 には、リク エス ト 送信先 のリソースを指定します。 送信するリク エス トパラメータを設定します。 画面下の「追加」ボタンから複数追加することができ、パラメータの名前と値をそれぞれ指定することができます。 これで、送信するHTTPリク エス トを設定できました。 スレッドグループの設定 さて、HTTPリク エス トが設定出来たら、スレッドグループの設定に戻りましょう。 スレッドグループでは、先ほど設定したHTTPリク エス トをどのように、どれぐらいの量、どれぐらいの期間で送信するかを設定できます。 *1 これらを決定するのが、スレッド数、Ramp-Up期間、ループ回数 です。 Ramp-Up期間 Ramp-Up期間が一番わかりやすいでしょうか。 Ramp-Up期間は、全リク エス トの作成時間です。 「スレッド数」で設定したリク エス ト群を、何秒間で作成するかを決めるのがRamp-Up期間です。 例えば、Ramp-Up期間を100(秒)、スレッド数を10とすると、 JMaterは100秒かけて10スレッド分のリク エス トを送信しようとします。 ただし、Ramp-Up期間はあくまで「リク エス トの作成時間」であり、テストの実行時間ではありません。 負荷検証するサーバの処理速度がテストに追いつかない場合は、この時間を大幅にオーバーしてしまいます。 もし、一定時間でテストを中断したい場合は、同画面の「スケジューラ」にチェックを入れて、終了時間を設定してください。 スレッド数とループ回数 スレッド数は、「リク エス ト群を送信する回数」のことです。 ここで重要なのことは、スレッドは「リク エス ト」ではなく「リク エス ト群」であること。 1スレッドでは複数のリク エス トを送信することができます。 では、この「リク エス ト群」内のリク エス ト数はどうやって設定するかというと、「ループ回数」で指定します。 要するに、ループ回数は「1スレッドで送信するリク エス トの量」を決める値です。 テスト実行時に送られる総リク エス ト数は、この「スレッド数」と「ループ回数」の積によって決まります。 総リクエスト数 = スレッド数 × ループ回数 ※ スレッド数 = 総リクエスト数 ではありませんよ。 この3パラメータの関係を時系列で図にまとめると、以下のような感じですね。 また、スレッドグループでは、スケジューラを用いることでテストの開始時間や終了時間を設定できます。 テスト実行中はリク エス トを送信する端末にも負荷がかかるため、これで夜間などにテストを実行させておけば楽(?)できますよ。 テスト計画作成の注意点 スレッド数、Ramp-Up期間、ループ回数 を用いてテスト計画を作ることができますが、ここであまりに大量のリク エス トを投げようとすると、 JMeter を実行する端末のCPUが食い散らかされてしまします。 デフォルト設定の JMeter は、たとえRamp-Up期間が長時間だったとしても、テスト開始と同時に、スレッド数で指定したスレッドを作ってから、テストを実行するそうで、スレッド数の量によっては、一発でフリーズしてしまいます。 *2 この場合、スレッドグループの設定画面にある Delay Thread creation until needed にチェックを入れることで、スレッドの作成をずらすことができます。 *3 JMeter has an option to delay thread creation until the thread starts sampling, i.e. after any thread group delay and the ramp-up time for the thread itself. This allows for a very large total number of threads, provided that not too many are active concurrently. Apache JMeter - User's Manual: Best Practices リスナーの追加 テストの実行結果を表示するリスナーを追加します。 左画面のスレッドグループを右クリックし、 追加 > リスナー > 結果を表で表示 を選択します。 続けて 追加 > リスナー > 統計レポート も追加しておきます。 他にも下図のように様々な結果の表示方法があるので、用途によって使い分けてください。 ただし、あまりリスナーを増やしてしまうと、メモリをたくさん使ってしまいますので、必要最低限にする必要があります。 (特に、今回用いる「結果を表で表示」は、全サンプルの結果を表示するのでたくさんメモリを使ってしまうそうです。) また、各リスナーは、テスト実施前にファイル名を指定することで、全てのデータをファイルに出力することができるので、 テスト結果に対して実行後に何らかの処理を加えたい場合は指定してください。 ここまでで作ったテスト計画は、ファイルとして保存できます。 テスト計画を選択したうえで保存ボタンを押下し、保存しておきましょう。 テスト計画の実行と結果の見方 いよいよテスト実施です。 まずはあまり負荷が高くない条件で動かしてみましょう。 画面上部の「開始」ボタンでテストを開始でき、テストを開始すると、画面右上のアイコンが緑色になり、終了すると灰色に戻ります。 以下の画面では、スレッド数:5、Ramp-Up期間:10秒、ループ回数:20 でテストを実施した場合の「結果を表で出力」画面です。 表項目それぞれの意味は次の通り。 項目名 意味 Sample リク エス トの番号 StartTime リク エス トの送信を始めた時間 Sample Time(ms) リク エス トの送信からレスポンスを受け終わるまでにかかった時間 Status レスポンスのステータスを示す Bytes 受信データのバイト数 SendByte 送信したバイト数 Latency リク エス トを送ってからレスポンスが届いた時間 Connect Time(ms) JMeter がサーバとの接続確立にかかった時間 ちょっと時間にかかわる用語がややこしいので、図で説明します。 また、結果をファイルへ出力する際に出力できる「Elapsed time」についても併せて説明します。 JMeter が1リク エス トを送信してレスポンスを受信するまでの処理は、上の図のように行われます。 Start Time はその名の通り、処理を開始した時刻です。(結果をファイル出力した場合はマシンタイムで表されます。) JMeter は、処理開始後、サーバとのHTTP接続の確立を行います。この接続の確立にかかる時間が Connect Time です。 もし、このConnect Timeに時間がかかる場合、 JMeter からの接続要求が待たされている可能性があるので、サーバの同時接続条件などを見直したほうがいいかもしれません。 JMeter は、接続が確立されると、リク エス トを送信し始めます。 全てのリク エス トが送信されると、サーバの処理が終わるまで待機し、サーバからレスポンスが返ってくるとレスポンスを受信し始め、すべてのレスポンス情報を受け取ると処理終了となります。 余談ですが、 JMeter はブラウザと違い、受信したレスポンスに対して処理を行いません。 したがって、(当たり前ですが) JavaScript のようなブラウザ側での処理は、 JMeter の結果に影響することはありません。 Elapsed Time はリク エス トを送信し始める直前から、すべてのレスポンスを受信した直後までの時間です。 Latency は、日本語に訳すと「潜時」と言って、「刺激が与えられてから反応するまでの時間」のことです。 JMeter では、「処理開始時間」から、「最初のレスポンスが返ってきた直後」の時間を指します。 (少しややこしいのですが、 JMeter の公式リファレンスの「Connect Time」の項によると、LatencyはConnect Timeを含んだ時間になるそうです。そのため、接続エラーが起きたリク エス トでは、 Connect Time = Latency になります。) *4 Sample Time は、これらの処理すべてにかかった時間です。 ちなみに、全リク エス トの通し番号である「Sample」は、この終了時間の昇順で割り当てられているらしいので、Start Timeが前後していても気にしなくていいそうですよ。 *5 「統計レポート」リスナーには、全サンプルの統計情報が記載されます。 たくさんのリク エス トを送信するテストの場合、どうしてもすべてを見ることは不可能なので、統計情報を参考にしてください。 おわりに さあ、これでざっくりですが、 JMeter の基本的な機能は使えるようになりました。 リク エス ト数を増やして、いざ、テスト! ...と考えた方、ちょっと待ってください! これだけ説明しておいてですが、 Apache は GUI モードでの本番テストを推奨していません!! *6 Don't run load test using GUI mode !   GUI mode should only be used for creating the test script, NON GUI mode must be used for load testing Apache JMeter - User's Manual: Getting Started Non- GUI モードのほうがより正しい結果を得られるため、 GUI モードはテスト計画の作成のみに使い、実際のテストはNon- GUI モードを使ってほしいそうです。 斯く言う私も、この記事を書くため公式ドキュメントを読んで気づきました(^^;) より正確な結果が求められるテストを行う場合は、 GUI モードでテスト計画を作成、上部メニューの保存ボタンから保存したのち、 Non- GUI モードから読み込んでお使いください。 以上、基本的な内容ですが、私が業務で使った JMeter の使い方について、説明しました。 もし、はじめての負荷検証であたふたしている人の助けになれば、幸いです。   エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 https://rakus.hubspotpagebuilder.com/visit_engineer/ rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com *1 : http://qiita.com/PlanetMeron/items/a604645d6f89b6ce3a14 *2 : http://keis-software.com/2013/09/02/jmeter-%E3%81%AE%E5%88%A9%E7%94%A8%E6%96%B9%E6%B3%951-ramp%EF%BC%8Dup%E3%80%81%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89%E6%95%B0%E3%80%81%E3%83%AB%E3%83%BC%E3%83%97%E5%9B%9E%E6%95%B0%E3%81%AE%E8%AA%A4/ *3 : http://jmeter.apache.org/usermanual/best-practices.html *4 : http://jmeter.apache.org/usermanual/glossary.html *5 : http://www.checksite.jp/jmeter-check-result-research/ *6 : http://jmeter.apache.org/usermanual/get-started.html#overview
アバター
はじめに はじめまして。開発エンジニアのstrongWhiteです。 ラク スに入社して今年で2年目になります。 今回は、仕事を進めていく上で WIPを制限する大切さ をお伝えしようと思います。 堅苦しい 話にならないように、あるゲームの内容をもとにお伝えできればなと思います。 WIP WIPとは「work in progress」の略で、仕事が進行中である あるいは 仕事が完了状態ではないことを意味します。 簡単にいうと、やりかけの作業 ということになります。 突然ですが、みなさんは仕事ができる人 や 仕事が早い人と聞くと、どんな人をイメージされるでしょうか。 いろいろな仕事を同時並行的にこなしている人をイメージされますか? 実は仕事を同時並行的に行うと、かえって完了が遅くなります。 仕事ができる人 や 仕事が早い人は、 ひとつひとつの仕事を確実に終わらせる 人です。 ここが今回の記事の肝になりますので、念頭に置いておいてください。 コインゲーム 先日、社内で開催された勉強会で コインゲーム を開催しました。 このゲームはWIPを制限する大切さを実感できるゲームです。 ゲームに必要なもの コインをひっくり返す「作業者」 作業者の作業時間を計測する「管理者」 1人の「顧客」 テーブル 同じサイズのコイン20枚 ストップウォッチ(あるいはストップウォッチ機能付き携帯電話) 結果を書き出す紙 遊び方 作業者と顧客はテーブルを囲んで着席します。 1人の作業者の後ろに1人の管理者が付き、管理者はストップウォッチを持ちます。 また、顧客もストップウォッチを持ってスタンバイします。 作業者・管理者・顧客の役割はそれぞれ以下の通りです。 作業者…すべてのコインをひっくり返して、次の作業者に渡す。(最後の人は顧客に渡す。) 管理者…作業者がコインをひっくり返すのにかかった 実質作業時間 を計測する。 顧客…最初のコインが届くまでの時間とすべてのコインが届くまでの時間(最後のコインが届くまでの時間)の2つを計測する。 ゲームは3回繰り返してプレイします。 最初は20枚のコインを一括で行い、2回目は5枚ずつに分けて行います。そして最後は1枚ずつに分けて行います。 勘のいい方はこの時点で気付いたかもしれませんが、このゲームでは、コインがひとつの WIP を示しています。 3回とも全く同じようにプレイしますが、違うのは WIPが徐々に小さくなっていく ことだけです。 今回、勉強会では作業者3名、管理者3名、顧客1名の計7名でゲームを行いました。 結果は以下の通りです。 20枚 5枚 1枚 Aさん 20秒 28秒 28秒 Bさん 23秒 26秒 28秒 Cさん 21秒 28秒 29秒 最初のコイン 67秒 23秒 4秒 合計時間 67秒 42秒 31秒 ゲームから学べること WIPが小さくなるにつれて作業者の作業時間は長くなりますが、最初のコインがゴールするまでの時間と合計時間は短くなります。 つまり、同時に作業する作業項目を減らすと、リードタイムが短くなるということになります。 ひとつひとつのコインを皆さんが仕掛っている仕事に当てはめると、同時並行的に仕事をするとすべての仕事が完了するのにとても時間がかかってしまうということになります。 この点から、WIPを減らすことによる重要性が理解できるかと思います。興味がある方はぜひ周りの人とゲームをプレイしてみてください。 まとめ 今回はWIPを制限する大切さをお伝えしました。効率的に仕事を進めるには、ひとつひとつの仕事を確実に終わらせるように立ち回ったほうがいいということが少しでも伝われば幸いです。 抱えている仕事が多いと、つい気が焦って何でもかんでも手をつけてしまいがちです。ですがそのまま進めても何もかもが中途半端に終わってしまい、何ひとつ完了している仕事がないという状況に陥ります。 そんなときは今回の記事を思い出していただき、WIPを制限していま取りかかっている作業を終わらせることに集中してみてください。 参考 Marcus Hammarberg、Joakim Sunden 著 『カンバン仕事術-チームではじめる 見える化 と改善』
アバター
はじめに はじめまして。エンジニアのnorthmkyです。 ラク スに新卒で入社し、今年で2年目になります。 他エントリが技術の内容だったので少し趣向を変えて ラク スが行っている技術交流会、 ビアバッシュ を紹介したいと思います。 ビアバッシュとは "ビア"とついている通り 「ビールなどのアルコールを片手に(+軽食)フランクに技術内容について発表したり語り合う交流会」 のことを指します。 だいたい月に一度くらいの頻度で有志が集まって開催しています。 参加費は...なんと無料です。 というのも技術交流会を会社が応援してくれていまして 補助金 がでるのです。 そのおかげもあり、 ラク スでは本イベントが3年も途切れることなく続いています。 (実はここまで会社内で技術イベントが続いてる事例は少ないんだそうです) ビアバッシュの流れ 以下のような流れでやっています。 ビアバッシュ開始 お酒をたしなみつつ... 発表スタート!! (発表 + 質疑応答) x 3名ほど 発表が終わりと思いきや... 飛び入り参加枠スタート ビアバッシュ終了 発表後半になると聴いていた参加者側の人が登壇したくなり、 飛び入り参加枠で話し始める...ということが結構あります。 気になる発表内容ですが...実に幅広いです。 話題の技術を使ってみた 勉強したことを整理してみた 実務をしていて身につけたTips紹介 読んだ本(技術書あるなし問わず)の紹介 実務をしていて感じたこと・大事だと思うこと 勉強会レポート 趣味について熱く語る 新卒一年目で感じたこと などなど。 熟練エンジニアから新卒で入りたての人まで、様々な人が登壇します。 前回の様子はこちら では実際に前回ビアバッシュの様子の一部を紹介したいと思います。 開催前、司会進行のスライドです。 開催前に参加可否のアンケートをとり、発表者とそのテーマをタイムテーブルに落とし込みます。 たまに発表はじまりの前、後に個人で宣伝したいことを宣伝する時間をとることがあり、 そのときもこの資料に記載しています。 「平日毎○曜日、勉強会開催してるよー」だったり「趣味のイベント参加者募集!」だったり 技術以外の宣伝もあります。 軽食といいながらお寿司がでちゃいます。 その会の運営している人のさじ加減で内容は変わります。 写真では伝わりませんが、BGMも流しています。 テンションがあがります。 実際の発表風景です。 お気づきかもしれませんが、本ブログのTOP画像の場所、 通称「 コワーキングスペース 」にて行いました。 この写真の登壇者の発表内容は数学よりの話だったので皆さん真剣に耳を傾けています。 上記のような感じで毎月やっています。 飛び入り枠の雰囲気もお伝えしたかったのですが、自身が飛び入りをしたのでお見せする写真はありませんでした... ビアバッシュのよいところ 私が参加してみてよいなあと思うところは 「普段仕事で関わる/関わらない人にかぎらず興味深い話が気軽に聞ける」 ところかなと思います。 なかなか他部署のエンジニアの方と話す機会って業務ではなかなかないのではないかと思います。 また同じ部署でも話さなかった人って実はいたりして、そのいう方々の話を聴くと 案外自分が気になっている情報を持っていらっしゃったりして、そこからより関係性が深まることもあります。 自分の好きな技術の話になりますと、やはり発表者もイキイキした表情と声で発表しているので、 伝染して楽しい気持ちになりますし、もっと知りたい!という知識欲をかりたたせられます。 おわりに ラク スでのビアバッシュを紹介しました。 お酒が入った中自由に技術の話をする/聴くのはやはり楽しいです。 そしてこのイベントを会社が推奨してくれるのもありがたいなと思います。 これからも続いていけるようにしていきます。 実は、外部の方を招いて勉強会をしようという声も上がっています。 その時はまた周知しますので気になった方はぜひ参加してみてくださいませ。 以上northmkyからのビアバッシュ紹介でした。
アバター
はじめに はじめまして。開発エンジニアのCarboxyです。 ラク スに新卒で入社して、今年で2年目になります。 今回は、新卒(≒エンジニア初心者)が、効率の良いプログラムを書けるようになるきっかけになればと思い、プログラムの計算量の求め方とその比較方法をソート アルゴリズム (選択ソート)を例に紹介します。 計算量とは ある問題を解くためにどのくらい計算が必要かどうか(どのくらい時間がかかるか) → アルゴリズム の性能評価に使用できる。 O(オーダー)記法を用いて示す。 ※計算量には時間計算量と空間計算量があるが、この記事では時間計算量の事を指す。 O(オーダ)記法 計算量の一般的な記述方法。大まかな時間計算量を表す。 例として、入力サイズ n の関数として表される時間計算量T(n)が で与えられる場合、オーダー記法では最も次数の高い項の係数を省いて となる。なぜこのように最も次数の高い項(主要項)の係数を省くような、漸近的な評価が使われるかというと、入力サイズ n が十分に大きい場合は、時間計算量は主要項にのみ依存するからである。 選択ソート 選択ソートを例に計算量を考える。 選択ソートは最も基本的なソート アルゴリズム の1つで、次のようなア イデア に基づきソートを行っていく。 1,入力データの中から最大のデータを見つける。 2,見つけた最大のデータをソートの対象から除外する。 3, 1と2 の操作を n - 1 回繰り返す。 ソースコード 入力サイズ n の配列 D[0]、D[1]、・・・、D[n-1] for (i=n-1; i>0; i=i-1) { max = D[0]; maxIndex = 0; for (j=1; j<=i; j=j+1) { if(D[j]>=max) { max = D[j]; maxIndex = j; } } swap(D[maxIndex],D[i]); } この アルゴリズム は、2重のfor文により構成されている。変数 n に依存する i , j の2重ループなのだからO(n^2)になることは安易に想像できるが、計算すると次のようになる。 外側のfor文の繰り返し実行回数は n - 1 回であり、内側のfor文は外側のfor文の変数 i に依存し、i 回の繰り返しとなっている。したがって、この アルゴリズム の計算量は、以下の式で表される。 計算量の比較 複雑になるため詳細は省略するが、その他のソート アルゴリズム の計算量を計算すると、例えば クイックソート の場合はO(n logn)になる。オーダー記法の漸近的な大小関係は以下のようになることから、選択ソートと クイックソート を比較すると クイックソート のほうが計算量が小さい事が 数値的に わかる。 まとめ オーダ記法によって漸近的な時間計算量を示すことができる。 プログラムを実行して時間を測定しなくとも、入力サイズ n に対してどの アルゴリズム が一番速いか数値的に比較できる。
アバター
はじめに はじめまして。開発エンジニアのwest-cです。 ラク スに新卒で入社し、今年で3年目になります。 ラク スでもエンジニアブログをはじめることになりました。 記念すべき1エントリ目を書くことになり光栄です。 本題 そんな1エントリ目のテーマですが、現在、私自身が新卒メンバーの育成を担当していることもあり、今年入社した新米エンジニアを対象にお話をしたいと思います。 大学や会社の研修でプログラムは学ぶかと思いますが、ログの見方・調査方法についてしっかり学んだことのある方は少ないのではないでしょうか。 個人で作成したプログラムであればエラーが発生したとき程度しか見ないログですが、お客様に提供するアプリケーションとなると話はちょっと変わってきます。 ログは、ユーザがとった行動の証跡(証拠)となることから、利用状況の把握から問題が発生した場合の原因特定まで非常に重要な役割を担います。 ログの形式はソフトウェアによって異なるためそれぞれの公式ドキュメントに譲るとして、ここでは ログ調査にあたり知っておくと便利な Linux コマンド を紹介したいと思います。 なお、今回は Apache のアクセスログ を例として説明を行います。 リアルタイムでログを監視したい $ tail -f access_log ファイルの末尾が更新されると自動的に追加分が表示されます。 例えば、検証環境にて画面遷移をした瞬間のログを確認したい場合などに重宝します。 長い スタックトレース を確認する場合は、予めEnterキーでいくつか改行を入れておくとログの切れ目が分かりやすくなり便利です。 ログをスクロールして表示したい $ less access_log 行数の長いファイルの場合、 cat でファイルの中身を見ようとすると画面に収まり切らず、目的のログに辿り着くのにひと苦労します。 そのようなときに less を利用すると、スクロールしながら閲覧することができます。 less コマンド内で利用できる操作のうち、個人的によく使うものは以下になります。 キーバインド 説明 b 1画面分上にスクロール スペース 1画面分下にスクロール g ファイル先頭に移動 G ファイル末尾に移動 /文字列 ファイル内を文字列で検索 n 次にヒットした検索文字列の行に移動 N 前にヒットした検索文字列の行に移動 F リアルタイムで監視( tail -f と同様) q less コマンドを終了する 表示する行を絞り込みたい 以降は、以下のような アクセスログ を前提として説明を行います。 (GET or POST の前の数値はリク エス ト処理にかかった時間(単位:秒)、末尾の数値はレスポンスサイズと解釈してください) $ cat access_log 192.168.10.11 - - [10/Oct/2000:13:55:36 -0700] 1 "GET /index.php HTTP/1.0" 200 2326 192.168.10.11 - - [10/Oct/2000:13:55:36 -0700] 0 "GET /top.jpg HTTP/1.0" 200 310 192.168.20.8 - - [10/Oct/2000:13:56:01 -0700] 10 "POST /login.php HTTP/1.0" 200 1793 192.168.30.50 - - [10/Oct/2000:13:57:11 -0700] 5 "GET /mypage.php HTTP/1.0" 200 831 192.168.30.50 - - [10/Oct/2000:13:57:11 -0700] 0 "GET /room.png HTTP/1.0" 200 4530 特定の文字列が含まれる行のみを抽出したい場合は grep の出番です。 $ grep "login" access_log 192.168.20.8 - - [10/Oct/2000:13:56:01 -0700] 10 "POST /login.php HTTP/1.0" 200 1793 ファイルから「login」という文字列が含まれる行のみが抽出されました。 逆に「login」という文字列を含まない行を表示する場合は、 -v オプションを付けましょう。 $ grep -v "login" access_log 192.168.10.11 - - [10/Oct/2000:13:55:36 -0700] 1 "GET /index.php HTTP/1.0" 200 2326 192.168.10.11 - - [10/Oct/2000:13:55:36 -0700] 0 "GET /top.jpg HTTP/1.0" 200 310 192.168.30.50 - - [10/Oct/2000:13:57:11 -0700] 5 "GET /mypage.php HTTP/1.0" 200 831 192.168.30.50 - - [10/Oct/2000:13:57:11 -0700] 0 "GET /room.png HTTP/1.0" 200 4530 grep -E または egrep を利用すると、検索文字列に 正規表現 を利用することができます。 上記を組み合わせると、画像ファイル( *.jpg , *.gif , *.png )を除外したログを表示したい場合に、以下のように記述することができます。 $ egrep -v "\.(jpg|gif|png)" access_log 192.168.10.11 - - [10/Oct/2000:13:55:36 -0700] 1 "GET /index.php HTTP/1.0" 200 2326 192.168.20.8 - - [10/Oct/2000:13:56:01 -0700] 10 "POST /login.php HTTP/1.0" 200 1793 192.168.30.50 - - [10/Oct/2000:13:57:11 -0700] 5 "GET /mypage.php HTTP/1.0" 200 831 表示する列を絞り込みたい 例えば以下の3つの情報がログ調査に必要であるとします。 アクセス日時 リク エス トURL リク エス トにかかった時間 この3つ以外の情報は今回は必要の無いノイズ情報ですので、 awk で表示する列を絞り込みましょう。 awk で列を絞り込む場合、デフォルトでは空白(スペース)またはタブ単位で区切られます。 今回の例だと、4列目(アクセス日時)・6列目(リク エス トURL)・8列目(リク エス トにかかった時間)だけを表示したいことになります。 $ awk '{print $4,$6,$8}' access_log [10/Oct/2000:13:55:36 1 /index.php [10/Oct/2000:13:55:36 0 /top.jpg [10/Oct/2000:13:56:01 10 /login.php [10/Oct/2000:13:57:11 5 /mypage.php [10/Oct/2000:13:57:11 0 /room.png 必要な情報のみが表示され、見通しが良くなりました。 $ の後の数字には、区切り文字で行を分割した際の順番が入ります(1始まり)。 区切り文字を変更したい場合は、 -F '区切り文字' とオプションを付与すれば良いです。 ちなみに cut コマンドでも同様のことは実現できますが、次に紹介する話との関連で、ログの確認時には awk を利用することをおすすめします。 条件に合致するログのみを抽出したい ひとつ前の例に追加して「リク エス トに3秒以上かかったログのみを抽出したい」場合を考えてみましょう。 awk は プログラミング言語 なので、条件分岐を記述することもできます。 $ awk '$6>=3{print $4,$6,$8}' access_log [10/Oct/2000:13:56:01 10 /login.php [10/Oct/2000:13:57:11 5 /mypage.php このように「○番目の項目が□□だった場合」と記述することができるため、単純な文字列一致の条件の場合でも grep よりも細かく絞り込みを行うことができます。 まとめ 私自身、入社したての頃にログファイルをviで開いて怒られたりログファイルを根こそぎ Excel に貼り付けてちまちま絞り込みを行ったりと苦い経験があったため、今回このテーマを選ぶことにしました。 今回取り上げた内容は基本的なものであり、さらに高度なログ集計を行おうとすると、 sort や uniq 、 sed なども必要になるかと思います。 まずはこの記事を足がかりに、その他のコマンドも習得してステップアップしてもらえると嬉しいです! エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com
アバター