koni blog

東京のウェブエンジニア koni です!ウェブサービスをガシガシ作っていきます!

これからは Docker Toolbox よりも Docker for Mac を使おう

2016年8月に正式リリースされた Docker for Mac/Windows。

勉強もかねて、Docker for Mac とそれまでの Docker Toolbox との違いをまとめました。

まとめ

Docker「これからはコンテナより下の部分についてはDocker for Mac/windows を使ってね!そのほうが高速だし、楽ちんだよ」

(ということだと思う)

Docker for Mac

  • Mac のネイティブアプリケーションであり、 /Applicationsにインストールされる
  • インストール時に /usr/local/bindockerdocker-composeにシンボリックリンクが貼られる。実体はネイティブアプリケーション内にある(/Applications/Docker.app/Contents/Resources/bin)
  • Docker for Mac は Docker社が公開したオープンソースの軽量な仮想化ツール「Hyperkit」で動く(VirtualBoxは使わない!)
    • Hyperkitは、macOS 10.10 Yosemite から実装されている仮想化フレームワーク「Hypervisor Framework」を利用しているので、macOS 10.10 以上でしか使えない 「Hyperkit」である VirtualBoxを使わず、
  • Docker for Macをインストールしても、Docker Machine で作成されたマシンには影響を与えない。
  • Docker for Mac アプリケーションは、 docker-machine は使わず、直接VMを作成し、管理する
  • Docker for Mac のインストール時に Docker Engine が動いている Alphine Linux ベースの Hyperkit VM がプロビジョンされ、ソケット /var/run/docker.sock と通信できるようになる。それ以降、docker コマンドや docker-compose コマンドで環境の指定をしない限り、デフォルトで呼ばれることになる。
  • Docker for Mac をインストールすると、唯一の VM を手に入れたことになり、管理する必要はなくなる。Docker for Mac アプリケーションが Docker のサーバー、クライアントバージョンを自動でアップデートする。

Docker Toolbox

  • Docker Toolbox をインストールすると、 docker, docker-compose, docker-machine/usr/local/bin にインストールされ、VirtualBoxもインストールされる。
  • docker-machine コマンドを使って、VirtualBox VM である default ホストをプロビジョニングしていた
    • この VM では、boot2docker という Linux Distribution で Docker Engine が動く。

参考

Google App Engine の場所(リージョン)選択のタイミングが変わった

これまで Google App Engine (GAE) のリージョン選択のタイミングは、プロジェクト作成時だったのだが、今試したらAppEngineを使い始めるタイミングに変更されていた。

あれ、と思いながらもプロジェクト作って、appcfg update .したら以下のようなエラーが。 これまではGCPのプロジェクト作るだけでよかったのが、App Engine の初期化が必要になった。

Error 404: --- begin server output ---
This application does not exist (project_id=u'cheetah-help'). To create an App Engine application in this project, run "gcloud beta app create" in your console.

一度間違えると変えられないので、不安だったので初期化はGUIからやった方がなんとなく安心ということでGUIでやりました。

こんな感じでとてもわかりやすくなりました。

f:id:konisimple:20170111002130p:plain

ヘルプも古い記述のままだったので注意!

サーバーの場所の設定

プロジェクトを作成するときに、サービスの提供元になる場所を指定できます。新しいプロジェクトのダイアログで、[詳細設定を表示] リンクをクリックして、プルダウン メニューから場所を選択してください。

Managing Cloud Platform Projects, App Engine Applications, and Billing  |  App Engine standard environment for PHP  |  Google Cloud Platform

Google App Engine プロジェクトのリージョンを東京リージョンに移す(移せない)

こんにちは。

以前から予告されていた、Google Cloud Platform (GCP) の東京リージョン開設がついに発表されました!

Google Cloud Platform Japan 公式ブログ: 東京 GCP リージョン の正式運用を開始しました

東京リージョン開設前は東京から最寄りのリージョンは台湾でしたが、台湾リージョンでは Google App Engine (GAE) は使えません。このため、これまではアメリカ西海岸(us-east1) を使っていることが多かったのではないでしょうか。 このせいで、RTTだけで200ms程度がどうしてもかかってしまっていました。

これが東京になると、数十ms台で通信できるようになります。

これはもう既存のプロジェクトをアメリカ西海岸から東京に移すしかない! ということで、既存の App Engine のリージョンを移す方法を調べてみました。

GAE のリージョンは変えられない

しかし、ドキュメントによると、どうやら一度決めた App Engine のリージョンは変更できないようです。

プロジェクトの作成後に場所を変更することはできません。

Managing Cloud Platform Projects, App Engine Applications, and Billing  |  App Engine standard environment for PHP  |  Google Cloud Platform

今回はほぼ静的なサイトのホスティングのみで、StackDriver なども使っていなかったので、プロジェクトごと作り、DNS の設定変更をすることにします。

※2017/1/11追記 プロジェクト作成時ではなく、AppEngineを使用開始するときに設定するように変わりました。 Google App Engine の場所(リージョン)選択のタイミングが変わった - koni blog

  1. 普通にプロジェクトを作成します。 f:id:konisimple:20161109201054p:plain

ここではロケーションを選ばなくなりました。上記は古い画面です。

いままではなかった、asia-northeast1が選べるようになっています。 これが東京リージョンです! ここで間違って選択すると、後からは変えられません!ご注意。

  1. AppEngineの画面を開き、「はじめてのアプリへようこそ」の下の言語名をクリック f:id:konisimple:20170111015624p:plain

  2. 「ロケーションを選択」で東京である「asia-northeast1」を選択 f:id:konisimple:20170111015653p:plain

  3. デプロイします。

  4. ドメインの設定を変更します。 DNS レコードの TTL を短くしておく、GAE 側の変更する、レコードの向き先を変える、といういつもの手順ですね。

無事に200msとかだったのが、10ms台が出るようになりました! (このサイトは実際にはほぼキャッシュしてもらっているので、あんまり関係ないけどね!w)

台湾リージョンでも GAEが使えるようになれば、マルチリージョンでスケールするようになって冗長性が高まるのですが、今でもリージョン単位でスケールする(複数のゾーンにまたがってスケールする)ので、十分そうですね。

参考

リージョン・ゾーンの一覧があります。 Global Locations - Regions & Zones  |  Google Cloud Platform

超簡単に PHP で Twitter Streaming API を叩く

Twitterでつぶやかれたリンクをすべて取得できないかなと考えていた。 そこでまずリンクが分量的にどのくらいのスピードで流れているか確認したい。

「http」とかの検索ワードで検索APIを一定時間おきに叩くというのが簡単にできそうだけど、分量が多すぎて抜け漏れがありそうだし、なんかスマートじゃない。

Twitter Streaming APIを使ってみる

Twitterのデータをリアルタイムに取得できる、Twitter Streaming APIというものがある。以前から使ってみたかったのだが、なかなか使う機会がなかったので、今回はそちらを使ってみることにする。

Streaming APIには、全ツイートの一部を返す、statuses/sampleと、statuses/filterがある。後者ならフィルタされていないんじゃなかろうか。

POST statuses/filter | Twitter Developers

ちなみにどのくらいのスピードで流れているか確認したいだけなので、Twitter 公式のテストツールでやってみようと思ったが、そもそもストリーミングには対応していなかった。Streaming APIは、ずーっと延々とデータが送られてくるというものなので、単純なAPI用のコンソールでは対応していないんだろう。WebSocketとかじゃなくて、Commet。

そこで、phirehose というライブラリを使って確認したのだが、あまりにも簡単だったのでメモしておく。

phirehose

fennb/phirehoseというライブラリを使う。 他ライブラリに依存せず、ストリーミングAPIのインターフェースのみを提供、というのが良い。 OAuthを使うライブラリだと、PEARのライブラリとかに依存していると面倒だけど、これは入れるだけでいいので非常に楽。 5分くらいでできる。

ファイルの取得

git clone git@github.com:fennb/phirehose.git

OAuth の登録

https://apps.twitter.com/ から、アプリを登録して、「Keys and Access Tokens」から自分のアクセストークンを取得。

ファイルの修正

いくつかサンプルが入っているので、これを直接編集して使う。 今回は example/filter-otuah.phpを使うので、これを開いて、TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, OAUTH_TOKEN, OAUTH_SECRETをさっきのサイトで取得した値を入れる

標準出力に出してもいいけど、せっかくなのであとから分析したいので、

      print $data['user']['screen_name'] . ': ' . urldecode($data['text']) . "\n";

している箇所を、

      file_put_contents('sample.txt', $data['created_at'] .' '.$data['user']['screen_name'] . ': ' . str_replace("\n", '', urldecode($data['text'])) . "\n", FILE_APPEND);

とかに変えておく。

実行

$ cd /path/to/project/example
$ php filter-oauth.php

...

Phirehose: Consume rate: 69 status/sec (4146 total), avg enqueueStatus(): 0.64ms, avg checkFilterPredicates(): 0ms (0 total) over 60 seconds, max stream idle period: 1 seconds.

ファイルに保存されるので、tail -fしながら眺める 処理中は1分おきにステータスが標準出力に出てくる。

結果

2016年10月4日9:30頃から30分ほど行った際に取得できたデータは以下。

/statuses/filter track=http 27分26秒で78218件 → 44.3件/s

/statuses/sample 26分33秒で78218件で62810件 → 39.4件/s

全世界のツイートは約5億/日らしい*1ので、約5800/sが発生していることになる。 ということは、sampleでとれたツイートは全体の約0.6%

リンク付きのツイート、全体の3割とすると、filterでとれたツイートは全体の2.5%((44.3/(5800*.3)))

参考

Streaming APIで日本全国のツイートを収集する - メヘンニミン

PHP で Google Cloud Datastore のデータを読み書きする

PHP で GCP の Cloud Datastore のデータを読み書きしてみました。 あまり情報がないので、とっかかりとしてメモしておきます。

Google App Engine から行いましたが、他の環境からでも動くはずです。

google/google-api-php-clientをありがたく使わせてもらいます。

このライブラリは、Google Cloudではなく、Google APIのライブラリなので、Google Cloudのライブラリ一覧のページには載っていません*1。 が、Google Cloud Client library for PHP はないようなので、こちらを使います。

ライブラリの導入

githubのreadme通りに導入します。

$ composer require google/apiclient:^2.0

ソースコードにautoload.phpをrequireします。

プロジェクトの作成と証明書の取得

Google Developer Consoleから、プロジェクトを作成し(ない場合)、サービスアカウントを作成します。

証明書を取得します。

  1. コンソールを開く
  2. API Manager
  3. 認証情報
  4. 「サービスアカウントキー」を作成
  5. 「App Engine default service account」を選択(新規作成しても可)
  6. jsonファイルがダウンロードできる

ソースコードの設置

hogehoge.json さきほどの証明書

app.yaml

application: practice161003
version: 1
module: default
runtime: php55
api_version: 1

threadsafe: true

handlers:
- url: /
  script: index.php

index.php

<?php

require('vendor/autoload.php');

# 証明書のパス
putenv('GOOGLE_APPLICATION_CREDENTIALS=' . __DIR__ . '/hogehoge.json');

$client = new Google_Client();
$client->useApplicationDefaultCredentials();

$client->addScope(Google_Service_Datastore::DATASTORE);

$datastore = new Google_Service_Datastore($client);

$kind            = new Google_Service_Datastore_KindExpression(['name' => 'User']);
$property        = new Google_Service_Datastore_PropertyReference(['name' => 'name']);
$value           = new Google_Service_Datastore_Value(['stringValue' => 'konishi']);
$property_filter = new Google_Service_Datastore_PropertyFilter([
    'property' => $property, 'op' => 'EQUAL', 'value' => $value]);
$filter          = new Google_Service_Datastore_Filter(['propertyFilter' => $property_filter]);
$query           = new Google_Service_Datastore_Query(['kind' => [$kind], 'filter' => $filter]);
$request         = new Google_Service_Datastore_RunQueryRequest(['query' => $query]);
$result          = $datastore->projects->runQuery('practice161003', $request);
var_dump($response->toSimpleObject());

上記のコードで、kind=Userのエンティティをname=konishiでフィルタしたデータをname列の降順で取得、となります。

ちなみにここに出てくるクラスはすべてGoogle_model クラスを継承しています。 Google_modelを継承するクラスは、setterを使わなくても、コンストラクタに連想配列で渡せるので、$queryは以下のようにもかけます。

$query = new Google_Service_Datastore_Query([
    'kind'   => [
        [
            'name' => 'User',
        ],
    ],
    'filter' => [
        'propertyFilter' => [
            'property' => [
                'name' => 'name',
            ],
            'op'       => 'EQUAL',
            'value'    => [
                'stringValue' => 'konishi'
            ]

        ]
    ],
    'order'  => [
        'property'  => [
            'name' => 'name',
        ],
        'direction' => 'descending',
    ],
    'limit'  => 10,
]);
$request  = new Google_Service_Datastore_RunQueryRequest(['query' => $query]);
$response = $datastore->projects->runQuery('プロジェクト名', $request);

このあたりは好みですかね。 個人的にはどうせラッパー書いてしまうことになると思うので、jsonでだーっと書いてしまう方にしたいと思います。

insert

$mutation = new Google_Service_Datastore_Mutation([
    'insert' => [
        'key'      => [
            'path' => [
                'kind' => 'User',
                'name' => 'keyとなるテキスト',
            ]
        ],
        'properties' => [
            'age' => [
                'excludeFromIndexes' => false,
                'integerValue'       => 27,
            ]
        ]
    ]
]);

$request = new Google_Service_Datastore_CommitRequest([
    'mode'      => 'NON_TRANSACTIONAL',
    'mutations' => [$mutation],
]);

$response = $datastore->projects->commit('プロジェクト名', $request);

jsonは、以下のリファレンスを見て組み立てます。

Method: projects.runQuery  |  Cloud Datastore  |  Google Cloud Platform

便利そうなラッパー作っている人もいますが、2013年で更新されておらず、今は動きません。

https://gae-php-tips.appspot.com/2013/12/24/getting-started-with-the-cloud-datastore-on-php-app-engine-part-ii/

感想

ローカル環境から実行したところ、上記のコードのrunQueryの部分だけで2秒ほどかかっていました。

GAE上だと10msほどになっていました。 Cloud Datastoreのデータはマルチリージョンということですが、GAEのリージョンus-centralになっているので、テストでアップしたデータはus-centralにあるようです。

東京リージョン早く来て欲しいなー。

参考

少し古かったので、現在動かすためには何点か修正が必要でした。

Google Cloud Datastore APIをPHPから使ってみる(データ取得) - Qiita

*1:検索したらありました。https://github.com/GoogleCloudPlatform/google-cloud-php 対応していないサービスが多いので、それ以外のサービスの場合は、API Client Library使ってねと書いてある。

macOS SierraにしたらPHPStormがエラーで起動しない問題の解消 (java, git)

対応バージョンのJavaが入ってないと言われるので、エラーメッセージに従って、Appleのホームページから落としてきて入れる。

Can't start git /usr/bin/git
Probably the path to Git executable is not valid. Fix it.

というエラーが出た。

whichすると、パスはあっている。

$ which git
/usr/bin/git

$ git
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

コマンドラインツールがinvalidらしいので、macOS Sierra用のCommand Line toolsをダウンロードする。

Command Line toolsは、XCode 8を入れるとついてくるが、XCode要らないのに5GB近くのものを入れたくないので、Command Line toolsだけインストールする。

Apple Developerにログインして、ダウンロードページに行き、Command Line Tools (macOS 10.12) for Xcode 8を入れる。

https://developer.apple.com/download/more/

問題なく使えるようになった。

この問題、OSのアップデートするといつも起きるのだが、自動的にやってほしい気がする。 できるのかな。

【全機能無料!】Twitterアカウント管理ツール「Cheetah」をリリースしました

2019/11/24 公開
この記事は2016/6/25 に公開するはずだったのですが、新サービスがうまくいきそうだったらポストしようと思って「下書き」に入れたものの、そのまま忘れたままになっていたものです。
4年経って Cheetah は SocialDog にサービス名を変え、ユーザー数20万人を突破しました!当時の雑なw感じを思い出すためにも公開しておきますw

こんにちは、小西です。

Twitter アカウントのフォロワーの質と量を改善する運用支援ツール「Cheetah」(チーター)をリリースしました! 無料で全機能お使いいただけるので、Twitter アカウントを運用している方は、ぜひ使ってみてください!

cheetahapp.net

フォロワーが数万人いても、フォロー・フォロー解除・ミュート・ブロックなどがサクサク行えます。 特にウェブでの集客のためにTwitterアカウントを運用されている方、フォロワーが1000人以上いる方は、便利さを実感いただけると思います。

機能の詳細については、ウェブサイトをご覧ください。

料金

すべての機能が無料で使えます。 たくさん使う場合だけ、月額980円の有料となります。

機能の詳細についてはホームページをご覧ください。

今後

「これ一つあれば他には何もいらない」というサービスを目指しています。