gitkadoの気まぐれ日記

島根在住エンジニアが何かに興味を持ったらブログを更新します

【備忘録】MacにNode.jsをインストール

Dockerでの開発だと色々と不便だったのでホストに入れることにした。
直接入れるのは嫌なのでバージョン管理できるようにした。

余談: 最近のMacでデフォルトでzshなんですね。知らんかった

anyenv install

git clone https://github.com/riywo/anyenv ~/.anyenv
echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(anyenv init -)"' >> ~/.zshrc
exec $SHELL -l

nodenv install

anyenv install nodenv
exec $SHELL -l
nodenv

# anyenv経由でnodenv入れた場合に必要だった
touch $(nodenv root)/default-packages

# nodenv経由で入れたnodeにyarnを入れる場合に必要だった
mkdir -p "$(nodenv root)/plugins"
git clone https://github.com/pine/nodenv-yarn-install.git "$(nodenv root)/plugins/nodenv-yarn-install"

Node.js install

v12.6.0をインストールしてグローバルに設定する。

nodenv install 12.6.0
nodenv global 12.6.0
node -v

# 特定フォルダ内のみに適用する
cd 'your-project-folder'
nodenv local 12.6.0

yarnコマンドでnode-gypのエラーが出た場合の対処

xcodeを入れ直して対処する。

yarn cache clean
sudo rm -rf $(xcode-select -print-path)
xcode-select --install

参考

Node.jsのバージョンを自動で切り替えられるnodenvが超便利
nodenv のインストール時に default-packages file not found と表示される問題
nodenv経由でインストールしたnodeにyarnをインストール
Macでyarn installしたらnode-gypのエラーが出た

最近知ったこと(gRPC編)

仕事でgRPCを触る可能性があったので軽く調べてみました。
前提知識としてRPCを簡単に説明します。

gRPCとは

f:id:gitkado:20200523010426p:plain

転載: What is gRPC?

プチ情報(本編では深掘りしない)

grpc-gateway(GitHub)

  • gRPCをREST APIとして呼び出せるようにする
  • RPCサーバに対してのリバースプロキシサーバを起動する(参考)
    • コンテナ内で2つのサーバを起動することになる(うーん...)
  • ルーティングはProtocolBuffersに定義してbuildする

No plan to support
True bi-directional streaming.

  • grpc-gatewayは双方向streamingに対応していない
    • ProtocolBuffersで双方向streamingを定義してはいけない
    • 個人的にはgRPCの速度パフォーマンスが活かせないので微妙

身の回りのgRPC

Googleの認可基盤(Zanzibar)ではgRPCが使用されています。

実装例

1. service.proto(ProtocolBuffers)を作成

syntax = "proto3";
package authorization;
option go_package = "pb;authorization";

service Authorization {
    rpc Check (stream CheckMessage) returns (stream CheckResponse);
}

message CheckMessage {
    string name = 1;
}

message CheckResponse {
    bool is_check = 1;
}

2. 以下のコマンドでservice.protoからGo言語のコードを生成

protoc --go_out=plugins=grpc:. pb/service.proto

3. 生成されたコードのinterfaceをServer/Clientそれぞれで実装

サンプル

動くコードを書いてみました。(Dockerが必要です)

github.com

感想

とりあえずgRPCでServer/Clientは実装できたからOKとしよう。
本編と関係ないがZanzibarの論文読むのは辛かった...

最近知ったこと(AWS FireLens編)

TL;DR

Amazon ECSコンテナからのログ送信がかなり柔軟に設定できるようになった。
(しかもすごく簡単!)

これまで

ECSコンテナからログを出力する場合に、LogDriver: awslogsを以下のように設定すると、Amazon CloudWatch Logs にログが送信されます。
LogConfiguration設定値について

LogConfiguration:
  LogDriver: awslogs
  Options:
    awslogs-group: /ecs/example
    awslogs-region: ap-northeast-1
    awslogs-stream-prefix: ecs

ECSコンテナがEC2タイプの場合は、LogDriverの選択肢も多く比較的困らないと思います。
しかしFargateタイプの場合は、LogDriverの選択肢がawslogssplunkの2択でした。

サポートされているLogDriverのいずれかを選択する必要がありましたので、
選択肢以外の出力先(*1)を選択したい場合に、追加のソフトウェアを維持する必要がありました。
*1 … Amazon Elasticsearch、Amazon S3サードパーティなど

docs.aws.amazon.com

AWS FireLens について

2019年11月にリリースされました。 公式ページ

FireLens を使用することで、顧客は、デプロイメントスクリプトを修正したり、手動で追加のソフトウェアをインストールしたり、追加コードを書き込んだりすることなく、コンテナログをストレージや分析ツールに直接追加できます。Amazon ECS または AWS Fargate の設定をいくつか更新することにより、必要な場所にコンテナログを送信することを FireLens に指示するため、宛先を選択し、オプションでフィルターを定義します。

FireLens は、

使用例

ECSからKinesis Data Firehoseにログ送信

f:id:gitkado:20200416111057p:plain

LogConfiguration:
  LogDriver: awsfirelens
  Options:
    name: firehose
    region: ap-northeast-1
    delivery_stream: my-stream

Source: https://aws.amazon.com/blogs/containers/under-the-hood-firelens-for-amazon-ecs-tasks/

ECSからfluentdにログ送信

LogConfiguration:
  LogDriver: awsfirelens
  Options:
    Name: forward
    Host: fluentdhost
    Port: 24224

Source: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_firelens.html#firelens-example-forward

ECSからサードパーティ(Datadog)にログ送信

LogConfiguration:
  LogDriver: awsfirelens
  Options:
    Name: datadog
    Host: http-intake.logs.datadoghq.com
    TLS: on
    apikey: <DATADOG_API_KEY>
    dd_service: my-httpd-service
    dd_source: httpd
    dd_tags: project:example
    provider: ecs

Source: https://github.com/aws-samples/amazon-ecs-firelens-examples/tree/master/examples/fluent-bit/datadog

最後に

ログ関係は知識が浅いので、これを機に調べてみようと思いました。
知らないけどCloudのログに関するベストプラクティスとかありそう。

AWS FireLensは、オンライン開催になったJAWS DAYS 2020のセッションから知りました。
来年は新型肺炎も終息して、現地で発表を聞けると信じてます!

参考サイト

aws.amazon.com

github.com

aws.amazon.com

最近知ったこと(Amazon RDS Proxy編)

TL;DR

AWS LambdaからDBサーバ(RDS)に繋ぐのがアンチパターンとは言い切れなくなった。

事前説明

DB(RDBMS)には最大同時接続数なる設定値が存在します。
Lambdaはリクエスト毎にコンテナを起動して関数処理を行います。
(リクエスト数 = コンテナ数)

これまでの問題点

LambdaからDBサーバ(RDS)に繋ぐのはアンチパターンである(以下、理由です)

DBサーバはメモリやリソースを、DB接続(コンテナ)毎に消費します。
サーバーレスアプリケーションは短時間に何万ものリクエストが発生します。
Lambdaのコンテナ間ではコネクションプールを共有できないので、
DBサーバが耐えきれず消沈してしまうわけです。
(リクエスト数 = コンテナ数 = コネクション数)

Amazon RDS Proxyについて

AWS re:Invent 2019 で発表されました。現在はプレビュー版です。(2020年4月14日時点)
公式ページ

  • アプリケーションとRDSのコネクションをプロキシでプール及び共有してくれます
    • DBサーバのリソース消費削減とアプリケーションのスケーラビリティが向上しました。
      ※ Lambdaに限った話ではないです
  • サポートしているDBエンジンのプロトコルと互換性を持っています。
    • アプリケーションは接続先をRDSではなくRDS Proxyに向けてやるだけでOKです。

Amazon RDS Proxy で何が変わった

Lambdaのコンテナ間ではコネクションプールを共有できないので、
DBサーバが耐えきれず消沈してしまうわけです。

コンテナ間ではプール共有できないですが、プロキシ内で共有することができます。
その結果、これまで問題になっていたDBサーバへのリソース消費が改善されました。

(リクエスト数 = コンテナ数 = コネクション数)

ではなくなりました!

最後に

RDS Proxyは、オンライン開催になったJAWS DAYS 2020のセッションから知りました。
来年は新型肺炎も終息して、現地で発表を聞けると信じてます!
(LambdaからRDSを呼び出すアーキテクチャのサービス紹介が何件か出てくると予想)

自分用 Vuejsルールを書いてみた

趣味プロダクトでVuejsを触ろうと思ったが、フロント開発なんてしたことない。
命名規則が結構大事そうだったから、自分用にルールをまとめておくことにした。

自分用 Vuejsルール

単一ファイルコンポーネント

  • ファイル名はパスカル
    o MyComponent.vue
    x mycomponent.vue, myComponent.vue

基底コンポーネント

  • 頻繁に使われる基底コンポーネントのファイル名は、Baseで始める
    o BaseIcon.vue
    x MyIcon.vue, Icon.vue

シングルインスタンスコンポーネント

  • ページごとに1回しか使われないコンポーネントは、Theで始める
    o TheHeading.vue, TheSideBar.vue
    x Heading.vue, SideBar.vue

コンポーネント

  • 複数単語
    o todo-item
    x todo

テンプレート内コンポーネント

JS内コンポーネント

propsプロパティ名

  • 定義時はキャメル
    o greetingText
    x greeting-text
  • HTML(テンプレート)やJSXで使う時はケバブ
    o greeting-text
    x greetingText

ディレクティブ短縮記法

  • 短縮記法を使用
    o :value, @input
    x v-bind:value, v-on:input

その他

  • propsプロパティはできるだけ詳細に定義する
    • データ型は絶対
  • dataプロパティはオブジェクトではなくオブジェクトを返却する関数にする
    • 1画面で複数回呼び出される場合に同一オブジェクトを参照することになる
  • v-forではkeyを付与する
    • 内部的にDOM切替の際に該当keyのみに反映させてくれる(パフォーマンス向上)
  • コンポーネント親子間やりとりでは$parent$childrenを使用しない
  • 状態管理はVuexを使用する

SAM使って文字起こし&言語分析してみた

はじめに

先日開催された JAWS-UG Shimane#10 で行ったハンズオンが非常に面白かったです。
ざっくり下図のような構成のハンズオンで、以下のリポジトリがハンズオンの資料です。

f:id:gitkado:20200206191753p:plain

https://github.com/harunobukameda/Amazon-Translate---Amazon-Polly---Amazon-Transcribe---Amazon-Comprehend---Amazon-Elasticsearch

ここから本題

これらをハンズオン後に、AWS SAM 使って一式構築してみました。

↓ 実装したソース一式
https://github.com/gitkado/aws-sam-polly-transcribe-comprehend

ポイント

  • Lambda関数をRubyで実装しました。
  • SAMを使用してワンライナーで構築することができます。

利用サービス

構成

f:id:gitkado:20200206191746p:plain

TranslateFunction

  1. 英語文章でリクエストされたparams['text']を日本語文章に変換して出力(Translate)

ComprehendFunction

  1. リクエストされたparams['text']を読み上げてmp3ファイルを生成 (Polly)
  2. 作成したmp3をS3にアップロード (S3)
  3. S3のmp3ファイルを文字起こし (Transcribe)
    ※ params['text']と同じ値が生成される予定
  4. 文字起こししたJSONファイルを言語分析して結果を出力 (Comprehend)

実行手順

  • Cloud9上で実行できることは確認できています。
  • Cloud9で本リポジトリをcloneして使用してください。
    • template.yamlの7行目に作成するS3バケット名を入力して使用してください。
# 関数実行
$ sam local invoke TranslateFunction --event events/us_event.json
$ sam local invoke ComprehendFunction --event events/ja_event.json

# APIサーバ起動(http://127.0.0.1:3000/)
$ sam local start-api

# sam package
$ sam package \
    --template-file template.yaml \
    --s3-bucket 作成済みの自由なバケット名 \
    --output-template-file packaged-template.yaml \
    --region ap-northeast-1
# sam deploy
$ sam deploy \
    --template-file packaged-template.yaml \
    --stack-name cfn-aws-sam-polly-transcribe-comprehend \
    --capabilities CAPABILITY_IAM

感想

  • AWSを知ったつもりになっていたが、まだまだ奥が深い。
  • Comprehend, Polly, Transcribe, Translateをそれぞれ初めて知って始めて使った。
  • こんな面白いサービスが準備なく、手軽に使えるのはクラウドの強みだと思った。
  • これらの使い方は大体わかったので、LINE BOTとかと組み合わせて、いい感じに何かしたいと思った。
  • 亀田さん、ありがとうございました!!
    また島根でお待ちしてます!!

ちょっとirb使わせて!ってなったメモ

Dockerでirb実行できました

ちょっとしたことを試したかった。そう、Rubyで。

あて、irbっと。あれ?Ruby入ってない...
※ 業務用Windowsでの話です

dockerは入ってる!よし、なんとかなりそう。 ちょっと手を加えたら日本語も入力できた。メデタシメデタシ

$ docker run -it --rm -e LANG=ja_JP.UTF-8 ruby:2.7.0 irb --noreadline
irb(main):001:0> 

最後に一言

Macで仕事したいわ...