OmniAICreator/Qiita-1.07M huggingface dataset:
Herokuのアプリを別アカウントに移行するには


https://qiita.com/akase244/items/438b3f434d1d0105a1b9

タイトルの作業自体は上記記事を参考にしてうまくいきましたが（感謝！）、コマンドが古くなっている箇所もあったので、今回の私の手順をまとめておきます。

## 移行元アカウントでログイン
```
$ heroku login
```

## 移行したいアプリのディレクトリに移動
```
$ heroku git:clone -a <移行したいアプリ>
$ cd <移行したいアプリ>
```

## コラボレーターを追加
```
$ heroku access:add <移行先アカウント>
```

## アプリのオーナーを移行
```
$ heroku apps:transfer <移行先アカウント> --app <移行したいアプリ>
```

## コラボレーターを削除
```
$ heroku access:remove <移行元アカウント>
```

## 元のディレクトリに戻る
```
$ cd ..
```


以上です！


#### 参考
https://devcenter.heroku.com/ja/articles/heroku-cli-commands
スプレッドシートの値を配列で取得

## 全部を取得
2次元配列になる

### .getDataRange().getValues()

```
const spreadsheet = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxx')
const sheet = spreadsheet.getSheetByName('シート1')

// 取得した配列を表示
console.log(sheet.getDataRange().getValues())

// A1セルを表示
console.log(sheet.getDataRange().getValues()[0][0])
```

## 範囲指定
2次元配列になる

### .getRange(1,1,6,3).getValues()
A1からC6まで取得する場合

```
// getRange(1行目の, 1列目から, 6行目の, 3列目まで)
sheet.getRange(1,1,6,3).getValues();

// or

sheet.getRange("A1:C6").getValues()
```
jQueryの基礎知識

##はじめに
UIを整える際に「jQuery UI」を使用している記事を多く見ました。
実装する前に概要を理解しておく目的で、今回はjQueryの概要を記します。

##jQueryとは

よく言われている言い方が「JavaScriptのライブラリ」である。
この「ライブラリ」とは、まとまったプログラムをあらかじめ作ってくれているファイルのこと。

つまりjQueryとは、JavaScriptをより簡単に記述できるように設計された拡張機能のようなもの。

##メリット
・どんなブラウザでも使える
現時点ではまだ自分はあまり実感できませんが、ここがjQueryが使われる最大の理由にあたるようです。
ブラウザには、「IE」、「Edge」、「Google Chrome」、「Safari」など様々な種類がありますが、
実はそれぞれ微妙に仕様が違うため、同じJavaScriptのコードでも異なる挙動になってしまうものがある。
そこでjQueryでは、どのブラウザでも同じコードで動作するようにしてくれるようになる。

・プラグインで拡張できる
こちらのメリットが今回自分がjQueryを調べるに至った所以です。
jQueryをベースに開発されたライブラリが多数提供されていて、簡単に独自の機能を追加できる。
代表的なライブラリとしては「jQuery UI」「jQuery Mobile」などがある。

##読み込み方
以下の文をhtmlファイル内に記述する。

```
 <script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
```

##min.jsとは
jQueryファイルをダウンロードすると、「jquery.js」「jquery.min.js」と2種類あったが、
結論これはどちらもまったく同じ動作をする。

「min.js」は圧縮版（minified）という意味で、改行・コメント・インデントなどを省略している。
これによりファイルの容量を小さくして読み込み時間を高速化している。

では「jquery.js」は非圧縮版で、開発者がコードを見ながらデバッグしやすくする意図がある。
要は本番の使用時は「min.js」を使用するのが一般的である。

##コードの書き方

基本構文は以下の通り。

```
$(“セレクタ”).メソッド(“パラメータ[引数]”);
```

セレクタで「どこの」、メソッドで「何を」、パラメーターで「どうする」、を決める。

例えば、「h1要素のを文字色を赤にする」場合。

```
$('h1').css('’color,'red');
```

セレクタに関して、
id指定の際は＃を、class名指定の際は.をつける。
（例）
id="tBox　→　$("#tBox);
class="font-main"　→  $(".font-main");

##さいごにJavaScriptとjQueryの使い分け

上記で挙げた通り、複数のブラウザでの使用が予想される場合はjQueryが便利である。
また、jQueryは多数のプラグインがあるので、それらを導入するだけで機能を追加できるという点がある。
しかし難点として処理速度は落ちるため、処理能力でいえばJavaScriptの方が断然速い。

まとめると、大規模のアプリであれば処理能力に重きを置いたJavaScript。
小~中規模程度のアプリであればコスパの良いjQueryが良いと言えそうである。
GoogleAppsScriptで作成したファイルを指定のフォルダへ移動

## ファイルの移動と削除

```
// 配置したいフォルダのIDを指定  
const id = PropertiesService.getScriptProperties().getProperty('配置したいフォルダのIDを指定')

// 移動させるファイルをIDで指定
// GASで動的にファイルを作っていた場合は 〇〇.getId() で取得
const file = DriveApp.getFileById('移動させるファイルのID')

// fileをコピーして指定フォルダにペースト
DriveApp.getFolderById(id).addFile(file)

// トップディレクトリにできたファイルを削除
DriveApp.getRootFolder().removeFile(file)
```
【GCP】アイレットのMSPについて

クラウドネイティブ時代の MSP サービス 〜 24 時間 365 日体制の監視、運用サービスの実情 〜
アイレット株式会社 執行役員　後藤 和貴
https://cloudonair.withgoogle.com/events/google-cloud-day-digital-21/watch?talk=d1-pl-13

2019年プレミアムパートナーのパートナープログラムにオンボード
GoogleCloudの
2021年にMSPパートナーに認定された

＝＝＝
24時間有人対応
その後のシステムを支える対応や設定ミスの対応、クラウドならではの使い方のナレッジを利用する
お客様の情報は漏洩していない。
パートナーとも積極的に組んでいく。
＝＝
un Managedなサービスとは
クラウドが出てきて、下回りをみなくてよくなった。
ユーザーに任せられている管理をMSP事業者が入って、本業に集中できるようにする。

＝＝＝
～運用サービス
障害対応もする

＝＝＝
監視サービス
リソースの監視もする

＝＝＝
運用サービス
サーバーのスケール対応もやっている

＝＝＝
組織体制
MSP認定を受ける際、専門チームが必要という要件があったが、その先をいっている
３つのグループに分かれている
DevSecOpsを意識したチーム構成
開発しながらオペレーションするが、それにセキュリティを絡める形。

===
有人監視
基本的にはnewrelicを使ってる。
そこからでた監視アラートをレベルチェックして、インシデントとなればPagerdutyに蓄積され人をアサインする。
お客様とのやりとりはBacklogを使い、証跡を残す。
＝＝
セキュリティも万全
セキュリティチームは専門家を置いている。
Csertの情報も得ながら対応する。
＝＝＝＝

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/cee9f57f-62c6-a323-5e94-7cfab465755d.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/984aec54-1dab-59ec-8c85-cef99f93a8b3.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/d9d2bc94-1a17-90ec-84e6-2577eec6c213.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/8165819a-f3b7-5f16-8428-4e25014660c4.png)
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/6c6ebc12-588b-c522-bcba-e4b463daf669.png)
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/0439ddd9-66d4-c1d4-d344-7a2fa18c093e.png)
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/42dc6df6-01b2-0f0a-950e-3cd71670befe.png)
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/1546cad2-165e-b9aa-49e4-58554a175f2d.png)
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/43acdbc8-2186-201e-819e-00ba422df553.png)
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/4457d458-a80f-1565-14a1-9de16393ec80.png)
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/e1f5fbc4-6d7c-a427-5f9a-5b85ff2acbd6.png)
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/21253fbb-1f5f-8bcd-c61a-61cd181b460b.png)
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/ccc812df-7785-aea5-9d9c-10c60c1431ef.png)
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/ae0e2fad-c8a3-fc78-04db-c06b22ad76d2.png)
APN Partner Central アライアンスリードにログインできなくなった時の対処法

#APNとは？

Amazon Partner Networkの略で、AWSと企業のパートナーネットワークのことです。
APN Partner Centralという、パートナー専用ページを通じて、
マーケティング、学習、ビジネス面でのさまざまな支援をAWSから受ける事ができます。

https://aws.amazon.com/jp/partners/#:~:text=AWS%20%E3%83%91%E3%83%BC%E3%83%88%E3%83%8A%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%20(APN)%20%E3%81%A8,%E3%81%AE%E3%80%81%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%AB%E3%81%AA%E3%82%B3%E3%83%9F%E3%83%A5%E3%83%8B%E3%83%86%E3%82%A3%E3%81%A7%E3%81%99%E3%80%82&text=AWS%20%E3%83%91%E3%83%BC%E3%83%88%E3%83%8A%E3%83%BC%E3%81%AF%E3%80%81%E4%B8%96%E7%95%8C%E4%B8%AD,%E8%A6%8F%E6%A8%A1%E3%81%A7%E5%AD%98%E5%9C%A8%E3%81%97%E3%81%BE%E3%81%99%E3%80%82

#アライアンスリードとは？

APNにおける、企業の代表者（担当者）のことです。
APN Partner Centralページで最も強い権限を持っているため、
アライアンスリードでないとパートナースコア情報の更新などができません。

#ログインできなくなった時の対処法

アライアンスリードですが、担当者の退職等でログインできなくなった場合、変更ができます

**1.新担当者を登録する**

APN パートナーセントラルの自己登録フォームから、
登録済みの企業ドメインと同じメールアドレスを使用し、
新担当者をAPNにユーザー登録します
https://www.apn-portal.com/selfregisterpartner


**2.アライアンスリード変更を申請する**

新担当者のアカウントでAPN Partner Centralにログインし、
`パートナースコアカードの表示`から、`アライアンスリード変更を申請する`を選択し、申請します



**3.待つ**

通常2-3日でアライアンスリードが変更されるはず...ですが
1週間経っても変更されない場合は、
問い合わせを行いましょう。

APN Partner Centralから、
`デバイスの掲載`→`APNサポートチームにお問い合わせ`
から問い合わせます
フォームは英語ですが、日本語で問い合わせ可能。

数日後、APNサポートチームから英文メールで変更が完了したとの連絡が届けば
アライアンスリードの変更完了です。
PostgreSQLで主キーが配列で与えられた順に行番号を振る

# 目的
行番号を持つテーブルが存在します。この時主キーを配列で与えてその順番で行番号を更新したいです。
# SQL
```sql
CREATE TABLE items (
id INT
,line_no INT
);


INSERT INTO tests (
  id, line_no
)
values (1, 1), (2, 2), (3, 3)
;

UPDATE items AS t1 SET
  line_no = t2.line_no
FROM 
  unnest(ARRAY[3, 2, 1]) WITH ORDINALITY as t2(id, line_no)
WHERE
  t1.id = t2.id;
```
Javascriptのイベントを知る

#Javascriptのイベントを知る
javaでdivclassに書いてある内容を取ってくる方法


```csharp
<body>
  
<h1>お名前を記入してください</h1>
<input type="text" id="name">
<button id="btn">入力完了</button>

<div id="disp-name"></div>

<script>
  var  btn = document.getElementById('btn');
  btn.addEventListener('click',function(){
   var name = document.getElementById("name").value;
   document.getElementById("disp-name").innerHTML = name;
  })
</script>

</body>
</html>
```

#解説
```csharp
 var  btn = document.getElementById('btn');
```
これで<button id="btn">入力完了</button>という箇所のことを示しており、btnという変数に入れることを意味しています。Elementとは一行のことを示している。

```csharp
btn.addEventListener('click',function(){
```
今回はbtn変数から受け取り、ボタンが押された場合どうするかを考えています。

```csharp
var name = document.getElementById("name").value;
```
nameという値(価値）を取ってくることを記載します。

```csharp
   document.getElementById("disp-name").innerHTML = name;
```
disp-nameというHTMLのinnerにnameを入れますよという表示になります。


結果的には以下のようになります。
![図2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1514036/3952814c-08d8-1707-d327-4356ab6e3110.jpeg)
AWS RDS



#RDS（Relational DAtabase Service）

マネージドRDBサービス。最大のメリットは運用効率化。オンプレミスでも使い慣れたデータベースエンジンから好きな物選択できる。AWS独自のAuroraも選択可能。

**・選べるエンジン**
Aurora、MySQL、PostgreSQL、ORACLE、SQLServer、MariaDB

**・NoSQLのエンジン**
DynamoDB、ElastiCache、Neputune、DocumentDB、Keyspaces

##RDSの特徴

###・マルチAZ
１つのリージョン内の２つのAZにDBインスタンスをそれぞれ配置し、障害発生時やメンテナンス時のダウンタイムを短くすることができるサービス。

#####マルチAZの注意点
ー読み込み速度が遅くなる。シングル構成よりも書き込みやコミットにかかる時間が長くなる。テスト環境の際もマルチAZで確認しないと、本番環境がマルチAZで、徹すと環境がシングルの場合、問題が発生する可能性がある。

ーフェイルオーバーには６0秒から120秒かかる。


###・リードレプリカ
更新用と参照用にDBインスタンスを分けることが可能。負荷分散を行える。マスターとリードレプリカのデータ同期は、非同期レプリケーション方式なので、タイミングによっては、マスターの更新がリードレプリカに反映されていないことがある。
**参照専用のレプリカを最大５台。Auroraのみ最大１５台設置可能。**

###・バックアップ/リストア

**ー自動バックアップ**
**バックアップウィンドウと保持期間を指定することで、1日1回自動的にバックアップ（スナップショット）を取得できるサービス。保持期間は、最大35日。バックアップからDBを復旧する場合は、取得したスナップショットを選択して新規でRDSを作成する。**

**ー手動スナップショット**
任意のタイミングでRDSのバックアップを取得できるサービス。１リージョンに１００個まで取得可能。

**ーデータのリストア**
**RDSにデータをリストアする場合は、自動バックアップもしくは手動スナップショットから新規RDSを作成する。**

「リストアとは」
ハードディスクなどの記憶装置が破損するなどしてデータが失われた際に、以前に取っておいたデータの複製を書き戻すなどして復元することをリストアという。

**ーポイントタイムリカバリー**
直近５分前から35日前まで任意のタイミングの状態のRSDを新規作成できる。

###・ストレージの容量変更
ストレージ容量は設定変更で増加させることはできるが、減少させることはできないので注意


##セキュリティ
データ暗号化の対象
・DBインスタンス
・自動バックアップ
・リードレプリカ
・スナップショット

暗号の方式は、S3やKMSなど利用する。

##シャーディング　書き込み処理のスケーリング
データベース内の複数のテーブルにデータを分割するための一般的な概念です。リクエスト増加などで単一のマスターDBの運用で限界がある場合に、一定のルールに従いデータを複数のDBに振り分けることでアクセスを分散させることができます。
**例、ID:０〜５００はマスター１、ID:５０１〜１０００まではマスター２**


##RDSの拡張モニタリングを有効化
DBインスタンス上のさまざまなプロセスまたはスレッドがCPUをどのように使用しているかを常時モニタリングするためには、RDSの拡張モニタリングを有効化することが必要です。これにより、DBインスタンスのOSのリアルタイムメトリックスが確認できるようになります。 RDSコンソールを使用してDBインスタンスのメトリクスを表示でき、CloudWatch Logsからの拡張モニタリングを利用することができます。 **デフォルトでは、拡張モニタリングメトリクスは30日間CloudWatch Logsに保存されます。**

##RDSの読み取りキャパシティを向上させために「３つの対応」 

**・RDS リードレプリカによって、データベース (DB) インスタンスの読み込みパフォーマンスと耐久性が向上します。**

**・高性能なインスタンスタイプに変更してスケールアップすることでDBの読み込みパフォーマンスが向上します。**

**・ElastiCacheをRDSの前面に配置することで、RDSの読取処理が多いデータをキャッシュとして保持して、インメモリ上で高速処理することができます。**

読み取り処理の負荷軽減をリードレプリカによって実施することが最適な構成となります。MySQL、MariaDB、PostgreSQL、Oracle では、各 DB インスタンスに最大 5 個のリードレプリカを追加できます。 
**コスト効率を考えた場合はリードレプリカの作成を優先させることになります。**

##RDSプロキシ
**アプリケーションとRDSデータベースの間の仲介役として機能します。RDS プロキシは必要となるデータベースへのコネクションプールを確立および管理し、アプリケーションからのデータベース接続を少なく抑える機能です。**

Lambda関数はRDSエンドポイントではなくRDSプロキシを利用して接続することが求められます。RDSプロキシはLambda関数の同時実行によって作成された大量の同時接続をスケーリングするために必要なコネクションをプーリングします。これにより、Lambdaアプリケーションは、Lambda関数呼び出しごとに新しいコネクションを作成するのではなく、既存のコネクションを再利用できます。 RDSプロキシを利用せず、エンドポイントを利用するとLambda関数によってコネクションが多数発生して処理が上手くいかなくなってしまいます。


##Trusted Advisor
使用率の高い全てのEC2インスタンスを検出することができます。
Trusted Advisor は AWS で利用している EC2 や RDS などのサービスを「コスト」「セキュリティ」「パフォーマンス」「耐障害性」「サービスの制限」について、ベストプラクティスに基づいたアドバイスを自動的に行なってくれるサービスです。
富岳にdonkeycarパッケージをインストールする

表題の手順をgithub上に公開しました。

> GitHub: Donkeycar on Fugaku
> https://github.com/coolerking/donkeycar_on_fugaku



去年あたりからニュース画像でもおなじみになってきたスーパーコンピュータ富岳ですが、OSSを使った計算を行う場合は多少厄介になります。

すでにインストール済みのものであればよいのですが、未インストールであり、さらに依存関係のあるOSパッケージ管理ツール管理化のパッケージを使用する場合、一般ユーザの許可されている権限でなんとかしないといけないので、いろいろややこしくなります。

自分が思いつく方法は、以下の２種類になります。

* ホームディレクトリ上でソースからコンパイル
* spack を使ってコンパイル＆インストール

ホームディレクトリ上にソースコードを展開して、手動でビルドするときに、`--prefix` オプションでホームディレクトリ上のサブディレクトリ（ex. `~/local/aarch64fx` ）にして`make install`したときにこのディレクトリに書き込まれるようにする方法です。

自分は Slackware 時代からのLinuxユーザなので、この手の手順にはなれていますが、依存関係のあるパッケージをたどっていくと..やがて LLVM まで到達してしまい、この方法であっているのか?..と。

で、富岳ポータルサイト（登録ユーザのみが参照可能）のコンテンツを調べ直したところ、Spackを使うことを推奨しているようです。

Spackは、スーパーコンピュータ上でOSSをインストールするためのツールで、Pythonで動作します（富岳にも最初からインストールされている）。なので、http://github.com/spack/spack.git をチェックアウトするだけで動作します。

Spackはpyenvやvirtualenv、condaなどのように"環境"を作ることができるので、デフォルトの環境ではなく、用途に合わせて個々の"環境"を作ることができます（削除もコマンド１発）。この"環境"の中にインストールすればOKです。最初の環境であるルート環境に入るには、用意されたセットアップシェルを実行します。

```bash
# インストール
git clone https://github.com/spack/spack.git ~/spack
cd ~/spack
git checkout releases/＜使いたいバージョン＞

# ルート環境に入る
. ~/spack/share/setup-env.sh
```

これでspackコマンドが使用可能になります。

独自の"環境"を作る場合も、spackコマンドを使用します。

```bash
# 環境 hogehoge を作成する
spack env create hogehoge
# 環境 hogehoge に入る
spack env activate hogehoge
# インストール可能なOSSパッケージをリスト
spack list
# インストール済みパッケージのリスト
spack find
# openblasパッケージをインストール
spack install openblas
# 環境 hogehoge から抜ける（ルート環境にもどる）
spack env deactivate
# 環境 hogehoge を削除する(確認なし)
spack env remove hogehoge
```

spack install で指定する引数によっては、OSSバージョン、使用するコンパイラおよびバージョン、リンクオプションなどを指定可能です。

```
# 富岳ではterminfoをリンクする場合-ltinfoを使う
spack install mesa ldlibs="-ltinfo"
```

spack install されると、`~/spack/var/spack/environments/＜Spack環境名＞/.spack-env/view` 以下の `bin` 、 `lib` や `include` へインストールされます。これらへのパスなどの環境変数は `spack env activate` 時にセットされます。

ただし、`pip` からフォークされる `cmake` などのオプションにまで到達しない場合があるので、個別にセットする必要があるケースもあります（Pythonパッケージを `pip` でインストールする際には内部で `cmake` することがあります）。このあたりはトライ＆エラーでみつけていくしかありません。

Pythonパッケージの一部もspackからインストールできます。もちろんpipも可能ですが、一般ユーザではグローバルインストールはできないので、`--user` オプションを付けないと動きません。


富岳は会話型とジョブ型の２種類の実行方法がありますが、`spack install` が会話型だと制限時間内に終わらないことがあるため、それなりのボリュームのパッケージはジョブ型で実行（ `pjsub`コマンドでシェルを実行）する必要があります。


> あと、TensorFlow2.2.0/PyTorch1.7.0はあらかじめインストールされたパスが公開されているので、これらへパスを変更することで使用可能になります。Spackでもインストールできそうですが、富岳管理者が提供しているので、コンパイラ最適化オプションをきちんとつけて作成している（..とおもいます）はずなので、こちらをつかうほうがよいでしょう。

なのでvirtualenvなどのPython環境と、Spack環境を併用するのがよいと、私は判断しました。最初に紹介したGitHub上のスクリプトも、それを前提に作成しています。

細かい使い方は [Spackのドキュメント](https://spack.readthedocs.io/en/latest/) を参照してみてください。チュートリアルもありますし、Youtubeに英語ですが [概要紹介のセッション動画](https://youtu.be/edpgwyOD79E) も投稿されています（字幕翻訳させれば内容はわかるとおもいます）。

<iframe width="560" height="315" src="https://www.youtube.com/embed/edpgwyOD79E" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

ご参考まで。
[Rails]Railsアプリへの画像アップロード機能を実装する[ActiveStorage]

# 記事の概要
　画像ファイルアップロード機能の実装についてまとめました。まずは、各種画像加工ツールの導入手順をまとめたのち、簡単に画像アップロードを実現してくれるActiveStorageについてまとめました。

# 画像加工ツール導入手順

### ①ImageMagickの導入
　まず、画像変換ツールであるImageMagickをインストールする。これはGemではなくソフトウェアなので、Homebrewからインストールする。

```
% brew install imagemagick
```

### ②MiniMagickとImageProcessingの導入
　MiniMagickは、ImageMagickの機能をRuby on Railsで使えるようにするためのGem。
　ImageProcessingは、画像サイズを調整する役割を持つGem。

```Ruby:Gemfile
gem 'mini_magick'
gem 'image_processing', '~> 1.2'
```
```
% bundle install
```
# ActiveStorage導入手順
　ActiveStorageはGemですが、Railに統合されているため、改めてGemfileへの記述とbundle installは不要。
　アプリ内でActiveStorageを利用できるようにするために、専用テーブルを下記コマンドで生成します。

```	
% rails active_storage:install 
```
　これでマイグレーションが生成されるので、続けてマイグレート実行。

```	
% rails db:migrate
```
　DBに「active_storage_attachments」と「active_storage_bolbs」の二つのテーブルが生成されていれば無事準備完了。

# 画像保存機能の実装

### ①ActiveStorageと、紐付けたいモデルとの間のアソシエーション
　今回、とあるモデルテーブルの各レコードと画像ファイルを1対1で紐付けるとする。例えば一つのツイートにファイルを一つ添付したい場合。has_one_attachedメソッドを使い、:ファイル名を記述。

```ruby:models/tweet.rb	
class Tweet < ApplicationRecord
  has_one_attached :image #ここのファイル名の命名は任意。
end
```
　一つのツイートに複数枚添付したいなら、has_one_attachedの代わりにhas_many_attachedとする。:imageは:imagesとする(複数形)。

### ②フォームの実装

```new.html.erb
<%= form_with model: @tweet, local: true  do |form| %>
  <%= form.text_area :content %><br>
  <%= form.file_field :image %><br>
  <%= form.submit %>
<% end %>
```
　複数枚アップロードする場合は、:imageを:imagesのように複数形にして、file_fieldにmultiple: trueを追記して、複数ファイルの選択ができるようにする。

### ③画像の保存を許可する
　コントローラー側で、ストロングパラメータを定義し受け取った画像の保存を許可する。imageという名前で送られてくる画像を含めてpermitする。

```ruby:tweets_controller	
def create
  Tweet.create(tweet_params)
end

private
# ここから、ストロングパラメータの記述
def tweet_params
   params.require(:tweet).permit(:content,:image).merge(user_id: current_user.id)
end
```
　ここも、複数枚の画像保存する場合は、:imageを、images:[]のように記述しておく。

# 画像を表示させる
　image_tagヘルパーメソッドで画像を表示する。引数にモデルから画像ファイルを呼出して記述する。ここでは、ファイル名imageとしているので、tweet.imageで取得できる。

```
#　ビューファイル
<%= image_tag tweet.image %>
```
　画像ファイルの表示サイズを指定したい時はvariantメソッドを使う。

```
モデル.ファイル名.variant(resize: '幅x高さ')
```
【React】axiosでリクエストしたとき、400(Bad Request)が発生した際の対処法【axios】

<h2>症状</h2>
Reactでaxiosを使用して、RailsAPIにアクセスしようとしたときに、400(Bad Request)が発生してしまいました。
railsAPI側のログをみると、アクセスしたいactionまで届いていそうではありますが、上手く動作していないようです。

```terminal:エラー
PUT http://localhost:3000/hoges/undefined 400 (Bad Request)
```

axiosのコードでアクセスしていた箇所はこんな感じです。

```react:accessPutjsx
export const url= (id) => `http://localhost:3000/hoges/${id}`;

export const accessPut() {
    hoge.id = 1
    axios.put(url(hogee.id))
}
```

<h2>解決策</h2>
今回はurlに設定するパラメータがミスっていたため、undefindedをそのまま送っていたため、エラーが発生していました
パラメータをちゃんとurl側に送って、それを正しいurlでアクセスしたら、エラーが解消しました

```react:accessPut.jsx
export const url= (id) => `http://localhost:3000/hoges/${id}`;

export const accessPut() {
    hoge.id = 1
    axios.put(url(hoge.id))
}
```
ROOT  installation on Ubuntu 18.04

久しぶりにROOTのアップデートをしてみた。インストールしたのは、root 6.24/00。
ほぼいつも通りの作業。

```
wget https://root.cern/download/root_v6.24.00.source.tar.gz
tar zxvf root_v6.24.00.source.tar.gz
mkdir root-6.24.00_build
cd root-6.24.00_build
cmake ../root-6.24.00
cmake --build . -- -j8
```

これでUbuntu 20.04では問題なくインストールできたのだが、Ubuntu 18.04ではなぜかコンパイルエラーを起こす。

```
CMake Error at /opt/root/root-6.24.00_build/XROOTD-prefix/src/XROOTD-stamp/XROOTD-build-Release.cmake:16 (message):
  Command failed: 2

   'make'

  See also

    /opt/root/root-6.24.00_build/XROOTD-prefix/src/XROOTD-stamp/XROOTD-build-*.log


CMakeFiles/XROOTD.dir/build.make:111: recipe for target 'XROOTD-prefix/src/XROOTD-stamp/XROOTD-build' failed
make[2]: *** [XROOTD-prefix/src/XROOTD-stamp/XROOTD-build] Error 1
CMakeFiles/Makefile2:362: recipe for target 'CMakeFiles/XROOTD.dir/all' failed
make[1]: *** [CMakeFiles/XROOTD.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
[ 79%] Built target RIO
Makefile:151: recipe for target 'all' failed
make: *** [all] Error 2
```

解決策はこちらにあった。

https://root-forum.cern.ch/t/error-while-building-root-from-source-code/44714

解決するには、```uuid-dev```というのを入れる必要があるのと、入れた後に```XROOTD-prefix```ディレクトリを削除する。


```
sudo apt-get install uuid-dev
rm -rf XROOTD-prefix
cmake ../root-6.24.00
cmake --build . -- -j8
```

これでインストールできるはず。
ipv6 で Nginx にアクセスする

1) サーバーの ipv6 のアドレスを調べます

```text
$ ip -6 addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 2400:8500:1302:802:133:130:124:81/128 scope global dynamic noprefixroute 
```

2400:8500:1302:802:133:130:124:81 がアドレスになります。

2) ping で確認

```text
$ ping -6  -c 3 2400:8500:1302:802:133:130:124:81
PING 2400:8500:1302:802:133:130:124:81(2400:8500:1302:802:133:130:124:81) 56 data bytes
64 bytes from 2400:8500:1302:802:133:130:124:81: icmp_seq=1 ttl=63 time=0.693 ms
64 bytes from 2400:8500:1302:802:133:130:124:81: icmp_seq=2 ttl=63 time=0.471 ms
64 bytes from 2400:8500:1302:802:133:130:124:81: icmp_seq=3 ttl=63 time=0.555 ms
```

3) DNS で AAAA レコードを登録
 onamae.com だと次のようになります。
![onamae_may25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/713f6000-9977-9cf0-dcf2-10e55f171630.png)


>ping で確認

>```bash
ping -6 -c 3 abc.example.com
```

>dig で確認

>```text
$ dig -t AAAA abc.example.com +short
2400:8500:1302:802:133:130:124:81
```

4) Nginx の設定

```text:/etc/nginx/sites-available/default
server {
        listen 80 default_server;
        listen [::]:80 default_server;
（省略）
```

>設定ファイルが正しいことを確認

>```text
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```

>Nginx を再起動

>```bash
sudo systemctl restart nginx
```

5) ブラウザーで ipv6 でアクセス

[http://[2400:8500:1302:802:133:130:124:81]](http://[2400:8500:1302:802:133:130:124:81])
tfenv操作まとめ


## tfenvとは？
terrafromのバージョン管理をしてくれる。
https://github.com/tfutils/tfenv


## インストール

```
$ brew install tfenv
```

ちなみに既にterraformを落としている状態だと下記のようなエラーが発生した。

```
Error: Cannot install tfenv because conflicting formulae are installed.
  terraform: because tfenv symlinks terraform binaries

Please `brew unlink terraform` before continuing.
```

指示通りunlinkを実行すると解消される。

```shell
$ brew unlink terraform
$ brew install tfenv
$ tfenv -v
# tfenv 2.2.2
```

## 色々なコマンド


### `list-remote`
現在インストール可能なterraformのバージョンリストが確認できる。

```
$tfenv list-remote
```

```
0.15.4
0.15.3
0.15.2
0.15.1
```

### `install`
指定バージョンのterrafromインストール。

```
$tfenv install 0.15.4
```



### `list`
インストール済みのバージョンを列挙する。

```
$ tfenv list
```

```
0.15.4
```

### `use`
デフォルトバージョンの切り替え。

```
$ tfenv use 0.15.4
```

```
Switching default version to v0.15.4
Switching completed
```
## リポジトリ内のバージョンの固定
`.terraform-version`ファイルをリポジトリに含めて、 `tfenv install`すると、
チームメンバーも指定のバージョンで統一することができる。

```
$ echo 0.15.4 > .terraform-version
$ tfenv install
```

### 参考
https://github.com/tfutils/tfenv
【OCI】オンプレミスからOCIを経由してインターネットに接続してみた

###概要
先日の記事「【OCI】NATインスタンスを構築してみた」ではOCIのPrivate Subnetから
インターネット宛の通信を可能にするNATインスタンスの作成方法を共有致しました。

今回はOCIとIPSec接続しているオンプレミス環境からOCIのNATインスタンスを経由して
インターネットにアクセスする方法を共有致します。

###検証構成
・VCN上にPublic Subnetを作成、NAT Instance(OS: Oracle Linux)を配置します
※NAT Instanceの作成方法は以下の記事をご参照ください
<font color="red">**[【OCI】NATインスタンスを構築してみた][1]**</font>
[1]:https://qiita.com/hongmnh/items/1cc8cf3d6feb65c7d21f

・オンプレミスとVPN接続するためにDRGとIPSec接続を作成します
※VPN接続方法は以下の記事をご参照ください
<font color="red">**[IX2000シリーズルータとOCI間をVPN接続、BGPでルート制御してみた][2]**</font>
[2]:https://qiita.com/hongmnh/items/b0845e3465caad432447
・NAT Instanceからインターネットへの通信のためにIntenet Gatewayを作成します
・NAT Instanceを配置するPublic Subnetのルート・ルール、セキュリティ・リスト
及びDRGのルート・ルールを下記構成図の通りに構成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/da35e2c5-09e0-7934-2fc2-9ddb935924fa.png)

###検証方法
・On-PremisesのユーザPCからOCIのNAT Instanceを経由してインターネット上にある
Google Public DNS(8.8.8.8)宛にpingによる疎通が取れるか試します
・On-PremisesのユーザPCからOCIのNAT Instanceを経由してインターネット上にある
Web Server(確認くん)にアクセス、正しくホームページが表示されることと
インターネットからみた送信元IPアドレスがOCIのNAT InstanceのPublic IPになっている
ことを確認します

###動作確認・結果

①CPE
OCIからBGPにて受信しているルーティング情報を確認
Public Subnetのネットワーク情報(10.0.1.0/24)とデフォルトルートを
受信していることを確認しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/4c009ee8-e0ad-1ebf-c301-38b16f20538e.png)

②On-PremisesのクライアントPC
・Google Public DNS(8.8.8.8)宛にpingによる疎通が取れることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/474390e7-8966-1c76-ee17-a339ea89f13d.png)
・OCIの外にあるWeb Server(確認くん)にアクセス、正しくホームページが表示されることと
外部からみた送信元IPアドレスがOCIのNAT InstanceのPublic IPになっていることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/2dc3d084-8228-2c80-2748-f7393a19333e.png)

###おわりに
・今回は検証環境の都合上、On-PremisesとOCI間の接続にIPSec VPNを利用していますが、
FastConnectを利用して接続した場合でも同じ結果になると思われます。
(理由はVPNとFastConnectともにCPEとDRG間で使うルーティング・プロトコルにBGPが
利用できることとTransit Routingが利用できるため)
・本記事は個人で検証した内容の記録であり、検証方法及び結果を
保証するものではないことをあらかじめご了承・ご理解いただけますようお願い致します。
ROSを用いてpythonからドローンを制御する方法

今回はardroneをROSを使用して、ドローン制御(自律飛行制御)を行う。
まず初めにROSについて、説明する

#ROSとは...
ROS(Robot Oparting System)の略であり、ロボットソフトウェアプラットフォームのことを言う。
これにより、ロボットようアプリケーションプログラムの開発においてパッケージ化されたモジュールやライブライが使用でき、開発が楽に行える。

もう少し簡単に言うと、ロボットが人についていく(トラッキング）プログラムを一から作るとなると大変だが、
これらのプログラムはもうすでに世界の誰かが作ってくれていて、私たちはモジュールというトラッキングプログラムが含まれたものを使用するだけで良い。

###ROSのインストール
ROSはubunts上で動くものなので、必ずubuntsを用意して動かしてください。
ROSのインストール方法はhttps://qiita.com/srs/items/e0e0a9dc3f94c2d3348eを見ながらやってみてください。

###作業フォルダの作成catkin_ws
ROS専用ビルドシステムであるcatkinを使用する。catkinを使用するために、catkin_wsといった作業スペースの中でプログライングスクリプトを記述する必要がある。
以下のコマンドで作成。ちなみに、catkin_makeとはビルドみたいな扱いであり、catkin_ws内のファイルを編集した際にcatkin_makeを行う。
```
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace
cd ~/catkin_ws
catkin_make
source ~/.bashrc
```

###ROSショートカット
ROSはコマンドをよく使うので、ショートカットは覚えておくと良い
```
cw: ~/catkin_wsへ移動
cs: ~/catkin_ws/srcへ移動
cm:　~/catkin_wsへ移動しcatkin_makeでビルド
```
###統合開発環境のインストール(IDE)
GUIを利用するコードを書く場合によく使われているIDEであるVScodeをここではインストールする。
https://code.visualstudio.com/downloadここからんubunt用をダウンロードする

###VsCodeの基本設定
左上の拡張機能からC++/pythonをインストール。
VSCodeでビルドする方法は『ファイル』⇨『フォルダーを開く』を選択しデバッグしたいパッケージを選択。
以下詳細はP39を参照

#catkin_wsのリセット法方
```
rm -rf /home/user/catkin_ws/src/
rm -rf /home/user/catkin_ws/build/
rm -rf /home/user/catkin_ws/devel/
```

#drone.pyファイル(Node)の作成方法
###CMakeLists.txtの編集
```
#該当部分をコメントアウト．また，必要なものを追加
#7行目あたり
find_package(catkin REQUIRED COMPONENTS
    roscpp
    rospy
    std_msgs
    message_generation
)
 
#45行目あたり
## Generate messages in the 'msg' folder
add_message_files(
    FILES
#   Message1.msg
#   Message2.msg
    Adder.msg
 )
 
#66行目あたり
generate_messages(
     DEPENDENCIES
     std_msgs
)
 
#104行目あたり
catkin_package(
# 　 INCLUDE_DIRS include
     LIBRARIES ros_adder
     CATKIN_DEPENDS roscpp rospy std_msgs
     DEPENDS system_lib
)
```
CMakeLists.txtの編集が終了したら、catkin_makeでビルドしておきましょう。
###ノードの作成
ros_adder/scriptsの中にdrone.pyを記述。
```
cd ~/ros_ws/src/ros_adder/
mkdir scripts; cd scripts
touch para_in.py adder.py
```

ノード作成後ビルドしておきましょう。
catkin_makeするときはcd ~/home/に戻ってから操作する
```
cd ~/ros_ws/
catkin_make
```
#ドローンを飛ばす時のコマンド
###ターミナル１
```
roscore
```
###ターミナル２　ardroneとの接続（wifiの接続を忘れないように)
```
rosrun ardrone_autonomy ardrone_driver
```
###ターミナル3
Pythonファイルの実行権限付与
```
cd ~/catkkin_ws/src/ros_adder/scripts
sudo chmod +x drone.py 

source devel/setup.bash
rosrun ros_adder drone.py
```
［入門］スパコン用の基礎知識~OpenMP, OpenMPI

#並列化アルゴリズムの基礎
今度スパコンの講習を受けるにあたって必要知識にOpenMPとOpenMPIが含まれていたので、ここに最低限のことをまとめておく。
具体的なプログラムについては、参考にしたサイトに乗っているのでそちらを参考にしていただきたい。
今回はあくまで、並列化の考え方と必要な知識等についてまとめていく。

#＃並列化とは
そもそも並列化とは、いくつかの処理命令を同時に出すことで処理にかかる合計の時間を減らすことを目的としている。並列化はプロセッサをいくつか積んでいるような**並列コンピュータ**を用いることで実行することができる。
並列コンピュータには、**並列アルゴリズム**、**プログラミング言語**、**並列処理を助けるコンパイラやオペレータなど**が必要である。今回のメイントピックであるOpenMP, OpenMPIはこの中で最後に分類され、並列処理を助けるインターフェースである。その他についてはここでざっくり説明しておく。
**並列アルゴリズム**
まず、アルゴリズムとは問題を解くため従う一連の指示のことであるが、コンピュータの構造によって2つのアルゴリズムに分類することができる。
1. Sequential Algorithme
　問題を解くための命令を順番に連続した命令のステップを実行していくようなアルゴリズム

2.pararel Algorithm 
　1つの問題をいくつかの小問題に分けてそれぞれを個別で解き、その後、個別を解を結合させることで全体の解を得るようなアルゴリズム

実際には並列アルゴリズムを考える際に問題をいくつかに分けるのは難しく、問題によっては並列化できないものや、並列化することで逆に計算時間を増やしてしまうこともある。

**並列コンピュータ**
コンピュータは、データや指示の流れの違いから、4つのカテゴリーに分類できる。
1.SISD (Single Instruction stream, Single Data stream computers)
　一つの制御装置、一つの処理装置、一つのメモリからなるコンピュータ
2.SIMD(Single Instruction stream, Multiple Data stream computers)
　一つの制御装置、複数の処理装置、共有メモリもしくは相互接続ネットワークからなるコンピュータ
3.MISD(Multiple Instruction stream, Single Data stream computers)
　複数の制御装置、複数の処理装置、一つのメモリからなるコンピュータ
4.MIMD(Multiple Instruction stream, Multiple Data stream computers)
　複数の制御装置、複数の処理装置、共有メモリもしくは相互接続ネットワークからなるコンピュータ

並列コンピュータというと、ほとんどの場合SIMD/MIMD型のコンピュータを指すことが多い。
これはその構造によるものであるが、ここでは説明を省略するので、気になった人は参考にしたページを以下に載せておくのでそちらをご覧いただきたい。

https://www.tutorialspoint.com/parallel_algorithm/index.htm

**プログラミング言語**
おそらくどのような言語でも、並列用のプログラムを書くことはできるがスーパーコンピュータで並列化しようと思うとfortranで書くことが大半であり、それ以外ではCやC++などが挙げられる。現在他の言語の開発も進められているようで、私の勉強不足のためこの3つの言語を代表例として挙げているだけである。

###OpenMPとOpenMPI
ここからやっと今回のメインであるOpenMPとOpenMPIについてである。

・OpenMP(Multiple_Processing)
マルチコアCPUの複数コアを利用し、複数スレッドを処理する
各スレッドは並列領域を開始時に生成され、並列処理が終了すると逐次処理に戻る
Fortran, C, C++言語のプログラミングで利用可能
コメントとして指示されている指示分に従って並列化を行う
Fortranでは、

```
!$omp parallel
!$omp end parallel
```

で開始、終了する
C, C++では

```
#programa amp parallel{}
```

で囲んだ部分が並列領域となる

・OpenMPI(Message_Passing_Interface)
複数の計算機と通信を行い、並列処理を行う
複数の計算ノードを用いた大規模並列が可能


基本的に個人のパソコンのみで並列を行う時はOpenMPを使い
スパコンのように複数の計算ノードを使う時は、メモリの共有を行う必要があるのでOpenMPIも使う
OpenMPと似たものにOpenACCがあり、これも並列化に利用することが可能である
今度時間があれば、二つの相違点について詳しく調べてみようと思う

あまりきれいにまとめられていないので、実際に使って知識を整理できたら記事を書き直したい


余談として
並列化を行う時に、全てのCPUを常にフルで並列化させるべきかという問題があるそうだが、以下のサイトに詳しく実験をした結果が載せられていたので、参考までにどうぞ


http://lpha-z.hatenablog.com/entry/2018/12/30/231500



参考URL

https://itcweb.cc.affrc.go.jp/affrit/faq/scs-faq/parallel

https://www.rccm.co.jp/development/parallel/openmp.html

https://www.nag-j.co.jp/openMP/openMPHelloOpenMP.html
Chakra-UIのテーマ


使い方忘れるのでメモ


https://chakra-ui.com/docs/theming/customize-theme


theme.js

```:theme.js
// theme.js
import { extendTheme } from "@chakra-ui/react"
const theme = extendTheme({
  components: {
    Button: {
      // 1. We can update the base styles
      baseStyle: {
        fontWeight: "bold", // Normally, it is "semibold"
      },
      // 2. We can add a new button size or extend existing
      sizes: {
        xl: {
          h: "56px",
          fontSize: "lg",
          px: "32px",
        },
      },
      // 3. We can add a new visual variant
      variants: {
        "with-shadow": {
          bg: "red.400",
          boxShadow: "0 0 2px 2px #efdfde",
        },
        // 4. We can override existing variants
        solid: (props) => ({
          bg: props.colorMode === "dark" ? "red.300" : "red.500",
        }),
      },
    },
  },
})
export default theme
```


_app.tsx

```:_app.tsx
import { ChakraProvider } from '@chakra-ui/react'
import theme from '../theme'
import { AppProps } from 'next/app'

import Layout from '../components/Layout'

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ChakraProvider resetCSS theme={theme}>
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </ChakraProvider>
  )
}

export default MyApp
```
csshxを使って複数サーバに同じコマンドを送る

色々あって複数のサーバの管理をしているので、アップデート（例えは```sudo apt update```とか）作業などはまとめてやりたい。幸いにも私が管理しているサーバば全部Ubuntuに統一しているので、ほとんどの場合は使用するコマンドは同じ。今まではターミナルをたくさん立ち上げて一つずつ手作業でやっていたが、サーバの数が4台を超えたあたりでもう少し効率化をしたくなった。

何かいい方法がないかと調べていて、```csshX```というのがあるのを知った。他にも似たようなもので```pssh```や```mpssh```というのがあるらしいが、完全に同じコマンドしかできないので、特に```sudo```のパスワードが違っていたりすると面倒な気がする。

Macで使う場合はHomebrewでインストールできる。

```bash
$ brew install csshX
```

あとは、使うサーバを列挙してsshでログインすると適当にタイルした端末をたくさん立ち上げてくれる。

```bash
$ csshX server1 server2 server3 server4
```

事前に```~/.ssh/config```で色々と設定しておくと楽だが、例えばパスワードがサーバによって違う場合はそれぞれの端末でパスワードを打てば良い。

ところで、この```csshX```がMacのBigSurではバグがあるらしく動かなかった。

```bash
$ csshX server1 server2 server3 server4
Unimplemented: POSIX::tmpnam(): use File::Temp instead at /System/Library/Perl/5.30/darwin-thread-multi-2level/POSIX.pm line 185.
Unimplemented: POSIX::tmpnam() at /usr/local/bin/csshX line 1130.
BEGIN failed--compilation aborted at /usr/local/bin/csshX line 1130.
```

https://stackoverflow.com/questions/64837097/cant-make-csshx-working-on-mac-os-big-sur
に解決策が書いてあった。というか、エラーメッセージそのものだけど、```/usr/local/bin/csshX```実体は```/usr/local/Cellar/csshx/0.74/bin/csshX```の1130行目を指示通り書き換えれば良い。ちなみにこのファイルは書き込み禁止になっているので、```chmod -w /usr/local/Cellar/csshx/0.74/bin/csshX```としないと書き換えられない。

```/usr/local/Cellar/csshx/0.74/bin/csshX
#==============================================================================#

package CsshX::Launcher;

use base    qw(CsshX::Socket::Selectable);
# use POSIX   qw(tmpnam);
use File::Temp   qw(tmpnam);
Use FindBin qw($Bin $Script);;

```

これで動いた。
【N＋1問題】RailsでSQL文が大量発生！

どうも、三町哲平です。

Ruby on Railsでアプリ作成もいよいよ大詰め。おおよその機能が完成したところで次に気にするのは、どこでしょうか？
私は、真っ先にユーザビリティ(Webサイトやソフトウェアなどの操作性)をもっと突き詰めたいと思う様になりました。しかもDBのデータを一覧表示するときだけ、処理が遅くない？と思いログを見ていたのですが、
![スクリーンショット 2021-01-17 17.22.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688029/d1d943b5-7474-cb10-00d4-1562e7a345dd.png)

なんか青文字がいっぱいじゃないですか！？

色々調べてみるとどうもN＋1問題というものが絡んでいそうなので、その辺りを今回はまとめてみました！

# Nプラス１問題とは?
「__データベースからデータを取り出す際に、SQLの発行を必要以上に行ってしまう問題のこと__」です。

このSQLの発行が必要以上行われることにより、処理に時間が掛かりページ遷移が遅くなってしまうという現象が起こります。

※__SQL__とは、データベース言語でDBへの更新、追加、削除などを行う事ができます。しかし、Railsの場合だとActiveRecordのおかげで直接データベース言語を書かなくてもDBへの更新、追加、削除などを行う事ができます。

※__ActiveRecord__とは、Ruby on Railsで使用しているO/Rマッパーのことです。

> O/Rマッピングとは、オブジェクト指向プログラミング言語におけるオブジェクトとリレーショナルデータベース（RDB）の間でデータ形式の相互変換を行うこと。そのための機能やソフトウェアを「O/Rマッパー」（O/R mapper）という。
引用記事:[O/Rマッピング（O/Rマッパー）とは - IT用語辞典 e-Words](https://e-words.jp/w/O-R%E3%83%9E%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0.html#:~:text=O%2FR%E3%83%9E%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0%E3%81%A8%E3%81%AF,O%2FR%20mapper%EF%BC%89%E3%81%A8%E3%81%84%E3%81%86%E3%80%82)

[オブジェクト関係マッピング - Qiita](https://qiita.com/yk-nakamura/items/acd071f16cda844579b9)

# 用語を理解した上で
N＋1問題で頻出する用語が分かった後は、大変分かりやすくまとめられている記事がいくつもございますで、こちらを参考にして解決していきましょう！
私が学習の際に利用したページのリンクを載せます。

## 動画で理解する
https://www.youtube.com/watch?v=NkmWcmA69XU

https://www.youtube.com/watch?v=6LxIpm5GKDA

## 記事で理解する
* [N+1問題 - Qiita](https://qiita.com/TsubasaTakagi/items/8c3f4317ad917924b860)
* [[解説] SQLクエリのN+1問題 - Qiita](https://qiita.com/muroya2355/items/d4eecbe722a8ddb2568b)
* [N+1問題は1+N問題 - Qiita](https://qiita.com/hisonl/items/763b9d6d4e90b1606635)
* [【Rails】パフォーマンス低下に繋がるN+1問題とは？解決策と併せて解説！｜TechTechMedia](https://techtechmedia.com/n1-includes-rails/)
* [【Rails】N+1問題って何？原因と対処法を徹底解説！ | Pikawaka - ピカ1わかりやすいプログラミング用語サイト](https://pikawaka.com/rails/n1)
* [N+1問題におけるORMの重たさについて - Atsuo Ishimoto's blog](https://aish.dev/misc/orm_n1problem.html)
* [【Ruby on Rails】N+1問題ってなんだ？ - Qiita](https://qiita.com/massaaaaan/items/4eb770f20e636f7a1361)

## それでもやっぱり難しい方へ
Railsには、bulletという便利なgemが存在します。
N＋1問題が発生している際に下図の様な警告文が出るのでその通りにcontrollerもしくは、viewを修正してやれば解決します。
![スクリーンショット 2021-05-25 13.05.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688029/60899a94-b59e-c6e0-be21-b3ec8eace285.png)

※bulletについての詳しい使用方法は、下記リンクを参考にして下さい。
* [【Rails】N+1問題をアラート表示してくれるgem「bullet」が超絶便利だった！｜TechTechMedia](https://techtechmedia.com/nplusone_query-bullet-rails/)
* [Railsライブラリ紹介: N+1問題を検出する「bullet」 | TECHSCORE BLOG](https://www.techscore.com/blog/2012/12/25/rails%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E7%B4%B9%E4%BB%8B-n1%E5%95%8F%E9%A1%8C%E3%82%92%E6%A4%9C%E5%87%BA%E3%81%99%E3%82%8B%E3%80%8Cbullet%E3%80%8D/)
* [【初心者】N+1問題を発見！Bulletの使い方 - Qiita](https://qiita.com/usami0322/items/712e53f9609c39de44e7)

今回の記事は、短いですが以上です！！
Rubyアルゴリズム（Palindrome Number）

## 問題
Given an integer x, return true if x is palindrome integer.

An integer is a palindrome when it reads the same backward as forward. For example, 121 is palindrome while 123 is not.

```
Input: x = 121
Output: true
Example 2:
```

```
Input: x = -121
Output: false
Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
```

## 私の答え

```ruby
def is_palindrome(x)
    if x.to_s == x.to_s.reverse
        return true
    else
        return false       
    end
end
```

無事Acceptedです。

```ruby
"123".reverse #=> "321"
```
文字列に使うと反対になるreverseを使いました。
あまりにシンプル。。
ubuntu20.04LTSにROS2 Galacticをインストールする

# はじめに

2021年 5月23日にROS2の最新ディストリビューションである`Galactic Geochelone`がリリースされました。

Galacticをubuntu20.04LTSにインストールしたのでインストール手順をメモ

基本的には公式のインストールガイド通り
https://docs.ros.org/en/galactic/Installation/Ubuntu-Install-Debians.html


# インストール
すでにROS2 Foxyが入っている場合、~/.bashrcの以下をコメントアウト

```bash
# source /opt/ros/foxy/setup.bash
# source ~/ros2_ws/install/local_setup.bash
```

変更した設定を反映

```bash
$ source ~/.bashrc
```



##  PPAの追加
```bash
$ sudo apt update && sudo apt install curl gnupg2 lsb-release
$ sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key  -o /usr/share/keyrings/ros-archive-keyring.gpg
$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
```

## インストール
```bash
$ sudo apt update
$ sudo apt install ros-galactic-desktop
```

## 環境設定
```bash
$ echo "source /opt/ros/galactic/setup.bash" >> ~/.bashrc
$ source ~/.bashrc
```

## colcon build インストール

すでにインストール済みの場合は不要

```bash
$ sudo apt install python3-colcon-common-extensions
```

## ワークスペースの作成

```bash
$ mkdir -p ~/ros2_ws/src
$ cd ros2_ws/
$ colcon build
```


# 動作確認

ターミナルを開いて以下を実行

```bash
$ ros2 run demo_nodes_cpp talker
```
別のターミナルで以下を実行

```bash
$ ros2 run demo_nodes_py listener
```

以下のようにメッセージが出ていれば成功

```bash
$ ros2 run demo_nodes_cpp talker
[INFO] [1611230592.489680360] [talker]: Publishing: 'Hello World: 1'
[INFO] [1611230593.490090831] [talker]: Publishing: 'Hello World: 2'
[INFO] [1611230594.490166446] [talker]: Publishing: 'Hello World: 3'
```

```bash
ros2 run demo_nodes_py listener
[INFO] [1611230787.236789185] [listener]: I heard: [Hello World: 3]
[INFO] [1611230788.215690250] [listener]: I heard: [Hello World: 4]
[INFO] [1611230789.215362123] [listener]: I heard: [Hello World: 5]
```


# 参考

https://docs.ros.org/en/galactic/Installation/Ubuntu-Install-Debians.html
Nuxt.jsで外部のjs,cssファイルを読み込む方法

Nuxt.jsで外部のjs,cssファイルを読み込む方法になります。

## 共通で読み込む場合
共通で外部ファイルを読み込む場合は、`nuxt.config.js`で設定します。

```js:nuxt.config.js
export default {
  head: {
    script: [
      {
        src: 'https://demo.js'
      }
    ],
    link: [
      {
        rel: 'stylesheet',
        href: 'https://fonts.googleapis.com/css?family=Roboto'
      }
    ]
  }
}
```

## ページ毎に読み込む場合
ページごとに外部ファイルを読み込む場合は、pagesディレクトリのvueファイルで設定します。

```vue:page.vue

<script>
export default {
  head() {
    return {
      script: [
        {
          src: 'https://demo.js'
        }
      ],
      link: [
        {
          rel: 'stylesheet',
          href: 'https://fonts.googleapis.com/css?family=Roboto'
        }
      ]
    }
  }
}
</script>

```
フィールドのアクセス修飾子について

# フィールドのアクセス修飾子について

JavaSilverの学習とマッチングサイト制作時に、フィールドのアクセス修飾子はprivateにするのが基本だということを知ったのをきっかけに、フィールドのアクセス修飾子について調べてまとめてみました。



<!-- 各チャプター -->
<a id="#Chapter1"></a>
# フィールドのアクセス修飾子の定石
フィールドはすべてprivateに指定するのが基本とされています。

privateでフィールドを指定することで外のクラスからは直接アクセスすることを阻止できます。

【privateフィールドの宣言（構文）】

`クラス名.staticフィールド名
`


<a id="#Chapter2"></a>
# privateフィールドにアクセスする方法
privateフィールドにアクセスする方法は、フィールドのある場所が同じクラスのメソッドと他クラスのメソッドで異なります。

## 同じクラスのメソッドからアクセスする方法

同じクラスのメソッドからは「this」を用いてアクセスします。

コード例

```Java
public class Sample {
    
    //privateフィールドの宣言
    private String word;

        public void hello() {
             //「this」を用いて値を変更
            this.word = "Hello Java!!";
        }
}
```
上記のコードではhelloメソッド()で「this」を用いてword変数にアクセスし、値を変更しています。


## 他クラスのメソッドからアクセスする方法
他クラスのメソッドからはgetter/setterを用いてアクセスします。

コード例（getterでフィールド値を取り出す）

```Java
public class Sample {
    
    //privateフィールドの宣言
    private String word;
    
        //インスタンス取得用のメソッド
        public String getWord() {
            return this.word;
        }
}

public class Hello {

        //インスタンス取得用のメソッド
        void talk(Sample h) {
            System.out.println(h.word);
        }
}
```

コード例（setterでフィールドに値を代入する）

```Java
public class Sample {
    
    //privateフィールドの宣言
    private String word;
    
        //インスタンス取得用のメソッド
        public void setWord(String word) {
           this.word = word;
        }
}
```

上記の例のようにフィールドへのアクセスにgetter/setterを使用することで、フィールドへのアクセスの検査や、フィールドの入出力時に必要な処理の追加が行えるようになり、外部からの不作法なアクセスを回避することができるので、Java開発者の間では良く用いられています。


<a id="#Chapter3"></a>
# まとめ
フィールドはすべてprivateに指定するのが基本とされています。

privateのフィールドは以下の方法を行うことで、アクセスすることが出来ます。

・同じクラスのメソッドからは「this」を用いてアクセスする。

・他クラスのメソッドからはgetter/setterを用いてアクセスする。

<br>
<br>
(きつねさんのllvm)実行ファイルdccを生成できなかった時の対処法

<p>/usr/local/llvm/lib/libLLVMSupport.aをリンクすると上手くいく</p>

<p>以下のコマンドを投下した</p>

<code>g++ -g ./obj/dcc.o ./obj/lexer.o ./obj/AST.o ./obj/parser.o ./obj/codegen.o /usr/local/llvm/lib/libLLVMSupport.a `llvm-config --cxxflags --ldflags --libs` -ldl -o ./bin/dcc
</code>
【PHP8】エラー制御演算子の動作に変更が入っている話

PHP7からPHP8に移行する際の小ネタになります。


set_error_handlerで定義したエラーハンドラ関数でエラー処理を行うために、
PHP7で以下のようなコード書いてました。

```php
error_reporting(E_ALL);

set_error_handler(function($errno, $errstr, $errfile, $errline) {
	// ... 処理
	
	// エラー制御演算子『@』付きの場合
	if (error_reporting() === 0) {
		// エラーが E_WARNING もしくは E_NOTICE の場合
		if ($errno === E_WARNING || $errno === E_NOTICE) {
			return;
		}
	}
	
	// ... 処理
});
```

PHP7系以下では、エラー制御演算子が使われている場合のerror_reporting()の返り値は常に0なので、上記コードは期待通りの動きをしていました。

そのままPHP8に移行したのですが、移行後にエラー制御演算子の制御が効かなくなっている事に気が付きました。error_reporting()の返り値を確認してみたところ、

**<font color=red>『4437』！！！</font>**

PHP8でエラー制御演算子の動作の変更が入っていたようです。

というわけで、以下のように書き換えて、めでたしめでたし。
（PHP7でも問題なく動きます、最初からこうしとけばよかった…）

```php
// PHP8ではデフォルトでE_ALLなので書かなくてもいい
error_reporting(E_ALL);

set_error_handler(function($errno, $errstr, $errfile, $errline) {
	// ... 処理
	
	if (!(error_reporting() & $errno)) {
		return;
	}

	// ... 処理
});
```

- エラー制御演算子付きの場合のerror_reporting()の返り値は4437
 - 4437 = E_ERROR + E_PARSE + E_CORE_ERROR + E_COMPILE_ERROR + E_USER_ERROR + E_RECOVERABLE_ERROR
- エラー制御演算子なしの場合のerror_reporting()の返り値は22527
 - 22527 = 4437 + E_WARNING + E_NOTICE + E_CORE_WARNING + E_CORE_WARNING + E_COMPILE_WARNING + E_USER_WARNING  + E_USER_NOTICE + E_USER_DEPRECATED;
MySQLDump で tablespaces の PROCESS privilege エラーが出だした時の対処方法


いつも使っていた MySQL Dump のシェルコマンドで、以下のエラーがでました。

```
mysqldump: Error: 'Access denied; you need (at least one of) the PROCESS privilege(s) for this operation' when trying to dump tablespaces
```

さくらインターネットのスタンダードプランのレンタルサーバーでも、日時バックアップをシェルで動かしているのですが、1月ぐらいから出始め、なんでだろうと思っていました。

原因は MySQL 5.7.31 からの tablespaces の仕様変更によるものらしいです。

[MySQL 5.7.31 のリリースノート](https://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-31.html)によると

> Incompatible Change: Access to the INFORMATION_SCHEMA.FILES table now requires the PROCESS privilege.

> This change affects users of the mysqldump command, which accesses tablespace information in the FILES table, and thus now requires the PROCESS privilege as well. Users who do not need to dump tablespace information can work around this requirement by invoking mysqldump with the --no-tablespaces option. (Bug #30350829)

ということは、さくらインターネットの MySQL サーバーもアップデートが行われたんですね。


## Tablespaces とは

MySQL Dump をする際に、--no-tablespaces オプションを加えると大丈夫のようです。

tabelspaces とは、MySQL 5.6 から加わった機能で、データーベース側で作成されるファイルを任意に指定できる機能のようです。

https://dev.mysql.com/doc/refman/5.7/en/create-tablespace.html

5.6 以前から使われている CMS やアプリケーションは一般的に、 tablespaces の指定をしていないと思われるので、tablespaces 情報が出力されなくても問題はありません。

なので、MySQL 5.7 以前から使われている MySQL を使うアプリケーションで、特に指定が無ければ、MySQL Dump 時に --no-tablespaces オプションを加えると良いでしょう。

## サンプル

```
mysqldump -h [ホスト] -u [DBユーザー名] --password="[DBパスワード]" --no-tablespaces --single-transaction [データベース名] > [保存先.sql]
```

※ `--single-transaction` オプションは InnobDB メインな DBでデータの整合性保つように追加しています。


## 参考 (感謝)

https://isgs-lab.com/424/

https://note.com/jgjugemu/n/n2405d2746c66
【Git】開発の流れと開発の際によく使用するコマンド


# Gitを使用した開発の流れ

###リポジトリのクローン
リモートリポジトリからローカルへリポジトリをクローン(複製)する

```bash:
git clone リポジトリのURL
```
<br>
###ブランチの作成

```bash:
git branch 作成するブランチ名
```

ローカルブランチの一覧を確認

```bash:
git branch
```

リモートブランチの一覧を確認

```bash:
git branch　-a
```

<br>
###ブランチの切り替え
作成したブランチへ切り替える

```bash:
git checkout ブランチ名
```

<br>

###実装
実装内容の確認(変更を行ったファイルの確認)

```bash:
git status
```
<br>

###実装後
変更したファイルをインデックス(ステージング)へ追加する

```bash:
git add ファイル名
```

変更を行ったファイル全てを一括でステージングへ追加する場合

```bash:
git add ./
```

<br>

###コミット

```bash:
git commit -m"コミットメッセージ"
```
コミットのログを確認

```bash:
git log
```

<br>

###リモートへプッシュ

```bash:
git push origin ブランチ名
```
Amazon LinuxにNginxをインストールするScript

Amazon LinuxにNginxをインストールして起動するScriptです。
<br>

検証済環境

```console
$ uname -r
4.14.231-173.361.amzn2.x86_64
```

Script

```shell
#!/bin/sh

sudo yum update
sudo systemctl enable nginx
sudo amazon-linux-extras enable nginx1
sudo yum -y install nginx
sudo systemctl enable nginx
sudo systemctl start nginx.service
```

実行例

```console
$ chmod 700 nginx.sh
$ ./nginx.sh
```
PyInstallerメモ

# 概要
PyInstallerで作ったバイナリに含まれるライブラリを確認する。

# 方法

`pyi-archive_viewer` を実行する。

（`pyi-archive_viewer` はPyInstallerをインストールすると一緒にインストールされる）

## コマンド例

```
$ pyi-archive_viewer <バイナリのパス>
```

ずらずら表示された後に

`O PYZ-00.pyz`

を入力。

含まれているライブラリが一気に表示される。

# まとめ

PyInstallerで作ったバイナリに含まれるライブラリを確認するには、
`pyi-archive_viewer` を使う。

表示が見づらいので良い感じに見る方法があったら知りたい。

# 参考

https://spoonblog.hatenablog.com/entry/2020/12/20/075838
（自分用のメモにこの記事から必要なところを抜き出しただけです、すみません）
【TP転職市場PJ日記その５】バッチ、検索、Twitter連携とかあとDB設計見直しとかとにかくめっちゃやった

#前回は...
検索とか頑張ったねー。そして次回について詳細画面とか評価の見える化について触れてるね。よかったわー何を書くんだっけ？ってなってたから助かった。というか誰がみるんだコレ。と思いながら書く。まぁログだな。
というわけで詳細画面のこんな風にしたよとか他機能とかもぱぱぱっと紹介してく。

#詳細画面
とりあえず物をみてもらお。
![詳細画面.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570502/78336000-b769-5918-c6a9-652d5176328e.png)

TPのチームに所属したい人がデータを登録するとTPの運営チーム側からはこんな感じで見れるように
した。必要な情報を満たしているかは判断難しいけど、ツイートを眺めた感じこんな情報があればなんとかると判断。
ちなみにTPのチームがメンバーを募集する時も項目含めほぼ同じように見えます。
というか項目をちゃんと設けようとするとそれだけで時間がかかるので表現に幅を持たせるようにコメント欄を設けたのでそこで補完してほしいなと思う。

#〇〇を送る系のボタン
これは当初評価が見えるようになったらというニーズを満たすために実装。
ボタンを押すとその人の受信箱に通知が言って「だれ」が「気になった」してくれたのか分かるようにした。
もう一個なんとなく「スカウト」ボタンも追加したが「気になる」と「スカウト」の違いとしては…

**気になる：チームメンバー入りできるかも？もしよかったらどぉ？的な**
**スカウト：チームメンバーに来て！お願い！的な**

ぐらいの切り分けをイメージした。まぁ某転職サービスと同じ感じにしただけｗ
パクってこう。うん。

#受信箱
貼ったスクショの上部のメニューに受信箱を作った。ウイイレでいうところのスキトレとかトレコとかプレゼントが来るやつイメージしたよ＾＾アイコンもそれっぽいの選んだんだ。
んでこれはスカウトとか気になるが来たらこんな感じになる。
![スカウト来たら.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570502/82ca1373-62f9-b1ce-f7c9-49173e611463.png)

一応何件来たかとかもそれとなく分かるようにした。

#受信箱の中身
はい、こんな感じ。
![受信箱.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570502/d0887b72-7f4a-4ca2-12c8-df070ccbae68.png)
種別毎に集計かけて表示する感じにした。
メッセージも書いて送れるように考えたけど、めんどくさいよね？ｗ
相手がどう思ったぐらいが分かればまずは御の字なんじゃないかなって思う。
一応ここからDMのリンク生成させてTwitterのアイコンクリックorタップするとTwitter側のDM送信画面が見えるようになると思う。この辺りは触る人の設定に依存するね。アプリとか入れてると勝手に起動してDM送信画面にいくと思うよ。まぁあとはDM送って仲良くなればいーじゃん。

#ユーザーアカウントもtwitterユーザー名を追加
![users.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570502/3952bb6a-0d13-48b3-ad73-ed18b38e07bb.png)

今回ここが一番おもろかった。とりあえずアカウントの存在有無もチェックするからね。
![errors.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570502/860f71c6-48be-187b-9881-ca188c7bf8e4.png)


#技術的な話
TwitterのAPIについて
今回、twitter連携の機能としてDMが送れるようにしたかったので「http://xxxxx.com 」でアクセスすると
Twitterの情報が取れるようにするためTwitterにAPIを使えるようにしてほしい申請をしたよ。
手順は先人方のブログを拝見しながら申請。

https://dev.classmethod.jp/articles/twitter-api-approved-way/

英語で書くのでグーグル翻訳でパッションを伝えてった。
んで、laravelとTwitter APIの実装は以下の先人記事で実装。
ほんとlaravel便利。

https://qiita.com/shihori_23/items/6c0a8d723fe75530952d

ちなみに今回のDM送信はAPIを経由してDMを送信させるのではなくDMのリンクを生成して
Twitter側の画面でDMを送ってもらう流れにした。というのもTwitterAPIの制限が結構色々とあるので
サービス側で制限を意識すると時間が掛かってしまうのでそこはリンクによる遷移で逃げましたｗ

ちなみにTwitterAPIの制限は↓

https://developer.twitter.com/ja/docs/basics/rate-limits

今回はAPP認証なので（多分）15分で300回も問い合わせするケースはないとおもうんだよなぁ…（汗）

というわけで、次回はメニュー画面とかそこらへんも変えたのでサービスの画面イメージとか貼ってこうかな
あ、あとサーバー構築がそろそろ始まるのでそっちもやります。
ランクマ全然できてない＾＾；

では。
マイクロフロントエンド(MicroFrontEnds)とは

マイクロフロントエンドについての調査をまとめていきます。
今回はマイクロフロントエンドの概要について記します。後にマイクロフロントエンドの実装方法、技術なども投稿します。

# マイクロフロントエンドとは

複雑、肥大化したアプリケーションの開発のため解決策、アイデア。
バックエンドからフロントエンド混合のMicroservicesチームを構成して、それぞれのチームがデータベースから UI に至るまでをすべて実装する。

因みに「Microservice」とはアプリケーションの構成要素を独立したサービス群 (マイクロサービス) へと分け、連携させる手法。

![ad1e0adf-3116-959c-f208-3b290bc06c98.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483460/40eb5d44-a1b0-dad3-4afb-0bafbc42ffae.jpeg)
↑一般的なマイクロサービスの構造 [1]
![d8b91bac-8053-c7c2-8457-c9ea66e53a61.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483460/ea4876c8-6ae0-3801-2c75-c1235ee794ab.jpeg)
↑マイクロフロントエンドの構造 [1]

# マイクロフロントエンドの根底にある考え
使う技術やコードなどの面でそれぞれチーム毎に独立させようという点が重要。

## 技術
各チームは技術において他チームの影響を受けない。
フレームワークに関しても同様で、それぞれのチームがそれぞれに適したReact,Angular,Vue.jsなどのフレームワークを使うことができる。

## コードやルール
技術同様、実際のコードも共有しない。
状態やグローバル変数、コーディングルールなども互いに依存しないよう独立して機能させる。
コンフリクトを避けるためprefixを決めておくとよい。

## ブラウザネイティブの API を使う
コンポーネント間のデータのやりとりには、できるだけブラウザネイティブのイベントを使いましょう。
もしコンポーネント間をつなぐ自作の API が必要ならできるだけシンプルにしましょう。

# 参考
[1] [フロントエンドエンジニアは Micro Frontends の夢を見るか](https://engineering.mercari.com/blog/entry/2018-12-06-162827/)
これが一番分かりやすかったので、これを読めば大体わかります。

[2] [[翻訳記事]マイクロフロントエンド](https://micro-frontends-japanese.org/) 
詳しく書かれています


# この記事について
この記事は[Thinkings株式会社](https://thinkings.co.jp/)にて長期インターンの業務として社内Qiitaに投稿したものを、私の個人用Qiitaに再投稿したものになります。許可を受けて再投稿しております。
また、2020/11/12に社内Qiitaに投稿されたものです。
[AWS_22]RDSを冗長構成にする

##環境
**Amazon Web Service**

* EC2(Amazon Linux 2 , t2.micro , 汎用SSD 8GB)
* RDS(MySQL , db.t2.micro)

**ローカルPC**

* MacBook Pro(2.9 GHz デュアルコアIntel Core i5 , 8 GB 2133 MHz LPDDR3)
* macOS 11.3.1（20E241）

##概要
現状ではRDSがシングル構成となっているため、マルチAZ化して冗長構成とする。
RDSをマルチAZ化すると自動的に以下のことを行なってくれるため、耐久性・可用性が向上する。

* マスターDBインスタンスを作成
* 異なるAZにスタンバイDBインスタンスを作成し、データも複製

##構成図
**Before**
![構成図08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758644/c7b81488-4c78-0e70-d146-b78b01f1f8c8.png)
**After**
![構成図09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758644/4ae3df39-5af0-ceec-0743-8921e5d64deb.png)



##RDSのマルチAZ化
1. 任意のRDSを選択し、`変更`をクリックする。
1. マルチAZ配置: `スタンバイインスタンスを作成する(本稼働環境向けに推奨)`を選択して`続行をクリックする。
1. 変更のスケジューリング: `すぐに適用`を選択して、`DBインスタンスを変更`をクリックする。
1. データベース一覧画面で`マルチAZ`の項目が`あり`になっているか確認する。

##障害試験
1. RDSを再起動する。その際、`フェイルオーバーで再起動しますか?`をチェックを入れて`確認`をクリックする。
1. RDSのステータスがが`再起動中`になっていても、Webページが問題無く開けることを確認する。
1. フェイルーバーの確認として、RDSの`ログとイベント`のタブで以下のようなログがあることを確認する。<br>
**May 25, 2021, 2:30:40 AM UTC　Multi-AZ instance failover started.<br>
May 25, 2021, 2:30:52 AM UTC　DB instance restarted<br>
May 25, 2021, 2:31:05 AM UTC　Multi-AZ instance failover completed**