サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
アメリカ大統領選
www.sambaiz.net
GASでAPIを公開する方法として、scripts.run APIで実行できる実行可能APIと、ウェブアプリがある。 前者は認証が走り実行者の権限で動くが、後者は認証を行わずデプロイユーザーの権限で動かすこともできるのでパブリックなAPIとして使うことができる。 当然、不正な操作が行われないように注意する必要があり、GASのQuotaやhard limitも気にする必要がある。無料で運用することができるが、レイテンシやエラーハンドリング、監視などを考えるとやや心許ない。 ウェブアプリではdoGet(e)とdoPost(e)を実装することでそれぞれのメソッドのリクエストをハンドリングできる。これ以外のメソッドには対応していない。 function doGet(e) { return ContentService.createTextOutput(JSON.stringify(e.parame
Raspberry Pi 3台でKubernetesクラスタを構築する、2020年版おうちKubernetesインターンの資料が公開されていたのでやってみる。 Kubernetesのバージョンはv1.20.6にした。 おうちで「おうち Kubernetes インターン」を実施しました | CyberAgent Developers Blog 材料調達 ほとんどの材料は書いてあるURLで揃えられたが、PoE HATは在庫が切れていたのでスイッチサイエンスで買った。Raspberry Pi 3 Model B+専用と書いてあるが4でも使える。 PoE(Power over Ethernet)はIEEE802.3afとして標準化されているLANケーブルで給電する技術で、48Vで最大15.4Wまで出力できる。 PDではない通常のUSB Type-Cが5Vで15Wなのでそれとほぼ同等のワット数だ。
autograd(自動微分) Tensorは自身が作成された関数の参照.grad_fnを持ち、backward()が呼ばれるとbackpropしてrequires_grad=TrueなTensorの勾配を自動で計算し.gradに入れてくれる。 MLPと誤差逆伝搬法(Backpropagation) - sambaiz-net import torch x = torch.randn(4, 4) y = torch.randn(4, 1) w = torch.randn(4, 1, requires_grad=True) b = torch.randn(1, requires_grad=True) y_pred = torch.matmul(x, w) + b loss = (y_pred - y).pow(2).sum() print(x.grad, w.grad) # None None
ブラウザから直接API GatewayのエンドポイントにアクセスしたときにCognitoのTokenで認証し、失敗したらログイン画面を表示させる。 API GatewayでCognitoの認証をかける場合、AuthorizerでUserPoolを指定するのが最も簡単なパターンだが、 これだとHeaderにTokenを付けてアクセスする必要があり認証に失敗するとUnauthorizedが返る。 Cognito UserPoolとAPI Gatewayで認証付きAPIを立てる - sambaiz-net なおAPI GatewayではなくALBをLambdaの前段に挟めば今回やることが簡単に実現できる。 LambdaとALBでCognito認証をかけて失敗したらログイン画面に飛ばす - sambaiz-net 準備 UserPoolとClientを作成する。 CloudFormationで作成
EC2でECSのServiceを動かすCFnテンプレートを書く。以前Fargateで動かしたものを一部再利用する。 ECS FargateでSidecarのFluentdでログをS3に送る構成をCloudFormationで構築する - sambaiz-net EC2で動かす場合、自分でリソースが不足しないようにインスタンスのスケールを気遣うことになるがprivilegedをtrueにするなどEC2でしかできないことがある。あと同リソースで比較すると安い。 まずはEC2インスタンス以外のリソースを書く。LaunchType以外はFargateのときとほぼ同じ。 LBなしでバッチのようなものを動かすことを想定した最小構成。 ECSCluster: Type: AWS::ECS::Cluster Properties: ClusterName: 'test-cluster' LogGroup:
GoでLispのcons,car,cdrの式を評価したい。 流れとしては字句解析器(lexer, tokenizer, scanner)でソースコードを分割しtoken列にして、構文解析器(parser)で構文木を作るなりして評価できるようにする。 $ brew install clisp $ clisp > (cons 1 ()) (1) > (cons () 1) (NIL . 1) > (car (cons 1 (cons 2 3))) 1 > (cdr (cons 1 (cons 2 3))) (2 . 3) package main import ( "fmt" "go/token" "go/scanner" ) func main() { var sc scanner.Scanner src := []byte(`("A" + "B") + "C"`) errorHandler
ALBのTargetとしてLambdaが選択できるようになり、 若干の時間課金が発生する代わりに柔軟にルーティングできるAPI Gatewayのように使えるようになった。 ActionとしてCognito認証を入れて認証に失敗したらログイン画面を表示させる。 API GatewayでCognitoの認証をかけて必要ならログイン画面に飛ばす処理をGoで書く - sambaiz-net ACMで証明書を発行する HTTPSでListenするため証明書が必要。 AWS Certificate Manager (ACM)でAWSで使える証明書を無料で発行でき参照できる。 外部で取ったドメインでもよい。 検証方法はDNSとメールとで選ぶことができて、DNSで行う場合Route53ならワンクリックで検証用のCNAMEレコードを作成できる。 検証までやや時間がかかるのでちゃんと通ってるかnslookup
const vpc = new ec2.Vpc(this, 'VPC', { cidr: props.vpcCidr, natGateways: 1, maxAzs: 2, subnetConfiguration: [ { name: 'digdag-public', subnetType: ec2.SubnetType.PUBLIC, }, { name: 'digdag-private', subnetType: ec2.SubnetType.PRIVATE, }, { name: 'digdag-db', subnetType: ec2.SubnetType.ISOLATED, } ] }) const db = new rds.DatabaseCluster(this, 'DBCluster', { engine: rds.DatabaseClusterEngine.AURORA_
ElasticsearchをDockerで動かしてGrafanaで可視化する - sambaiz.net ESに送られるデータの量が増えてくるとGrafanaのDashboardにグラフが表示されなくなってしまった。 表示されたエラーはこういうの。 "root_cause": [ { "type": "circuit_breaking_exception", "reason": "[request] Data too large, data for [] would be larger than limit of [8998512230/8.3gb]", "bytes_wanted": 10464007168, "bytes_limit": 8998512230 } ], これは1リクエストの集計などで使うメモリ量がしきい値をこえて Circuit Breakerが発動したということ。 メ
localでのstreamsとproducerのbenchmark aws-fluent-plugin-kinesisの make benchmark はlocalにDummyServerを立ち上げて送っている。 空でもいいのでroleをつけておく必要がある。 $ git clone https://github.com/awslabs/aws-fluent-plugin-kinesis.git $ cd aws-fluent-plugin-kinesis $ yum install -y ruby-devel gcc $ echo 'gem "io-console"' >> Gemfile $ make $ make benchmark RATEを指定しなければデフォルトで秒間1000レコードが送られる設定。 fluentdを起動してから10秒後にプロセスをkillし、そのレコード数など
Logging AgentをNodeレベルのDaemonSetとして動かすのではなく、Podの中にSidecar Containerとして動かす。その分リソースは食うが、独立した設定で動かせる。 アプリケーション https://github.com/sambaiz/go-logging-sample Goで定期的にログを出すサンプルコードを書いたのでこれを使う。 viperで設定を持ち、 zapでログを出力する。 あとSIGINTを拾ってSync()してGraceful Shutdownするようにしている。 Golangの高速なロガーzapとlumberjackでログを出力してrotateさせる - sambaiz-net multistage-buildして、GKEで動かすのでContainer Registryに上げる。 $ docker build -t go-logging-sa
package main import ( "fmt" "net/http" "io/ioutil" ) var client = http.Client{} func main() { req, err := http.NewRequest("GET", "http://example.com", nil) if err != nil{ panic(err) } resp, err := client.Do(req) if err != nil{ panic(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil{ panic(err) } fmt.Println(string(body)) } Client TransportがTCPコネクションをキャッシュするのでClien
go-sql-driver/mysql で MySQL に接続するときに適切なパラメータを渡さないと日時が意図しない値になる問題について確認する。 $ cat docker-compose.yml services: db: image: mysql:8.0 container_name: testdb platform: linux/arm64 restart: always environment: MYSQL_ROOT_PASSWORD: test MYSQL_DATABASE: testdb TZ: Asia/Tokyo ports: - "3306:3306" $ docker-compose up -d $ docker exec -it testdb mysql -h127.0.0.1 -P3306 -uroot -ptest mysql> select version();
grpc-goはInterceptor(Middleware)でhandlerの前後で処理を行うことができる。 UnaryとStreamでシグネチャが異なる。 type UnaryServerInterceptor func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (resp interface{}, err error) type StreamServerInterceptor func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error func UnaryServerInterceptor(opts ...Option) grpc.Unar
IstioはEnvoyというProxyをSidecarとしてPodに入れてトラフィックを通すことでマイクロサービスのRoutingやTelemetryをサービスのコードに手を入れずに行うことができるサービスメッシュ。 もともとEnvoy自体は単体で、コネクションを張りっぱなしのgRPC(HTTP/2)をK8sのServiceのL4ロードバランサーでは分散できない問題の解決方法の一つとして 各PodのIPの一覧を返すHeadless Serviceと使われていたが、各Manifestに入れたりConfigMapを編集したりする必要があり少し面倒だった。 Istioにするとそれらが省けて、さらに賢いRoutingやモニタリングの仕組みまで付いてくるのでとても便利だ。 インストール IstioをダウンロードしてきてHelmでインストールする。Istioには様々なコンポーネントが含まれているが、パ
RSA暗号とは c ≡ m^e (mod n) で暗号化し、m ≡ c^d (mod n) で複合する暗号。 e と n が公開鍵で d が秘密鍵。n はとても大きく近くない素数 p,q の積で、 これを公開しても p * q に素因数分解できないのがこの暗号の前提になっている。 768bit(10進数で232桁)では既に解読されているので、少なくとも1024bit以上にする。 eはEuler totient function(1~nまでの整数でnと互いに素なものの個数 φ(n)=(p-1)(q-1))未満で互いに素な正の整数で、小さすぎても大きすぎても良くない。2^16 + 1 = 65537 がよく使われる。 d は ed ≡ 1 (mod φ(n)) を満たす値にする。 例 例として (p,q) = (193,709) とすると各変数は次のようになる。 n = p * q = 136
Pythonのasyncioはイベントループを回してシングルスレッドで並行に非同期処理を行う。 マルチスレッドで並列に実行するのがthreadingで、 マルチプロセスで並列に実行するのがmultiprocessing。 import asyncio async def sleep(s): await asyncio.sleep(s) print(s) return s loop = asyncio.get_event_loop() loop.run_until_complete(sleep(5)) coros = [sleep(3), sleep(2)] futures = asyncio.gather(*coros) loop.run_until_complete(futures) print(futures.result()) loop.close() get_event_loop(
OpenID Connectは認可 (AuthoriZation) のプロトコルであるOAuth 2.0を正しく認証 (AutheNtication) に使うためのプロトコル。 OpenID Connect Core 1.0(日本語訳) OAuth2.0のメモ - sambaiz-net OpenID Connect では OAuth のアクセストークンに加えて Issuer (IdP) によって署名されたJWT (JSON Web Token) 形式のIDトークンも返す。 このIDトークンの署名を検証し、含まれる Issuer とクライアントの情報を参照することで OAuth の Implicit flow でのトークン置き換え攻撃を防ぐことができる。 JWT/IDトークン JWT は RFC7519 で定義されている、パーティ間で安全に Claim (エンドユーザーのようなエンティティ
TensorflowのRNN(Recurrent Neural Networks)のチュートリアルのコードを読む。これは文章のそれまでの単語の履歴から、その次に続く単語を予測することで言語モデルを作るもの。 RNN/LSTMとは RNNは入力に対して出力のほかに情報を次のステップに渡すことで時系列データで学習できるようにするネットワーク。 展開すると同じネットワークに単語を一つずつ入れていくように表現できる。 これを単純にMLPで実装しようとすると逆誤差伝搬する際に過去の層にも伝搬させる(BPTT: Backpropagation through time)必要があり、 時間を遡るほど活性化関数の微分係数が再帰的に繰り返し掛けられるため勾配が消失や爆発しやすくなってしまう。 また、時系列データのうちに発火したいものと発火したくないものが混在している場合、同じ重みにつながっているため更新を打
Pythonの可視化というとmatplotlibや、 そのラッパーのseaborn、 データ解析ライブラリのPandasにもそのような機能があるが、 これらが静止画を描画するのに対して、 BokehはD3.jsによって拡大やスクロールができるグラフを描画する。Bokehはカメラのボケ。 似たようなものにPlotlyというのもあって、 こちらはPandasと同じpydata.orgドメインでスターが多い。
Apexでfunctionをデプロイするとトリガーが登録されないのであとで追加することになる。 これを手作業で行うこともできるのだが、せっかくなのでアプリケーションと一緒に管理したい。 そんなときのためにterraformコマンドをラップしたapex infraが用意されている。 TerraformでVPCを管理するmoduleを作る - sambaiz-net functionsと同列にinfrastructureディレクトリを作成してtfファイルを置く。 その下に環境ごとのディレクトリを作成することもできて、その場合は –env で指定した環境のものが使われる。 - functions - infrastructure main.tf variables.tf - modules - cloudwatch_schedule main.tf variables.tf project.js
82 a7 63 6f 6d 70 61 63 74 c3 ac e3 82 b9 e3 82 ad e3 83 bc e3 83 9e 82 a6 6e 75 6d 62 65 72 cd 03 e7 a6 73 74 72 69 6e 67 a3 61 61 61 一行目の82は要素数2のfixmap(要素数15まで)を表す。 二行目のa7が7バイトのfixstr(31bytesまで)で、 63 6f 6d 70 61 63 74が"compact"。c3はtrue。 三行目のacは12バイトのfixstrで、e3 82 b9 e3 82 ad e3 83 bc e3 83 9eが"スキーマ"。 四行目はこれのvalueで、要素数2のfixmap(82)。 五行目は6バイトのfixstr(a6)、“number”(6e 75 6d 62 65 72)、 cdがuint16で、999(0
Keep-AliveするとTCPコネクションを使い回し、名前解決やコネクション(3 way handshake)を毎回行わなくてよくなる。 Goのnet/httpではデフォルトでKeep-Aliveが 有効になっているが、 全体と同一ホストでそれぞれKeep-Aliveするコネクション数が制限される。 これらの値はClientのTransportが持っていて、 これがnullだとDefaultTransportが参照されるので、意識しなければこの値が使われる。 MaxIdleConns: DefaultTransportでは100になっている。0にすると無制限。 MaxIdleConnsPerHost: デフォルト値は2。0にするとデフォルト値が使われる。 同一のホストに同時にたくさんリクエストする場合、2だとほとんど意味を持たない。これを増やして比較してみた。 package main
fluentdのAggregatorをELBで負荷分散し、Blue/Green Deploymentする デプロイやスループットの調整を簡単にするため、BeanstalkでAggregatorを立ち上げた。 負荷分散 TCPの24224(設定による)が通るようにEC2,ELBのSGとリスナーの設定をする必要があって、 ELBのSGのアウトバウンドの設定が見落とされがち。ELBのクロスゾーン分散は有効になっている。 まず、ELBに3台、それぞれ別のAZ(1b, 1c, 1d)に配置されている状態でログを送り始めるとそれぞれ均等にログが届いた。 その状態から4台(1b * 2, 1c, 1d)にすると、2つのインスタンス(1b, 1c)のみに均等にログが届くようになった。 4台になると(1b, 1c)と(1b, 1d)に分けられてELBのノードがそれらの組に紐づいたということだと思う。 各ノー
Terraform $ brew install terraform $ terraform -v Terraform v0.9.11 Terraformの設定要素 provider IaaS(e.g. AWS)、PaaS(e.g. Heroku)、SaaS(e.g. CloudFlare)など。 AWS Providerはこんな感じ。 ここに直接access_keyやsecret_keyを書くこともできるが、誤って公開されてしまわないように環境変数か variableで渡す。
Chrome DevTools Protocolに ExperimentalだがPage.setDownloadBehavior というのがあったので、これを呼んでファイルをダウンロードしてみた。 今回は公式のDevToolsのNode API、Puppeteerを使うが、 setDownloadBehaviorを送るAPIはまだなく、直接clientを取ってsendするので他のライブラリでもやることは変わらないと思う。 Puppeteerのインストールの際にChromiumも入る。setDownloadBehaviorは現行Chromeの60では対応していないようだが、62が入ったのでなんとかなりそう。 $ yarn add puppeteer $ find . -name "*chrome*" ./node_modules/puppeteer/.local-chromium/mac-4
CREATE TABLE sample ( id SERIAL, name VARCHAR(30) ) ENGINE=InnoDB CHARACTER SET utf8mb4; INSERT INTO sample (name) VALUES ('tom'),('Tom'),('TOM'); mysql> SELECT * FROM sample2 WHERE name = 'tom'; +----+------+ | id | name | +----+------+ | 1 | tom | | 2 | Tom | | 3 | TOM | +----+------+ 3 rows in set (0.01 sec) MySQL :: MySQL 5.6 リファレンスマニュアル :: B.5.5.1 文字列検索での大文字/小文字の区別 単純な比較操作 (>=、>、=、<、<=、ソート、およ
NorikraはTD社のtagomoris氏が作った、 スキーマレスのストリーミングデータを処理するOSS。 モチベーションとしてはfluentdでElasticsearchにログを送って可視化していたのだが、 流量が増えてきてピーク帯に耐えられなくなってしまったため、前もって集計してから送ることで流量を減らそうというもの。 Norikraを立ち上げてクエリを実行する 公式で紹介されているDockerイメージがあったのでこれで動かしてみる。 $ docker run -e "TZ=Asia/Tokyo" -p 26578:26578 -p 26571:26571 -v `pwd`:/var/tmp/norikra:rw -d myfinder/docker-norikra norikra start --stats /var/tmp/norikra/stats.json -l /var/t
PuppeteerでHeadless Chromeを動かすコードを Lambda上で動かすStarter Kitを作った。 puppeteer-lambda-starter-kit Chromeの準備 Puppeteerのインストール時に落としてくるChromeをLambda上で動かそうとしても Lambdaにないshared libraryに依存しているため失敗する。 error while loading shared libraries: libpangocairo-1.0.so.0: cannot open shared object file: No such file or directory Lambda上でHeadless Chromeを動かす例がないか調べたらserverless-chromeというのがあって、 Headless用の設定でChromeをビルドしていた。 ほ
次のページ
このページを最初にブックマークしてみませんか?
『[sambaiz.net]』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く