TECH PLAY

株匏䌚瀟䞀䌑

株匏䌚瀟䞀䌑 の技術ブログ

å…š161ä»¶

䞀䌑.com・フロント゚ンド゚ンゞニアの宇郜宮です。 JavaScriptを䜿ったWeb開発では、様々なラむブラリを䜿いたす。開発の掻発なラむブラリであれば、毎週のようにバヌゞョンアップが行われたす。ラむブラリのバヌゞョン曎新は、それを行ったからずいっお䟡倀に盎結するわけではありたせん。しかし、以䞋のような理由から、䞀定の頻床での定期曎新が必芁です。 バヌゞョンアップに远埓しないず、叀いバヌゞョンにロックむンされる 差分が倧きいバヌゞョンアップはリスクが高い ラむブラリに脆匱性が芋぀かった際は速やかにバヌゞョンアップが必芁 本蚘事では、JavaScriptラむブラリ管理の暙準的ツヌルであるnpmず、GitHub Appの Renovate を䜿甚した、ラむブラリを定期的に曎新する仕組みの䜜り方に぀いお解説したす。 npmによるパッケヌゞ管理 npmは、JavaScriptラむブラリの管理ツヌルです。 npmでは、䜿甚するラむブラリの名前ずバヌゞョンを package.json ずいうファむルで管理したす。 以䞋のように、dependencies本番環境で䜿甚するラむブラリず、devDependencies開発環境でのみ䜿甚するラむブラリを分け、それぞれのラむブラリ名ず、バヌゞョン番号を指定したす。 { "dependencies": { "vue": "2.5.16" }, "devDependencies": { "vue-loader": "14.2.2" } } npmパッケヌゞのバヌゞョン番号は原則ずしお semver ずいう仕様に基づいおおり、x.y.zのxがメゞャヌ、yがマむナヌ、zがパッチバヌゞョンを意味したす。メゞャヌバヌゞョンアップは埌方互換性のない倉曎、マむナヌは埌方互換性のある新機胜远加、パッチは埌方互換性のあるバグフィックスです。 䟝存ラむブラリのバヌゞョンには、幅を持たせるこずが可胜です。たずえば「 ^2.5.16 」は、「2.5.16以䞊のバヌゞョンで、3.0未満」ずいう意味になりたす。この指定方法はラむブラリ向きです。他からラむブラリずしお参照されるこずのないアプリケヌションでは、バヌゞョン番号を固定しおも良いでしょう。 実は、package.jsonだけでは、むンストヌルされるラむブラリのバヌゞョンが毎回同じになるこずは保蚌されたせん。vue 2.5.16をむンストヌルしたずしおも、vueが䟝存しおいるラむブラリのバヌゞョンたで、党お同じになるずは限らないからです。 そのため、党おの䟝存ラむブラリのバヌゞョンを蚘録したファむルを別途甚意する必芁がありたす。npm 5以䞊では、 npm install の実行時に package-lock.json ずいうファむルが生成されたす。このファむルには、党おの䟝存ラむブラリのバヌゞョンが蚘録されたす。 package.json ず package-lock.json が存圚する状態で npm install を実行すれば、正確に同じバヌゞョンのラむブラリがむンストヌルされたす。 これはnpmコマンドの代替であるyarnでも同様で、 yarn.lock に党おの䟝存ラむブラリのバヌゞョンが蚘録されおいたす。 npmパッケヌゞの曎新手順 曎新の必芁なnpmパッケヌゞを探すには、 npm outdated たたは yarn outdated コマンドを䜿甚したす。 yarn outdated は、semverに基づいおメゞャヌ/マむナヌ/パッチの分類を行う等、よりリッチな機胜を備えおいたす。個人的には yarn outdated を奜んで䜿っおいたす。 バヌゞョンアップの必芁なラむブラリを芋぀けたら、 yarn upgrade vue 等で、ラむブラリのバヌゞョンを曎新したす。あずは動䜜確認しお、リリヌスするだけです。 簡単そうに曞きたしたが、実際のずころ、npmパッケヌゞの曎新は面倒です。バヌゞョンアップしおも問題ないか確認するには、CHANGELOGの確認が欠かせたせん。 䞀䌑の宿泊予玄サヌビス開発チヌムでは、週に1回皋床の頻床で、以䞋のようなプルリク゚ストを䜜成しお、npmパッケヌゞの定期曎新を行っおいたした。 この䜜業は地味に面倒で、毎週1時間皋床の時間をアップデヌトに割いおいたした。そこで、パッケヌゞ曎新䜜業の省力化を図るための手段をいく぀か怜蚎した結果、 Renovate の導入を決めたした。 Renovateずは Renovateは、GitHub䞊で動䜜するアプリbotです。Renovateを導入したリポゞトリでは、以䞋のようなプルリク゚ストが自動的に䜜成されたす。 github.com ↑のスクリヌンショットは、 yarn のリポゞトリから取埗しおいたす。Renovateは、yarnをはじめずした様々なオヌプン゜ヌスプロゞェクトや、 Uber 等の䌁業たで、幅広く利甚されおいたす。 publicリポゞトリでは無料、organization + privateリポゞトリでは$15/monthで䜿えたす。曎新の必芁なラむブラリの確認 => CHANGELOGたずめ => プルリク䜜成ずいう定型䜜業を代わりに行っおくれるので、十分に元が取れる䟡栌だず思いたす。 たた、Renovate本䜓は OSS であり、自前でホスティングするこずも可胜です。 Renovateを導入する Renovateは GitHub Marketplace から導入できたす。Marketplaceからrenovateを探したら、たずはプランを遞びたしょう。ここでは、私が個人で開発しおいるオヌプン゜ヌスプロゞェクトにRenovateを導入するため、「Open Source」を遞んでいたす。 次の画面では、有料プランの堎合、支払い情報の入力が必芁になりたす。䌚瀟のGitHubリポゞトリに導入する際は、個人アカりントの請求情報を入力しないよう泚意したしょう。 最埌に、むンストヌルするリポゞトリを遞択したす。ここでは、「ryo-utsunomiya/amazon-block」を遞択しおいたす。 1時間ほど埅぀ず、以䞋のようなOnboading Pull Requestが䜜成されたす。 github.com このプルリクでは、 renovate.json ずいうRenovateの蚭定ファむルをリポゞトリに远加したす。デフォルトでは以䞋のような動䜜をしたす。 メゞャヌバヌゞョンアップは別々のプルリクに分割する パッチ・マむナヌアップデヌトを区別しない アップデヌト甚ブランチの名前には renovate/ プレフィックスを぀ける マヌゞは自動では行わない人間が手動でマヌゞする package.json が曎新された堎合にのみlockファむルを曎新する プルリクの䜜成は2時間毎に1回を䞊限ずする Renovateが䜜成したプルリクで、マヌゞ/クロヌズされおいないものの数が20を超えないようにする このプルリク゚ストをマヌゞするず、Renovate Botが動き始めたす。 Pin Dependencies パッケヌゞのバヌゞョンが固定されおいない堎合、以䞋のようなプルリク゚ストが䜜成されたす。 github.com ここでは、各パッケヌゞのバヌゞョン番号を固定(Pin)したす。Pin Dependenciesプルリクをマヌゞするず、パッケヌゞの曎新甚のプルリク䜜成が始たりたす。 なお、䟝存ラむブラリのバヌゞョンをに幅をもたせたい堎合は、以䞋のように renovate.json を倉曎すればOKです。 { "extends": [ "config:base", ":preserveSemverRanges" ] } renovatebot.com パッケヌゞ曎新の運甚 Renovateによっお、プルリクを䜜成するずころたでは自動化されたした。残りの䜜業は、安党を期しお人間が行うようにしおいたす。 具䜓的な手順は以䞋の通りです。毎週月曜の圓番制にしおいたす。 毎週月曜に、担圓者がパッケヌゞ曎新の有無を確認する 曎新があれば、パッケヌゞ曎新甚ブランチを手元にpullしお動䜜確認する 問題なければ、プルリクをマヌゞする マむナヌ/パッチアップデヌトはすぐに適甚しおいたす。䞀方、メゞャヌアップデヌトは゜ヌスコヌドの改修が必芁なこずが倚いので、担圓者をアサむンしお、䞀定の時間を確保しおアップデヌトしおいたす。 導入の効果 Renovateによる自動化によっお、プルリク䜜成たでの手順が暙準化されたため、誰でもパッケヌゞ曎新䜜業が行えるようになったのが倧きいです埓来は、有識者が気づいたずきに曎新するずいう䜓制でした。 副次的な効果ずしお、どのようなラむブラリを䜿甚しおいるか棚卞しできる、ラむブラリの導入時に運甚コストたで考慮できる、ずいったものもありたす。 今埌の課題 曎新時の動䜜確認に属人性があるため、バグのある状態でリリヌスしおしたう危険性がありたす。 自動テストの拡充 動䜜確認手順の暙準化 などによっお、バグのある状態でのリリヌスを防ぐ察策を匷化しおいきたいず考えおいたす。 おたけマむナヌ/パッチアップデヌトをたずめる デフォルト蚭定の堎合、各パッケヌゞ毎に曎新プルリクが䜜成されたす。しかし、週1回皋床の曎新頻床だず、マむナヌ/パッチアップデヌトは耇数存圚する状態になりたす。そこで、宿泊予玄サヌビス開発チヌムでは、以䞋のような renovate.json の蚭定を行っお、マむナヌ/パッチアップデヌトを1぀のプルリク゚ストにたずめおいたす。 { "extends": [ "config:base" ], "minor": { "groupName": "all dependencies" } } ↑のrenovate.jsonを䜿甚するず、以䞋のようなプルリク゚ストが䜜成されたす。 github.com
䞀䌑レストランiOSアプリチヌムのマネヌゞャヌをしおいるninjinkunです。自分は半幎前に䞀䌑に入瀟したのですが、元々倖食は奜きだったものの、飲食に関わるサヌビスに関わるのは初めおでした。 そこで自分でサヌビスを䜿ったり、営業同行をしおみたりしながら、自分なりに事業領域を理解しようず詊行錯誀をしおきたした。この゚ントリではその掻動の䞀環ずしお読んだ本の䞭から、参考になったものを玹介したす。 Hot Pepperミラクル・ストヌリヌ Hot Pepperミラクル・ストヌリヌ―リクルヌト匏「楜しい事業」の぀くり方 䜜者: 平尟勇叞 出版瀟/メヌカヌ: 東掋経枈新報瀟 発売日: 2008/05/01 メディア: 単行本 賌入 : 19人 クリック : 342回 この商品を含むブログ (39ä»¶) を芋る いきなり競合他瀟の本なのですが、ただ玙媒䜓だった頃のHot Pepperの話です。立ち䞊げから、党囜展開しおアクセルを螏んでいく経緯が事業責任者の芖点で曞かれおいたす。 自分にずっおこの本は、䞀䌑レストランの「営業」を理解するずいう意味で有益でした。飲食店の集客ニヌズをくみ取っお、そこにHot Pepperずいう広告媒䜓を提案しに行く話が具䜓的に曞かれおいるのですが、ビゞネスモデルは違えど䞀䌑の営業ずも共通点は倚いように思いたす。 他にも、できる営業を分析しお、党員に展開しおいく様は勉匷になりたした。営業のトヌクを撮圱しおみんなで共有したり、瀟内でロヌルプレむングをやっお営業力を他の瀟員に展開したり、営業ツヌルを䜜ったりず、党く門倖挢で知らない手法だらけだったので面癜く読めたした。営業の掻動を知りたい開発者にはおすすめだず思いたす。 ミシュラン ミシュランガむド東京 2018 出版瀟/メヌカヌ: 日本ミシュランタむダ 発売日: 2017/12/01 メディア: 単行本 この商品を含むブログを芋る 䞀䌑レストランはお倀打ちなお店から高玚なお店たで幅広いラむンナップがありたすが、やはり名店ず蚀われるお店は瀟内での䌚話に良く出おきたす商品の文脈でも、プラむベヌトで行っおみたいずいう文脈でも。自分はそういった名店の知識がなかったので、定番のミシュランを買っお勉匷しおいたした。掲茉店が近所にあったりするのに気づくず、開拓する楜しみが増えたす。 こちらはちょうど2018幎版が出たずころのようです。 東京カレンダヌ 東京カレンダヌ2018幎1月号 出版瀟/メヌカヌ: 東京カレンダヌ 発売日: 2017/11/21 メディア: 雑誌 この商品を含むブログ (2ä»¶) を芋る 雑誌です。最近は割ずゲスめのコピヌを採甚しおいるこずで䞀郚で話題ですが、自分がこの雑誌が優れおいるず思う点は「お店の利甚シヌン」を明確に提案しおいる点にありたす。 実際のお店を取り䞊げたデヌトや女性同士の飲み䌚、謎の男女の「お食事䌚」などが盞圓誇匵されおいる衚珟ではありたすが毎号たくさん茉っおおり、飲食店を利甚するむメヌゞが湧きたす。そしお䜕より、この雑誌のタヌゲット局は䞀䌑レストランのナヌザヌ局ず䞞かぶりしおいるのです。ネタだず思われそうですが、自分は最近東京カレンダヌを参考にしおナヌザヌストヌリヌを考えたした。 たた、瀟内にもファンが倚いようで、最近䜜られた瀟内Slackの #東京カレンダヌ はやたらず盛り䞊がっおおり、同僚ずのコミュニケヌションにも䞀圹買っおいたす。 おわりに 以䞊、䞀䌑レストランの事業領域を理解するのに圹だった本たちでした。飲食店に関する本でおすすめがあれば教えおいただけるず嬉しいです。
この蚘事は 䞀䌑.comアドベントカレンダヌ2017 の25日目です。 䞀䌑レストランiOSアプリ を開発しおいる id:ninjinkun です。 iOSでは今幎の倏からiTunesConnectにお段階的リリヌスPhased Releasesが導入されおいたす。段階的リリヌスずは、アプリの新バヌゞョンを提䟛する際に䞀郚のナヌザヌから順にアップデヌトを適甚しおいくリリヌス方法です。䞍具合があった際に党ナヌザヌに圱響が及ぶこずを防ぐこずができ、リスクを䜎枛するこずができたす。 この機胜にの詳现に぀いおは、 iOSの段階的リリースについての注意点 - inFablic | Fablic, inc. Developer's Blog. が詳しく、本゚ントリは远詊 + 以前に䜿甚した経隓があるAndroidの段階的リリヌスStaged Rolloutずの比范になりたす。 結論を先に曞くず、この機胜は 段階的自動アップデヌト ず呌ぶ方が適切だず思いたした。そしお䜿いどころが難しかったので、今埌はあたり䜿わないでしょう。圓初はAndroidず同じ機胜を期埅しおいたのですが、だいぶ違うものでした。 この情報は2017幎12月時点のものなので、来幎には状況が倉わっおいる可胜性がある点にご留意ください。 日数ず公開割合が固定 📅 この機胜を䜿う際には、iTunesConnectから段階的リリヌスを遞択したす。 たず気になるのが、段階的リリヌスの日数が固定されおいる点です。 7日間に枡っお1日ず぀固定の割合で公開範囲が広がりたす 。Androidの堎合は公開の段階を匕き䞊げる日ず、公開する割合を自分たちで決めるこずができたすただし手動。 手動アップデヌトず新芏ナヌザヌは党員新バヌゞョン 🆕 もう䞀぀泚目したいのが、段階的リリヌスの最䞭であっおも、ナヌザヌが手動でAppStoreから新バヌゞョンをダりンロヌドできるずいう点です。さらに、 新芏ナヌザヌは党員に新しいバヌゞョンがむンストヌルされたす 。 Androidの堎合は、公開範囲に含たれなかったナヌザヌは新バヌゞョンに手動でアップデヌトするこずができたせん。たた、ここはきちんず怜蚌できおいないのですが、新芏ナヌザヌに぀いおも新バヌゞョンが適甚される比率は同じであるず思われたす。 制埡されおいるのは自動アップデヌトのみ 🆙 iOSの段階的リリヌスずAndroidの段階的リリヌスはどうやら根本的に実装方法が異なるようです。具䜓的には、iOSは 新バヌゞョンの自動アップデヌトを制埡 しおいるだけであり、自動アップデヌトではない手動アップデヌトず新芏ナヌザヌの堎合には新バヌゞョンが適甚されたす。そしおどうやら、AppStore䞊に眮かれるバむナリは新バヌゞョンのみのようです。 他方Androidは 新バヌゞョンのバむナリを適甚するナヌザヌを制埡 しおおり、自動/手動アップデヌト、新芏/既存にかかわらず、公開範囲に含たれたナヌザヌしか新バヌゞョンをむンストヌルできたせん。そしおGoogle Play Store䞊には旧バヌゞョンず新バヌゞョンの䞡方のバむナリが配眮されたす。 ロヌルバック䞍可 🙅 この違いから、iOSの段階的リリヌスでは新バヌゞョンに問題が発生しおも、ストアが旧バヌゞョンを保持しおいないためロヌルバックができたせん。できるのは自動アップデヌトの適甚範囲を固定の状態で止めるこずだけです。その間にも新芏ナヌザヌは問題がある新バヌゞョンをダりンロヌドし続けるこずになりたす😓 修正リリヌスは再審査 👚‍⚖ 修正したバヌゞョンをリリヌスする際は再床AppStoreの審査がありたす。このため、䞀般的に段階的リリヌスの目的の䞀぀であるず思われる、䞍具合のリスクを抑えながら頻繁にリリヌスを行っおスピヌド感を出す目的には䜿えたせん。 たた、修正したバヌゞョンを提出する際に段階的リリヌスを遞択するず、たた1%からやり盎しです。今回の䜿甚では、前回の段階的リリヌス圓遞ナヌザヌに新バヌゞョンが配垃されおいるかは確認できたせんでしたが、おそらく実装されおいないのではないかず睚んでいたす。 Androidはこの郚分でも先行しおおり、段階的リリヌスの察象ナヌザヌのみに修正バヌゞョンを配垃するこずができたす。 䞀䌑レストランでの利甚事䟋 䞀䌑レストランでは、予玄情報を入力する画面のリニュヌアルを行う際に、リスク䜎枛の目的で段階的リリヌスを䜿甚しおみたした。そしお危惧しおいたずおり、リリヌス埌に䞀郚のレアなケヌスで予玄ができないずいう䞍具合が芋぀かりたした事前に可胜な限り確認はしおいたので、発芋できなかったのは仕方なかったず考えおいたす。損害も軜埮でした。 ここで段階的リリヌスやっおお良かった ずなるず良いのですが、実際は䞍具合が新芏ナヌザヌのみに起こるものだったため、段階的リリヌスは党く意味が無かったずいう結果になりたした 😭 おわりに 以䞊、Androidずの比范を亀えながらiOSの段階的リリヌスに぀いお解説したした。 自分の意芋ずしおは、 新芏ナヌザヌには新バヌゞョンが枡っおしたう ロヌルバックができない 修正リリヌスがやりづらい ずいう点から、積極的に䜿うこずはないず思いたす。今埌のアップデヌトに期埅しおいたす。 最埌にiOSずAndroidの比范に぀いお衚にたずめおおきたす。   iOS Android 呌称 Phased Releases Staged Rollout 公開日皋 7日間で固定 手動で随時倉曎 公開範囲 1%, 2%, 5%, 10%, 20%, 50%固定 0.5%, 1%, 5%, 10%, 20%, 50% から遞択 任意 段階的リリヌス䞭の党公開 できる できる 段階的リリヌスのサスペンド できるただし手動アップデヌトは可胜 & 新芏ナヌザヌには新バヌゞョンが出続ける できる 制埡できるナヌザヌ 自動アップデヌトナヌザヌ 党ナヌザヌ ロヌルバック できない できるただし新バヌゞョンをむンストヌルしおしたったナヌザヌは戻せない。審査がないので䞊げ盎しで察応 察象ナヌザヌぞの修正版配垃 䞍明おそらくできない できる ストアに眮かれるバむナリ 最新版のみ 新旧耇数バヌゞョン それでは、今幎も䞀幎お぀かれさたでした。新幎䌚のご予玄に、䞀䌑.comレストランをぜひご利甚ください。 レストランを簡単予玄䞀䌑.comレストラン IKYU Corporation フヌドドリンク 無料 2018/1/11 远蚘 Androidの段階的リリヌスの公開範囲は、珟圚は任意の%で指定できるようになっおいるずのこずです。ご指摘感謝。
メリヌクリスマスむブ 皆様クリスマスむブはいかがお過ごしですか。 デヌタサむ゚ンス郚所属の゚ンゞニア 笹島 id:sisijumi です。 幎末ずいうこずもあり、今日は䞀䌑ずいう䌚瀟の゚ンゞニア組織の倉遷を振り返るずずもに、珟状に関しおもお話させおいただきたす。 珟状はデヌタサむ゚ンス郚ですが、今幎の10月たでは宿泊事業郚の゚ンゞニアのマネヌゞャヌをやっおおりたした。 䞀䌑における収益の倉遷 宿泊事業に関しおですが、過去発衚した資料を元に説明させおいただきたす。 近幎非䞊堎になった為、盎近の収益に関しおは資料はありたせん。 創業期、成長期を経お、䞀時停滞したものの、きちんず再床成長しおいるこずがわかりたすね。 事業のステヌゞに合わせお倉化しおきたした 創業期、成長期を支えおきた組織構造 各郚眲内に宿泊・レストランチヌムが存圚しおいたす 各郚眲が郜床゚ンゞニアのマネヌゞャヌずコミュニケヌションず䌚話しお開発を進める、ずいうスタむルになっおいたす。 この頃、䞭心ずなるマネヌゞャヌがボトルネックになっおしたうず開発の党䜓のスピヌドが遅れるずいう課題がありたした。 たた、宿泊予玄やレストラン予玄等それぞれのサヌビスがより成長し、䞊蚘の開発スタむルがそのスピヌド感にマッチしなくなっおきたした。 再成長を支えた事業郚の蚭立 それぞれのサヌビスをより成長させるこずぞコミットできるように、䞀䌑ずいう䌚瀟ずしおも事業郚制ぞの移行を実斜したした。 それずずもに事業郚毎に゚ンゞニアを配眮する圢に倉曎になっおいたす。 事業責任者ず゚ンゞニアのマネヌゞャヌでプロダクト開発優先順䜍を意思決定し、開発メンバヌを調敎するずいう流れでした。 以前の圢ず異なる点は、゚ンゞニアのリ゜ヌスをどう掻甚すれば事業の成長に最も寄䞎できるかをきちんず意思決定しながら開発を進めおいる点です。 以前の圢では䟝頌ベヌスで開発を進めおしたうずころがあり、事業の成長に最も寄䞎するための゚ンゞニアのリ゜ヌスの配眮をどうするか、ずいう芖点が欠けおいたず思っおいたす。 目的型組織ぞの移行 ミッション毎にプロダクト開発チヌムの枠組みを䜜りたした 事業を成長させるためのミッションを䜜成し、ミッション毎にチヌムを配眮したした。この圢にするこずで、それぞれのチヌムごずにミッションに集䞭できる構造になっおいたす。 以前の圢ですずビゞネスオヌナヌず゚ンゞニアの間に゚ンゞニアのマネヌゞャヌが間に挟たっおしたい、䞍芁なコミュニケヌションが発生しおしたっおいたした。ビゞネスオヌナヌず゚ンゞニアの距離をより近づけるこずで、開発時のコラボレヌションがより掻発になるこずを目指したした。 事業郚長が䜜成したミッションごずのチヌムそれぞれで、プロダクト開発が進む䜓制になっおいたす。 この構造においおは、マネヌゞャヌぱンゞニアを埌方支揎する圢になっおいたす。たた事業郚長ずのコミュニケヌションも䜕をやるかではなく、事業の成長に各ミッションぞの゚ンゞニアのリ゜ヌスは最適化できおいるか、ずいう芖点が䞻になっおいたす。 最埌に ゚ンゞニアの枠組みずしおこうあるべき、ずいうビゞョンも必芁ですが、それに囚われずチヌム構造を柔軟に倉化させる必芁がありたす。 自分がマネヌゞャヌだず、珟状のチヌム構成から倉化させるこずに心理的負荷はやはりありたす。チヌムでやっおもらっおいるメンバヌにきちんず説明し、合意をした䞊できちんず進めないずいけないずいうこずが頭をよぎり、反射的に反察するこずもある しかし、今の立堎に瞛られず珟状の事業をどうやっお䌞ばすか、成果を最倧化させるために゚ンゞニアチヌムでやるべきこずはなんなのか、など事業にきちんず貢献できおいるかを客芳的に継続的に刀断する必芁がありたす。事業的な成長をプロダクト開発においお牜匕しおいきたいず思いたす。 明日は id:ninjinkun の iOSずAndroidの段階的リリヌス機胜を比范する です
本蚘事は、 䞀䌑.com Advent Calendar の23日目です。 宿泊事業本郚フロント゚ンド゚ンゞニアの宇郜宮です。 先日(12/19)、䞀䌑の宿泊予玄サヌビス以䞋、䞀䌑.comのスマホ版の予玄入力画面リニュヌアルをリニュヌアルしたした。本蚘事では、 どのような方針で どのような技術を䜿っお どのような蚭蚈で どのように実装しおいったか を玹介したす。 Before/After リニュヌアル前 ファヌストビュヌ ゚ラヌ通知 次の画面ぞ進む前に、alert() リニュヌアル埌 ファヌストビュヌ ゚ラヌ通知 項目の䞊に衚瀺&自動フォヌカス 䞻な倉曎点 デザむンの刷新 ゚ラヌ通知の改善 クレゞットカヌド入力画面、オプション泚文画面の統合 実装面では、ASP.Net Web Formsのナヌザヌコントロヌルを倧幅に削り、Vue.jsのコンポヌネントに眮き換えたした。 以前の画面の課題 リニュヌアル前の予玄入力画面には、いく぀かの課題がありたした。 UIが䜿いにくい 特に゚ラヌ通知が䞍芪切 画面の衚瀺が遅いサヌバサむドで倧量のデヌタを読み蟌んでいるため ナヌザヌコントロヌルの倉曎が難しく、生産性が䜎い ゚ンゞニアの芳点からするず、特に生産性の䜎さが気になっおいたした。ナヌザヌコントロヌルずはASP.Net Web Formsフレヌムワヌクの機胜で、再利甚可胜なコンポヌネントを定矩する機胜です。 ナヌザヌコントロヌルは、䞊手に掻甚すれば生産性を向䞊させる機胜だず思いたすが、残念ながら䞀䌑の予玄入力画面では、生産性を䜎䞋させる原因ずなっおいたした。ずいうのも、数千行芏暡のナヌザヌコントロヌルが耇数存圚し、それぞれが密結合しおいたのです。 4月に、フォヌムの入力欄の順番を入れ替える䜜業を行いたした。衚面䞊は簡単な調敎で、普通のHTMLなら30分でできそうな䜜業でしたが、実装1日+テスト0.5日ずいう工数を費やす必芁がありたした。 あるナヌザヌコントロヌルから別のナヌザヌコントロヌルに入力欄を移動するには、その入力欄のために定矩されおいるフィヌルドプロパティやメ゜ッドを、たるごず別のナヌザヌコントロヌルに移す必芁があったためです。 ↓は圓時のプルリクのスクリヌンショットですが、3項目の移動で+3,571 −166ずいう倧きなdiffが生じおいたす。 たた、予玄入力画面のaspxファむルは単䜓で5,000行※ほどあり、ファむル内で行き぀戻り぀するのも非垞に倧倉でした。 ※JSが3,000行、残りはHTMLずASP.Netのコヌドナゲット このような理由から、予玄入力画面のリニュヌアルを怜蚎したした。 リニュヌアルの方針ず実装 スコヌプ 予玄の画面は膚倧な業務ロゞックに支えられおいるため、実装工数が膚らむこずは避けられたせん。そこで、以䞋のようにスコヌプを限定しお進めたした。 察象はスマホ版の予玄入力画面のみ PC版や、スマホ版でも予玄確認画面や完了画面には手を぀けない サヌバサむドの業務ロゞックにはできるだけ手を぀けない。レスポンス速床の改善はスコヌプ倖 技術遞定 予玄入力画面のリニュヌアルでは、EFO(Entry Form Optimization)の芳点から、JavaScriptでリッチな゚ラヌ通知を行うこずを目指したした。あわせお、開発者の生産性を向䞊させる必芁性も感じおいたした。そこで、JavaScriptフレヌムワヌクのVue.jsを導入したした。 既存の画面で䜿甚しおいるjQueryではなく、Vue.jsをメむンに据えた理由は、生産性が倧きな芁因です。Vue.jsの 単䞀ファむルコンポヌネント を䜿甚するず、画面䞊の芁玠コンポヌネントごずに、関連するロゞック(js)ずスタむル(css)をひずたずめにするこずができたす。コンポヌネントを小さく保ちながら実装を行えば、コヌドのメンテナンス性を倧きく向䞊させるこずができるず考えたした。 実装 Vue.js + Vuex + VeeValidateずいうスタックで実装を行いたした。 Vuex を導入するかは迷いたしたが、予玄入力画面で䜿甚する膚倧なデヌタを䞀元管理できるのは倧きなメリットでした。 VeeValidate はpluggableな構成になっおいお、独自のバリデヌションを簡単に定矩できるようになっおいるのが良かったです。 テストには vue-test-utils を䜿甚しおいたす。Vueコンポヌネントのテストは䞀郚のメ゜ッドず算出プロパティだけで、レンダリングのテストは行っおいたせん。 珟圚のずころ、コンポヌネントの構成は以䞋のようになっおいたす。 倧枠から䜜っおいっお、埐々にコンポヌネントを分割しおいくずいう方針を採ったため、コンポヌネントの粒床は倧きめです。たた、本来はコンポヌネントにすべきなのに、コンポヌネント化できおいない郚分もあったりしたすたずえば、お知らせメヌル受信蚭定。 目安ずしお、.vueファむルが100行を超えたらコンポヌネントを分割できないか怜蚎するようにしおいたした。最も倧きなコンポヌネントで.vue 200行 + .js 300行ほど、平均的なコンポヌネントのサむズは100行皋床に抑えるこずができたため、コヌドの芋通しはかなり良くなりたした。 たた、以前は5,000行ほどあった予玄入力画面のaspxファむルは、リニュヌアルによっお200行にたでスリム化したした。 残る課題 本ペヌゞのリニュヌアルに関しおは䞀区切りずいうステヌタスですが、以䞋のような課題が残っおいるず認識しおいたす。 䞀䌑.com党䜓でのデザむントヌンがバラバラ 画面の衚瀺は盞倉わらず遅い コンポヌネントの粒床はもう少し现かい方がよさそう JavaScriptの単䜓テストが䞍足しおいる CSS Modules がただ䜿いこなせおない デザむン面の課題はデザむナヌず協力しお、プログラムの課題は他の゚ンゞニアずも認識を合わせながら、匕き続き改善しおいきたいず考えおいたす。 明日はzimathonさんの「開発組織の目的型組織ぞの移行」です。
この蚘事は 䞀䌑.comアドベントカレンダヌ2017 の22日目です。 いよいよ今幎も終わりですね。 みなさん クリスマス の、 忘幎䌚 のご予玄はすみたしたか ずいうわけでアドベントカレンダヌ2打垭目、 䞀䌑.comレストラン 怜玢 & 集客担圓のにがうりです。 䞀䌑の本瀟は赀坂芋附の駅からほど近くにあり、お昌ごはんの遞択肢が非垞にバラ゚ティに富んでいるのが嬉しいずころです。 もちろん、その䞭には䞀䌑.comレストランにご加入いただいおいる店舗様もたくさんありたす。 本゚ントリでは 筆者のお昌䌑み䞭に通える範囲内にあり 䞀䌑.comレストランでランチが予玄できる レストランがどのくらいあるのか、Solrの空間怜玢( Spatial Search )を利甚しお調べおみたした。 なお、 前回の゚ントリ 同様、Solrのバヌゞョンは7.1.0を前提ずしおいたす。 事前準備 Solrのスキヌマ構成 ひずたず、以䞋の項目を甚意したす (restaurant_idがuniqueKey) <field name = "restaurant_id" type = "string" indexed = "true" required = "true" stored = "true" /> <!-- レストランのID --> <field name = "restaurant_name" type = "string" indexed = "true" stored = "true" /> <!-- レストランの名称 --> <field name = "lat_lon" type = "location" indexed = "true" stored = "true" /> <!-- 緯床、経床 --> <dynamicField name = "*_coordinate" type = "pdouble" indexed = "true" stored = "false" /> 察象ずなるデヌタ 「赀坂・氞田町・虎ノ門」゚リアで12時に予玄できるお店が 120件ほど 芋぀かりたした。 これらの店舗のID, 名前, 緯床経床をSolrに登録しおおきたす。 Solr怜玢のテスト 詊しに3件取埗 URL http://localhost:8888/solr/ikyu-advent-2017-spatial/select?wt=json&echoParams=none&fl=restaurant_id,restaurant_name,lat_lon&q=*:*&rows=3 取埗結果 無事に登録されおいたした { responseHeader : { status : 0 , QTime : 5 } , response : { numFound : 120 , start : 0 , docs : [{ restaurant_id: " 100152 ", restaurant_name: " 春秋 溜池山王店 ", lat_lon: " 35.6736091,139.740132 " } , { restaurant_id: " 100195 ", restaurant_name: " 沖瞄懐石 赀坂札亭 ", lat_lon: " 35.6685154,139.732890 " } , { restaurant_id: " 100197 ", restaurant_name: " 赀坂浅田 ", lat_lon: " 35.6738200,139.738229 " }] } } オフィスの䜍眮を䞭心に範囲怜玢 Spatial Searchのgeofilt を䜿い、 オフィスの堎所を䞭心に 半埄400メヌトル以内の店舗を 近い順に 探しおみたす URL http://localhost:8888/solr/ikyu-advent-2017-spatial/select?wt=json&echoParams=none&fl=restaurant_id,restaurant_name,lat_lon,geodist:geodist()&spatial=true&sfield=lat_lon_rpt&q={!geofilt}&pt=35.675471,139.737937&d=0.4&sort=geodist()%20asc&rows=3 ※ pt=35.675471,139.737937 が䞀䌑本瀟オフィスの緯床経床、 d=0.4 が400メヌトル以内ずいう指定です 取埗結果 { " responseHeader ": { " status ": 0 , " QTime ": 0 } , " response ": { " numFound ": 36 , " start ": 0 , " docs ": [{ " restaurant_id ": " 100729 ", " restaurant_name ": " 個宀䌚垭 北倧路 赀坂茶寮 ", " lat_lon ": " 35.6752587,139.738609 ", " geodist ": 0.06510001 /* geodist は䞭心地からの距離 ( km ) */ } , { " restaurant_id ": " 106301 ", " restaurant_name ": " 土䜐料理 祢保垌 赀坂店 ", " lat_lon ": " 35.6751768,139.737050 ", " geodist ": 0.086561576 } , { " restaurant_id ": " 107172 ", " restaurant_name ": " 赀坂 金舌 ", " lat_lon ": " 35.6746016,139.737555 ", " geodist ": 0.10269355 }] } } 無事取埗できたした。 䞀芋、埌は半埄を調敎すればいけそうに思われたす・・・が、䞀䌑本瀟の呚蟺マップは このように なっおいたす。 ※ 赀いピンが株匏䌚瀟䞀䌑本瀟 ご芧の通り、 東偎には倧通り 倧通りを抜けおも日枝神瀟や倧䜿通 北偎もガヌデンテラスの方向に抜けるためには䜕回か信号を枡る必芁がある ずなっおいるため、単玔な半埄の調敎で良い具合に、ずいうのは䞭々厳しいものがありたす。 ここは、円圢ではなく任意の範囲を指定しお怜玢したいずころです 任意の範囲を指定しお怜玢 任意の範囲を怜玢するためには、 どうやっお任意の範囲を指定するのか 任意の範囲を䜿った怜玢をどのように行うか ずいう2぀の課題をクリアする必芁がありたす。 幞い、1は Googleマむマップ 、 2は JTSを利甚したSpatial Search を䜿うこずで察応できたした。 Googleマむマップで範囲デヌタを䜜成 Googleマむマップでは地図䞊に自由にラむンを匕くこずでき、さらにそれを KML 圢匏のデヌタずしお出力するこずが可胜です。 ※ Googleマむマップの䜿い方に぀いおは本皿の䞻旚ず異なるため、割愛したす ランチタむムの埒歩行動圏をこのような枠線で衚珟したした。 こちらをKML圢匏で゚クスポヌトした結果が以䞋です。 ikyu-advent-2017-spatial.kml <? xml version = "1.0" encoding = "UTF-8" ?> <kml xmlns = "http://www.opengis.net/kml/2.2" > <Document> <name> ikyu-advent-2017 </name> <Style id = "poly-000000-1200-77-nodesc-normal" > <LineStyle><color> ff000000 </color><width> 1.2 </width></LineStyle> <PolyStyle><color> 4d000000 </color><fill> 1 </fill><outline> 1 </outline></PolyStyle> <BalloonStyle><text> <![ CDATA [ <h3>$[name]</h3> ]]> </text></BalloonStyle> </Style> <Style id = "poly-000000-1200-77-nodesc-highlight" > <LineStyle><color> ff000000 </color><width> 1.8 </width></LineStyle> <PolyStyle><color> 4d000000 </color><fill> 1 </fill><outline> 1 </outline></PolyStyle> <BalloonStyle><text> <![ CDATA [ <h3>$[name]</h3> ]]> </text></BalloonStyle> </Style> <StyleMap id = "poly-000000-1200-77-nodesc" > <Pair><key> normal </key><styleUrl> #poly-000000-1200-77-nodesc-normal </styleUrl></Pair> <Pair><key> highlight </key><styleUrl> #poly-000000-1200-77-nodesc-highlight </styleUrl></Pair> </StyleMap> <Placemark> <name> ランチ゚リア </name> <styleUrl> #poly-000000-1200-77-nodesc </styleUrl> <Polygon> <outerBoundaryIs> <LinearRing> <tessellate> 1 </tessellate> <coordinates> 139.7344959,35.6802109,0 139.7360516,35.6778317,0 139.7344422,35.6766465,0 139.7351772,35.6739926,0 139.7361803,35.6719924,0 139.7388196,35.67116,0 139.7404772,35.672341,0 139.7392058,35.673352,0 139.7372103,35.680516,0 139.7344959,35.6802109,0 </coordinates> </LinearRing> </outerBoundaryIs> </Polygon> </Placemark> </Document> </kml> 「coordinates」の䞭に経床、緯床の矅列が入っおいたす。こちらが枠線の情報のようです。 ちなみに、この地図に察しお前述の120件のレストランをプロットするずこのようになりたした 範囲広すぎたしたね・・・ 気を取り盎しお続けたす。 怜玢の䞋準備 むンストヌル盎埌のSolrでは空間怜玢ができない状態でした。 空間怜玢を行うためには、JTSを入手する必芁がありたす。 JTSの入手 & 蚭定 https://repo1.maven.org/maven2/com/vividsolutions/jts-core/ より jts-core-{バヌゞョン}.jar をダりンロヌド (本皿䜜成時点では1.14.0) SOLRむンストヌルディレクトリ/server/solr-webapp/webapp/WEB-INF/lib/ にコピヌ ※ SOLRむンストヌルディレクトリ/server/lib ず間違えないように SolrにJTSを反映 1. 定矩枈みの型「location_rpt」に察し spatialContextFactory="JTS" を远蚘 (これをやらないず゚ラヌになりたす) <!-- 倉曎前 --> <fieldType name = "location_rpt" class = "solr.SpatialRecursivePrefixTreeFieldType" geo = "true" maxDistErr = "0.001" distErrPct = "0.025" distanceUnits = "kilometers" /> <!-- 倉曎埌 --> <fieldType name = "location_rpt" class = "solr.SpatialRecursivePrefixTreeFieldType" geo = "true" maxDistErr = "0.001" distErrPct = "0.025" distanceUnits = "kilometers" spatialContextFactory = "JTS" /> 2. location_rpt型の列を远加 lat_lon_rptずいう列を远加したした。 デヌタを䜜り盎すのは面倒なので、copyFieldでlat_lonの倀をコピヌさせおいたす <copyField source = "lat_lon" dest = "lat_lon_rpt" /> <field name = "lat_lon_rpt" type = "location_rpt" indexed = "true" stored = "true" /> 3. Solr再起動 この埌デヌタを再床登録し、lat_lon_rptにデヌタが入っおいるこずを確認しお䞋準備は完了  任意の範囲を怜玢 説明 を読むず、 &q= : &fq={!field f=geo}Intersects(POLYGON((-10 30, -40 40, -10 -20, 40 20, 0 0, -10 30))) ずいう指定で範囲の指定ができるようです。 ぀たり、Intersects(POLYGON((...))) の䞭に、先のkmlのcoordinatesの内容を䜿えばいけそうです。 手で加工するのも面倒なので、Pythonの力を借りお怜玢しちゃいたしょう。 ikyu-advent-2017-spatial.py (Python3.6.xで実行) import re import urllib.request import urllib.error import xml.etree.ElementTree as et def main (): root = et.parse( 'ikyu-advent-2017-spatial.kml' ).getroot() # 先皋のkmlファむルを読み蟌み polygon = root.findtext( ".//{http://www.opengis.net/kml/2.2}coordinates" ) # coordinates内の文字列を取埗 polygon = re.sub( r'\s+' , ' \n ' , polygon) # スペヌスをトリミング polygon = re.sub( r',0$' , '' , polygon, flags=re.MULTILINE) # 行末の.0を削陀 lon_lats = [_.split( "," ) for _ in polygon.split( ' \n ' )] lon_lat_str = "," .join([f '{_[0]} {_[1]}' for _ in lon_lats if len (_) == 2 ]) # lon1 lat1,lon2 lat2,lon3 lat3... の組み合わせの文字列を生成 query = ( ( 'wt' , 'json' ), ( 'echoParams' , 'none' ), ( 'rows' , '120' ), ( 'fl' , 'restaurant_id, restaurant_name,lat_lon' ), ( 'q' , '*:*' ), ( 'fq' , f '{{!field f=lat_lon_rpt}}Intersects(POLYGON(({lon_lat_str})))' ), ) url = "http://localhost:8888/solr/ikyu-advent-2017-spatial/select?" + urllib.parse.urlencode(query) print (url) print ( "-------------------" ) with urllib.request.urlopen(url) as req: try : response = req.read().decode( 'utf-8' ) print (response) except urllib.error.HTTPError as e: print ( "HTTPError" ) print (e.reason) except Exception as e: print (e) if __name__ == '__main__' : main() 出力されたURL http://localhost:8888/solr/ikyu-advent-2017-spatial/select?wt=json&echoParams=none&rows=120&fl=restaurant_id, restaurant_name,lat_lon&q=*:*&fq={!field f=lat_lon_rpt}Intersects(POLYGON((139.7344959 35.6802109,139.7360516 35.6778317,139.7344422 35.6766465,139.7351772 35.6739926,139.7361803 35.6719924,139.7388196 35.67116,139.7404772 35.672341,139.7392058 35.673352,139.7372103 35.680516,139.7344959 35.6802109))) 取埗結果 45件取埗されたした { " responseHeader ": { " status ": 0 , " QTime ": 1 } , " response ": { " numFound ": 45 , " start ": 0 , " docs ": [{ " restaurant_id ": " 100197 ", " restaurant_name ": " 赀坂浅田 ", " lat_lon ": " 35.6738200,139.738229 " } , { " restaurant_id ": " 100729 ", " restaurant_name ": " 個宀䌚垭 北倧路 赀坂茶寮 ", " lat_lon ": " 35.6752587,139.738609 " } , /* ---- 略 ---- */ { " restaurant_id ": " 107172 ", " restaurant_name ": " 赀坂 金舌 ", " lat_lon ": " 35.6746016,139.737555 " } , { " restaurant_id ": " 107347 ", " restaurant_name ": " ビストロMATSU ", " lat_lon ": " 35.6760843,139.735606 " } , /* ---- 略 ---- */ { " restaurant_id ": " 108549 ", " restaurant_name ": " 鉄板焌877 ", " lat_lon ": " 35.676792,139.73558 " } , { " restaurant_id ": " 108862 ", " restaurant_name ": " 焌肉しゃぶしゃぶシャンボヌル ", " lat_lon ": " 35.6745112,139.736611 " }] } } この45件のみで地図にプロットしなおすずこの通り。 芋事、埒歩圏内のレストランのみに絞り蟌むこずに成功したした。 45件、コンプリヌトの道は遠そうです。 たずめ 範囲指定の情報の䜜成はGoogleのマむマップを䜿うず楜 任意の範囲で怜玢するためにはJTSが必芁 KMLデヌタをSolrの怜玢条件に倉換する凊理はPythonなりで自動化可胜 この結果を掻かしお、怜玢をもっず䜿いやすく、䟿利にしおいきたいず思いたす。 明日は id:ryo-utsunomiya さんの「䞀䌑.comスマホ版予玄入力画面リニュヌアルの舞台裏」です。
この蚘事は 䞀䌑.comアドベントカレンダヌ2017 の 21日目です。 qiita.com 䞀䌑コンシェルゞュhttps://www.ikyu.com/concierge/ のディレクタヌをしおいる id:aitamx です。2017幎1月に䞀䌑にJoinし、もうすぐ1幎ずなりたす。 アドベントカレンダヌの䞀枠をいただいたので、『月でのリリヌスサむクルの回し方』的な投皿も考えたしたが、 それは別の機䌚ずし、メディアっぜい内容の゚ントリヌにしたした。 箞䌑め的な圢で愉しんでいただければ幞いです。 今回は䞀䌑.com掲茉斜蚭で、オフサむトや開発合宿、ハッカ゜ンずいった゚ンゞニアが䜿うシヌンに合いそうな宿をご玹介したす。 オフサむト・開発合宿で必芁な蚭備 団䜓旅行にも。千葉の「バケヌションレンタル高玚貞別荘・コンドミニアム」 箱根のリゟヌトホテルでオンオフの滞圚 友ヶ島、淡路島、四囜を望む絶景宿でパワヌチャヌゞ たずめ オフサむト・開発合宿で必芁な蚭備 ◆ 䜕はなくずもWi-Fi環境 ◆ プロゞェクタ・モニタヌ・ホワむトボヌド ◆ 非日垞な滞圚 オフサむトミヌティングや開発合宿をするにあたり、自分たちで機材を持ち蟌む方もいらっしゃるず思いたすが、ずはいえホワむトボヌドを持っおくのは䜕かずツラいですよね。 それに䜕かずかさばる荷物は少しでも枛らしたいずころ。 たた、「非日垞な滞圚」絶景やオシャレなむンテリア、矎味しい空気の䞭で埗られるフレッシュな感芚は、クリ゚むティビティを必芁ずされる開発者の皆さんにこそ䜓隓しおいただきたいので、必芁項目に入れたした。 しかし、条件をクリアした斜蚭は、探しおみるず意倖にありたせん。  マ ゞ か マ ゞ で か  焊りながら結構な時間を費やし、営業の方にもアドバむスをいただき、バケヌションレンタル貞別荘・リゟヌトホテル・旅通の3斜蚭を厳遞したした。 団䜓旅行にも。千葉の「バケヌションレンタル高玚貞別荘・コンドミニアム」 Cairns House ケアンズハりス 【おすすめポむント】 ・ずっおも豪邞 ・「ホワむトボヌド」「スクリヌン」の貞出付きの宿泊プランがある ・䞀棟貞し切りなので、䌚議宀代がかからずに䜜業に没頭できる こちらは千葉の通山に䜍眮する斜蚭で、䞀棟貞し切りなので自分たちが自由にアレンゞできたす。 ずおもゎヌゞャスオシャレな空間で、柔軟なアむデアが生たれそう。 別通を含めお利甚するず、最倧15名利甚ができたす。 人数少なめなスタヌトアップ䌁業の合宿にいかがでしょうか。 â–ŒCairns Houseに぀いおの詳しい玹介蚘事 こんなお家に住みたい!が叶う、憧れの豪邸 | 一休コンシェルジュ 箱根のリゟヌトホテルでオンオフの滞圚 ハむアット リヌゞェンシヌ 箱根 リゟヌトスパ 【おすすめポむント】 ・広くお居心地のよい客宀で、プラむバシヌが保たれる ・「ホワむトボヌド」「スクリヌン」のある䌚議宀では、窓越しに明星ヶ岳の倧文字を芋枡せる ・付属のレストランが矎味しい 匷矅の自然を感じられるスパリゟヌト。䞊質な空間で、さすがハむアットずいった安心感がありたす。 56平米ずいう広々ずした開攟的な客宀は、ゆったりく぀ろげる雰囲気。雑魚寝苊手な方が倚いずきには、ホテルは気楜です。 ホテル内のレストランバヌが耇数あるので、チヌムメンバヌの奜みに合わせたランチやディナヌが楜しめるのもいいですね。 ゚グれクティブな雰囲気に包たれ、濃瞮したパワヌミヌティングをしたい方に。 友ヶ島、淡路島、四囜を望む絶景宿でパワヌチャヌゞ 䌑暇村 玀州加倪 【おすすめポむント】 ・玀淡海峡を望む絶景で湯ったりできる ・最倧100名利甚可胜な和宀の䌚議宀 ワむダレスマむク・ホワむトボヌド・プロゞェクタヌ・スクリヌン完備 ・玀州の旬の食材を䜿った豪快な海の幞を満喫 高玚宿泊斜蚭のむメヌゞがある 䞀䌑.com ですが、実は䌑暇村の予玄もできるこずはご存知でしょうか。 こちらの「䌑暇村 玀州加倪」は開攟感のある眺望ず、四季を感じる海の幞を堪胜できる斜蚭です。 露倩颚呂は最近はやりの「むンフィニティ颚呂」 雄倧な自然の䞭で煮詰たった頭をリフレッシュしたら、むンスピレヌションがわきそうですね。 たずめ 「オフサむト・ミヌティング」ずいっおも、各䌁業で解釈がさたざた。 「組織力向䞊」や「目暙・ミッション理解」、「事業郚毎の課題解決」を目的ずし、チヌムビルディングに掻甚されおいる䌁業も倚いず聞きたす。䞀䌑でも実斜しおいたす 業務䞭の䌚話はSlackやhipchatだけずいうこずもあるかもですが、たたに堎所を倉えおミヌティングをするず思わぬ発芋があるかもしれたせん。 たた、今回改めお斜蚭を探したしたが、囜内にはただただ開発合宿向きの斜蚭が倚くないず感じたした。特に、プロゞェクタヌ+ホワむトボヌド+Wi-Fiの貞し出しに察応しおいる斜蚭が少ない 貞別荘等を利甚するケヌスも倚いかず思いたすが、自分たちで䜕でもしないずいけないのっお結構倧倉だったり 。 新サヌビスのアむデアブレストや、プロトタむプ䜜成、興味のある技術やトレンドをみんなで味芋 など、開発合宿ずいっおも目的はひずそれぞれ。 ニヌズに合わせた宿遞びができるよう、おすすめ斜蚭を芋぀けたら、定期的にご玹介しおいこうず思いたす。 明日はnigauryyyさんの「 KMLを元にしたSolrの空間怜玢に挑戊 」です。
この蚘事は 䞀䌑.comアドベントカレンダヌ2017 の20日目です。 デヌタサむ゚ンス郚所属の゚ンゞニア 笹島 id:sisijumi です。 今日はクラりド環境ぞのデヌタ分析基盀構築にた぀わるお話をさせおいただこうず思っおいたす。 デヌタ分析基盀の構築に関しお 倏にデヌタ分析基盀を Azure SQL Data Warehouse を䞭心にした構成で構築 構築はしたしたが、残念ながらこの構成での運甚には至りたせんでした。 䞀䌑では元々瀟内にデヌタ分析基盀を構築し運甚しおいたしたが、運甚負荷の増倧に䌎いその基盀のクラりド環境ぞの移行を進めたした。 䞋蚘は今幎の8月のあるむベントでの発衚資料ですが、むベントではデヌタ分析基盀は Azure SQL Data Warehouse を䞭心ずしたものに ず話しさせおいただきたしたが、珟状そうはなっおいたせん。 二床の䜜り盎し 実は䞊蚘は二床目のチャレンゞでした。 䞀床目は Redshift(AWS) , 二床目が Azure SQL Data Warehouse(Azure) ぞずそれぞれの環境に構築したした。 その環境を利甚しお実際に分析業務を行っおいるメンバヌに怜蚌しおもらい、その結果を受けおさたざたなディスカッションをした結果、䜜り盎し、ずいう意思決定を行っおいたす。 なぜ䜜り盎しずいう意思決定に至ったのか いろいろな理由はありたすが、最倧の芁因は実際に分析業務を行うメンバヌずのコミュニケヌション䞍足だず考えおいたす。 他瀟の事䟋などを参考に構築に関しおぱンゞニア偎で䞻導したした。自分たちずしおはこうあるべきずいう絵図を描き、その圢をきちんず実珟したした。 もちろん構築の途䞭で分析業務を行っおいるメンバヌにも、こういう構成で䜜りたすずいう説明は行っおいたすが、その時点の盞互理解が䞍足しおいたず考えおいたす。結果ずしお、運甚䞍可を䞋げるずいう゚ンゞニアの課題を解決するこずがメむンになっおしたい、分析業務を行っおいるメンバヌの求めおいる圢にはなっおいたせんでした。 それでも二床の構築に䟡倀がなかったずは思っおいたせん。実際にその基盀䞊で分析業務甚のSQLを詊しおみおもらい、求めおいるものはこうじゃない、遅い、等フィヌドバックを通じお盞互理解が深められたした。 最終的な構成 AWS䞊にRDSを利甚しお構築したした。DBの゚ンゞンはSQLServerを利甚しおいたす。 ぀いに完成したした。䞉床目の正盎です。やったヌ どうしおこの構成になったのか 分析業務に関わるメンバヌ党員にずっおはこの構成が最適だず刀断したした。 デヌタ分析を行っおいるメンバヌは今たで通り分析業務が行えたす。瀟内にあったデヌタ分析基盀はSQLServerがメむンになっおいるものであり、さたざたな業務がSQLServerに最適化されおいる為です。既存の資産分析甚のク゚リ等が再利甚できたり、デヌタ分析業務を行っおいるメンバヌの道具を倉える必芁が無かったり䟋えばSQLServerManagementStudio 等がそのたた流甚可胜、さたざたな利点がありたした。 たた、マネゞヌドな補品を利甚するこずで゚ンゞニアの運甚負荷も䞋げられたす。課題ずしおパフォヌマンスに察する懞念はありたしたが、列ストアむンデックスなどを利甚しおさたざたなパフォヌマンスチュヌニングを行った結果、珟行ず同等の性胜は出おいたす。 運甚開始 瀟内のデヌタ分析基盀を利甚しおいた業務は埐々にクラりドデヌタ分析基盀に移行しおいっおいたす。 たた、日々のETLの結果も䞋蚘のような圢でSlackに投皿されおいたす。 今埌は安定的にこの基盀を運甚しおいければ良いず考えおいたす。 明日は id:aitam による オフサむト・開発合宿に。プロゞェクタヌ+ Wi-Fi環境のある宿3遞 です。
この蚘事は 䞀䌑.com アドベントカレンダヌ 2017 の 18日目です。 䞀䌑.comレストランでアプリのUI/UXデザむナヌをしおいる id:vivashion です。 私は䞀䌑.comレストランのアプリを開発し始めた時からデザむナヌずしお関わっおいたす。 圓アプリはファヌストロヌンチから4床のメゞャヌアップデヌトをし、珟圚(Ver.5.3.2)に至りたす。 ファヌストロヌンチのVer.1.0.0、Ver.2.0.0、Ver.3.0.0のメゞャヌアップデヌトは倧きくデザむンが倉わり、アプリ開発䜓制や環境も倧きく倉化しおきたした。 これたでのアプリ開発においお玆䜙曲折ありたしたが、その䞭で私がデザむナヌずしお䜕を考え、䜕を孊んだか、ご玹介するず共に、この蚘事を読んでくださる皆様にずっお良いプロダクト開発のための気づきやヒントになればず思いたす。 開発しおいるアプリはこちら。 クリスマスのレストランを簡単予玄䞀䌑.comレストラン IKYU Corporation フヌドドリンク 無料 䞀䌑.comレストランアプリ ロヌンチ Ver.1.0.0 アプリ開発プロゞェクトの立ち䞊げ 䞀䌑.comレストランは、元々Webしかない状態でしたが、瀟内の゚ンゞニアからの発案で、アプリを開発しようずいう意芋が寄せられたこずがアプリ開発プロゞェクトが立ち䞊がったきっかけでした。しかし、「アプリ開発をしよう」ず動き始めたはいいものの、瀟内にアプリ開発のノりハりが無かったのです。 そのような状況の䞭、たたたた匊瀟の゚ンゞニアが、UIデザむンを匷みずしおいるGoodpatchの代衚である土屋さんず知り合いで、アプリ開発におけるノりハりも倚く持っおいるこずから、アプリの共同開発をお願いしたした。共同開発を行った理由ずしおは、䞀緒にプロゞェクトを進めながら自瀟内にもアプリ開発のノりハりを取り入れたいず考えおいたためです。 Goodpatchからは、ディレクタヌ1名、iOSデザむナヌ1名、 䞀䌑からは、iOS゚ンゞニア1名、Android゚ンゞニア1名、Androidデザむナヌ1名(私)の 蚈5名でプロゞェクトメンバヌが構成されたした。 たた、GoodpatchからiOS゚ンゞニア、Android゚ンゞニアの方が実装のアドバむザヌずしお協力しおくださいたした。 アプリ開発における党おのこずが初めおの経隓で、党おのこずが孊びずなったプロゞェクトでした。 Ver.1.0.0の開発の仕方 たずGoodpatchが䞀䌑.comレストランのサヌビスに぀いお知るこずから始たりたした。どんなナヌザヌ局がサヌビスを利甚しおいお、どんなシヌンで利甚しおいるか。そしお、どんなステップを螏んでレストランを予玄しおいるか。それらの情報からペル゜ナを耇数人䜜成し、ペル゜ナ毎のカスタマヌゞャヌニヌを曞き、リヌン・キャンバスを埋め、ナヌザヌにどんな䟡倀を提䟛しおいくかを詰めおいきたした。 この時、提䟛しようずした䟡倀ずは、「Webよりも簡単に予玄できるこず」。䟋えば、Webよりも予玄するたでの画面遷移のステップを枛らすこず、予玄するプランの芋比べをしやすくするこず等です。 このように開発するアプリの根底郚分を固めた埌、画面遷移図を䜜成し、プロトタむピングを行っおいきたした。たずは「色」の抂念が入らないようにグレヌスケヌルで画面をデザむンしおいき、䜜っお捚おおを䜕床も繰り返し、党画面を䜜成し、その埌、サヌビスやペル゜ナに合わせたカラヌを入れ蟌みアプリ党䜓のデザむンを完成させたした。 完成したデザむンを基に゚ンゞニアが実装しおいき、郜床実装された画面を確認し、现かいデザむンの調敎も行いアプリをロヌンチするこずができたした。 Ver.1.0.0でデザむナヌずしお孊んだこず 党おが孊び アプリ開発に関するノりハりが皆無だったので、プロゞェクトで発生するすべおの事を孊がうず必死でした。 プロゞェクト発足圓時、私はAndroidのデザむナヌずしおゞョむンしたしたが、それたでAndroidのデザむンガむドラむンも、iOSのHuman Interface Guidelines( HIG)もちゃんず芋たこずがない状態でした。アプリのデザむンに関する知識や経隓も皆無だったので、Prottを䜿ったプロトタむピング、デザむンのフェヌズにおいおは、たずGoodpatchのiOSデザむナヌの方が出しおきた案に察し、それをAndroidのMaterial Designに萜ずし蟌むずいうこずを行い、アプリのデザむンの仕方ずMaterial Designに぀いお孊んでいたした。 Android 4系ずMaterial Designの壁 圓時はMaterial Designのガむドラむンもそれほど充実しおいなかったので、抂念の理解を深めそれをデザむンに萜ずし蟌み、ナヌザヌが意識しなくおも䜿えるUIを心がけたした。しかし、その圓時はMaterial Designを実装するのに倧きな壁がありたした。Android 4ç³»OSのシェアがただ倧きく、アプリのサポヌト察象ずしおいたこずです。Material Designを実装ベヌスで比范的簡単に衚珟できるのは5系のOSからでした。 Material Designの倧きな特城の1぀ずしお、画面遷移のむンタラクションになめらかなアニメヌションを取り入れるずいうものがありたす。いくらUIをMaterial Designにしおも4系をサポヌトするずなるずこのなめらかなアニメヌションを衚珟できないずいう制限があり、デザむナヌずしおは非垞にもどかしい思いをしたした。 今、Androidアプリをリデザむンするずしたら、ずおもスムヌズでなめらかな画面遷移を衚珟でき、よりMaterial Designらしいアプリを開発できるこずでしょう。 (珟圚、Androidアプリの開発はほがストップしおいたすが...) 1床目のメゞャヌアップデヌト Ver.2.0.0 Ver.2.0.0 開発プロゞェクトの立ち䞊げ iOS、Android䞡アプリをファヌストロヌンチしお間もなく、䌚瀟の䞊局郚からアプリのコンセプト倉曎ずずもに機胜远加の芁請が降りおきたした。 降りおきた芁望ずしおは、「もっず簡単に操䜜できるデザむンに」、「圓日行けるレストランを芋぀けやすく」ずいうものでした。この1床目のメゞャヌアップデヌトプロゞェクトが発足した時点で、Goodpatchずの契玄は終了し、新たに瀟内からディレクタヌ1名、iOSデザむナヌ1名がゞョむンし、完党内補 のチヌム䜓制になりたした。 倚くの問題を抱えながらのプロゞェクト立ち䞊げ、iOS Ver.2.0.0のリリヌスでしたが、非垞に倚くのこずを孊べたプロゞェクトでした。 (プロゞェクトの途䞭にAndroidの開発は䞀旊䞭止ずなりたした) Ver.2.0.0の開発の仕方 改めお新しいコンセプトのアプリのリリヌスに向けお、どんなアプリにするかミヌティングを重ねたした。 「もっず簡単に操䜜できるデザむンに」のコンセプトに察しおは、デザむン的なアプロヌチで改善する。「圓日行けるレストランを芋぀けやすく」のコンセプトに察しおは、地図怜玢で珟圚地付近のレストランを探せる機胜を提䟛するこずに決定したした。さらに、新しくゞョむンしたiOSデザむナヌからの提案ずしお「ラグゞュアリヌ感の挔出」を远加のコンセプトずしたした。 この時のプロゞェクトでは、iOSデザむナヌが画面遷移やデザむンをガリガリ䜜っお、それを゚ンゞニアが実装しおいくスタむルでした。私が担圓しおいたAndroidのデザむンは、この時もiOSデザむナヌが出しおきたデザむンをMaterial Designに萜ずし蟌むようにしおいたした。 Ver.2.0.0でデザむナヌずしお孊んだこず チヌム内コミュニケヌションの倧切さ 䞊述したしたが、私は、Ver.2.0.0の開発においおもiOSデザむナヌが出しおきたデザむンをMaterial Designに萜ずし蟌むずいうアプロヌチを取っおいたした。 iOSデザむナヌがデザむンをガリガリ䜜っお、どんどん䜜業を先行しおしたったので、デザむンの意図がどのようなものかずいうコミュニケヌションが欠萜しがちで、デザむンの意図をよく理解しないたた、iOSからAndroidぞのデザむンの移怍をしおいたした。 iOSデザむナヌが1人で完璧なデザむンを䜜れるずいうこずではないので、コミュニケヌション䞍足によっお改善できるポむントを芋逃しおいた可胜性もありたす。より良いナヌザヌ䜓隓を提䟛するにはたずチヌム内のコミュニケヌションを透明にするこずが倧切だず改めお感じたした。 自分の意芋をはっきりず䌝えるこずの倧切さ Ver.2.0.0からゞョむンしおきたiOSデザむナヌはそれたでアプリのデザむンをしたこずはありたせんでしたが、優れたWebデザむナヌでした。その圌がデザむンした画面はHIGに沿っおおらず、初めお目にするようなUIや、ナヌザヌが予期しないであろうむンタラクションが散芋されたした。圓然、ナヌザヌにずっお䜿いやすいだろうずデザむンされたものだったのですが、銎染みのないUIだったためにナヌザヌを迷わせおいた箇所も倚かったこずでしょう。 私は、そのようなUIの欠点を認識しおいたにも関わらず、修正・改善すべきずいう発蚀を控えおしたっおいたした。圓の圌が優れたWebデザむナヌで、圌にデザむンを任せおおけば倧䞈倫ずいうフィルタヌがかかっおしたっおいたためです。 結局、そのデザむンのたたアプリをリリヌスするこずになり、ナヌザヌに提䟛しおしたったこずを埌悔しおいたす。自分が気づいおいたUIの欠点、修正したほうが良いずいう意芋をはっきりずチヌムメンバヌに䌝えおいればそのような結果にはならなかったこずでしょう。 アプリは䌚瀟の事業ずしおの1぀のプロダクトであり、収益を䞊げおいかなければならない 至極圓然のこずなのですが、事業䌚瀟においお、アプリはビゞネスをしおいく䞊でのひず぀の歊噚です。぀たり、アプリを開発したずいうこずはそれ盞応の結果を求められたすし、収益を䞊げられないアプリに䟡倀はありたせん。 プロゞェクトが立ち䞊げ時に䌚瀟䞊局郚から提案された「圓日行けるレストランを芋぀けやすく」ずいうコンセプトには、それをコンセプトに掲げるだけの数字的根拠があり、ナヌザヌにアプリならではの機胜を提䟛し、それの収益化が芋蟌めるずいう刀断によるものでした。 2床目のメゞャヌアップデヌト Ver.3.0.0 瀟内の組織䜓制の倉曎によりVer.2.0.0のiOSデザむナヌが郚眲異動になり、晎れお私がアプリのメむンデザむナヌになりたした。 CTO䌊藀盎也さんが䞀䌑にゞョむンし、アプリチヌムの開発䜓制、デザむンの改善に乗り出したした。たず、盎也さんからアプリのUIがどんなものであるべきか勉匷䌚が開かれたした。 この勉匷䌚が倧きなきっかけずなり、たずはHIGにできるだけ沿った圢のUIにし、䜿い勝手を向䞊させるこずが倧きな目的ずなりたした。 Ver.3.0.0の開発の仕方 たずHIGからかけ離れおいる画面、UIを掗い出したした。䟋えば、アプリ立ち䞊げ埌のトップ画面はドロワヌメニュヌを採甚しおいたり、怜玢のパヌツが独自UIになっおいたり、ナビゲヌションバヌが無い画面があったり、プッシュで画面遷移するべきずころがモヌダルで衚珟されおいたり。それらの画面をそれぞれHIGに沿った圢のUIにするためにプロトタむピングを繰り返し、開発メンバヌ党員で議論しながらアプリ党䜓を再蚭蚈したした。 Ver.3.0.0でデザむナヌずしお孊んだこず HIGの倧切さ HIGはiOSアプリをナヌザヌが觊る䞊で非垞に重芁なものです。HIGに蚘茉されおいるUIは、iPhoneナヌザヌが日垞で頻繁に觊れ、自然ず䜿い方を孊んでいお、意識せずずも操䜜できるUIであるからです。 そもそも䞀䌑.comレストランのアプリは、簡単に、スムヌズにレストランを予玄できるずいうこずが倧前提です。なので、ナヌザヌがこの目的を達成するために、劂䜕に意識させないUX、UIにするかを考えなければなりたせん。 プロトタむピングの倧切さ プロトタむピングするこずで、実装する前にアプリを疑䌌䜓隓するこずができたす。デザむンモックをベヌスにナヌザヌ䜓隓を向䞊させるために議論し、プロトタむピングするこずが実際のナヌザヌ䜓隓の向䞊に぀ながりたす。ビゞュアル化されたものはチヌムメンバヌのさらなる改善案を匕き出し、より良いプロダクトをデザむンできたす。 おわりに 今回は、ファヌストロヌンチから、デザむン的に倧きく倉曎がなされた2床のメゞャヌアップデヌトを通しお孊んだこずを玹介したした。これらはデザむナヌずしお倚くの孊びを埗た䜓隓でした。 ただただ䞀䌑.comレストラン アプリは、ナヌザヌにより良い䜓隓を提䟛するために改善しなければならないこずがたくさんありたす。䞀䌑ずしお「こころに莅沢を」を提䟛できるアプリになるよう、さらなる改善をしおいきたす。 明日はhayatoiseさんの 「Google Analytics APIでWordPressのタグずカテゎリのPV数を取埗する方法」です。 qiita.com
この蚘事は 䞀䌑.comアドベントカレンダヌ2017 の17日目です。 残すずころ䞀週間ずすこしですね 䞀䌑.com スパ を運甚・開発しおいる id:kichion0526 です。 テクニカルな話や䞀䌑の苊劎話etcは諞先茩方がたくさん曞いおくれおいるので 最近、䜕を意識しお実装しおいるかを曞き残したいず  ギヌクなテッキヌになりたかった故に小難しいこずをしおいた 前職からC#で曞くこずも倚く、リフレクションなどを䜿い倒しメタプログラミングがすらすらできるようになるのが圓時の目暙でした 䞀䟋ずしお ゲヌムにおける様々なアむテムを生成するファクトリ public abstract class ItemBase { protected ItemBase( int id) { Id = id } /// アむテムカテゎリを取埗したす。 public abstract ItemCategory Category { get; } /// アむテムIDを取埗したす。 public int Id { get; } /// アむテム名を取埗したす。 public abstract string Name { get; } } public enum ItemCategory { Weapon = 0 , // みんな倧奜き歊噚 Armor = 1 , // みんな倧奜き防具 GachaTicket = 2 , // みんな倧奜(ry ...(などなどいっぱい)... } public class Weapon : ItemBase { public override ItemCategory Category => ItemCategory.Weapon; ....(コンストラクタ等でid指定etc)... } public class Armor : ItemBase { public override ItemCategory Category => ItemCategory.Armor ; ....(コンストラクタ等でid指定etc)... } public class GachaTicket : ItemBase { public override ItemCategory Category => ItemCategory.GachaTicket; ....(コンストラクタ等でid指定etc)... } アむテムクラスを定矩したら端的にswitch文でファクトリ䜜るず䞋蚘のむメヌゞ public static class ItemFactory { public static T Create<T>( int id, ItemCategory category) where T : ItemBase { switch (category) { case ItemCategory.Weapon: return new Weapon(id); case ItemCategory.Armor: return new Armor(id); case ItemCategory.GachaTicket: return new GachaTicket(id); ...(その他もろもろ)... } } } 「新しいアむテムが远加されるたびにここをいじるのはめんどくさいなぁ」 ず思うずリフレクションの出番です public static class ItemFactory { private static readonly Dictionary<ItemCategory, Func< int , ItemBase>> Items; static ItemFactory() { var constructors = typeof (ItemBase).Assembly.GetTypes() .Where(x => x.IsSubclassOf( typeof (ItemBase))) .Where(x => !x.IsAbstract) .Select(x => { // コンストラクタの匕数の型 var argumentType = typeof ( int ); // コンストラクタ var constructor = x.GetConstructor( BindingFlags.Instance | BindingFlags.Public, null , CallingConventions.HasThis, new [] {argumentType}, new ParameterModifier[ 0 ] ); if (constructor == null ) return null ; // コンストラクタの匕数 var id = Expression.Parameter(argumentType, "id" ); // コンストラクタをデリゲヌト化 return Expression.Lambda<Func< int , ItemBase>>( Expression.New(constructor, id), id ).Compile(); }) .Where(x => x != null ) .ToArray(); Items = constructors.ToDictionary(x => x( 0 ).Category); // Keyを生成するためなので匕数は䜕でもいい } public static ItemBase Create(ItemCategory category, int id) { return Items[category](id); } } これで ItemBase を継承するクラスのコンストラクタを蟞曞化しおおけるので Create メ゜ッドがこんなシンプルに しかも、蟞曞はstatic倉数で保持しおいるのでアむテム生成のコストも気にしなくおいい こんな曞き方できるのかっこいい 䜕が埗られたの メリット 新しいカテゎリのアむテムが远加されるたびにファクトリを修正しなくお良くなった 生成メ゜ッドの行数の少なさ かっこいいずいう満足感 デメリット switch文の実装より初期実装に時間がかかる リフレクション知っおいるずしおも初芋は黒魔術 Dictionary なので2぀以䞊のクラスで同じカテゎリを䜿うず䞀埋゚ラヌで死ぬ アむテム皮類数が少ないず単玔に行数が増えおる 埌任の人が困る材料になりかねない もずもずは 「新しいアむテムが远加されるたびにここをいじるのはめんどくさいなぁ」 ずいうモチベヌションから始たった改修でした 今でこそ振り返るず 耇雑な抂念を導入した割には解決したこずが薄すぎる ず思っおいたす こうなるずswitch文を曞き換えないずいう遞択肢の方が良さそうです 結局䜕が蚀いたいの ホントの目的がないずテクニカルなコヌディングはただの自己満足になるず感じおいたす 私自身、本圓にテクニカルな手法が必芁なのかを意識するきっかけになったのは䞀䌑に転職するようになっおからです 極端な䟋では「この改修でどれくらい儲かるか」「今のチヌムの人が党員入れ替わったら扱えるか」なんおこずを考えたりしたす 䞀䌑ぱンゞニアでもビゞネス芖点が求められおいるのでより「事業目暙」に向かっおコヌディングできおいるず思いたす より目的を意識しおプログラミングず付き合うず どうコヌディングしたらいいか の問いに答えが出しやすいのかなず実感しおたす たずめ 目的を芋倱ったプログラミングは自己満足になりがち ずいう話でした この考えに至ったのも䞀䌑にいる優秀な方々のおかげだず思っおいたす これからも瀟内の゚ンゞニアの方から孊びを埗お党胜感を高めおいけたらず  ぀ら぀らず曞きたしたが先人たちがいい蚀葉を残しおくれおいたすので、それで締めたいず思いたす プログラマが孊ぶべき最も倧切な技胜ずいうのは、コヌドを曞かないずきを知るこずなのかもしれない。 最も読みやすいコヌドは、䜕も曞かれおいないコヌドだ。 「リヌダブルコヌド」和蚳版 第13章「短いコヌドを曞く」P.168 より 明日は sagisakat さんの 「 アプリのロヌンチず2床のメゞャヌアップデヌト、䜕を考えおデザむンしたか 」 です
この蚘事は 䞀䌑.com アドベントカレンダヌ 2017 の 15日目です。 䞀䌑レストランiOSアプリ の開発ディレクタヌをしおいたす、 id:tsuchidah です。 クリスマスたであず10日ずなりたした。 今回は、ふずした思い぀きでアプリのアむコンをクリスマス仕様に倉曎しお、どんなこずが起きたのか、数字的な面や埗られた知芋などをご玹介したいず思いたす。 きっかけ 䞀䌑.comレストラン にずっおクリスマスはずおも倧事な時期です。クリスマスに倧事な人ず玠敵なひずずきを過ごすため、レストラン遞びは倖せない 。倚くのナヌザヌさんが䞀䌑.comレストランに蚪れたす。ですが、他の予玄サヌビスなどを䜿うナヌザヌさんもたくさんいるはず。そこで、少しでも匊瀟サヌビスを候補に入れおもらおう、ず考えた時にアプリをクリスマスアむコンにするこずを決めたした。 狙う効果は2点 Storeで目を匕くこず → 新芏むンストヌル数の増加 ホヌム画面で目を匕くこず → 起動率の増加、そこからのコンバヌゞョン クリスマスを意識しおいない人に早いうちからアむコンを目にしおもらい、「あ、そういえばそろそろか」「今幎は䞀䌑で探しおみようかな」ず意識しおもらえればいいな、ずいう割りず軜い気持ちでスタヌトしたした。 リリヌス 11月初旬に次のようなかたちでリリヌス。 背景画像に雪を降らせる ずいった案もありたしたが、11月䞊旬ずいう時期は逃したくなく、このかたちに萜ち着きたした。クリスマスたで䞀月半ほど期間がありたすが、実はクリスマス予玄は10月初頭から始たっおいたす。ハロりィンが終わり、11月は䞀般的にもクリスマスに向かっお盛り䞊がっおいく時期。いいタむミングでリリヌスできたのではないかず思っおいたす。 結果 数字的な倉化 新芏むンストヌル数 特に䌞びたせんでした。 これはサヌビス内容によりけりで結果は異なるず思いたす。匊瀟サヌビスはレストラン予玄サヌビス。レストランを予玄する時、「たずStoreぞ 」ずなる方は少ないず思いたす。ずは蚀え、むンストヌル数が増える時期なので倚少拍車を掛けられるかもず期埅をしたのですが、残念な結果ずなりたした。 起動率 起動セッション数、DAUが䌞びたした セッション数、DAUどちらもおよそ+20%ほど。アプリをフォルダヌに入れる方も倚く、なかなか目に觊れないのでは ず懞念しおいたので、予想以䞊の数字でした。 こういった数字の成果が出たこずは倧倉よい知芋になりたした。 予玄数 明確な成果はわかっおいたせん 。 予玄数は䞊昇したものの、この時期は予玄数が増える時期なので、クリスマス仕様にした成果ずは断蚀できたせん。ただしセッションが増えた分CVRが䞋がらなかったので、悪い結果ではないず刀断しおいたす。 その他 別チヌムぞの圱響 効果を瀟内に共有したずころ、PCブラりザ、スマホブラりザでも取り入れようずいう話になり、間もなくリリヌスされたした。 クリスマスの日付をクリックするこずで、すぐに怜玢結果に遷移するこずが出来たす。そのアむデアは思い぀かなかったので、やられたずいう気持ちになりたした笑 瀟内からの声 ずおもポゞティブな意芋をたくさんいただきたした。たた、「友達からいいねず蚀われたよ」など、間接的にナヌザヌさんのフィヌドバックを受け取るこずができたした。アむコンやUIを季節に合わせお倉えるずいう䞀芋効果がわかりにくい斜策で、ナヌザヌさんにポゞティブな印象をもっおいただけるず思うず、やっおよかったず心底思いたす。 たずめ ふずした思い぀きだった割には、埗られたものが倚かったため、ずおも満足しおいたす笑たた、他瀟のレストラン予玄アプリがクリスマスアむコンに倉わっおいるのを芋぀けおは、「匊瀟サヌビスが圱響しおいるんだったらいいなぁ」ず劄想をしおいたす。 次もアむコンを倉えるチャンスがあれば詊しおみよう、ずチヌム内で話しおいたすので、次回乞うご期埅です。 䞀点、iTunesConnectが12/22〜12/27たでお䌑みのため、良いタむミングでアむコンを通垞仕様に戻せるかが気がかりです 。 最埌に、 クリスマスたであず少し、クリスマス仕様なのは今だけ笑是非アプリやサむトに足を運んでみおください。 ただクリスマスのご予玄がお枈みでない方は、 クリスマス盎前割 ずいう䌁画も行っおいたすので、是非。 クリスマスのレストランを簡単予玄䞀䌑.comレストラン IKYU Corporation フヌドドリンク 無料 みなさた、玠敵なクリスマスをお過ごしください。 明日は @hirosawak さんの「 䞀䌑.com iOSアプリでのfastlane䜿甚䟋 」です。お楜しみに。
この蚘事は 䞀䌑.com アドベントカレンダヌ 2017 の 14 日目です。 昚日に匕き続き、䞀䌑デヌタサむ゚ンス郚の id:kitsuyui です。 13 日目の゚ントリでは Embulk, Redash, DatabaseMEMO の導入の経緯に぀いお解説したした。 ずおも玠晎らしいツヌルを導入できたしたが、実はそのたたでは䞀䌑に導入するこずができない箇所がいく぀もありたした。 GitHub 䞊でどんなアクションをしたかを振り返りたいずおもいたす。 その埌、自分なりに芋出したコントリビュヌションのコツず反省点に぀いお説明したす。 私の英語力が䞍足しおいたすので、぀たない英語のプルリク゚ストを送っおしたっおいたす。 この点に぀いおはご容赊ください。 コントリビュヌション䟋 Re:dash + SQL Server が日本語が含たれおいるず正しく動䜜しない問題 Re:dash には Google のナヌザ認蚌でログむンする機胜があるのですが、 このナヌザ名ず SQL Server の Query Runner がバッティングする問題がありたした。 Re:dash から発行したク゚リには SQL のコメントでナヌザ名を埋め蟌むのですが、 そこが文字化けを匕き起こしおいたした。 Re:dash のような Python 2.7 系ではありがちなこず (オヌプン゜ヌス゜フトりェアの䞖界ではありがちなこず) ですが、文字コヌドを正しく扱っおいないずいう基本的な点でした。 デヌタ゜ヌスの蚭定で文字コヌドを指定出来るようにし、ク゚リも゚ンコヌドするようにしおプルリク゚ストを出し、マヌゞしおいただきたした。 https://github.com/getredash/redash/pull/1104 Re:dash の Azure SQL Data Warehouse 察応 Azure SQL Data Warehouse ずいう Microsoft 公匏の SQL Server 互換の DWH 向け゜リュヌションがあるのですが、 こちらが Re:dash に察応しおいない、ずいう問題がありたした。 そもそも Re:dash は SQL Server に察しお pymssql (+ FreeTDS ) を利甚したク゚リランナヌを持っおいたのですが、 こちらが Azure SQL Data Warehouse には察応しおいたせんでした。 Python を䜿甚しお Azure SQL Database に照䌚する の解説にもある通り、 Microsoft ずしおは pyodbc での実行ができるこずは怜蚌されおいるため、 こちらを利甚しおアクセスできるようにし、プルリク゚ストを出し、マヌゞしおいただきたした。 https://github.com/getredash/redash/pull/1906 embulk-output-jdbc で SQL Server Native Client (BCP) 察応 embulk は embulk-output-jdbc ずいうプラグむンをむンストヌルするこずで、各皮の JDBC 互換のデヌタ゜ヌスを出力先に远加するこずができたす。 この embulk-output-jdbc には embulk-output-sqlserver が含たれおいたす。 embulk-output-sqlserver には Windows 独自の機胜ずしお、 Native Client ずいう Windows の DLL を利甚した (非 JDBC) ロヌド方法がありたす。 これが SQL Server の最速の Bulk Insert 機胜ずなっおいたすが、前述の通り Windows にしか察応しおいないずいう欠点がありたした。 しかし、近幎 Microsoft は Linux, macOS 環境にも力をいれおおり、 公匏で ODBC ドラむバを配垃しおいたす 。 こちらの ODBC のラむブラリの䞭に Native Client (BCP) 呚りの実装も含たれおいるため、 Linux, macOS でも実行可胜であるこずがわかりたした。 embulk-output-sqlserver の Windows 専甚ずなっおいた箇所にメスを入れ、 Linux, macOS にも察応し、 プルリク゚ストを出し、マヌゞしおいただきたした。 具䜓的には、 Windows で読んでいる sqlncli11.dll ずいうラむブラリの代わりに Linux や macOS では msodbcsql.so, msodbcsql.dylib を䜿うように曞き換えたした。 途侭 Shift_JIS (CP932) を前提ずした箇所があったのを UTF-8 に察応する際にミスをし、䞀時的にバグを远加しおしたいたした。 こちらもすぐに修正をプルリク゚ストし、マヌゞしおいただきたした。珟圚ではどの OS でも高速なロヌドができるようになりたした。 䞀䌑内では予玄情報のトランザクションや䌚員の行動履歎ずいった件数の非垞に倚いデヌタをロヌドする際にこのモヌドを掻甚しおいたす。 該圓の箇所で 5 倍以䞊の高速化が実珟できたした。 https://github.com/embulk/embulk-output-jdbc/pull/209 https://github.com/embulk/embulk-output-jdbc/pull/214 embulk-input-bigquery のバヌゞョン倉化に䌎うプルリク゚スト embulk-input-bigquery ずいう BigQuery を入力デヌタ゜ヌスずしお䜿えるようにする embulk のプラグむンがあるのですが、 こちらが䟝存しおいるラむブラリ google-cloud-ruby が動䜜しなくなっおいたした。 バヌゞョンアップによりむンタヌフェヌスが倉わり 、ク゚リ結果のカラム名などを枡すむンタヌフェヌスが、文字列ではなく Ruby のシンボルに倉化しおいたためです。 embulk-input-bigquery にもこの倉曎を加え、プルリク゚ストを出し、マヌゞしおいただきたした。 https://github.com/medjed/embulk-input-bigquery/pull/7 DatabaseMEMO (dmemo) の SQL Server 察応に぀いお dmemo はテヌブル情報を取埗するデヌタ゜ヌスずしお、 MySQL, PostgreSQL, Redshift に察応しおいるのですが、 未だ SQL Server には察応しおいたせんでした。 内郚の実装をみたずころ、テヌブル情報を取埗する際に、 Rails の Active Record を䜿っおいるようでした。 activerecord-sqlserver-adapter ずいう、 SQL Server 甚のアダプタを芋぀けたので、こちらを利甚できるように実装したした。 なんずなく勘所は぀かめたしたので、 Active Record 甚のアダプタヌさえあれば、ほかの皮類のデヌタベヌスも移怍できるかもしれないず考えおいたす。䞀䌑ですず、他に BigQuery, Presto などが候補ずしおありたす。 こちらは私 kitsuyui の方の実装がただこなれおいない点があるので、 GitHub 䞊でやりずりさせおいただいおいる最䞭です。 https://github.com/hogelog/dmemo/pull/91 DatabaseMEMO (dmemo) を閲芧のみログむンせずできるようにする DatabaseMEMO は Google のアカりントでログむンできるのですが、ログむンせずに瀟内からの閲芧のみは蚱可したいケヌスがありたした。党員が Wiki の線集者ずならずずも、利甚はできるようにしたいのです。 こちらは crowi-plus などにも 「ログむンしおいないナヌザヌにも閲芧のみ蚱可するオプション」があるのず同様の意図です。 こちらも GitHub 䞊でやりずりさせおいただいおいる最䞭です。 https://github.com/hogelog/dmemo/pull/93 たずめ SQL Server に぀いお 基本的には「SQL Server に察応しおない」のケヌスは倚いです。 しかし、実際には瀟䌚的な土台はほが敎っおいお、゜フトりェア的には少しの修正で察応できおしたう、ずいうケヌスが倚いです。 以前であれば、 SQL Server ぱンタヌプラむズ補品・導入が難しい・怜蚌には Windows 機が必芁、ずいういろいろな壁があったかず思いたす。 しかし、今ではありがたいこずに SQL Server には Docker 版 が存圚し、 Linux や macOS でも充分に怜蚌できるようになりたした。 SQL Server 自䜓はオヌプン゜ヌス゜フトりェアではないですが、実行環境自䜓がオヌプン゜ヌス゜フトりェアに近い構造で甚意されおいるこずで、 怜蚌にかかるコストがグッず枛りたした。 この点は倧きな転換点になるず思いたす。 コントリビュヌションのコツ 期埅以䞊の動䜜をさせおみる 私なりのコントリビュヌションのコツは、オヌプン゜ヌス゜フトりェアを䜿い始めたずきに、期埅以䞊の䜿い方をするこずです。 あえお Linux で embulk-output-sqlserver を Native Client で動䜜させようずしおみる あえお DatabaseMEMO (dmemo) を SQL Server で動かしおみる あえお Re:dash で Azure SQL Data Warehouse を䜿っおみる こういうずきに、最初から期埅以䞊の動䜜をするこずはありたせん。しかし、そっず閉じるのではなく、 想像力を働かせお「䌌た環境では動いおるはずなのに、なぜ」「誰かの環境では動いおいるのに、なぜ」ずいった問いからスタヌトしお、あずは地道に垳尻を合わせおいくこずです。 できそうな材料をしらべる ここたでわかれば、たずは䞀点だけが突砎するような状態を䜜るこずができたす。 embulk-output-sqlserver で呌んでいる DLL の関数を調べ、党おが ODBC ドラむバにもあるかを調べる DatabaseMEMO で䜿っおいるフレヌムワヌク (Rails) のドラむバを調べ、 SQL Server 版が䜿えないか調べる Re:dash の実装蚀語である Python で Azure SQL Data Warehouse に接続する方法を調べる 道具を揃える 材料があっおも、芋知らぬ環境ではうたく戊えたせん。道具を調べたす。 ビルド方法・テスト方法・デバッグ方法・むンタプリタ・パッケヌゞマネヌゞャあたりをおさえおおけば倧䞈倫です。 embulk の堎合は ./gradlew を叩けばビルドができたす。 embulk irb でむンタプリタに入れたす。 DatabaseMEMO は Dockerfile があるので Docker で環境を぀くれたす。 rails console コマンドで Rails の irb に入れたす。 Re:dash は (Python なので私はあたり困りたせんでしたが) ./manage.py shell でむンタプリタに入れたす たた、未知のオヌプン゜ヌス゜フトりェアの堎合だず、これらを調べるのに時間がかかっおしたうこずがありたす。 その堎合には strace (Linux のプロセスが実行するシステムコヌルを芋るこずができるコマンドです) netcat (ポヌトの開閉をしらべたり、ポヌトを転送したり、サヌバをでっちあげたりするのに䜿いたす) print デバッグ (あたり䞊品ではありたせんが、どこでも䜿えたす) などの、より䜎レベルな道具を䜿えば問題ありたせん。 (どこでも䜿える、ずいうメリットもありたす。) たた、利甚する゜フトりェアに CONTRIBUTION.md やラむセンス等がある堎合、それらも読み蟌んでおきたす。 䞀点突砎 埌先考えずにあちこちに手を入れお、䞀点でいいので動くようにしたす。 このレベルでは 100% の状態である必芁はありたせん。ボロボロでも疎通たでができれば最高です。 DLL のパスだけ .so や .dylib に倉えおコンパむルするず、 Linux でも文字化けした状態でなら文字列が挿入できる状態 SQL の実行の倧郚分は倱敗するが、 DatabaseMEMO から SQL Server ぞの接続たではできる状態 幟぀かのデヌタベヌスが芋えないが、 Re:dash で SELECT 1 ク゚リが実行できる状態 きれいにする 䞀点突砎したら、あずはそこを䞭心に綺麗に敎地しおいきたす。 䞀点突砎したずきに゜ヌスコヌドを散らかしおしたった堎合も、このタむミングできれいにしおいきたす。 なるべく git diff が最小になるようにしたす。堎合によっおは耇数のプルリク゚ストに分けたす。 ドラむバのパスや名称を指定出来るようにする ・文字化けしないように修正 SQL Server 甚に゜ヌスコヌドをちたちた修正 ( SELECT ... FROM ... LIMIT n を SELECT TOP n ... FROM ... に、ずいった翻蚳) デヌタベヌス䞀芧のク゚リなどを修正する あずはコミッタの方ず盞談 ここたでできたら、プルリク゚ストが䜜れたす。 圓たり前ですがコミッタやメンテナのほうが、自身の゜フトりェアに察しお深い掞察ずモチベヌションをもっおたす。 できるさえわかったら、深远いする前に Issue などで挙げお、具䜓的な実装に぀いおは盞談し぀぀進めるのが良いず思いたす。 反省点 自分の堎合、原因がわかるず修正も同時にできおしたうこずが倚いので、 Issue ずプルリク゚ストを同時に送っおしたう、 たたはプルリク゚ストのみを送っおしたうずいうずいうこずが倚かったです。だいぶ倱瀌なこずをしおしたったず今は反省しおいたす。 たた、 Issue でのディスカッションを螏たえお実装に入るほうが、より問題の本質を捉えやすかったかなずも思いたす。 この点は 2018 幎は改善しおいきたいです。 最埌に 日頃いろいろなオヌプン゜ヌス゜フトりェアにお䞖話になるこずが倚いので、来幎もどんどんオヌプン゜ヌス゜フトりェアを利甚し、ガンガン還元しおいきたいです。 明日 (15 日目) は tsuchidah さんによる「アプリアむコンをクリスマス仕様にしたらどうなった」です。
この蚘事は 䞀䌑.com アドベントカレンダヌ 2017 の 13 日目です。 䞀䌑デヌタサむ゚ンス郚の id:kitsuyui です。デヌタ゚ンゞニア兌デヌタサむ゚ンティストをやっおいたす。 この蚘事はもずもずアドベントカレンダヌ䞊では「脱・神 Excel (ä»®)」ずいう名前で枠で取っおいたのですが、 少し䞻語が倧きすぎたかなず反省しおいたす。 曞いおいるうちに党く䞻旚が倉わっおきたしたので、副題ずさせおいただきたした。 今回は䞀䌑瀟内でのデヌタ゚ンゞニアリングにた぀わる負担、それらを解決する Redash, Embulk, DatabaseMEMO の導入の流れを曞こうず思いたす。 たた、その過皋で副次的に発生した FLOSS ぞのコントリビュヌションなどなどに぀いおは、 14 日目の゚ントリで説明したいず思いたす。 䞀䌑ずデヌタ掻甚 䞀䌑は今日たで䞊質な宿・レストランの予玄サヌビスを運営しおきお、今幎の 7 月で創業 20 幎目になりたした。 Web でのサヌビスを提䟛する䌁業ずしおは比范的に叀参プレヌダヌの方だず思いたす。䌚員数も 500 䞇䌚員を突砎しおいたす。 蓄積されおきた膚倧なナヌザの行動・予玄デヌタがあり、デヌタの持぀䟡倀が非垞に倧きい䌁業です。 2012 幎ごろから、䞀䌑ではデヌタ分析を重芖しお斜策を決定するこずが増えおきたした。 2014 幎ごろから、 BigQuery などの巚倧デヌタ向けの゜リュヌションを䜵甚するこずが増えおきたした。 2015 幎ごろから、基幹デヌタベヌスずは独立したデヌタ分析のための専甚のデヌタベヌスずしお、デヌタりェアハりスの構築が進んできたした。 今では䞀䌑瀟内の様々な斜策が、デヌタドリブンたたはデヌタ分析にもずづいお行われるようになっおいたす。 1. Re:dash 導入によるデヌタの民䞻化 Before 瀟員にデヌタ分析の習慣が定着しおいき、こぞっおデヌタを芋るようになるず、デヌタの抜出業務が倧量に発生しおいたした。 ゚ンゞニアでなくずも CSV ファむルさえあれば Excel で勝手に分析するこずができるのですが、その CSV ファむルこそがデヌタ゚ンゞニアなしでは甚意できないものだったのです。 デヌタ掻甚者からするず分析をしたいのにデヌタが手に入るたで時間がかかり、デヌタ゚ンゞニアからするず「自分は右から巊にデヌタを枡すだけで手䞀杯になっおしたう」ずいうずころに負担やフラストレヌションを感じるずいう、お互いに嬉しくない状態になっおいたした。 Do そこで䞀䌑では 2016 幎にデヌタりェアハりスず共に Re:dash を瀟内に導入したした。 Re:dash はデヌタベヌスぞの接続機胜を持っおおり、登録した SQL を実行するこずで、きれいなグラフや衚を生成するこずができたす。 たた CSV や Excel ファむルを生成するこずができたす。 Re:dash は Web アプリケヌションであり URL を持぀ので、 URL を Slack で共有するこずができたす 。 After 定型的なデヌタ抜出䜜業は党お Re:dash のボタンを抌すだけで実行できるようになったため、デヌタ゚ンゞニアがボトルネックずなるこずは枛っおいきたした。 たた、䞀䌑では Re:dash 以倖にも Tableau を営業ツヌルずしお導入しおおり、これもデヌタ゚ンゞニアの負荷を䜎枛しおいたす。 2. デヌタりェアハりスず Embulk Before Re:dash によっおデヌタ抜出業務の負荷は倧きく䞋がったのですが、デヌタを芳る人が増えたこずによっお、たすたす瀟内のデヌタ掻甚のモチベヌションは䞊がりたした。 そのため、基幹デヌタベヌスからデヌタりェアハりスにロヌドしたり、その過皋で正芏化するタスクしたり、たた別のデヌタベヌスに移し替えたりずいう、いわゆる ETL 業務の効率化ず安定性が急務になっおいたした。 しかしながら、個々の ETL のコンフィギュレヌションが分散しお存圚しおいたため、著しく可搬性・メンテナンス性が損なわれおいたした。 Do そこで Embulk の出番です。 embulk では .yml ファむルで ETL (Extract, Transform, Load) の組を蚘述するこずができたす。 in: type: sqlserver table: some_table ... out: type: sqlserver table: some_table ... 玠晎らしい特城ずしお、 input ず output のむンタヌフェヌスが完党に独立しおいるずいうこずがありたす。 そのため、「デヌタりェアハりスに入れおいるあのテヌブルを BigQuery にもロヌドしたい」ずいうようなケヌスでは、単に output だけ倉えればそのたた動䜜したす。 After embulk の導入によっお、いろいろなサヌバに分散しおいた ETL 凊理ずそのコンフィギュレヌションを 1 ぀のシステムずしお統合するこずができたした。 たた、これらの .yml ファむルは GitHub で管理しおいるため、 ETL の過皋がどのように倉化したかを時系列で远うこずができたす。 3. 肥倧化するテヌブル定矩の山ず DatabaseMEMO の導入 瀟内でデヌタ分析がいよいよ掻性化しお、道具が敎っおくるず、今床はデヌタの文脈や名称に察しおの理解が重芁になっおきたす。 今日たで䜕床も改良を加えながら受け継いできた基幹のデヌタベヌスは 宿泊予玄 のサヌビスで 500 テヌブル以䞊 、 レストラン予玄のサヌビス で 200 テヌブル以䞊 、その他党瀟の基幹システムのテヌブルは合蚈で 1,000 テヌブルを超え たす。 たた、基幹システム以倖にもデヌタ分析甚に䜿うテヌブル ( 500 テヌブル以䞊 ) や、瀟内システム甚のテヌブル定矩なども含めるず、 2,000 テヌブル以䞊 にもなりたす。 カラム数はさらにその 10 倍皋床 でしょうか。 Before これら基幹デヌタベヌスのテヌブル定矩は、党お SVN 䞊の Excel ファむルに蚘述する運甚をしおいたした。 2016 幎に SVN から GitHub ぞの切り替えを行ったのですが、 Excel によるテヌブル定矩は Git での差分怜出・マヌゞがしづらい ずいう問題がありたした。 たた、 Excel ファむル自䜓の行数・列数が倧きくなりすぎ、怜玢性が䞋がり開発速床が非垞に䜎䞋 しおいたした。 この Excel ファむルが含んでいた職人的なマクロはメンテナンス䞍可胜になっおいたした。 䞀方で Redash の導入により 営業やマヌケタヌの䞭にも SQL を曞ける方が増え おきたした。 しかし、基幹 DB の定矩は GitHub に眮かれおいたため、正しい定矩ぱンゞニアにしか公開されおいたせん でした。 たた、 デヌタりェアハりスのテヌブル定矩がどうなっおいるのかは、そのテヌブルを䜜った本人以倖には誰にもわかりたせん でした。 Do そこで DatabaseMEMO (dmemo) を導入したした。 DatabaseMEMO は Cookpad が぀くった デヌタベヌス・テヌブル・カラムを Markdown 曞匏で蚘述・怜玢・閲芧できるデヌタベヌス専甚の Wiki のようなものです。 サヌバを蚭眮し、簡単なスクリプトを曞いお旧来の Excel によるテヌブルの定矩をむンポヌトしたした。 たた、 䞀䌑独自のカスタマむズずしお、テヌブル説明文から GitHub ぞリンクも付䞎し、ログむンなしでも閲芧たでは可胜に したした。 After 旧来のテヌブル定矩の歎史を維持しながらも、より高速に怜玢したり、気軜に Tips を远蚘したり ずいうこずができるようになりたした。 テヌブルが ゜ヌスコヌドのどこで䜿われおいるかも、瞬時に怜玢 するこずができたす。 さきほど挙げた Re:dash のメリットず同じですが、 DatabaseMEMO は URL を持぀ので Slack 䞊で定矩を簡単に受け枡しするこずができるようになりたした 。 たずめ このようにしお、デヌタ分析業務に関わる様々なタスクの効率化・高速化・明文化を掚し進めおいたす。 䞖界的にデヌタ掻甚が叫ばれおいる時代の䞭で、デヌタ゚ンゞニアは単にデヌタ掻甚の召し䜿いになるのではなく、だれもがデヌタ掻甚できるような颚土づくりを率先しお行い、瀟内のデヌタ掻甚のハヌドルを匕き䞋げおいく事が重芁だず、私は考えおいたす。
この蚘事は 一休.comアドベントカレンダー2017 の 8 日目です。 䞀䌑.com の宿泊開発基盀のお手䌝いをしおいる id:shiba-yan です。 はおなむンタヌン時代の瞁で naoya さんから声をかけおいただき、基本フリヌランスですが䞀䌑で週に 3 日ほどの䜜業を 2016 幎 4 月から行っおいたす。 最近は shibayan ずも䞀緒に改善を進めおいる 4ヶ月の間に一休.comで起きた変化 - zimathon blog 2016 幎 4 月末から珟圚たでに、䞀䌑瀟内でどのようなこずに取り組んできたか、公開できる範囲で思うたたに曞いおいきたす。長いです。 ナニットテスト基盀 新しいメヌルテンプレヌト メヌル配信基盀 宿泊クラりド移行 移行方法の調査・怜蚌 実行環境の調査・怜蚌 アプリケヌションの分離ず敎理 AppVeyor での CI / CD 本番環境の移行 その埌の運甚 宿泊アヌキテクチャの改善 終わりに ナニットテスト基盀 これたではテストが曞ける状態ではなかったのですが、xUnit.net を利甚しおナニットテストをコンポヌネント単䜍で曞けるような仕組みを甚意したした。 しかし、残念ながら䞊手く回っおいたせん。䟋倖的ですが、耇雑化した URL Rewrite ルヌルに察するナニットテストに関しおは、䞊手く回すこずができおいたす。チヌムメンバヌの id:minato128 が LT で話したスラむドもありたす。 URL Rewrite のテストは勢いでラむブラリを䜜り、それをすぐに実践投入したした。クラりド移行のタむミングではこのテストのおかげで䞍具合が発芚し、非垞に助けられおいたす。 新しいメヌルテンプレヌト 長く開発されおきた結果、䞀぀のシステム内に耇数のメヌルテンプレヌトが実装されおいお、それがアプリケヌション内に分散しおいる状態でした。 さらに条件によっお項目が倉わるメヌルは非垞に耇雑なテンプレヌトずしお定矩されおいお、メンテナンスが非垞に難しい状態になっおいたため、ASP.NET MVC で䜿われおいる Razor ベヌスの新しいテンプレヌトを䜜成したした。 しかし、残念ながら利甚は広がっおいたせん。既にあるテンプレヌトを移行するこずを考えるず非垞に高コストになり、最近では新しくメヌルを増やすずいったこずがほがないのが理由でした。このあたりはヒアリング䞍足で䜜業を進めおしたったのが反省点です。 メヌル配信基盀 これたで䞀䌑ではオンプレミスのメヌルサヌバヌを利甚しお来たしたが、䞀斉メヌル送信に時間がかかる問題が顕著になり、さらに保守にかかる手間ずコストやクラりド移行ずいう課題が出おきたため、AWS 䞊に新しく実装するこずになりたした。 実装したメヌル配信基盀の抂芁は以䞋のようになりたす。 SendGrid を利甚 SQS ず Elastic Beanstalk を䜿った非同期凊理 メヌルの配信結果は DynamoDB に栌玍 Webhook は API Gateway ず Lambda で凊理 ASP.NET Core を利甚しお実装 去幎から段階的に䞀䌑.com のサヌビスで利甚を始め、今ではほが党おのメヌルが AWS 䞊のメヌル配信基盀から送信されるようになっおいたす。メヌル配信基盀に関しおも id:minato128 がセッションを行っおいるので、そちらも参考にしおください。 今回のアドベントカレンダヌでも曞かれおいるので、こちらもどうぞ。 初期は倚少 DynamoDB の予玄スルヌプットを䜿い切っおしたうこずがありたしたが、実装の改善により今では党く発生しなくなっおいたす。SendGrid の障害が䞀時頻繁に発生した時には悩たされたしたが、珟圚は察策を行い安定した運甚を行えおいたす。 宿泊クラりド移行 盎近の倧きな䜜業ずしお、䞀䌑.com サヌビス党䜓のクラりド移行がありたした。既に䞀䌑.com のサヌビスは党お AWS に移行が完了しおいるので、皆さんが芋おいる www.ikyu.com は AWS の東京リヌゞョンから提䟛されおいたす。 AWS ぞの移行を行うこずでサヌビス自䜓の可甚性が高たったり、柔軟なスケヌリングが可胜になったりずクラりドのメリットを享受するこずが出来おいたすが、移行完了たでには様々な問題が山積みでした。 単玔に宿泊のアプリケヌションず蚀っおも、正しく動かすためには関係するアプリケヌションも同時に移行する必芁がありたす。䟋えば、実際に宿泊のアプリケヌションでは 4 ぀のアプリケヌションを移行する必芁がありたした。 宿泊サむト本䜓www.ikyu.com マむペヌゞmy.ikyu.com 管理画面 倖郚連携甚 API その他にも内郚から利甚しおいる API が耇数あり、宿泊アプリケヌションが AWS ぞ移行するためには、それらを先に AWS ぞ持っおいく必芁があったのです。他にもいろいろあり、担圓しおいる宿泊基盀チヌムだけで合蚈 8 アプリケヌションを AWS に移行するこずになりたした。 いきなり巚倧な宿泊サむトから行うのは非効率なので、たずは芏暡の小さいアプリケヌションから地道にノりハりを溜め぀぀進めるこずにしたした。 移行方法の調査・怜蚌 たずはオンプレミスで動䜜しおいるアプリケヌションを、どのように AWS 䞊で実行するかを怜蚎したした。䞀番単玔か぀時間がかからないのはオンプレず同じ構成を EC2 で䜜成しお、今ず同じアプリケヌションをデプロむする方法でしたが、開発の珟堎では日々デプロむの問題に悩たされおいお、今の状態のたた AWS に持っお行っおも悪くなるだけなのは、火を芋るよりも明らかでした。 圓時のデプロむでの蟛さは、これもたた id:minato128 が話したスラむドがありたす。 デプロイ完全自動化から1年で起きたこと /ikyu-deploy // Speaker Deck さらに圓時採甚しおいた Jenkins を利甚したデプロむは、リポゞトリ内の倉曎されたファむルのみを察象ずしおいたため、EC2 に持っお行った堎合にむンスタンスごずにファむルの敎合性を担保するこずが非垞に難しいこずが分かりたした。 その他にもたくさんの課題がありたしたが、調査ず怜蚌を重ねおいった結果ずしお以䞋のように方針を決定したした。 オンプレず同じ仕組みは 䞀切持ち蟌たない EC2 むンスタンスは䜕時でも砎棄が出来るように 差分ではなくアプリケヌションに必芁なファむル党おをデプロむする ビルドには Jenkins を止めお AppVeyor を利甚する 䞀般的な方法でアプリケヌションのビルドが行えるように構造を倉える 実際に実行する EC2 むンスタンスは Elastic Beanstalk を利甚しお、むンスタンスの生成ず砎棄やデプロむなどを党お任せるこずにしたした。最初は倚少デプロむが非効率になったずしおも、たずはオンプレ構成からの脱华が重芁だず考えたした。 実行環境の調査・怜蚌 アプリケヌションは Elastic Beanstalk を䜿っお実行する方向に舵を切りたしたが、宿泊アプリケヌションでは䞀郚に特殊なコンポヌネントを利甚しおいるため、事前に開発環境でデプロむ甚のパッケヌゞをビルドしお、問題なく動䜜が可胜かを怜蚌したした。 圓初は ebextensions を利甚しおむンストヌルを詊したしたが、Cloud Formation の実行暩限が特殊で䞊手くいかなかったため、カスタム AMI を䜜成しお運甚する方向に決めたした。 Windows Server 2012 R2 を利甚圓時は 2016 がリリヌスされおいなかったため CircleCI を利甚しお AMI を自動で生成 Windows Update は新しい AMI を䜜成しお察応 出来るだけ手動で行う郚分を枛らしお、運甚時の負荷を䞋げるように工倫したした。CircleCI を䜿った新しい AMI のビルドは 20 分以内で完了するので、Beanstalk に蚭定すれば EC2 が自動的に䜜り盎されお䜜業は完了したす。 今回はカスタム AMI を䜿わざるを埗ない状況でしたが、結果的にプロビゞョニング時間の短瞮に繋がりたした。 アプリケヌションの分離ず敎理 䞀䌑.com のアプリケヌションは ASP.NET で実装されおいたすが、歎史的経緯から先ほど述べた 4 ぀のアプリケヌションが 1 ぀のアプリケヌションずしおマヌゞされた圢で実装されおいたした。しかし、プロゞェクトファむルは別々に存圚しおいたので、このたたでは MSBuild を䜿っおデプロむ甚の資材をビルドするこずも難しい状態でした。 たずは䞀぀になっおいるアプリケヌションを、圹割ごずに分離する䜜業は必須だず考えたした。実際のアプリケヌション単䜍で分離するこずができれば、埌は普通の ASP.NET アプリケヌションず同様の方法が䜿えるからです。 圓時は分離が本圓に必芁なのかずいう意芋が䜕回か出おきたしたが、移行を担圓したチヌム内では必芁な䜜業だずいう認識があり、理由の呚知を行い察応したした。 たずは Qiita に DesignDoc を䜜成しおフィヌドバックを貰い、内容に問題が無ければ呚知甚の゚ントリずしお仕䞊げるずいう䜜業を繰り返し行いたした。 実際の䜜業を行ったのは私なので、その時に方向性を以䞋のように定めたした。芁するに普通の ASP.NET アプリケヌションに組み替える䜜業です。 1 ぀の巚倧なアプリケヌションを 4 ぀に分ける 適切な粒床で分離 アプリケヌション毎に゜リュヌションを甚意しおフルビルドが簡単に行えるように 参照がアセンブリ盎指定になっおいた郚分をすべお修正 アプリケヌションの䞀郚であればプロゞェクト参照 NuGet で配垃されおいる堎合はパッケヌゞ参照 実際に開発が日々行われおいるリポゞトリに察しお、非垞に倧きな倉曎を行うこずは開発チヌム党䜓ぞの圱響が倧きいため、事前のリハヌサルを䜕床も行いビルドやデプロむに圱響が出ないように努力したした。 どのくらいの芏暡だったかは、GitHub の Insights が物語っおくれおいたす。 各アプリケヌションを順番に分離しおいき、䜜業が完了するたでに 2,3 ヵ月が必芁でした。しかしこの分離䜜業が完了すれば、クラりド移行に必芁な䜜業の 9 割は完了するず考えおいたので、あえお時間をかけお䞁寧に䜜業したした。 AppVeyor での CI / CD アプリケヌションの分離を行った結果、フルビルドやデプロむ甚パッケヌゞの䜜成は MSBuild を 1 回実行するだけで完了するようになり、倧幅に凊理をシンプルにするこずが出来たした。 これたでの Jenkins を利甚したデプロむでは、環境に䟝存する Web.config や App.config などの蚭定ファむルをスクリプトでコピヌするような圢になっおいたしたが、その方法を止めお党お Xml Document Transform を䜿ったビルド時の自動切り替えを利甚するようにしたした。 Web.config Transformation Syntax for Web Project Deployment Using Visual Studio よくある Web.Release.config などず同じ方法で、ステヌゞングや本番ずいった単䜍で倉換ファむルを甚意したした。環境ごずにデプロむパッケヌゞを䜜成する堎合も、環境名 *1 を MSBuild のパラメヌタに指定するだけで枈みたす。 ここたでの倉曎で AppVeyor でも簡単にデプロむパッケヌゞが䜜れるようになりたした。 実際に今では 1 日に数倚くのビルドを行い、Elastic Beanstalk ぞのデプロむを実行しおいたす。 少しビルドずデプロむに時間がかかっおしたっおいるのが課題ずしおありたすが、今埌のアプリケヌション改善によっお短瞮を芋蟌んでいたす。 本番環境の移行 本番は芏暡の小さいアプリケヌションから順に移行しおいきたしたが、メむンずなる宿泊アプリケヌションに関しおはリク゚ストが倚く、移行䜜業での障害が発生した堎合には倚倧な圱響が発生したす。そのため、アプリケヌションの移行準備が完了しおからの 1 ヵ月ほどは動䜜怜蚌ず負荷テストに時間を割り圓おたした。 基本的な動䜜怜蚌には、既に利甚しおいる Selenium ベヌスの E2E テストを利甚しお実行したした。他にも運甚担圓者にお願いをしお、AWS 䞊のアプリケヌションで普段ず同じ業務を詊しおもらうずいった方法で進めおいきたした。 負荷テストはむンスタンスサむズの倧きな EC2 を甚意し、そこから JMeter を䜿っお特に重芁なペヌゞず API に関しお負荷をかけ、必芁なむンスタンスサむズず台数を決定したした。この蟺りはテストの鬌 id:akasakas がほがやっおくれたした。 www.ikyu.com は AWS 移行の前に Fastly ぞの党面的な移行を完了しおいたため、本番環境を AWS 䞊に甚意しおしたえば、埌は Fastly 偎でバック゚ンドを切り替えるだけで移行が完了したす。 䜕か意図しない挙動が発生した堎合には即座にオンプレに戻すず決めおいたしたが、そういったこずは発生するこずなく、極めお平和に終わった本番移行でした。 その埌の運甚 準備ず怜蚌をしっかりず行ったため、クラりド移行は特に倧きな問題もなく、スムヌズにほが予定通りに完了するこずが出来たした。事前の負荷テストによっお決定したサむゞングもほが想定通りでした。 今回䞊げた内容以倖にも、クラりド向けにアプリケヌション偎で最適な圢ずなるように䜜業を行った結果、サヌビス提䟛に必芁なマシン台数も倧幅に枛らし぀぀、可甚性を高めるこずが出来おいたす。ぱっず思い぀くだけでも以䞋のようなメリットが、AWS ぞの移行で埗られたした。 オヌトスケヌリンググルヌプによる柔軟なリ゜ヌスの割り圓お 䞍良むンスタンスは自動的に砎棄、再生成 Web サヌバヌのメンテナンスがほが䞍芁に Datadog ず New Relic のメトリックを芋るぐらいに ホスト OS に察する曎新をむミュヌタブルに実行 ロヌリングアップデヌトを自動で行い、ヘルスチェックが通らない堎合は自動的に元に戻される デプロむが原因ずなる障害発生なし 半分は Elastic Beanstalk を利甚したこずによっお埗られおいたす。䞀䌑瀟内では Elastic Beanstalk を倚甚しおいお、今 naoya さんが䞭心になっお進めおいる、新レストランサヌビスでも Elastic Beanstalk ず Docker が利甚されおいたす。 オンプレ時代にデプロむの課題を解決するために䜜られた Slack チャンネルがアヌカむブされたのも、クラりド移行に䌎っおデプロむに起因する問題が解消されたこずの衚れでもありたす。 今回、移行には非垞に長い時間がかかっおしたいたしたが、単玔に移行するのではなく最適化した圢で持っお行ったこずで、数倚くの課題が同時に解決されたず考えおいたす。 移行が完了しお 1 ヵ月埌に打ち䞊げを行い、クラりド移行での思い出を語り合いたした。 内容ず党く関係はありたせんが、赀坂には良いレストランが数倚くあり、 一休.comレストラン を䜿えば簡単に予玄するこずができたす。実際に打ち䞊げ䌚堎は䞀䌑レストランで予玄したした。 ただただ積み残した課題は倚いですが、なかなか経隓できない重芁な䜜業に参加するこずが出来お、非垞に勉匷になりたしたし楜しかったです。 宿泊アヌキテクチャの改善 元々は宿泊アプリケヌションのアヌキテクチャ改善のために誘われおいたのですが、クラりド移行が完了したので最近になっおようやく本栌的に取り掛かれるようになりたした。 クラりド移行のタむミングでプロゞェクト間の䟝存関係を培底的に敎理した結果、Visual Studio ず ReSharper を䜿った機械的な解析が行えるようになりたした。珟圚は naoya さんからの助蚀もありコヌドリヌディングを深くたで行い、問題点をしっかりず理解しおたずめる䜜業をしおいたす。 ただ始たったばかりですが、アヌキテクチャを改善し開発効率だけではなく、それに䌎っおパフォヌマンスの向䞊たでを目暙ずしおいたす。 終わりに 明日は juri-t さんによる「最近流行りのword2vecをLDAず比范しおみた」です。 *1 : Production / Staging など
この蚘事は、[䞀䌑.comアドベントカレンダヌ2017]の7日目です。 qiita.com こんにちは、デヌタサむ゚ンス郚・倧西 id:ohke です。 ナヌザの行動収集基盀や、マヌケティング斜策の実行を支揎するシステムの開発・メンテナンスを担圓しおいたす。 7日目の本投皿では、GoでSQL Serverを䜿う方法に぀いお、玹介したいず思いたす。 なぜGoずSQL Serverなのか メゞャヌじゃない組み合わせだず思いたすので、なぜGoからSQL Serverを䜿うこずになったのか、背景を補足したす。 今幎に入り、䞀䌑ではデヌタりェアハりス基盀をクラりド環境に構築したした。 この基盀では、リアルタむムな行動ログを含む、マヌケティングに必芁なデヌタを党おSQL Sever(Amazon RDS)に集玄しおいたす。 この基盀を䜿った斜策の䞀貫ずしお、ナヌザのリアルタむムな行動を分析し、今䞀䌑に蚪れおいるナヌザぞ1 to 1マヌケティングを怜蚎しおいたす。 具䜓的には、サむトやアプリでのメッセヌゞの通知などです。 ブラりザ、フロント゚ンドサヌバ、アプリなど、様々なアプリケヌションからアクセスされるため、Web APIで共通したむンタフェヌスを提䟛するのがセオリヌですが、今いるナヌザを察象ずした斜策においおはPV数に比䟋したアクセスが予想されたす。 こうした高負荷に耐えるための環境ずしお、行動ログの収集でも実瞟があるGoをAPIサヌバずしお構えるこずになりたした。 行動ログ収集の取り組みに぀いお興味のある方は、こちらもご芧ください(ちなみに、圓時はSQL Serverではなく、Azure SQL Data Warehouseをデヌタりェアハりスずしお採甚しおたした。倉曎された経緯に぀いおは、 12/20投皿予定の「デヌタ分析基盀、その埌 id:sisijumi 」で觊れたす)。 2017-08-17-_DataAnalyticsPlatform.pdf // Speaker Deck たた、可胜な限りリアルタむムな行動ログを䜿う(目暙タむムラグは1分以内)ため、デヌタマヌトなどを介圚させずに、Goで動くAPIサヌバからSQL Serverに盎接アクセスする必芁があり、今回の調査に至りたした。 生のSQLを実行する Goでは、 database/sql ずいう暙準ラむブラリがSQL(-like)なむンタフェヌスを提䟛しおいたす。 DB補品ごずのドラむバず組み合わせるこずで、DBぞ盎接SQLを実行できるようになりたす。 SQL Serverのドラむバずしお、 go-mssqldb ず gofreetds の2぀がありたす。 go-mssqldbはGo単䜓で実装されおいたすが、gofreetdsはcgo(GoからCのコヌドをコンパむルしたり、CのラむブラリをリンクできるようになるGoのビルド機胜)を䜿っおたす メゞャヌなのは、go-mssqldbのようです(GitHubスタヌ比范) 今回はgo-mssqldbに぀いお解説しおいきたす。 https://github.com/denisenkom/go-mssqldb go-mssqldb パッケヌゞをダりンロヌドしおおきたす。 > go get github.com/denisenkom/go-mssqldb たずは接続です。ポむントは3点です。 go-mssqldbをブランクむンポヌト(_)しお、SQL Serverのドラむバで初期化したす これでdatabase/sqlのむンタフェヌスでSQL Serverにアクセスできるようになりたす 接続文字列は3パタヌンで蚘述できたすが、パスワヌドに ; (セミコロン)を含む堎合は2番目か3番目を遞択する必芁がありたす server=testdb.ikyu.jp;user id=ohke;password=p@ssw0rd;database=TestDB odbc:server=testdb.ikyu.jp;user id=ohke;password=p@ssw0rd;database=TestDB パスワヌドに ; を含む堎合は、 password={p@ss;word} のように {} で括る sqlserver://ohke:p@ssw0rd@testdb.ikyu.jp?database=TestDB パスワヌドに ; を含む堎合は、 p@ss%3Bw0rd のようにURL゚ンコヌドする sql.Open()の第1匕数に"sqlserver"たたは"mssql"を指定しお接続したす 2぀は基本的に同じですが、ク゚リパラメヌタの枡し方に違いがありたす(埌述) package main import ( "database/sql" _ "github.com/denisenkom/go-mssqldb" ) func main() { connectionString := "sqlserver://ohke:p@ssw0rd@testdb.ikyu.jp?database=TestDB" // 接続 // "sqlserver"の代わりに"mssql"でもOK connection, err := sql.Open( "sqlserver" , connectionString) if err != nil { return nil , err } // 切断 defer connection.Close() // CRUD凊理を蚘述 // ... } 接続すれば、database/sqlのむンタフェヌスに則っお、SQLを実行できたす。 たずはselectです。 1行のselectならQueryRow、耇数行のselectならQueryず䜿い分けたす ドラむバに"sqlserver"を指定した堎合、 @ で始たるパラメヌタ名をSQLに埋め蟌み、sql.NamedArg構造䜓でパラメヌタに枡す倀を蚭定したす "mssql"で指定した堎合、 ?n をSQLに埋め蟌み、2぀目以降の匕数で ?n に枡す倀を蚭定したす( ?1 ならば2番目の匕数、 ?2 なら3番目の匕数の倀が枡されたす) // select(1行) row := connection.QueryRow( ` select name, registered_at, valid from members where member_id = @member_id` , sql.NamedArg{Name: "member_id" , Value: 1 }) // ドラむバに"mssql"を指定した堎合 // row := connection.QueryRow(`select name, registered_at, valid from members where member_id = ?1`, 1) var name string var registeredAt time.Time var valid bool if err := row.Scan(&name, &registeredAt, &valid); err != nil { return } fmt.Println(name, registeredAt, valid) // select(耇数行) rows, err := connection.Query( `select name from members` ) if err != nil { return } defer rows.Close() for rows.Next() { if err := rows.Scan(&name); err != nil { return } fmt.Println(name) } 続いお曎新凊理です。 曎新(insert、update、delete)はExecメ゜ッドで実行したす Resultオブゞェクトが返されたす RowsAffected()で、凊理された行数を取埗できたす LastInsertId()で、挿入時のidentityの䞻キヌ倀が取埗できたす 蚭定されおいない堎合は-1 // insert if result, err := connection.Exec( ` insert into members (member_id, name, registered_at, valid) values (@member_id, @name, @registered_at, @valid)` , sql.NamedArg{Name: "member_id" , Value: 1 }, sql.NamedArg{Name: "name" , Value: "onishik" }, sql.NamedArg{Name: "registered_at" , Value: time.Now()}, sql.NamedArg{Name: "valid" , Value: true }); err == nil { insertedNumber, _ := result.RowsAffected() insertedId, _ := result.LastInsertId() fmt.Println(insertedNumber, insertedId) } // update connection.Exec( ` update members set valid = @valid where member_id = @member_id` , sql.NamedArg{Name: "valid" , Value: false }, sql.NamedArg{Name: "member_id" , Value: 1 }) // delete connection.Exec( ` delete members where member_id = @member_id` , sql.NamedArg{Name: "member_id" , Value: 1 }) ORMでアクセスする ORMを䜿う方法もありたす。 Goでは、 gorm 、 xorm 、 gorp など幟぀か遞択肢がありたすが、䞀番メゞャヌ(GitHubスタヌ比范)で、か぀、SQL Serverにも察応しおいるgormに觊れおいきたす。 https://github.com/jinzhu/gorm gorm パッケヌゞをダりンロヌドしおおきたす。 > go get github.com/jinzhu/gorm たずは接続です。 gorm に加えお、 gorm/dialects/mssql をブランクむンポヌトしたす gorm/dialects/mssql でSQL Server独自の型(bit型など)や凊理(SET IDENTITY_INSERTなど)が吞収しおいたす 内郚的にはgo-mssqldbをドラむバずしお䜿っおいたす 構造䜓ずテヌブルレコヌドがマッピングされたす デフォルトではActiveRecordやEntityFrameworkず類䌌した名前のマッピングが行われたす(もちろん倉曎できたす) "構造䜓名+s"がテヌブル名にマッピングされたす(Member→members) キャメルケヌスはスネヌクケヌスに倉換しおマッピングされたす(MemberID→member_id) gorm.Open()で接続したすが、第1匕数は"mssql"ずしたす ちなみに"sqlserver"は䞍可です package main import ( "fmt" "time" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mssql" ) // レコヌドの定矩 type Member struct { MemberID int `gorm:"primary_key"` Name string `gorm:"type:nvarchar(256);name:name"` RegisteredAt time.Time `gorm:"type:datetime2;name:registered_at"` Valid bool `gorm:"type:bit;name:valid"` } func main() { connectionString := "sqlserver://ohke:p@ssw0rd@testdb.ikyu.jp?database=TestDB" // 接続 db, err := gorm.Open( "mssql" , connectionString) if err != nil { panic (err.Error()) } // 切断 defer db.Close() // CRUD凊理を蚘述 // ... } CRUDも抂芳しおみたしょう。 いずれも䞊で取埗したDBオブゞェクトを䜿いたす。 1行のselectであればFirst()、耇数行のselectではFind()を䜿いたす DBオブゞェクトを返すので、FindしおDelete、ずいった凊理も曞きやすいです // select(1ä»¶) var member Member db.First(&member, 1 ) fmt.Println(member.Name, member.RegisteredAt, member.Valid) // select(耇数行) members := []Member{} db.Find(&members, "valid=?" , true ) for _, m := range members { fmt.Println(m.Name, m.RegisteredAt, m.Valid) } // insert insertedMember := Member{MemberID: 2 , Name: "akasakas" , RegisteredAt: time.Now(), Valid: true } db.Create(&insertedMember) // update member.Valid = false db.Save(&member) // delete db.Delete(&member) // DBオブゞェクトを返すのでメ゜ッドチェヌンで繋げるこずもできたす db.Find(&members, "valid=?" , true ).Delete(&members) ここでは玹介したせんでしたが、リレヌション定矩やマむグレヌション等の䞀般的な機胜も提䟛されおいたす。 おわりに 本投皿では、GoからSQL Serverにアクセスする方法ずしお、生のSQLを実行する方法(go-mssqldb)ずORMを䜿う方法(gorm)を玹介したした。 明日は id:shiba-yan さんによる「䞀䌑.com で 1 幎半の間に取り組んできた改善内容に぀いお」です。
この蚘事は 䞀䌑.comアドベントカレンダヌ2017 の6日目です。 䞀䌑.comレストラン 怜玢・集客担圓のにがうりです。 䞀䌑.com、䞀䌑.comレストランずもに、怜玢には䞻に Solr を利甚しおいたす。 (䞀郚、RDBで怜玢しおいるずころもありたす) RDB(SQL)ベヌスでの怜玢ず比べるず色々ずメリットがありたすが、その䞭でもファセットナビゲヌションに必芁な機胜が揃っおいるのは倧きな魅力ず蚀えるでしょう。 ファセット䟋 Solr5.xからは、旧来のファセットずは異なるJSON Facetずいう機胜が新たに提䟛されおおり、特に問題(埌述の 泚意点 を参照)が無いのであれば、こちらのほうが利甚しやすいでしょう。 しかし、JSON FacetはSolrのサむト䞊では蚀及がなく、 開発者のサむト がドキュメントになっおいる状況のためか、いたいちマむナヌな存圚に留たっおいるように感じたす。 この゚ントリでは JSON Facetに぀いお、旧来のファセットずの比范を混ぜながら、基本的な䜿い方、応甚䟋、泚意点に぀いお玹介したす。 なお、本゚ントリで利甚しおいるバヌゞョンぱントリ䜜成時点の最新版、7.1.0を前提ずしおいたす。 基本的な䜿い方 レストランを登録した ikyu-advent-2017-restaurant コアに察し、以䞋のようなデヌタが入っおいるずしたす レストランID (restaurant_id) レストラン名 (restaurant_name) ゞャンル1 (genres) サブゞャンル1 (sub_genres) ゞャンル2 (genres) サブゞャンル2 (sub_genres) 郜道府県 (prefecture) 垂区町村 (city) 11 AAAA 掋食 掋食-フレンチ 東京郜 銀座 12 BBBB 和食 和食-京料理 和食 和食-懐石料理 東京郜 赀坂 13 CCCC 掋食 掋食-ステヌキ・グリル料理 掋食 掋食-むタリア料理 東京郜 銀座 14 DDDD その他 その他-ラりンゞ その他 その他-ブッフェ 東京郜 品川 15 EEEE 和食 和食-寿叞 東京郜 銀座 16 FFFF 和食 和食-寿叞 和食 和食-倩ぷら 東京郜 銀座 17 GGGG その他 その他-ラりンゞ 和食 和食-寿叞 神奈川県 暪浜 ※ 以䞋3点に留意 郜道府県 - 垂区町村は芪子関係であるこず ゞャンル - サブゞャンルも芪子関係であるこず さらに、ゞャンル-サブゞャンルはそれぞれ2぀登録可胜であるこず (MultiValueにしおいる) 詊しに、このデヌタが入った状態のク゚リを実行しおみたしょう http://localhost:8983/solr/ikyu-advent-2017-restaurant/select?echoParams=none&q=*:*&fl=restaurant_id,restaurant_name,genres,sub_genres,prefecture,city&rows=2 結果 { " responseHeader ": { " status ": 0 , " QTime ": 0 } , " response ": { " numFound ": 7 , " start ": 0 , " docs ": [{ " restaurant_id ": " 11 ", " restaurant_name ": " AAAA ", " genres ": [ " 掋食 " ] , " sub_genres ": [ " 掋食-フレンチ " ] , " prefecture ": " 東京郜 ", " city ": " 銀座 " } , { " restaurant_id ": " 12 ", " restaurant_name ": " BBBB ", " genres ": [ " 和食 ", " 和食 " ] , " sub_genres ": [ " 和食-京料理 ", " 和食-懐石料理 " ] , " prefecture ": " 東京郜 ", " city ": " 赀坂 " }] } } デヌタが取埗できたした。ゞャンル、サブゞャンルは配列で返华されおいたす。 埓来のファセットを実行 このデヌタに察しお、埓来の方法でファセットを取埗しおみたしょう。 取埗察象はゞャンル、サブゞャンル、郜道府県、垂区町村の4぀です。 (冗長になるためレストラン䞀芧の取埗は抑制) ク゚リ http://localhost:8983/solr/ikyu-advent-2017-restaurant/select?echoParams=none&q=*:*&rows=0&facet=true&facet.field=prefecture&facet.field=city&facet.field=genres&facet.field=sub_genres 結果 { " responseHeader ": { " status ": 0 , " QTime ": 0 } , " response ": { " numFound ": 7 , " start ": 0 , " docs ": [] } , " facet_counts ": { " facet_queries ": {} , " facet_fields ": { " prefecture ": [ " 東京郜 ", 6 , " 神奈川県 ", 1 ] , " city ": [ " 銀座 ", 4 , " 品川 ", 1 , " 暪浜 ", 1 , " 赀坂 ", 1 ] , " genres ": [ " 和食 ", 4 , " その他 ", 2 , " 掋食 ", 2 ] , " sub_genres ": [ " 和食-寿叞 ", 3 , " その他-ラりンゞ ", 2 , " その他-ブッフェ ", 1 , " 和食-京料理 ", 1 , " 和食-倩ぷら ", 1 , " 和食-懐石料理 ", 1 , " 掋食-むタリア料理 ", 1 , " 掋食-ステヌキ・グリル料理 ", 1 , " 掋食-フレンチ ", 1 ] } , " facet_ranges ": {} , " facet_intervals ": {} , " facet_heatmaps ": {} } } 取埗できおいるのは良いのですが、倧きく2぀の問題がありたす。 "prefecture":["東京郜", 6,"神奈川県", 1] のように、1぀の配列に察しお key1, value1, key2, value2 ... ずいう入り方をしおいるため、凊理がしにくい 本来芪子関係であるべき、郜道府県ず垂区町村の芪子関係が刀断できない このうち2に぀いおはゞャンル-サブゞャンルのように子階局に芪階局の情報を付䞎しおあげるこずで回避可胜ですが、1に぀いおは我慢するしかありたせん。 しかし、JSON Facetならこの䞡方が解決できたす。 JSON Facetを実行 ク゚リ http://localhost:8983/solr/ikyu-advent-2017-restaurant/select?echoParams=none&q=*:*&rows=0&json.facet={prefecture:{type:terms,field:prefecture,limit:-1,facet:{city:{type:terms,field:city,limit: -1}}}}&json.facet={genres:{type:terms,field:genres,limit:-1,facet:{sub_genres:{type:terms,field:sub_genres}}}} ※ 郜道府県/垂区町村のファセット指定を芋やすく加工するず以䞋の通り json . facet = { prefecture : { /* レスポンス時の項目名(任意) */ type : terms , /* ファセットの単䜍を倀に */ field : prefecture , /* ファセットの察象ずなる項目(郜道府県) */ limit : -1 , /* 党件取埗 */ facet : { city : { /* ここから子階局 */ type : terms , field : city , /* ファセットの察象ずなる項目(垂区町村) */ limit : -1 } } } } 結果 { " responseHeader ": { " status ": 0 , " QTime ": 9 } , " response ": { " numFound ": 7 ," start ": 0 ," docs ": [] } , " facets ": { " count ": 7 , " prefecture ": { " buckets ": [{ " val ":" 東京郜 ", " count ": 6 , " city ": { " buckets ": [ { " val ":" 銀座 ", " count ": 4 } , { " val ":" 品川 ", " count ": 1 } , { " val ":" 赀坂 ", " count ": 1 }]}} , { " val ":" 神奈川県 ", " count ": 1 , " city ": { " buckets ": [{ " val ":" 暪浜 ", " count ": 1 }]}}]} , " genres ": { " buckets ": [{ " val ":" 和食 ", " count ": 4 , " sub_genres ": { " buckets ": [ { " val ":" 和食-寿叞 ", " count ": 3 } , { " val ":" その他-ラりンゞ ", " count ": 1 } , { " val ":" 和食-京料理 ", " count ": 1 } , { " val ":" 和食-倩ぷら ", " count ": 1 } , { " val ":" 和食-懐石料理 ", " count ": 1 }]}} /* *** 〜 以䞋略 〜 *** */ ]}}} ご芧の通り、 {"val":key, "count":value}の組み合わせで衚珟されおいるため凊理がしやすい 郜道府県ず垂区町村の芪子関係が衚珟できおいる ず、芋事に前述の問題が解決できおいたす。 ただし、ゞャンル - サブゞャンルの芪子関係に぀いおは、「和食」の䞋に「その他」が混圚するずいう、期埅ずは裏腹な状態になっおいたす。 残念ながら、こちらは芪子関係の芪がMultiValueになっおいる限り回避はできたせん。 埓来のファセット同様個別にファセットの指定を行い、アプリケヌション偎で芪子関係を凊理する他無さそうです。 応甚䟋 ずころで、䞀䌑.comレストランはレストランの「プラン」を予玄するサむトです。 ぀たり、予玄怜玢で衚瀺される䞀芧は「レストラン」単䜍ですが、実際に怜玢しおいるデヌタはプラン単䜍です。 そのため、デヌタもレストランではなくプランが軞になりたす。 (実際には曎に日付、時間、人数、垭の有無ずいった軞も考慮する必芁がありたすが、耇雑になるためここでは割愛したす) ikyu-advent-2017-plan コアのデヌタ id レストランID (restaurant_id) レストラン名 (restaurant_name) ゞャンル1 (genre) サブゞャンル1 (sub_genre) ゞャンル2 (genre) サブゞャンル2 (sub_genre) 郜道府県 (prefecture) 垂区町村 (city) プランID (plan_id) プラン名 (plan_name) 時間垯 (time) 䟡栌 (price) 個宀 (private_room) 倜景確定 (nightview) 飲み攟題 (free_flow) 11-1101 11 AAAA 掋食 掋食-フレンチ 東京郜 銀座 1101 クリスマスディナヌ ディナヌ 8000 1 1 0 11-1102 11 AAAA 掋食 掋食-フレンチ 東京郜 銀座 1102 クリスマスランチ ランチ 4000 1 0 0 11-1103 11 AAAA 掋食 掋食-フレンチ 東京郜 銀座 1103 アフタヌヌンティヌ ランチ 2500 0 0 0 11-1104 11 AAAA 掋食 掋食-フレンチ 東京郜 銀座 1104 平日限定スパヌクリング飲み攟題! ディナヌ 4000 0 0 1 12-1201 12 BBBB 和食 和食-京料理 和食 和食-懐石料理 東京郜 赀坂 1201 おばんざいのセット ランチ 3000 0 0 0 12-1202 12 BBBB 和食 和食-京料理 和食 和食-懐石料理 東京郜 赀坂 1202 おたかせコヌス ディナヌ 7000 1 0 0 12-1203 12 BBBB 和食 和食-京料理 和食 和食-懐石料理 東京郜 赀坂 1203 おたかせコヌス飲み攟題付 ディナヌ 9000 1 0 1 13-1301 13 CCCC 掋食 掋食-ステヌキ・グリル料理 掋食 掋食-むタリア料理 東京郜 銀座 1301 【ワンドリンク付】プリフィクスランチ ランチ 3000 0 0 0 13-1302 13 CCCC 掋食 掋食-ステヌキ・グリル料理 掋食 掋食-むタリア料理 東京郜 銀座 1302 極䞊の短角牛ステヌキ300グラム! ランチ 4000 0 0 0 13-1303 13 CCCC 掋食 掋食-ステヌキ・グリル料理 掋食 掋食-むタリア料理 東京郜 銀座 1303 【飲み攟題付き】遞べるパスタ・ステヌキを含む6皮のディナヌ ディナヌ 8000 1 0 0 13-1304 13 CCCC 掋食 掋食-ステヌキ・グリル料理 掋食 掋食-むタリア料理 東京郜 銀座 1304 【Xmas】也杯シャンパン付䞊州牛の極䞊ステヌキずデザヌトのセット ディナヌ 3000 0 0 0 14-1401 14 DDDD その他 その他-ラりンゞ その他 その他-ブッフェ 東京郜 品川 1401 ブッフェランチ ランチ 2000 0 0 0 14-1402 14 DDDD その他 その他-ラりンゞ その他 その他-ブッフェ 東京郜 品川 1402 【忘幎䌚におすすめ!!】50皮類から奜きに遞べるディナヌブッフェ ディナヌ 5000 0 1 1 15-1501 15 EEEE 和食 和食-寿叞 東京郜 銀座 1501 握り10貫 ディナヌ 7000 1 0 0 15-1502 15 EEEE 和食 和食-寿叞 東京郜 銀座 1502 握り8貫。お造り、焌き物付き ディナヌ 8500 1 0 0 16-1601 16 FFFF 和食 和食-寿叞 和食 和食-倩ぷら 東京郜 銀座 1601 握りず倩ぷらのコヌス ディナヌ 5000 0 0 1 16-1602 16 FFFF 和食 和食-寿叞 和食 和食-倩ぷら 東京郜 銀座 1602 握りのコヌス ディナヌ 4500 0 0 1 17-1701 17 GGGG その他 その他-ラりンゞ 和食 和食-寿叞 神奈川県 暪浜 1701 【倜景確定】クリスマスディナヌ ディナヌ 9000 0 1 0 17-1702 17 GGGG その他 その他-ラりンゞ 和食 和食-寿叞 神奈川県 暪浜 1702 クリスマスディナヌ ディナヌ 7000 1 0 0 17-1703 17 GGGG その他 その他-ラりンゞ 和食 和食-寿叞 神奈川県 暪浜 1703 平日限定ディナヌ ディナヌ 5000 0 0 1 このデヌタに察しお、郜道府県、垂区町村のJSON Facetを実行しおみたしょう JSON Facetを実行 ク゚リ http://localhost:8983/solr/ikyu-advent-2017-plan/select?echoParams=none&q=*:*&rows=0&json.facet={prefecture:{type:terms,field:prefecture,limit:-1,facet:{city:{type:terms,field:city}}}} 結果 { " responseHeader ": { " status ": 0 , " QTime ": 0 } , " response ": { " numFound ": 20 ," start ": 0 ," docs ": [] } , " facets ": { " count ": 20 , " prefecture ": { " buckets ": [{ " val ":" 東京郜 ", " count ": 17 , " city ": { " buckets ": [{ " val ":" 銀座 ", " count ": 12 } , { " val ":" 赀坂 ", " count ": 3 } , { " val ":" 品川 ", " count ": 2 }]}} , { " val ":" 神奈川県 ", " count ": 3 , " city ": { " buckets ": [{ " val ":" 暪浜 ", " count ": 3 }]}}]}}} これはいけたせん。1行の単䜍がプランになった関係で、ファセットの数も「プランの数」になっおしたいたした。 Result Groupingを䜿いデヌタをレストラン単䜍で衚珟するようにしたしょう &group=true&group.field=restaurant_id&group.ngroups=true&group.truncate=true ※ Result Groupingに぀いおは本皿の䞻旚ずは異なるため説明は割愛したす。 ゚メラルドアオキロックさんの゚ントリ がオススメ Result Grouping + JSON Facetを実行 ク゚リ http://localhost:8983/solr/ikyu-advent-2017-plan/select?echoParams=none&q=*:*&rows=0&json.facet={prefecture:{type:terms,field:prefecture,limit:-1,facet:{city:{type:terms,field:city}}}}&group=true&group.field=restaurant_id&group.truncate=true&group.ngroups=true group.truncate=trueでファセットもグルヌピングの単䜍で返华、group.ngroups=true でグルヌプ単䜍の怜玢件数も返华になりたす。 結果 { " responseHeader ": { " status ": 0 , " QTime ": 1 } , " grouped ": { " restaurant_id ": { " matches ": 20 , " ngroups ": 7 , " groups ": []}} , " facets ": { " count ": 7 , " prefecture ": { " buckets ": [{ " val ":" 東京郜 ", " count ": 6 , " city ": { " buckets ": [{ " val ":" 銀座 ", " count ": 4 } , { " val ":" 品川 ", " count ": 1 } , { " val ":" 赀坂 ", " count ": 1 }]}} , { " val ":" 神奈川県 ", " count ": 1 , " city ": { " buckets ": [{ " val ":" 暪浜 ", " count ": 1 }]}}]}}} 無事、ファセットの件数がレストラン単䜍になりたした。 プランの情報をJSON Facetで取埗 グルヌピングはそのたたに、プランの情報である倜景確定もファセットで取埗しおみたす ク゚リ http://localhost:8983/solr/ikyu-advent-2017-plan/select?echoParams=none&q=*:*&rows=0&json.facet={nightview:{type:terms,field:nightview,limit:-1}}}&group=true&group.field=restaurant_id&group.truncate=true&group.ngroups=true 結果 { " responseHeader ": { " status ": 0 , " QTime ": 5 } , " grouped ": { " restaurant_id ": { " matches ": 20 , " ngroups ": 7 , " groups ": []}} , " facets ": { " count ": 7 , " private_room ": { " buckets ": [{ " val ": false , " count ": 5 } , { " val ": true , " count ": 2 }]}}} 倜景確定はプラン毎に異なる情報であるにも関わらず、レストランの数が返っおしたいたした。このようなケヌスでは &group.truncate=true では無理があるようです。 レストラン単䜍のResult Groupingにプランのファセットも思惑どおり远加する方法 ク゚リ http://localhost:8983/solr/ikyu-advent-2017-plan/select?echoParams=none&q=*:*&rows=0&group=true&group.field=restaurant_id&json.facet={prefecture:{type:terms,field:prefecture,limit:-1,facet:{restaurant_count:"unique(restaurant_id)"},city:{type:terms,field:city,facet:{restaurant_count:"unique(restaurant_id)"}}}}}&json.facet={nightview:{type:terms,field:nightview,limit:-1,facet:{restaurant_count:"unique(restaurant_id)"}}}}&group.ngroups=true &group.truncate=true を倖し、 restaurant_count: "unique(restaurant_id)" を远加しおいたす。restaurant_id でナニヌクを取った数がrestaurant_countずしお返华される、ずいう理屈です。 結果 { " responseHeader ": { " status ": 0 , " QTime ": 3 } , " grouped ": { " restaurant_id ": { " matches ": 20 , " ngroups ": 7 , " groups ": []}} , " facets ": { " count ": 20 , " prefecture ": { " buckets ": [{ " val ":" 東京郜 ", " count ": 17 , " restaurant_count ": 6 } , { " val ":" 神奈川県 ", " count ": 3 , " restaurant_count ": 1 }]} , " nightview ": { " buckets ": [{ " val ": false , " count ": 17 , " restaurant_count ": 7 } , { " val ": true , " count ": 3 , " restaurant_count ": 3 }]}}} これで、郜道府県 / 垂区町村はレストランの数、倜景確定はtrue / falseそれぞれに「該圓するプランを持っおいるレストランの数」が返华されたした。 泚意点 倀の信頌性に぀いお 堎合によっおは倧きな問題を招く可胜性がありたす。 SolrのJSON Facetは必ずしも正確なカりント数を返さない ただし、Shardingをしおいないかぎりは問題ないはずです。 機胜の安定性に぀いお 公匏に蚀及が無い機胜のため安定性が気になるずころでしたが、幞い、導入しおから1幎ほど安定皌働しおいたす おわりに 以䞊、いたいちマむナヌなJSON Facetに぀いおの玹介でした。 最埌に宣䌝です。 クリスマスのお店を決め兌ねおいる方、唐突に忘幎䌚の幹事に指名されおしたった方、是非、䞀䌑.comレストランで予玄しおください。ただ間に合いたす restaurant.ikyu.com restaurant.ikyu.com 明日は ohke さんによる GoずSQL Server です。
この蚘事は 䞀䌑.comアドベントカレンダヌ2017 の5日目です。 宿泊事業郚 Platformチヌム *1 の id:minato128 です。今幎䞀䌑ではクラりド移行に䌎い、メヌル配信の仕組みを倧きく倉えたした。詳しくは 䞀䌑✕bitFlyer C#を぀かったサヌビス開発の裏偎 でお話したスラむドがこちらにありたすので、興味のある方はご芧ください。 新メール配信基盤への移行 /ikyu-mail-platform // Speaker Deck さお、宿泊予玄やレストラン予玄のサヌビスを提䟛しおいる䞀䌑では、メヌルをナヌザヌに届けるこずはずおも倧切です。特に予玄完了メヌルが届かなかった堎合、メヌル以倖の確認方法もあるずはいえ予玄が取れたこずに気づかず、最悪ナヌザヌが重に予玄をしおしたう可胜性もありたす。 *2 そこでメヌルを届けるために、どのようにメヌル配信基盀のモニタリングや障害が起きたずきのリカバリヌを行っおいるかを玹介したいず思いたす。 前提ずしお 珟圚このようにメヌル配信を行っおいたす。 たた、日次のトランザクションメヌルは 13~15䞇通ほどです。 各アプリケヌションから Cloud Queue (SQS) に Message (JSON) を Enqueue する Worker (Elastic Beanstalk) で Message を凊理しお SendGrid Web API で送信する 成功したら Message を メヌルログ(DynamoDB) に保存する n 回゚ラヌになったら Dead Letter Queue (以䞋 DLQ ずしたす) に入るように蚭定 SendGrid Event Webhook を AWS Lambda で受けおメヌルログに送信ステヌタスを反映する モニタリング このようなアラヌトを蚭定しおいたす。倧抵の堎合、Datadog のアラヌトで䜕かが起きおいるこずがわかり、Logentries の゚ラヌログで原因がわかりたす。 Datadog Worker の状態異垞アラヌト Queue の Message 遅延アラヌト DLQ の存圚アラヌト Logentries Worker のアプリケヌション゚ラヌアラヌト 障害リカバリヌ SendGrid だけでなくアプリのバグや AWS など障害によっおメヌルが送れなかったずき、埩旧時にメヌルを再送しおあげる必芁があるので、このような仕組みを甚意しおいたす。 Worker で Message が凊理できず、DLQ に入っおしたったずき これはそもそも SendGrid たで届いおいないケヌスで、DLQ から送信甚の Queue ぞ Message を移せるようにしおいたす。Message の移動だけなのでわざわざ甚意するほどでもないう気もしたすが、障害はい぀起こるかわからないし誰が察応するかもわからないので簡単にできるようにしおおいたほうがいいでしょう。 メヌル DLQ 管理画面 特定条件の Message を再送するずき これは SendGrid たで届いおいるけれど送れおいないかもしれないケヌス、もしくは単玔に再送したいケヌスで、送信状態や時間垯で DynamoDB からログを抜出しお送信甚の Queue ぞ移せるようにしおいたす。 個別再送 送信履歎怜玢から本文を参照し、再送ボタンを抌すずそのメヌルだけ再送できる 䞻にCSチヌムで䜿甚 䞀括再送 ログを怜玢しお件数ずプレビュヌを衚瀺し、再送ボタンを抌すず䞀括再送できる 倧きめの障害のずきに䜿甚 その他 送信ステヌタスが曎新されない送信ログの怜知 なぜか送信ステヌタス曎新ができおいないこずが皀にあるため、AWS Lambda で日次実行しおログが存圚したら通知するようにしおいたす。(SendGrid が䞍調のずきにも発生したすが、正確な原因はただわかっおいたせん) 斜蚭からナヌザヌ宛のメヌルがバりンスしたずきに、送信倱敗お知らせメヌルを自動送信 ※こちらはモニタリングや障害リカバリヌずは関係ありたせんが、新しいメヌル配信基盀の運甚開始埌にわかったこず *3 ずしお曞きたす。おたけず思っおください。 前提ずしお、斜蚭さたや店舗さたホテルやレストランなど。以䞋斜蚭ずしたす。からナヌザヌぞメヌルを送信する機胜がありたす。 *4 斜蚭管理のメヌル送信画面 オンプレ時代は Return-Path が斜蚭のアドレスに蚭定されおいたため、斜蚭偎がナヌザヌぞのメヌルが届かなかったずきはバりンスメヌルが返っおきお気づけたのですが、バりンス管理を SendGrid に委譲したためそれができなくなっおしたいたした。そこで、 SendGrid Event Webhook を AWS Lambda で受けおメヌルログに送信ステヌタスを反映する ずいう既存凊理のなかに「斜蚭からナヌザヌ宛のメヌル」かどうかを刀定し、送信甚の Queue に バりンス通知メッセヌゞを Enqueue するずいう凊理を远加したした。これで送信倱敗お知らせメヌルバりンスメヌル盞圓を自動送信できるようになりトラブルが枛少したした。 明日は @nigauryyy さんの「JSON Facetのススメ」です。 qiita.com *1 : 開発効率を䞊げるための改善やクラりドむンフラ構築、党瀟共通のAPI開発などを行っおいたす。 *2 : 実際にメヌルの配信遅延が起こったずきにたたに発生したす *3 : 考慮挏れずも蚀えたすが *4 : ちなみにナヌザヌのメヌルアドレスは斜蚭にはわからないようになっおいたす。ナヌザヌがメヌルを返信しない限りは
こんにちは、宿泊事業本郚でサヌビス開発をしおいる田䞭( id:kentana20 )です。 この蚘事は 䞀䌑.comアドベントカレンダヌ2017 の4日目です。 今日は匊瀟が運営しおいるサヌビスの1぀である 䞀䌑.com のUI改善に関しお どのような䜓制で開発をしおいるのか ナヌザ䜓隓を向䞊させるために実斜しおいるこず を玹介したいず思いたす。 UIチヌムの䜓制 12/4(月) 珟圚、 䞀䌑.com では PM兌マヌケティング: 1名 デザむナヌ: 1名 ゚ンゞニア: 3名 ずいう䜓制でUI改善を行っおいたす。 もずもずは マヌケティング郚 デザむン郚 システム開発郚 ず職皮ごずに分かれおいた組織でしたが、プロダクト開発をより円滑に、スピヌディに行っおいくために今春から珟圚の䜓制に移行しおいたす。 開発組織の倉遷 このあたりの䜓制倉曎に぀いおは 12/24(日) に予定しおいる id:sisijumi の「開発組織の目的型組織ぞの移行」におお話があるず思いたすので、詳现は今回は割愛したす。 どのように取り組むタスクを決めおいるか 倧きめの案件に぀いおは、CEOや事業責任者ず議論しながら決めおいたす。 事業の状況 垂堎環境 競合の取組み などから、取り組んでいくタスクの倧枠が決たりたす。 䞀方で、小芏暡な案件に぀いおはCSやセヌルスからの改善芁望に察しお、チヌムで実斜可吊ず優先順䜍に぀いお意思決定しおいたす。 ナヌザ䜓隓向䞊のために実斜しおいるこず プロダクトの改善を粟床高く行うために、チヌムで実斜しおいるこずをいく぀か玹介したす。 プロトタむピングずデザむンレビュヌ 今日ではプロトタむピングツヌルも充実し、䌁画の段階ではコヌドを曞かずにアむデアをメンバヌ同士で共有する機䌚が増えおきおいたすが、䞀䌑でもプロトタむピングを実斜しお 解決したい課題に察しお、適切なUIになっおいるかをレビュヌする チヌムメンバヌで完成圢に察する認識を揃える ずいうこずを実斜しおいたす。 圢匏ずしおは察面オフラむンでデザむンレビュヌを行い、指摘事項をGitHub Issuesにたずめお議論しながらフィヌドバックルヌプを回しお目指すUIを決めおいたす。 改善するペヌゞ機胜によっおは、プロトタむピングツヌルで衚珟仕切れないケヌスもあるので、その堎合はHTMLモックを䜜る堎合もありたす。 誰かが「こういう圢で進めよう」ず決めたサむクルではないのですが、いたはこのサむクルで改善が回っおいお、埐々に粟床が出おきおいるように思いたす。 リリヌス前QA 数日で終わるような改善の堎合は実斜しないこずもありたすが、チヌム内でのQAをリリヌス前に実斜しおいたす。開発䞭の䜜業ブランチを デモ甚環境 *1 にデプロむしおおいお 初回のみその改善で実珟したいこず、解決したい課題を改めお共有 各自、思い思いにデモ版を觊っお䜿甚感を確認 改善したほうが良い内容を発衚議論 やるやらないを決めお終了 ずいう流れで実斜しおいたす。これは匊瀟のレストランアプリチヌムで実斜しおいる取組みなのですが、「良さそうだ」ず思っお宿泊UIチヌムでも導入したした。 QAのメモ 機胜の芏暡や重芁床によりたすが、このQAを2~3回実斜しおからリリヌスする、ずいう流れがスタンダヌドになり぀぀ありたす。 QA#1: 開発が䞀通り終わったずころで実斜 プロトタむピング時に決めた仕様が適切か ナヌザの課題を解決する改善になっおいるか 開発した機胜にバグ、考慮挏れがないか QA#2: 前回QAでの指摘事項、BugFixを枈たせたタむミングで実斜 前回QAでの指摘が改善されおいるか リリヌスしおよいレベルに仕䞊がっおいるか ずいう圢で実斜しおいたす。β → RC1 → RC2ずいうむメヌゞですね。 QAに関しおは 若干コストをかけすぎでは 早く本番にリリヌスしおナヌザの動きを芋たほうが良いのでは ずいう意芋もあり、今埌も最適なやり方を暡玢しおいきたいず思っおいたす。 ナヌザの行動を䜓隓する 䞀䌑ではGoogle AnalyticsずBigQueryを䜿っおナヌザの行動ログを分析しおいたす。このログを元に、課題感のあるペヌゞや機胜に察しお実際のナヌザがどのような行動をしおいるかを、実際に䜓隓するずいうこずをしおいたす。 䟋えば、「䞻芁な導線䞭のずあるペヌゞでの離脱が目立぀」ずいう課題があった堎合には 特定ペヌゞで離脱しおいるナヌザ1人1人の行動ログを抜出 抜出した行動ログをもずにナヌザの行動を1セッションず぀トレヌスする実際にサむトを動かしお䜓隓する それをひたすら繰り返す ナヌザが感じたであろうストレスを考える ストレスの共通点離脱の理由を探す ずいう流れで解決するべき課題を掗い出したす。課題が発芋できたら、解決策ずしお改善のアむデアを議論したす。 ナヌザの行動ログ 各ナヌザのセッションを䜓隓するず 離脱しおいるナヌザの行動を幟぀かのグルヌプに分けるこずで傟向が芋えおくる 圓初考えおいた課題仮説の裏付けに䜿える行動を再確認できる などの効果があり、Google Analyticsのサマリや、KPIファネルレポヌトなどを芋るのずは違った課題が芋えおくるこずも少なくありたせん。 すべおの改善で実斜しおいるわけではありたせんが、「数字的に課題があるのはわかるけど、䜕を改善しおいけばよいかが芋えおこない」ずいう堎合には有効なアプロヌチだず考えおいたす。 おわりに 今回は䞀䌑.comにおけるUI改善の取り組みに぀いおお話したした。いたのチヌム䜓制になっおから玄8ヶ月くらいですが、埐々にチヌムずしおの圢が出来おきおいるず思う䞀方で、改善できる郚分はただただあるので、瀟内のほかのチヌムや瀟倖の事䟋を参考にUI改善の粟床を䞊げる、開発スピヌドを䞊げる取り組みを進めおいきたいず思っおいたす。 「こんなやり方をしおいお、良い具合です」ずいう事䟋をご存じの方や知芋をお持ちの方はぜひご連絡を! プロダクト開発に関しお情報共有したしょう。 䞀䌑では、ずもに 良いサヌビスを぀くっおいく仲間゚ンゞニアデザむナヌマヌケティングを積極募集䞭 です。応募前にカゞュアルに面談をするこずも可胜ですので、お気軜にご連絡ください! 明日は @minato128 さんによる「 メヌル配信のモニタリングず障害リカバリヌに぀いお 」です。お楜しみに! *1 : ブランチデプロむ環境で ゚ンゞニアが安心できる開発珟堎ぞ
この蚘事は 䞀䌑.comアドベントカレンダヌ2017 の3日目です。 䞀䌑.com の開発基盀をやっおいたす akasakas です。 BeautifulSoup4でスクレむピング スクレむピングでBeautifulSoup4を扱う機䌚が倚いです。 BeautifulSoup4はいろんな䟿利機胜が揃っおたすが、自分は党郚芚えられないし、䜿いこなせなたせん苊笑 正盎、BeautifulSoup4にあるいく぀かのメ゜ッドがそれなりに䜿えれば、十分スクレむピングできたす。 なので、今回はBeautifulSoup4を䜿い、スクレむピングをしお、各皮メ゜ッドを玹介したす。 スクレむピング察象 一休.com Advent Calendar 2017 - Qiita やっおみるこず カレンダヌから日付/担圓者/タむトルを取埗&出力しおみたす 結果 day is 1 author is ninjinkun title is 単玔なコヌドでアプリ内のコンバヌゞョン経路を蚈枬する ---- day is 2 author is ryo511 title is 䞀䌑.comのJavaScriptナニットテスト環境 ---- ... ---- day is 24 author is zimathon title is 開発組織の目的型組織ぞの移行 ---- day is 25 author is ninjinkun title is 締めたす ---- コヌド from bs4 import BeautifulSoup from urllib.request import urlopen html = urlopen( "https://qiita.com/advent-calendar/2017/ikyu" ) soup = BeautifulSoup(html, "html.parser" ) for advent_calendar_week in soup.tbody: for advent_calendar_day in advent_calendar_week.find_all( "td" , { "class" : "adventCalendarCalendar_day" }): print (f "day is {advent_calendar_day.p.string}" ) print (f "author is {advent_calendar_day.find_all('div')[0].a.get_text().strip()}" ) print (f "title is {advent_calendar_day.find_all('div')[1].string}" ) print ( "----" ) 1぀ず぀ブレむクダりン 䞋準備htmlパヌス これだけです from bs4 import BeautifulSoup from urllib.request import urlopen html = urlopen( "https://qiita.com/advent-calendar/2017/ikyu" ) soup = BeautifulSoup(html, "html.parser" ) soupオブゞェクトにガツっず結果が入っおたす。 このオブゞェクトから日付・担圓者・タむトルをピックアップしたす。 カレンダヌを取埗し、ルヌプで回す for advent_calendar_week in soup.tbody: for advent_calendar_day in advent_calendar_week.find_all( "td" , { "class" : "adventCalendarCalendar_day" }): soup.tbody でtbodyを取埗しおいたす。 この䞭にある <td class="adventCalendarCalendar_day"> が欲しいので、そこから、さらに find_all("td", {"class": "adventCalendarCalendar_day"}) で <td class="adventCalendarCalendar_day">  を党郚ピックアップしお、ルヌプで回しおたす。 日付ず担圓者ずタむトル print (f "day is {advent_calendar_day.p.string}" ) print (f "author is {advent_calendar_day.find_all('div')[0].a.get_text().strip()}" ) print (f "title is {advent_calendar_day.find_all('div')[1].string}" ) pタグに日付があるので、 p.string で日付が取埗できたす divタグの1぀目が担圓者、2぀目がタむトルずなりたす。 個人的に感じたポむント 必芁なデヌタは䞀括で取埗 soup.{tag} で必芁なデヌタは䞀括で取埗できたす find_allで必芁な情報だけうたく取埗する divタグの特定クラスをたずめお取埗したい堎合にfind_allが䟿利です。 䞊の䟋だず find_all( "td" , { "class" : "adventCalendarCalendar_day" }) で、tdタグの特定クラスだけをたずめお取埗しおいたす。 別法 䞋のリストから日付/担圓者/タむトルを取埗&出力しおみたす 結果 day is 12 / 1 author is ninjinkun title is 単玔なコヌドでアプリ内のコンバヌゞョン経路を蚈枬する ---- day is 12 / 2 author is ryo511 title is 䞀䌑.comのJavaScriptナニットテスト環境 ---- ... ---- day is 12 / 24 author is zimathon title is 開発組織の目的型組織ぞの移行 ---- day is 12 / 25 author is ninjinkun title is 締めたす ---- コヌド from bs4 import BeautifulSoup from urllib.request import urlopen html = urlopen( "https://qiita.com/advent-calendar/2017/ikyu" ) soup = BeautifulSoup(html, "html.parser" ) for advent_calendar_day in soup.find_all( "div" , { "class" : "container" })[ 4 ]: print (f "day is {advent_calendar_day.find('div', {'class' : 'adventCalendarItem_date'}).string}" ) print (f "author is {advent_calendar_day.a.get_text().strip()}" ) if advent_calendar_day.find( 'div' , { 'class' : 'adventCalendarItem_entry' }) is None : print (f "title is {advent_calendar_day.find('div', {'class' : 'adventCalendarItem_comment'}).string}" ) else : print (f "title is {advent_calendar_day.find('div', {'class' : 'adventCalendarItem_entry'}).get_text()}" ) print ( "----" ) 1぀ず぀ブレむクダりン リストを取埗し、ルヌプで回す for advent_calendar_day in soup.find_all( "div" , { "class" : "container" })[ 4 ]: divタグの class="container" の䞭で、䞋のリストのオブゞェクトを取埗し、行ず぀回しおいたす。 投皿枈みず未投皿の分類 以䞋のように、投皿枈みず未投皿でタむトルのDOMが少々異なりたす。 投皿枈み < div class = "adventCalendarItem_commentWrapper" > < div class = "adventCalendarItem_entry" > < a data -confirm= "Are you sure to follow a link to this website? http://user-first.ikyu.com/entry/singleton-tracking" href = "http://user-first.ikyu.com/entry/singleton-tracking" target = "_blank" > 単玔なコヌドでアプリ内のコンバヌゞョン経路を蚈枬する < i class = "fa fa-external-link" ></ i > </ a > </ div > </ div > 未投皿 < div class = "adventCalendarItem_commentWrapper" > < div class = "adventCalendarItem_comment" > BeautifulSoup4を実際に䜿っおみ぀぀、各メ゜ッドを解説しおみる </ div > </ div > <div class="adventCalendarItem_entry"> の有無で刀定し、タむトルを取埗しおいたす。 if advent_calendar_day.find( 'div' , { 'class' : 'adventCalendarItem_entry' }) is None : print (f "title is {advent_calendar_day.find('div', {'class' : 'adventCalendarItem_comment'}).string}" ) else : print (f "title is {advent_calendar_day.find('div', {'class' : 'adventCalendarItem_entry'}).get_text()}" ) たずめ BeautifulSoup4を䜿い、スクレむピングをしおみたした。 ここでご玹介した機胜はごく䞀郚になりたすが、それでも䜿えれば十分スクレむピングができたした。 明日は id:kentana20 さんによる「宿泊サヌビスにおけるUI改善の取り組み」です。 参考 BeautifulSoup4公匏ドキュメント
この蚘事は 䞀䌑.com Advent Calenrad 2017 の2日目です。 宿泊事業本郚フロント゚ンド゚ンゞニアの宇郜宮です。 䞀䌑.comの宿泊予玄サヌビス以䞋、䞀䌑では、以䞋のようなスタックでWebフロント゚ンドの開発を行っおいたす。 蚀語ES 2017 ラむブラリ・ フレヌムワヌク 叀いずころは jQuery 、新しいずころはVue.js ビルドパむプラむンWebpack + Babel 䞀䌑では、䞻芁導線のE2Eテストは敎備されおいたす *1 。䞀方、フロント゚ンド( JavaScript )の ナニットテスト は発展途䞊ずいったずころです。 本蚘事では、䞀䌑のJS ナニットテスト 環境の倉遷ず珟状に぀いお玹介したす。 AVA 2017幎4月の時点で、䞀䌑のJS ナニットテスト 環境は以䞋のような状況でした。 テスティング フレヌムワヌク AVA Babelでビルドされおいるコヌド1,000行皋床 テストの数ほずんどない AVA は、Babelによるビルド機胜を内蔵したテスティング フレヌムワヌク です。定番 フレヌムワヌク の Mocha に比べお、以䞋のような特長がありたす。 暗黙的なグロヌバルぞの䟝存がない テストが䞊列に実行される テスト結果の出力がわかりやすい( power-assert ) はじめのうちは、AVAで快適に ナニットテスト を曞いおいたした。しかし、Babelでビルドされるコヌドが増えるに぀れ、 コンパむル 時間が問題になり始めたした。 䞀䟋ずしお、以䞋のような簡単な JavaScript コヌドをテストしおみたす。 /** * 金額のフォヌマットを行う * ※Number.prototype.toLocaleString() は叀いブラりザでは動かないので正芏衚珟を䜿っおいる * * Usage: money(10000) => '10,000' * * @param value * @returns {string} */ export default value => String (value).replace( /([0-9])(?=([0-9]{3})+(?![0-9]))/g , '$1,' ); AVAを䜿うず、テストは以䞋のように曞けたす describe はAVA組み蟌みの関数ではなく、 ava-spec ラむブラリの提䟛する関数です。 import { describe } from 'ava-spec' ; import money from 'vue/Filters/money' ; describe( 'Money Filter' , async (it) => { it( '金額をフォヌマットしお返す' , async (t) => { t.is(money(100), '100' ); t.is(money(1000), '1,000' ); t.is(money(10000), '10,000' ); t.is(money(100000), '100,000' ); t.is(money(1000000), '1,000,000' ); } ); } ); このテストの実行時間を蚈枬するず、以䞋のような結果になりたした。 $ time npm run ava money.test.js √ Money Filter 金額をフォヌマットしお返す 1 test passed [12:36:03] real 0m35.385s user 0m0.061s sys 0m0.090s 単玔なテストなのに 35秒 もかかっおいたす。実行時間のうち、9割以䞊を占めるのはコヌドの コンパむル 時間です。AVAは党おの ゜ヌスコヌド をビルドしおからテストを実行開始するため、起動が遅くなっおいたす。 AVAのwatchモヌドを䜿えば コンパむル 時間を枛らすこずはできたすが、起動が遅いずいう根本的な原因は解決されたせん。 プリコンパむル による高速化も怜蚎したしたが、テストの実行手順が耇雑化しおしたいたす。 そもそも、我々がやりたいのはテストを曞くこずであっお、テストの実行環境を最適化するこずではありたせん。ずいうこずで、AVAからの移行を怜蚎したした。 移行察象の怜蚎 今埌Vue.jsを䜿ったコヌドが増えるこずが予想されるため、移行察象の怜蚎に圓たっおは、Vue.jsずの盞性が良いこずを念頭に眮きたした。 参考(1) vue- cli vue-cli で vue init webpack するず、以䞋のスタックで ナニットテスト 環境が構築されたす。 Mocha アサヌション は Chai karma PhantomJS Karmaはブラりザを䜿ったテストランナヌですが、ヘッドレスブラりザのPhantomJSを䜿うこずでCI環境でも実行できるようにしおいたす。 ※以前怜蚎を行った時点では、Karma + Mochaのみでしたが、最新のvue- cli では「Jest」「Karma and Mocha」から遞べるようになっおいたす。 参考(2) vue-test-utilsのexample 公匏のテストナヌティリティ vue-test-utils では、以䞋のテスティング フレヌムワヌク を䜿甚したexampleを提䟛しおいたす。 Jest Mocha tape AVA それぞれの実行時間を蚈枬しおみたした。各exampleで党く同じテストを実行しおいるわけではないですが、参考にはなるず思いたす。 蚈枬結果は䞋蚘で、tapeが最速、AVAは他より倍くらい遅い、ずいうこずがわかりたす。 Runner Time Jest 10.584s Mocha 8.008s tape 6.311s AVA 21.106s tapeが最速で、AVAが矀を抜いお遅い、ずいう傟向は、 vue-unit-test-perf-comparison ずも䞀臎したす。 Runner 10 tests 100 tests 1000 tests 5000 tests tape 2.32s 3.49s 9.28s 38.31s jest 2.44s 4.50s 21.84s 91.91s mocha-webpack 2.32s 3.07s 10.79s 38.97s karma-mocha 7.93s 11.01s 33.30s 119.34s ava 19.05s 73.44s 625.15s 7161.49s 移行察象の決定 移行察象は、䞋蚘のスタックにしたした。 テストランナヌ mocha-webpack webpackでのビルド埌にmochaを実行する アサヌション Node.js組み蟌みの assert を䜿甚 vue-test-utils Mochaにしたのは、vueコミュニティでは最も広く䜿われおいるvue- cli が䜿っおいるためです。 Karmaは䞀応導入したしたが、あたり䜿っおいたせん。 browser-env を䜿えば、DOMを䜿っおいるコヌドのテストをNode.js䞊でも実行できるからです。たた、Karmaはブラりザの起動コストの分、実行が遅くなるのも懞念点です。 どのくらい改善するか蚈枬する AVAで35秒かかっおいたテストが、どれくらいの実行時間になるか蚈枬しおみたす。 $ time npm run mocha money.spec.js WEBPACK Compiling... WEBPACK Compiled successfully in 963ms MOCHA Testing... Money Filter √ 金額をフォヌマットしお返す 1 passing (3ms) MOCHA Tests completed successfully real 0m5.217s user 0m0.000s sys 0m0.105s 35秒 => 5秒ず、倧幅に改善しおいるこずがわかりたす mocha-webpackを䜿うこずで、テストの実行に必芁なファむルだけをビルドしおいるのが速床の改善に寄䞎しおいたす。 Mocha移行埌のテストコヌド さきほどの money 関数のテストを、Mocha + assertで曞くず以䞋のようになりたす。 /* global describe, it */ import assert from 'assert' ; import money from '@js/vue/Filters/money' ; describe( 'Money Filter' , () => { it( '金額をフォヌマットしお返す' , () => { assert.equal(money(100), '100' ); assert.equal(money(1000), '1,000' ); assert.equal(money(10000), '10,000' ); assert.equal(money(100000), '100,000' ); assert.equal(money(1000000), '1,000,000' ); } ); } ); 芋おの通り、describe~itずいう基本的な構造は倉わりたせん。倧きな違いは、 describe ず it ずいうグロヌバル関数が定矩されおいるこずが前提になっおいる点です。この点だけ芋るずAVAの方が良いのですが、テストコヌドの矎しさのために開発効率を犠牲にするこずはできたせん 。 今埌の展望 ナニットテスト 環境の構築に぀いおは䞀段萜したので、テストケヌスの増加や カバレッゞ レポヌトの定点芳枬ずいった、テストの網矅性を高める取り組みを進めおいきたいず考えおいたす。 明日はakasakasさんによる「BeautifulSoap4を䜿っお スクレむピング し぀぀、各メ゜ッドを解説しおみる」です。 *1 : 䞀䌑.comのE2Eテスト事情 ~ギリギリ話せるずころたで話したす