Blogaomu

WEBアプリケーション開発とその周辺のメモをゆるふわに書いていきます。

HTTP/2独習メモ2日目(nghttpxでTLS終端)

HTTP/2の学習シリーズ。本当はKanazawa.rb #87もくもく会でやっていたことなんですが参加エントリーを書かない内に次のKanazawa.rbが来そうなので学んだことだけ抜き出してメモっておこうというモチベーションです。

www.blogaomu.com

前回はクライアント-サーバー間のHTTP/2通信についてGoでサーバーを実装し確認するという内容でした。今回は間にリバースプロキシを挟んでTLS終端を担ってもらいます。よくありがちな構成をシンプルにしたものですね。

構成

nghttpx

まずは nghttpx の設定です。基本的な項目のみになっています。注目すべきは2行目の backend で proto=h2 で HTTP/2 プロトコルで接続するようになります。

frontend=0.0.0.0,8443
backend=server,8080;;proto=h2
private-key-file=/etc/nghttpx/cert/server.key
certificate-file=/etc/nghttpx/cert/server.crt

backend

h2cでリクエストを受け付けるように修正したBackendの実装は以下になります。h2c というパッケージが用意されているのでこれを利用します。

package main

import (
    "io"
    "log"
    "net/http"

    "golang.org/x/net/http2"
    "golang.org/x/net/http2/h2c"
)

func main() {
    handler := http.HandlerFunc(index)
    h2s := &http2.Server{}
    srv := &http.Server{
        Addr:    ":8080",
        Handler: h2c.NewHandler(handler, h2s),
    }

    log.Fatal(srv.ListenAndServe())
}

func index(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "Hello World! by HTTP/2")
}

オーケストレーション・リクエストの実行

前回サーバーはdocker化したので、docker-composeでリバースプロキシを含めて構成したいと思います。

version: "3.7"
services:
  server:
    build:
      context: server
  reverse-proxy:
    image: dit4c/nghttpx
    ports:
      - "8443:8443"
    volumes:
      - "./nghttpx:/etc/nghttpx"
      - "./cert:/etc/nghttpx/cert"
    depends_on:
      - server

プロジェクトは以下の構成です。

.
├── cert
│   ├── server.crt
│   └── server.key
├── docker-compose.yml
├── nghttpx
│   └── nghttpx.conf
└── server
      ├── Dockerfile
      └── main.go

これで全ての構成の準備ができたので docker-compose を起動します。

$ docker-compose up

別のターミナルでHTTPSリクエストを行います。

$ curl -v -k https://localhost:8443

*   Trying ::1:8443...
* TCP_NODELAY set
* Connected to localhost (::1) port 8443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /usr/local/etc/openssl@1.1/cert.pem
  CApath: /usr/local/etc/openssl@1.1/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=JP
*  start date: Dec 17 23:13:26 2019 GMT
*  expire date: Dec 16 23:13:26 2020 GMT
*  issuer: C=JP
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fe729822a00)
> GET / HTTP/2
> Host: localhost:8443
> user-agent: curl/7.67.0
> accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 200
< content-type: text/plain; charset=utf-8
< content-length: 22
< date: Thu, 19 Dec 2019 07:40:30 GMT
< server: nghttpx
< via: 2 nghttpx
<
* Connection #0 to host localhost left intact
Hello World! by HTTP/2

リバースプロキシを挟んでHTTP/2サーバーにリクエストし正常にレスポンスすることを確認できました。

また、dockerネットワークに接続して tcpdumpWireshark で確認してみます。(tcpdumpイメージは前回参照)

$ docker run \
    --net=container:$(docker ps -f "name=reverse-proxy" --format "{{.ID}}") \
    -v $(pwd)/tcpdump:/var/dump-data \
    tcpdump tcpdump -i eth0 -w /var/dump-data/eth0-2.pcap

https://i.gyazo.com/a8aac324b6fed700367dce17a6e30ef1.png

172.0.0.3 が reverse-proxy で 172.0.0.2 が backend server です。これらの間の通信もHTTP/2で行われていますね。よかったよかった。

まとめ

今回はnghttpxを利用してTLS終端およびバックエンドサーバーへのリバースプロキシを行いました。また、HTTP/2でのリクエスト・レスポンスを確認できました。余談ですが docker-compose.yml をさくっと書けたのは日頃の作業が身に付いてる感じがあって良かったです。

今回のソースコードはこちらにアップロードしています。 github.com

Kanazawa.rb meetup #86 に参加しました #kzrb

最近涼しくなっていよいよ秋だなあと感じるこの頃、みなさまいかがお過ごしでしょうか?今回のkzrbは意識高いもくもく会 @ DMM Games でした。

kzrb.doorkeeper.jp

ちなみに、お昼はビリヤニ(ヤギ)。

HTTP/2の学習

分かるようでよく分からないHTTP/2について以下の資料を見ながら学習していました。

tools.ietf.org

summerwind.jp

8pockets.booth.pm

HTTP/1.1には無かった概念がいくつか出てきていたのでその辺をふむふむ言いながら読んでいました。特にフレームという単位でデータを送受信するというのが特徴的でなるほどと思った部分でした。実際に手元でも確認したいなと思い、クライアント-サーバー間の通信を見てみようと思いtcpdumpで取得したデータをWiresharkで開いて確認するというのを進めていました。クライアントはHTTP/2対応のcurl、サーバーはGoで実装したものを利用しました。server.crt server.key はローカル環境で作成したものです。

package main

import (
    "io"
    "net/http"

    "golang.org/x/net/http2"
)

func main() {
    var srv http.Server
    srv.Addr = ":8080"

    http2.ConfigureServer(&srv, nil)
    http.HandleFunc("/", index)

    srv.ListenAndServeTLS("server.crt", "server.key")
}

func index(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "Hello World! by HTTP/2")
}

*1

先ほどのソースコードをdockerビルド時にビルドし、dockerコンテナで実行できるように。

FROM golang:1.13

WORKDIR /go/src/app
COPY . .

RUN go get -d -v .
RUN go install -v .

CMD ["app"]

これらを準備してひとまずcurlでリクエストできるか確認。

# サーバー起動
% docker run --rm -p 8080:8080 --name http2-server <image>:latest

# 別のターミナルウィンドウで
% curl -v --http2 https://localhost:8080 --insecure

*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=JP
*  start date: Oct 19 05:07:49 2019 GMT
*  expire date: Oct 18 05:07:49 2020 GMT
*  issuer: C=JP
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7f8e6c806800)
> GET / HTTP/2
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 200
< content-type: text/plain; charset=utf-8
< content-length: 22
< date: Mon, 21 Oct 2019 07:44:23 GMT
<
* Connection #0 to host localhost left intact
Hello World! by HTTP/2* Closing connection 0

良さげですね。で、今度はtcpdumpしてみました。以下の記事を参考にしながら。

medium.com

% docker build -t tcpdump - <<EOF 
FROM ubuntu 
RUN apt-get update && apt-get install -y tcpdump 
CMD tcpdump -i eth0 
EOF

% docker network create demo-net
# --nameを指定
% docker run --network demo-net --rm -p 8080:8080 --name http2-server server:latest
# tcpdumpで出力されるファイル置き場
% mkdir tcpdump
# tcpdump実行
% docker run --net=container:http2-server -v $(pwd)/tcpdump:/var/dump-data tcpdump tcpdump -i eth0 -w /var/dump-data/eth0.pcap

この流れで eth0.pcap ファイル生成されて、wiresharkで開くことができました。が、https://wiki.wireshark.org/HTTP2のような形式では表示されずヘッダー情報などが確認できませんでした。この辺はもう少し調べてみたいと思います。

懇親会

tabelog.com

tabelog.com

今回は5人と少人数でしたがその分濃い話で盛り上がりました。信頼の昇龍、お腹一杯であまり食べられなかったのが悔やまれます。某交差点から離れるほど良い店に当たる確率が高くなるという話を聞いてなるほどなーと思いました😇

*1:『はじめてのHTTP/2』41ページより引用

Googleフォーム・スプレッドシート・ドライブで立て替え金の管理を試している

11月20日に「AWS Community Day Kanazawa」というAWSユーザーグループ(JAWS-UG金沢)とAWSの共催で行われるイベントが開催されます。私はこの運営に携わっていてそのタスクの一つに立て替え金の管理というのがあります。今回はできるだけ 頑張らず に立て替え金の管理を行う試みを行っているのでその紹介をしようと思います。

頑張らない?

ここで言う「頑張らない」というのは、時間を掛けない、コストを掛けない、自動化させる、他の人でもできる、ということを心がける意味の言葉として捉えてもらえればと思います。コミュニティ主体のイベントという性質もあって、私個人としては仕事や家庭やプライベートなどから限られた時間やリソースを捻出する中でのスタッフ活動になりますのでできるだけこのような心がけで運営するというのが持続的に活動する上で大切だと考えています。もちろん、他のスタッフが支えてくれているからこそという側面もありますので関係各位には改めて感謝を申し上げます。

立て替え金管理のワークフロー

さて本題に戻って、立て替え金管理についてのワークフローを示します(細かいところは省略)。

  • イベント運営に必要な費用をスタッフが立て替えて支払い、領収書を受け取る
  • スタッフは会計担当スタッフ(私)に立て替えを申請する(1)
  • 会計担当スタッフは申請内容を記録し、領収書(スキャンしたPDF)を保存する(2)
  • 会計担当スタッフは立て替え費用を集計する
  • (スポンサー等から)費用が運営に入ってきたら、会計担当スタッフは立て替えてくれたスタッフに精算を行う

このフローでは具体的な方法について書かれていませんがこれからどうやってやろうかという観点で読んでもらえればと思います。まず、(1)の立て替えたことを会計担当スタッフに申請する部分ではどのような方法を利用することが考えられるでしょうか。メールで申請する、専用のフォームを用意してここから入力してもらう等ありそうです。次に(2)の申請内容を記録・保存する部分についてはどうでしょうか。集計のことを考えるとExcelGoogleスプレッドシートに記録していくのが良さそうですね。

今回の要件としては、管理に必要な項目が決まっている、できるだけオープンに管理する、というポイントがありさらに頑張らないことを加味するとGoogleフォームとGoogleスプレッドシートおよびGoogleドライブを利用することにしました。

ツール 利点
Googleフォーム 入力フォーマットの統一、Submit後Googleスプレッドシートへ自動的に反映、ファイルもアップロード可、自ら実装およびホスティングしなくてよい、GASでカスタマイズ可能(後述)
Googleスプレッドシート 共有可能
Googleドライブ 領収書ファイルの置き場として共有可能

特にフォームについては様々な機能が利用できる上に自分で実装とホスティングしなくてよいというのが嬉しいポイントです。フォームを作成するときもブラウザでポチポチするだけなので他の人にも引き継ぎやすいと思います。

Googleフォーム・スプレッドシート・ドライブを使ったワークフロー

Googleフォーム、スプレッドシート、ドライブを使うワークフローは以下になります。赤字の部分が影響範囲になります。これで会計担当スタッフ(私)が関与する部分がだいぶ減りました。

  • イベント運営に必要な費用をスタッフが立て替えて支払い、領収書を受け取る
  • スタッフはGoogleフォームに必要な項目(日時、担当者名、金額、用途、領収書をスキャンしたPDF)を入力し申請を行う
  • Googleスプレッドシートに入力された内容が同期され、領収書PDFは特定のGoogleドライブフォルダに保存される
  • 会計担当スタッフはGoogleスプレッドシート上で立て替え費用を集計する
  • (スポンサー等から)費用が運営に入ってきたら、会計担当スタッフは立て替えてくれたスタッフに精算を行う

プラスα

これで運用の負担はだいぶ減ったのですが、フォームに申請があっても私にしか通知が届かないという課題としてありました。課題と感じた理由としては、私のメールにのみ届くため見落とす可能性がある、また申請者や他のスタッフにも通知がある方がオープンになって良いという点です。

そこでGAS(Google Apps Script)を使ってJAWS-UG金沢のSlackに通知する機能を実装しました。実装方法については以下のリンクが詳しいですのでこちらを参照ください。(「google form slack」でGoogleするといろいろ参考になる記事がでてきます)

qiita.com

うまく連携できるとSlackには以下のような通知が来るようになります(アイコンはそれっぽい絵文字を指定した)。フォームに入力された値を使って通知メッセージを生成しています。

Image from Gyazo

Slackの通知を含めると最終的にはこのような仕組みとなりました。*1

f:id:TAKAyuki_atkwsk:20191017232035p:plain

おわりに

これまで見てきた仕組みによって要件を満たしつつ運用としてはだいぶ楽になりました。その分仕組みを考えるときや作るときには多少頑張りました。今回は立て替え金管理というフローで利用しましたが応用できる業務フローは他にもあると思います。このような仕組みで頑張らない運用を考えるのも面白いですね。

最後に宣伝ですが、11月20日に金沢でAWS Community Dayが開催されますのでAWSクラウド、IoT、ビッグデータにご興味のある方はぜひお越しください。お待ちしております。

awscommunityday2019.jaws-ug.jp

*1:アイコンはこれらを利用しています Googleフォーム新しいロゴ icon by Icons8, Googleスプレッドシート icon by Icons8, Google ドライブ icon by Icons8

Kanazawa.rb meetup #85 に参加しました #kzrb

記事を書くのがご無沙汰。前回の#84でKanazawa.rbは7周年を迎えて、今月からは8年目に突入しています。

kzrb.doorkeeper.jp

GraphQL Frontend入門

How to GraphQLというチュートリアルサイトがあって、もくもく会ではこれのフロントエンド編(React + Apollo)を写経していました。実はバックエンド編は一度写経を終えています。

www.howtographql.com

GraphQLの基本的な概念はすでに学んでいたため、今回の写経ではReactのコンポーネントとは?とかそういうところで時間が取られてしまいました。ここ最近のフロントエンド事情は疎い限りなのですがVue.jsをちょろっと触ったぐらいなので、モジュール化するのはなんとなく分かるけど状態管理あたりはさっぱりです。。今回の題材はReactですが基礎は抑えておきたいと思いました。ひとまずMutations: Creating Linksまでは完了。

雑談

近くに @_kentaro_m さんが座っていて、「Gatsby.jsを触っているけど内部ではGraphQLを使ってて動作を知っておきたいので何かいい資料ありますか?」と相談があったので一旦上記のHow to GraphQLを薦めておきました。あとは、なんかの弾みでマイクロフロントエンドの話になって、なるほど最近はそういう設計パターンもあるんすね、あーそれってコンウェイの法則があてはまってるのかな?とかいろいろ話していました。最近読んだEffective DevOps本の影響もあって組織とソフトウエア設計、パターンの関連について興味が出てきていて食いついたのもありますね。

余談。楽しそうな飲み物があったので即購入!

懇親会

www.hotpepper.jp

www.hotpepper.jp

1件目はイタリアン大衆酒場のお店。よく通りすがるけど入ったことなかった。2件目はおなじみの手羽先のお店。

富山から参加されていた @kunitoo さんが隣の席だったので Toyama.rb の話とかリモートワークの話とか聞いてました。あとは、@yu_kgr さんの近況やキャンプ、台湾の屋台、酒は資産、山が安く売り出されているなどの話をしてました。

お知らせ

来たる11/3に富山Ruby会議が開催されます!!!私は諸々の都合で参加できないのですが、スピーカーも豪華な面々なのでぜひ参加してみてください〜。

toyamarb.github.io

また、11/20には金沢でAWS Community Day Kanazawaが開催されます!!!こっちは運営に携わってます。平日開催ではありますがぜひ参加してみてください〜。

awscommunityday2019.jaws-ug.jp

Algolia勉強会 in 金沢を開催しました

2019-07-20にDMM GAMESにてAlgolia勉強会 in 金沢が開催されました。

connpass.com

Algoliaより篠原さん(@shinodogg)をお招きし、昨今激アツな検索エンジン&APIサービスの Algolia について学びました。今回は開催に到った背景なんかをまとめておきたいと思います。

www.algolia.com

開催までの背景

www.instagram.com

私が東京にいたころ、Bracket(現ストアーズ・ドット・ジェーピー株式会社)という小さなスタートアップ企業に在籍しており、運用しているサービスでAWSを利用していたことからSA(Solutions Architect)によるアドバイスを受けたり相談してもらったりしていました。篠原さんはその時のSAとして技術相談やスタートアップを対象としたミートアップなど様々な場面でお世話になっていました。

私が金沢に戻ってからはお会いする場面はなくなっていたのですがSNSで近況を見ているとAlgoliaに転職したというのが流れてきました。しばらくしてKanazawa.rbのとある回で清原さん(@kiyohara)がAlgoliaについて調べていて、実はAlgoliaにこういう方がいるんですって言ってみたところ駄目元で金沢来て話してくれないかなーと盛り上がり、早速篠原さんにFacebookで連絡を取ってみることに。すると二つ返事でやりましょうと言っていただき、そこからトントン拍子で勉強会の内容やスケジュール等が決まっていきました。このスピード感はスタートアップさながらの雰囲気でしたねw

実務的なところは清原さんがゴリゴリ進めてもらって非常に助かりました。また、Kanazawa.rbやJAWS-UG金沢のメンバーそしてDMM GAMESさんにも協力いただいて開催までおよび当日もスムーズに運営できました。この場を借りて皆様にお礼申し上げます 🙇

実際に動かしてみて

www.slideshare.net

さて、勉強会ではハンズオンを行い、AlgoliaのInstantSearch.jsを利用した検索ページを作成しました。InstantSearch.jsはAlgoliaが提供しているオープンソースで、これによってsearch APIのクライアントおよびUIウィジェットを利用することができます。

github.com

ハンズオンでは、シンプルなhtml1ファイル、javascript1ファイル、CSS1ファイルで商品検索ができるページを作成しました。インストラクションの通りに実装してみると、検索結果が返ってくるまで速いこと速いこと。サーバーに通信しているのに平気で20msを切るようなレスポンスになっていてうわさ通りの爆速っぷりを見せてくれました。

また、インクリメンタルサーチや範囲検索(例えば、¥10,000〜20,000のような価格の範囲)、typo-tolerance(打ち間違えてもそれっぽい結果が返ってくる)なども利用できて感心しました。こういうのは自前でフロントエンド含めて一から実装しようとするとかなり手間がかかるものだと思っているので、シュッと実装できてしまうのはAlgoliaのおすすめポイントだと感じています。

懇親会

アーキテクチャの話からキャンプは最高、体を動かすことについて、自転車を買った、金沢人の酒の飲み方などなど篠原さんを交えて楽しい時間を過ごせました。だいぶ飲んでしまいましたがw

感想

この勉強会開けてよかったなと思うのは、Algoliaというサービスを知ることができて、あーこういう解決方法が存在するんだーという学びを得たことです。私自身恥ずかしながらこの勉強会まではAlgoliaというサービスを知らず、検索機能を実装するにはElasticsearchやCloudSearchを使って良い感じにやるという解をぼんやり思い浮かべていたのですが、他の選択肢としてAlgoliaもあるよねと知れたのは大きいです。

togetter.com

また、参加者の皆さんにも概ね好評(と受け取れる)だったようでなによりです。継続的に学習する場、学んだことをアウトプットできる場というのを今後もお手伝いできればいいなと思った次第です。

最後に宣伝になりますが、次回のKanazawa.rbは7周年記念のLT大会なので、こちらもご参加いただければと!!

kzrb.doorkeeper.jp

ScalaMatsuri 2019に参加しました #ScalaMatsuri

2019年6月28日、29日に東京で開催されたScalaMatsuri 2019に参加してきました。2016年に参加して以来2度目の参加でした。以下聴講したセッション+αについてメモや感想を書いていきたいと思います。

2019.scalamatsuri.org

関数型オブジェクト指向命令型 Scala

  • Scala.jsのAuthor @sjrdoeraene さん
  • 関数型、オブジェクト指向、命令型(手続き型)、さまざまなパラダイムScalaでは使うことができる
    • Scala.js のコードを例に出しながら解説していた。
    • apiの中で、アルゴリズムによっては関数型で書くと読みづらいまたは複雑になる場合、varを使うことも考えてよい。
    • sometimes, builders are better in readability というケースもある。
    • mutableな状態をクラス内に持っているけど、privateになってるので外からは見えない。(encapsulation)
    • いろいろなパラダイムを局所化(クラスの中に隠蔽しておく等)しておくというのがポイントだと思った。
  • こういう点はScalaの良いところだと思う

Scala における型クラス入門

speakerdeck.com

  • @phenan さん
  • 型クラスを、型システムにより支援されたストラテジパターンとみなすと理解しやすい
    • 少し理解が進んだ
    • Scalaでは型システムとimplicitパラメーターのおかげで良い感じに実装できる
  • 拡張メソッドの話
    • implicit classで既存のクラスにメソッドを追加できる
    • 型制約(implicitパラメーター)をつければ型クラスインスタンスでのみ使えるようにもできる
  • Scala3での型クラス利用法の紹介
    • implicitの用途がいろいろあって混乱しがちなので、Scala3ではキーワードが個別に定められていて良いと感じた
  • 型クラスを理解して実装できるようになるとScalaレベルが一段あがるような気がする

Spotify での Scio を使ったデータ処理

spotify.github.io

  • @skaalf さん
  • big data is big money
    • 大量のデータを扱うにはコスト管理(ストレージ、ネットワーク、コンピューティング)も大変というのは確かになあと思った。いかに効率的に行うかもビジネスに関わってきますよね。
  • Kryo to Typesafe coder. runtime black magic から compile time black magicになったという説明が面白かった
  • 巨大なデータを分割(シャード?)してマージするというjoinの仕方(SMB join)があるのを初めて知った
  • データ処理分野でもScalaが利用されているんだなあというのは今回の発見だった

休憩スペース

休憩スペースでは、freeなコーヒーとお菓子が提供されていました。私は一人でコーヒー飲みながら休憩してましたが、複数人で雑談してる人も多かったです。

Scala Driven Management

speakerdeck.com

  • @hiraiva さん
  • レビューとして型安全性と仕様的に正しいかに注力したというのも興味深いポイント
    • プロジェクトで使える時間も限られているため、スコープを絞るのは重要だなあと思う
  • 型安全性、ケースクラス、エコシステム(Java資産含めて)のおかげで最小のマネジメントコストで実装できたとのこと

プロジェクトで引き回す型をEffにするメリット

speakerdeck.com

  • @wing_007 さん
  • for糖衣構文を利用するに当たってどの型を使うか問題
    • 型合わせ問題…
  • 発表者は Eff[R, A] という型を利用しているとのこと
    • 銀の弾丸ではないと思うが、調べてみても良さそうだなと思った

お昼ご飯

海外からの参加者も多く、宗教等に配慮してお弁当にもいくつか種類があるようでした。これは恐らくハンバーグ弁当。1階にも休憩&充電スペースがあり、ここでゆっくり食べられて良かったです。

Scala における関数型並行処理入門

slides.com

  • 昼ご飯食べて会場に着いたら立ち見だったので聞くのを諦めました…

ハイパフォーマンスScala

speakerdeck.com

  • 発表者の経験からすると、パフォーマンスの問題が起きるのはI/OとGC
    • その理論を知っておくことが問題の解決につながる
  • プロファイリングツール使ってスレッドの監視すると良い
  • ノンブロッキングをサポートするライブラリはいくつかある。Slick, ScalikeJDBC-Async, quill-async, akka-http, finagle
  • ブロッキング処理用のスレッドプールを用意すべき。
    • Scalaやり始めた当初は何でもかんでも global な ExecutionContext を利用してハマった思い出がある
  • 大きなコレクションオブジェクトはGCボトルネックになる傾向がある
    • 計算するのに適切なコレクションクラスを利用しよう
    • 並列コレクション知らなかった
  • HashMapに対してWeakHashMapのkeyは弱参照
    • 参照に強さという概念を持つことを初めて知った
    • ということはkeyは独自のオブジェクトの方がよかったりするのか?(例では UserId 型のオブジェクトをkeyにしている)

Scala ♥ Graal

  • @flaviowbrasil さん
  • JITコンパイラをGraalに移行して、JVMJavaで実装できるようになったと言っていたような
    • 解釈あってる?
  • JVMの最適化でパフォーマンス改善できたっていう結論。しかし、詳細はついていけなかったw
    • 自分はまだJVMの理解は浅いのだなと再認識できた

継続とDI

gakuzzzz.github.io

  • @gakuzzzz さん
  • 再利用可能なモジュールを合成する方法について
    • 複雑な問題に対しては分割して解を合成するアプローチが必要
    • 継続渡しスタイル(CPS)と依存性注入(DI)の2つの手法を解説
  • 関数型プログラミングではCPSを使うことで再利用の粒度を変えられるようになった
    • すなわち、依存する関数を引数で渡す方法
    • これまでのプログラミングの歴史を追って再利用の粒度というのを解説しているのが良かった。
    • 構造化プログラミング→オブジェクト指向プログラミング→関数型プログラミング
  • CPSは素直に書くとネストが多重になるので、継続自体をクラスにしてmap/flatMapを定義することでforを使ってすっきり書くことができるようになる
    • このあたりはScalaらしいやり方だなと思った
  • アドホックな合成を行いたいときはCSPを使うとやりやすい

2日目

2日目の始まりは、前日までに書き込まれたアンカンファレンスで話したいことから反響の多かったものを中心に実際に行うセッションを決める「朝会」からスタート。書き込んだ人がセッション内容の概要を説明し、興味ある人が手を上げて、司会のお二人がその人数に応じて会場とコマを割り当てるというやり方。ゆるっとした空気感で良かったです。

Scala and SRE

  • アンカンファレンスで当日決まったセッション
  • 参加者みんなでテーマに沿って議論するというスタイルでした
    • モニタリング、分散トレーシング、パフォーマンスチューニング、Scalaならではのハマりポイント、etc.
  • 各社のSREが集まっていて、弊社ではこうやっているとかこういう場合ってみんなどうしてる?っていう感じでした
    • なので詳細はここには書くことができないw (これもアンカンファレンスの醍醐味ですね)
  • Javaパフォーマンス』をまずは読めと薦められた

Scala酒場

Scala関西Summitのアンカンファレンスで生まれたScala酒場がScalaMatsuriでも登場しました。Chatworkさんのブースに有志持ち込みの酒がどーんと設置されており、Scalaやその他雑談しながら飲んでました。なぜか方言の話になって面白かったですw

ハウツー・テストproper{t,l}y

speakerdeck.com

  • @larsr_h さん
  • プロパティテスティングについては興味はあるけど、まだ使えていないため知見が得られればいいなと思い聴講
  • テストの入力をどう生成するかというところの技術について解説されていた印象
  • Cogen/perturb当たりでよく分からなくなったのでつぶやいたところ、たまたま出席されていた @xuwei_k さんから解説いただいた(ありがとうございます)

感想

  • 国際カンファレンスとあって普段聞けないような話をたくさん聞けた
  • セッションによって同時通訳無しで半分程度理解できたものと、全然理解できなかったものがあった
    • 技術的な背景をどの程度知っているかにも依存しそう
  • 2016年のScalaMatsuriにも参加していたが、その頃よりも経験や知識を身に付けたのでより楽しめたと思う
    • 自分の中でこの部分は理解できてる、できていないというのが認識できてよかった
  • 写真もっと上手く撮りたい

Kanazawa.rb meetup #81 に参加しました #kzrb

今月も参加してきました。

kzrb.doorkeeper.jp

meetup.kzrb.org

会場は DMM.com のオフィスでした。毎度ありがとうございます!

CircleCIのインシデントレポートを読む

status.circleci.com

CircleCIで約2週間に渡って不安定な状態が続いていた障害についてレポートが公開されているので、これを読んで学びを得ようと思いました。

雑なメモ(雑な訳)

  • 2019-03-26から2019-04-10の間、CircleCIのプラットフォームは不安定になりダウンタイムも発生。これはビルドのキューを支えるデータストア(=MongoDB)の問題によるもの。
  • これにより、ジョブやワークフローが上手く処理できなくなった。また、パブリックAPIデグレードをももたらした。(デグレードっていい日本語無いですかね?)
  • 障害が発生した同時期にJVMのマイナーバージョンアップを行ったが、その中にDockerについての対応が含まれていた
  • 時間をおいて再びMongoDBに問題発生
    • このことより一連のインシデントにおいてJVMのバージョンアップは主な原因ではないと認識した

と、まだ全体の三分の一程度しかレポートを読めていませんが、長期に渡ってインシデントが続いたので問題が複雑そうな感じがします。

その他

他の参加者のもくもく内容を聞いて、某中の人と繋げられそう、ということで早速連絡を取ってみることに。来月辺りにお知らせができたら嬉しいです。

懇親会

GRAN NICK -グランニック-
〒920-0853 石川県金沢市本町2-374
4,500円(平均)1,200円(ランチ平均)
r.gnavi.co.jp

グランピング気分が味わえるということで女性客やデートのお客さんが多い中、Rubyおじさん御一行で一次会!料理は全般的に美味しかったです。席が隣になった @yu_kgr さんと結構喋ってた記憶。オフラインならではの内容が多かった気がしますw あとは恒例のキャンプ話とかポッドキャスト話とか。