技術書展3に行ってきた
概要
技術書展3に行ってきたので、戦利品(2点)をさらします。
まだ、中身は読めていないです。
(あまり買えなかったですね..)
戦利品
- こうしてぼくらは、書籍を売るアプリを作った
- Gopher Walker
こうしてぼくらは、書籍を売るアプリを作った
メルカリカウル を作った話ですね。
気になる内容
- ChatOpsの勘どころ
- Goのinterface設計
Gopher Walker
golang.tokyo が出版した本(PDF)です。
Gopherとして読んでみたい本でした。
(無料配布でしたが、少額の寄付をさせていただきました!)
気になる内容
感想
この台風前の雨の中、大勢の方が来られていました。 よくみられた出版物は下記の形の印象でした
- 機械学習系
- やっぱり多かったですね
- Swift
- Swift系の出版物がちらほらみられました
Go系のものがまだまだ少なかったので、増えてくれるとうれしいですね。
次回も覗きに行けたらいいかなぁと思います。
補足
「Goならわかるシステムプログラミング」が買えなかったのが残念です。
Serverless App作成ツール Up を利用してみた
概要
up と呼ばれるツールを利用してみました。
(Introductionをそのまま試してみただけです。)
upとは?
Serverless Applicationを簡単に作成、デブロイできるツールです。
現状の構築環境と方式は、下記のとおりです。
対応言語
個人的にはGolangに対応しているのが良いですね。
(Lambda自体はまだ、Golang対応していないので)
手順
こちらのサイト に記載のまんまです。
1. Install
curl直接 or npm
# curl版 % curl -sfL https://raw.githubusercontent.com/apex/up/master/install.sh | sh # npm版 (内部で上記curlを叩いているだけです) % npm i -g up
2. AWS Credenstialsの設定
~/.aws/credentials
に追記が楽かと思います。
[go-up-test] aws_access_key_id = xxxxxxxx aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxx
3. up.json
(設定ファイル)作成
必須の項目は、profile
のみです。
~/.aws/credentials
で設定したprofile名と合わせてください。
{ "profile": "go-up-test", "regions": ["ap-northeast-1"] }
4. 好きな言語でサーバー側の処理を記載
package main import ( "fmt" "log" "net/http" "os" ) func main() { addr := ":" + os.Getenv("PORT") http.HandleFunc("/", hello) log.Fatal(http.ListenAndServe(addr, nil)) } func hello(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello go-up-test") }
5. Deploy
# develop環境へのDeploy % up # production環境へのDeploy % up deploy production
6. 確認
# ブラウザでOpen % up url --open # ClipbordにCopy % up url --copy
% curl "https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/development/" Hello go-up-test
補足
# past 5 minutes % up logs # real time log % up logs -f
up stack delete
で作成したresourcesを全て削除できます
サンプルコード
所感
AWSの設定さえ終わっていれば、非常に簡単にServerless Appを作成できると感じました。Slack Commandが簡単に作れるようなので、試してみたいです。 (元々、SlackのSlash Commandを簡単に作れるという記事を見かけて、興味を持ちました。)
参考
Machine Learning事始め (TensorFlow)
概要
お盆休みを利用して、Machine LearningをTensorFlowのTutorialを通して触れてみました。
解いた問題は、手書き数値の認識です。
Machine Learning
おこなっていることは、任意のグラフに対して近似する関数(=Model)を見つけること
用語
- データ
- (Training用) データとそのラベルのセットを持つ必要がある
- ex) 手書き文字 <-> 書いてある文字
- (Test用) accuracyを計測するためのデータ
- 同様にデータと正解ラベルを持つ必要がある
- (Training用) データとそのラベルのセットを持つ必要がある
- weight
- 入力値への重みテンソル(行列)
- bias
- weightと入力値の積をずらす
- x
- 入力値
- y
- 出力
- activation function
evidence = W * x + b ------------------- Tensor W = weight x = input b = bias -------------------
- softmax function
- evidence(活性化関数=activation functionの結果)を確率へと変換する
- 確率より 0 <= y <= 1
- loss function
- 期待値と実際の結果の差分を計測する関数
- ※ loss functionの結果を0に近づけることが目標
(=期待値と実際の値が一致する)
Machine Learningの流れ
- Trainingデータセットを用意する
- activation function(
W * x + b
)を定義 - loss functionを定義
- TrainingするOptimizerを決めて、loss functionをセットする
ex) Gradient Decent (最小勾配法) - Trainingを実施
テストデータを利用して、関数を何度も実行する。
実行するたびに、W
とb
をOptimizeする。(TensorFlow利用時は勝手にOptimizeしてくれる) - Modelのaccuracyを測定する
サンプルコード
手書き数値の認識
CNNを利用せずにの実装もできましたが、accuracyを上げるためにも、CNNを利用したほうが良いみたいです。
Convolutional Neural Network
- 畳み込みニューラルネットワーク
- 面を一定の大きさのフィルタで覆い、領域で特徴量を抽出する方法
- ex) 32x32の画像を5x5のフィルタでスライド1の場合 => 28x28の画像となる
- pixel単位でないため画像が全体的に類似しているかを判断できる
- Filter
- パラメータ
- filterの数
- filterの大きさ
- filterの移動幅
- padding
- 画像の端の領域を0で埋める
- パラメータ
- Layer
- Convolutional Layer
- Pooling Layer
- サイズを圧縮する層
- max poolingが利用される
- 領域内の最大値を取る手法
- Fully Connected Layer
肝となると感じた部分
- 大量のTrainingデータを用意すること
- accuracyを向上させるためのチューニング
まとめ
基本的に、TensorFlowのTutorialを上からなぞってコード書いてみただけですが、
Machine Learningで何やってるかを少しだけ知ることができました。
絶賛、下記を読み込み中なので読めたらneural networks
とdeep learning
について
正確に理解できるかなと思います。
Neural networks and deep learning
ひとまずPythonでやってみてますが、GolangでもTensorFlow自体は使えるので、
書き直したいところです。
参考
【WEB+DB PRESS Vol.99】k8sの記事での利用コマンド
概要
WEB+DB PRESS Vol.99 の記事を参考にk8sを利用してみました。
詳しい内容は、記事をご参照いただければと思います。(非常にわかりやすい記事でした)
下記は、記事に書いてあるコマンドのままですが、メモ書き程度に思っていただければ。
コマンド
gcloud側の設定
# project の設定 % gcloud config set project xxxx # ゾーンの設定 % gcloud config set compute/zone asia-northeast1-a # 認証設定 % gcloud auth login
コンテナクラスタ起動
# クラスタ起動 % gcloud container clusters create one \ --cluster-version=1.6.7 \ --machine-type=g1-small Creating cluster one...done. Created [https://container.googleapis.com/v1/projects/xxxxx/zones/asia-northeast1-a/clusters/one]. kubeconfig entry generated for one. NAME ZONE MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS one asia-northeast1-a 1.6.7 35.190.233.232 g1-small 1.6.7 3 RUNNING
GCRにイメージをbuildしてpush
# Container build file % cat manifest/cloudbuild.yaml env: ['PROJECT_ROOT=one'] args: ['build', '-o', 'goneup'] - name: 'gcr.io/cloud-builders/docker' env: ['PROJECT_ROOT=one'] args: ['build', '--tag=asia.gcr.io/$PROJECT_ID/one/goneup', '.'] images: ['asia.gcr.io/$PROJECT_ID/one/goneup']% # push gcr % gcloud container builds submit --config=manifest/cloudbuild.yaml .
kubernetes利用
Pod単独
% cat manifest/pod.yaml apiVersion: v1 kind: Pod metadata: name: goneup spec: containers: - image: asia.gcr.io/[project]/one/goneup:latest imagePullPolicy: Always name: goneup # create pod % kubectl create -f manifest/pod.yaml # port forward % kubectl port-forward [pod name] [local port]:[external port]
ReplicaSet
apiVersion: extensions/v1beta1 kind: ReplicaSet metadata: name: goneup spec: replicas: 3 template: metadata: labels: name: goneup spec: containers: - image: asia.gcr.io/[project]/one/goneup:latest imagePullPolicy: Always name: goneup # create replicaset % kubectl create -f manifest/replicaset.yaml # check replicasets % kubectl get replicasets NAME DESIRED CURRENT READY AGE goneup-1100937273 2 2 2 57s # replace replicaset % kubectl replace -f manifest/replicaset.yaml
Deployment
% cat manifest/deployment.yaml apiVersion: apps/v1beta1 kind: Deployment metadata: name: goneup spec: replicas: 3 template: metadata: labels: name: goneup spec: containers: - image: asia.gcr.io/[project]/one/goneup:latest imagePullPolicy: Always name: goneup # create deployment % kubectl create -f manifest/deployment.yaml # check deployment % kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE goneup 2 2 2 2 50s
Service
% cat manifest/service.yaml apiVersion: v1 kind: Service metadata: name: goneup spec: type: LoadBalancer selector: name: goneup ports: - port: 8080 # create service % kubectl create -f manifest/service.yaml
Ingress
% cat manifest/ingress.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: goneup spec: rules: - http: paths: - path: /* backend: serviceName: goneup servicePort: 8080 # create ingress % kubectl create -f manifest/ingress.yaml
まとめ
各マニフェストファイルを作成することで、簡単にGCP上にk8sを構築できました。
また情報にアクセスしたい際は、kubectl get xxx
で簡単にアクセスできるところが非常にいいなと感じました。
基本的な設定しか入れていないので、利用してみてもっと詳細な設定まで使いこなせると良いかと思います。
Dockerについて
概要
Dockerについて、本当に簡単な部分だけまとめてみました。
(ここから、Docker->ECS->k8s->GKEと進めていければなぁと思っています。)
Dockerとは
Software Container Platform
=コンテナが動作するプラットフォーム
Containerとは
- 一つSoftwareが実行されるために必要なすべてをパッケージングしたもの
- Softwareを動かすために必要なライブラリと設定のみが入っている
- Container内で、独自にリソースを持つ(メモリ/プロセス/ネットワーク)
どういった問題を解決するのか
「自分のローカルに環境で動いたけど、検証サーバーに載せると動かない..」
→ こういった、環境差分
を解決することができる
Containerにくるむことで、どこでも同じように安全に動作することが保証されます。 そのため、Containerにくるんでおけば安心して、検証、本番環境へとSoftwareをリリースすることができます。
Container(= Docker Container)の作り方
Dockerfileを書きましょう。
Dockerfileとは
- Docker Containerの設計が書かれたファイル
- Dockerfile` というファイル名で作成する
- 記述はDockerfile用DSL
- Dockerエンジン + Dockerfile + ソースファイル があればどの環境でも同じように実行可能
Docker image
- Dockerfileに記述されたOSやアプリケーションコード等をまとめたテンプレート
- Containerはimageを実体化したもの
- Dockerfileをbuildすることで作成することができる
- Dockerエンジン + Docker image があればどの環境でも同じように実行可能
- imageを作成して、Docker Hub等のコンテナ管理サービスにpushしておく
- Docker Hub等からimageをpullしてくるだけで実行可能に
Docker Containerの生成手順
- Dockerfile記述
- BuildしてDocker imageの作成
- imageをもとにRunしてContainerの起動
例: Go Appの実行
下記のようなGolangのHello WorldのコードをContainer内で実行してみます。
package main import "fmt" func main() { fmt.Println("Hello World!") }
\1. Dockerfile記述
下記のようなDockerfileを作成します。(詳細はコメント参照)
# ベースイメージの指定 # Docker Hub(https://hub.docker.com/)上に様々なイメージが公開されている # そちらから利用したいベースイメージを選択 FROM golang:1.8.3-alpine3.6 # 作業を行うディレクトリを選択 WORKDIR /go/src # コマンドを実行 # golangイメージは Alpine Linuxをもとに作成(軽量のためDockerでよく利用される) # linuxコマンド(ls,mkdir)等が実行可能 RUN mkdir hello # 作業を行うディレクトリを変更 WORKDIR /go/src/hello # 作業ディレクトリからコンテナ内にファイルをコピー # COPY [ホスト側] [コンテナ内] COPY . . # Go Appをbuild RUN go build -o hello main.go # コンテナ起動時に実行されるコマンド CMD ["/go/src/hello/hello"]
\2. BuildしてDocker imageの作成
% ls Dockerfile main.go # imageの作成 # (-t でタグを設定できる) % docker build -t hello:1.0 ./ # imageの確認 % docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello 1.0 df9a562be589 10 minutes ago 259MB
\3. imageをもとにRunしてContainerの起動
# コンテナの実行
% docker run hello:1.0
Hello World
まとめ
docker-composeやswam等は別途まとめようかなと思います。 また、詳細なDockerfileのDSLや、docker build/runオプションについてもまとめられたら良いですね。
参考
エンジニアとして学びたいこと(歴2年目)
概要
エンジニアとして、どのあたりを学んでいこうかなぁとの備忘録
項目
Golang
最近ずっと利用しているメイン言語です。仕事上ではJavaを利用することが多いですが、 書いている時間も量もそろそろ超えてくるのではと思っています。
好きなところはこんな感じです。
- ビルドしたバイナリがあればどの環境でも動かしやすい点
- 型あり
- Httpサーバーの起動しやすさ
- プログラマーならたぶん誰でも読める
- ドキュメントが読みやすい
学びたいこと
- パッケージの構成方法
- 自由に書けてしまってどこに何を書くかが明確になっていない
- パッケージの切り方
- 各ファイル内のinterface,strcut,methodの構成
- 周辺ツールの利用方法
- ツールが充実しているのことで、きっちり使い方を抑えたい(pprofとか)
- 実務上でのコードレベル
- OSSのライブラリ等を読んでみる等ですかね
- 体系的な知識
- Webでの情報がメインのため、体系的な知識が身についてない疑惑
- 書籍でまとまったものがあれば一度読むのも良いかも
次のステップ
- 標準ライブラリ読む
- OSS読む
- 本をよむ
- 実務での利用
- 布教
クラウド
実務できっちり利用できていない分、プライベートで学んでおかないと遅れが目立ってしまう印象です。
学びたいこと
次のステップ
- GAEにGoサービスを載せてみる
- WEB+DB PRESS Vol.99を読む
低レイヤー
Goならわかるシステムプログラミングを読んでいて感じましたが、低レイヤーの知識が圧倒的に足りないと感じます。このあたりのコンピュータサイエンスについて、きっちり抑えておきたいです。
低レイヤー周りを最適化したコードを実装できるように、理解を深めたいです。
学びたいこと
次のステップ
- Web記事を読む
- 書籍を読む
まとめ
ざっくりと思い当たることについて、並べて書いてみました。自分の整理にはなったかなとは思います。
学ぶのに良い情報をお持ちの方がいたら、ぜひ教えていただけると幸いです。
まだまだ、手を動かしてコードを書く経験値が足りなさすぎるので、手はとにかく日々動かし続けていきたいとは思っています。
GoSNS
概要
AmazonSNS likeな、簡易メッセージングサーバーを練習がてら書いてみました。
(Amazon SNSちゃんと使ったことないので、ぜんぜん違うかもしれないですが…)
モデルは、Pub/Subを意識しています。
機能概要
- Channel登録
- Channelに対して購読登録
- 購読手段はSlackのWebHook一択(Mail等の対応も検討中)
- 新規Channelの開設
- Handshakeリクエスト
簡易API Doc一覧
メルカリ製のgo-httpdocを利用してドキュメント生成しました。
I/F
基本POSTリクエストでサーバーとやり取りをします。
POSTのBodyに下記のRequest構造のJSON
を書き込んでリクエストします。
Channel登録 (/meta/channel)
新規に開設したい、Channelを登録します。
Request
名前 | 型 | 概要 |
---|---|---|
channel | String | 登録したいchannel名 |
サンプル
{ "channel": "golang" }
Response
JSON構造
名前 | 型 | 概要 |
---|---|---|
channel | String | 登録したchannel名 |
successful | String | 登録成否 |
error (optional) |
String | エラー |
購読登録 (/meta/subscribe)
購読の登録をします。
現在は、Slack通知(WebHook URL)を用いての手法にのみ対応しております。
Request
名前 | 型 | 概要 |
---|---|---|
channel | String | /meta/subscribe |
client_id | String | ID(現在は適当な文字列) |
subscriptions | Array(String) | 購読したいchannelのリスト |
method | Method | 購読手法 |
Method
名前 | 型 | 概要 |
---|---|---|
method | String | 購読手段(下記選択) - slack |
webhook_url | String | Slack WebHookURL (slack選択時必須) |
サンプル
{ "channel": "/meta/subscribe", "client_id": "MRAjWwhTHcgagka", "subscription" : [ "/golang" ], "method" : { "format": "slack", "webhook_url": "https://hooks.slack.com/services/XXX" } }
Response
JSON構造
名前 | 型 | 概要 |
---|---|---|
channel | String | /meta/subscribe |
successful | String | 購読成否 |
client_id | String | ID |
subscriptions | Array(String) | 購読したchannelのリスト |
error (optional) |
String | エラー |
Topic登録 (/topic)
Channelに対して、Topicを登録します。
Request
名前 | 型 | 概要 |
---|---|---|
channel | String | Topic登録するchannel名 |
data | String | Topic内容 |
{ "channel": "/golang", "data" : "*Update GAE Go1.8*" }
Response
文字列
文字列 | |
---|---|
成功 | ok |
失敗 | not found channel |
内部実装
どのように実装をしているか、メモ書き程度に残しておきます。
Pub/Sub Model
PublisherとSubscriberの関係は、1Topicに限ると1対多の関係です。
PublisherはどのSubscriberに送信するかといった情報には関与しません。
Publisherはtopicを送るだけ、Subscriberは送られたTopicを購読するだけといった構成です。
データ保持
購読データの保持は、JSONファイル
にて行っております。
(DB等の利用がベタ-かと思いましたが、ファイルが一番楽だったので選びました)
ファイルI/Oを呼び出しごとに発生させたくなかったため、内部でキャッシュを持たせています。 キャッシュとファイルは常に同期している想定です。
ただ、キャッシュから時間でデータが破棄されることもあり、キャッシュにない場合はファイルを見にいくようにしてます。
ユーザー認証
完全に未実装です。認証なくPOSTが送れたら自由にデータの書き換えができます。
テスト
go-httpdoc に記法にならって記述しています。
API I/Fの部分以外で書けていないところは、順次書き足したいです。
パッケージ管理
depを利用しています。 管理ファイルがtomlファイルになってて驚きましたが、問題なく使えています。
利用しているライブラリ一覧
- API Documet作成用 github.com
- 購読情報のキャッシュ github.com
- パッケージ管理 github.com
感想
Goを触り始めて、初めてある程度ましな成果物を作成しました。
AmazonSNSのドキュメントを読んで、メッセージングサーバーの面白さを感じ、とりあえず自分でも作ってみたといった感じです。
書いてて感じたことですが、パッケージ構成の方法
がよくわからなかったです。
パッケージの切り方や、同一パッケージ内でのファイル分割の方法等で、いまいち方針がなく何度も再構成しました。
他の方のソースを読んで、このあたりは勉強していこうかなと思います。
総じて、楽しく書けたのでGoはかなり自分にあっている気がします。