以前の記事「メッセージの安全性新時代:Letter Sealing」にて、LINEの1:1トークにエンドツーエンド暗号化(End-to-End Encryption、E2EE)を実装したことをお伝えしました。それ以降もLINEは、より多くの機能にLetter Sealingを適用拡大するために多大な努力を続けてきました。今回の記事では、これまでの取り組みをご紹介したいと思います。 適用拡大による改善点 1:1トークでLetter Sealingがデフォルト有効化される より安全にサービスをご利用いただけるよう、1:1トークでLetter Sealingがデフォルトで有効化されました。これまではユーザーが必要に応じてLetter Sealingオプションをオンに設定する必要がありましたが、現在はユーザーがオフに設定しない限りLetter Sealingがデフォルトで有効化されています。 最初から全ユーザーを対象にLetter Sealingをデフォルトオンで提供しなかった一番大きな理由は、iOSのプッシュ通知方式のためでした。LINEは、受信したメッセージ内容の一部をプッシュ通知でプレビュー表示します。ただ、Androidと違ってiOSでは、プッシュ通知を表示するプロセスにアプリが介入できる余地が少ないのが事実です。通常、サーバはメッセージ内容の一部をプッシュ通知で送信します。 しかし、Letter Sealingの特性上、LINEサーバはユーザー間でやり取りされるメッセージを見ることはできないため、その内容をプッシュ通知に含めることはできませんでした。 しかし、幸いなことに、VoIP Push Notificationというプッシュ通知方式がiOS 8からサポートされるようになりました。この方式を採用すれば、プッシュ通知が届いた際にアプリを起動して暗号化されたメッセージを受信し、その内容を復号してユーザー端末にプッシュ通知で表示することができます。LINEの開発チームは、iOS 9.3.1から同機能が安定的に動作することを確認し、Letter Sealingを使用するユーザーに従来と同様のユーザビリティを保証できると判断しました。その結果、iOS 9.3.1にアップデートしたユーザーを対象にLetter Sealingをデフォルト有効状態にして適用することができました。 グループトークルームでもより安全にメッセージを送受信できる 1:1トークルームのみならず、グループトークルームでもより安全にトークを楽しむことができます。 グループから退会した場合、そのユーザーはグループトークルームの暗号化されたメッセージを解読できなくする必要があります。さらにもう一つ注意したいのは、モバイルメッセンジャーの特性上、グループトークルームの参加者全員が常にオンライン状態、つまり常にリアルタイムでメッセージを確認できる状態ではないということです。そのため、1:1トークルームよりグループトークルームへのLetter Sealing適用はもっと複雑です。 このような問題をすべて考慮したうえで約1年にかけて開発とテストを行い、最新バージョンにおいてグループトークルームにLetter Sealingを適用することができました。現在は、50人以下のグループトークルームのみを対象としています。 LINEの開発チームがこれらの問題をいかに解決したかについては、次回の記事で詳しく説明したいと思います。 無料通話とビデオ通話でもLetter Sealingを利用できる LINEは、いつどこでも無料で音声通話およびビデオ通話ができる無料通話機能を2011年10月より提供しています。一般のトークメッセージ以外に追加でLetter Sealingを適用する機能を内部で検討した結果、より安全な通話を実現すべく無料通話でもE2EEを開発、適用することにしました。メッセージを送受信する場合と同様、1:1通話の場合も、通話を行うユーザー同士のみが知りうる暗号化鍵を生成し、通話内容を暗号化して転送します。この暗号化鍵はユーザーの端末上にのみ保有されるため、LINEサーバでも通話内容を解読することはできません。 新規に追加された無料通話のセキュリティ機能を使用するためには、別途設定を行う必要はありません。LINE 6.5(iOS版、Android版)およびLINE 4.8(Windows PC版)以降のバージョンを使用しているユーザーの場合、既存のLetter Sealingオプションがオンになっていれば、別途設定しなくてもセキュリティが強化された無料通話を使用できます。 トークルームのLetter Sealing適用有無も一目で分かる LINEでのトークは、Letter Sealingをオンに設定していなくても、ユーザー端末とサーバ間の通信を暗号化して行っており、送受信されるメッセージの保護を行っています。Letter Sealingは、個人のプライベートなトーク内容を送信者と受信者の端末でのみ確認できるようにし、LINEのサーバ上への保存や、内部のサーバ間の通信においても暗号化された状態のままで、より安全に行うために考案された機能です。 Letter Sealingを実装した後、LINE内部ではLetter Sealingがオンになっているトークルームを識別できる状態表示(status indicator)の必要性について多くの議論が行われました。議論の結果、ほぼすべてのトークルームにLetter Sealingを適用する前までは、同機能が使えるケースと使えないケースが混在することによってユーザーに混乱を与えることが懸念されました。また「Letter Sealingが適用されていないトークルームは安全ではない」という誤解を招く可能性もあると判断しました。 今はLetter Sealingがデフォルトで有効化されているので、このようなことを懸念しているよりは、Letter Sealingの適用有無に関する状態情報をユーザーに分かりやすく表示することがもっと重要であると判断しました。そのため、Letter Sealingが有効になっている1:1トークルーム、グループトークルーム、1:1無料通話にはロックアイコン()を表示し、Letter Sealing適用中であることが分かるようにしました。 以上でご紹介した強化されたセキュリティ機能は、iOS版、Android版、PC版(Windows、Mac)※注への対応を皮切りに、他のプラットフォームへも対応範囲を拡大しつつあります。LINEはこれからも、ユーザーの皆様に安心してメッセンジャーサービスをご利用いただけるように最善を尽くしてまいります。 ※注:PC版(Windows、Mac)のLINE 4.8では、1:1トークとグループトークに限って状態表示(status indicator)を提供しています。無料通話への状態表示は次のバージョンで対応予定です。 作成者の紹介 この記事は、LINEでメッセンジャーサーバ開発を担当しているシン・キビンさんが作成しました。
↧
メッセージの安全性のさらなる強化:Letter Sealingの適用拡大
↧
PromCon 2016登壇レポート
はじめに 以前のblog postで予告したように、OSSのモニタリングツールとして最近注目を集めているPrometheusの初のカンファレンスPromCon 2016に参加して発表してきました。 発表資料や動画はこちらから見ることができるので各セッションの詳細はそちらをご覧ください。 このblog postでは当日の様子をお伝えしたいと思います。本家でもレポートが出ているので興味ある方はそちらもチェックしてみると良いと思います。 https://prometheus.io/blog/2016/09/04/promcon-2016-its-a-wrap/ 当日のイベントの様子 参加者の雰囲気 PromCon 2016は8/25(木), 26(金)の2日間にわたってドイツのベルリンで開催されたイベントです。会場はGoogle Berlinで、LINEはシルバースポンサーとして協賛しました。 カンファレンスの規模は参加者約80名でシングルトラックで進行しました。東京でのPrometheusイベントでさえ約100名のエンジニアが参加したぐらいなので、本家のカンファレンスで80名というキャパシティは少ないのではと最初は思っていたのですが、実際その通りだったようでチケットは一瞬にして売り切れたそうです。参加者はクラウドサービスを活用したインフラエンジニア、SREといったポジションの方が多かったようです。 会話した限りではやはりヨーロッパからの参加者が多く、ドイツ以外ではイギリス、アイルランド、スペイン、フランス、スウェーデンといった国から、アジアでは日本を除くとタイ、インドネシアから参加している方がいました。主催者の方も遠いアジアまでPrometheusが広まっていることに驚きと喜びを感じているようでした。私は4月末にCFP(Call for Papers)を出し、それがacceptされたのでspeakerとして参加できました。 私の発表 私の発表資料は以下を参考にしてください。 発表時の写真と名札はこちらです。 私はFluentdでログ収集してHadoopに蓄積するということをやっているので、そのシステムのモニタリングにPrometheus, Grafanaを使っている話と、OSSとして公開したpromgenを紹介しました。 promgenはRubyで実装されたWebアプリケーションで下記2つの機能を持っています。 Prometheusの設定ファイルの自動生成およびPrometheusのreload アラート通知先の制御 私の発表に限らず参加者はアットホームというかハートウォーミングに発表を聞いてくれ、とてもやりやすい雰囲気でした。発表後に「Nice Talk!」と言ってくれる人もいて、とても嬉しかったです。 印象深かったやりとりと私の経験 私以外のセッションでは、Prometheus開発者によるストレージやアラート周りの発表やPrometheus誕生秘話、kubernatesのモニタリングなどPrometheusのユースケース紹介、Grafanaの話、Prometheusを活用してモニタリングサービスを展開する話、などバラエティに富んだセッションが沢山ありました。 セッションのなかで個人的に気になったのは、地味だけど重要なアラート周りの話です。機械学習の異常検知によるアラートの話題も出て個人的には面白いと思いますが、運用が少し難しそうです。 PromQLを使った例は出てきましたが、クエリが少し複雑で僕の環境で取り入れるのは先になりそうです。 アラートのunit testってどうするの?という話題も出て、現状だとドッグフーディングしかないかもしれないと聞いてやはりまだそうなのかと思った次第です。アラートがちゃんと動いているか確認するのは実践でやるしかない部分もありますが、障害がそんなに頻繁に起きるわけでもないので、アラートが来ないバグというのは気付きづらい傾向にあります。実際に私自身も最近それを経験しました。 PrometheusのAlertmanagerのご紹介 Prometheusの世界ではアラートはAlertmanagerが担当します。アラートが発生するとAlertmanagerがmailなりhipchatなりslackなりにそれを通知しますが、私の環境ではまずpromgenがアラートを受け取って処理をするという流れです。Prometheus → Alertmanager → promgen → hipcaht/mail という経路です。こうすることによってAlertmanagerのreloadをしなくてもアラート通知先を柔軟に変更することができます。promgenは当初CSRFの問題があったためRack::Protectionを用いてリファラーが無いリクエストははじくように変更を入れたところ、Alertmanagerからのアラート通知を拒否してしまい結果的にアラートが来ないという状況になってしまいました。 そのような経緯があり、現在では下記のようにアラート通知に失敗した場合は障害になるようにアラートルールを追加しました。 ALERT AlertDeliveryError IF rate(alertmanager_notifications_failed_total[5m]) > 0 FOR 5m LABELS {severity="critical"} ANNOTATIONS {summary="notification through promgen failed."} このアラートルールに引っかかってもpromgenに問題があって通知できないのでは困るので、Alertmanagerに関するものはpromgen以外の経路で下記のようにmail通知するようにしています。 global: smtp_smarthost: '... smtp_from: '... route: receiver: 'promgen-webhook' routes: - receiver: 'promgen-mail' match: job: alertmanager receivers: - name: "promgen-webhook" webhook_configs: - url: 'http://promgen:password@localhost:9092/alert' - name: "promgen-mail" email_configs: - to: '...' require_tls: false AlertmanagerのHAのLightning Talks アラート周りの他の発表ではAlertmanagerのHA(High Availability)のLightning Talkがありました。Lightning Talkは参加者が会場で下記のようにホワイトボードに書いてsign upする方式でした。 Prometheusはpull型のアーキテクチャなのでHAは簡単に組めます。同じ設定ファイルで2つのPrometheusを動かすだけです。しかしAlertmanagerは現状SPOF(Single Point of Failure)なので、HAは必要だと思います。私のようなHadoopエンジニアだとHAと聞くとZooKeeperが必要なのかな?と思ってしまいますが、AlertmanagerのHAはZooKeeperのような外部のミドルウェアを必要としません。これならセットアップも楽そうですね。 内部的にはCassandraのようにGossipプロトコルでノード間通信を行いCAP定理のAP型システムのようです。またAlertmanagerが複数あっても同じアラートを複数受け取ることになっては意味がないのでそこについての説明もありました。 Alertmanager HAの実装は終わっているもののテストが足りないようでまだリリースされていません。リリースされたら私もチェックしようと思っています。 会場で提供された食べ物、飲み物、Tシャツ、バッグ イベント当日は食べ物も非常に充実していました。朝食と昼飯としてはヨーロッパとアジアを区分せず様々な料理がでました。ドリンクもコーヒーを含め様々な種類が提供されていて、デザートにPrometheusケーキもありました。カップケーキの上にPrometheusのマークが乗っているのが印象的です。 さらにお土産にPrometheusバッグとTシャツももらいました。 さらにイベント初日の夜には懇親会も開催され活発な議論が展開されました。 (…)
↧
↧
LINE Developer Dayトークの見所を一部ご紹介します
9月29日(木) に渋谷ヒカリエホールにて開催するLINE DEVELOPER DAY 2016 では、17のトークをお届けする予定です。今回は、17のトークのうち、4つのトークについてご紹介したいと思います。 参加登録は公式サイトから、応募締切は9月15日(木)です。 LINE Developer Day 2016 ■ HALL A 11:00 – 11:40 「Keynote / New world by the LINE BOT」 LINE Developer Day 2016 のキーノートスピーカーのを担当する松野です。 今年の keynote は LINE の BOT プラットフォームがテーマです。今年の春から始まった LINE の Bot をお試しで作れる Trial Bot の現状。そして今後。Bot Platform の新機能。Bot 関連の新サービスなどなど。初公開の情報など盛りだくさんでお届けしますので乞うご期待! ■ HALL A 14:20 – 15:00 「Security x LINE Platform」 Security x LINE Platformというタイトルでお話をさせていただく愛甲です。 LINEではサービスを利用するユーザーの安全を第一に考え、様々なセキュリティ対策を行っています。当セッションでは、LINEのメッセージングにおいて使用される暗号、特に「Letter Sealing」について解説します。LINEでは、2016/08/31より通信内容の暗号化の有無を意味する「鍵マーク」を表示するようになりましたが、このマークの裏側で実際に行われている暗号通信について説明いたします。また、LINEが提供するWebサービスやゲームにおいても、ユーザーが安心して利用できるよう、リリース前にセキュリティ診断を実施します。これはLINEが提供するすべてのサービスに対して例外なく行われます。このセキュリティ診断について、どのような調査、対策を行っているのかについて説明いたします。 ■ HALL B 14:20 – 15:00 「LINE Bot Live Coding」 開発3センターサービス開発1室の海津です。LINE Bot Live Codingのセッションでは、LINE Botに搭載される新機能を最も早く体感出来るセッションになります。 内容については比較的初心者向けな話が多くなりますが「LINE Botを使えばこんな機能を作れるんだ」という事をどなたでも理解出来るようなセッションにする予定です。まだLINE Botを作った事の無い方、今後のLINE Botの展望に期待している方には、是非足を運んで見に来て頂けたらと思います。40分で収まらなかったらごめんなさい。 ■ HALL A 13:00 – 13:30 「LINEが乗り越えてきた困難な問題」 こんにちは。LINEが乗り越えてきた困難な問題、というテーマで話をするnasuです。 昨年のDevDayでは、メッセージング基盤の話としていくつかLINEのアーキテクチャやマイクロサービスの紹介と改善の話をしましたが、別の側面として、障害が発生した結果様々な課題が見えてきてLINEはさらにアーキテクチャやマイクロサービスを改善してきています。 これまで多くの障害が発生してみなさんにご迷惑をおかけしている部分については、TwitterやFacebookを通じて皆さんに共有をしていますが、今回は今年3/11に発生した障害のバックグラウンドを紹介しつつ、なぜ障害が発生したのか、発生時に開発者がどのように障害を解決・対応したのかという過程を話したいと思います。 キーワードとしては4つ、クリエイターズ着せかえ、共通データの更新の仕組み、認証、リクエストバーストです。 当日は、来場者限定で入手可能なお土産などもご用意しております。参加登録は公式サイトからお願いいたします。応募締切は9月15日(木)です。 LINE Developer Day 2016 皆様のご来場をお待ちしております! Twitter 公式ハッシュタグ #linedevday
↧
LINE LIVE チャット機能を支えるアーキテクチャ
LINE株式会社のOklahomerです。 本記事では、LINE LIVEという動画配信サービスのチャット機能が、どのような構成で成り立っているのか紹介します。 チャットの紹介 LINE LIVEのiOS/Android アプリでは、配信中の動画を視聴しながらリアルタイムにコメント投稿できるチャット機能を提供しています。この機能の役割は、視聴者同士が対話を楽しむだけにとどまりません。配信者が視聴者のコメントに返答するという形で配信者と視聴者の接点として機能したり、また配信者がコメント内容に従って企画を進めるなど、配信者と視聴者が一体となって配信を作り上げていく上でも重要な機能となっています。 これが有名人による配信となれば当然視聴者数も多くなりますし、その配信中に視聴者からのコメントを募れば瞬発的に相当量のコメント流入があることは容易に想像できるでしょう。もちろんコメント流入が増えるということは、全視聴者へと中継すべきコメントの量も増えますから、それらをいかに高速に捌くかが常に課題となります。実際、一配信のみで分速1万件を超えるコメントが投稿されるようなこともあります。 そのためチャットでは、滝のように流れるコメントに耐えることを前提に開発が進められ、今では100台以上のサーバインスタンス上で稼働しています。 以下、その構成を説明いたします。 サーバ構成の全体像 まずは全体像として、以下の画像をご覧ください。 詳細な説明は以降の項目に譲るとして、ここではチャット機能を実装するにあたって重要な「チャットルーム」の概念を理解頂くため、Chat Server1に接続されたClient 1がコメントを送信し、それがChat Server2に接続しているClient 2に送り届けられている点に注目ください。 先述の通り、人気配信者による配信となると流入するコメント量は相当なもので、読み切れないほどのコメントが流れるのは盛り上がりを体感する上でとても重要な要素となります。が、あまりにも多すぎると、コメントを捌くサーバ側にとっても、それを表示するクライアントにとっても負担となってしまいます。そのため、私たちは「チャットルーム」という概念を採用し、視聴者が増えるに連れてチャットルームを分割し、同一チャットルームに属するユーザ同士でのみ対話を行えるようにしました。このチャットルームは複数のサーバをまたいで分散されるため、同一チャットルームに属するユーザ同士でも、その接続は異なるサーバへとバランシングされます。 これを実現するための構成として、チャットサーバの構成の特徴には以下の3つが挙げられます。 WebSocket: クライアントとサーバ間の疎通 Akka toolkitによる高速な並行処理 Redisを利用したサーバ間のコメント同期 以降の項目では、これら3つの項目についてそれぞれ焦点を当てて説明します。 WebSocket WebSocketを採用することで、張り続けられた単一のコネクション上で、低いレイテンシで双方向のコミュニケーションを行うことができます。これにより、高速に流れるコメントをリアルタイムにユーザへ送り届けることは勿論、ユーザからのコメント投稿に関しても都度HTTPリクエストを送信する必要がなくなるなど、サーバリソースを有効に使える利点があります。 ただし、単一のコネクション上でメッセージングを行うということは、慣れ親しんだWeb APIのようにエンドポイントによってレスポンス形式を分けることができず、サーバ・クライアント共に受け取ったペイロードを適切に識別してハンドリングする工夫が必要になります。チャットの実装ではJSON形式のペイロードを送り合うのですが、全てのペイロードに共通するフィールドを一つ持たせ、その値を識別することによってペイロードが何を表すか識別し、対応するクラスにマッピングできるようにしています。この方法のおかげで、有料ギフトの実装などで新たなペイロード定義が必要になるような場合でも柔軟な対応が可能となります。 ここで注意したいのは、モバイル端末との接続ということもあり、長時間張り続けたコネクションが不安定になるケースが目立つということです。これを回避するため、ペイロードの送信状態を監視し、コネクションが不安定だと判断できる場合は一度コネクションを切断して再接続を促すなどの対応が取られています。 Akka toolkit Akkaアクターシステムを構成する重要な要素として、何よりまずactorと、そのsupervisorの仕組みが挙げられるでしょう。チャットサーバのアクターシステム構成の前に、前提となる特徴を挙げてみます。アクターモデル全般についての概要は、ここでは割愛します。 Actor まず、それぞれのactorは内部に状態と振る舞いを持ち、mailboxと呼ばれるキューが割り当てられます。actorが持つ状態は隠蔽されていて外からはうかがい知れないため、actor同士は互いにメッセージを送り合いつつ、受け取ったメッセージに対して各々定義された振る舞いをし、また次のactorにメッセージを送ります。 このメッセージパッシングは非同期に行われるため、メッセージを送ったactorはすぐさま自分のmailboxから次のメッセージを受け取り、次の処理へと移ることができます。そのため、それぞれのactorには大きなタスクを持たせず、細分化されたタスクを少しずつ処理しながら互いにメッセージパッシングすることが、アクターシステム全体として効率よく並行処理を行う上で肝要となります。 この設計を誤ると、ブロッキングな処理がactorの振る舞いに組み込まれてしまい、メッセージが積もってmailboxが溢れてしまうことになりかねません。特に注意したいのは、サードパーティのライブラリを利用する際など、うっかりブロッキングなAPIを呼んでしまうようなケースです。最悪なのは処理が完全にブロックされるケースで、この場合、該当actorの実行を担うスレッドが占有され続けてしまい、ひいてはスレッドの枯渇に繋がります。 それでもakkaアクターシステムを採用する利点としては、「各actorが軽量スレッドを割り当てられていて、そのスレッド上でのみ実行される」というコンセプトで実装できるため、任意のactorが同時に複数スレッドから呼び出されることが無い点が挙げられます。そのため、actor内の状態を管理する際などは、スレッドセーフであることを意識しなくても良くなります。また、対障害性を高める上で重要なsupervisorの仕組みも利点といえるでしょう。 Supervisor actorのライフサイクルを把握する上で重要となるのは、actorは他のactorによってのみ生成されるということです。これにより、actor間には必ず親子関係が生まれます。この生成したactor(親)が、生成されたactor(子)のsuprevisor(監視者)としての役割を担いますので、どのactorにも必ずsupervisorが存在することが保証されます。Akkaアクターモデルにはlet-it-crashの考えがあり、子actor内で処理が例外を投げた場合は即座にそれがsupervisorである親actorへと伝播され、エラーハンドリングは親actorの責務となります。親actorは受け取った例外を識別し、必要に応じて以下の4つのdirectiveから最適な対応を選択します。 Restart: actorの再起動。actorインスタンスを新たに作り、mailboxに溜まった次のメッセージから処理を継続します。 Resume: mailboxに溜まった次のメッセージから処理を継続します。Restartがactorインスタンスを再度生成するのに対し、Resumeでは既存のactorがそのまま利用されます。actor内の状態が正しく保てなくなった場合などにRestartを利用し、処理が継続できる場合ならばResumeを利用するなどの使い分けが考えられます。 Stop: actorの停止。この時点でmailboxに溜まった残りのメッセージは処理されません。 Escalate: 子actorの例外について親自身もハンドリングができないようなケースでは、Escalateでさらに上位のsupervisorに例外を伝播して対応させます。 actorが再起動したり停止したりするとなると、そのactorを参照しているアプリケーションの実装でもactorのライフサイクルを意識しなくてはならないように思えます。が、実際の所、actorを生成した際に返されるのはactorの実体ではなく、ActorRefと呼ばれるactorへの参照のみが返されます。アプリケーション内では、このActorRefに対してメッセージを送ることになるため、その下にいるactorの実体が再起動している最中であったり停止する過程であるなどの状態について意識する必要がなく、実装がシンプルに保てます。また、この抽象化によってアプリケーションコードはactorの所在を知る必要がなくなるため、複数サーバをまたいでアクターシステムを構築する際にも柔軟に対応できます。 チャットサーバのアクターシステム構成 先ほどの全体像より、もう少しactorに焦点を当てた簡略な図を見てみましょう。 上の図のように、主にChatSupervisor、ChatRoomActor、UserActorの3種類のactorが連携しあってユーザのコメントを届けています。それぞれの役割は以下の通りです。 ChatSupervisor: JVM上に一つのみ存在するactorで、actorの生成と監視を行ったり、外部から流入するメッセージを対応するactorへとルーティングする役割を持ちます。私達の定義するactor群の最上位に位置するもので、ロジックは持たず、メッセージごとの実際の処理は行いません。 ChatRoomActor: 各チャットルーム毎に生成されるもので、チャットルーム内でのコメント送信や配信終了などのイベントを表す各種メッセージは一度ここへと伝えられます。詳しくは後述しますが、サーバ間のコメント同期のためにRedisへpublishしたり、Redisへのコメント保存などもここで行い、クライアントへ届けるべきメッセージはUserActorへとパッシングされます。 UserActor: ユーザごとに生成されるactorで、ChatRoomActorからメッセージを受け取り、自分が担当するクライアントのWebSocketコネクションに対してペイロードの送信を命じます。 ここまでの説明で、ChatRoom内でのRedis連携やUserActorでのWebSocketコネクション越しのペイロード送信について言及しました。先述の通り、actor内ではブロッキングな処理を行わないようにすることが重要です。そのため、これらの処理でも可能な限り非同期メソッドを利用し、Akkaアクターシステムに割り当てられた実行スレッドの占有を防いでいます。 Reids Clusterとpub/subの利用 チャットでは、サーバ間のコメント同期と、コメントや各種数値の一時的な保存目的のためにRedis Clusterを利用しています。 コメントの同期 ユーザ数に応じてチャットルームが分割されること、同一チャットルームであっても複数サーバに分散されることは既に述べました。ですが、チャットルームが複数サーバにまたがる場合、サーバ間でいかにコメントを同期するかが重要になります。akka toolkitは豊富な機能を提供していて、Akka clusterやevent busなどの選択肢もあるのですが、akka clusterを採用した場合のnodeの分散や、event busを利用した場合のデプロイ時の煩雑さを考慮して、運用・実装共に容易なredis pub/sub機能を利用しています。以下の図を見ていただくとイメージが湧きやすいでしょう。単一のルームが複数サーバにまたがって存在すること、同一ルーム内でのコメントがredisのpub/subによって同期されていることが伝わるかと思います。 高速なKVSとしての利用 また、配信中のコメントを一時的にredis上に保存する用途やカウンタとしての利用目的で、高い可用性とスケーラビリティを持つRedis Clusterを採用しています。コメントの流量が多くなることなどを考慮し、配信中のコメントやギフト送信情報などのイベントはまず高速なread/writeが可能なインメモリKVSとしてのRedis Clusterに保存し、配信終了後に、恒久的なストレージとしてのMySQLへマイグレートしています。Redisに保存される時点では、これらの各種イベントは配信経過時間を基準とした一つのソート済みセットに納められるため、チャット入室時に直近のイベントを数十件時系列に表示するなどの用途でも重宝しています。これらのイベントはMySQLへマイグレートする段階で正規化され、該当するテーブルへと保存されます。 Redisクライアント JavaのRedisクライアントライブラリは様々なものがあり、本家ドキュメントで推奨されているものだとJedis、lettuce、Redissonなどがあります。チャットでは以下の理由からlettuceを採用しています。 Redis Clusterをサポートしている master/slaveフェイルオーバーやMOVED, ASKリダイレクトに対応し、nodeやhash slot情報のキャッシュを最新に保ってくれる 非同期APIが提供されている pub/subでのsubscribe用コネクションでもフェイルオーバーに対応している 活発に開発が行われている 先述の通り、Akka actor内ではブロッキングな処理を極力避ける必要があるため、非同期APIが提供されているのはとても重要です。またChatRoomActorでのpub/sub利用では、最長で配信開始から終了までの期間にわたってsubscribeし続ける必要があるため、このsubscribe用コネクションの死活監視ができることも重要になります。lettuceではClusterClientOptionsを適切に設定することにより、node downが検知されればsubscribe用コネクションも適宜張り直してくれるという機能があります。また、subscribeの際、接続クライアントが最も少ないノードに対してsubscribe用のコネクションを生成してくれるのも大きな利点です。 まとめ 以上、LINE LIVEのチャット機能を支える構成について紹介いたしました。 WebSocketを用いてサーバ・クライアント間のリアルタイムな双方向メッセージングに対応していること サーバ内ではakka toolkitを利用することで高速な並行処理を行っていること Redis Clusterを、一時的なデータの保存用途と、pub/subによるサーバ間のコメント情報同期で用いていること これらの3点を理解いただければ幸いです。 最後になりますが、冒頭で述べた通り、この機能は100台を越えるサーバインスタンス上で稼働しています。そこで大量のコメントを捌いていると、当然ながらサードパーティライブラリのエッジケースとも言えるissueに行き当たることがあります。そうした際には、その開発コミュニティであったりgithub issueなどを通じて開発者とコミュニケーションを取りながら修正したり、ワークアラウンドを採用することも必要になります。たとえば最近では、Redis Clusterにnodeを追加した際に複数サーバでlettuceの挙動が不安定になり、githubでissue報告をして対応してもらった例などがあります。 詳しくは9/29のLINE Developers Day 2016にてお話させていただきます。 なおLINEでは、次の各分野のエンジニアを募集しています。多くのご応募をお待ちしております。 サーバサイドエンジニア【LINE GAME】【ファミリーアプリ】【LINE Pay】
↧
LINE DEVELOPER DAY 2016 の LINE LIVE配信が決定しました
LINE DEVELOPER DAY 2016 開催のお知らせで開催告知をさせていただきましたが、当日はLINEが提供するライブ配信プラットフォーム「LINE LIVE」にてリアルタイム配信を行います。 2つのホールをそれぞれ以下のチャンネルで配信いたします。「フォロー」を設定すると配信開始時に通知が届きますので、是非ご登録ください。 HALL-A https://live.line.me/r/channels/31960 HALL-B https://live.line.me/r/channels/31959 ※会場では同時通訳が用意されておりますが、LINE LIVEの配信では会場で流れる音声のみをお送りします、あらかじめご了承ください。 なお、各セッションは、日本語もしくは英語(セッション番号)で行います。 タイムテーブルはLINE DEVELOPER DAY 2016 公式サイトをご覧ください。
↧
↧
LINE Developer Day 2016 結果報告
こんばんは、LINE DEVELOPER DAY運営担当のMomokiです。 本日、当社が運営するサービスについて、技術領域の側面から様々な経験や国内外での技術的なチャレンジ、最新の展開等を紹介する技術カンファレンス「LINE DEVELOPER DAY 2016」を開催いたしました。 応募者多数のため抽選となりましたが、社内外のエンジニアを中心に1,000名を超える皆さまにご来場いただき、盛況となりました。ありがとうございました! 「LINE DEVELOPER DAY 2016」では、LINEのchatbot戦略やその一環である「LINE BOT AWARDS」開催の発表やLive Coding、LINEの暗号化通信方式「Letter Sealing」の仕組み、「LINE LIVE」やLINEのグループ通話機能などの大量通信の処理構造、LINEの障害対応事例など、LINEの技術にまつわる多岐にわたるテーマで、合計17セッションを行いました。 早速、LINE LIVEで配信したプレゼン動画のアーカイブと投影資料も公開しておりますので、是非こちらからご覧ください。 ※字幕入りのプレゼン動画は後日公開します。 HALL A:https://live.line.me/r/channels/31960 HALL B:https://live.line.me/r/channels/31959 【A-1】Opening & Introduction 【A-2】New World by the LINE Bot 【A-3】Difficult Challenges That LINE has Overcome 【A-4】LINE Login – LINE Platform 【A-5】Security x LINE Platform 【A-6】Group App Platform 【A-7】Architecture Sustaining LINE LIVE 【A-8】LINE Group Call 【A-9】LINE Shop Powered by Armeria 【A-10】Working Environment and Culture for LINE Engineers 【B-1】Rinna and rinna 【B-2】LINE Game Cloud – Our Personal EC2 【B-3】LINE Bot Live Coding 【B-4】Gravty: A Graph Database for LINE Timeline 【B-5】Stellite: Apply Chromium Open-Source to LINE Game 【B-6】New Stream Processing Platform with Apache Flink 【B-7】A True Agile Team – (…)
↧
コマンドラインから LINE にメッセージを送れる LINE Notify
はじめに LINE Notifyの開発をしている渡辺です。開発者向けにLINE Notifyを使ってコマンドラインからメッセージを送るという方法を紹介いたします。 これまでシステム的にLINEにメッセージを送るためにはBot API TrialまたはBusiness Connectを使用する必要がありました。これらの機能はMessaging APIとしてより洗練されましたが、Messaging APIは高機能な一方で、API呼び出しのためには多少高度な実装が必要になります。 LINE Notifyではメッセージ送信に機能を絞り、極めて短いステップでLINEにメッセージを送れるAPIを用意しています。 curl を使ってメッセージを送ってみる LINE Notifyで発行できる「パーソナルアクセストークン」を使い、APIのエンドポイントにHTTP POSTリクエストを送るだけでメッセージを送ることができます。HTTPリクエストができればどんな方法でも使うことができますが、ここではコマンドラインで使えるHTTPクライアントであるcurlを使ってみることにします。 パーソナルアクセストークンを発行する LINE Notifyのマイページ(LINE IDでのログインが必要)にアクセスすると「トークンを発行する」ボタンがあります。 これをクリックすると、トークン名と、このトークンを使った場合のメッセージの通知先を選択する画面が現れます。 トークン名は任意の分かりやすい名前を入力しておきます。通知先に1:1を選択した場合には、LINE Notify公式アカウントとのトークにメッセージが送信されます。トークルームを選択した場合には、そのトークルームにLINE Notify公式アカウントからメッセージが送信されます。 通知先はトークンごとに変えることができます。別々のトークルームにメッセージを投稿したい場合にはそれぞれでトークンを発行できます。 ここで発行したアクセストークンは一度しか表示されないので、どこかにメモしておきます。といっても、わからなくなってしまったら、削除して発行しなおせばいいだけです。 通知を送ってみる 取得したパーソナルアクセストークンでLINEにメッセージを送ってみます。curlコマンドを以下のように呼ぶことで、メッセージの送信ができます。[access_token]の部分を取得したパーソナルアクセストークンに置き換えてください。 curl -X POST -H 'Authorization: Bearer [access_token]' -F 'message=foobar' https:// notify-api.line.me/api/notify -X はリクエストメソッドの指定 -H はリクエストヘッダの指定 -F はフォームデータの送信 となっています。URLはLINE Notifyの通知用エンドポイントです。 以上のようにとても簡単です。 応用例 curlで簡単に送れることはお分かりいただけたかと思います。ここから少し応用例を紹介します。 例1: Jenkinsのビルド結果を送る Jenkinsのビルド結果をLINEに通知してみる例を紹介します。 せっかくですので、Jenkins2.0から正式に導入されたJenkinsfileを使ってみます。以下のようなspecで作ってみましょう。 1.Jenkinsのビルド結果を、以下の形式で送ります。 Build {branch}, result is {result}. {buildUrl} 2.また、もしもビルド結果が失敗だった場合はムーンが小馬鹿にしてくる画像を送ってみます(実際にこのような画像を送ることはやめましょう…今回の例は、あくまでジョークです)。 すごくシンプルなJenkinsfileにはなりますが、このように書けば実現することができます(今回はJava projectを想定しているので、gradleでビルドとテストの実行をしています)。 #!groovy node { try { stage 'Checkout' checkout scm stage 'Build and test' sh './gradlew clean check' currentBuild.result = 'SUCCESS' } catch (err) { currentBuild.result = 'FAILURE' } stage 'Notify' notifyLINE('YOUR_LINE_NOTIFY_TOKEN', currentBuild.result) } def notifyLINE(token, result) { def isFailure = result == 'FAILURE' def url (…)
↧
LINE Beacon [LINE DEVELOPER DAY 2016 Edition]の仕様
こんにちは、LINE Beacon関連の担当をしているsotaroです。 LINE DEVELOPER DAY 2016 では、イベント限定として LINE Beaconを作成し来場者の皆様にお渡ししました。今回はそのLINE Beacon [LINE DEVELOPER DAY 2016 Edition]および付属品について少し説明をさせていただきます。なお、こちらに記載されている内容は2016年10月現在のものです。 ビーコンイベントを受信する条件 まず前提として、現在Developer Trial Accountのみビーコンを受信可能です。フリープラン、ベーシックプラン、プロプランではビーコンとの連携は出来ないのでご注意下さい。 電源を入れるとLEDが30秒程点滅し、点滅が停止すると電波が発信されます。 ビーコンから発信される電波の出力電力は0dBmに設定されています。目安として、障害物のない環境で10mほどの距離受信可能な出力強度となります。 下記の条件を満たした上で、電波の受信圏内に入ったタイミングでイベントが発火されます。 一度受信圏外に出て入り直さない限りは、イベントは再度発火されません。 ビーコンと連携しているアカウントを友だち追加している(ビーコンとアカウントの連携はこちらから)。 LINEアプリのLINE Beaconの利用がONになっている(その他 > 設定 > プライバシー管理 > LINE Beaconを利用)。 端末のBluetoothがONになっている。 電池の耐用年数 目安として、電源を入れっぱなしの状態で数ヶ月から1年ほど持ちます。 iOS10問題 一部のiOS端末とiOS10の組み合わせにおいてビーコンが検知しづらいという事象が発生しています。主にiPhone5,5sにおいて発生するという問い合わせをいただいています。 対策については現在調査中ですが、端末のBluetoothをON/OFFすることで一時的にビーコンを検知しやすくなる場合があります。お試しください。 その他の注意点 「LINE DEVELOPER DAY 2016」で配布したビーコン端末を日本以外の地域でご利用になる際は、該当地域の電波法令を遵守して下さい。
↧
GitHub Universeに登壇しました
こんにちは、LINEでiOSエンジニアを担当しているInami (@inamiy) です。 GitHub Universe 2016イベントの紹介 先日、2016年9月13日〜15日の3日間、「GitHub Universe 2016」というイベントが、アメリカ・サンフランシスコのPier 70にて開催されました。 海辺のガレージを改築した会場に、総勢1500人の開発者、テックリード、ビジネスリーダーらが来場し、GitHub社・共同創業者でCEOのChris Wanstrath氏による基調講演をはじめ、世界各国から招待された約40名のスピーカーによる様々なオープンソースプロジェクト・企業の取り組みが紹介されました。 私は今回、日本から唯一のスピーカーとして、パネルディスカッションに登壇させていただきました。 以下、数枚の写真でイベント現場の雰囲気をお伝えいたします。 Pier 70にあるウェアハウス(倉庫)の会場と屋上から見下ろすOctocatです。 会場内の雰囲気を写真に収めてみました(Heroku、Travis、Circle CI、IBMのブースがありました)。 豪華な朝食とランチに、無限タピオカジュースも完備されていました。また、皆大好き、GitHub Shopも出店していました。 Chris Wanstrath氏による基調講演の様子です。 この基調講演の中で、同氏は「過去最大のアップデート」と述べ、以下の6つの新機能について紹介しました。 1. Integeration: GraphQL APIの提供や、その他の機能拡張サービスへのEarly Access 2. Businesses: 2段階認証の必須化、SAMLを使ったアカウント管理(来年予定) 3. Workflow: かんばん方式によるタスク管理「Projects」の導入 (参考リンク) 4. Reviews: 「レビュー開始」、「承認」、「修正要望」などのボタンが追加され、コードレビューからマージまでの作業を能率良く統合(参考リンク) 5. Profile: ユーザーの過去の活動が見渡せるタイムラインが追加 6. Forums: ユーザー同士でコミュニケーションを取れる掲示板。教育用、プラットフォーム用、GitHubコミュニティ用(来年予定)など。 これまで、GitHub社では新機能のリリースを小出しに行ってきた印象があっただけに、今回の発表は予想以上のサプライズで、とても興奮しました。 特に「Projects」と「Reviews」は、ユーザーが待ち望んだ機能ではないでしょうか。 今後のプロジェクト運営や業務において、幅広い活用が期待できそうです。 弊社のインナーソースの取り組み 私は今回、「インナーソース(企業内におけるオープンソース志向の取り組み)」というテーマで、パネルディスカッションに登壇する貴重な機会をいただきました。GitHub社のKakul Srivastava氏を司会に、Jeff Jagoda氏 (IBM)、Joan Watson氏 (Hewlett-Packard)、Jeremy King氏 (Walmart)、Panna Pavangadkar氏 (Bloomberg)と並んで、弊社の取り組みやインナーソースの課題などについて話しました。 Launch – InnerSource: Reaping the Benefits of Open Source, Behind Your Firewall(動画) ディスカッションの内容について、各種メディアに取り上げていただきましたので、ご覧ください。 [GitHub Universe 2016]LINEのエンジニアとGitHub幹部にGitHubの新機能について聞いてみた (1) LINEとGitHubを活用しているLINEのiPhoneアプリ開発チーム | マイナビニュース ウォルマートやLINEも採用–注目される“インナーソース開発”の勘所 – ZDNet Japan ASCII.jp:GitHub Universe 2016:デベロッパーの働き方を一般に広める (1/2)|松村太郎の「西海岸から見る”it”トレンド」 「GitHub」の働き方革命は何がスゴいのか? | ワークスタイル | 東洋経済オンライン | 経済ニュースの新基準 なお、LINEでは、2012年からGitHub Enterpriseを活用したプロジェクト管理を行っています。 導入の経緯や、開発フローなどについては、下記のブログ記事も合わせてご参照ください。 LINEではGithub Enterprise を導入しています « LINE HR Blog LINE Serverの開発とリリースプロセス « LINE Engineers’ Blog LINE (…)
↧
↧
アジャイル開発手法を活用したLINE TODAYサービス
はじめに 今回の記事では、アジャイル開発手法を使ってLINE TODAYサービスを開発した経緯をご紹介します。LINE TODAYは、2016年初めに台湾、タイ、インドネシア、ミャンマー、米国でリリースしたモバイルニュースサービスで、2016年7月30日現在1日3千万ページビュー(Page View:PV)を記録しています。ちなみに、日本では独自のニュースサービスとしてLINE NEWSを展開しています。 LINE TODAY開発プロジェクトは、ユーザー、顧客、開発者、企画者が複数の国にまたがる多国籍プロジェクトです。多数の開発者、企画者、QAエンジニア、UITエンジニア、デザイナー、ビジネス担当者で構成され、メンバーは台湾、中国(大連)、韓国の3ヵ国のオフィスに分散していました。しかも、LINE TODAY開発プロジェクトチームは、新設されたばかりのチームでした。開発者のほとんどがLINEの開発環境と技術に慣れていない新米エンジニアで、プロダクトを開発する全体的なプロセスに詳しいメンバーもいませんでした。 また、このサービスは台湾、タイ、インドネシアなど複数の国でリリースする予定だったため、各国の様々な要望を考慮しなければなりませんでした。例えば、CP(Content Provider)によって希望するコンテンツフィードメカニズムが異なることを意識する必要がありました。台湾のCPはFTPを好み、タイとインドネシアのCPはRSSを好んでいました。 このプロジェクトはとてもタイトなスケジュールで進められました。LINE TODAYサービスは、FastTrack、RegularTrackの2回に分けてリリースされました。FastTrackではビジネスの収益性を評価するProof of Concept(概念実証)を行い、それを踏まえて継続的にサービスを運営するためにRegularTrackをリリースしました。FastTrackは設計、開発、テスト、リリースをたったの6週間で完了しなければいけませんでした。さらに、それから3ヵ月以内にRegularTrackをリリースすることが求められました。 唯一のソリューションは俊敏な対応、つまり「アジャイル」 スクラム(Scrum)は、複雑なプロジェクトに適したソリューションとして知られています。そのため、このプロジェクトにスクラムを採用し、以下の4原則を実践しました。 チームスピリット(team spirit) 自己管理と自己啓発(self-management and self-development) コミュニケーション方法論 開発方法論 では、LINE TODAY開発プロジェクトでアジャイル開発プロセスとスクラムを適用した方法をご紹介します(理解を助けるために、スクラム用語は下線付きで表示しました。例: daily stand-up meeting)。 チームスピリット(Team Spirit) 真の「アジャイル」なチームになるには、強いチームスピリットが必要です。開発プロジェクトの主要な成功要因は、スクラムプラクティスを実行するうえで常にチームスピリットを持ち続けることです。 信頼と約束(Trust and Commitment) スクラムマスターは、開発者同士、開発者と企画者、企画者とビジネス担当者間で信頼を構築できるように最善の努力注がなければなりません。そのため、開発者はスケジュールの算出と実行計画の策定に積極的に参加しました。マネジメントチームが一方的に意思決定を行うことはありませんでした。開発者は、自分で約束したスケジュールを守るために最善を尽くしました。開発者が約束した期限に合わせて作業を完了したことで、企画者は開発者を、そして主要担当者は企画者を信頼するという関係が構築されました。 方向性の提示:イノベーションとクリエイティブ 開発者がクリエイティブなアイデアを出せるようにイノベーションを奨励し、Pros/Cons分析を使って皆でアイデアを検討しました。このプロセスは、planning meetingで実行計画を議論し、タスクを分割するときに行われました。例えば、データベースのフレームワークを選択するときやデータのスキーマを決定するときに、開発者全員がPros/Cons分析に参加し、意見を出し合いました。 Why、What、How、When まず、企画者は、planning meetingやbacklog groomingで「What To Do(やるべきこと)」と「Why To Do(やるべき理由)」を開発者に説明しました。ここで大事なのは、開発者がuser storyの重要性を理解することです。次に、開発者は、planning meetingで「How To Do(どうするべきか)」と「When To Do(いつまでするべきか)」を企画者に伝えました。開発者はそのuser storyの実装にどれくらいの時間が必要かを説明し(complexity estimation)、企画者はコストパフォーマンスを分析して優先順位を調整しました。最後に、企画者と開発者とが互いに合意した優先順位に基づき、開発者はそのスプリント内でどのuser storyを完了するかを伝え、実装方法を決めました(task breakdown:タスク分割)。 自己管理と自己啓発(self-management and self-development) LINE TODAYチームにはすばらしいチームスピリットがあったため、チームリーダーは比較的容易に自己管理と自己啓発ができるスクラムチームを作り上げることができました。 Planning Meeting Planning meetingは、通常planning meeting 1とplanning meeting 2の2段階に分かれます。Planning meeting 1の主な活動は、企画者がProduct backlogにあるuser storyとepicを開発者に説明することです。また、Planning meeting 2の主な活動は、開発者がuser storyを選択してタスクを分割することです。 LINE TODAYスクラムチームは、この1段階と2段階を明確に区分していませんでした。その代わり、キーコンセプト、つまり、企画者側で構想中のuser storyを開発者が早期に把握し、理解できるように努めました。また、開発者がその場で初めて聞いたuser storyをそのスプリントですぐに完了するように求めることはありませんでした。必要であれば「backlog grooming」ミーティングを開催し、企画者が大まかなuser storyやepicを詳細に説明する時間を設定しました。なお、企画者はdaily stand-up meetingにおいて、30分を超えない範囲内で細かいuser storyを説明しました。 User storyを実現するための活動には「King and Servant」モデルを活用しました。一人の開発者がそのスプリントでkingの役割を担当してuser storyを選択し、on-time-deliveryや品質、blockerの除去など、すべて責任を取りました。他の開発者はservantとしてkingをサポートしてuser storyを完了しました。 Daily Stand-up Meeting Daily stand-up meetingは、約15分から30分かけて各自の進捗状況を共有する時間です。 スクラムマスターは、daily stand-up meetingで非常に重要な役割を担っています。メンバーの進捗状況を共有するだけでなく、チームの運営モデルを策定し、関係を構築しなければなりません。このような役割は、新規のスクラムチームにとって特に重要です。新しいチームは協力する方法を自ら模索し、成熟させていく必要があります。リーダーは、トップダウンで命令を下す司令官ではなく、提案とアドバイスをしてメンバーが自力で運営モデルを確立できるようにサポートするのが役割です。約2ヵ月ほど経過したら、LINE TODAYスクラムチームは、チームワークを発揮して開発に取り組む自主的な組織へと成長しました。 Live Demo 企画者と主な担当者にこれまでの作業の成果を説明するのは重要なことです。そのため、スプリントが終了する度にlive demoを行いました。通常、live demoではユーザーの観点からuser storyを説明します。しかし、私たち開発者は、live demoでAPIまたはテスト自動化といったエンジニアリングタスクに関するuser storyを説明しました。User (…)
↧
LINE Ad SDKを利用したテスト自動化
この記事では、LINEプラットフォームで提供している広告クライアントモジュールをテストした方法をご紹介します。LINEの広告クライアントモジュールは、モバイルとWebで使用できますが、ここではモバイルクライアントのテスト方法だけを説明したいと思います。 LINE Ads Platformの概要 LINE Ads Platformは、下図のようにシンプルな構造になっています。サーバとクライアント間の通信には多様なプロトコルが使用できますが、今回のテストはHTTPプロトコルを対象にしています。 テスト環境の概要 LINE Ads Platformはサーバ-クライアント構造のシステムですが、このような環境でクライアントの多様な動作をテストする場合は、障害になる要素がある可能性があります。テストを行う主体(人間または自動化されたシステム)は、各テストを実施する度に特定の動作をサーバに期待します。 しかし、毎回サーバを修正して期待通りの動作を誘導することは効率的ではありません。特に、サーバの失敗状態をテストするための環境を構成するのは簡単なことではありません。 このような困難を解決し、テストをより容易にするために、実際のサーバの動作を模倣するツールを使用しました。HTTPをベースにした多様なモックサーバ(mock server)ツールがありますが、LINEの広告クライアントモジュールのテストにはWireMockというツールを使用しました。下図は、WireMockを用いたテスト環境をダイアグラムで表したものです。 上図にある各要素の役割は以下のとおりです。 Mobile Device : テスト対象のアプリケーションをインストールし、そのアプリケーションをテストするためのコードが動作する実際のスマートフォン、エミュレータまたはシミュレータ。 Client App : LINE広告クライアントモジュールが使われたアプリケーション。テストコードはこのアプリケーションのUIを操作して広告クライアントモジュールSDKを動作させることで、多様なシナリオのテストを実施できる。 SDK : LINE広告クライアントモジュール。 Testing App : テストコードを含んでいるバイナリ。 Testing Helper: テストコードで使用するモジュール。テストで期待される動作をサーバに設定し、各リクエストに対する有効性を検証するために情報をサーバに依頼する機能を提供する。 Server PC : モックサーバが動作しているPC。 Server App : クライアントのテストに必要なサーバの動作を実装したサーバアプリケーションで、Javaで作成されている。基本的にはWireMockのHTTP Mock機能を使用し、自動化されたテストを実施するために必要な一部の機能を追加することもある。 WireMock : HTTPベースのサーバAPIを簡単に定義し使用できるようにサポートするオープンソースツール。 Mappings : 特定のリクエストに対するレスポンスを定義しているファイル。WireMockで使用し、JSON形式で作成される。 Response files : Mappingsに定義された一部のレスポンスを外部ファイルとして提供するときに使用する。WireMockで使用し、テキストファイルで作成される。LINE広告クライアントモジュールではJSON形式で作成されたファイルのみ使用する。 WireMockの紹介 WireMockの公式Webサイトでは、WireMockは、HTTPベースのAPIのためのシミュレータであり、サービス仮想化ツールまたはモックサーバとして考慮する価値があると紹介しています。 WireMockが提供する機能は以下のとおりです。 Stubbing : 事前に定義したマッチング情報を基にリクエストに対するHTTPレスポンスを定義し、適切なレスポンスを返す機能を提供する。 Verifying : WireMockは受信したすべてのリクエスト情報を記憶し、特定のリクエストの受信有無および詳細情報を確認できる機能を提供する。 Request Matching : URL、HTTPメソッド、Headersなど多様な属性情報を利用してリクエストを識別する機能を提供する。 Proxying : 特定のリクエストを別のホストに転送できるプロキシ機能を提供する。 Record and Playback : 転送されたリクエストとレスポンスを記録し、ファイルで保存する機能を提供する。 Simulating Faults : エラーコードを含むHTTPレスポンスまたは間違った形式のレスポンスを送信したり、レスポンスを遅延させたりする機能を提供する。 Stateful Behaviour : 状態を定義し、状態によって異なるレスポンスを定義できる機能を提供する。 HTTPS : WireMockは、必要に応じ、HTTPSでもリクエストを送信できる機能を提供する。 WireMockの使い方 WireMock機能を使用したアプリケーションを作成するためには、WireMockに対する依存性を追加する必要があります。 Mavenビルドを使用するプロジェクトでは、以下のとおり追加します。 Maven <dependency> <groupId>com.github.tomakehurst</groupId> <artifactId>wiremock</artifactId> <version>x.x.x</version> </dependency> Gradleビルドを使用するプロジェクトでは、以下のとおり追加します。 Gradle testCompile "com.github.tomakehurst:wiremock:x.x.x" コード作成中にWireMockのAPIを使用するために、以下の構文をimportします。 import static com.github.tomakehurst.wiremock.client.WireMock.*; 別途のアプリケーションを作成せず、Javaコマンドを使ってWireMockを実行できます。 リポジトリから希望するバージョンのjarファイルをダウンロードし、以下のコマンドを実行します。コマンドに対する付加オプションについては、ヘルプを参考にしてください。 $ java -jar wiremock-standalone-x.x.x.jar User Interface Testing (…)
↧
LINE NotifyにSticker送信機能と画像アップロード機能が追加されました
こんにちは。LINE Notifyの開発をしている長谷部です。 先日のblogで、コマンドラインからLINE Notifyを利用してLINEにメッセージを送信する方法についてご紹介しました。この度、LINE NotifyのAPIに画像アップロード機能とsticker送信機能が追加されましたのでご紹介します。 Sticker送信機能 先日のblogで、Jenkinsのビルド結果をLINE Notifyで通知する例を紹介しました。 そのときに、失敗時にムーンが小馬鹿にしてくる画像を送信したわけですが、ブログを書いているときに我々は気づいてしまったのです。 「…Sticker、送れるようにすれば良いのでは?」、と。 Stickerが送れると、LINEらしさもあって良さそうです。というわけで、Sticker送信機能を追加しました。 コマンドラインからStickerを送信する curlコマンドを利用してstickerを送信してみます。 $ curl -X POST https://notify-api.line.me/api/notify -H 'Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN' -F 'message=test' -F 'stickerPackageId=1' -F 'stickerId=113' といった具合に、Stickerが送信できるようになりました。 ※送信できるStickerは、documentにも記載してありますがMessaging APIと同じものになっています。 画像アップロード機能 これまでは、LINE Notifyで画像を送信する為には画像をURLで指定する必要があったため、なんらかの方法で画像をpublicサーバーに置く必要があり、少々面倒くささがありました。 LINE Notifyはユーザーのみなさんが手軽に使えることを第一に考えています。 なので、画像アップロード機能を追加することによってユーザーのみなさんが簡単に画像を送信できるようにしました。 Privateなネットワークにあるサーバーからも手軽に画像を送信する事が可能になります! 対応している画像形式やアップロード可能な回数等といった詳しい仕様は、documentをご覧ください。 コマンドラインから画像をアップロードする curlコマンドを利用して画像を送信してみます。画像はmultipart/form-dataで送信します。 $ curl -X POST https://notify-api.line.me/api/notify -H 'Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN' \ -F 'message=test' \ -F 'imageFile=@/PATH/TO/IMAGE/cony.jpg' といった具合に、画像をアップロードして送信することができるようになりました。 せっかくですので、他にも画像アップロード機能に関してもう少しだけ実用的(?)な例を紹介したいと思います。 Raspberry Piを利用して、動体検知監視カメラbotを作る 自宅のネットワーク内に設置したRaspberry Piから、MotionというOSSを利用して手軽に動体検知監視カメラbotを作る例をご紹介します。 用意するもの Hardware Raspberry Pi 3 Raspberry Pi camera module v2 OS RASPBIAN Jessie Lite 2016-09-23 手軽に手に入る小型サーバーとして、Raspberry Piと公式のカメラモジュールを利用します。OSは10/25現在で最新のRaspbianを利用しています。 設定 ネットワーク設定等、標準的な設定についてはそれぞれの環境に合わせて行ってください。Motionでカメラモジュールを利用するために、カメラの有効化とkernel moduleの読み込みを行います。 # カメラを利用できるようにカメラモジュールを有効化 $ sudo raspi-config # V4l2経由でカメラモジュールを扱えるようにkernel module読み込み $ sudo modprobe bcm2835-v4l2 $ echo "bcm2835-v4l2" | sudo tee -a /etc/modules Motion本体は、apt-getでinstallします。 $ sudo apt-get install motion # daemonとして起動したときに書き込めるようにownerを修正 (…)
↧
LINE Advent Calendar 2016のお知らせ
こんにちは、LINEで技術関連のPRを担当している三木です。エンジニアの活動をサポートする仕組みや、イベントの企画などを担当しています。 さて、タイトルの通り、LINE Engineers’ BlogにてAdvent Calendarを実施することになりましたのでお知らせします。Advent Calendarの実施は、本ブログ開設以来、初めてとなります。 本ブログでは通常、LINEのサービスに関する技術記事を関連部門のエンジニアが執筆していますが、Advent Calendarは一種の「お祭り」ということもあり、今回テーマには特に制約を設けず、自身の関心が高い技術領域について思う存分書いてください、という要件で執筆者を募集しました。結果、16名のエンジニアが手を挙げてくれました。 平日枠のみの公開となりますが(最終公開日:12/22)、初年度の開催ということでご容赦いただければ幸いです。なお、本ブログでは基本的には記事を日本語・韓国語・英語で公開しておりますが、Advent Calendarの記事は日本語版のみの公開となりますことをご了承ください。 読者の方へのプレゼントについて Advent Calendarはクリスマスシーズンのお楽しみイベントでもありますので、本ブログをご覧頂いている皆様にも、ささやかなプレゼントをご用意しました。 12月中にLINE Advent Calendarの記事をTweet(ハッシュタグ#line_advをつけてください)頂いた方から抽選で1名様に、LINEのキャラクター、ブラウンの土鍋をお送りいたします(※)。今年の冬はラニーニャ現象で厳しい寒さになると予想されていますが、この鍋をご活用頂き、体を温めることで乗り切って頂ければと思います。 (※)割れ物につき発送の関係上、国内にお住いの方のみを対象とさせて頂きます。また当選した方へのご連絡は、対象のTwitterアカウントに@LINE_DEVよりダイレクトメッセージにて行います(2017/1頃予定)。あらかじめ「設定」の「セキュリティとプライバシー」の「すべてのユーザーからダイレクトメッセージを受信する」にチェックが入っていることをご確認ください。 執筆スケジュール 日付 著者 タイトル 12/01(木) 三木 LINE Advent Calendar 2016 のお知らせ 12/02(金) munetoshi git で reviewer を探すスクリプトを作りました 12/05(月) @dxhuy エンジニアの効率を向上するために 12/06(火) Masakuni toLowerCase の落とし穴と NFKC_Casefold の話 12/07(水) Shoji Androidで日付表示をお手軽に国際化する 12/08(木) 川田 新卒で LINE Shop チームに入って Elasticserach をいじった話 12/09(金) @inamiy SwiftでElmを作る 12/12(月) Neil Comprehensive security for Enterprise Hadoop(仮) 12/13(火) 趙 HBase Cross Row, Cross Tableトランザクション処理機能を実装してみました(仮) 12/14(水) やまぐち CMakeを使ったクロスプラットフォーム開発環境 12/15(木) Kagaya Project Creation Tool: Lazybones 12/16(金) tkengo リアルタイム画風変換とその未来 12/19(月) @Yappo YAPC::Hokkaido 2016 と Fukuoka Perl Workshop #27 の登壇報告 12/20(火) 久保 Sparkと機械学習(仮) 12/21(水) @overlast mecab-ipadic-NEologd を使って最新のニュース記事をカテゴリ分類してみた (仮) 12/22(木) 愛甲 Unity Gameの分析(仮)
↧
↧
git で reviewer を探すスクリプトを作りました
こんにちは、LINE の Android Client を開発している munetoshi です。 この記事は LINE Advent Calendar2016 の 2 日目の記事です。 レビュアーを探すスクリプトを作りました 皆さん、元気にコードレビューをしていますか?レビューはしっかり行いたいものですが、適したレビュアーを見つけるのって面倒ですよね。 特にチームの人数が多い場合、私みたいな引きこもり系エンジニアには、誰が何を担当しているのかを完全に把握するのは難しいです。その割に、私は広く浅くコードに触れることも多いので、”これって誰にレビューしてもらえばいいのかなー” と途方に暮れることもあります。弊社ではコード管理に git/GitHub を使っているので、git history や blame を見ればいいのでしょうけれど、プルリクエストを作るたびにその作業をするのは骨が折れます。 そこで、 git history をたどってレビュアーに適した人を探し出すスクリプト”suggest_reviewer” を作ることにしました。 で、どうやってレビュアーを探すのさ 基本的には、git history を使ってレビュアー探すのですが、このとき以下の条件を満たすようにします。 変更されたファイルに詳しい人が、レビュアーとして選出される。 変更されたすべてのファイルで、レビュアーの誰かがレビューできる。 無駄にレビュアーを増やさない。 これを実現する方法を大雑把に説明します。まず 1 を満たすため、ファイルごとにコミット数が多い人を何人か選び、その人をレビュアー候補とします。次に 2 を満たすため、各ファイルのレビュアー候補から一人ずつレビュアーとして選出します。このとき 3 を満たすように、多くのファイルに詳しい人を優先的に選出します。 例えば、 file1 と file2 が変更された場合を想定します。ここで、A さんが両方のファイルにたくさんコミットしているなら、 A さんがレビュアーとして選出されれば十分です。もし、 file1 は A さんだけが、 file2 は B さんだけがコミットしている場合、A さんと B さんの両方がレビュアーとして選出される必要があります。 これを、あまり時間をかけずにサクッと作りたいので、git の他、ruby や基本的な UNIX コマンドは使えることを前提にします。ただ、やはりサクッと他の人 (含む Jenkins) に使ってもらうため、 RubyGems とかは使わないようにします。 で、サクッと作りました ここに ruby スクリプトをおいておきました。なかなかふんわりサクサクに仕上がったと思います。使い方は suggest_reviewer --help を見てください…ではあんまりなので、軽く説明します。 まず、 git のレポジトリに移動します。ここで、 HEAD~3 から HEAD の差分に対応するレビュアーを探したい場合、 suggest_reviewer HEAD~3 HEAD とすれば、 author1@example.com dir1/file1 dir1/file2 author2@example.com dir2/file3 とか出力されるはずです。これの意味するところは、 author1 は file1 と file2 をレビュー可能で、 author2 は file3 をレビュー可能ということです。 このスクリプトは内部的に git diff を使っているので、 (…)
↧
LINEのエンジニアリングを支える社内ツール
この記事は LINE Advent Calendar2016 の 3 日目の記事です。 はじめに はじめまして、LINEの@huydxです。現在「Engineering Efficiency」というかっこいい名前のチームに配属されています。日常の仕事では、社内のモニタリングミドルウェア、自動化ツールの開発などにおいて、主にバックエンド側を担当しています。エンジニアリングで組織全体の生産性と幸せを向上することです。この記事では、チームの取り組み、そして個人的な気づきなどを紹介させていただきます。 背景 現在私が所属している部署はLINEメッセージのバックエンド側を担当しています。システムの規模が大きくなるとともに、組織全体も大きくなる一方です。ソフトウェアのスケールはもちろん難しいですが、組織のスケールも簡単なことではありません。 もちろん、体制、マネージメントなどで頑張って、組織を小さく分割するなどの方向で進むところもあります。ですが、LINEメッセージプラットフォームの特徴として、モノリシックな「Talk-server」という巨大なJavaアプリが中心に存在し、たくさんの開発者がそこに毎日コントリビュートしています。そこで、効率良く安全にLINEメッセージ基盤を提供するためどうしてもマネージメントだけでは無理なところがあって、そこでちゃんとエンジニアリングで解決できるものを解決し、エンジニアたちが安心して効率よくパフォーマンスを出るようにするのが私のチームのミッションのひとつです。 基本の解決方針としては Painful Pointを発見して、自動化できる(また自動化すべき)ところを自動化する 新しい技術、ベストプラクティスを導入することによりプロセスを改善する 良いモニタリングシステムと良いデプロイシステムを提供することで、より早く、安全でソフトウェアを開発を進むことを可能にする その方針に沿って、最近の取り組みや気づきを簡単に紹介します。 プロセスをコードで表現 現在の部署では多くの人々がいくつかのメインリポジトリで毎日開発を進めています。大人数のエンジニアがお互いに何をしているかを把握しないと混乱が発生してしまうので、ちゃんと定義したプロセスとコンベンションに従わないといけない。そのプロセスは一昨年のブログで紹介されていますので、是非ご覧ください。記事を読んでみると分かると思いますが、フォローするのはなかなか大変です。ただ大変とはいえ、LINEのようなプラットフォームでは、安全にソフトウェアをリリースするために欠かせないプロセスとなります。 その大変さをどうやって解消するか工夫していて、最近の取り組みのひとつとして「Process As A Code」という概念を私が独自に定義しました。つまり、プロセスそのものを全部コードで表現して、表現したものをツールとして実装すれば、エンジニアが手軽にプロセスをフォローすることができ、ストレスも解消できると考えます。ツールはすごく簡単なコンマンドラインツールで、使い方も日常よく使われているコンセプトに基づいて気軽に使えます。 $lineflow talk-server Usage: lineflow talk-server new-develop-branch <BTS-ID> lineflow talk-server develop-pull-request [--skip-mvn-test] lineflow talk-server commit [--add-all] [--no-issue] [--squash] <message> lineflow talk-server release-cherry-pick lineflow talk-server release-pull-request [--skip-mvn-test] lineflow talk-server rc-create [--push-new] lineflow talk-server version-commit [--increase-patch] [--increase-minor] [--increase-major] <version> ツールの中でJIRA, GitHub Enterprise, 社内のデプロイシステムを全部連携して、自動化できるところを全部自動化し、また、過去のコマンドをヒストリーファイルに保存して、「次にどのコマンドを打てば良いか」を推薦する機能なども開発しています。新しいプロセスを追加するとき、またはコンベンションを変えるときには、コードにそれを反映して、チーム全員がツールの最新バージョンを更新すれば同じコンベンションをフォローできますよね。新しいメンバーが入るときに、ややこしいプロセスに邪魔されず、すぐに開発を進めることも期待できます。 社内ツールを作るときの考え方 現在、チームが開発しているソフトウェアは「社内ツール」と呼ばれていますが、「社内ツール」には特にAPIとか認証とかいらないなというイメージを持っている方が多いと思います。しかしながら、私たちの考えは社内ツールだからこそ以下の性質を持たないといけないと考えています。 使いやすいAPIを提供する 認証ができ、監査がしやすい状態にする コード品質とプロダクトの方針を明確に定義する ドキュメントを充実させる まずAPIさえあれば、チーム内のコラボレーションがやりやすくなり、ユーザ(開発者)自身による自発的なツール開発もできます。逆に APIがないと、直接DBを接続して変更したりすることになりうるので結合度が密になって変更しづらくなってしまい、システムが更新できなくなります。APIは基本的なHTTPのRESTで設計されいるので簡単にcurlを使ってテストができ、また、手軽にswaggerなどを使ってウェブUIで使い方などを確認できます。 認証についてですが、大人数が同じリポジトリを触っていて、同じサーバクラスターにデプロイするので、安全性を保つためには、「誰が何をできる」かをちゃんと認可(Authorize)できることが要求されます。そこで、現在のチームではOAuthベースの認証システムを開発しており、基本的な操作はウェブUI、あるいはトークンベース認証のAPIを通じて操作するので、全部の操作はログで残していて、なにかある場合はトラブルシューティングがしやすいです。 社内ツールというのは、短期的な目的に対しての簡単なハックかスクリプトになりがちでしょう。ただそうなると、大きい組織全体にはスケールできず、要求の変更によるメンテナンスがしづらいので、費用対効果は良くありません。なので、最初からツールの目的、使えるスコープ、利用シナリオなどをちゃんと考慮して開発しないといけません。また、オープンソースに向けて開発を進めるのが一番オススメです。 最後に、社内ツールだからこそドキュメントはエンドユーザ向けのアプリケーションよりも充実しないといけないません。ドキュメントが足りないと、誰も使ってくれませんし、逆にドキュメントが充実していればユーザから積極的にコントリビュートしてくれるでしょう。良いドキュメントであるためには、ちゃんと以下の項目が存在すれば良いと思います。 ツールを作った背景 ツールのアーキテクチャ どうやってコントリビュートするのかを明確に書く 社内開発をやるか、あるいはオープンソースを利用するのか 現在のチームでは、モニタリングツール、デプロイツールなどを全部自社で開発しています。なぜオープンソースが使われていないか、という疑問を持っている方もいると思います。もちろん、オープンソースで使えるところでは積極的にJenkinsなどのオープンソースを使っていますが、LINEのスケールに合わない、過去の経緯やインフラストラクチャーの構成に合わない、またはセキュリティなど色々な問題に囲まれて、オープンソースがフィットしない場面もあります。 その時はちゃんと開発リソースを確保して開発しないとLINE本体のシステムに影響がでてしまうこともあります。一方で、社内の開発だけに頼ると、現在の技術トレンドやベストプラクティスに追いつくのが大変ですので、両方をうまく組み合わせるのがベストです。 最近の取り組みのひとつを紹介します。現在社内のモニタリングシステムが自社で開発されて、IMONというシステムを担当しています。IMONはデータ収集、チャートの表示、アラート・ノーティフィケーション管理などを全部含めるAll-In-Oneのシステムで結構便利に使えるシステムです。 ですが、いままでのユーザが毎日見ないといけないIMONのチャート表示機能は簡単なチャートしか表示できていません。豊かなダッシュボードを作りたい、アノテーション機能ほしい、テンプレート機能ほしいなど様々なユーザからたくさんの要求があり、その機能を全部ちゃんとサポートするのはかなり時間がかかるし、工数もすごいかかる見込みなのでGrafanaを利用することを選択しました。 IMONのデータソースを開発し、Grafanaにグラフ表示とダッシュボード作成などを任せることにしました。これにより、Grafanaに慣れている多くの開発者にとって使いやすくなり、Grafanaのたくさんの機能を流用することも可能になって、工数の削減もできてとてもよかったと感じていました。今後私たちのチームもフィットするところを探して積極的にオープンソースなども導入する方針を進めていきます。 結論 話が長くなってしまいましたが、現在のチームでは、エンジニアのためのものづくりで毎日楽しくソフトウェア開発ができています。グロバールサービスで使われている最高のモニタリングシステム、便利なデプロイシステム、そしてエンジニアの幸せを向上するさまざまなシステムを開発するエンジニアを積極的に募集しています。 https://linecorp.com/ja/career/position/664 明日はMasakuniさんによる「toLowerCaseの落とし穴とCase Foldingの話」についての記事です。お楽しみに!
↧
toLowerCaseの落とし穴とCase Foldingの話
こんにちは。LINEでAndroid Clientを開発しているMasakuniです。 これはLINE Advent Calendar 2016の4日目の記事となります。 LINEのアプリ・サービスは多くの国で使われているため、国際化や多言語化はサービス開発時における重大なテーマの一つです。 今回は、その中でも「大文字・小文字変換」について話をします。 Javaにおける String#toLowerCase() / toUpperCase() の挙動 まずは一つ、問題を出してみましょう。 Q. 以下のJavaテストコードは常にpassすることが保証されているでしょうか? A. No. 一見単純なテストコードですが、これはJavaの実行環境によっては失敗することがあります。何故かと言うと、 "I".toLowerCase() は "I".toLowerCase(Locale.getDefault()) と等価であり、実行環境のデフォルトロケールによって動作が変わるからです。 具体的には、ロケールがトルコ語(“tr”)のときに上記のテストは失敗します。トルコ語ではドット付きのIとドット無しのIが区別されており、”I”に対応する小文字は “ı” (U+0131, LATIN SMALL LETTER DOTLESS I) で、”i”に対応する大文字は “İ” (U+0130, LATIN CAPITAL LETTER I WITH DOT ABOVE) となります。 つまり、Javaのテストコードで書くと以下のようになるわけです。 別の例を挙げましょう。Grave accentが付いている “Ì” (U+00CC, LATIN CAPITAL LETTER I WITH GRAVE) に対応する小文字は、多くのロケールにおいては “ì” (U+00EC, LATIN SMALL LETTER I WITH GRAVE) になります。しかしリトアニア語(“lt”)においては、”i” (U+0069, LATIN SMALL LETTER I, 普通のi) に結合文字 U+0307 (COMBINING DOT ABOVE) と U+0300 (COMBINING GRAVE ACCENT) が続いた “i̇̀” (U+0069 U+0307 U+0300) となります。つまり、Javaテストコードでは以下のようになります。 このようにUnicodeでのキャラクター数が増加する変換は他にもあります。たとえば、ドイツ語の ß (U+00DF, LATIN SMALL LETTER SHARP S) いわゆるエスツェット(Eszett)は大文字に変換すると “SS” になります。 もっと厄介な例としては、ギリシア文字の小文字シグマがあります。これは通常 σ (U+03C3, GREEK SMALL LETTER SIGMA) で表されますが、単語の末尾では字形が変化した ς (U+03C2, GREEK SMALL LETTER FINAL (…)
↧
Androidで日付表記をお手軽に国際化する
こんにちは、LINEでAndroid clientを開発しているShojiです。何故か一部からはビルド王子と呼ばれています。この記事はLINE Advent Calendar2016の5日目の記事です。 Androidアプリの日付表記の国際化 せっかく頑張ってコードを書いて、テストしたAndroidアプリなら海外含めて沢山の人に使って欲しいですよね? LINEは海外でも使われているのでUIテキストの翻訳をするのは勿論ですが、アプリの国際化はUIの翻訳に限りません。特にLINEはアプリの性格上日付表示がUI上に多く、このフォーマットを各言語文化にあった形で表示する必要があります。 同じ英語でも、皆さんも中学校の英語の授業できっと習ったように、 イギリス式: Fri, 18 Nov 2016 アメリカ式: Fri, Nov 18, 2016 と月日の順序が違ったりします。 アメリカ英語とイギリス英語ぐらいなら各言語用のフォーマットを用意して、こんな風にRクラス経由で 対応することも出来なくは無いですが、対応言語が増えると果たして出力されたテキストがネイティヴにとって自然かの検証が微妙な感じです。海外製アプリだと有名どころでも日本語設定で「11月 16, 2016」と表示されてしまったり、それがデザインが良い感じ風なAndroid WearのWatch faceだったりするともう残念感がハンパないです。せっかくMoto 360 2nd gen買ったのに・・・! android.text.format.DateUtils そこでandroid.text.format.DateUtilsの出番です。 https://developer.android.com/reference/android/text/format/DateUtils.html で、Android端末の言語設定を切り替えると イギリス英語: Fri, 18 Nov 2016 アメリカ英語: Fri, Nov 18, 2016 日本語: 2016年11月18日(金) と良い感じに出力してくれます。「2016/11/18」のような表記が欲しい場合は、 とFORMAT_NUMERIC_DATEを指定すれば イギリス英語: 18/11/2016 アメリカ英語: 11/18/2016 日本語: 2016/11/18 と、こちらもちゃんとイギリス英語とアメリカ英語の慣習の違いを反映してくれます。 ただし、Android APIなのでOS versionよって微妙に動作が異なる事があり、例えば、 で、 Android 6.0: 2016年11月18日(金) Android 4.1: 2016/11/18 (金) で、 Android 6.0: 2016年11月18日金曜日 Android 4.1: 2016年11月18日 (金) と挙動にぶれがあります(エミュレータにて動作確認)。小さいTextViewに表示する際にはOS versionによって見切れてしまっていないかなどの検証をしましょう。 DateUtilsにはformatDateTime以外にも「5分前」や「3日前」などを各言語で出力する、SNSのFeed向けなgetRelativeTimeSpanStringなどもあります。 で出力すると、 日本語: 3 日前 英語: 3 days ago フランス語: Il y a 3 jours と日本人プログラマがつい忘れがちな複数形も自動的に処理できます。 さらに挙げれば、日本語では「2016年に」も、「金曜日に」も、「9時に」も、同じ「に」ですが、英語ではそれぞれ”in 2016″、”on Friday”、”at 9″と前置詞が異なります。(中学校でやりましたね!) とwithPrepositionをtrueにすると適切な前置詞付きで出力してくれます。 日本語: 11月18日 英語: on Nov 18 フランス語: le 18 nov. 写真データの注釈としてや、過去のイベントを表示するUIなどで便利だと思います。 いずれのAPIもOS version間での挙動差分や、ビジネス上アプリで必要な言語をAPIが対応してくれるかの検証は必要ですが、デザイン的な制約が少ない箇所であればお手軽な日付表示の国際化としてオススメです。 Android 7.0 (…)
↧
↧
Elasticsearch を検索エンジンとして利用する際のポイント
こんにちは、LINE でスタンプ・着せかえショップのバックエンド開発をしている川田 (@hktechno) です。 この記事は、LINE Advent Calendar 2016 の 6 日目の記事です。 今年の4月に、Java も Elasticsearch もまともに知らなかった新卒エンジニアが Elasticsearch クラスタの管理を突然任されて苦労した話をしようと思います。 Elasticsearch とは Elasticsearch は、Elastic 社が開発している検索・分析エンジンおよびそのストレージを担うソフトウェアです。簡単に言えば、検索に特化したクエリを投げることができるデータベースのようなものです。No-SQL 型の DB といっても良いと思います。 Elasticsearch のすごいところは、大量のドキュメントの中から形態素解析や n-gram など自然言語的な解析を行った上で、素早く検索クエリを処理でき、かつノードを増やすことで簡単にスケールアウトすることができることです。最近では、Elasticsearch は様々なログの収集・分析にも使われるようになっていて、どちらかと言うとログ収集で苦労した話が多いと思います。ちなみに、私の所属しているチームでは、ログ収集・メトリック分析ツールとしても Elasticsearch を利用しています。 しかし、今回はログ収集ではなく、実際にプロダクション環境で検索エンジンおよびデータベースとして利用した場合の Elasticsearch の苦労した点について書こうと思います。このような情報はあまり多くないので、参考になれば幸いです。 LINE Shop とは ところで、私達のチームは LINE Shop と呼ばれていて、主に LINE 内のスタンプや着せかえを担当する部署となっています。LINE を利用したことのある方であれば、有料スタンプや着せかえを販売している LINE 内のショップを見たことのある方も多いと思います。 この2つのショップと、Web 上でスタンプや着せかえを購入することができる LINE STORE は共通のバックエンドを共有しています。LINE Shop では、Elasticsearch を広範囲に利用していて、実際にみなさんがスタンプショップなどへアクセスする際の殆どのレスポンスは Elasticsearch を利用したものとなっています。 具体的にどの部分かというと… スタンプ・着せかえ検索 人気ランキング・新着などのリスト生成 カテゴリーリスト生成 あなたへのおすすめ など、ただのキーワード検索用途だけではなく、ほぼすべてのリスト表示系のデータベース用途として利用しています。 LINE Shop 内部は、Armeria を使ったマイクロサービスとなっていて、大幅に単純化して説明すると以下のような構造になっています(Armeria について詳しくは LINE Developer Day の発表スライド LINE Shop powered by Armeria をご覧ください)。 内部にSearchFe というサービスが存在し、このサービスが Elasticsearch へのリクエストのフロントエンドとなってリクエストの変換やクエリ生成及びキャッシュを担当しています。 また、スタンプ向けの MySQL と着せかえ向けの MongoDB も内部では利用しており、詳細表示や購入系などのリクエストはこちらのデータベースが担当しています。 なぜ Elasticsearch を使うのか LINE Shop で Elasticsearch を利用するモチベーションとしては、様々ではありますが代表的なものは以下の2点です。 内部的にスタンプと着せかえで利用しているデータベースの種類が異なる (MySQL と MongoDB) ので、これらのクエリを共通化するため LINE Shop で表示するリストの掲載・ソート条件は、国やデバイスタイプ、その他属性により複雑なため、柔軟なクエリを処理できる必要がある LINE Shop の場合は、それほどドキュメント数が多くない (商品情報は 500,000 程度) こともあり、Elasticsearch (…)
↧
SwiftでElmを作る
この記事は、LINE Advent Calendar 2016の 6日目の記事です こんにちは、開発1センター・開発2室の 稲見 (@inamiy) です。 普段はiOSエンジニアとしてSwiftを書いていますが、最近はもっぱら関数型プログラミング全般に興味があります。 今日は、「SwiftでElmを作る」というテーマで、お話しさせていただきます。 Elmって何? Web向けの静的型付け・関数型プログラミング言語です。詳しくは http://elm-lang.org をご参照ください。 簡単に言うと、「Haskell + React.js + Redux」です。コンパイル時に、JavaScriptに変換されます。 さっそく、簡単なボタンカウンターの例を見てみましょう。 import Html exposing (beginnerProgram, div, button, text) import Html.Events exposing (onClick) -- `main`関数 = プログラムの始まり。 -- 初期状態(model)に`0`をセット + 以下にあるview関数、update関数をセット。 main = beginnerProgram { model = 0, view = view, update = update } -- `view`関数 = モデル(状態)からビュー(Virtual DOM)を生成。 -- プログラムがメッセージを受け取る度に呼ばれる。 -- ユーザー入力(onClick)等の度に、プログラムにメッセージが送られる。 view model = div [] [ button [ onClick Decrement ] [ text "-" ] , div [] [ text (toString model) ] , button [ onClick Increment ] [ text "+" ] ] -- `Msg` = メッセージ型。今回は2つのパターンだけ定義。 type Msg = Increment | Decrement -- `update`関数 = (…)
↧
Comprehensive Security for Hadoop
(This is the 8th article of LINE Advent Calendar 2016) Hello everyone, this is Neil Tu from Data Labs. I am in charge of Hadoop architecture at Line Corp. I construct and manage Hadoop clusters and their ecosystems, and supply a high availability, and high performance platform for the engineers and data analysts in our group. Today, the topic we are going to talk about is “Comprehensive Security for Hadoop”. Abstract Nowadays, Hadoop has become a popular platform for data storage, data analysis, reporting, and distributed calculations. Basically, Hadoop cluster is an open platform that supplies users with the required resources and HDFS capacity to execute queries. But as you (…)
↧