AWS大阪リージョンが開設されて、なにができるようになるのか?

先日、AWSの大阪リージョンが開設されました。というのを今日知りました。
AWSは、今回の大阪リージョン開設までは、国内には東京リージョンしかありませんでした。大阪リージョンが開設されたことで、どんな利点が生まれるのか?ちょっとだけ調べてみました。
 


1 大阪リージョンとは?

AWS アジアパシフィック(⼤阪) リージョンは⽇本で 2 番⽬、アジア太平洋地域で 9 番⽬、そして世界で 25 番⽬に新たに開設された 3 つのアベイラビリティーゾーン(AZ)を持つ AWS リージョンです。

AWS 大阪リージョン - 2021年3月 誕生! | AWS (アマゾン ウェブ サービス)
 


2 どんな利点があるのか?
 
(1)西日本の利用者は、通信遅延を減らすことができる。
東京リージョンと大阪リージョンは直線距離で約400km離れている。西日本の利用者からすれば、それだけリージョンの距離が縮まったということなので、当然通信遅延が減少する。

(2)東京リージョンと組み合わせれば、国内のリージョンだけで災害・障害に強い冗長化が可能になる。
東京リージョンだけで冗長化していた場合、関東地方で大規模災害が発生した場合、全てのアベイラビリティゾーンがだめになる可能性が高い。2つのリージョンを組み合わせれば、災害や障害発⽣時でも業務を継続させることが要求されるアプリケーションを、国内のリージョンだけで運用することができる。
 
 
 
3 ちょっと聞いた話
 
エンジニアの方には常識なんだと思いますが、知人から聞いて面白いなあと思った話があるので書かせてください。
AWSを導入している企業でも、業界によっては「国内リージョン以外使用できない」ところがあるらしいです。色々な事情で。東京リージョンしかなかった従来のAWSだと、そのような企業はリージョンをまたいだ冗長化が不可能でした。そのために、オンプレミスとAWSを併用したり、VPSAWSを併用したりしていたみたいです。
しかし、今回大阪リージョンが開設されたので、そういった企業も国内のリージョンだけでリージョンをまたいだ冗長化が可能になります。
 
純粋に夢が広がる話だし、AWS関連の仕事も今後増えていきそうだなあと思いました。
 
 
4 結論
 
ポートフォリオやっと形になったところだけど、今後インフラ環境を発展させていくに当たって、是非大阪リージョンを使ってEC2, RDSの冗長化をしたいなあ。
 
 
 
5 参考

AWS上でSpringBootアプリを継続起動させる。

こんにちは、くまごろーです。
前回のブログで、AWSに構築した環境にSpringBootアプリをデプロイするところまでいきました。
ただ、SpringBootアプリに内蔵されたTomcatを使用しているので、現状ではアプリを起動させることはできても、コンソールを閉じてしまえばアプリが停止してしまいます。
当然24時間稼働させた状態にしたいので、今回はその設定についてまとめます。
 
 
 
1 一言でいうと
 
Amazon Linux2で、作成したアプリを「サービス化」してしまえばいいらしい。
httpd」とか「nginx」と同じように。そうすれば

#systemctl start アプリ名

とかのコマンドで起動・停止を管理することができるようになります。
 
 

2 手順
 
(1)アプリを「Fully Executable Jar」という形式のJarファイルにする
「Fully Executable Jar」って?

Spring Bootでは、作成したJARファイルをjava -jarで起動することができますが、UNIX環境でより簡単に起動することができる仕組みです。

 
Spring Bootのサービス稼働環境 - EatSmartシステム部ブログ

通常のJarと違い、サービスとして起動することができる。(らしい)
 
ビルドしたJarファイルをこの形式にするには、pom.xmlタグ内を以下の様に変更する。

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <executable>true</executable>  //ここがポイント
            </configuration>
        </plugin>
    </plugins>
</build>

 
(2).confファイルを作成して、環境変数を設定
上記のJarファイルを格納しているディレクトリに、Jarファイルと同名のconfファイルを作成。環境変数はそこに設定します。
私はRDS(MySQL)への接続設定を環境変数でやっているので、その記述をこちらのconfファイルに移しました。
 
(3)サービスとして登録する
Amazon Linux2では、/usr/lib/systemd/system/にサービスファイルを作成すればサービスとして登録されるみたい。

[Unit]
Description=springboot //サービスの説明
After=syslog.target

[Service]
User=root
ExecStart=/home/application/test.jar //Jarファイルのパス
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target


この時点で、一応systemctlコマンドが使えるようになります。
が、私はこの後かなり苦戦しました。結局jarファイル&サービスファイルの権限・所有者の設定を変更していないのが原因でした(-_-;)
 
 
 
4 参考

AWS(EC2,RDS(MySQL))環境にSpringBootで作成したアプリをデプロイ

こんにちは、くまごろーです。
昨日、やっとAWSで構築した環境に、家計簿アプリをデプロイすることができました!
まだまだ修正するところはたくさんありましたが、ひとまず安心しました(-_-;)
今回のサーバー環境には、RDSにMySQLを導入しており、アプリとRDS内のMySQLをどうやって接続すればいいのかというのが苦戦ポイントでした。
そこら辺の方法をまとめておこうと思います。
 
 
 
1 前提
 
環境構築は済んでいる前提で話します。
今回は、AWS教材ではおなじみの、山浦さんのUdemy講座を参照しました。
www.udemy.com
手順だけでなく、サーバー・ネットワーク関係の基礎知識も説明してくれているのでおすすめです。

インフラ図としてこんな感じです。(合ってるかな・・・?)

f:id:kumaGoro_95:20210226115537p:plain
 
ほぼ、山浦さんの講座の通りに構築しました。
で、その上で以下のミドルウェアを導入しました。

<EC2>
→ nginx(リバースプロキシ設定済)・Tomcat

<RDS>
→ MySQL
 
 
 
2 手順
 
手順は非常に単純でした。

  1. EC2の環境変数を設定して、SpringBootアプリがVPC内のMySQLに接続できるようにする。
  2. アプリケーションをSTSMavenビルドして、jarファイルにする。
  3. jarファイルをTomcatのwebappsフォルダに移動させて実行する。


 
でも、ここまでたどり着くのに結構時間かかりました・・・(-_-;)
 
 
 
3 EC2の環境変数を設定して、アプリがVPC内のMySQLに接続できるようにする。
 
現在のアプリケーションは、ローカル環境のMySQLに接続するよう設定されていると思います。これをAWS環境内のMySQLに繋がるよう設定変更しなければいけません。ここが地味に苦戦ポイントでした。
 
最初私は「application.propertiesの設定をいじって、ビルドすればいいんだよね?」なんて考えてトライしてみたんですが、
ビルドできない!

VPCMySQLは、プライベートサブネットの中に構築されたRDS内にあるので、外からはアクセスできないんですよね。それで接続エラーになっちゃのでビルドできないと。
 
じゃあどうすればいいのか?
なんと、SpringBootアプリのDB接続先は、環境変数で設定できるらしい・・・
本当、ここら辺の知識が無いの痛感しました。
 
以下、手順です。

(1)EC2にログインして、bash_profileを編集する

#vim ~/.bash_profile

(2)以下の環境変数を追加する

export SPRING_DATASOURCE_URL=jdbc:mysql://エンドポイント名:3306/example_db
export SPRING_DATASOURCE_USERNAME=MySQLユーザー名
export SPRING_DATASOURCE_PASSWORD=MySQLパスワード
export SPRING_DATASOURCE_DRIVER_CLASS_NAME=com.mysql.jdbc.Driver

(3)編集結果を反映させる

#source ~/.bash_profile


※ ちなみに、環境変数はこのコマンドで確認できます。

#printenv




4 アプリケーションをSTSMavenビルドして、jarファイルにする。

[プロジェクト名を右クリック]>[実行]>[Mavenビルド] で、アプリをjar化します。
生成されたjarファイルは、targetフォルダに格納されます。
 
 
 
5  jarファイルをTomcatのwebappsフォルダに移動させて実行する。
 
以下のコマンドでjarファイルを実行。

java -jar ファイル名

 
これで、URLを叩けばデプロイしたアプリケーションが表示されるはず・・・


6 参考


 
 

【Spring Boot】Thymeleafで日時の表示形式を調整する方法

こんにちは、くまごろーです。
今日は、Thymeleafでの日時の表示形式を調整する方法についてまとめます。
 
 
 
1 やりたいこと

DBに、以下の様な形式で日時データが格納されているとします。

<DB>

2021-02-22 15:23:05.000000

これを、「2021-02-22 15:23」といった形に成形して表示したい場合、どうすればいいのか?
 
 
 
2 #temporalsを使用する
 
Thymeleafには、ユーティリティオブジェクトという、コーディングの手助けとなるオブジェクトが実装されています。(これ最近まで知らなかった・・・)
今回は、「#tempolars」というオブジェクトを使用します。
#temporalsは、LacalDateやLocalDataTimeを扱うことができるユーティリティメソッド群です。

<基本コード>

#temporals.format(time, 'yyyy-MM-dd HH:mm')}


こんな風に書くと

投稿日時:[[${#temporals.format(post.createdAt, 'yyyy-MM-dd HH:mm')}]]

こういう感じで出力されます。

投稿日時:2021-02-22 14:28


これ以外にも色んな使い方があるらしい。

コード ふるまい
${#temporals.format(time, 'yyyy/MM/dd HH:mm:ss')} 日付を自由にフォーマット
${#temporals.year(date)} 年を取得
${#temporals.month(date)} 月を取得
${#temporals.day(date)} 日を取得
${#temporals.dayOfWeekName(date)} 曜日を取得
${#temporals.hour(time)} 時間を取得
${#temporals.minute(time)} 分を取得
${#temporals.second(time)} 秒を取得

 
 
 
3 参考

英語でLTやってみた。

こんにちは、くまごろーです。

先日、所属しているコミュニティで開催された英語LTに登壇してみました。
今までLTは何度かやってきましたが、英語のLTは初めて。
半ば勢いで挑戦してみた英語での発表でしたが、結果的には最高でした。英語LT、色んな面でメリットがすごいです。
今日はそれについて話します。
 
 
 
1 「英語に挑戦」という面で、意外とハードルが低い
 
 LTは5分です。たったの5分。話す内容は事前に決めることができ、スライドもあらかじめ用意できます。

私自身がそうなんですが、英語でのコミュニケーションが苦手な人が不安なのは

  • 「相手の話が聞き取れなかったらどうしよう」
  • 「返事を英語で思いつかなかったらどうしよう」

とかだと思うんですよね(=_=)

その点では、LT発表はかなりハードル低めです!(質疑応答まで英語だったらちょっと厳しいですが)
不安ならしっかり原稿を準備して臨めばいいし、スライドを充実させて自分の助けにすることもできます。

「ゆくゆくは不自由なく英語で話せるになりたいけど、挑戦の場が・・・」という方におすすめだと思いました。
 
 
 
2 日本語以上に、発表テーマへの理解が必要
 
今回、私は軽い気持ちでテーマに「アセンブリ言語」を選びました・・・(-_-;)
私自身、アセンブリについての知識はほぼなくて、「アセンブリ言語を全く知らない人に、その概要を説明する」といったコンセプトでの発表を目指していました。
日本語の資料を読んで、「なんとなく理解できたかな」と思って英語でスライド&原稿を用意し始めると、全然うまく行かないんですよね笑
母国語で「なんとなく」のニュアンスで理解している部分が、英語に切り替えるとどんどん浮かび上がってくるんです。
結果、想像以上にLT準備に時間がかかってきつい思いをしましたが、これはすごい勉強になると実感しました。
 
 
 
3 英語の資料に対する抵抗感が減少する

最初の内は、日本語の書籍・記事から情報を集めてました。
でも、英語でスライド・原稿を作成しているのに、日本語の資料から情報を収集するのって手間じゃないですか?
というわけで、自然と英語の記事を参照するようになります。苦手意識なんてすぐに消し飛びます(=゚ω゚)ノ
Spring Bootやってると、日本語の記事が少なすぎて結局英語記事から答えを引っ張ってくるなんてことがよくあるんですが、今回のLT準備で英語記事への抵抗感が更に減りました。
 
 
 
4 まとめ
 
軽い気持ちで挑戦して、大変な思いをした初英語LTでしたが、得るものが多い体験でした!また近いうちに、今度はJavaやSpringBootをテーマにして挑戦したいなと思います(=゚ω゚)ノ
 
 
<今回のスライド>

【Spring Boot】リダイレクト先のURLを指定するには

こんにちは、くまごろーです。
今日は、リダイレクトについてまとめます。
  
 
1 何をしたいのか
 
こういうような、投稿詳細画面があったとします。
f:id:kumaGoro_95:20210214171623p:plain
 
で、URLにリクエストパラメータとして投稿IDが付加されているとする。

http://localhost:8080/post/{postId}

投稿ID1番ならURLは「http://localhost:8080/post/1」、2番なら「http://localhost:8080/post/2」になる。

コメント投稿実行時に、同ページにリダイレクトさせたい場合、どうすればいいんだろうか?となったんですね。
 

<試してみたコード>

//コメント投稿処理
@PostMapping("/postComment")
  public String postComment(@Validated @ModelAttribute("comment") PostComment comment, BindingResult result,
    Authentication loginUser, UriComponentsBuilder builder) {
		
  /*コメント投稿処理*/

  return "redirect:/post/{postId}?postComment"
}


この方法だと、リダイレクトが無限ループしてしまうらしく、エラーになってしまいました。
 
 
 
2 解決策
 
UriComponentsBuilderというクラスでURLを組み立てることができるらしい。

@PostMapping("/postComment")
  public String postComment(@Validated @ModelAttribute("comment") PostComment comment, BindingResult result,
    Authentication loginUser, UriComponentsBuilder builder) {
		
  //リダイレクト先を指定
  URI location = builder.path("/post/" + comment.getPostId()).build().toUri();
		
  //コメント投稿処理

  return "redirect:" + location.toString();

}

 
URIインスタンスでURLを組み立てたことで、投稿ID1番へのコメントなら「localhost:8080/post/1」へ、2番へのコメントなら「localhost:8080/post/2」へリダイレクトさせられるようになりました!
 
 
 
3 参考
Spring Bootでリダイレクト先のURLを組み立てる - Qiita

【SpringBoot】一つのFormで、二つのModelAttributeをコントローラーに渡すには

こんにちは、くまごろーです。
今日はちょっとイレギュラーなFormの使い方についてまとめます。
 
今まで作成したFormは「1つのFormで、1つのインスタンスの情報を送る」という形式のものだったのですが、(ログインフォームとか)
アプリを作っている中で、「1つのFormの中に、2つのインスタンスの情報が含まれている」Formが欲しいという状況になりました。
わかってしまえば簡単だったんですが、最初かなり調べまくったので、ここでまとめようと思います。
 
 
 
1 どういう状況か
 
今回はこんな感じの状況でした。
ユーザー設定変更のフォームなんですが、
 
f:id:kumaGoro_95:20210210173750p:plain
  
下記の様な方法で処理したいと考えていました。
 

  • アップロードした画像は、ファイル専用のインスタンスとして送りたい。

 
 
 
2 Controllerクラス
 
結果的にすごいシンプルな方法でいけました。
 

@Transactional
@PostMapping("/setting")
public String process(@Validated @ModelAttribute("user") SiteUser user, BindingResult result, @ModelAttribute("file") FileUploadForm file, HttpServletResponse response,
			Authentication loginUser, RedirectAttributes redirectAttributes) {
//処理内容は省略
}

 
かなり長ったらしいですが・・・

public String process(@Validated @ModelAttribute("user") SiteUser user, BindingResult result, @ModelAttribute("file") FileUploadForm file, ) {

上記のように、とりあえず@ModelAttributeアノテーションを付けて並置すればOKです。
 
 
 
3 viewクラス

↑に対するhtmlファイルがこれ。
 

<form enctype="multipart/form-data" th:action="@{/setting}" method="post" novalidate>
  <div class="file-field input-field">
  <div class="btn">
  <span>アイコン画像選択</span> 
  <input type="file" th:field="${file.uploadedFile}"></div>
  <div class="file-path-wrapper">
  <input class="file-path validate" type="text"  th:field="${user.icon}"></div></div>

  <input type="hidden" name="username" th:value="${user.username}" />
  <input type="hidden" name="createdAt" th:value="${user.createdAt}" />
  <input type="hidden" name="role" th:value="${user.role}" /> 
  <input type="hidden" name="password" th:value="${user.password}" />
	
  <div class="form-group">
  <label for="name">ユーザー名(2文字以上20文字以内) </label>
  <input type="text"th:errorclass="is-invalid" th:field="${user.userNickname}">
  <div class="invalid-feedback" th:errors="${user.userNickname}"></div>
  </div>
 
<!-- 略 -->

  <button class="btn setting-update">更新</button>
</form>

 
 
本当にくだらない話なんですが、私Formで情報を送信するときは、必ずformタグに

th:object="${user}"

みたいに、特定のインスタンスを指定しなきゃいけないと思ってたんですよ(=_=;)
だから、「1つのフォームで複数のインスタンスの情報送るのは無理じゃない?」と思ってたんですが・・・
 
何はともあれ、うまくいってよかったです。
 
 
 
4 参考