Spring Boot(Jar)ファイルをAzure App Serviceにデプロイしてみました
以下の記事を参考にSpring Boot(Jar)ファイルをAzure App Serviceにデプロイしてみました。
Maven と Azure を使用して Spring Boot JAR ファイルのアプリをクラウドにデプロイする | Microsoft Docs
ポイントは、Azure CLIでpomを書き換えるところです。
ここでデプロイ先、モジュール(Jar/War)を決めることができます。後はデプロイするだけです。
Azure CLI のインストールは以下を参照してください。 Azure CLI のインストール | Microsoft Docs
spring-bootのサンプルアプリを使うので簡単に試すことができました。
手順
$ git clone https://github.com/spring-guides/gs-spring-boot $ cd gs-spring-boot/complete # ビルド & 実行 $ ./mvnw clean package $ ./mvnw spring-boot:run # 動作確認します $ curl http://localhost:8080 # pom のbuildセクションに追加します。 $ cat pom.xml <plugin> <groupId>com.microsoft.azure</groupId> <artifactId>azure-webapp-maven-plugin</artifactId> <version>1.6.0</version> </plugin> $ ./mvnw azure-webapp:config [INFO] Scanning for projects... [INFO] [INFO] -----------------< org.springframework:gs-spring-boot >----------------- [INFO] Building gs-spring-boot 0.1.0 [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- azure-webapp-maven-plugin:1.6.0:config (default-cli) @ gs-spring-boot --- [WARNING] The plugin may not work if you change the os of an existing webapp. Define value for OS(Default: Linux): 1. linux [*] 2. windows 3. docker Enter index to use: Define value for javaVersion(Default: jre8): 1. jre8 [*] 2. java11 Enter index to use: Define value for runtimeStack(Default: TOMCAT 8.5): 1. TOMCAT 9.0 2. jre8 3. TOMCAT 8.5 [*] 4. WILDFLY 14 Enter index to use: 2 Please confirm webapp properties AppName : gs-spring-boot-1559091271202 ResourceGroup : gs-spring-boot-1559091271202-rg Region : westeurope PricingTier : Premium_P1V2 OS : Linux RuntimeStack : JAVA 8-jre8 Deploy to slot : false Confirm (Y/N)? : Y # pomのpluginセクションに追加されていることを確認します。 # デプロイします $ ./mvnw clean package $ ./mvnw azure-webapp:deploy
Home - Microsoft Azureにデプロイされていることを確認しブラウザでアクセスしてみます。
以下の画面が表示されれば成功です。
GraalVMを試してみました
遅まきながら、GraalVMのサイトのGetting Startを試してみました。
試してみるようdockerイメージが用意されています。Docker Desktopをインストール済みであればこれを使うのが簡単です。
サイトには、Node、Ruby、Pythonを使ったサンプルもありますがまずはJavaで試してみました。
手順
# docker image取得 $ docker pull oracle/graalvm-ce:19.1.1 # docker imageに接続 $ docker run -it oracle/graalvm-ce:19.1.1 bash bash-4.2# # 気持ち的にrootにファイルは作成しにくい bash-4.2# cd home # "Hello Word!"を出力するjavaファイル作成 bash-4.2# vi HelloWorld.java bash-4.2# cat HelloWorld.java public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } bash-4.2# javac HelloWorld.java bash-4.2# java HelloWorld Hello, World! # native-imageを作成 # デフォルトでは入っていないのでダウンロードする bash-4.2# install native-image bash-4.2# native-image HelloWorld bash-4.2# ./helloWorld Hello, World! # バイナリをhexdumpする # elfファイルになっている。 bash-4.2# hexdump -C helloworld | head 00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| 00000010 02 00 3e 00 01 00 00 00 00 10 40 00 00 00 00 00 |..>.......@.....| 00000020 40 00 00 00 00 00 00 00 d0 0c 23 00 00 00 00 00 |@.........#.....| 00000030 00 00 00 00 40 00 38 00 09 00 40 00 26 00 25 00 |....@.8...@.&.%.| 00000040 06 00 00 00 05 00 00 00 40 00 00 00 00 00 00 00 |........@.......| 00000050 40 00 40 00 00 00 00 00 40 00 40 00 00 00 00 00 |@.@.....@.@.....| 00000060 f8 01 00 00 00 00 00 00 f8 01 00 00 00 00 00 00 |................| 00000070 08 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00 |................| 00000080 38 02 00 00 00 00 00 00 38 02 40 00 00 00 00 00 |8.......8.@.....| 00000090 38 02 40 00 00 00 00 00 1c 00 00 00 00 00 00 00 |8.@.............| # ファイルサイズ bash-4.2# ls -l total 2256 -rwxr-xr-x 1 root root 2299472 Jul 21 01:23 helloworld -rw-r--r-- 1 root root 427 Jul 21 01:20 HelloWorld.class -rw-r--r-- 1 root root 116 Jul 21 01:20 HelloWorld.java # 実行時間 bash-4.2# time ./helloworld Hello, World! real 0m0.002s user 0m0.000s sys 0m0.000s bash-4.2# java HelloWorld Hello, World! bash-4.2# time java HelloWorld Hello, World! real 0m0.076s user 0m0.060s sys 0m0.000s
以下の記事はJavaフレームワークをnative-imageで起動した結果です。今後の動きから目が離せません。
あと、同じ著者が書いたこの記事も参考になります。 native-imageとJITは同程度だと思っていたのですが、JITの方がこんなに早いとは思いませんでした。
pyOxidizerを試しててみました
以下のページを参考にしてpyOxidizerを試してみました。 PyOxidizer を試してみた - Qiita
python環境を持ち運ぶ(repl)として使うとか、アプリをpythonをインストールしていない環境で実行するなど使い道はありそうです。
環境
macOS Mojave 10.14.5
事前準備
rust環境をインストールする必要があります。 homebrewでインストールした場合pyOxidizerに必要なモジュールがインストールされないので、rustセットアップシェルを実行しました。
$ curl https://sh.rustup.rs -sSf | sh
アプリ環境作成
$ pyoxidizer init pyapp
pythonファイル作成
パッケージのルートディレクトに作成します。
$ cat helloworld.py print("hello world")
設定ファイル()編集
$ cat pyoxidizer.toml # Package .py files discovered in a local directory. [[packaging_rule]] type = "package-root" path = "." packages = ["helloworld"] [[embedded_python_run]] # Run an interactive Python interpreter. #mode = "repl" <-- init時にはここが有効になっています # Import a Python module and run it. mode = "module" module = "helloworld" #module = "mypackage.__main__"
ビルド & 実行
$ pyoxidizer build $ pyoxidizer run packaging application into /.../pyapp/build/apps/pyapp/debug purging /.../pyapp/build/apps/pyapp/debug copying /.../pyapp/build/target/x86_64-apple-darwin/debug/pyapp to /.../pyapp/build/apps/pyapp/debug/pyapp resolving packaging state... pyapp packaged into /.../pyapp/build/apps/pyapp/debug hello world
ファイルサイズは約27M。
$ ls -l build/target/x86_64-apple-darwin/debug/pyapp -rwxr-xr-x 2 unokun staff 27291660 7 14 09:23 build/target/x86_64-apple-darwin/debug/pyapp
リンク
SwiftUIチュートリアル(Landmarks)を試してみました
Windows版Leelaを使って見ました
AWS Cloud9に移行しました
Cloud9が終了するということでAWS Cloud9に移行しました。 とても親切な移行手順だったので特に困ることはありませんでした。
12月まで使えると思っていましたので、6月30日に使えなくなるのに驚きました。
メールはちゃんと読まないといけませんね....
we plan to discontinue the ability to create new or to use existing workspaces on c9.io on June 30, 2019 and to discontinue all access on December 31, 2019. We would love it if you would join us on AWS Cloud9.
同時ログイン禁止(後勝ち)
実装
Spring Web Applicationで同時ログイン禁止(後勝ち)を実装するためには、WebSecurityConfigurerAdapterで以下の記述をする。
Spring Security 使い方メモ セッション管理 - Qiita
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests().antMatchers("/", "/home").permitAll().anyRequest().authenticated() .and().formLogin() .loginPage("/login").permitAll() .and() .logout().permitAll() .and() .sessionManagement().maximumSessions(1) .maxSessionsPreventsLogin(false) .expiredSessionStrategy(new MySessionInformationExpiredStrategy()); } } public class MySessionInformationExpiredStrategy implements SessionInformationExpiredStrategy { @Override public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException, ServletException { DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); redirectStrategy.sendRedirect(event.getRequest(), event.getResponse(), "/login"); } }
動作
- ブラウザAでログイン
- ブラウザBでログイン
- ブラウザAでログイン後ページを更新 ブラウザAはログイン画面に遷移する。
ただし、ブラウザのタブで同時ログインした場合は、同じセッションIDを使い回すので、この方法ではできない。
java – Spring Securityで複数のブラウザタブを管理できますか? - コードログ
また、UsernamePassword認証をカスタマイズしている場合、UsernamePassword認証のFilterの方が先に実施されるため、この方法(セッション管理)は期待通りの動きにならない。
UsernamePassword認証Filterより前に実行されるようにできれば良いのだが...。
以下はMySessionInformationExpiredStrategyが実行されている場合のスタックトレース。