Spring Bootを紹介してみる
はじめに
この記事は SLP KBIT Advent Calendar 2019 の3日目の記事です。
最後の一枠余っていたので急遽書きました。
今回は、最近自分が一番使っていてるであろうSpring Bootを紹介したいと思います。
Spring Bootってなんぞや?
Spring BootとはJavaやKotlinなどで利用できるWebアプリケーションフレームワークです。 Spring Bootの特徴は調べてもらったらいくらでもでてくるので割愛します。 Spring Bootの良さはたくさんありますが、個人的に良いなと思っているのは以下の点です。
特にライブラリが豊富な点は個人的に良いなと感じており、プロジェクトの規模感に応じてORマッパーを使い分けたりできるのは魅力的です。 また、アーキテクチャ設計の自由度が高い点もプロジェクトの規模感に応じて使い分けれるのでとても良いところだなと感じています。
実際に使ってみる
今回は、Spring Bootでメモ管理システムを作ります。
基本のCRUD機能を実装して完成となります。
使用技術
プロジェクトの立ち上げ
Spring Bootのプロジェクトを立ち上げにはSpring Initializerを使います。
今回は使用技術にあるように、Java11、Spring Boot2.2.1、Gradleを利用していきます。
それぞれ必要なライブラリ群を選択しGenerateするとそれらのライブラリが入った状態のプロジェクトがダウンロードできます。
この時点でライブラリを入れ忘れても、あとでbuild.gradleに書き込めば追加できます。
その後Eclipseを起動し、ファイル -> インポート から 既存のGradleプロジェクトから先程のプロジェクトをインポートします。
実装するエンドポイント
今回実装するエンドポイント一覧です。 Webページは1枚で、メモ一覧表示用にすべてのフォームを実装します。 POST、PUT、DELETEのリクエストが来たときには処理を行った後そのページにリダイレクトするようにしています。
エンドポイント | method | 説明 |
---|---|---|
/memos | GET | メモ一覧表示用 |
/memos | POST | メモ作成用 |
/memos/:id | PUT | メモ更新用 |
/memos/:id | DELETE | メモ削除用 |
テーブル構成
今回はmemoテーブルのみを作成します。カラムの制約はあえてなしにしています。
memo
カラム名 | 型 |
---|---|
id | BIGINT |
body | VARCHAR(256) |
created_at | TIMESTAMP |
updated_at | TIMESTAMP |
アーキテクチャ
Spring Bootでは3層アーキテクチャが使われることが多いです。そこで今回は、そのアーキテクチャを少し改造してcontroller層、service層、repository層、entity層に分けて実装します。 3層アーキテクチャは以下の記事が参考になると思います。
controller層
controllerではリクエストが来た際にどの様な処理を行うのかを実装します。
見慣れないアノテーションがたくさんあったりと複雑そうに見えますが、基本的には来たリクエストをservice層で処理し、その後必要な結果を返すといった実装となっています。
@AutowiredはDependency Injection、いわゆるDIを自動で行ってくれるものです。(DIの説明に関しては今回は省きます)
とりあえず今はmemoService変数には、MemoServiceのインスタンスが入っていると思ってくれれば良いかなと思います。
package work.tomosse.AdventCalendarProject.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import work.tomosse.AdventCalendarProject.entity.Memo; import work.tomosse.AdventCalendarProject.service.MemoService; @Controller @RequestMapping("/memos") public class MemoController { @Autowired MemoService memoService; /** * メモ一覧表示 * * @param mav * @return */ @GetMapping public ModelAndView index(final ModelAndView mav) { mav.addObject("memoList", memoService.getMemo()); mav.setViewName("index"); return mav; } /** * メモ作成 * * @param memo * @return */ @PostMapping public String create(@ModelAttribute final Memo memo) { memoService.createMemo(memo); return "redirect:/memos"; } /** * メモ更新 * * @param memo * @return * @throws Exception */ @PutMapping("/{id}") public String update(@ModelAttribute final Memo memo) throws Exception { memoService.updateMemo(memo); return "redirect:/memos"; } /** * メモ削除 * * @param id * @return */ @DeleteMapping("/{id}") public String delete(@PathVariable final Long id) { memoService.deleteMemo(id); return "redirect:/memos"; } }
service層
serviceでは、controllerから送られてきたデータをもとに処理を行います。
今回の場合だと、データベースを使った処理を行うことがほとんどになりましたが、複雑なシステムになるとここでの処理が増えることになります。
package work.tomosse.AdventCalendarProject.service; import java.util.Date; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import work.tomosse.AdventCalendarProject.entity.Memo; import work.tomosse.AdventCalendarProject.repository.MemoRepository; @Service public class MemoService { @Autowired MemoRepository memoRepository; /** * memoの一覧を返却する * * @return */ public List<Memo> getMemo() { return memoRepository.findAll(); } /** * memoを作成する * * @param body */ public void createMemo(final Memo memo) { memo.setCreatedAt(new Date()); memo.setUpdatedAt(new Date()); memoRepository.save(memo); } /** * メモを更新する * * @param body * @throws Exception */ public void updateMemo(final Memo memo) throws Exception { memo.setUpdatedAt(new Date()); memoRepository.save(memo); } /** * memoを削除する * * @param id */ public void deleteMemo(final Long id) { memoRepository.deleteById(id); } }
repository層
repository層はDBへのCRUDを自動で実装してくれるインタフェースが集まった層となります。 JpaRepositoryを継承しただけなので説明は省きます。
entity層
entityは今回の場合だとmemoテーブルの構造を表しています。
@Columnでデータベースのカラムとの紐付けを行っています。
本来であれば、Getter/Setterを定義しますが、それをベタに書いてしまうとすごく長いクラスとなるので、Lombokを使って省略します。(@Dataの部分)
LombokはJavaを書く上ですごく便利なライブラリなので積極的に使うと良いと思います。
package work.tomosse.AdventCalendarProject.entity; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import lombok.Data; @Entity @Data public class Memo { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column private Long id; @Column(name="body") private String body; @Column(name="created_at") private Date createdAt; @Column(name="updated_at") private Date updatedAt; }
表示部分
表示部分はThymeleafで実装します。といっても普通のHTMLベースでの書き方なので詰まることは少ないと思います。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>AdventCalendarProject</title> </head> <body> <h1>AdventCalandarProject</h1> <label>登録</label> <form th:method="POST" th:action="@{/memos}"> <input type="text" name="body" /> <input type="submit" value="登録" /> </form> <table border="1"> <tr> <th>ID</th> <th>内容</th> <th>作成日</th> <th>更新日</th> <th>更新</th> <th>削除</th> </tr> <tr th:each="memo: ${memoList}"> <td th:text="${memo.getId()}"></td> <td th:text="${memo.getBody()}"></td> <td th:text="${memo.getCreatedAt()}"></td> <td th:text="${memo.getUpdatedAt()}"></td> <td> <form th:method="PUT" th:action="@{'/memos/' + ${memo.getId()}}"> <input type="text" name="body" th:value="${memo.getBody()}" /> <input type="submit" value="更新" /> </form> </td> <td> <form th:method="DELETE" th:action="@{'/memos/' + ${memo.getId()}}"> <input type="submit" value="削除" /> </form> </td> </tr> </table> </body> </html>
実際の画面
実際の画面がこちらです。 ちゃんとメモの登録、作成、削除ができるようになっています。
作ったもの
まとめ
かなりざっくりですが、Spring Bootの紹介をしました。
Spring Bootは使えば使うほど良さがわかるフレームワークだと思います。
最初は慣れるまで大変だと思いますが、根気よく使ってみてください。
きっと良さがわかると思います。
GitHubに1年間毎日コミットした話
昨年の2月末あたりから先輩の影響で、毎日コミットを始めました。
そこで今回は、GitHubに毎日コミットして1年が経ったのでそれらの感想をまとめたいと思います。
始めた経緯
僕自身今までプログラミング自体は好きでやっていましたが、毎日やる習慣はありませんでした。
しかしこのままだと自分の目標としているところまで技術力が伸びないのではないかと思い、毎日コミットを始めました。
毎日コミットを始めるちょっと前までの自分
1年前だとRailsやSinatraを使ったWebアプリケーションの勉強や、Linuxサーバの構築、Herokuを使って身内で使うサービスを立ち上げたりすることを主に行っていました。
他には、VimやZshのカスタマイズなどを行うことが多かったです。
この頃はとにかく何か動くものを作ってみたい!とかとにかく自分が使いやすい開発環境を作る!というようなことに集中していた気がします。
毎日コミットを1年間続けた後の自分
毎日コミットしてみて気づいたことを挙げてみます。
- 今までよりもたくさんの技術を使えるようになった
- 自分の作ったものをたくさんの人に使ってもらえるようにしたいと思うようになった
- ただアプリを作るだけじゃなく、パフォーマンスやUI、コードの品質なども意識するようになった
特に2と3の内容が1年前の自分よりも大きく意識が変化した部分だと思います。
2に関してはCodeCandyがまさに良い例です。 誰かにサービスを使ってもらいたいと思った時、ちょうど新入生が大学に入学してくる時期だったので、新入生にプログラミングを気軽にはじめてもらいたくて作ったサービスでがCodeCandyでした。 今では知らない人にも使ってもらえるくらいに成長し、とても良い経験をさせてくれているWebアプリケーションになりました。
3に関しては、いくつかWebアプリケーションを運用してみて、今までよりもよりユーザに使ってもらいやすいUIを意識したり、サーバからの応答速度に気を使うようになりました。
特にCodeCandyではプログラムをリアルタイム実行できるようにしているので、アプリケーションのパフォーマンスをよく気にするようになりました。
結果的に、信頼性を考えたシステム開発を意識するようになりました。
結果的に今までよりも サービスのパフォーマンスや使いやすいUIなどを考えながら開発する意識が高まりました 。
また、毎日コミットを行っていると以前よりも様々な技術に触れてみたいと強く思うようになり、今までよりもたくさんの技術を使えるようになりました。(Spring Bootを使やサーバサイドスクリプトの開発などなど)
あと、アイデアをissueやメモに書き込む癖ができたので、今までよりもアイデアを忘れることが減りました。
まとめ
毎日コミットは最初のうちは慣れなくてしんどい時もありましたが、慣れてくるとむしろ毎日コミットをやっているほうが自分の時間をうまく作れるようになったので、やってみてよかったなと思います。
これからも毎日コミットは続けていきたいと思っています。
みなさんも是非やってみてはいかがでしょうか?
ps. みなさんCodeCandy使ってください!! codecandy.tomosse.work
Webサービスを運用していて便利だと思ったツール・サービスを紹介してみた
はじめに
この記事は SLP KBIT Advent Calendar 2018 の14日目の記事です。
何の記事を書こうかかなり悩んだのですが、今回は自分がWebサービスを運用していて、個人的に便利だと思ったツール・サービスについてまとめていきたいと思います。 また最後に、今後導入してみたいツールなどの紹介も行いたいと思います。 ちなみに過去に書いたSLP KBIT Advent Calendarの記事は以下のリンクから見ることができます。
2016年はラズパイサーバ、Pythonで作った音楽プレイヤーの話、 2017年はRailsのAPIモードの話をしています。 Pythonで作った音楽プレイヤーの記事は今でもそこそこアクセスがあるみたいなのでいつか書き直したいと思っています。(この記事Python2で書いたのでPython3で書き直したい)
Webサービスを運用している環境
本題に入る前に、私がWebサービスを運用している環境を少しだけ紹介しておこうと思います。
主に利用している環境は2つあり、VPSを使った環境とHerokuを使った環境を使い分けています。
VPSはConoHaを利用しており、WebサーバにはNginxを採用しています。
使い分けの内容としては、大規模なサービスでそこそこのサーバスペックやインフラ環境を柔軟に扱う必要がある場合はVPSを、小規模でインフラ周りを意識せずに利用できる場合はHerokuを利用しています。
だいたいは外部向けのサービスにはVPS環境を、身内で利用するサービスにはHerokuを用いることが多いです。
ちなみに、
CodeCandyや誰でも簡単形態素解析
はVPS環境で運用しています。
今回は、主にVPS環境でWebサービスを運用するにあたって便利だと思ったツール・サービスについて紹介します。
Webサービスを公開していて便利だと思ったツール・サービス
- お品書き
- Mackerel
- Slack Bot
- Google Analytics
- Fluentd
- Monit
Mackerel
はてな社が提供しているサーバ管理・監視サービスです。
サーバ監視ツールというと、SLP KBIT Advent Calendar2018の6日目の記事で@wakatakeruさんが紹介したPrometheusなども有名だと思います。
なぜ僕が、Mackerelを利用しているのかというと、導入コストが極めて低かったからです。
agentの導入はコマンド一発で導入できるのでとても楽です。
サーバ監視ツールを導入する際に、ツールの導入に時間をかけたくないが、サーバ監視を疎かにしたくないという要求を考えた結果、Mackerelを使うようになりました。
導入してみて良いと感じている点としては、導入の手軽さ、十分な監視機能、グラフがとても見やすいという点です。
現在は無料プランでの利用を行っていますが、自分の用途的には無料プランで十分だと感じています。
APIも公開されているので、足りないと思う機能があればは自作プラグインなどを作ってカバーすればいいかなと思っています。
Slack Bot
これは、サーバに誰がいつSSHでログインしたかを監視するために導入しました。 SSHでサーバにログインするとSlackに通知が行くようにしています。 正直必要かなと思う面もありますが、スマートフォンなどからでも過去のログイン情報を簡単に閲覧できるのは便利です。 また、ログインしたことをすぐに通知してくれるので、誰か知らない人がログインしてもすぐに気づくことができます。(されたことはないですが) 地味だけどなんだかんだ便利だと思っている技術です。 このツール自体は既存のツールではなく、自作する必要がありますが紹介しておく価値があると思い紹介しました。
Google Analytics
Google社が提供しているWebページのアクセス解析サービスです。
主にサイトの訪問者数や、訪問時刻、デバイス毎のアクセス数を調べるのに利用しています。 このツールのおかげで、メンテナンスするのに最適な時間がわかったり、訪問者が良く訪れるページがわかるようになったので、サービスのメンテナンスや改良が楽になりました。 このツールは最近導入したばかりなのですが、もっと早くから導入していればよかったと後悔しています。
Fluentd
OSSのログ収集ツールです。
簡単に言うとログをより柔軟に収集、保存ができるツールです。 今現在の主な用途はNginxのログをPostgreSQLに保存する目的で利用しています。 Nginxのログだけでなく、様々なイベントをログにして出力できるのがとても魅力です。 また、保存先もファイルやRDB、NoSQLなど幅広く対応しているのも魅力的だと感じています。 このツールを導入する前は、Vimの検索機能を使ったり、自作parserを作成して、ログを利用していましたが、導入後はそれらの手間が一気に省けたのでとても快適にログを活用できています。 プラグインもかなり揃っている印象があるのでかなり使い勝手はいいと思います。
Monit
プロセス・プログラム・ディレクトリなどを監視するためのシステムマネジメントツールです。
Webサービスを公開して数ヶ月立った時、大学のOBの先輩に教えてもらい導入したツールです。
それまでは、サービスが落ちたら手動で復旧するしかありませんでしたが、このツールを導入してからはMonitでサービスのプロセスを監視し、サービスが落ちていたら自動で復旧するようにしたので、以前よりも安心感を持ってサービスを運用できるようになりました。
設定もそれほど難しくないのが個人的にいいなと思っています。
ただ、あまりサービスが落ちることは考えたくないので、使う場面が少ない方が嬉しいですね。
今後導入してみたい技術
今後はサービスのログ解析や、Webサービスのチューニングを行うことが増えいくと感じているので、その辺りで使えるツールの導入は検討しています。
特にAthena + S3やBigQueryなどは導入したいツールの筆頭ですが、今現在お金にあまり余裕がないので導入はまだ先になりそうです...。 現在、それらのかわりとなるツールを作り始めているので、当分は自作ツールで運用していこうと思います。
また、せっかくFluentdを導入したので、ElasticsearchやKibanaも導入してみてログの検索、グラフ化なども行ってみたいと考えています。
まとめ
他にもWebサービスを運用するにあたって使っているツールがありますが、全部紹介しようとするとキリがないので今回は最近使っていて特に便利だと思った5つのツール・サービスを紹介しました。
ただWebサービスを運用するだけであれば、これらのツールやサービスは必ずしも必要というわけではないかも知れませんが、これらのツールを導入することでより快適にWebサービスを公開できるようになり、またインフラ面で悩むことが減ったように思います。
このような技術を取り入れることで、開発に専念しやすくなった気もします。
正直みなさんが知ってるツールばかりな気もしますが、Webサービスを公開する際に少しでも役に立てばいいなと思います。
JavaのArrayListの検索方法 【for文・拡張for文・ラムダ式】
はじめに
久しぶりのブログ更新となりますね。
最近は何かと忙しく、なかなかブログを更新することができませんでした。(悲しい...)
近況報告をすると、夏の間はインターンシップに参加していました。
最近だとCodeCandyを改良したり、オープンキャンパスでの展示などを行っていました。
そして研究室にも配属されて新たな大学生活がスタートしました。
また今後も、のんびりきままにブログを更新していきたいと思っています。
本題
今回は、私が最近一番使っていると言っても過言ではないJavaについてのお話です。 最近Javaをよく使うようになったのですが、その中でもArrayListをよく使います。 ArrayListは簡単に言うと可変長の配列みたいなものです。 今回はそのArrayListにおける検索方法についてまとめていきたいと思います。
前提
利用するArrayListは以下のものとします。
ArrayList<Integer> numberList = new ArrayList<Integer>(); // 値の格納 numberList.add(1); numberList.add(10): numberList.add(100); numberList.add(1000);
そして肝心の検索方法についてですが、今回はfor文・拡張for文・ラムダ式について説明していきます。
for文
サンプルコード
for (int index = 0; index < numberList.size(); i++) { System.out.println(numberList.get(index)); } // 出力結果 // 1 // 10 // 100 // 1000
これが一番初心者の方にもとっつきやすい検索方法じゃないでしょうか。 配列の検索方法と同様にArrayListの検索を行います。 配列はlengthで長さを取得できましたが、ArrayListはsize()で長さを取得することができます。 また要素は、get(要素番号)で取得することができます。
拡張for文
サンプルコード
for (int number: numberList) { System.out.println(number); } // 出力結果 // 1 // 10 // 100 // 1000
先程のfor文による操作よりもコンパクトになって見やすくなったと思います。 この方法だと、ArrayListの最初から最後までを順番に操作することになります。 要素番号を取得する必要がない時や、処理の途中でbreakしたい時などには便利に使えそうです。
ラムダ式
サンプルコード
numberList.forEach(number -> { System.out.println(number) }); // 出力結果 // 1 // 10 // 100 // 1000
ラムダ式はJava8から実装された機能です。 拡張for文より簡素に、そして直感的に書けるようになりました。 拡張for文との違いとして、拡張for文で利用する変数には型が必要でしたが、ラムダ式で利用する変数には型の宣言が必要なくなっています。 ただラムダ式は検索の途中でbreakすることができないので注意が必要です。
まとめ
雑になってしまいましたが、ArrayListの操作方法についてまとめてみました。
基本的には、直感的に何を行っているのかわかるラムダ式を使うのがいいと思いますが、検索途中でbreakする場合は拡張for文、要素番号が欲しい時はfor文を使うなど、用途に合わせて使い分けすれば便利に使えるのではないでしょうか。
オンラインコンパイラサービス CodeCandyを開発した話
はじめに
なかなか記事が書けなくて申し訳ありません。ようやくCodeCandyの紹介をします。
今回はCodeCandyを開発して気づいたこと、思ったことなどをまとめていけたらなと思います。
CodeCandyのURLはこちら ↓
https://codecandy.tomosse.work
オンラインコンパイラCodeCandyとは
Web上で、プログラムの作成から実行まで行うことのできるアプリケーションです。 機能としては、自由にコーディングする機能と、問題に取り組む機能の2つが存在しています。 厳密には、オンラインコンパイラ+オンラインジャッジシステムといったほうが正しいのかもしれません。 特徴としては、以下のことが上げられます。
- ブラウザ上でコーディング、実行ができる
- 問題に取り組むことも、自由にコーディングすることもできる
- 複数の言語に対応している
- Twitterアカウントがあればすぐに利用できる
構成
Ruby on Railsを利用して開発しました。 主にサーバサイドの開発に力を入れています。 サーバサイドはRailsを採用し、DBはPostgreSQL、実行モジュールにDockerを採用しました。 また、複数のコンテナを利用するので、管理を簡単にするためにdocker-composeを採用しました。 コンパイラモジュールはREST APIとして提供しているのでサードパーティ製のアプリも開発できるようにしています。 フロントエンドはERB+jQueryといった一番使い慣れたものを利用しました。
技術の採用理由
CodeCandyを作成する上で一番意識したことは、開発速度です。 じっくり開発するというよりも、素早く目標としている機能を実装できることを意識しました。 そこで今回は自分が一番使い慣れており、迅速に開発が行えるRailsを採用しました。 また、フロントエンドの機能を手軽に作れるGemが、豊富にあるのも大きなメリットだと感じました。 PostgreSQLを採用した理由も自分が一番使い慣れているからといったのが一番大きな理由です。 MySQLを採用するかも悩んだのですが、あまりDBでアプリの重さに影響がでるような設計にはならないと感じたので使い慣れているPostgreSQLを採用しました。 コンテナ周りは、LXDにするかDockerにするかで悩んだのですが、過去に似たようなシステムをDockerを用いて作ったというのと、今後Dockerを用いてアプリをデプロイできるようにしたいと思っていたので、 今回はDockerを採用しました。 フロントエンドはソースの多さと友人からアイデアや意見を貰いやすい用、ERB+jQueryを採用しました。
開発してみての感想
開発してみて、やはりRailsはとても開発速度が速いと感じました。 作成したい機能をかなりの速度で開発することができました。 またこれは開発してみて思ったことなのですが、意外とRubyでDockerコンテナを操作しやすいことに驚きました。 CodeCandyでは、作成したAPIからコンテナを操作する機能がとても重要となってくるので、この技術を採用してよかったと感じました。
運用してみての感想
運用してみて一番感じたことは、ユーザにとって一番良いプログラムと開発者が良いと思って作成したプログラムは必ずしも一致しないといったことです。 やはりこのあたりのことは、サービスとして展開して、他の人に使ってもらわないとわからないことだと強く思いました。 また運用目線と開発目線ではアプリケーションに対する見方がかなり変わるイメージも持ちました。 今までは開発者視点からしかあまり技術を見ることができていなかったのかなと思いました。
今後の展開
今後の展開としては、テストコードをより揃える、実行モジュールを拡張しやすいものにする、より活用しやすいようログインの方法を増やすことなどを重点的に行っていきたいと思っています。
まとめ
このCodeCandyを開発、運用してから自分自身の技術力はかなり上がったと感じています。 これからもCodeCandyをよりよくすることはもちろん、他のサービスも作成してみたいと思います。
6月中に行ってきたこと
はじめに
この記事は、6月中に私自身が行ってきたことをまとめた記事です。 6月では、新しい技術を取り入れたり、勉強会に行ったりなど、今までとは違ったことをよく行った一ヶ月になりました。
サーバ監視ツールの導入
現在CodeCandyを動かしているサーバや自宅内で利用しているサーバにMackerelを導入しました。 そもそもは、自分でサーバ監視ツールを作成しようと思っていたのですが、今回はせっかくなので、前々から知っていたMackerelを利用してみたいと思い使い始めました。 Mackerelを選んだ理由としては大きく3つあります。
・手軽に導入できて、使用できる ・ポートを開けていないサーバにも利用できる ・前々から使ってみたいと思っていた
特に、2つ目のポートを開けていないサーバにも利用できるといった点が、採用に大きく影響しました。 自分の環境では、外部に公開していないサーバもあるので、そのサーバでも利用できるのはとてもありがたいことです。 そして、Mackerelを導入してまず思ったのが、とても手軽に導入できることです。 使い始めも、難しくなく、監視するサーバにツールを導入するものとても簡単にできました。 また、初めて使うときは14日間無料で有料プランを利用できるといったことも良い点だと思いました。 現在は無料プランで利用していますが、無料プランでもかなり使い勝手がいいです。 僕のサーバ環境なら十分すぎるくらいです。 また、様々なプラグインが用意されているので、今度使用してみたいと思っています。
技術大会に参加した
技術大会に参加しに、京都に帰省しました。 今回参加した勉強会は、はてな・ペパボ技術大会 #4 〜DevOps〜 @京都です。 はてなさんとペパボさんの合同技術大会ということで、過去に大学で講演していただきお世話になり、とても興味があったので参加しました。 内容はDevOpsに関することで、はてなのエンジニアさんとペパボのエンジニアさんがそれぞれ、講演(プレゼン)し、トークセッションを行い、懇親会といった流れでした。 私は、友人と二人で当日香川から京都に出発し参加しました。現地では、別の友人や、先輩も参加していました。 この技術大会を聴講して、今まで自分が考えていたインフラに対するイメージや、開発者としての目線について、大きく考えが変わりました。 また、たくさんの技術者の方との交流を深められて、とても刺激を得れた一日となりました。 ただ、日帰りで参加したこともあり、とても疲れてしまったということが個人的に残念でした。(次は、もっと余裕をもって参加したい) 個人的には、懇親会で、Mackerelを通して、たくさんお話ができたのがとても嬉しかったです。 たくさんのいい刺激や影響を受けれたので、参加してとてもよかったです。
CodeCandyの改良
URL: https://codecandy.tomosse.work
6月はあまり、開発が進みませんでしたが、CodeCandyの改良は少しずつ行っていました。 モデルの設計の見直し、Javaの実行環境を整えたことなどが大きなアップデートでしょうか。 また、使用しているDockerのコンテナのイメージを変更しました。 今まではUbuntuのイメージを利用していたのですが、openjdk:10のイメージを利用するようになりました。 理由としては、Javaの実行環境を導入するのに、一番適していると考えたからです。 今後は、現在開発している新機能の実装と、実行モジュールの改良を行っていきたいと思います。
まとめ
6月はあまり、開発面では大きな進捗はなかったですが、得るものはとても多くあったと思います。 今後も積極的にイベントに参加したいと思う一ヶ月でした。 7月では、CodeCandyの実行モジュールの改良に力を入れたいと思います。 もちろん大学の授業もおろそかにならないように頑張ります。
Rubyで外部コマンドを実行する方法と処理時間の測定方法
はじめに
現在、大学の授業でプログラムの性能実験を行っています。 実験では、C言語で作成されたコードの性能比較を行うのですが、実行時間の測定などを行うのが大変です。 そこで、今回はRubyを利用して、C言語のコードを実行し、その実行時間を測定する方法を紹介したいと思います。
C言語のコードを実行するために
RubyでC言語のコードを実行するために、外部コマンドを利用します。 外部コマンドとは、簡単にな例をあげれば、Linux上であれば、BashでRubyのコードを動かした時、RubyのコードでBashで動かすことです。 外部コマンドが利用できれば、あとはいつも通りターミナル上でC言語のコードを動かす感覚で、C言語のプログラムを実行することできます。 Rubyには外部コマンドを動かす方法がいくつか存在するのですが、今回はバッククォート(`)を使った方法とopen3を使った方法を紹介します。
バッククォートを使った場合
バッククォートを使った場合の、外部コマンドの実行方法は以下の通りです。
`echo "Hello World`
バッククォートで囲った外部コマンドを実行できます。 標準出力しか、得ることができないのですが、Bashであれば、Bashの標準入力を使うことで標準入力を使うことができます。 簡単な実行結果であれば、バッククォートを使うのがいいでしょう。
open3を使った場合
open3を使った場合の、外部コマンドを実行するサンプルを以下に示します。 今回はpopen3で説明を行います。
require 'open3' Open3.poepn3("echo Hello World") do |stdin, stdout, stderr, status| stdin.puts "" stdin.close stdout.each do |line| puts line end stderr.each do |line| puts line end end
open3を使えば、標準出力だけでなく、標準入力、標準エラー、ステータスなども使うことができます。 Open3.popen3の("")内の外部コマンドが実行されます。
時間測定
Rubyには、Benchmarkという時間測定に便利なライブラリが存在します。 サンプルコードを示しておきます。
require 'benchmark' result = Benchmark.realtime do # 測定したい処理 end puts "#{result}秒"
Benchmark.realtimeを使うことで、do ~ end内の処理時間を測定することができます。 Benchmark.realtimeが実行時間を返却してくれるので、変数に格納してあげるとよいでしょう。 返却値は、秒数となっています。
まとめ
今回は自分が最近よく使う、open3とBenchmarkを紹介しました。 みなさんも機会があれば使ってみてはいかがでしょうか。