読者です 読者をやめる 読者になる 読者になる

divの閉じタグがないよ

映画/音楽/時々プログラミング

新サービスが間もなくローンチ

Vook noteがリリース

僕が手がけた新サービスが間もなくローンチになります。

vook.vc

映像業界のqiitaとも言えるサービスで映像制作者のための制作ノートです。 使用した機材や映像制作で困ったことを書き込み共有するサービスです。

2016年11月にリリースしたVook port(審査制)もみてください! f:id:deiki08:20170127172427p:plain Vook(ヴック)|映像に関わるすべての人のためのポートフォリオサイト

こちらは映像制作者のためのポートフォリオ共有サイトです!

映像制作者のためのサービスVook

Vook port, Vook noteともに同じドメインの中のサービスなので連携がうまく撮れているため映像制作者の方々が欲しい情報が手に入れやすくなっています!

どうぞ宜しくお願いします!

Capistrano備忘録

Capistranoデプロイでエラーがでた

デプロイ時にunicornをrestartするのだけれど、そこで何回も引っかかる。

sudo /etc/init.d/unicorn start

とすると

already unicorn started

と出る。

さらに、

sudo /etc/init.d/unicorn restart

sudo /etc/init.d/unicorn stop

とすると、

そのようなプロセスはありません

と出てくる。

いわゆるよくあるkillコマンドを叩いてもどうにもならないので、困っていました。 以下がcapistaranoエラーです。 ちなみにunicronは/init.d以下に自動起動スクリプトを書いていたので、さらに謎は深まるばかり….

00:26 unicorn:restart
      01 kill -s USR2 $(< /var/www/Vook/current/tmp/pids/unicorn.pid)
      01 kill:
      01 sending signal to 4082 failed
      01 :
      01 そのようなプロセスはありません
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as Daiki@52.198.21.134: kill exit status: 1
kill stdout: Nothing written
kill stderr: kill: sending signal to 4082 failed: そのようなプロセスはありません

SSHKit::Command::Failed: kill exit status: 1
kill stdout: Nothing written
kill stderr: kill: sending signal to 4082 failed: そのようなプロセスはありません
/Users/takayadaiki/projects/Vook/lib/capistrano/tasks/unicorn.rb:22:in `reload_unicorn'
/Users/takayadaiki/projects/Vook/lib/capistrano/tasks/unicorn.rb:51:in `block (3 levels) in <top (required)>'
Tasks: TOP => unicorn:restart
(See full trace by running task with --trace)
The deploy has failed with an error: Exception while executing as Daiki@52.198.21.134: kill exit status: 1
kill stdout: Nothing written
kill stderr: kill: sending signal to 4082 failed: そのようなプロセスはありません


** DEPLOY FAILED
** Refer to log/capistrano.log for details. Here are the last 20 lines:


 DEBUG [e906a1b0] Command: if test ! -d /var/www/Vook/releases/20170125061945; then echo "Directory does not exist '/var/www/Vook/releases/20170125061945'" 1>&2; false; fi

 DEBUG [e906a1b0] Finished in 0.084 seconds with exit status 0 (successful).

  INFO [f744d9da] Running $HOME/.rbenv/bin/rbenv exec bundle exec rake db:migrate as Daiki@52.198.21.134

 DEBUG [f744d9da] Command: cd /var/www/Vook/releases/20170125061945 && ( export RBENV_ROOT="$HOME/.rbenv" RBENV_VERSION="2.1.3" RAILS_ENV="staging" ; $HOME/.rbenv/bin/rbenv exec bundle exec rake db:migrate )

  INFO [f744d9da] Finished in 3.577 seconds with exit status 0 (successful).

  INFO [0223c969] Running /usr/bin/env ln -s /var/www/Vook/releases/20170125061945 /var/www/Vook/releases/current as Daiki@52.198.21.134

 DEBUG [0223c969] Command: ( export RBENV_ROOT="$HOME/.rbenv" RBENV_VERSION="2.1.3" ; /usr/bin/env ln -s /var/www/Vook/releases/20170125061945 /var/www/Vook/releases/current )

  INFO [0223c969] Finished in 0.148 seconds with exit status 0 (successful).

  INFO [09437040] Running /usr/bin/env mv /var/www/Vook/releases/current /var/www/Vook as Daiki@52.198.21.134

 DEBUG [09437040] Command: ( export RBENV_ROOT="$HOME/.rbenv" RBENV_VERSION="2.1.3" ; /usr/bin/env mv /var/www/Vook/releases/current /var/www/Vook )

  INFO [09437040] Finished in 0.127 seconds with exit status 0 (successful).

 DEBUG [07bf5446] Running [ -f /var/www/Vook/current/tmp/pids/unicorn.pid ] as Daiki@52.198.21.134

 DEBUG [07bf5446] Command: [ -f /var/www/Vook/current/tmp/pids/unicorn.pid ]

 DEBUG [07bf5446] Finished in 0.134 seconds with exit status 0 (successful).

  INFO [c30db33d] Running /usr/bin/env kill -s USR2 $(< /var/www/Vook/current/tmp/pids/unicorn.pid) as Daiki@52.198.21.134

 DEBUG [c30db33d] Command: ( export RBENV_ROOT="$HOME/.rbenv" RBENV_VERSION="2.1.3" ; /usr/bin/env kill -s USR2 $(< /var/www/Vook/current/tmp/pids/unicorn.pid) )

 DEBUG [c30db33d]     kill: 

 DEBUG [c30db33d]     sending signal to 4082 failed

 DEBUG [c30db33d]     : 

 DEBUG [c30db33d]     そのようなプロセスはありません

結局、解決策としては

tmp/pids/unicorn.pid

を削除することで解決できた。

僕のアプリケーションではcapistrano3-unicornを使っていなかったためにunicorn:restartの例外処理の記述がなく、前のプロセスが残ってしまったまま?stopしようとしていたらしい。

完全な備忘録なので同じようなエラーに困ってる方がいれば、コメントください。

divの閉じタグがないよ

f:id:deiki08:20161204022919j:plain

僕が携わっているVook(ヴック)|映像に関わるすべての人のためのポートフォリオサイト の大幅な機能追加の実装がラストスパートに差し掛かり、年末休みを返上でコードを書いています。 納期に追われ、この2、3日中にプルリクを送らなくてはいけないため常にイライラしていますが(笑)

年末らしいことを特にしていないので、年末らしくrubyとべったり付き合うことになった2016年を振り返ってみようと思いました。

人生が変わったかもしれない2016年2月

私が初めてrubyに触れたのは今年の2月でした。

まさか一年も経たないうちwebサービスを設計からデプロイまでをするとはこの時点では思いもしなかったです。

当時の私は映画業界で働きたいと思っていため、映像関係の会社でインターンをして就活を有利に進めようと配給会社や映像制作会社に電話やメールをかけまくっていました。

運良くハリウッドで映画を制作している方と出会う機会があり、その方の紹介で今のアルバイト先に面接に行くことになりました。 面接で映像業界で生きるためには?なんて話をしてもらえるだろうと期待していた私ですが、そこで人生を変えてしまうようなある言葉をかけられました。

俺の代わりにRubyをやってくれない?

『映像関係の会社でインターンをして映画配給会社の方とコネを作って就職するんだ』と気合いが入っていたはずの自分でしたが、大学の授業で少し習ったC言語の面白さを思い出し、興味本位でやってみることしました。

その後の様々な苦労を考えると苦笑いです。(これまで数え切れないエラーとため息を出してきました笑)

一番の試練といえば周りにRubyについて詳しい人がいないために一人でググったり、書籍とにらめっこしながらコード書くことでした。 当時の僕がプログラミングで知っている知識といえばC言語JavaというものがあるというぐらいでRubyに関していえば『なにそれ宝石のこと?宝石関係なくね??』って感じでした。

赤い画面とにらめっこする日々

実際にコードを書き始めるまでの下準備は今考えると不思議なくらいにうまくいったように思います。

プログラミング初心者は実際にコーディングするまでにpcにいろんなものをインストールして環境を整えるわけですが、特に困ったこと起きず自分にはプログラミングの天性の才能があるのではないかと酷い勘違いをしてしまうほどでした。

通常、初心者にruby, railsを一人でインストールさせるのは崖から突き落として素手で登らせるようなものです。(大げさかもしれませんが笑)

そして、そこから実際に開発を行っていくわけですが皆さんが想像するようにrailsのあの赤いエラーとの理不尽な戦いが僕を待っていました。

f:id:deiki08:20161229235703p:plain

MVCというRuby on Railsの最も肝となる規則を理解していなかったために400のエラーを出しまくったり、ちょっと上達しても500エラーを出しまくって画面をしょっちゅう真っ赤にしていました。

当時作っていたアプリケーションはTwitterのクローンアプリで投稿機能をつけるまでに一ヶ月くらいかかったことを記憶しています。(今なら15分で作れると思います...)

しかし、幸いにもruby という比較的日本でのコミュニティが活発である言語を選択したこととプログラミングを学ぶ上で役に立つwebサービスが存在していたために三ヶ月を過ぎたあたりから簡単な制作物をローカル環境で幾つか作ることができるようになっていました。

さらに大きな変化が自分の中で起こっていました。

困難な問題にぶち当たるたびによくインターネットで原因を調査したり、質問サイトで助けを求めていたのですが、そうするうちにITで飯を食っていきたいと思い始めていましたのです。

ITの世界の人たちは自分で書いたコードを自ら進んでネットに載せ、そのコードをもとに見ず知らずの誰かと議論することで自分の技術力を高めていったり、誰かが困っていると自分は一銭ももらえないのにわざわざ自分でその環境を再現し、問題を見つけ解決策を提案する。そんなコミュニティの暖かさに惚れていました。

僕もたくさんの方にコードを見てもらいレビューを頂いてきました。そういう方々がいなかったら僕はエンジニアとして就職したいなんて思わなかっただろし、何より今あるwebアプリケーションはローンチできなかったと思います。

一般的にコンピューターに関わる職種の方はPCの画面を見てばかりでコミュニケーションが取れないと思われがちですが、少なくともインターネット上ではユーモアがあり、やさしく、時に厳しくアドバイスをコミュ力の高いエンジニアが多いような気がします。(もしかしたら現実でもそういう人はコミュニケーション能力が高い人なのかもしれないが)

私自身、今は情報をもらう側としての方が多いですがいずれは自ら情報を発信し、この世界に貢献する人間にならなくてはいけないという風に思っています。

最後に

タイトルはもらったhtml, cssファイルにデザインを当てている時に僕がよくがデザイナーさんから言われることです。 まだまだこんな初歩的なミスを犯しているダメなエンジニアですが、2016年2月からは劇的に成長していると思います。 そして何より、全くの初心者の僕をアルバイトとして雇ってくれた会社の方には感謝でいっぱいです。これからもより良いコードで人の役に立つことができるように精進したいと思います。

生物学科の自分はIT就活をどう戦うか

f:id:deiki08:20161208210444j:plain

まず筆者の置かれている状況から

都内の情報系が強いことで有名な大学に通っている大学三年生です。 とはいっても大学の専門は脳神経科学で大学の授業でプログラミングをしたの大学一年の後期の半期だけでした。 大学ではいつもDNAからたんぱく質が作られる過程や神経細胞がどのように除法伝達しているかとか情報学よりも医学部の方が近いと思います。現に私の受けている授業の教授には他大学の医学部の授業を受け持っている先生もいるくらいです。

それとは別にアルバイトとしてベンチャー企業のwebエンジニアとして働いています。 主にサーバーサイドエンジニアとして、設計から開発、運営までの全てを任されています。 クライアントサイドはwebデザイナーさんにお願いしていて、二人で開発しています。

vook.vc

こちらが私が製作したwebアプリケーションになります。 ということで私は大学の専門である生物学ではなくITエンジニアとして就職したいと考えているわけです。

大学でプログラミングをやっていないと戦えないのか?

f:id:deiki08:20161204022919j:plain

決してそんなことはないです、いわゆるSIerやインフラエンジニアはプログラミング経験がなくても入社後の研修が充実しているので極端な話プログラミング言語をやったことがなくても大丈夫です。 しかし、一部のメガベンチャーでは即戦力を求めていることをはっきりと宣言していました。 そして会社説明会などに行くとエンジニア社員の方のレベルの高さに驚くと思います。やはり、急成長している会社は優秀なエンジニアの待遇に関してはたくさんのお金をかけて雇っていることがわかりますよ。(いろんなものが会社のお金で利用出来る。例えば飲食代に関しては一切払わなくて会社持ちなど)

ポートフォリオインターンなんかより強力な武器になる

インターンについてはここ最近大学生なら一度は行くイベントでインターンに行くと就職につながるというイメージが蔓延していますが、インターンよりも自分で作ったアプリケーションを就活の際に持っていく方がはるかに効果的だということが経験からわかりました。

ポートフォリオを持っていくとソースコードなどを面接官に見せたりして、自分の技術力を評価してもらえます。 そして、何より学生で大量のアウトプットをしている人はあまり多くいないので他の学生よりも大幅リードできると思います。

最初は簡単なアプリケーションをたくさん作って、その中でプログラミング言語を覚えていくのが効率が良くていいと思います。最近はフレームワークがかなり優秀なので一時間もあればなんちゃってのアプリケーションが作れてしまうのでオススメです。

最後に

就活では他の学生と比べ自分の光る部分をしっかりアピールしなければいけない戦い方だと思いました。 これは社会に出てから上司に評価される際などに、自分を行った業績についてしっかりアピールしなければ上に行くことができないことと共通なのかな?とまだ社会に出ていない学生は思いました。

ネットメディアとSEO

DeNAの一連の騒動

代表取締役社長兼CEO 守安功からの一連の事態に対するお詫びとご説明

医療メディアWELQに端を発するDeNAのメディアにおける一連の問題。普段から色んな妬み恨みを買う会社であるDeNAだけに今回の炎上ぶりはすごいなぁと楽観視していたのですが、よく調べていると結構ことやっていたことがわかりこれは簡単に収まりそうにないと思えてきた。

文章の盗用を黙認していたDeNA MERYなどの10個のメディアでインターネット上の文章を転用とみられても仕方ないような書き方で記事を書き、公開していたというもの。しかも、それを会社がマニュアル化していたという驚きの事実。

その結果、共通する運営体制・方針の9つのメディア(WELQ、iemo、Find Travel、cuta、UpIn、CAFY、JOOY、GOIN、>PUUL)に関して、マニュアルやライターの方々への指示などにおいて、他サイトからの文言の転用を推奨していると捉えられか>ねない点がございました。この点について、私自身、モラルに反していないという考えを持つことができませんでした。

引用: DeNA公式サイトより

組織的とも捉えかねられないマニュアル

コピペではバレるので所々文章を書き換えること これを内部で黙認していたそうです。新卒採用サイトにユーザーのことをとことん考えサービスを生み出すと言っていた会社とは思えないですね。とりえずPV数を稼いで目先の広告収入が得られればいい、そして盗用がOKなら記事を生み出すに労力がかからないだろうということで記事一本あたりの単価も下がり、ライターはよりコピペやリライトに走る。

メディアで執筆していた経験があるので申し上げると記事を書くのに一番大変で時間のかかる作業は画像探しです。ユーザーは文字だらけの記事なんて読みません。適度に画像があり、読みやすい分量の文章が繰り返されて記事が出来ていれば必然的にプレビュー数は上がります。

よく見るアレです。タイトル => 見出し=> 画像=> 文章=> 見出し=> 画像=> 文章って流れです。

f:id:deiki08:20161204005643p:plain 注: これは僕が以前執筆した記事で画像もフリー画像を使っています。 これにSEO対策が加わればPVなんていとも簡単に稼ぐことができます。そして、一度人気が出れば継続的にバズることができて安定的な産業の完成です。MERYのようにブランド力のあるメディアなら記事の質が落ちていってもすぐには人気が落ちないでしょう。しかし、それによってだんだんと記事自体の文章の質が落ちゴミが量産されていきます。ゴミが量産されるだけならまだしも最適化されたSEO対策のせいでゴミが検索上位に引っかかり、本当に欲しい情報が得られなくなります。

悪い大人を真似して稼ぐ意識高い系学生

先に述べたようにメディアはノウハウがあれば簡単に体験を稼ぐことができてしまいます。つまり、学生でも大人の真似事をしているだけでお金を稼ぐことができてしまうんですね。 最近、Twitter などでよく見るメディアを運営して起業しています。圧倒的成長とか叫んでいる学生です。 彼らの全てが盗用など違法な行為をしているとは決して言えませんが、私が見る限りグレーであったり以前見かけたことのあるような記事ばかりを見かけます。メディアはより多くの人に見てもらうのが目的なので内容が似通ってしまうのは仕方のないことなのですが、それを逆手にとって少し内容を変更すればバレない検索で上に来た記事の方がオリジナルかのような態度で記事を量産している学生が多々いて、辟易します。

ユーザーにとって本当に価値ある情報を得る

ゴミ記事でPVを稼いだところでその事業は長く続く主力サービスとはならないことは経営陣もよくわかっていると思います。優秀なエンジニアを数多く抱えるDeNAには本当の意味で有益な記事を大量生産してくれることを切に望みます。

文字列置換の備忘録

受け取った文字列を一括置換してくれる書き方

文字列変換で便利な記法があったのでメモ。 以下元となる文字列から変換したい文字があったとする。 "FRTDCABC" => "FRTD3123"

before after
A 1
B 2
C 3
s="FRTDCABC"
puts s.gsub(/[AEGIOSZ]/, "A" => "1", "B" => "2", "C" => "3")

 => FRTD3123

このように記述すれば変換した文字列が表示される。

配列の要素の足し算(inject)

これまた備忘録になります。 配列の足し算をするときに毎回、eachメソッドを使って要素を一つずつ取得して足し算していく書き方がなんとなく嫌だったので別の方法を探していたところinjectメソッドというものを発見した。

enum.inject {|memo, item| block }

enum: (例えば)配列やハッシュ memo: ブロックの中で有効な変数 item: 配列やハッシュから取り出してきた値を格納する変数

s = [1, 2, 3]
p s.inject(0){ |sum, i| sum + i}

=> 6

まずブロック内で有効な変数sumに0を代入する部分が

inject(0)

そして、iの部分では配列から値を順々に取り出している。 以下はブロックの処理の部分。

sum + i

inject(0)初期化で初期化を行わないとブロックが実行される回数が異なるので注意。

p [1,2,3].inject{|sum, i| sum + i*i }
=> 14

p [3,2,1].inject{|sum, i| sum + i*i }
=> 8

これは平方和を求めるプログラム。各要素の二乗を足し合わせている。 なぜ上と下のコードの結果が異なるかというと、ブロックの中で格納される変数が異なるからである。

上では

1回目: 1 + 2*2 =5(sum = 1, i = 2)

2回目: 5+3*3 = 14(sum = 5, i = 3)

下では

1回目: 3+2*2= 7(sum = 3, i = 2)

2回目: 7+1*1 = 8(sum = 7, i =1)

こういうことを防ぐために、一回目のブロック実行時のsumに0が入るように初期化する。

[n..m].inject(0){ |sum, i| block }

参考URL: Rubyのinjectには初期値を明示的に指定したほうがいい

アプリを高速化するためにキャッシュについて考えてみる

そもそもなぜキャッシュが大事なのか

本当に恥ずかしい限りなのですが、今までキャッシュ・セッション・クッキーについてよくわかっていませんでした。(クッキーなんてiphone使っているだけでもよく出てくるのに...恥ずかしい)今回、AWSのEC2で運営しているサーバーの冗長化を考える際にどうしてもキャッシュなどについてしっかりした理解が必要だと感じました。そして、アルバイトをしている会社の社長の知人にとても詳しい方がいたので1日かけてサーバーの冗長化を教わりました。

キャッシュ (cache)とは

キャッシュとは、使用頻度の高いデータを高速な記憶装置に蓄えておくことにより、いちいち低速な装置から読み出す無駄を省いて高速化すること。また、その際に使われる高速な記憶装置や、複製されたデータそのもののこと。

引用: キャッシュとは|cache|キャッシング|caching − 意味 / 定義 / 解説 / 説明 : IT用語辞典

すごくまとめてしまうとアプリに関する"速さ"に影響します。キャッシュがあると、次回以降のアクセスに備えておくことにより次回アクセスした時に早くページを表示したりすることができます。リクエストされたコンテンツを保存し、再利用することによって高速化します。

私が開発で使っているrailsではキャッシュはファイルに書き込みそれを参照しています。そのためSQLなどがたくさん発行され、後述するRedis(No SQLデータベースの一種)にキャッシュを残すよりも速度が落ちてしまいます。さらに今回、教えていただいたサーバーの冗長化ではサーバーを二台設置してエンドユーザーにはどちらに接続していても、キャッシュやセッションが存在していなくてはならないためRedisを使いサーバーの外に置く必要がありました。

セッションとは

接続/ログインしてから、切断/ログオフするまでの、一連の操作や通信のこと。

引用: セッションとは|session − 意味 / 定義 / 解説 / 説明 : IT用語辞典

例えばamazonでお買い物をする場合を考えます。

  1. ログインする

  2. 欲しいものを検索する

  3. カートに入れる

  4. クレジット会計をする

  5. 完了

なるわけです。(ページの移動がもっと細かくあります。)

ですが、一回ログインしたらその後の操作はログイン情報は保持したまま操作したいですよね?欲しいものを検索して、リストが出てくるときに再びログイン画面が出てきたらもう買い物をやめたくなります。一回ログインしたら1~4までの操作はもちろんログインなしで操作したいわけです。そんなときに活躍してくれるのがセッションです!これによってログイン情報を記録してくれることによってユーザーは同一ユーザーとして操作ができるわけです。たまに見かける"セッションが切れました"という表記は長時間操作しないためにログイン情報がなくなりましたよということを指すわけです。

通常アプリではセッションを記録しておく場所があり、今回はこれまたRedisで管理することによってサーバー二台で運営しても矛盾が出ないことになります。

クッキーとは

キャッシュでは具体的にはwebページのコンテンツを保存しておくのですが、クッキーではユーザーの個人情報などを保存しておくものです。

ふたたびamazonで買い物をする場合を考えると、 以前にamazonで買い物をしたことがあるときにクレジット情報や住所などが自動で記入されていることがあったりしますよね!(もちろんログイン画面もそうなのですが)ログインボタンを押したらいきなり以下のようになっているのを見たことがあるはずです!

f:id:deiki08:20161025002956p:plain

これはクッキーのおかげなんですね。クッキーを残すことによって、次回以降面倒な個人情報の入力をしなくて済むわけです。そんな便利なクッキーですが、なりすまし格好の餌食になることがあるので注意が必要です。

セッションハイジャック[編集] クッキーでセッション管理を行う場合、もし第三者がセッションIDを知ることができれば、そのIDを名乗ることで本来のユーザになりすますことができる。このような「なりすまし」行為をセッションハイジャックと呼ぶ。 例として、以下のような通信を行うシステムがあるとする。 トップページでユーザIDとパスワードの入力を求める。 認証に成功するとサーバはセッションIDを割り当て、クッキーとしてクライアントに通知する。 クライアントは以降の要求にクッキーとしてセッションIDを付加する。サーバは対応するセッション情報にアクセスし、どのユーザであるか識別する。 もし第三者がセッションIDを知ることができれば、そのセッションが有効な間だけとはいえ、1~2を飛ばして3から開始することができる。すなわち、パスワードを知らなくても「なりすまし」が可能となる。

引用: HTTP cookie - Wikipedia

クッキーでセッション管理をする際にはアプリの通信でHTTPSを使うべきなんですね。

最後に

いかがだったでしょうか?サーバーの冗長化については記事が長くなってしまったため、別記事で書きたいと思います。間違っていることを書いていたら是非、コメントをお願いします!!