goのginを使ってjsonでパラメータを返すサーバーを立ててみた
やんてらです。今回はgoの話になります。 goのフレームワークは何が良いのか分からなかったのでネットで調べたところginが良さげだったので採用してみました。
本題
レストランの一覧を返すjson用のapiサーバを立てていきます。前回と変わらずdokcerで作っていきます(構成は少し変えてます
構成
今回はこんな感じです
|-docker | |-go | |-Dockerfile |-src | |-api | |-main.go | |-restaurant.json | |-Gopkg.toml |-docker-compose.yml
Dockerfile
- 今回はalpine使ってみました
FROM golang:1.10.3-alpine3.8 COPY src/api /go/src/api/ WORKDIR /go/src/api/ RUN apk update \ && apk add --no-cache git \ && go get -u github.com/codegangsta/gin \ && go get -u github.com/golang/dep/cmd/dep \ && dep ensure EXPOSE 8080 CMD ["gin", "-i", "run"]
docker-compose.yml
version: '3' services: api: build: context: . dockerfile: docker/go/Dockerfile volumes: - ./src/api:/go/src/api - vendor:/go/src/api/vendor ports: - 8080:8080 tty: true
Gopkg.toml
[[constraint]] name = "github.com/gin-gonic/gin" version = "1.2.0" [prune] go-tests = true unused-packages = true
main.go
package main import ( "github.com/gin-gonic/gin" "io/ioutil" "encoding/json" "log" ) type Restaurant struct { Id int `json:"id"` Name string `json:"name"` } func main() { r := gin.Default() restaurant := Restaurant{ Id: 3, Name: "サイゼリヤ", } r.GET("/restaurant", func(c *gin.Context) { c.JSON(200, restaurant) }) bytes, err := ioutil.ReadFile("restaurants.json") if err != nil { log.Fatal(err) } var restaurants []Restaurant if err := json.Unmarshal(bytes, &restaurants); err != nil { log.Fatal(err) } r.GET("/restaurants", func(c *gin.Context) { c.JSON(200, restaurants) }) r.Run(":8080") }
restaurants.json
[ {"id": 1, "name": "デニーズ"}, {"id": 2, "name": "ジョナサン"} ]
実行結果
無事表示されましたね
まとめ
とりあえず、jsonで値を返すやり方がなんとなく分かったので次はフロント側でいい感じのレストランのマップを実装して行こうと思います。
参考URL
mysqlのクエリが詰まったので解消したメモ
どうもやんてらです。今回はmysqlでクエリが詰まりすぎて何もできなくなったのでそれを解消したメモになります。
クエリが詰まるとCPU使用率がどんどん高くなっていきました(99.8%ぐらいまで上がっていたのでほんと危なかったです笑
show processlist
を使用するとmysqlで積み上がっているクエリが見れます
show processlist +----+------+------------------+---------+---------+------+--------------+-------------------------------------------------------------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+------------------+---------+---------+------+--------------+-------------------------------------------------------------------------------------------+ | 1 | root | 172.18.0.5:35500 | example | Query | 0 | Sending data | SELECT `sutudents`.* FROM `sutudents` WHERE `students`.`id` = 94068 | | 2 | root | 172.18.0.1:47626 | example | Query | 0 | NULL | show processlist | +----+------+----------------------------+---------+------+--------------+-------------------------------------------------------------------------------------------+
上で表示されている詰まっているIDのプロセスをkillすれば残りのプロセスが実行されていくはずです。
kill Id
※もし本番で発生した場合は一人で対応ではなく複数人でダブルチェックしながら作業するのがおすすめです。(select 以外のプロセスをkillすると大惨事になるので気をつけて下さい
今回はこれで以上です。
rubyのbundleでgemfileのパスでハマったのでメモ
どうもやんてらです。bundleを行う時にGemfileが上手く読み込めなかったので、その時周りの方に教えて頂いたメモになります。
このような感じでGemfileを置いてて、
root@dda622750a80:/app# ls -al Gemfile -rw-rw-r-- 1 1001 1001 3901 Nov 16 09:38 Gemfile
bundle installを叩くと
root@dda622750a80:/app# bundle install ~ Bundle complete! 75 Gemfile dependencies, 176 gems now installed. Bundled gems are installed into `/usr/local/bundle`
と出てきて想定したgemがインストールされていなくて(予定では 75 Gemfile
ではなく 76 Gemfile
になるはずでした
bundle config
を叩くと、
root@7934b4f05fde:/app# bundle config Settings are listed in order of priority. The top value will be used. gemfile Set via BUNDLE_GEMFILE: "/tmp/Gemfile"
と出てきてgemのパスが想定した場所と違っていました(想定は/tmp/Gemfile
ではなく/app/Gemfile
の予定でした
解決方法
以下のコマンドを叩けば解消できました。
$ bundle install --gemfile=Gemfile(Gemfileのパス) ~ Bundle complete! 76 Gemfile dependencies, 176 gems now installed. Bundled gems are installed into `/usr/local/bundle`
root@7934b4f05fde:/app# bundle config Settings are listed in order of priority. The top value will be used. gemfile Set via BUNDLE_GEMFILE: "/app/Gemfile" root@7934b4f05fde:/app#
これで無事インストールすることが出来ました。
dockerを使ってgoの環境を立ち上げる流れを作ってみたのでそのメモ
お久しぶりです。久々の更新ですみません。 今回はgo作業する時、dockerを使って開発したいなーと思って作成したそのメモになります。
自分は docker fo mac
を使用しています。
フォルダ構成
|- docker | |- go | |- Dockerfile |- docker-compose.yml |- main.go |- templates |- chat.html
Dockerfile
ROM golang:latest RUN apt-get update -qq && apt-get install vim -y WORKDIR /go ADD . /go EXPOSE 8080 CMD ["go", "run", "main.go"]
docker-compose.yml
version: '3' services: app: build: context: . dockerfile: docker/go/Dockerfile environment: TZ: Asia/Tokyo volumes: - ./:/go ports: - "8080:8080" tty: true stdin_open: true
main.go
package main import ( "log" "net/http" "path/filepath" "sync" "text/template" ) type templateHandler struct { once sync.Once filename string templ *template.Template } func (t *templateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { t.once.Do(func() { >-t.templ = template.Must(template.ParseFiles(filepath.Join("templates", t.filename))) }) t.templ.Execute(w, nil) } func main() { http.Handle("/", &templateHandler{filename: "chat.html"}) if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatal("ListenAndServe", err) } }
chat.html
<div> test test test </div>
実行結果
↑ファイル構成で
docker-compose up -d
を実行すると
こんな感じで表示されます。 今回はただ表示して動かしただけなので、次はホットリロードに対応した構成にしたい。
参考URL
モブプロを初めて1ヶ月立ったので感じた事のまとめ
どうもやんてらです。私が開発チームのリーダーになって2ヶ月くらいになりました。
以前書いた記事から1ヶ月くらいたったので、久々の更新です。
今回はチームでモブプログラミングを初めて大体1ヶ月ほどたって感じた事を書いていきます。
はじめはモブプロではなくペアプロもどきをやっていたのですが、 私の時間がレビューコストとリーダーの業務とメンテ等で全て奪われて行き、更に開発もしないといけない状況になりました。 流石にこれは無理だと思ってやり始めたのがモブプログラミングです。
※参考書籍はモブプロをする時、めっちゃ勉強になりました。
モブプロを導入しようと思ったのは以下の点です。
- 相互レビューしながら開発するのでレビューのコストがなくなるのでは?
- 案件の認識を合わせるMTGがなくなって常に同期されるのでは?
- 自分も開発に参加出来るのでは?
- 個人的に一度やってみたかった←ココ重要!!
モブプロを行う時のルールは以下のとおりです
モブプロのルール
- 毎朝、1日の予定を決める
- 各メンバーに会議が入っている等を洗い出す
- 開発を行う時間を決める
- 自分たちのチームは10:00-18:00でモブプロをしてます
- 残りの1時間は各々やりたいことをやってます。
- 休憩
- 自己判断で休憩をとるのが難しくなるので、強制的に休憩を取るタイミングを決める(1、2時間単位ぐらい
- 大体10~20分くらい休む
- 全員で考えて10分詰まったら強制的に休憩する
- 17時を過ぎているとそのまま振り返りをして自習(解散)ということもある
- 1日の振り返りは絶対にする
- これをやらないと最適化されないのでよりチームに合ったやり方と見つけるために振り返りの時間を30分ほど取ってます
- google driveなどで今日やった事やKPTの写真を取って成果の管理する。
- PCは各々によって環境が違うので、ドライバー交代時はブランチをpullする。
- 案件の見積もりはメンバー全員でする
- issueは機能単位で切り、出来るだけMinimumにする
- ここで言うMinimumとは見積もりが出来る且つ、少し余裕があるくらいの見積もりの大きさです
- 追加や漏れがあった場合、別issueで行う
- 案件で発生するissueをまとめるissueを作成する
- issueは機能単位で切り、出来るだけMinimumにする
- 2週間のスプリントで区切り、見積もり含めて順調に案件が進んでいるかを見直すようにした。
モブプロのルールは毎日の振り返りを行い、毎日振り返りをして最適化した結果こうなりました。 個人的に見解ですがルールが変わらなくなれば、見積もりを含めてほぼ完璧に成果が出せるようになっていると思います。
やってみた結果(メリット)
- プルリクを投げるとすぐにマージできるようになった。
- 細かくcommit&pushをするようになった。
- 互いが何をやっているかの共有会がなくなった。
- 私も開発に参加出来る時間が増えた。
- メンバー間のコミュニケーションがよくなった。
- 周りから見て楽しそうに開発しているように見えているらしい。
- 教育コストが減った。
- 雰囲気が良さげだと別のチームが真似をしてモブプロに近いことを始める。
- マーケティングチームが似たような事を始めました。
- いらない会議を減らせた
やってみた結果(デメリット)
- 正直めちゃくちゃしんどい。
- サボる事は不可能になった。
- 自分のタイミングで気分転換するのが難しいので、そこはいい感じに解決しないと問題になる。
まとめ
自分のチームでは基本的にモブプロ+アジャイルというスタンスでやってます。
基本的にMAX6.5時間ほどモブプロをして、後の1時間は各々でやりたい業務をするという流れにした結果、良い雰囲気で開発出来るようになったかなと思っています。(残りの0.5時間は休憩です
あと、余裕がなくなると愚痴が多くなりパフォーマンスが下がるので、出来るだけ余裕を持って作業出来るようにするとチームは良いパフォーマンスを発揮するのでは無いかなと思いました。
参考書籍
カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで
- 作者: 市谷聡啓,新井剛
- 出版社/メーカー: 翔泳社
- 発売日: 2018/02/07
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る
- 作者: Jonathan Rasmusson,西村直人,角谷信太郎,近藤修平,角掛拓未
- 出版社/メーカー: オーム社
- 発売日: 2011/07/16
- メディア: 単行本(ソフトカバー)
- 購入: 42人 クリック: 1,991回
- この商品を含むブログ (257件) を見る
エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング
- 作者: 広木大地
- 出版社/メーカー: 技術評論社
- 発売日: 2018/02/22
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
- 作者: リチャード・シェリダン
- 出版社/メーカー: 翔泳社
- 発売日: 2017/01/20
- メディア: Kindle版
- この商品を含むブログを見る
カイゼン・ジャーニーを読みながらマネジメントっぽい事を始めて2週間ぐらいたったので感じた事をメモ
最近チームのリーダーの人が抜けて急遽自分が代わりにマネジメントっぽい事を始めたので気づいた事をメモ。
今までスクラムを意識してやっていたのですが、どうもチームで作業している感が無くて改めて今までの開発フローを見直しました。 (ほとんどカイゼン・ジャーニーを参考にして行いました)
やめた事
- 開発チーム (4人)の代表とプロダクトオーナーだけで話し合って案件(githubのISSUEのチケット)の優先順位を決めていた事。
- ↑の会議で話し合った案件をチームに割り振る事(優先度の理由は別途聞き直す理由があった)。
- 1つの案件に対して1人で作業する事。
始めた事
- 案件の優先度は開発チーム全員とプロダクトオーナーで話し合って優先順位を決める事。
- 決めた優先順位の案件に対して2人以上で取り組む事。
- スコープが小さすぎると1人でやる事もある
- ISSUEのテンプレートを作成した。
- issueは開発チーム以外から上がることが多いので案件について誰が見てもわかるようなテンプレートを作成。
- トレードオフスライダー
- 星取表(スキルマップ)
やった結果
- 案件の優先度は開発チーム全員とプロダクトオーナーで話し合って優先順位を決める事。
- 開発チームに危機感や一体感が出てきた。
- 決めた優先順位の案件に対して2人以上で取り組む事。
- これは相談できる相手がいるというのがあったりするのでチームの雰囲気は少し良くなったなと思います。
- ISSUEのテンプレートを作成した。
- これは作成したばかりなのでまだ結果はわかりません。
- トレードオフスライダー
- 開発チームのメンバーが何故このサービスにジョインしているのか知ることが出来た。
- メンバーの優先度が互いに共有できた。
- 星取表(スキルマップ)
- メンバーが今の開発チームで不安に思っていることが知れた。
- メンバーの苦手な部分を知れた。
- メンバーのやりたいことが知れた。
- これは各自の技術的なスキルマップだけでは無くサービスに関しての機能単位でもやることにより、どの機能を誰に聞けば良いかなども明確になった。
- 逆に誰も知らない機能があるというのも明確になったのでより危機感を覚えました笑
最近始めようと思っていること
- 朝の案件の共有をもう少し時間を取ること。
- 具体的にはファイブフィンガーを取り入れようと思ってます。
まとめ
結果がすぐに出ている訳ではないですが、チームで見えていない部分の共有が出来るようになったかなと思ってます。 個人的な考えですが、メンバー1人1人の課題はチームの課題だと言っても過言ではないと個人的に思ってます。 なのでこれからはどんどん不要な課題は取り除けたら良いなと思ってます。
カイゼン・ジャーニーは勉強になる事ばかりだったので、困ったらとりあえず読み直そうと思います。
カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで
- 作者: 市谷聡啓,新井剛
- 出版社/メーカー: 翔泳社
- 発売日: 2018/02/15
- メディア: Kindle版
- この商品を含むブログを見る
rubyのcountについてメモ
count
を使わなくて失敗したので戒めを含めメモ。
Active Recordのデータ(配列)に対して
sizeを使えば配列を全てオンメモリ
で扱って、結果を返す。
countはを使えばdbに投げて
結果を返してくれる。
↑のことはわかっていたけど、物理的な部分を理解しているつもりで終わっていた。
例えば、100件程度のデータならsizeの方が良いと思うが、数十万件となるとcountの方が良いと思う。
理由としては
数十万件のデータを全てメモリに載せようとするとおそらくメモリが足りずに落ちる
からである。
blank?とかpresent?
とかも同じことが言える。
配列を判定する時に値が存在する、存在しないという処理も配列のデータをオンメモリで扱おうとするので仮に数十万件データが入っていると落ちる可能性がある。
array.count > 0
という処理はpresent?
を使えば良いと思っていたけど、時には必要なんだなと思った。
countが使えない場合はfind_each
とかを使って頑張るしか無いかなと思う。
その辺をわかっているつもりでわかっていなかったから、不具合を産んでしまった。次は絶対に同じミスをしない。