カテゴリーアーカイブ 未分類

takahashi 著者:takahashi

楽天カードに大規模障害が発生した件で思うこと

先日、 楽天カードでなかなかヤバい障害が発生していましたね…

【一部復旧】当社サービスの一時利用停止のお詫びとお知らせ
(株式会社QTnetの電源設備更新作業に伴う不具合)- Rakuten Card

上記記事によると、2019年11月23日(土)6時ごろから、楽天カードや楽天ペイ、およびこれらサービスの利用明細確認などの機能が障害により停止し、なんとカード決済までも止まってしまう障害が発生していました。

カード決済機能と楽天Payは当日中に復旧しましたが、明細確認機能などはこの記事作成時点においてもまだ復旧していません。

原因は楽天カードの決済サーバーが置かれているQTnet社のデータセンターで、電源設備入れ替え時に電源障害が発生し電源が一瞬落ちたそうで、それが原因で同データセンターで稼働していたサービスが影響を受けてしまったようです。

この関係で、楽天以外にも、同データセンターにサーバーを置いていた官公庁や電力会社のHPにも障害が発生していたようです。

楽天カードなど260社・自治体に影響 九電系で障害 – 日本経済新聞

入れ替え中とはいえ、データセンターで電源を一瞬でも落としてしまうというのはあってはならない障害ですが、AWSですら電源ではないですが設備設定の入れ替えで障害を起こしたこともあるぐらいで、残念ながらデータセンターであっても障害が起きるときは起きてしまうものです。

個人的に、今回一番に問題に感じたのは楽天側のシステム構成の問題。

費用の問題もありますし、ダウンタイムが許容されるようなサービスであれば単一データセンターで動かしていたとしても理解はできます。

しかし、楽天カードはクレジットカードという超重要な社会インフラですし、たとえそれなりのコストがかかったとしても、決済機能だけでも絶対に止めてはいけないシステムであったはずです。

最近ではクレジットカードをメインに使用し、現金を持ち歩かない人も増えているようですが、もし食事やサービスを利用した際に現金をもっていない状況で(利用者側の落ち度なく)カードの利用ができなくなってしまっていたら、利用者がどのような状況に陥るのかは想像に難くありません。

生活費をカードで決済している場合もあります。

また楽天カードはETCも発行しています。

実際に起きていたかどうかはわかりませんが、決済ができないということはETCなどでの利用でも問題が発生した可能性もあると思います。

もし出場時に問題が発生して出られなければ、利用者はパニックに陥りかねないとおもいます。

停止すれば日常生活に実害をもたらしてしまう可能性のあるサービスが、単一のデータセンターが障害されただけで止まってしまうという状況は、楽天カード側の障害対策が甘すぎると感じました。

今回は電源断でしたが、万が一そのデータセンターが災害などに巻き込まれて完全に破壊されてしまったら、どう復旧するつもりなのでしょうか。

もう少し、耐障害性のことを考えたシステム設計にすべきなのではないかと個人的には感じました。

今後の対策に注目したいと思います。

  • この記事いいね! (0)
asaba 著者:asaba

【create-react】npmのバージョンが古い状態でwebpackをインストールするとエラーが起きて読み込み終了する

webpackを更新したくてnpm install –save-dev webpackで最新のwebpackをインストールすることに。

npm run webpackしたところで

 

Cannot read property ‘thisCompilation’ of undefined npm ERR! というエラー出現

 

原因はnpmのバージョンとインストールしたwebpackのバージョンのズレでした。

npmが古すぎるとwebpack読み込み時にエラーが起きて読み込み中断してしまう

みたいです。

 

 

解決方法は、一旦ダウンロードした新しいwebpackをnpm remove webpackで

 

アンインストール→その後バージョン@3.11.0をインストール。赤文字でERRと出なければ解決です!

同じことではまっている方は今使っているnpmのバージョンを確認してみてください。

  • この記事いいね! (0)
asaba 著者:asaba

【android】古いandroidStudioを消したらマニフェストが狂った

新しいandroidStudioに触れて早三か月となったある時、Cドライブが圧迫

し始めていることに気づいた。

 

要らないファイルを少しずつ消していたところ、もう使っていない

androidStudioのファイルを発見。

2.0と3.0だったのでもう使わないからいいやと思い軽い気持ちで削除。

ここまでは良かった。ところが翌日になって現行のandroidStudioを

立ち上げるとこんなエラーが起きていた。

 


<span style="color: #800000;"><strong>The minSdk version should not be declared in the android manifest file. You can move the version from the manifest to the defaultConfig in the build.gradle file</strong></span>

 

マニフェストにminSDKのバージョンを書くなとのこと。なん・・・だと・・・。

つい昨日までマニフェストに明記していたはずのminSDKが今のバージョンで

読み込めなくなっていた。

 

原因は消したandroidStudioファイルの中のキャッシュも一緒に

消したためだと思われる。

 

書いておいたminSDKのバージョンを消すと正常にビルドできた。

これ以降はandroidstudioを復元しなくても普通に動いてくれたので

このまま明記しなくても良さそう。

  • この記事いいね! (0)
asaba 著者:asaba

【next.js】next.jsの環境構築方法

今回はreactのレンダリングを高速化してくれるというフレームワーク、next.js

についてです。

 

reactでは、通常ではscriptはクライアント側で読み込むのですが、

これが大規模になってくるとクライアント側だけでは処理が重く

パフォーマンスに悪影響が出てしまいます。

 

そんな中開発されたnext.jsは、reactのscriptをサーバーサイドで読み込むことができるため

レンダリングでの早いレスポンスを期待することができます。

今回はそのnext.jsの開発環境の構築方法を記載します。

(結構簡単でした。)

 

構築方法

①まずcreate-react-app sampleでreactを作ります。

②cd sampleで移動

③npm i nextでインストールをします。npmのバージョンは

6.13.0でした。

④npm iで再度インストールをします。

まず、sampleフォルダの中のpackage.jsonを開いて

コマンドが打てるようにスクリプト群の一番下に”dev” : “next”を追加します。

 

</pre>
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"dev": "next"
},
<pre>

⑤最後にnpm run devをしてttp://localhost:3000/でローカル

サーバーにアクセスをします。

画面のような文字が表示されたら環境構築成功になります。

 

以上でnext.jsの環境構築は終了です。

ちょっとしか書いていないので使用感は分かりませんが、

使いにくいという印象はなかったです。

reactを使ったことのある方はそこまで苦労しなそう・・・。

 

ただ、一つ感じたのが、reactでのcssの書き方で保存をしていると

cannot resolveになってしまうので、もう完成してしまったアプリを

next.jsに合わせて書き直すのは骨が折れそうだなと思いました。

 

また、npm i とuninstallを繰り返していてもwebpackでライブラリが欠落したり

してしまうのでそちらの考慮しないと書き直しは怖くてできないです。

  • この記事いいね! (0)
asaba 著者:asaba

【npm】packeage.jsonの手動で弄った時に気を付けること

npmのパッケージやコマンドを新しく追加したい時にpackage.jsonを

よくいじると思います。ところが、jsファイルと違って誤字に寛容でないので

少しのタイポも見逃してくれない厳しい仕様となっています。

例えば、このエラー↓

 


npm ERR! code EJSONPARSE
npm ERR! file C:\Users\swift0910\Documents\tutorial\package.json
npm ERR! JSON.parse Failed to parse json
npm ERR! JSON.parse Unexpected token } in JSON at position 2367 while parsing near '....js --env=jsdom",
npm ERR! JSON.parse },
npm ERR! JSON.parse "jest": {
npm ERR! JSON.parse "...'
npm ERR! JSON.parse Failed to parse package.json data.
npm ERR! JSON.parse package.json must be actual JSON, not just JavaScript.

 

よく見ると、4行目でUnexpected tokenでカッコの前後に不適切な文字列が

混入しているよ~って言われています。

 

で、package.jsonを見ると、

 


"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js --env=jsdom",
},

 

4行目の最後で「,」を打っているのが分かります。これは、新しい

コマンドを試したときに”test”: “node scripts/test.js –env=jsdom”の後ろの

「,」を消し忘れていたのが原因ということになります。

これを消して保存することで無事ビルドさせることができました。

以上でpackage.jsonのエラーは解決となります。タイピングミス気を付けましょうネ!

 

 

  • この記事いいね! (0)
asaba 著者:asaba

【cordova】FCMPrugin is not foundの解決法

cordovaでプラグインを入れ直した直後に

ビルドしたところ、FCMPrugin is not foundのエラーに遭遇。

デバッグした結果、この中で一つ当てはまった場合に起きるエラー

のようです。

 

①FCMPruginが正常に読み込まれていない

②tokenが無効な値

③onDeviceReady内で処理をしていない

④FCMPruginが他のプラグインとせり合いを起こしている

 

自分の場合は④で、FCMPruginのバージョンが古かったため

他のfirebaseのプラグインと役割が被っていたのが原因でした。

④に関してはFCMPruginのバージョンを下げて追加

することで解決させることができます。

 

それでも解決しない場合は、platformsを削除、そのあとfirebaseに関わるプラグインを

全て消して再び追加、最後にplatformsを追加

をしてください。

以上がFCMPrugin is not foundの解決方法になります。

 

plugin関係は依存度の理解とかプラグインのエラーの原因と

なったファイルを探す探索力が必要になってくるのですが、

まだまだそこが理解できていない部分があるので

慣れておく必要があると感じました。

 

 

 

 

  • この記事いいね! (0)
著者:杉浦

【JavaScript】配列関数を使った読みやすいオブジェクト生成の書き方

 次の様な入出力を実現する関数dictMergeをなるべく読みやすく短い関数で実現するのが目標です。dictMergeは未定義や余分な定義を含む複数の辞書から必要なカテゴリーの語のみをまとめるための関数です。たとえなので辞書ですが今回紹介する配列、オブジェクト操作のようなやり方は色々な場面で使えます。

// 入力
const categoryKeys = ['hoge', 'fuga', 'hogefuga'];
const dictA = {
	hoge : ['hoge1', 'hoge3', 'hoge5'],
	fuga : ['fuga3', 'fuga7', 'fuga13'],
}
const dictB = {
	hoge : ['hoge7', 'hoge9', 'hoge11'],
	bar : ['bar2', 'bar4', 'bar6'],
}
const dictC = {
	hoge : [],
	fuga : ['fuga19', 'fuga29', 'fuga37'],
	hogefuga : ['hogefuga'],
}

// 出力
const mergedDict = dictMerge(categoryKeys, dictA, dictB, dictC);
console.log(mergedDict);
/*
{
	hoge : ['hoge1', 'hoge3', 'hoge5', 'hoge7', 'hoge9', 'hoge11'],
	fuga : ['fuga3', 'fuga7', 'fuga13', 'fuga19', 'fuga29', 'fuga37']
	hogefuga : ['hogefuga']
}
*/

 実装したdictMerge()が次になります。コードの細部はコメントの通りです。

/**
 * @param {Array} categoryKeys
 * @param {Array} dicts
 * @return {Object}
 */
function dictMerge(categoryKeys, ...dicts) { // 第二引数以下を変数dictに配列として格納する. 今回ならdicts = [dictA, dictB, dictC]
    return categoryKeys.reduce((mergedDict, category) => { // reduce関数で配列を一つのオブジェクトに変換する。詳しくは下記
        return {
            ...mergedDict, // スプレッド構文でreduceの前のループ結果を引き継がせる
            [category]: dicts.map(dict => dict[category]) // [category]で変数をキー名にする。map関数で扱う配列を[dictA[category], dictB[category], dictC[category]]にする
                .flat() // 配列の中身を一段flatにする。例えば[Array(3),Array(3),Array(0)]の二次元配列がArray(6)の一次元配列になる
                .filter(v => v !== undefined)// 未定義でない値のみを配列の中身に残す
        }
    }, {});
}

 上記の様にJavascriptに用意されている関数をチェーンするだけで少々複雑な問題も簡易な記述で解けます。この様なやり方を用いる際に注意する必要があるのはreduce関数です。reduce関数はJavaScriptの配列操作においてとても汎用的であり、書こうとさえ思えばほぼ全ての配列操作関数をreduce関数で表現できます。これを使うと次のように黒魔術的もかくやというコードを書けます。

// dictMergeと等価
function dictMergeByReduce(categoryKeys, ...dicts) {
    return categoryKeys.reduce((mergedDict, category) => {
        return {
            ...mergedDict,
            [category]: dicts.reduce((acc, value, index) => {
                acc[index] = value[category];
                return acc;
            }, [])
                .reduce((acc, value) => acc.concat(value), [])
                .reduce((acc, value) => {
                    if (value !== undefined) {
                        acc.push(value);
                    }
                    return acc;
                }, [])
        }
    }, {});
}

 なるべくreduceを使わず特化的な名前の少ない引数の配列関数を使うとわかりやすいコードになります。最初の例も正直reduceを使うまでもありません。reduce((o, k)=>{return {…o, [k]:kに関する何か}},object型引数)という構文は便利なのですが慣れない人に渡すとけっこう混乱します。注意するべきでしょう。

// 多くの人がわかりやすく読みやすいであろう版
function dictMergeSimple(categoryKeys, ...dicts) {
    const mergedDict = {};
    categoryKeys.forEach(category => {
        mergedDict[category] = dicts.map(dict => dict[category])
                .flat()
                .filter(v => v !== undefined)   
    });
    
    return mergedDict;
}
  • この記事いいね! (1)
asaba 著者:asaba

node_moduleがno such file or directoryの時の対処法

node_moduleがno such file or directoryの時に対応したこと

cordova prepare androidをした時に出てきたエラーです↓

 

ERROR in ./node_modules/react-router-dom/node_modules/warning/warning.js
Module build failed: Error: ENOENT: no such file or directory, open ‘C:\Users\swift0910\Documents\NEW_APP\node_modules\react-router-dom\node_modules\warning\warning.js’
@ ./node_modules/react-router-dom/HashRouter.js 7:15-33
@ ./www/js/app.js

ERROR in ./node_modules/react-router-dom/Route.js
Module not found: Error: Can’t resolve ‘react-router/Route’ in ‘C:\Users\swift0910\Documents\NEW_APP\node_modules\react-router-dom’
@ ./node_modules/react-router-dom/Route.js 5:13-42
@ ./www/js/app.js

 

ファイルが見つからない為正常にビルドができませんと言いたいようです。

react-router-domなんてnpm installしたら必ずついてくるのにも関わらずです。

node_moduleを作成した後のファイルが見つからないなんてどういうことなのか

まだ理解できていないのですが、このままでビルドするわけにもいかないので

少しずつ修正作業へ。

npm cache cleanでキャッシュを削除

npmのバージョンを6.9.0から3.10.10にダウングレード

node_moduleを手動で消した後にnpm installで解消

 

6.9.0だとnode_moduleが競り合いを起こす。そもそも

新しいnpmに対応していないファイルを呼ぼうとしている

->ファイルが見つからないということです。

参考 https://stackoverflow.com/questions/52215541/module-build-failed-error-cannot-find-module-node-sass

  • この記事いいね! (0)
asaba 著者:asaba

【gradle】gradleのtask wrapperの書き方が変わっていた

build.gradleに書いてあるtask wrapper(type: Wrapper)は

gradle5.0から書き方が変わったらしく、そのままビルドすると

 


ERROR: Cannot add task 'wrapper' as a task with that name already exists.

 

エラーになってしまいます。

 

ここでは一番最初に記載されてあるtaskとtype:Wrapperを消去して

 


これを

task wrapper(type: Wrapper) {
gradleVersion = '5.4'
}

 


修正

wrapper{
gradleVersion = '5.4'
}

 

wrapperのみ記述することでエラーを回避することができます。

現状ではこの回避方法が無難かなぁと思います。

 

愚痴ですが、gradleのバージョンを上げなければandroidStudioでビルドしてくれない。

上げたら上げたでまた別の依存関係が出てくる(主にgoogle-serviceとか)

 

google-serviceの依存関係って本当面倒だ・・・。

 

  • この記事いいね! (0)
takahashi 著者:takahashi

WindowsのHostsファイルに記述できるエイリアス名の上限

Windowsには自分のマシン内だけで使用できる存在しない仮のホスト名(ドメイン)をIPアドレスと紐づけたり、実在する ドメイン と対応するIPを別のものに書き換えたりすることができるhostsという仕組みがあります。

例えば、ドメインを取得する前に取得予定のドメイン名を使用してWebサイトが意図した動作をするか…などの確認に使えたりします。

Windowsのhostsファイルは次の場所に存在します。

C:\Windows\System32\drivers\etc\hosts

このhostsファイルですが、中身を見ると次のような書式になっています。

192.168.XXX.XXX example.com sub1.example.com sub2.example.com sub3.example.com

見方としては、一番左がIPアドレス、2番目が紐づけたいホスト名、そして3番目からはエイリアスとなるホスト名となっています。

ホスト名とエイリアスの違いはほぼありませんが、設定上の扱いは、2番目のホスト名が正式な名前で、3番目以降はこの正式なホスト名の”別名”という扱いになっています。

hostsファイルではサブドメインを登録する際に*(ワイルドカード)を使用することができず、使用する可能性のあるドメイン名をすべて列挙する必要があります。

別のレコード(行)に分けて書いてもいいのですが、同じIPに対して複数の異なる名前を付ける場合に全部別の行にしてしまうと見づらくなってしまうので、この場合はエイリアスを使用すると見やすくなります。

さて、このエイリアスですが、実は登録できるホスト名の数に上限があります。

HOSTS ファイルにおけるエイリアス名の最大数について – Microsoft

つまり一つのレコードにエイリアスを9個以上設定してしまうと。9個目以降はOSに認識してもらえず、設定されていないことになってしまいます。

そのため、9個目以降のホスト名でアクセスしようとしてもドメインが見つからない旨のエラーが出てしまいます。

この場合は9個目以降のドメインを別の行として書けば問題なく使用できるのですが、この使用を知らないとうまくいかなかったときちょっと焦ります。(僕は知らなくて一瞬焦りました…w)

hostsを使用して開発を行う場合は把握しておきましょう。

  • この記事いいね! (0)