kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Mac で「なめらかに」デモを見せるために必須なアプリと機能

技術講師としてプレゼンテーションをしながらデモをする場面が多く,無駄な操作をせず,Mac を「なめらかに」操作することを意識している.「なめらかな」操作をするために個人的に必須なアプリと機能があり,最近紹介する機会も増えているため,記事にまとめることにした.

ウィンドウ操作「Magnet」

Mac でウィンドウ操作を「なめらかに」するために「Magnet」を購入している.現時点だと250円で購入できる.ウィンドウの「移動」「リサイズ」なら関連するアプリとして有名な「Spectacle」も便利だけど,Magnet なら Windows でよく使う「スクリーンの端にウィンドウ当ててリサイズするジェスチャー」にも対応していて,適材適所に使える.正直 Magnet に慣れすぎてしまって離れられなくなっている.僕は以下のショートカットをよく使う.

  • 最大 : ^ ⌘ ↑
  • 左 : ^ ⌘ ←
  • ^ ⌘ →

Magnet

Magnet

  • CrowdCafé
  • Productivity
  • $1.99
apps.apple.com

magnet.crowdcafe.com

ズーム「2本指でピンチ」

Chrome を使ってウェブサイトを「なめらかに」ズームする場合,Mac のトラックパッドで「2本指でピンチ」を使う.ブラウザ側の機能(⌘ +)を使うと,ウェブサイトのスタイルが崩れることが多く,基本的に使わなくて良いと思う.

設定は「システム環境設定 → トラックパッド → スクロールとズーム」を開き「拡大/縮小」を有効化する.1日使っていると動かなくなることもあり,その場合は「設定 OFF → 数秒待機 → 設定 ON」で直る.

f:id:kakku22:20190828221052p:plain

ズーム「スクロールジェスチャ」

基本的に「2本指でピンチ」を使うけど,例えば Chrome の DevTools など「2本指でピンチ」に未対応の場所もあり,その場合は Mac の「スクロールジェスチャ」を使う.

設定は「システム環境設定 → アクセシビリティ → ズーム機能」を開き「スクロールジェスチャと修飾キーを使ってズーム」を有効化する.ショートカットはデフォルトのまま ^ Control にしているため ^ を押しながらトラックパッドを上下にスクロールするとズームできるようになる.紹介した2種類のズームを覚えておくと良いと思う.

f:id:kakku22:20190828221108p:plain

ドラッグ「3本指のドラッグ」

「3本指のドラッグ」は去年に記事を書いているけど,まだ未設定の人が多いように思う.記事にも書いているけど,例えば「文字をドラッグしてコピーするとき」「ウィンドウをスクリーン側に移動するとき」など,「3本指のドラッグ」を使うとスムーズに操作できるようになる.PowerPoint や Keynote でスライドを作るときにも使えて,正直「3本指のドラッグ」を使わないと作業の効率さが大きく変わってしまう.

設定は「システム環境設定 → アクセシビリティ → マウスとトラックパッド」を開き「トラックパッドオプション → ドラッグを有効にする → 3本指のドラッグ」を有効化する.本当にオススメ!

f:id:kakku22:20190828223446p:plain

kakakakakku.hatenablog.com

ランチャー「Alfred」

Mac でアプリを「なめらかに」開くために,Dock から選ぶのではなくランチャーから起動する.Spotlight もあるけど,個人的には「Alfred」に慣れてしまっていて,ずっと使っている.起動するときのショートカットは ⌥ Space にしている.

「Alfred」から iTerm2 や Visual Studio Code などのアプリを開くこともできるし,接頭辞に ' を付けるとファイル検索ができるし,Google で検索をするときにも Alfred を使う.ランチャーをうまく使いこなせるとデモに限らず日常的な操作が効率的になる.

www.alfredapp.com

まとめ

Mac を「なめらかに」操作しよう!練習あるのみ!

nginx でリクエストを制限できるモジュール「ngx_http_limit_req_module」

nginx でリクエストを制限できるモジュール「ngx_http_limit_req_module」を使うと,Throttling や DoS 対策など,リクエストの過剰な増加に nginx で対応できるようになる.挙動を確認するため,Docker Compose を使って検証環境を構築した.

nginx.org

検証環境

今回 Docker Compose を使って,nginx と Sinatra を起動する検証環境を構築した.コンテナは計4種類で,以下の構成図にまとめた.今回は default.conf の異なる3種類の nginx (Frontend1-3) の挙動を確認する.

  • Frontend1 (nginx) : limit_req
  • Frontend2 (nginx) : limit_req + burst
  • Frontend3 (nginx) : limit_req + burst + limit_req_status
  • Backend (Sinatra)

f:id:kakku22:20190825131113p:plain

リクエストを投げるために今回は Vegeta を使う.

github.com

特に設定はなく,すぐに docker-compose up で起動できるようにした.なお,Docker Compose の設定などは GitHub に公開した.

$ docker-compose up

$ curl http://localhost:8080
Hello, backend!

$ curl http://localhost:8081
Hello, backend!

$ curl http://localhost:8082
Hello, backend!

github.com

検証 1 : limit_req

まず,Frontend1 の設定(一部)を以下に載せる.ngx_http_limit_req_module の基本設定となる limit_req_zone$binary_remote_addr を指定し,IP アドレスごとに制限をしている.他にも $server_name を指定し,サーバごとに制限をすることもできる.そして今回は rate=1r/s を指定し,1秒間に1リクエストを許容する.

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    server {
        (中略)
        location / {
            limit_req zone=one;
            proxy_pass http://backend;
        }
    }
}

さっそく Vegeta でリクエストを投げてみる.今回は -rate=10-duration=5s を指定し「1秒間に10リクエストを5秒間」とする.結果レポートの中で注目するポイントは「200:5 503:45」で,1秒間に1リクエストを許容しているため,残った45リクエストは「503 Service Temporarily Unavailable」になっている.

$ echo 'GET http://localhost:8080' | vegeta attack -rate=10 -duration=5s > result.bin

$ vegeta report -type=text result.bin
Requests      [total, rate, throughput]  50, 10.21, 1.02
Duration      [total, attack, wait]      4.898020366s, 4.896749649s, 1.270717ms
Latencies     [mean, 50, 95, 99, max]    2.134954ms, 1.814726ms, 3.90771ms, 6.088868ms, 6.088868ms
Bytes In      [total, mean]              22305, 446.10
Bytes Out     [total, mean]              0, 0.00
Success       [ratio]                    10.00%
Status Codes  [code:count]               200:5  503:45
Error Set:
503 Service Temporarily Unavailable

nginx のアクセスログは以下のように出力されていた.

frontend1_1  | 2019/08/25 00:00:00 [error] 6#6: *3 limiting requests, excess: 0.100 by zone "one", client: 172.21.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost:8080"
frontend1_1  | 172.21.0.1 - - [25/Aug/2019:00:00:00 +0000] "GET / HTTP/1.1" 503 494 "-" "Go-http-client/1.1" "-"

検証 2 : limit_req + burst

次に,Frontend2 の設定(一部)を以下に載せる.Frontend1 との差は burst=10nodelay で,今回は burst を指定することにより,制限を超えたリクエストをキューに溜められるようになる.さらに nodelay を合わせて指定し,キューに溜まったリクエストを遅延処理しないようにできる.リクエストを制限しながら緩和できる設定となり,よく使うことになりそう.

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    server {
        (中略)
        location / {
            limit_req zone=one burst=10 nodelay;
            proxy_pass http://backend;
        }
    }
}

Frontend2 にも Vegeta でリクエストを投げてみる.結果レポートを確認すると「200:15 503:35」となり,burst に設定したリクエストも処理できた.残った35リクエストは「503 Service Temporarily Unavailable」になっている.

$ echo 'GET http://localhost:8081' | vegeta attack -rate=10 -duration=5s > result.bin

$ vegeta report -type=text result.bin
Requests      [total, rate, throughput]  50, 10.20, 3.06
Duration      [total, attack, wait]      4.901103127s, 4.899598364s, 1.504763ms
Latencies     [mean, 50, 95, 99, max]    3.344031ms, 1.78755ms, 13.669119ms, 17.032244ms, 17.032244ms
Bytes In      [total, mean]              17515, 350.30
Bytes Out     [total, mean]              0, 0.00
Success       [ratio]                    30.00%
Status Codes  [code:count]               200:15  503:35
Error Set:
503 Service Temporarily Unavailable

検証 3 : limit_req + burst + limit_req_status

最後は,Frontend3 の設定(一部)を以下に載せる.Frontend2 との差は limit_req_status で,特に API リクエストを制限する場合など,レスポンスコードとして「503 Service Temporarily Unavailable」ではなく「429 Too Many Requests」を返すべき場面もあると思う.今回は limit_req_status を指定することにより,レスポンスコードを指定している.

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    server {
        (中略)
        location / {
            limit_req zone=one burst=10 nodelay;
            limit_req_status 429;
            proxy_pass http://backend;
        }
    }
}

Frontend3 にも Vegeta でリクエストを投げてみる.結果レポートを確認すると「200:15 429:35」となり,残った35リクエストは「429 Too Many Requests」になっている.

$ echo 'GET http://localhost:8082' | vegeta attack -rate=10 -duration=5s > result.bin

$ vegeta report -type=text result.bin
Requests      [total, rate, throughput]  50, 10.20, 3.06
Duration      [total, attack, wait]      4.905475679s, 4.903894373s, 1.581306ms
Latencies     [mean, 50, 95, 99, max]    3.614673ms, 2.121613ms, 8.324474ms, 34.016092ms, 34.016092ms
Bytes In      [total, mean]              6140, 122.80
Bytes Out     [total, mean]              0, 0.00
Success       [ratio]                    30.00%
Status Codes  [code:count]               200:15  429:35
Error Set:
429 Too Many Requests

nginx のアクセスログは以下のように出力されていた.

frontend3_1  | 2019/08/25 00:00:00 [error] 6#6: *1 limiting requests, excess: 10.210 by zone "one", client: 172.21.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost:8082"
frontend3_1  | 172.21.0.1 - - [25/Aug/2019:00:00:00 +0000] "GET / HTTP/1.1" 429 169 "-" "Go-http-client/1.1" "-"

まとめ

nginx でリクエストを制限できるモジュール「ngx_http_limit_req_module」を試した.IP アドレスごとなど,設定した単位ごとにリクエストを制限でき,burst を設定すれば緩和もできる.モジュールに実装されたレベルの制限なら nginx で実現できそう.実際に ngx_http_limit_req_module.c など,実装を紐解くと,正確には r/s は1秒間に許容するリクエストではないらしく,本番環境などトラフィックのある環境に導入するときには様々なシナリオを考えて負荷テストをしておく必要がありそう.

関連記事

kakakakakku.hatenablog.com

iTerm2 を Python から制御できる新機能「Python Scripting API」

7月末にリリースされた「iTerm2 v3.3」に大きく2種類の新機能がある.今回は「Python Scripting API」を中心に紹介したいと思う.

  • Python Scripting API
  • Scriptable Status Bar

Python Scripting API

「Python Scripting API」を簡単に説明すると「Python で iTerm2 を制御できる API が公開された」と言える.正確には iterm2 という Python ライブラリが公開されているため,iTerm2 のウィンドウを制御したり,プロファイルを制御したり,新機能のステータスバーを制御できるようになる.

pypi.org

ドキュメントに API リファレンスもある.今までは AppleScript API を使う必要があったため,Python を使えるようになったのはコミュニティにとっても良いことだと思う.便利なスクリプトがどんどん公開されそう!

iterm2.com

Python API Tutorial

「Python Scripting API」を試すため,今回はドキュメントにある「Python API Tutorial」を進めていく.

  • 1 : Python API Introduction
  • 2 : Example Script
  • 3 : Running a Script
  • 4 : Daemons
  • 5 : RPCs
  • 6 : Hooks
  • 7 : Troubleshooting

iterm2.com

1 : Python API Introduction

「Python Scripting API」で使えるスクリプトは大きく「2種類」ある.

  • Simple
    • 例えば「ウィンドウを作成する」など,必要なときに実行するスクリプト
  • Long-running daemons
    • 例えば「定期的にアクションを実行し続ける」など,iTerm2 の中に常駐するデーモン形式のスクリプト

最初は「Simple」スクリプトを作成するため,iTerm2 のメニューから「Scripts → Manage → New Python Script」と選択すると,ウィザードが表示される.「Basic → Simple」を選ぶ.ファイル名は tutorial にしておく.

f:id:kakku22:20190811235835p:plain

f:id:kakku22:20190811235848p:plain

初回実行だと「Download Python Runtime?」とダイアログが出るため,ダウンロードをしておく.

f:id:kakku22:20190811235906p:plain

2 : Example Script

スクリプトを作成したため,自動生成された tutorial.py をエディタで表示できるようになる.スクリプト自体は ~/Library/Application\ Support/iTerm2/Scripts ディレクトリにあり,自動生成されたスクリプトを解説する内容になっている.ポイントを整理しておく.

  • Python API を使うために iterm2import する
  • コードは main 関数の中に書く
  • Python API は asyncio を使っているため async / await など非同期処理を前提とする
    • run_until_complete() / run_forever() なども重要になる
  • await window.async_create_tab() で新規タブを作成している
#!/usr/bin/env python3.7

import iterm2
# This script was created with the "basic" environment which does not support adding dependencies
# with pip.

async def main(connection):
    # Your code goes here. Here's a bit of example code that adds a tab to the current window:
    app = await iterm2.async_get_app(connection)
    window = app.current_terminal_window
    if window is not None:
        await window.async_create_tab()
    else:
        # You can view this message in the script console.
        print("No current window")

iterm2.run_until_complete(main)

3 : Running a Script

実装したスクリプトを実行する方法として,5種類紹介されている.

  • From the Scripts menu.(スクリプトメニューから実行する)
  • At the command line.(コマンドラインから実行する)
  • Auto-run scripts launched when iTerm2 starts.(iTerm2 の起動時に自動実行する)
  • With an interactive interpreter called a REPL.(REPL から実行する)
  • From the Open Quickly window.(Xcode の Open Quickly から実行する)

「スクリプトメニュー」から実行する場合,iTerm2 のメニューから「Scripts → tutorial.py」と簡単に実行できる.

f:id:kakku22:20190812002624p:plain

「REPL」でインタラクティブにコードを実行する場合,iTerm2 のメニューから「Scripts → Manage → Open Python REPL」を選択する.

f:id:kakku22:20190812003041p:plain

REPL を起動したら app オブジェクトを取得するために最初は以下のスニペットを入力する.ドキュメントにもコピーすると書いてあった.

import iterm2
connection=await iterm2.Connection.async_create()
app=await iterm2.async_get_app(connection)

4 : Daemons

iTerm2 の起動時に「デーモン」として自動実行する場合,~/Library/Application\ Support/iTerm2/Scripts/AutoLaunch ディレクトリにスクリプトを保存しておく必要がある.もう1度ウィザードを表示し,今度は「Basic → Long-Running Daemon」を選ぶ.ファイル名は daemon にしておく.自動生成されるコードではなく,ドキュメントに載っているコードに置き換える.

#!/usr/bin/env python3
import iterm2

async def main(connection):
    async with iterm2.CustomControlSequenceMonitor(
            connection, "shared-secret", r'^create-window$') as mon:
        while True:
            match = await mon.async_get()
            await iterm2.Window.async_create(connection)

iterm2.run_forever(main)

作成した AutoLaunch/daemon.py のポイントは最後にある run_forever() で,デーモンとして常駐させている.

iterm2.run_forever(main)

今回のコードは iTerm2 のエスケープシーケンスを受け付けるため,以下のコマンドを入力すると,コマンドラインから iTerm2 のウィンドウを作成できる.

$ printf "\033]1337;Custom=id=%s:%s\a" "shared-secret" "create-window"

5 : RPCs

デーモンを RPC として定義しておくと,例えば iTerm2 のショートカットキーからスクリプトを実行することもできる.ドキュメントに載っている以下のスクリプトを clear.py として登録しておく.以下のスクリプトを実行すると「全てのセッションのヒストリをクリア」できる.

#!/usr/bin/env python3

import iterm2

async def main(connection):
    app = await iterm2.async_get_app(connection)

    @iterm2.RPC
    async def clear_all_sessions():
        code = b'\x1b' + b']1337;ClearScrollback' + b'\x07'
        for window in app.terminal_windows:
            for tab in window.tabs:
                for session in tab.sessions:
                    await session.async_inject(code)
    await clear_all_sessions.async_register(connection)

iterm2.run_forever(main)

そして clear_all_sessions() をショートカットキーに登録する.単純に clear を実行するのと大きな差はないけど,実装したスクリプトをショートカットキーに設定できるのは便利だと思う.ショートカットキー以外に「トリガー」にも対応しているため,Linux の alias のように設定できる.ドキュメントにある例は boss is coming という文字列に clear_all_sessions() をバインドしてて笑った!

f:id:kakku22:20190813193837p:plain

6 : Hooks

Python API の Hooks は iTerm2 の動作を変更できる機能で,現在は以下の「2種類」がサポートされている.

  • Session title provider(セッションタイトルの文字列を変更する Hooks)
  • Status bar provider(ステータスバーに表示する文字列を制御する Hooks)

ドキュメントに載っている以下のコードを AutoLaunch/upper_case.py として保存しておく.

#!/usr/bin/env python3.7

import iterm2

async def main(connection):
    @iterm2.TitleProviderRPC
    async def upper_case_title(auto_name=iterm2.Reference("autoName?")):
        if not auto_name:
            return ""
        return auto_name.upper()

    await upper_case_title.async_register(
        connection,
        display_name="Upper-case Title",
        unique_identifier="com.iterm2.example.upper-case-title")

iterm2.run_forever(main)

そして「Preferences → Profiles → General → Basics → Title」「Upper-case Title」を設定する

f:id:kakku22:20190813195028p:plain

すると,iTerm2 のタブ文字列が大文字になっている.Hooks の Session title provider を使うと,こういう拡張ができる.なお,ターミナルの上部に載せている「CPU 使用率 / Memory 使用率 / Network 使用率」「iTerm2 v3.3」のもう1個の新機能「Scriptable Status Bar」で,別の機会に紹介できればと思う.

f:id:kakku22:20190813195234p:plain

7 : Troubleshooting

iTerm2 のメニューから「Scripts → Manage → Console」と選択し,Script Console を開くと,Python API のログを確認できる.さらに Scripting Inspector を使うと変数など詳細まで確認できる.今度スクリプトを自作するときに活用する.

まとめ

  • 7月末にリリースされた「iTerm2 v3.3」に大きく2種類の新機能がある
    • Python Scripting API
    • Scriptable Status Bar
  • 今回はドキュメントにある 「Python API Tutorial」を進めた
  • Python API を使うと Python で iTerm2 を制御(ウィンドウ作成 / タブ作成など)できる

技術ブロガー必読!と言える「Technical Blogging, Second Edition」を読んだ

技術ブロガー必読!と言える「Technical Blogging, Second Edition - Amplify Your Influence」を読んだ.タイトルにある通り「技術ブログ」にフォーカスした本となる.本書は2012年に出版された歴史のある本で,最新版となる Second Edition が6月末に出版された.なお,Second Edition は今年1月から β として公開されていて,β 1.0 → β 5.0 と進化しながら出版されている.

技術ブロガーとして,今まで10年以上育ててきた暗黙知をうまく整理する機会になった.本書の内容は非常に共感できるし,僕自身新しく気付けたこともあった.何よりも「技術ブログ」に対する様々なアプローチを完璧に言語化されている点が素晴らしく,正直言って「本書って僕が書いたの?」と頭が混乱するほどにシンクロを感じる場面もあった.シンクロ具合を表現するために,過去の登壇資料を並べながらまとめる.

pragprog.com

目次

本書は「技術ブログ」にフォーカスしながら「全5パート」から構成されている.Plan It / Build It / Promote It / Benefit from It / Scale It となり,目次で既に興味を惹かれてしまう!

  • Plan It
    • 1: What Kind of Blog Are You Going to Run?
    • 2: Rock-Solid Planning for Your Blog
  • Build It
    • 3: Setting Up Your Blog
    • 4: Customizing and Fine-Tuning Your Blog
    • 5: Creating Remarkable Content
    • 6: Producing Content Regularly
    • 7: Finding Time to Blog
  • Promote It
    • 8: Promoting Your Blog
    • 9: Understanding Traffic Statistics
    • 10: Building a Community Around Your Blog
  • Benefit from It
    • 11: Advancing Your Career with Blogging
    • 12: Promoting Your Own Business
  • Scale It
    • 13: Scaling Your Blogging Activities
    • 14: Beyond Blogging: Strategizing for Social Media
    • 15: Final Words of Advice

本書は6月に「DevLOVE X」に登壇したときにも資料に載せている.正式に出版されてから書評記事を公開しようと考えていた.

f:id:kakku22:20190807201005p:plain

Plan It 🌟

「Plan It」パートでは,ブログを始める前に準備しておくべき内容がまとまっている.

General vs. Niche

ブログで取り扱うテーマを決めるときに「General(一般)」「Niche(ニッチ)」だったらどちらにするべきだろう?という内容だった.本書では,多くの技術的な内容を表現するなら「General(一般)」だけど,特定の技術に限定した「Niche(ニッチ)」を選べば,テーマが明確になり,ブログを人気にできる可能性が高いと書いてある.僕の kakakakakku blog もそうだけど,個人的には「General(一般)」を選ぶと良いと思う.理由としては,ブログを「自分の学習履歴を残す場 = 外部記憶装置」として使うと効果的だと考えているから.

Identify Your Niche

ブログで取り扱うテーマを決めたら,次に「記事タイトルを10個洗い出す」というステップが紹介されていた.さらに事前に洗い出しておくと「ネタ切れを心配する必要がなくなる」とも書いてある.それな!

まさにブログメンタリングの1日目でメンティと一緒に取り組んでいる内容で,僕の場合は最初に「20個」出してもらって,そこから「30-50個」まで増やしている.ネタの粒度が大きすぎることを指摘できる機会にもなる.

f:id:kakku22:20190807211527p:plain

さらに本書では Google Keyword PlannerGoogle Trends を使って「Niche(ニッチ)」かどうかを調査するテクニックが紹介されていた.Google Trends は比較的よく使うけど,Google Keyword Planner は今まで使ったことがなく,Ad を配信するときに使うツールだけど,確かに検索ボリュームを把握するために使えそうだと思う.本書だと「少なくとも 1ヶ月 10000 以上のキーボリューム」を持っているキーワードをブログのメインテーマにすると良いという指標が載っていた.

f:id:kakku22:20190807212138p:plain

ads.google.com

Build It 🌟

「Build It」パートでは,ブログを構築したり,ブログを書く時間を捻出する内容がまとまっている.

Your Three Main Software Options

ブログを構築する選択肢として,以下の3種類が紹介されている.本書だと WordPress の内容も多くあるけど,個人的にはブログサービスを使って記事を書くことに集中するのが良いと思う.デメリットとして,カスタマイズの自由度が低かったり,サービスにロックインしてしまうと書かれているけど,このあたりはサービスの機能にもよると思う.

  • ホスティング(WordPress など)
  • 静的サイトジェネレーター(Jekyll / Hugo など)
  • ブログサービス

Customize Your Sidebar

ブログにとって「サイドバー」は非常に重要なコンポーネントであるという内容で,サイドバーをカスタマイズするべきと書かれていた.具体的にはサイドバーに検索ボックスを置いたり,カテゴリ一覧を置いたり,人気記事一覧を置いたりする.さらにヒートマップサービスを活用するとサイドバーの分析もできると書かれていた.それな!(2回目)

ブログメンタリングでも「サイドバーの見直し」はメンティによく伝えていて,特に「ファーストビュー」を意識することが重要だと思う.ブログに流入したときに他の記事まで回遊して欲しいし,他にどういう技術系の記事があるのかを知ってもらうこともできる.

Finding Time to Blog

次にブログを書く時間を捻出しよう!というテーマで,具体的には TODO リストを活用したり,仕事など優先順位を明確にしたり,できる限り割り込みを減らしたり,一般的な時間管理術として知られている内容だった.特にカレンダーに「Blogging(ブログ書く)」という予定を入れておくというテクニックは素晴らしく,習慣化に悩んでいる人は取り入れてみると良さそう.さらにポモドーロを使って集中するという内容もあった.ポモドーロが大好きな僕としては「ブログ x ポモドーロ」という話題が出てくることに興奮した!

kakakakakku.hatenablog.com

Promote It 🌟

「Promote It」パートでは,ブログを宣伝することにフォーカスした内容になっている.ウェブマーケティング手法とも言える.本書には多くのブロガーは宣伝をしていないと書いてあるし,ブログを成功させるためには宣伝が必要であるとも書かれている.

Promote Your Articles on Social Networks

Twitter / Facebook など,ソーシャルメディアに積極的にシェアする.サムネイル画像も重要であると書かれていた.また Reddit / Hacker News / DEV Community などに投稿するという海外ならではのアプローチも書かれていた.重要なのは「どんなに素晴らしい記事でも読まれないと埋もれてしまう」ということで,ブログメンタリングでも積極的にシェアしていく大切さを伝えるようにしている.

Understanding Traffic Statistics

ブログのトラフィックを理解するために Google Analytics を導入し,活用するという内容になっている.特に見るべき指標として以下が挙がっていた.例えば「新規ユーザー」が多いと,幅広くリーチしていると言える反面,リピートしてもらえていないという側面もあり,トラフィックを分析するメリットがある.正直言って,僕は以下の全ての指標を Google Analytics でモニタリングしているし,特に「ページ/セッション」を気にしているけど,具体的なアクションプランまで落とし込めていないなと気付けた.ホッテントリに入ると全ての指標が異常値になるし,Google の検索アルゴリズムの変更にも影響を受けるので,例外はありつつも,もう少し分析をしたいと思う.

  • Visit Quantity
    • ページビュー数
    • セッション
  • Visit Quality
    • ユーザー
    • 新規ユーザー
    • 直帰率
    • 平均セッション時間

Keep Track of Your Blog’s Growth

ブログに関連する KPI を Excel / Google Spread Sheet などにまとめるという内容も書いてあった.メンタリングでも毎週 KPI を取得してもらっている.それな!(3回目)

f:id:kakku22:20190807230515p:plain

Benefit from It 🌟

「Benefit from It」パートでは,ブログを書くことで「様々な恩恵を受けられる」という内容がまとまっている.メインは「キャリア的な恩恵」となり,興味のある人のために「マネタイズ」の話も入っている.

Improve Your Skills

まず,ブログを習慣化して書くことにより,ライティングスキルが向上する.また「議論をうまく引き起こすことができるようになる」「情報を広く伝えるインフルエンサーになれる」といった内容もあり,言語化が上手だなと感じた.さらにブログ記事を書くことは「人に教える」ことにも繋がるため,技術的な理解が深まるという恩恵も受けられる.個人的には「ブログを書くモチベーション(フェーズ)」と表現していて,非常に似ていると思う.

f:id:kakku22:20190807221746p:plain

Advance Your Career

キャリア的な観点だと,新しい仕事を見つけられるようになると書いてあった.特に履歴書にブログの URL を載せることで,技術的な興味を伝えられたり,スキルの証明にもなるため「ブログ自体が履歴書になる」という話は共感できる.それな!(4回目)

f:id:kakku22:20190807222431p:plain

Deal with Opportunities

ブログを書き続けていると,多くの人から様々な機会を得られるという話があり,例えば,技術的なアドバイスをしてもらう技術顧問的な機会を得られたり,カンファレンスに登壇する機会を得られたりする.すごく共感できるし,実際に僕自身もカンファレンスに登壇する機会を頂けたことが多くある.また技術書が出版されたときに献本を頂ける機会も最近は増えていて,これも「恩恵を受けている」と言えると思う.

Scale It 🌟

最後の「Scale It」パートでは,ブログの可能性を限界まで伸ばすという内容で,垂直スケールも水平スケールもできると書いてあった.最初に書いてあったのは「ブログをオンラインマガジンに変える」「ブログをニュースサイトに変える」という内容だったり,テクニカルライターを採用するという内容だったり,個人的な興味範囲とは違っていたので,あまり深くまでは読まなかった.

How to Get Your Initial Followers

後半はソーシャルメディアを活用して,どのようにフォロワーを増やすか?という内容で,一部は「Promote It」と似ている.例えば,Twitter などに毎日 10-20 回は投稿するという内容もある.ブログメンタリングでもメンティに「最低1日1ツイートしましょう!」というアドバイスをしている場合もあり,共感できる内容になっていた.

f:id:kakku22:20190807223807p:plain

まとめ

技術ブロガー必読!と言える「Technical Blogging, Second Edition - Amplify Your Influence」を読んだ.「技術ブログ」にフォーカスした本とは言え,300 ページもあり,比較的読むのは大変だった.ブログメンタリングで伝えている内容が網羅的にまとまっているため,今までブログメンタリングで伝えてきたことは正しかったんだな!と暗黙知をうまく整理する機会になって良かった.是非興味があれば読んで欲しいし,技術ブロガー同士で輪読会をしたら絶対に楽しいと思う!

また僕自身,本書の存在に気付いてなく,「分散システムデザインパターン」の出版レビューでお世話になった @dblmkt さんに会ったときに「ブログメンタリングに関連しているから読んでみたら?」と紹介してもらって,β の途中から読み進めていたという経緯がある.本書に出会えて本当に良かった.ありがとうございました!

合わせて読んでもらえると!

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

ドットインストールで「Lua 入門」を受講した

先月に「ngx_http_mirror_module」の検証記事を書いた通り,最近 nginx を調べ直している.次に「lua-nginx-module」を検証する予定だけど,今まで Lua 自体をあまり書いたことがなく,まずは Lua の基礎を学ぶことにした.まさに Yak Shaving!

kakakakakku.hatenablog.com

Lua 環境

今回 Mac を使うため,brew で Lua をインストールする.

$ brew install lua

$ which lua
/usr/local/bin/lua

$ brew info lua | grep stable
lua: stable 5.3.5 (bottled)

$ lua -e 'print(_VERSION)'
Lua 5.3

Lua の Version History を見ると,2015年にリリースされた Lua 5.3 が現在も最新となり,Patch まで含めると,2018年に Lua 5.3.5 がリリースされている.

www.lua.org

エディタは VS Code + Lua Extension にした.

marketplace.visualstudio.com

ドットインストール : Lua 入門 (全17回)

「Lua Reference Manual」などを参考に闇雲に学ぶより,個人的には Step by Step に学びたく,教材を探していたら,なんと「ドットインストール」「Lua 入門」があった!公開日を見るとまさかの「2013年」で,流石に古いかなと思ったけど,Lua のリリースもあまり進んでないこともあり,実際に受講してみることにした.結果的に何も問題なく,Lua 5.3 でも学ぶことができた.

  • 01 : Luaとはなにか?
  • 02 : はじめてのLuaプログラミング
  • 03 : 変数とデータ型について
  • 04 : 数値データを扱ってみよう
  • 05 : 文字列データを扱ってみよう
  • 06 : テーブルデータを扱ってみよう
  • 07 : if文で条件分岐をしてみよう
  • 08 : 条件式をマスターしよう
  • 09 : ループ処理をしてみよう (1)
  • 10 : ループ処理をしてみよう (2)
  • 11 : 関数をつくってみよう (1)
  • 12 : 関数をつくってみよう (2)
  • 13 : 数値の便利な命令を使ってみよう
  • 14 : 文字列の便利な命令を使ってみよう (1)
  • 15 : 文字列の便利な命令を使ってみよう (2)
  • 16 : テーブルの便利な命令を使ってみよう
  • 17 : 日付/時刻の便利な命令を使ってみよう

レッスンごとに写経した Lua コードは GitHub に push してある.今回の記事では全てをまとめるのではなく,個人的に Lua の特徴として印象に残った部分に限定してまとめておこうと思う.

github.com

03 : 変数とデータ型について

Lua で変数を使う場合,以下のように多重代入 (multiple assignments) も実装できる.

x, y = 10, 15
-- 10
print(x)
-- 15
print(y)

06 : テーブルデータを扱ってみよう

Lua の特徴的な機能に「テーブル」がある.配列 / 連想配列 / 構造体に似ていると表現することもできるけど,異なる型を並べることができたり,関数自体を設定することもできたり,幅広く使える.以下の例はシンプルだけど,実行結果は 234 となる.テーブルに対する添字が「"1" 開始」という点は覚えておく必要がありそう.

a = {23, 234, "hello"}
-- 234
print(a[2])

テーブルにキー名を指定したデータを登録する場合,user["name"] のように実装することもできるし,よりシンプルに user.name と実装することもできる.

user = {name = "kakakakakku", score = 120}
-- kakakakakku
print(user["name"])
-- kakakakakku
print(user.name)

10 : ループ処理をしてみよう (2)

テーブルをループする場合,イテレータと呼ばれる ipairspairs を使う.

a = {12, 24, "hey"}
b = {name = "kakakakakku", score = 120}

-- 1   12
-- 2   24
-- 3   hey
for i, value in ipairs(a) do
    print(i, value)
end

-- score   120
-- name    kakakakakku
for i, value in pairs(b) do
    print(i, value)
end

12 : 関数をつくってみよう (2)

Lua の関数には可変長引数 ... を使える.覚えておこう.

function sum(...)
    local a = {...}
    local total = 0
    for i = 1, #a do
        total = total + a[i]
    end
    return total
end

-- 9
-- 26
print(sum(2, 7))
print(sum(2, 7, 8, 9))

まとめ

  • ドットインストールで「Lua 入門」を受講した
    • 2013年に公開されたレッスンだけど,現在でも色褪せず,基礎の基礎を学ぶことができた
  • 今後は Lua Reference Manual を参考により実践的な実装を学んでいく予定

www.lua.org

ドットインストール関連

最近だと textlint のレッスンも受講した.Step by Step に第一歩を踏み出すときにドットインストールは本当に便利!

kakakakakku.hatenablog.com