ホーム ブログ ページ 48

postgresqlでデータベース間でテーブル結合する方法(dblink)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

postgresqlでデータベース間でテーブル結合する方法を紹介します。

 dblink

contlibにdblinkというモジュールが登録されているのでこれを利用する。

windowsのインストーラーからインストールした場合同梱されています。

以下のデータベースを例に記載します

データベース host名
db1カレントのデータベースhost1
db2接続先のデータベースhost2

テーブル

データベース名テーブル名
db1table1
db2table2

table1のフィールド

フィールド名
db1_field1int
db1_field2text
db1_field3timestamp

table2のフィールド

フィールド名
db2_field1int
db2_field2text
db2_field3timestamp

 データベースにモジュールを適用する。

ログインする

psql -U [ユーザ―名] -d [モジュールを適用するデータベース名]

モジュールをインストール

create extension dblink;

これでインストールされます。

 接続

以下のSQLを発行すると’接続名’で定義した名前でコネクションを生成します。

select dblink_connetct(‘接続名’,’host=host2 port=5432 dbname=db2 user=xxx password=xxx’);

 切断

以下のSQLを発行すると’接続名’で定義したコネクションを切断します。

select dblink_disconnect(‘接続名’);

 接続先のデータベースにSELECT文を実行するには

上記の接続を実行後に以下のSQL実行することで、値が取得出来ます。

※SQLの返り値の型指定をしないとけないのが面倒。

select *

from dblink(‘接続名’,’ select db2_field1, db2_field2, db2_field3 from table2 ‘)

as t1 ( db2_field1 int, db2_field2 text, db2_field3 timestamp)

 このままでは、SQLが複雑になるのでビューにするとよい。

以下のようにビューを作ると。。。

create view db2_view as

select *

from dblink(‘接続名’,’ select db2_field1, db2_field2, db2_field3 from table2 ‘)

as t1 ( db2_field1 int, db2_field2 text, db2_field3 timestamp);

通常のテーブルのようにSQLが発行出来る。

select * from db2_view;

カレントデータベースにあるテーブルと結合してみる。

普通の結合文のように実行すれば結果が取得出来ます。

select db1.*, db2_view.* from db1

join db2_view on db2_view.db2_field1 = db1.db1_field1;

このように、データベースが異なる場合でもテーブル結合ができるので

活用してみてはいかがでしょうか?

詳細は、PostgreSQLのドキュメント、付録 F.追加で提供されるモジュールの項のdblinkに詳しく書いてあります。

http://www.postgresql.jp/document/9.1/html/dblink.html

DBの実データサイズを調べる(PostgreSQL編)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

DBを運用していると、どのテーブルが実際にどれくらいのファイルサイズなのかを知りたい場面があるかと思います。

そんな時、DBが使用している実データサイズを調べる方法を説明したいと思います。(データベース/テーブル)

今回はPostgreSQLが対象です。※9.1で確認しました。おそらく8系でも同じ方法かと思います

 データベースの実データサイズを調べる

データベースにはそれぞれoidという識別子が設定されています。

そして、実際にデータが格納されているディレクトリ名にもこのoidが付いています。

ですので、このoidが分かれば、あとは該当のディレクトリのサイズを調べることで、データベースの実データサイズが分かるのです。

oidはpg_stag_databaseという稼働統計情報から調べることができます。

# select datid,datname from pg_stat_database;
 datid  |            datname             
--------+--------------------------------
      1 | template1
  12172 | template0
  12180 | postgres
  30310 | hoge

このdatidというのがデータベースのoidです。hogeデータベースのoidは30310ということになります。

次にPostgreSQLのデータディレクトリから30310という名前のディレクトリを探します。

※データディレクトリの場所は環境やinitdb時の指定により異なります。よく使われるのは/usr/local/pgsql/data/などでしょうか。

[/usr/local/pgsql9.1/data/base]$ du -sh ./*
5.7M    ./1
5.7M    ./12172
5.8M    ./12180
 32M    ./30310
  0B    ./pgsql_tmp

duなどでディレクトリのファイルサイズを調べます。30310は32Mなので、hogeの実データサイズは32MBだと判明しました!

 テーブルの実データサイズを調べる

テーブルの実データサイズの調べ方も基本はデータベースと同じです。

テーブルのoidを調べ、データディレクトリから同じidのディレクトリを探します。

oidはpg_classのrelfilenodeカラムで確認できます。

hoge=# select relfilenode,relname from pg_class order by relname;
 relfilenode |                             relname                             
-------------+-----------------------------------------------------------------
       11868 | _pg_foreign_data_wrappers
       11877 | _pg_foreign_servers
       11886 | _pg_foreign_tables
       11896 | _pg_user_mappings
       30311 | users

usersテーブルのoidは30311だと分かりました。あとは先程調べたhogeデータベースのデータディレクトリ内の同名ディレクトリのファイルサイズを調べればOKです。

[/usr/local/pgsql9.1/data/base/30310]$ du -sh ./* | grep 30311
 16K    ./30311
 24K    ./30311_fsm

grepすると2件ヒットしますが、30311_fsmの方はVACUUM で発見されたすべてのフリースペースが記録されているファイルですので今は無視してOKです。

ですので、上記よりusersテーブルの実データサイズは16KBと分かりました。

以上です。もっと簡単に調べることができれば便利なのですが・・・。

ともあれ、この方法でDBの実データサイズを調べることができますので、ぜひご活用ください。

AWS Management ConsoleからAmazon EC2のインスタンスをセットアップしてみた

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。アピリッツの本多です。

前回に引き続きAWSの記事です。

今回はAmazon EC2のインスタンスをセットアップする手順を紹介します。

※注意:ブラウザはFirefoxを推奨。理由は後述

まずは前回の記事で作成したAWSのアカウントを用意しましょう。

アマゾンウェブサービス(AWS)のアカウントを作成してみました。

1.アマゾンウェブサービスTOPにアクセス

http://aws.amazon.com/jp/

2.ページ右上の「アカウント/コンソール」⇒「AWS Management Console」をクリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.02.AWS_TOP_menu.png

画像の赤枠のリンクです。

3.作成したAWSアカウントでAWS Management Console Homeにログイン

http://doruby.kbmj.com/honda_on_rails/files/ec2.03.Amazon_Web_Services_Sign_In.png

“My e-mail address is:”にメールアドレスを、

“I am a returning user and my password is:”にチェックしてパスワードを入力し

「Sign in using our secure server」をクリック。

ログインに成功すると、↓のようなページに遷移します。

http://doruby.kbmj.com/honda_on_rails/files/ec2.04.AWS_Management_Console_Home.png

4.EC2 Management Consoleに移動

Amazon Web Servicesのメニューの中にある”EC2″をクリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.04.AWS_Management_Console_Home_EC2_link.png

画像の赤枠のリンクです。

以下のページに遷移します。

http://doruby.kbmj.com/honda_on_rails/files/ec2.17.EC2_Management_Console.png

5.インスタンスセットアップ開始

http://doruby.kbmj.com/honda_on_rails/files/ec2.17.EC2_Management_Console2.png

Regionが”Asia Pacific (Tokyo)”になっている事を確認(画像左上の緑枠)し、

画像中央の赤枠の”Launch Instance”をクリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.05.Create_a_New_Instance.png

Classic Wizardを選択して「Continue」をクリック

6.OSを選択

http://doruby.kbmj.com/honda_on_rails/files/ec2.06.Choose_an_ami.png

特に決めているものが無ければ”Amazon Linux AMI”の64bitを選択

インスタンスのタイプ次第ではメモリが4GBを超えるものもあるため、64bitを選択しておくのが無難だと思います。

7.インスタンスタイプを選択

http://doruby.kbmj.com/honda_on_rails/files/ec2.07.Instance_Type.png

言い換えればサーバースペックの選択ですね。

業務の場合は用途に合ったスペックのインスタンスタイプを選択してください。

今回は、無料で使用出来るMicroを選択しています。

8.Availability Zoneを選択

http://doruby.kbmj.com/honda_on_rails/files/ec2.08.Availability_Zone.png

特に決めていない場合は”No Preference”を選択で良いです。

ただし、webサーバー用インスタンスを複数台用意する等、冗長化構成を取る場合は予め使用するAvailability Zoneを決めておき、

明示的に”ap-northeast-1a”、”ap-northeast-1b”を選択するようにしてください。

http://doruby.kbmj.com/honda_on_rails/files/ec2.09.Advanced_Instance_Options.png
http://doruby.kbmj.com/honda_on_rails/files/ec2.10.Storage_Device_Configuration.png

途中のAdvanced Instance OptionsやStorage Device Configurationはそのままで次へ。

Shutdown Behaviorが”Stop”になっている事だけ確認しておいてください。

9.サーバー名を設定

http://doruby.kbmj.com/honda_on_rails/files/ec2.11.Add_tags_to_your_instance.png

これはインスタンス一覧に表示する際に使われるタグの設定です。

Nameのvalueにサーバー名を入れておきましょう。

10.鍵ファイルの作成&設定

ログインするのに必要な鍵ファイルを作成する

http://doruby.kbmj.com/honda_on_rails/files/ec2.18.Create_a_new_Key_Pair.png

“Enter a name for your key pair”のフォームに名前を入力して”Create & Download your Key Pair”をクリックする。

すると鍵ファイルのダウンロードが始まるので任意の場所に保存。

保存後は次の画面に自動で遷移します。

※なお、IEだとダウンロードに失敗するという情報があるので、firefoxで実施する

既存の鍵ファイルを流用する際は”Choose from your existing Key Pairs”から鍵ファイル名を選択する

11.セキュリティグループの作成&指定

外部からのアクセスを制限するため、IPアドレスやポートの設定を行う。

http://doruby.kbmj.com/honda_on_rails/files/ec2.12.Create_a_new_security_group.png

デフォルトでSSHの22番ポートが全IPアドレスに対して開放されている状態です。

http://doruby.kbmj.com/honda_on_rails/files/ec2.13.Create_a_new_security_group_list.png

HTTPやHTTPS等の良く使われる設定は、いちいち番号を入力せずともリストから選択可能です。

設定して「Continue」をクリック

12.確認画面の内容をチェック

http://doruby.kbmj.com/honda_on_rails/files/ec2.14.review_the_information.png

問題なければ”Launch”をクリックしてインスタンス起動

http://doruby.kbmj.com/honda_on_rails/files/ec2.15.Your_instances_are_now_launching.png

正常に起動されれば↑のような画面に遷移します。

以上の手順でインスタンスを起動する事が出来ました。

それでは最後に接続確認をしましょう。

13.作成したインスタンスにSSHでログイン出来る事を確認

EC2 Management Consoleからインスタンス一覧に遷移する

“INSTANCES”⇒”Instances”をクリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.17.EC2_Management_Console_2.png

画像の赤枠のリンクです

インスタンス一覧に作成したインスタンスが追加されている事を確認し、クリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.16.EC2_Instance_selected.png

インスタンス詳細に大きくPublic DNSが表示されているので、メモしておく

画像の赤枠の部分です。

14.SSHクライアントでログイン

13で確認したPublic DNSと、10で作成した鍵ファイルを元にSSH接続

※SSHクライアントにputtyを使用している場合は、別途変換する必要有

ID: ec2-user

PASS: なし

でログイン出来る事が確認できればOKです。

あとがき

今回は手順を細かく砕いて説明したため、14もの工程になりましたが、手順そのものはさほど難しくなく

行う事が出来たのではないかと思います。

次回はEC2を業務利用する上で必要な作業の1つであるEIPの設定手順を紹介したいと思います。

rails3のログ解析ツール「request-log-analyzer」について

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rails3のログ解析ツールを紹介します。

 request-log-analyzer

rails3のproduction.logを解析する事になったので、調べてみると

request-log-analyzerというツールが良いとの記事を見た。

 インストールしてみる。

railsが入っている環境であれば以下のコマンドでインストールされます。

 gem install request-log-analyzer

 小職の環境では、以下にインストールされました。

/usr/local/bin/request-log-analyzer

 使ってみる

以下を入力すると。。。。

request-log-analyzer production.log

解析が始まり、解析が終わると

Request summary リクエストのサマリー
  • Parsed lines 解析した行数
  • Skipped lines スキップした行数
  • Parsed request 解析したリクエスト
  • Skipped lines スキップしたリクエスト
  • Warnings 警告数
  • First request 最初のリクエストの日時
  • Last reuquest 最後のリクエストの日時
  • Total time analyzed 解析した期間
Request distribution per hour 時間当たりのリクエスト数
Most requested リクエストの多い順(TOP20)
HTTP methods HTTPメソッド毎のリクエスト数
HTTP status returned HTTPのステータス毎のリクエスト数
REQUEST DURATION – BY SUM リクエストの所要時間の合計
REQUEST DURATION – BY MEAN リクエストの所要時間の平均
VIEW RENDERING TIME – BY SUM ビューのレンダリング時間の合計
VIEW RENDERING TIME – BY MEAN ビューのレンダリング時間の平均
DATABASE TIME – BY SUM データベースからの応答時間の合計
DATABASE TIME – BY MEAN データベースからの応答時間の平均
Process blockers (> 1 sec duration) 
Parse warnings 解析時のワーニングが表示されます

 railsのログ以外での使い方

Apacheのログを解析したい。

request-log-analyzer apache.log

rails ログと同様に解析した結果が出力されます。

 さまざまなオプション

入力オプション

–format, -f 解析するログのフォーマットを指定します。

  rails,rails3 rails のログとして解析します。

  apache apacheのログとして解析します。

  この他にも、merb,rack,delayed_job,amazon_s3,mysql,postgresql,oink,haproxy等を解析できるようです。

出力オプション

–output , -o 出力するフォーマットを指定します。

デフォルトだとコンソールに整形された文字列として出力されます。

   HTML HTML形式で整形された文字列として出力されます。

–file 指定したファイルに出力します。

–database,-d 指定したSQLite3形式のデータベースとして出力します。

詳しくは以下に載っています。あなたもこれでログ解析ライフを!

https://github.com/wvanbergen/request-log-analyzer/wiki

アマゾンウェブサービス(AWS)のアカウントを作成してみました。

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。KBMJ改めアピリッツの本多です。

最近仕事で利用しているAWSについての記事を書かせて頂きます。
今回は、アカウントの作成手順を紹介します。

■予め必要なもの

・クレジットカード
・有効な電話番号
・メールアドレス

1.アマゾンウェブサービスTOPにアクセス

http://aws.amazon.com/jp/

2.ページ右の「今すぐ申し込む」または右上の「サインアップ」をクリック


画像の赤枠のリンクです。

3.ログイン用のメールアドレスを入力してサインアップを開始


My e-mail address isの欄に自身のメールアドレスを入力し、
I am a new user.をチェックして「Sign in using our secure server」をクリック。

4.ログイン用の情報を登録


アカウント名及びログインするためのメールアドレス/パスワードを入力して「Continue」をクリック
My e-mail address isの欄には、先ほど入力したメールアドレスが予め入っている状態です。

5.利用者の個人情報の登録


お問い合わせ情報のフォームに住所、氏名、電話番号等を入力し、
利用規約に同意して「アカウントを作成して続行」をクリック。
注意点としては、氏名や住所等の情報が全て半角英数字で入力しなければならないという事です。
例えば“渋谷区”⇒”Shibuya-ku”みたいな書き方をしないといけないので、慣れない入力に戸惑うかもしれません。

6.クレジットカードの情報を登録


クレジットカードの情報を入力して「続ける」をクリック
請求先は5で登録した住所をそのまま指定する事ができます。

7.電話による身元確認を実施

なんと、AWSから実際に電話を受けて認証を行うシステムが導入されています。
おそらく一個人・団体がアカウントを大量に取得する事を防ぐための対策だと思いますが、ここまでやるかAmazonと関心しました。


国コードは”Japan(+81)”を選択し、電話番号(必要な場合は内線番号も)を入力して「確認用に自分に電話をする」をクリック。


しばらくするとAWSから電話がかかってくるので、案内にしたがって画面に表示されている暗証番号を通知する。


暗証番号の通知に成功すると、画面が↑のように切り替わって身元確認が完了します。
「続ける」をクリック。

8.確認画面に遷移し、AWS側の認証を待つ


認証が完了したら登録したメールアドレス宛に

「AWS Unified Registration Sign-Up Confirmation」

というタイトルで登録完了メールが送られてきます。
メールが届けば、AWSが利用可能になります。

あとがき

以上の手順で、AWSへのアカウント登録が完了しました。
英語での住所の入力や、電話を使っての身元確認はあまり他で見かけないため戸惑うかもしれませんが、
難しくは無いので頑張って挑戦してみてください。

次回は作成したアカウントを使って、Amazon EC2 Instanceの作成手順を紹介したいと思います。

Mysql(InnoDB)のロックの変化について

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

最近、MysqlでUpdate を行った際、更新対象件数によって、書き込みロックが行ロックからテーブルロックに変化することがあったので

その原因と対処方法について書こうと思います。

環境は下記の通りです。

OS: CentOS 5.6, MacOSX 10.7.3
Mysql 5.1(InnoDB)

↓のテーブルに、1000件レコードが存在すると仮定して説明していきます。

CREATE TABLE `sample_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `val` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ロックが行ロックからテーブルロックに変化する現象が発生するのは、

以下のSQL文です。

UPDATE sample_table SET val = "hoge" WHERE id in (100件分のid); => 行ロック
UPDATE sample_table SET val = "hoge" WHERE id in (500件分のid); => テーブルロック

ロックの変化の原因を探っていると、EXPLAINの結果に違いがあることがわかりました。

対象件数が100件の場合にはtypeがrangeなのに対し

対象件数が500件の場合にはtypeがALLになり、インデックスが使われていません。

対象件数 100件
EXPLAIN SELECT * FROM sample_table WHERE id IN (100件分のid);
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table            | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | products         | range | PRIMARY       | PRIMARY | 4       | NULL |  500 | Using where |
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+

対象件数 500件
EXPLAIN SELECT * FROM sample_table WHERE id IN (500件分のid);
+----+-------------+------------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table            | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+------------------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | products         | ALL  | PRIMARY       | NULL | NULL    | NULL | 1000 | Using where |
+----+-------------+------------------+------+---------------+------+---------+------+------+-------------+

このフルテーブルスキャンが原因でテーブルロックが発生していました。

ロックの変化についてMysqlリファレンスを調べたところ、下記のような記述がありました。

 MySQL では利用可能な場合でもインデックスが使用されない場合があることに注意し
てください。この一例として、インデックスの使用によって、MySQL がテーブルの 30% 
を超えるレコードにアクセスする必要が生じる場合が挙げられます(この場合は、必要な
シークが大幅に減少するため、テーブルスキャンのほうが高速になる可能性が高くなり
ます)。 ただしこのクエリに、レコードの一部のみを取り出す LIMITが使用されている場
合、結果で返される少数のレコードを迅速に検索できるため、MySQL はインデックスを
使用します。

上記を参考に、LIMITを付け加えることでインデックスが使用され、テーブルロックになることが防げました。しかし、速度が犠牲になる可能性があるため、使いどころは考える必要がありそうです。

10分ではじめるウェブサービス

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


よしだです。

今回は無料で使える PaaS「Heroku」を利用して、簡単にウェブサービスを作成、公開する方法を紹介します。

 概要

Heroku」は無料で使える PaaS です。

PaaS とは IaaS (一般的なVPS)をベースにしたもので、実用に不可欠であるウェブサーバや DBMS などを最初から備えているサービスを指します。PaaS を利用すれば「ちょっとしたウェブサービスを作って公開したい!」といったときに、自らサーバ構築を行う必要がなくなります。とくに「Heroku」は無料で利用することができ、さらに「サービスの人気向上に伴うサーバ強化」などのスケーリングが必要になった際にも、課金サービスを受けることで柔軟な対応が可能になります。

今回はこの「Heroku」の利用方法を紹介します。

 1. Heroku に登録

1. メールアドレスの登録

まずは Heroku のアカウント登録ページでメールアドレスを入力します。

https://api.heroku.com/signup

メールアドレスを登録すると下記の画面に遷移します。

https://api.heroku.com/signup/ok

2. メールの確認

Heroku から届いたメールを確認し、記載されている URL にアクセスします。

「Welcome to Heroku」と書かれた入力フォームが開かれます。

3. パスワードを設定

適当なパスワードを設定し、「Save」ボタンを押します。

Heroku への登録はこれだけでおしまいです。

次にクライアント側のセットアップに移ります。

 Heoku に必要なソフトウェアをセットアップ

1. git 、ruby、rubygems をインストール

今回はウェブサービスの作成に Ruby on Rails を使用することにします。

Heroku では Rails3 がサポートされているので、これに対応するソフトウェアをインストールします。

CentOS の場合:

# yum -y install git
# wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p290.tar.gz
# tar xvzf ruby-1.9.2-p290.tar.gz
# cd ruby-1.9.2-p290.tar.gz
# ./configure
# make
# make install
# cd
# wget http://rubyforge.org/frs/download.php/74619/rubygems-1.7.2.tgz
# tar xvzf rubygems-1.7.2.tgz
# cd rubygems-1.7.2
# ruby setup.rb
FreeBSD の場合:

# echo 'RUBY_DEFAULT_VER=1.9' >> /etc/make.conf
# cd /usr/ports/lang/ruby19
# make install clean
# cd /usr/ports/devel/ruby-gems
# make install clean
# cd /usr/ports/devel/git
# make install clean

2. Heroku のセットアップ

Heroku 専用のコマンドをインストールします。

# gem install heroku
# heroku keys:add
Enter your Heroku credentials.
Email: hyoshida@appirits.com
Password: 
Uploading ssh public key /home/hyoshida/.ssh/id_rsa.pub

 ウェブサービスのセットアップ

1. Rails のアプリケーションを作成

適当な名前のアプリケーションを作成します。

% rails new simple-sg

2. Heroku 向けに編集

ここは少し引っかかりやすいところになります。

Heroku では DBMS に PostgreSQL をサポートしているので、これに合わせた設定が必要になります。

% cp Gemfile /tmp
% vim Gemfile
% diff Gemfile /tmp/Gemfile
8,14c8
< group :preoduction do
<   gem 'pg'
< end
< 
< group :development, :test do
<   gem 'sqlite3'
< end
---
> gem 'sqlite3'
% cp config/database.yml /tmp
% vim config/database.yml
% diff config/database.yml /tmp/database.yml

3. 必要な gem のインストール

Rails アプリに必要な gem のインストールを行います。

今回は Rails 主題の話ではないので、細かい説明は割愛します。

% bundle install --path vender/bundle --without production

4. git の初期化

git に、作成したアプリケーションのファイル群をコミットします。

先ほど追加した gem のファイル群は、コミットする必要がないため除外しています。

% cd simple-sg
% git init
% echo 'vender/bundle' >> .gitignore
% git add .
% git commit -m 'first commit'

 Heroku にアップロード(デプロイ)

1. Heroku 上にアプリケーション枠を用意する

いよいよウェブサービスを公開していきます。

まずは適当なアプリケーション名を Hroku に登録します。

% heroku create simple-sg
Creating simple-sg... done, stack is cedar
http://simple-sg.herokuapp.com/ | git@heroku.com:simple-sg.git
Git remote heroku added

2. リモートリポジトリを追加する

1. で出力された内容を元にして、git にリモートリポジトリを追加します。

% git remote add heroku git@heroku.com:simple-sg.git

3. デプロイする

下記のコマンドで git のコミット内容をリモートリポジトリに反映させるだけで、Heroku 上にウェブサービスが立ち上がります。

% git push heroku master

 おわりに

少し早足になりましたが、このように簡単にウェブアプリケーションをはじめることができます。

次回は、Heroku 上に簡単なソーシャルゲームを作成する手順について紹介したいと思います。

タッチイベントを用いたスワイプ&フリックの実装サンプル

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

スマートフォンのタッチイベントを用いて、画像を横方向にスライドさせる実装をご紹介します。

※PCではマウスイベントで代用可能だと思われます。

※Android/iPhone両方で動作するはずです。

ポイントとしては、スワイプとフリックの動作です。

スワイプ

画面をタッチした状態で指を動かす動作

フリック

画面をタッチした状態で指を「素早く動かす、弾く」動作

この2つの動作を組み込むことで、ネイティブアプリのようなスムーズな動きが実現できます。

 sample.css

body {margin:0;padding:0;}

#slider {
    position: relative;
    width: 320px;
}

#slider a:focus {
    outline: 0;
}

.slider-view {
    position: relative;
    border: 1px solid #bbb;
    width: 320px; /* スライダーで表示するエリアの大きさ */
    height: 360px;
    overflow: hidden; /* 必須 */
}

.slider-container {
    position: absolute;
    top: 0;
    left: 0;
    background-color: black;
	width: 2000px; /* 本来はコンテンツの横幅を取得して動的に設定すべきです */
}

/* スライドするコンテンツ部分 */
.slider-container div {
    position: relative; /* ループ処理に使う */
    float: left;
}

/* チラツキ対策 */
.slider-container {
  -webkit-transform:translate3d(0,0,0);
}

 sample.html

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  <title>Sample</title>
  <script src="/assets/jquery.js" type="text/javascript"></script>
  <script src="/assets/sample.js" type="text/javascript"></script>
  <link href="/assets/sample.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="slider">
  <div class="slider-view">
    <div class="slider-container">
      <div id=1><img src="/images/01.jpg" /></div>
      <div id=2><img src="/images/02.jpg" /></div>
      <div id=3><img src="/images/03.jpg" /></div>
    </di>
  </div>
</div>
</body>
</html>

sample.jsではjQueryを利用しているので、jQueryをロードしておきます。

※HTMLタグは都合上全角になっております。実際は半角です。

 sample.js

$(function () {

// 対象となる要素を変数に格納しておく
var $slider     = $('#slider'),
    $container  = $slider.find('div.slider-container'),
    $containerDiv = $slider.find('div.slider-container div');
var distance = 0;    //移動距離を指定するのに使う

// スライド関数
var slide = {
  
  // スライド(進む)
  next: function (index, spd, flick_flg) {
    distance = distance + index;
    slide.scroll(distance, spd, flick_flg);
  },
  
  // スライド(戻る)
  prev: function (index, spd, flick_flg) {
    distance = distance - index;
    slide.scroll(distance, spd, flick_flg);
  },
  
  //移動距離分スクロール
  scroll : function (d, spd, flick_flg) {
    var move = -d
    var env = 'translate3d(' + move + 'px,0,0)';
    
    if (flick_flg) {
      /* フリック時はwebkit-transformプロパティを設定し、滑らかなアニメーションにする */
      transit_property = '-webkit-transform ' + spd + 'ms cubic-bezier(0,0,0.25,1)';
    } else {
      transit_property = 'none';
    }
    
    $container.css({
      '-webkit-transform':env,
      '-webkit-transition':transit_property
    }).bind('webkitTransitionEnd', function(){
       //ここで移動後の終了イベントが取れます     
    });
  }
}

$(window).load(function() {
  var pageX;      //リアルタイムのX座標
  var pageY;      //リアルタイムのY座標
  var startPageX; //スタート時のX 座標の位置
  var startTime;  //スタート時の時間
  var move_time = 0;
  
  /* タッチの開始時のイベント */
  $('#slider').bind('touchstart', function() {
    event.preventDefault();     // ページが動いたり、反応を止める(A タグなど)
    pageX = event.changedTouches[0].pageX;
    pageY = event.changedTouches[0].pageY;
    startPageX = pageX;
    startTime = +new Date();
  });
  
  /* タッチしたまま動かしたときのイベント */
  $('#slider').bind('touchmove', function() {
    var moveX = event.changedTouches[0].pageX; // X 座標の位置
    var absX = Math.abs(pageX - moveX); // 移動距離の絶対値
    var spd = 0.5;
    pageY = event.changedTouches[0].pageY;
    
    /* スワイプ処理 */
      if (pageX > moveX) {
        slide.next(absX, spd);
      } else if (pageX < moveX) {
        slide.prev(absX, spd);
      }
      pageX = moveX;
  });
  
  /* タッチ状態から離れたときのイベント */
  $('#slider').bind('touchend', function() {
  	/* 終了処理が必要ならここに書く */
    /* このイベントは、位置を取得できないので注意 */
    
    var diffX = startPageX - pageX;
    var absX = Math.abs(diffX);
    var mv = 200; //フリック移動距離
    var spd = 700; //フリックスピード
    var now = +new Date(); //現在時間
    var diffTime = now - startTime; //touchstartからの経過時間

    /* フリック処理(touchstartからの経過時間が短い場合) */
    if (diffTime < 400) {
      if (diffX > 0) {
        slide.next(mv, spd, true);
      } else if (diffX < 0) {
        slide.prev(mv, spd, true);
      }
    }
    
    move_time = 0;
  });
});
});

スワイプかフリックかの判定は、touchstart(タッチした瞬間)からtouchend(離した瞬間)までの時間で判定します。

上記サンプルでは400ミリ秒未満の場合はフリックと判定するようにしています(diffTime < 400)

以上です。スワイプとフリックでネイティブアプリのような動きを実現しましょう!

CentOS disk容量 dfとduの値の違い

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rick No26です。
ついこの間、サーバの容量が圧迫されduコマンドなどで調べても全然使用していないのにdfでみると使用率80%近くいっていたことがあったので、解決方法を紹介します。

環境

CentOS 5.4

dfの値

# df -h
Filesystem サイズ 使用 残り 使用% マウント位置
???秘密???    113G  83G  24G  78%    /
・・・省略・・・
???秘密???     379G  220G  140G 62% /var
これを見ていただくと
「/」と「/var」で約300G使用していることになる。

duの値

# du -h /
これで出てきた最後の「.」は、235Gだった。

疑問

「/var」をduすると220Gで合っていた。
それ以外をduすると、全部で15Gしかなかった。
確かにduで「/」から行った時の合計は235Gだ、
だが、dfで行った時の合計は300G近く、
「/var」があっているので「/」がおかしい、
83Gと15G、、、68Gはいったいどこで使用されているのか?

原因

どうやら削除しても削除しきれていないファイルデータがあるらしい。
# ls -al /proc/*/fd/* | grep deleted
これで出てきたものが削除しきれていないファイルです。
このログをみて、ファイル移動したなとか、プロセス強制終了したなとか思い当たるフシがあるはずです。
そのファイルを操作しているアプリを再起動してみてください。
「/」のdisk使用量が一気に下がるはずです。
自分の場合は、40G程一気に解放されました。

以上、困った時の参考になると幸いです。

鍵がカギで無くなる日

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

先日、米国で開催された「Hackers on Planet Earth 2012」で、とあるデモが行われた。

このデモは、3Dスキャナと3Dプリンタを用い、カギを複製する物だった。

3Dプリンターは、安い物では10万円前後で買うことが出来、1つあたりのコストもわずか数十円とお手軽である。大きな物を作ることは出来ないが、手のひらサイズなら問題なく作成できる。この3Dプリンターは、底辺から輪郭を含めて、すべてを「印刷」することで、オブジェクトを作成する。こうして作成されたオブジェクトは、通常の彫刻や削りでは再現することが難しい、完全につなぎ目の無いモノを作成することが出来る。

次に、3Dスキャナー*1だが、見たモノを見たままに、3Dとして記憶することが出来る。このプリンターと先ほどの3Dプリンターを用いることで、完全にうり二つのモノを作成することが容易に出来る。

 カギの脆弱性

カギが物理形状を成している以上、3Dプリンターの前では、なすすべが無い。

たとえば、ピッキング対策として、採用されているディンプルキーと呼ばれるカギですら、3Dプリンターと3Dスキャナーを組み合わせれば、いとも簡単に同じモノを複製することができる。もはや、物理形状の複雑さだけでは、家を守ることが出来なくなっているのかもしれない。3Dプリンターといえども、磁気情報やIC情報、電波などの物理的に見えるモノ以外の情報を複製できない。もし、真剣に守りたいなら、ディンプルキーではなく、ICカードや磁気カードなどを複数組み合わせたモノを採用する必要が出てくるのかもしれない。

 日本独自のカギ文化

日本独自と言っても過言では無いカギがある。それは、多くの金融機関で採用されており、他国ではほぼ採用されていないもの。そう、印影である。

印影が一致しない限り、現金を引き出すことが出来ない。逆に言えば、印影が一致すれば、現金を引き出すことが出来るもの。それが印影で有り、印鑑だ。通常、印影は印鑑と対になっており、「印鑑をお持ちください」と言われれば、すなわち「印影」を示すことが多い。こうした印影は、当然のように3Dプリンターと3Dスキャナの前では、為す術無く複製されてしまう。欧米のように、簡単には複製できない、筆圧や書き順などに対応した、署名に移行する時期も近いのかもしれない

*1: 安いモノで、300万円ほどする

Rails migrationでbigint型のidカラムを作成

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Railsのmigrationでbigint型のカラムを作成する方法です。

Rails3.1.3, Postgresql 9.1.0 にて確認。

Railsではmigrationのadd_columnでprimary_keyオプションを指定すると、自動でシーケンステーブルとオートインクリメントの付いたカラムを作成してくれます。

class AddColumnIdToUsers < ActiveRecord::Migration
  def up
       add_column :users, :id, :primary_key
  end

  def down
    remove_column :users, :id
  end

end

ですが、これでは型がintegerになってしまいます。型を変更するオプションなども無いようです。

bigintでカラムを作成するため、SQLを直接発行することにします。

class AddColumnIdToUsers < ActiveRecord::Migration
  def up
    execute <<-SQL
      ALTER TABLE users ADD COLUMN id bigint DEFAULT nextval('users_id_seq') PRIMARY KEY;
    SQL
  end

  def down
    remove_column :users, :id
  end

end

Postgresqlでのシーケンステーブルは以下のように作成できます。

class CreateUsersSeq < ActiveRecord::Migration
  def up
    ActiveRecord::Base.connection.execute("create sequence users_id_seq;")
  end

  def down
    ActiveRecord::Base.connection.execute("drop sequence users_id_seq;")    
  end
end

AndroidでGoogle Mapsを表示

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

AndroidでGoogle Mapsを表示するための方法をご紹介します。

 Maps APIキーの取得

Android上でGoogle Mapsを使用するためにMaps APIキーが必要です。

その際、Googleのアカウントと証明書が必要となります。

証明書はデバッグ用のものが以下の手順で取得できます。

$ keytool -list -keystore ~/.android/debug.keystore
...
Certificate fingerprint (MD5): 94:1E:43:49:87:73:BB:E6:A6:88:D7:20:F1:8E:B5:98

パスワードを聞かれますが、入力せずにEnterを押します。

次に以下のサイトにアクセスします。

Android Maps API Key

規約確認のチェックボックスをONにし、

先ほど出力したフィンガープリントを入力して、「Generate API Key」ボタンを押すと、

Maps Keyを取得できます。

 Google APIsインストール

Android Mapsを使用するためにはGoogle APIを使用します。

プロジェクト作成時のビルドターゲットに「Google APIs」が無い場合は、Android SDK and AVD Managerでインストールしてください。

※Google APIsはプラットフォーム別に複数あるので、開発に使うプラットフォームのものは必ずインストールします。 まあ全部インストールしちゃってもいいと思います。

1. Android SDK and AVD Managerを開く

(開発にEclipseを使用している場合は、[ウィンドウ] – [Android SDK and AVD Manager] などで開けます)

2. Available PackageでインストールするGoogle APIsにチェックを入れる

3. [Install Selected]をクリックしてインストール

 AVDの作成

Google APIs用のAVD(Android Virtual Device)を作成しておきます。

Google APIsをインストールした時と同じようにAndroid SDK and AVD Managerで作成します。

1. Android SDK and AVD Managerを開く

(開発にEclipseを使用している場合は、[ウィンドウ] – [Android SDK and AVD Manager] などで開けます)

2. Virtual Devicesで[新規]をクリック

3. 「名前」は適当なものを入れ、「ターゲット」には開発で使用するGoogle APIsのプラットフォームを入力して、[Create AVD]をクリック

 サンプルプロジェクトの作成

最後に簡単にGoogle Mapを表示するためのサンプルプロジェクトを紹介します。

新規プロジェクトの作成では、ビルドターゲットに先ほどインストールしたGoogle APIsを選択します。

package com.exapmple.androidmaps2;

import android.app.Activity;
import android.os.Bundle;

import android.os.Bundle;
import com.google.android.maps.*;
 
public class AndroidMaps2 extends MapActivity {
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MapView map = new MapView(this, "[Android Maps API Key]");
        map.setEnabled(true);
        map.setClickable(true);
        setContentView(map);
    }
 
    @Override
     protected boolean isRouteDisplayed() {
        return false;
    }
}

[Android Maps API Key]に準備で取得したAndroid Maps API Keyを入力して下さい。

AndroidManifest.xmlは下記のようになります。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.androidmaps" android:versioncode="1" android:versionname="1.0">
    <uses-sdk android:minsdkversion="1.5" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".AndroidMaps" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
		 <uses-library android:name="com.google.android.maps" /> ←追加
    </application>
    <uses-permission android:name="android.permission.INTERNET" /> ←追加
</manifest>

これでGoogle Mapが表示されます!

リアルタイム多人数じゃんけんゲーム「JANG Battle」をリリースしました

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

 概要

  • Node.js+socket.io+expressアプリはとっても簡単
  • herokuにデプロイしたら予想外のところで詰まった
  • 格闘ジャンケンゲームJANG Battle!みんな遊んでね!

 リアルタイム通信するアプリを作ったことありますよね

 こんにちは,Rails厨のわたなべ(hackugyo)です.

 ところでみなさんはNode.jsって知っていますか.Node.jsのヴァージョンを管理するソフトにナベっていうのがあるんですが,私はワタナベなのでライバル視しています.

 node.js+Socket.IOのNon-blockingI/O環境を見ると,一刻も早くリアルタイムに通信するアプリを作りたくなりますよね.私もそうです.ざっと見たところ,リアルタイム通信ときいて一番にみなさんが思いつくのはチャットアプリのようで,node.jsの前開発リーダRyan Dahlさんもgithubでサンプルを公開されています(https://github.com/ry/node_chat).

 私も学習のためにチャットアプリを作ろうと思ったのですが,リアルタイム通信といえばゲームだよなと思い直し,途中から格闘ゲームに切り替えて作りました.といっても中身はほとんどチャットで,パンチ・ガード・ジャンプキックの3つのうちどれかをコマンド選択して,相手のコマンドとの相性で勝敗を決めるという,簡単なものです.

こちらがアプリです

 対戦格闘じゃんけんゲーム

 JANG Battle!!

  1. ぐー・ちょき・ぱーから手を選びます
  2. 他のプレイヤの選んでいる手に勝っていれば,1点ゲット
  3. 連打によってどんどん点を稼げます
  4. 他のプレイヤがリアルタイムに手を変えるので,同じ手を連打していても勝てないかもしれません
  5. 20点とったら勝ちです

 このアプリの作成にあたっては,ゲーマの友人の今井晋さん(facebookページ)より企画・アイデアをいただきました.貴重なアイデアを無償で公開していただき感謝します.

 勝敗判定など,今後もアップグレードを続けていきます!

(ソースもこちらで公開します.https://github.com/hackugyo/ChatJangBattle

 ヘロクにデプロイする

 さて,せっかく作ったのですから,localhostで動かすだけでなく,公開してみんなに遊んでもらいたいものです.チャットアプリもそうですが,リアルタイム通信の面白みを知るにはやはり多くのクライアントをさばく様子を見たいわけです.ましてや今回は対戦型格闘ゲームを作ってしまったので,ひとりで複数タブからパンチ……ガード……していてもむなしいだけです.

 最近は恐ろしいことに,Paasなホスティング環境が無料でたくさんそろっています.DotCloud, Cloud Foundry, OpenShift, Node Ninja, Nodejitsu, etc.(node.js対応のホスティング環境の一覧はこちらにまとまっています).いまやWebアプリを試すのにも,localだけで満足する理由はほとんどなくなりました(セキュリティまわりの問題はありますが).さあ,どこにホスティングさせてもらいましょうか?

 さあ,私はRails厨なので、ここでもちろんHerokuを選びます.HerokuはRubyの作者まつもとゆきひろ氏をチーフアーキテクトに迎えるなど,Rubyに対しなみなみならぬ優しさをもったプラットフォームです.言語としてはほかにもScala, Java, Pythonなどにも対応しており,もちろんnode.jsもOKです.

herokuデプロイ時の注意

masterブランチをpushすること

 gitを利用し,ふだんのヴァージョン管理とほとんど変わらない気軽さでデプロイできるのが,Herokuの大きな魅力ですが,ここにはちょっとした心理的落とし穴があります.

 私は最近,gitのブランチモデルについて勉強し,release / develop / featureなどのブランチをごりごり切り替えて使っているのですが,その影響で,herokuに大してもうっかり

$ git push heroku release

とreleaseブランチをpushしてしまったのです.これではさしものherokuも理解してくれません.ここは,正しくは

$ git push heroku relase:master

とすべきでした.あるいは,おとなしくmasterブランチをrelease目的に使ってもいいでしょうね.

ポート番号には注意

 ローカル環境でWebアプリを試して,それをherokuにデプロイする場合,気をつけたいのはポート番号の設定です.ほかにも,Procfileを書くなどの追加点はありますが,既存のソースに手を入れるのはつい忘れがちです.

 さて,ローカル環境で試したWebアプリには,主に2カ所,ポート番号を書いているところがあります.

  1. サーバサイドのjs
  2. クライアントサイドのjs

 あたりまえですね.

 サーバサイドは簡単です.app.jsのここを

var port = 5000;
app.listen(port, function(){
  console.log("Express server listening on port %d in %s mode", 
    app.address().port, app.settings.env);
});

こう変えるわけです.

var port = process.env.PORT || 5000;
app.listen(port, function(){
  console.log("Express server listening on port %d in %s mode", 
    app.address().port, app.settings.env);
});

これで,herokuデプロイ時にはprocess.env.PORTの値が使われるようになります.(デフォルトポートが5000なのは,foremanというマネージャに合わせたためです)

 問題はクライアントです.jadeからclient.jsを切り出したのはいいのですが,その中でこういう記述をしていました.

var socket = io.connect('http://localhost:5000/chat');

// 一覧表示要請を検知し,ログを表示する
socket.on('chat.list', function(list) {
  ...
});

ソケット接続を要求するためのコードですが,ポート5000がまるのまま出てきていますね.io.connectを使った書きかたは,node.jsのv0.7以降で登場したものだそうで,ネットを見てもあまり情報がありません.

 ここは素直にこう変えます.

var socket = io.connect('/chat');

// 一覧表示要請を検知し,ログを表示する
socket.on('chat.list', function(list) {
  ...
});

これで,ポートやホスティング先URLに関係なく,正しい接続要求をすることができます.

 みなさんもnode.jsでherokuに楽しいアプリを作ってください!

 ご参考

  1. herokuへのnode.jsアプリのデプロイについては,本家ブログに記事があります. https://devcenter.heroku.com/articles/nodejs
  2. node.jsじたいの解説は, Web+DBPRESS vol.58(技術評論社, 2012)の特集”Node.js実践入門”がたいへん参考になります.著者は名村卓(@snamura)さんです.
  3. チャットアプリのUIについては,いくつもライブラリが公開されています.最近だとBaloons.IOなどかっこいい. https://github.com/gravityonmars/Balloons.IO
  4. テンプレートエンジンにはexpressのデフォルトのJadeを使いました.こちらのコンヴァータは便利:http://html2jade.aaron-powell.com/
  5. 開発環境はEmacsでしたが,Nideもちょっと触りました.面白いですね.http://coreh.github.com/nide/

ここ最近使ってみたiOSのライブラリまとめ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

最近になって仕事としては約1年ぶりにiOSアプリの開発をしております。

その間にiOSが5になったり、iPhone4Sが出たりと状況が変わっており一瞬浦島太郎気分を味わったり、そんな自分がここ最近触ってみたiOSのライブラリを紹介したと思います。

 AFNetworking

https://github.com/AFNetworking/AFNetworking

ネットワーク用のライブラリです。今までネットワークのライブラリはASIHTTPRequestを使っていましたが、開発が止まってしまい、新たな案件で使い続けるのも不安だったのでこっちに乗り換えてみました。

通信終了後の処理をブロックで書けるのが何気に便利ですね。

XMLやJSONをダウンロードするためのクラスも用意されております。

JSONをJSONKitと組み合わせて使ってみましたが、特に意識することなくダウンロードしたJSONをNSDictionary、NSArrayの形で展開してくれてすごく便利でした。

 SVProgressHUD

https://github.com/samvermette/SVProgressHUD

ライブラリを取り込んで、下の1行を書くだけでクールなインジケータを出すことができます。

[SVProgressHUD showWithStatus:@"ダウンロード中" maskType:SVProgressHUDMaskTypeGradient];

 OHAttributedLabel

https://github.com/AliSoftware/OHAttributedLabel

これを使うと下のように1つのラベルで色を変えたり、文字のサイズを変更したり、リンクを貼ることが出来ます。

コードはこんな感じです。

    NSString *text = @"赤文字、青文字、大文字、太字、http://doruby.kbmj.com/";
    NSMutableAttributedString *attrStr = [NSMutableAttributedString attributedStringWithString:text]; 
    [attrStr setTextColor:[UIColor redColor] range:[text rangeOfString:@"赤文字"]];
    [attrStr setTextColor:[UIColor blueColor] range:[text rangeOfString:@"青文字"]];
    [attrStr setFont:[UIFont systemFontOfSize:16] range:[text rangeOfString:@"大文字"]];
    [attrStr setFont:[UIFont boldSystemFontOfSize:12] range:[text rangeOfString:@"太字"]];
    _label.attributedText = attrStr;
    [_label addCustomLink:[NSURL URLWithString:@"http://doruby.kbmj.com/"] inRange:[text rangeOfString:@"http://doruby.kbmj.com/"]];

一つのラベルで色を変えたり、リンクを貼ることが出来たり便利なライブラリですが、いくつか何点もありました。

  • iOS5でテーブルビューのセルで使うとカクカクになりやすい。
  • 複数行表示させると標準のUILabelに比べて行間が広い。

売買される個人情報

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

皆さんは、自分の個人情報について、どれくらい気を使っているだろうか。その昔、メールと名前、性別がセットで1件当たり○○円で売買しているなんて記事が、ネットに流れたこともあった。現在は、そういったセット販売の価格が暴落し、単純に1件でいくらという価格出はなくなりつつあると聞く。

 売買される個人情報の価値

まず、売買される個人情報について考えてみよう。売買される個人情報には、いくつかのランクがあり、まず、単なるメールアドレスだけの場合。これはほとんど無価値と呼ばれており、数十万レコード有ったとしても、その価値は高くても数千円止まり。下手をすると、数百円ってこともある。これは、そのメールアドレスが本当に現在も使われているか(流通しているか)が確定していないためだ。もし、これが、すべて使われている場合は、10倍程度の価値がつく。ただし、本当にすべてのメールアドレスが使われていれば・・・の話だ。また、それがフリーのメールアドレスなのか、それとも、企業が使っているメールアドレスかによっても、価値が変わる。もし、企業が使っているメールアドレスの場合、おいそれと変更するわけにいかず、使い続ける可能性が高い。逆に、フリーメールの場合は、簡単に変えられるため、使い続ける可能性が低く、大量に迷惑メールを受信した場合は、そのメールアドレスを捨てる可能性が十分に有る。そのため、企業とフリーのメールアドレスでは、その価値が大きく異なる。ただし、メールアドレスだけでは、先ほども書いた通り、あまり価値はなく、それ以外にヒモ付けされたものがあれば、その価値はぐっと上がる。

先ほど、企業のメールアドレスの場合は、価値がフリーアドレスに比べ、高いと書いたが、これは変更されない事と、もうひとつ理由がある。それは、その企業に属していることがほぼ確定しているためだ。.co.jp の場合、その企業に属しているもしくは、何らかの関係者であるため、個人を特定しやすい。たとえば、katayama@appirits.com といった場合、「アピリッツに勤めている片山」さんとわかるわけだ。このように、個人を特定する事ができる情報はきわめて価値が高い。これに、クレジットカード情報と性別、電話番号が含まれていれば、1件あたり10円前後の価値があるかもしれない。1件10円と聞くと、あまり価値がないように感じられるかもしれないが、数万件集めれば、ちょっとした小遣い稼ぎになる。

先ほども述べたように、個人を特定する情報は価値が高いが、逆に個人を特定できない情報はあまり価値がないと書いた。最近では、買い取り時には金銭が発生しないケースが有る。このケースでは、どんな状態(情報)で有っても、個人情報を渡す際には一切の金銭授受が発生しない。では、どのように行うかというと、アフィリエイト型と呼ばれる方法だ。この方法では、先ほどのように、1件いくらといった相場は存在しない。たとえば、Aさんの情報を含んだものを、アピリッツ商事に私が渡したとする。この時点では、金銭授受が発生しない。Aさんがアピリッツ商事で100万円の買い物をするとする、買い物額の25%である、25万円が私の懐に入る。Aさんが、アピリッツ商事で買い物をし続ける限り、延々と私の手元には、購入金額に応じ数%〜20%前後が振り込まれる。個人情報を渡した時点で金銭授受が発生しない分、売り逃げはできないが、システム上いくらの売り上げが有ったのかを確認することができ、そして、いくらの振り込みが有るのかを確認することができるため、個人情報の売り手にとって非常においしい仕組みになっている。仮に、渡した個人情報が10万件有ったとして、そのうち1%、つまり、1千人が、毎月1万円の買い物をした場合、何もしなくても、毎月25万円の小遣いだ。

とはいえ、10万件ものメールアドレスや個人情報を集めるのは、相当骨の折れる作業だ。しかも、目の前に有るような個人情報をわしづかみにして、売り払うと、某証券会社のような状態になりかねない。しかも、売却額よりも損害賠償額の方が、はるかに大きい状況では、割に合わない。そこで、個人情報を集めてる人に聞いた、さまざまな方法を書いて見よう。

 マルウェアを用いる方法

世の中には、マルウェアを自分好みにアレンジしてくれるサイトがいくつかある。マルウェアに感染させ、中に含まれるさまざまな情報を、根こそぎ奪ったり、キーロガーを仕掛けて、さまざまな情報を抜く方法も有る。特に、銀行や証券会社のIDとパスワード、名前セットは非常に高く売買されている。

 メールサーバ の仕様上の問題を突く

メールサーバには、受け入れられるメールアドレスをメール本文を送信する前に送信者に返答する仕様が有る。辞書を使って、大量に存在していると思われるユーザを片っ端に調べることで、その企業やISPに所属しているメールアドレスを大量にかつ確実に入手することができる。

 SQLインジェクションを用いる

最近、中国や韓国から、日本のネットショップが狙われている方法だ。それも、かなり自動化されており、ほぼ100%人が介在していない。最も今用いられている方法の一つだ。

 同業他社の情報をいただく

こういった情報を収集している企業は数多く存在している。そういった企業のサイトには、セキュリティ対策が施されておらず、簡単にgoogle や yahoo などの検索エンジンに引っかかるケースがある。こういった情報をもとに、効率良く情報を取得する方法も有る。

大量の個人情報を集めたら、それを、適切なフォーマットに並び替え、CD-RやUSBメモリなどに入れて、顧客に渡す。メールを用いても良いのだが、足が付いてしまう危険性があるため、フリーのwebメールで、多段串を経由するか、複数の国外踏み台を経由してのアクセスなど、よほど入念に対策を施した状態でなければ、メールで送信することは無い。

今回は、筆者が複数の関係者から聞いた話をまとめて書いた。個人情報がどのように売買されているのか、少しは興味を持ってくれただろうか。くれぐれも、加害者、被害者ともに、ブラックマーケットに関わることの無いように。といっても、被害者になってることすら、気づかないんだけどな。

ECサイト構築パッケージ「エレコマ」の初期設定@Ubuntu 10.10

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


よしだです。

前回の記事』では、エレコマのインストール手順を紹介しました。

今回はインストール後の初期設定について書いていきたいと思います。

 概要

エレコマのロゴ

今回はエレコマはインストール後に行う必要最低限な設定を紹介します。

主な設定は以下の3つになります。

 1. 管理者ユーザの登録

 2. ショップ情報の登録

 3. 商品情報の登録

それでは早速設定操作に移りましょう。

 1. 管理者ユーザの登録

エレコマに販売したい商品を登録するには、管理画面へアクセスする必要があります。

この管理画面にアクセスするためのユーザを管理者ユーザと呼びます。

エレコマインストール直後は、管理者ユーザが登録されていない状態なので、新しく登録します。

a. エレコマディレクトリへ移動

前回の記事でエレコマをインストールしたディレクトリに移動します。

% su - ec
ec% /usr/local/elecoma

b. 管理者ユーザ ID、パスワードの変更

管理者ユーザの ID とパスワードを任意の物に変更します。

デフォルトの ID とパスワードは admin、pass となっています。

ec% vim test/fixtures/admin_users.yml

c. 管理者ユーザの登録

下記のコマンドでデータベースに管理者ユーザの情報を登録します。

ec% rake db:fixtures:load FIXTURES=admin_users RAILS_ENV=production

d. 登録確認

登録できたことを確認するために、管理画面へのログイン画面から実際にログインします。

ログイン画面へは http://(サーバの IP アドレス)/admin からアクセスできます。

http://doruby.kbmj.com/hyoshida/files/elecoma_login.png

(ログイン画面です)

http://doruby.kbmj.com/hyoshida/files/elecoma_admin.png

(正常にログインできると管理画面にアクセスできます)

無事にログインできれば次のステップに進みます。

 2. ショップ情報の登録

商品を登録する前に、ショップ情報を入力しておきます。

ショップ情報が入力されていないと一部のページが機能しなくなるので注意が必要です。

ショップ情報を登録するには、管理画面のメニューから「店舗情報」⇒「SHOPマスタ」と辿って下さい。

登録画面で社名や住所、メールアドレスなどの必要な情報を入力します。

http://doruby.kbmj.com/hyoshida/files/elecoma_admin_shop.png

(ショップ情報を入力して登録します)

 3. 商品情報の登録

いよいよ商品情報の登録に移ります。

エレコマでは、[商品]+[規格]の組み合わせをひとつの商品情報として扱っています。

  • ◎[商品]には、商品名や画像、紹介文が関連づけることができます。
  • ◎[規格]には、たとえば同名商品の「色違い」を赤、青、緑の分類として関連づけることができます。

まず[規格]の登録方法から紹介します。

a. [規格]の登録

規格登録画面は「商品管理」⇒「規格登録」からアクセスすることができます。

ここでは例として、色違いの商品を表現するための規格と分類を登録していきます。

  1. 規格名に「色」入力して登録します。
  2. 登録した規格と同行にある「分類登録」リンクへ飛びます。
  3. 規格分類名にそれぞれ「赤」「青」「緑」と入力した3つの分類を登録します。

これで[規格]の登録は完了です。

b. [商品]の登録

商品登録画面は「商品管理」⇒「商品登録」からアクセスすることができます。

ここから商品名や画像、紹介文などを順番に入力していきます。

すべて入力し終えたら登録を済ませます。

c. [規格]+[商品]を組み合わせる

最後に先ほど登録した[規格]と[商品]を組み合わせて、ひとつの商品情報に仕上げます。

  1. 「商品管理」⇒「商品マスタ管理」から先ほど登録した商品を探します。
  2. 対象商品の行にある「規格」リンクにアクセスします。
  3. 赤、青、緑の規格のうち、有効にしたい規格にチェックを入れ、商品コードや価格を入力します。

あとはこれを登録するだけで商品情報が完成します。

できあがった商品は、「商品マスタ管理」の「確認」リンクから販売サイト視点で確認することができます。

 最後に

前回と今回で、エレコマのインストールから初期設定までを簡単に紹介しました。

説明が荒削りになっている部分もあるかとは思いますが、少しでも参考になれば幸いです。

一緒に始めようSencha Touch 2.0 入門編: 第1回 Sencha Touchを導入しよう

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

はじめまして、2012年新卒として入社致しました、だーますと申します。どうぞよろしくお願い致します。

今回はスマートフォンアプリのような操作性を持つWebアプリ開発フレームワークである”Sencha Touch 2.0″について解説させていただきます。

 Sencha Touchって何?

Sencha Touchとは、米国のSencha社が開発した、HTML5ベースのWebアプリ開発フレームワークです。

具体的な特徴

・スマートフォンやタブレットのWebブラウザで動く、ネイティブアプリのようなアプリを作れる!・iOS、Androidのどちらでも動作する!・HTML5って書いてはあるけど、JavaScriptさえわかれば開発できる!・AjaxやJSONPリクエストもバッチリ送れる!・無料で利用でき、しかも商用もOK!

対応OS

・iOS 4.0以上 (iPhone、iPod touch、iPad)

・Android 2.2以上

・BlackBerry

・テスト用:WebKitブラウザ (Chrome、Safari)

Windows Phoneや、WebKitでないブラウザ(IEやFirefox、Opera等)では使えません。

どんなアプリが作れるの?

Sencha社公式のデモアプリ集採用例集をご覧になると良いかと思います。(注:WebKitブラウザで見てください)

ここにあるアプリ、全部JavaScriptで書かれています。すごいですよね!

 Sencha Touch 2.0を入手する

それでは早速、Sencha Touch 2.0のライブラリを入手してみましょう。

  1. Sencha Touch 2.0のダウンロードページに飛びます
  2. Open Source Version(GPLv3ライセンス)かFree Commercial Version(商用版・独自ライセンス)のどちらかを選び、ダウンロードします。本稿執筆時点でのバージョンは2.0.1.1です。
  3. 落ちてきたZIPファイルを展開します

これでOKです。

開発環境はどうするの?

エディタ

JavaScriptが書ければなんでもOKです。私はMacでEclipseにAptana Studioを入れて使っています。

ブラウザ

PC上で動作確認をするならば、WebKitブラウザーを用意してください。

デベロッパーツールを画面横分割して使えるChromeがおすすめです。

少し前まではSafariの方がSencha Touchの動作がなめらかでしたが、最近はChromeも追いついて来ました。

Webサーバー

スマートフォンやタブレットから動作確認するなら、PC上にWebサーバーを立てておくと楽でしょう。

Mac OS Xで、有線でネットワークに接続しているなら、Web共有とAirMacでのインターネット共有を併用すれば簡単にできます。

[2012/11/13追記]

OS Xの最新版Mountain Lionでは、システム環境設定からWeb共有の設定ができなくなっています。

しかし、機能が消滅したわけではなく、以下のサイト等を参考に手動で設定可能です。

うまでしか Blog: Mountain LionにおけるWeb共有の消滅と403 Forbiddenの解決策

 とりあえず触ってみよう!

ライブラリーを入手したら、早速ソースコードを書いてみましょう。

適当なところにフォルダを作って、そこに先ほど展開したSencha Touchのフォルダごと入れてください(本稿ではsencha-touch-2.0.1.1 とします)。

index.html

作ったフォルダにindex.htmlというファイルを作り、次のように記述してください:

<!DOCTYPE html>
<html>
    <head>
        
        <title>Sencha Touch App</title>
        <link rel="stylesheet" type="text/css" href="sencha-touch-2.0.1.1/resources/css/sencha-touch.css" />
        <script type="text/javascript" src="sencha-touch-2.0.1.1/sencha-touch-all-debug.js"></script>
        <script type="text/javascript" src="app.js"></script>
    </head>
    <body></body>
</html>

“sencha-touch.css”は、UIのデザインを指定したスタイルシートです。”sencha-touch-all-debug.js”が、Sencha Touchのライブラリです。そして”app.js”が我々が作ろうとしているアプリの本体で、これから記述します。

bodyタグの中身は、何も書かないでください。bodyの中身は、ライブラリによってすべて動的に生成されます。

app.js

同じフォルダにapp.jsというファイルを作り、次のようにしてみましょう:

Ext.application({   
    launch: function() {
        Ext.Viewport.add({
            xtype: 'panel',
            items: [
            {
                xtype: 'label',
                html: 'Hello,world!'
            }]
        });
    }
});

これをPCのブラウザで確認してみましょう。以下のようなページができるはずです。

上にいくつかメソッド・関数が出てきていますが、

  • Ext.application(): アプリの大元締め
  • launch: function(): アプリが実行されて一番最初に呼び出される関数
  • Ext.Viewport.add(): 画面にUIを追加するメソッド

であると思っておいてください。

Sencha TouchのUIはオブジェクトの形式で記述する

上記のExt.Viewport.addの中身を見てみてください:

{
    xtype: 'panel',
     items: [
    {
        xtype: 'label',
        html: 'Hello,world!'
    }]
}

となっていますね。この部分でUIを定義しています。まるでJSON形式みたいな記法ですね。Sencha Touchではこの記述方法をたくさん扱いますが、Sencha Touchを修得する上で覚えられると思います。カンマやコロンを忘れたりするとちゃんと動きませんので、忘れないように。

具体的に見てみましょう。xtype: ‘panel’ となっているのは、panel形式のUIコンポーネントを配置する、という意味です。そしてこの panel コンポーネントには、次の items に記述することでサブコンポーネントを追加できます。

items の中には xtype: ‘label’ が入っており、その次の行の html: ‘Hello, world!’ がラベルとして表示する中身です。(html なのでタグによる記述も可能です)

サブコンポーネントをちょっと増やして遊んでみましょう。app.jsを以下のように書き換えてみてください:

Ext.application({
    launch: function() {
        Ext.Viewport.add({
            xtype: 'panel',
            items: [
            {
                xtype: 'label',
                html: 'Hello,world!'
            },{
                xtype: 'button',
                text: 'ボタンです'
            },{
                xtype: 'textfield',
                placeHolder: 'テキストボックスです'
            }]
        });
    }
});

実行結果です:

キャプチャプラグインの都合上ボタンの右端が切れてしまいましたが、ちゃんと表示はされるはずです。他にも様々なコンポーネントがあります。これらについては、次回以降説明することにします。

 ナビゲーション (Navigation View)

もうちょっとiOSライクなUIを見てみたいですね。app.jsを次のようにしましょう。階層が増え始めましたが、Sencha Touchではよくあることなので、慣れてください:

Ext.application({
    launch: function() {
        Ext.Viewport.add({
            xtype: 'navigationview',
            items: [{
                xtype: 'panel',
                title: 'First View',    // ナビゲーションバーに表示する文字列
                items : [
                {
                    xtype: 'label',
                    html: 'This is First View'
                },{
                    xtype: 'button',
                    text: 'Push Next View',
                   
                    // ボタンにイベントを設定
                    handler: function() {

                        // このコンポーネントの2つ上の navigationview で定義されたメソッド
                        this.parent.parent.push({
                            xtype: 'panel',
                            title: 'Second View',
                            items: [{
                                xtype: 'label',
                                html: 'This is Second View' // 画面遷移後にナビゲーションバーに表示する文字列
                            }]
                        });
                    }
                }]
            }]
        });
    }
});

これを実行すると次の画面になります:

ここにある、”Push Next View”というボタンを押すと…?!

アニメーションして上のような画面が現れます!もちろん、”Back”をタップすると、前の画面に戻れます。

これがiOSアプリでよく見られる、ナビゲーションビューというものです!

上記のソースコードではまず、一番上のコンポーネントに xtype: ‘navigationview’ を設定しています。そこで最初に表示するコンポーネント xtype: ‘panel’ を items に記述しています。その panel の中には、ナビゲーションビューがそのコンポーネントを表示している際に画面上部のバーに表示する文字列を表す title と、さらにそのサブコンポーネントとして items 内に xtype: ‘label’ と xtype: ‘button’を記述しています。

この button に注目してください。handler: function() というのがあります。ここで、そのボタンが押された時に実行する処理を記述しています。これでボタンがただの飾りから、ちゃんと動作するコンポーネントに進化しました。

さらにその handler の処理ですが、this.parent.parent.push というメソッドがあります。これは、このボタンの二つ上のコンポーネントである navigationview に定義されている push というメソッドを指しています。これはナビゲーションビューで新しい画面を呼び出すメソッドです。今回はこの中に直接新しく xtype: ‘panel’ を記述しています。”Back”ボタンは自動で生成されるので、こちらで特に記述する必要はありません。

このように、JavaScript を記述するだけで、iOSライクなインターフェースを実現することができるのです!すばらしいですね!

これらのコンポーネントは、動的に生成して表示することも可能です。これは、今後説明させていただいます。

今回はごく簡単な説明のみさせていただきましたが、様々なUIコンポーネントを組み合わせることにより、リッチなUIを持ったスマートフォン向けWebアプリケーションを作ることができるようになるのです。とても素晴らしいですね!

 次回は

様々なUIコンポーネント、そしてそれらをクラスとして定義する方法について説明する予定です。どうぞお楽しみに!

意外に知らない人が多い!Skypeを使うときに気をつけたい話(1) ~オフラインが招くトラブル~

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

 2012年新卒で入社いたしました、ずんです。僭越ながら今回初めてDoRubyにて記事を執筆致します。よろしくお願いします。今回はSkypeを使っていると誰でも必ず遭遇したことがあるであろうトラブルについて。check it out!!

 モバイル・インターネットの急速な発展のおかげで最近はPCだけでなくスマートフォンでも使えるようになり、より手軽に、無料で、高音質・高画質で、電話やテレビ電話に代わるコミュニケーションツールとなったSkype。

 最近ではビジネスの現場でも使われるようになった。

 社内での連絡を内線やメールを使わずに、Skypeで全て済ますことで組織運営の簡略化を図る例も珍しくない。

 しかし便利な反面、サーバが存在せずP2PでメッセージをやりとりするSkype特有の性質を知っておかないと大変なミスを引き起こすことになるかも……。

 意外に誰も気にしない問題;相手がオフラインの時に送信されたメッセージはいつ相手に届くのか

 パソコンなり、スマートフォンなりでSkypeを使ったことがある読者諸兄は多いと思う。そんな読者諸兄は一度はこういう怪奇現象に巻き込まれた事があるだろう。

※ここから、とある事の報告を頼まれて、それをSkypeのメッセージを使って送ろうとしているルークと、

仕事を頼み、報告を受け取ろうとしている上司のオビワンが居るとしよう*1

 金曜日、オビワンは仕事が落ち着いており、家族と週末を使って旅行にいくため有給休暇を取って会社に居ない。

 そこで、ルークはオビワンからの仕事を一手に引き受け、月曜日に結果をなんらかの形で報告するように指示されている。

 しかし、ルークは月曜日に有給休暇を申請しているので、金曜日に退社する時までにオビワンに何らかの方法で仕事の結果についてメッセージを残しておかなくてはならない。

状況まとめ
  1. ルーク(部下)は金曜日に出勤しているが、月曜日は居ない。
  2. オビワン(上司)は金曜日は居ないが、月曜日に出勤する。
  3. オビワンは、ルークに対して仕事の報告をメールでもSkypeでもなんでもいいので、なんらかの形で月曜日朝に出勤したときに分かるように指示している。
  4. オフィスが多くの部屋に分かれている上、在宅勤務のスタッフも居るため、普段の業務中のコミュニケーションはSkypeのテキストチャットを用いている。
  5. 2人のSkypeのアカウントは仕事用に作ったため、出勤時以外はSkypeにログインしない。

 さて、滞り無くタスクを終え、オビワンに報告を書いて退社しようとするルーク。

 普段の業務でもSkypeで、仕事の指示・報告・連絡・相談からファイルのやりとりまでやっているため、普段通りSkypeのテキストチャットでオビワン宛に報告を書いて退社した。

 そして火曜日。久々の3連休を充実して過ごし元気一杯で出勤したルーク。

 しかし彼は出勤直後にオビワンから怒られてしまう。

「報告が、届いていないじゃないか。月曜に来たときに分かるように報告を残せと言ったはずだ!」

 しかし、ルークは間違いなく金曜の退勤時にオビワンに対しSkypeで報告を投げたはずである。だが、月曜日にオビワンが確認したところそれが届いていなかった。

 彼曰く、火曜日の朝になって、たった今届いたというのだ。何故だろうか。

 なぜ、届かなかったか

 さて、間違いなくルークはオビワンに報告を送ったのは間違いない。*2

 しかし一方で、それがオビワンに対して月曜日に届いていなかった。

 その理由は、Skype特有の性質にある。Skypeでは相手がオフライン時に送られたメッセージはどのように相手に届けられるのだろうか。

 Skypeは、メッセージを中継するサーバが存在しない

 Skypeにはメッセージを中継するサーバが存在しない。そう、存在しないのだ。*3

 一般的なインスタントメッセンジャーのように、サーバ&クライアントの従属関係があって、メッセージを中継するサーバが存在している場合は、

相手がオフラインの時はメッセンジャーのサーバ側でそれを一旦預かって貰い、相手がオンラインになった瞬間、

「送り側がオンラインか否かにかかわらず」オフラインメッセージという形でメッセージが送信される。

 SkypeはP2Pでメッセージや音声、ビデオをやりとりしているためそれが無い。

 なので、メッセージが送受信されるタイミングは「お互いがSkypeを起動している」状態でないとつながらないのだ。(P2Pについては次回)

 「仕組み」を簡単に書くとこういうことではないだろうか。

ルークが、オフラインのオビワンにメッセージを送る。

 ↓

オビワンはオフラインであるため、メッセージは送信されずにルークのPCのローカルにメッセージが一旦保存される。

 ↓

ルークがPCの電源を入れ、Skypeを起動している間、オビワンがPCの電源を入れ、Skypeを起動すると、それをルークのPCのSkypeが検知して、ローカルに保存したメッセージを送信する。

 ↓

オビワンがメッセージを受信する。

 改善方法

  1. もし、グループでSkypeを使っているなら、メッセージ中継用のアカウントをグループ内に建てる。
    • それを常にオンライン状態に維持する。
    • グループ内で、その中継用アカウントが全ての発言ログを記録するため、自分がオフライン中のグループ内での他人の発言は、その中継用アカウントから取ってこれる。
  2. 相手がオフラインの時はメールで送る。
    • なんだかんだ言って、メールは必須ですよね。
  3. 同じ社内でやり取りしているなら、文書にして紙で置いておく。
    • 時にはアナログに。

 ちなみに、上記のようなトラブルは割と頻繁にある話で、僕の友人でも

「まさに同じ現象があった!でもなんで!?どういうことなの!?すごい大事な事を書いたのにすごい遅れて届いた!!」と泣く方がそれはもう多く……。

 つまり何が言いたいかというと、インターネットがだいぶ発展してきて、昔はかなり手間がかかっていたことを、クリック1つで簡単に、誰でも、しかも無料でできる世の中になりました。

 しかし前提としてまず自分の使うツールの性質をよく理解しておきましょうね……という話でした。

 次回予告

技術的な話~Skypeはどんな通信をしているのか?~

 次回は、今回の話を踏まえて

「じゃあ、Skypeでは起動してからどのような通信を行なっているか」という事を、「プロトコル」と「P2P」の話を交えつつなるべくわかりやすく書いてみようと思います。

 普段皆様何気なくSkypeを使っていると思いますが、きっと気になったことがあるかも?

 少しでもweb技術に詳しい方なら「P2P」という単語を聞いたことはあるとは思いますが、じゃあ実際SkypeにおいてP2Pがどのように使われているかは意外に知らないものです。

 ならば折角だし一緒に詳しく掘り下げてみましょう!

 大丈夫。TCPとかUDPとか聞いたことない人でも解るように書きますよ!

 DoRubyはどちらかというと技術者向けの記事が多いですが、僕はちょっと趣向を変えて、

IT技術に詳しくない人でもわかりやすく、できれば普段何気なく使っているIT関連の物の仕組みについて関心を持ってもらえるような記事を書いてみたいと思います。*4

 お便り

 単なる感想や「こんな事聞きたい・知りたい」などのお便りをお待ちしております。次の記事の種になるかもしれません。

 種にならなくとも1通でも届くと中の人が喜びます。次の記事を書くモチベーションにつながります。

※返信は致しかねます。また、頂いたメールやコメントは記事内で引用させていただく事があります。

mailto:zun.doruby@gmail.com

*1: この記事をアップした翌朝、何人かの同期に「なぜルークとオビワンなのか」と聞かれたが、単にスター・ウォーズが好きなだけである。

*2: 「普通こういうモノはメールか文書で残すものじゃないのか」というツッコミは、申し訳ないがこらえていただきたい。

*3: 正直、無いというと語弊がある。実際は「スーパーノード」と呼ばれる、Skypeを起動している端末たちの中で安定している、いわば「選ばれし端末」が色々と中継点を担っているが、調べながら執筆しているのと、詳しく書くと次のネタが無くなるので、これは次回のおはなし。

*4: 次回の掲載は、来週月曜日6月18日ごろを予定しています。ただ、中の人の状況によって1週間ズレる場合もあります。

ECサイト構築パッケージ「エレコマ」のインストール手順@Ubuntu 10.10

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

はじめまして、よしだです。 DoRuby 初投稿の今回は、最近になって SourceForge.jp から GitHub にこっそり移住したECサイト構築パッケージ「エレコマ」オープンソース版のインストール手順を紹介したい思います。

 概要

通販サイトを作りたい! という要望を簡単に実現してくれる EC サイト構築パッケージ。エレコマは日本初の Ruby on Rails を利用した EC サイト構築パッケージで、オープンソースであるため無料で利用することができます。

詳しい機能については『エレコマ公式サイト』を参照してください。また、実際の動作を確認できるデモサイトもあります。

今回はエレコマのインストール手順を紹介したいと思います。

 環境

OS と DB は基本的には何でも構いません。

ここでは OS に Ubuntu 10.10 を利用することにします。

(ちなみに、CentOS へのインストール手順は GitHub 上の README に書かれています)

  • ◇ OS: Ubuntu 10.10
  • ◇ DB: PostgreSQL
  • ◇ WEB: Apache
  • ◇ APP: Passenger
  • ◇ Ruby: 1.8.7
  • ◇ Ruby on Rails: 2.3.5
  • ◇ RubyGems: 1.3.5

上記が今回用意する環境になります。

 インストール手順

早速インストールしていきます。

ここでは Ubuntu 10.10 がクリーンインストールされていることを前提とします。

0. パッケージリストのアップデート(必ず行ってください!)

手始めに Ubuntu のパッケージリストを最新のものにします。

Ubuntu 10.10 の場合、初期のパッケージリストでは killapache などの脆弱性を取り込むことになってしまいます(killapache については、ととろさんの記事『apache の脆弱性』が詳しいです)。

そこで、各ソフトウェアをインストールする前にパッケージリストの更新を行っておくと安心です。

$ sudo su -
(パスワードを入力し、管理者権限に切り替えます)
# apt-get update

1. Ruby のインストール

Ruby とその他の必要なソフトウェアをインストールします。

特定バージョンの Ruby を利用するためにソースからコンパイルします。

# apt-get -y install gcc zlib1g-dev libssl-dev ncurses-dev libreadline-dev
# wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p174.tar.gz
# tar zxf ruby-1.8.7-p174.tar.gz
# cd ruby-1.8.7-p174
# ./configure
# make
# make install
# cd

2. RubyGems のインストール

RubyGems をインストールします。

# wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz
# tar zxf rubygems-1.3.5.tgz
# cd rubygems-1.3.5
# ruby setup.rb
# cd

3. ImageMagick のインストール

エレコマでは商品画像を扱うためのライブラリとして ImageMagick を利用します。

CentOS 向けのインストール手順では ImageMagick へのリンクがすでに切れているようです。

リンクが切れている場合は、適宜 URL を変更して実行してください。

# apt-get -y install libjpeg-dev libpng-dev libgd2-xpm-dev libfreetype6-dev
# apt-get -y install libperl-dev
# wget http://ftp.nl.netbsd.org/pub/pub/ImageMagick/ImageMagick-6.5.8-4.tar.gz
# tar zxf ImageMagick-6.5.8-4.tar.gz
# cd ImageMagick-6.5.8-4
# ./configure
# make
# make install
# cd

4. Rmagick のインストール

Rmagick は ImageMagick を Rails から扱うための Gem です。

# gem install rmagick -v 2.12.2

5. その他の依存 Gem のインストール

エレコマの各機能に必要な Gem をインストールします。

確実な動作を保障するためにバージョンを指定してインストールします。

# gem install rails -v 2.3.5
# gem install gettext -v 2.1.0
# gem install gruff -v 0.3.6
# wget http://www.artonx.org/data/lhalib/lhalib-0.8.1.gem
# gem install lhalib-0.8.1.gem
# gem install webmock -v 1.3.4
# gem install thoughtbot-factory_girl -v 1.2.2 --source http://gems.github.com
# gem install json
# gem install daemons

6. PostgreSQL のインストール

PostgreSQL 本体と Rails 用の Gem をインストールします。

# apt-get -y install postgresql libpq-dev
# gem install postgres

7. ユーザの作成

エレコマを実行するユーザを作成します。

パスワードも適当に設定しておくと良いかもしれません。

# useradd -m ec
# passwd ec
Enter new UNIX password: elephant
Retype new UNIX password: elephant

8. Git のインストール

GitHub からエレコマをダウンロードするにあたって Git が必要になるので、これをインストールします。

# apt-get -y install git-core

9. エレコマのダウンロード

いよいよエレコマのインストールに入ります。

まずは GitHub からエレコマのパッケージをダウンロードします。

# cd /usr/local
# git clone git://github.com/elecoma/elecoma.git
# chown -R ec:ec /usr/local/elecoma

10. PostgreSQL のセットアップ

エレコマ用のデータベースを用意します。

ここでは Development, Test, Production という Rails 環境に合わせて3つのデータベースを作成します。

# /etc/init.d/postgresql start
# su - postgres
postgres$ psql template1
postgres=# alter user postgres with password 'hoge';
(パスワードを適当に設定しておきます)
postgres=# q\
postgres$ createuser ec
Shall the new role be a superuser? (y/n) y
postgres$ psql template1
postgres=# alter user ec with password 'elephant';
(このパスワードは手順 11. で必要になるので覚えておきましょう)
postgres=# \q
postgres$ createdb --owner=ec ec_dev
CREATE DATABASE
postgres$ createdb --owner=ec ec_test
CREATE DATABASE
postgres$ createdb --owner=ec ec
CREATE DATABASE
postgres$ psql -l
        List of databases
   Name    |  Owner   | Encoding 
-----------+----------+----------
 ec        | ec       | UTF8
 ec_dev    | ec       | UTF8
 ec_test   | ec       | UTF8
 postgres  | postgres | UTF8
 template0 | postgres | UTF8
 template1 | postgres | UTF8
(6 rows)

11. エレコマのセットアップ

エレコマを動作させるための最低限の設定を行います。

# su - ec
ec$ cd /usr/local/elecoma/config
ec$ cp database.example.yml database.yml
ec$ vim database.yml
(データベースへのアクセスに必要なユーザ名を ec、パスワードを elephant といった具合に設定します)
ec$ diff database.example.yml database.yml
3,4c3,4
<   username: postgres
<   password: 
---
>   username: ec
>   password: elephant
ec$ cd environments
ec$ vim production.rb
(環境に合わせてメールサーバの設定を変更します)

12. プラグインのインストール

エレコマに必要な Rails プラグインをインストールします。

一部古いバージョンのプラグインを利用するために、変則的なインストール方法を取っているところがあるので注意してください。

ec$ cd /usr/local/elecoma
ec$ ruby script/plugin install git://github.com/realityforge/rails-active-form.git
ec$ ruby script/plugin install git://github.com/rails/acts_as_list.git
ec$ ruby script/plugin install git://github.com/technoweenie/acts_as_paranoid.git
ec$ ruby script/plugin install git://github.com/rails/acts_as_tree.git
ec$ ruby script/plugin install http://topfunky.net/svn/plugins/ar_fixtures/
ec$ ruby script/plugin install git://github.com/jpmobile/jpmobile.git -r 'tag 0.0.8'
ec$ ruby script/plugin install http://taslam-plugins.googlecode.com/svn/trunk/jpmobile_emoticon_filter/
ec$ cd vendor/plugins
ec$ git clone git://github.com/tmtysk/mbmail.git mbmail
ec$ cd mbmail
ec$ git checkout 654ce3ec2dfa10ac3b05cd9354eb84456d206a6d
ec$ rm -fr lib/jpmobile
ec$ rm -fr .git
ec$ cd ../../..
ec$ ruby script/plugin install git://github.com/jamesgolick/resource_controller.git
ec$ cd vendor/plugins/
ec$ git clone  git://github.com/mislav/will_paginate.git
ec$ cd will_paginate/
ec$ git checkout origin/2-3-stable
ec$ cd ../../..
ec$ ruby script/plugin install git://github.com/kakutani/yaml_waml.git
ec$ ruby script/plugin install git://github.com/rails/ssl_requirement.git
ec$ ruby script/plugin install git://github.com/DianthuDia/double_submit_protection.git
ec$ ruby script/plugin install git://github.com/champierre/image_submit_tag_ext.git
ec$ ruby script/plugin install git://github.com/dchelimsky/rspec-rails.git -r 'tag 1.2.9'
ec$ ruby script/plugin install git://github.com/dchelimsky/rspec.git -r 'tag 1.2.9'

13. データベースのセットアップ

データベースにエレコマ用のテーブルとカラムを用意します。

ec$ cd /usr/local/elecoma
ec$ rake db:migrate RAILS_ENV=production

14. Apache2 と Passenger のインストール

今回はウェブサーバに Apache2 を、アプリケーションサーバには Passenger を採用しました。

この他の、たとえば nginx + Unicorn などの組み合わせでも導入は可能です。

# apt-get -y install apache2
# apt-get -y install build-essential libcurl4-openssl-dev
# gem install passenger
# passenger-install-apache2-module

15. Apache2 の設定

アプリケーションサーバとの連携を行うための設定を施します。

バージョンの違いや、エレコマのインストール先ディレクトリによって記述に違いが出るので注意してください。

# cat > /etc/apache2/httpd.conf
LoadModule passenger_module /usr/local/lib/ruby/gems/1.8/gems/passenger-3.0.12/ext/apache2/mod_passenger.so
PassengerRoot /usr/local/lib/ruby/gems/1.8/gems/passenger-3.0.12
PassengerRuby /usr/local/bin/ruby

# cat > /etc/apache2/conf.d/ec.conf

  ServerName ec.example.com
  DocumentRoot /usr/local/elecoma/public
  RailsEnv production
  
    AllowOverride all
    Options -MultiViews
  

16. Apache2 の再起動

設定を反映するために Apache2 を再起動します。

もしかしたら reload だけでも良いかもしれませんが試してません。

# /etc/init.d/apache2 restart

 インストール完了

お疲れ様でした!

以上の手順をもって、エレコマのインストールは完了です。

(ブラウザからアクセスすると、エレコマのデモサイトが閲覧できます)

次回はインストール後の初期設定について書きます。

オンラインゲームを有利にしてみよう!

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

今回は、オンラインゲームで自分を有利にするチート行為に迫ってみよう

一般的に、チートはゲームをプレイするうえで、自分に有利なように働きかけるパッチやアプリケーションによって行われる。オンラインゲームではないゲームの場合、保存されているセーブデータを書き換えることで、自分のレベルを上げたり、アイテムを増やしたりすることができる。オンラインゲームの場合、そう簡単に行うことはできない。前回説明したように、チートを管理しているゲートウェイが存在しており、送られるパケットの整合性をチェックしており、そう簡単に、通過することはできない。

そもそも、ネットゲーの場合、ユーザのPCにインストールされているアプリは、あくまでもクライアントであり、実際にプレイを行っているのは、接続されたサーバ上になる。このため、どんなにPC上のクライアントを変更しようとも、その過程をチェックしているゲートウェイをだますことができなれば、チート行為は成立しない。

このゲートウェイは、ネットワークセキュリティにおける、IDSやIPSと同等のことを行っていると考えれば良いだろう。通常、やりとりされる通信の内容から、不正を見抜く方法が用いられる。この場合、何らかの方法を用いてチェックサムをチート時も書き換える必要がある。

 では、具体的にその手法についてみていこう。

チート行為を行うには、大きく分けて2種類の方法がある。1つはメモリを書き換える方法だ。先ほど書いたように、ゲームのデータそのものは、サーバ側に蓄積されている従って、これを直接書き換えることはできない。が、ゲームの仕様上、一時的にクライアントアプリのメモリ空間に持つことがある。これは、高速な回線で通信していれば問題ないが、低速な回線(100kbps以下)では、戦闘中のデータを的確に更新することが出来ず、サーバ内での戦闘とユーザの見ている戦闘が同期しないケースが出るためである。クライアントに保持される内容には激しい戦闘情報やアイテム交換など様々な要素が有り、戦闘が始まる前と終わるときに、サーバとクライアント間でデータが交換される。複数のユーザで的を倒す際も、同様の行為が行われるが、この場合はユーザが敵に対して行った攻撃情報がサーバを介して各ユーザに敵の状態と共に提供される。

このような状況で、注目すべきは、クライアントに保持されるメモリの内容だ。

このメモリの内容は、定期的にチェックされ、改ざんできないようにチェックされている。このチェックは、ユーザの目からすると常に行われているように見えるが、リアルタイムで行われているわけではなく、早い状態だと数μs程度、遅くとも数ms程度で行われている。当然として、この速度はゲーム全体の速度からすれば、かなり遅い「割り込み」であり、これ以外にも様々な「割り込み」が存在する。

 今回は、この割り込みについて注目する。

先ほども述べたように、メモリ内の改ざんチェックの割り込みは、ゲーム全体からすると、かなり遅い部類に入る。割り込みタイミングさえわかれば、次の行為を行える。

1.アイテムや経験値、金などが含まれるメモリアエリアを特定する

2.割り込みタイミングを定点観測し、どの時点での割り込みが「もっとも頻繁に行われるか」を確認する

このうち、2.が重要となるので、何度もリトライを繰り返した方が良いだろう。

1は、ゲームによって異なるが、多くの場合は、メモリの相対アドレスは決まっており、そのメモリ内に、確実にアイテムなどの情報はまとまって置かれる。

 やり方はこうだ。

1のエリアを限定した状態で、1の内容を他のエリアに一度コピーする。

2の割り込みが入った直後に、内容を改ざんする。2の割り込みが入る直前に、コピーした元の内容を書き戻す。書き戻す際には、ゲームで進行した情報は忘れずに加える。

こうすることで、メモリ内部は書き換えられ、ゲーム進行は思いのまま、得られる金や経験値、レベルなどはウハウハである。

とはいえ、これを人間業で行うことは、とうてい無理。そこで、プログラムを書くわけだが、イメージ的にはバッファオーバーフローをしかける事に似ている。

メモリを直接書き換える場合は、「割り込み」の存在を必ず忘れないように!

 パケットを改ざんする方法

先ほどは「割り込み」との戦いであったが、今度は、ゲームサーバのチートチェッカとの戦いだ。

チートチェッカは、送られてくるパケットの内容が適切であるかをチェックしている。とはいえ、すべてのパケットの内容を一つ一つ確認しているわけではなく、これも割り込みを利用している。クライアントから送信するパケットを改ざんし、送信すればたちどころに「チート行為」と見抜かれてしまう。では、どのようにするかというと、、、

パケットを改ざんしたら、必ず「チェックサムと呼ばれる物も改ざんする。」チェックサムは、そのパケットが正しいかを確認している物であり、内容(数値上の内容)とそのチェックサムさえ一致すれば、チートチェッカは素通りさせてくれる「可能性がある」。あくまでも、可能性であることを忘れてはならない。

こういった行為は、あまり頻繁にやると、「垢バン」される事になりかねない。十分注意されたい。

安価なVPSを骨の髄までしゃぶり尽くそう!

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

最近、安価なVPS(Virtual Private Server)が大量に出回っているのは、読者も知っているだろう。このVPSを使うにあたり、様々な問題が出ていることを知っているだろうか。今回は、そうした、VPSの問題点やセキュリティ上の不備について考えてみたいと思う。

 国内のVPS について

まず、国内のVPS事情についてだ。国内には、様々な事業者がVPSを提供している。中には、月々わずか500円足らずで借りることのできるVPSすら存在する。また、VPSでは足らずに、クラウドサービスを利用しているユーザもいる。これらのVPSでは、ディスク容量やCPUの数、スレッド数、メモリサイズなどで、事細かにサービス品目が異なる。

では、実際にいくつかのサービスについてみてみよう。

まずは、先ほど示したワンコインVPSだ。中で稼働しているOSは、Centos 5.5 だ。このサービスでは、同一サーバ上に、数多くのユーザを利用していると推測され、非常に動作が重いのが特徴だ。そこで、処理能力を計測すべく、下記のようなコマンドを実行してみた。

何はともかく、ディスクへの書き込みが異様に重いと感じる。

time sudo yum update

real 6m15.104s

user 0m5.041s

sys 0m0.683s

同様の環境を、比較的高価な別のVPSに用意し、同じ time sudo yum update を実行した結果は、下記だ。このように、非常に安価なvpsは、サービスレベルに難があるように感じられる。

time sudo yum updat

real 1m23.131s

user 0m33.218s

sys 0m19.095s

 踏み台に対する考え方

さて、お次はこれらのvpsを利用していると、セキュリティ上の問題がどのように発生しているかをみてみよう。

まず、高速かつ、安定したvpsを設置している同一のセグメントから、大量のsshアタックがやってきた。

49.212.2.xxx (www20109u.xxxxx.ne.jp): 6110 times

49.212.47.xxx (www31424u.xxxxx.ne.jp): 59 times

49.212.97.xxx (www39397u.xxxxx.ne.jp): 1576 times

これらは、すべて同一の事業者が提供しているvpsからのssh atackだ。みてわかるとおり、その数たるや尋常な数字ではない。では、こうした攻撃がなぜ発生しているか?それについて、ひもといていこう。

まず、こうしたssh atack は、管理者が適切な管理をしていないから発生していることは言うまでもない。非常に安価であり、大量にドメインを抱えたり、情報を配信したとしても、誰からも文句を言われない。そう、利用者はレンタルサーバ屋である場合がある。その証拠に、ssh atack をしているIPアドレスにアクセスすると、レンタルサーバ屋の画面が表示されることがままある。次に、何も考えずに、単なるファイル置き場として、お気楽に考えている、素人が設置しているケースだ。この場合は、apache がデフォルト画面であることや、ssh へのアカウントログインで、root が有効であったり、デフォルトパスワードがそのまま有効であることからも、素人がお気楽に使っていると推測される。

こうしたことから、同一のネットワークから、ssh atack が繰り返し行われている状況を踏まえると、比較的簡単にサーバが踏まれてる(侵入されている)事が多いことに気づかされる。

これに対し、安価なワンコインVPSでは、外部からのssh atack によって、システム全体が高負荷になることを恐れ、vpsが提供されて間もない頃に、早々に、このssh atack の回避がシステムアップデートによって行われた。通常、sshのポートは、22/tcpであるが、これを異なるポートへアップデートしたのである。

皮肉なことに、システムが不安定、かつ、遅いワンコインが、現状以上に遅く、不安定になることを恐れ、ssh ポートを変更した。これに対し、システムが安定稼働している比較的高価なシステムにおいては、現在もなお、22/tcp で稼働し、同一ネットワークからssh atackの攻撃にさらされている現状がある。

 攻撃に遭わないための対策

では、これらの攻撃に遭わないためには、どうすれば良いのだろうか?

ひとつは、安価なvpsサービスが行ったように、port を変更すればよいように思われる。しかしながら、実際には変更されたportが決まっているのであれば、その決まったportに対して攻撃を行うように変更すれば、同様に攻撃が行われるため、単なるportの変更だけでは、対応のしようがない。そこで、単なるportの変更だけではなく、ssh の鍵交換を設定すれば、仮にport番号がばれようとも、関係なくなる。もし、大量にssh atackを受けて困っているのであれば、こうした鍵交換も一つの方法として、考えてみてはいかがだろうか。

では、こうした動きを、攻撃者視点で考えてみよう。

 攻撃者はこう考えているよ

攻撃者は、特定のvpsサービスにログインできれば、その中の情報を調べる。portの開放状態を調べ、traceroute などのネットワークのコマンドを用いて、ネットワークの状態を調べるだろう。ここから、ネットワークの全体像、少なくともセグメントを見極めることができる。こうして、次に行うのは、ssh の辞書アタックだ。同一セグメントに何台のvpsがあるかはわからないが、しつこく辞書アタックを繰り返して行えば、そのうちの1つや2つ、簡単に侵入できるだろう。当然として、ヒットしたパスワードとIDの組み合わせは、他の同一サービス上の、別セグメントに対しても有効であることが多い。

 まとめ

サーバ毎に管理者IDとパスワードを変更する事は重要なことだ。

快適で安価なvpsはそれだけ、周りに不慣れな管理者が居ることにも繋がる。vpsを借りるなら、相応の管理体制をとり、攻撃者から自分のvpsを確実に守れるようになって欲しい。

最近人気な記事