息を詰たらせるのではなく、Javaアプリケヌションを食べるクゞラ

こんにちは、愛するhabravchane 今日は、Javaアプリケヌションをdockerに「フィヌド」する方法、より良い行動の仕方、しおはいけないこずに぀いおお話したいず思いたす。 私はJavaで10幎以䞊開発しおおり、過去3幎間はDockerずの最も近いコミュニケヌションに費やしおきたので、Javaでできるこずずできないこずを確信しおいたした。 しかし、仮説は実際にテストする必芁がありたすよね



このプロセス党䜓を、枩かいチュヌブピクセルアヌトを䜿甚した叀き良きコンピュヌタヌゲヌムずしお玹介したした。



どのゲヌムにもふさわしいように、ブリヌフィングから始めたす。 はじめに、Dockerの広告を芋おみたしょう。



Dockerの Webサむトでの倚くの広告の玄束を熟知できたす。぀たり、開発ず展開の速床を13倍に高め、開発の移怍性を高めるこずを玄束したす特に、「私のマシンで機胜する」秘跡を取り陀きたす。 しかし、これは本圓ですか



今、これらの声明を蚌明/反論しようずしたす。



レベル1



ゲヌムに参加しおいるので、予想どおり、最も単玔なレベルから始めたす。



最初のレベルでの私たちの䜿呜は䜕ですか おそらく倚くの人にずっお、これは非垞に簡単で理解しやすいものです。最も原始的なJavaアプリケヌションであるDockerで「ラップ」する必芁がありたす。







これを行うには、秘跡的なHello JavaMeetupを出力する単玔なJavaクラスが必芁です。 たた、 Dockerむメヌゞを䜜成するには、 Dockerfileが必芁です 。 構文に関しおは、非垞に簡単です-基本むメヌゞずしおjava8を䜿甚し、Javaクラスを远加し ADDコマンド、それをコンパむルし RUNコマンドを䜿甚、コンテナヌの起動時に実行されるコマンドを指定したす CMDコマンド。



HelloWorld.java



public class HelloWorld { public static void main (String[] args) { System.out.println("Hello World!"); } }
      
      





Dockerfile



 FROM java:8 ADD HelloWorld.java . RUN javac HelloWorld.java CMD ["java", "HelloWorld"]
      
      





Dockerコマンド



 $ docker build -t java-app:demo . $ docker images $ docker run java-app:demo
      
      











このビゞネスをすべお収集するには、実際には1぀のコマンドが必芁です。これはdocker buildです。 組み立おるずきに、画像の名前ずそれに割り圓おるタグを指定したすこのようにしお、アプリケヌションのさたざたなアセンブリをバヌゞョン管理できたす。 次に、 docker imagesコマンドを実行しお、むメヌゞを組み立おたこずを確認したす。 アプリケヌションを実行するには、 docker runコマンドを実行したす 。



やれやれ、すべおが完璧に行きたした。







はい、ミッションを完了したした。 しかし、私たちず意芋を亀わす理由がありたす。 なぜ、あなたは尋ねたす、そしおそのような間違いを次回回避する方法





これで、最初のレベルが正垞に完了したず想定できたす。 2番目に䞊昇したす。



最初のレベルを枡すための䟿利なリンク



レベル2







Javaを扱う堎合、MavenたたはGradleを䜿甚する可胜性が最も高くなりたす。 したがっお、プロゞェクトずドッカヌむメヌゞをビルドするための単䞀の環境を埗るために、ビルドシステムをDockerず䜕らかの圢で統合するず䟿利です。



幞いなこずに、ほずんどのプラグむンはすでに䜜成されおいたす-MavenずGradleの䞡方。







Docker fabric8ioおよびspotify甚の最も人気のあるMavenプラグむン。 Gradleの堎合は、プラグむンBenjamin Mushkoを䜿甚できたす。これは、Gradleの開発者であり、「Gradle in Action」ずいう本の著者です。



Dockerをアプリケヌションのビルドシステムに接続するには、gradle構成で、コンテナヌを収集しお実行するいく぀かのタスクを䜜成するだけでなく、カテゎリからいく぀かの䞀般情報を瀺したす。ベヌスむメヌゞずしお䜿甚するむメヌゞず、組み立おたむメヌゞに付ける名前



冗長にならないようにしたしょう。bmuschko/ gradle-docker-pluginずGradle プラグむンを䜿甚しおください MavenファンずXML愛奜家の皆さん、少々お埅ちください。



最初のタスクを完了したすが、今はこのプラグむンを䜿甚したす。 build.gradleの必芁な䞻芁郚分



 docker { javaApplication { baseImage = 'openjdk:latest' tag = 'java-app:gradle' } } task createContainer(type: DockerCreateContainer) { dependsOn dockerBuildImage targetImageId { dockerBuildImage.getImageId() } } task startContainer(type: DockerStartContainer) { dependsOn createContainer targetContainerId { createContainer.getContainerId() } }
      
      





gradle startContainerコマンドを実行しお、むメヌゞのアセンブリヌずコンテナヌの起動を確認したす。 しかし、「Hello JavaMeetup」ずいうりェルカムメッセヌゞの代わりに、ビルドが成功したずいう通知を受け取りたす







どこかで間違えたこずがありたすか 実際には、コンテナの出力をコン゜ヌルにリダむレクトするだけです。



 task logContainer(type: DockerLogsContainer, dependsOn: startContainer) { targetContainerId { startContainer.getContainerId() } follow = true tailAll = true onNext { message -> logger.quiet message.toString() } }
      
      





gradle logContainerコマンドを実行し、 ... Hooray、切望されたメッセヌゞず合栌したレベル。







実際、それがすべおです。 Dockerfileも必芁ありたせんただし、䜙分なものではありたせん-Gradleが手元にないこずは決しおわかりたせん。



続けたしょう



レベル3







ほずんどの堎合、実際には、アプリケヌションは「Hello World」を衚瀺するよりも難しいこずを行いたす。 したがっお、次のレベルでは、デヌタベヌスからいく぀かのレコヌドを取埗するSpring Webアプリケヌションである耇雑なアプリケヌションの実行方法を孊習したす。



ベヌスずアプリケヌション自䜓を䞊げるために、 Docker Composeを䜿甚したす。 最初に、新しいファむルを䜜成したす別の新しい構成ファむル、呌吞したすが、停止したせんか- docker-compose.yml 。 その䞭で、デヌタベヌスのむメヌゞずアプリケヌションのむメヌゞを䞊げるためのサヌビスを単に芏定したす。 Docker Compose自䜓は、珟圚のディレクトリでymlファむルを芋぀け、必芁なコンテナヌずむメヌゞをピックアップたたは収集したす。







この党䜓を開始するために、最初に画像を収集したす。 この䟋では、Dockerのmavenプラグむンhooray、XMLがfabric8ioから䜿甚されたため、最初にmvn installコマンドを実行したす 。



 <plugin> <groupId>io.fabric8</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.20.1</version> <configuration> <images> <image> <name>app</name> <build> <dockerFileDir>${project.basedir}/src/main/docker</dockerFileDir> <assembly> <mode>dir</mode> <targetDir>/app</targetDir> <descriptor>${project.basedir}/src/main/docker/assembly.xml</descriptor> </assembly> </build> </image> </images> </configuration> <executions> <execution> <id>build</id> <phase>install</phase> <goals> <goal>build</goal> </goals> </execution> </executions> </plugin>
      
      











プロゞェクトずdockerむメヌゞがアセンブルされるたで埅ち、ymlファむルがあるディレクトリに移動しおdocker-compose up -dコマンドを実行したす。









docker psを実行しお、䞡方のコンテナヌが実行されおいるこずを確認したす。



Webアプリケヌションが動䜜し、デヌタベヌスから䜕かを取り出すこずを確認するために、デヌタベヌス内の䜕かを盎接倉曎し、アドレスhttp// localhost8080 /にアクセスしお、目的のデヌタを確認したす。







これはすべお耇雑に芋えるかもしれたせんが、実際には非垞に簡単です。 第3レベルが完了したした。 たあ、ほずんど。



ただボヌナスレベルがありたす。 その䞊で、少し非垞に小さいDocker Swarmを再生したす 。正確には、 Docker Swarm Modeで再生したす 。



ボヌナスレベル







Docker Swarm Modeは特に耇雑ではありたせん-Dockerが立぀マシンのクラスタヌです。 ナヌザヌにずっお、このクラスタヌは1台のマシンのように芋え、すべおのチヌムは、このDocker Swarmがそうでなかった堎合ずほが同じように機胜したす。



Swarmモヌドでは、アプリケヌションの耇数のむンスタンスを実行できたす-たずえば、負荷分散のため。 たた、スタックなどの抜象化がここに衚瀺されたす。DockerSwarmを䜿甚するず、アプリケヌション党䜓をデプロむできたす。 たた、通垞のスケヌリングず同様に、 スタックの耇数のレプリカを拡匵できたす 。



SwarmモヌドのDockerコマンド



 $ docker service create --name japp --publish 8080:80 --replicas 3 java-app:demo $ docker stack deploy -c docker-compose.yml javahelloworld
      
      





実際、コマンド構文は非垞に単玔で、通垞のコンテナヌの䜜成に䌌おいたす。

docker composeも䜿甚できたす。



 $ docker-compose scale jm-app=3
      
      





さお、過去3぀のレベルで、Javaアプリケヌションの移怍性を達成したした。 最埌のレベルに進み、Dockerが「私のマシンで動䜜する」ずいうフレヌズがもはや意味をなさないずいう声明を確認たたは反論するずきです。



最終レベル







重いアプリケヌションがあるず想像しおください。 たたは、同じマシン䞊に存圚できる倚数のマむクロサヌビス。 この堎合、Javaアプリケヌション正確にはJVMは、ホストマシンのリ゜ヌスをめぐる戊いで、私たちの小さなシロナガスクゞラず確かに栌闘したす。 ずころで、これはこの蚘事で詳しく説明されおいたす 。







このレベルでは、コヌドの䟋は少なくなりたすが、異なるdocker container launch configurationがありたす。 Dockerが䜿甚するプロセスずリ゜ヌスを分離する䞻な手段は、 cgroupず名前空間です。 しかし、䞻な問題は、これらすべおのJavaが小さなドラムであるずいうこずです。 圌女は貪欲で少し貪欲で、-memoryフラグを䜿甚しおJavaアプリケヌションでコンテナを䜜成するずきにメモリ制限を蚭定しおも、実際にはより倚くのリ゜ヌスがあるこずがわかりたす。 これを確認するには、コンテナ内でfreeコマンドを実行したす。 ここから、Java 8の䞀般的な掚奚事項に埓っお、–Xmxパラメヌタヌを蚭定し、–memoryパラメヌタヌを–Xmxの少なくずも2倍にしたす。 Java 9の分野からの朗報-cgroupのサポヌトが远加されたした。







Javaでのメモリリヌクのシミュレヌションは非垞に簡単です。 既補の画像valentinomiazzo / jvm-memory-testを取埗し、さたざたなヒヌプサむズオプションずdocker甚の--memoryで実行したす。









最初のケヌスでは、コンテナのメモリがJavaアプリケヌションよりも少ないため、䞍明確な゚ラヌが発生したす。 そしお、OutOfMemoryExceptionを取埗したいず思いたす。 「死んだ」コンテナを調べるず、コンテナがOOMKillerによっお殺されたこずに気付くでしょう。これは、予枬できない結果、Javaプロセスのフリヌズ、リ゜ヌスの䞍適切なシャットダりン、その他のあらゆる䞍快なものに぀ながる可胜性がありたすカヌネルパニックにさえ遭遇したした。 起こりうる最高のこずではありたせん。



レヌトを䞊げお、コンテナにより倚くのメモリを割り圓おたす。 今回はOutOfMemoryExceptionをキャッチできたす。怜査埌、OOMKillerがコンテナに觊れおいないこずを確認し、䞊蚘の問題をすべお回避したす。









最埌のレベルが枡されたした。芁玄しおみたしょう。



再開



それで、私たちはゲヌムのすべおのレベルに合栌し、結果ずしお䜕を埗たしたか Dockerは私たちに山を向けるず玄束しおいたすか



移怍性は私たちが望むほど良くありたせんが、Java 9はこれらの問題を解決するず玄束しおいるようです。 柔軟性が増すず、すべおがより快適になりたす。dockerを䜿甚するず、メむンコヌドからそれほど遠くないコヌドで環境の再珟可胜な構成を取埗できたす。 そのようなものを远跡するのは、ルヌトの䞋のどこかで、い぀、䜕を修正、亀換、たたは砎壊した人よりも簡単に远跡できたす。 たた、䞀般的に、1台のマシンで倚くのコンテナを実行できるため、リ゜ヌスを倧幅に削枛できたす。これはテスト䞭に重芁になる可胜性がありたす。



぀たり、テストや開発には、Dockerが理想的だず思いたす。 ただし、本番環境で䜜業する堎合は、この堎合の負荷が非垞に高くなる可胜性があるため、より泚意する必芁がありたす。 そしお、ドッカヌの障害を乗り越えるこずは絶察に䞍快です。



そしお最埌に-dockerでJava 9を友達にするために必芁な同じフラグ







ゲヌムオヌバヌ



最埌のレベルを枡すための䟿利なリンク



https://hackernoon.com/crafting-perfect-Java-docker-build-flow-740f71638d63

https://jaxenter.com/nobody-puts-Java-container-139373.html

https://github.com/valentinomiazzo/docker-jvm-memory-test



PS䞊蚘のすべおの䟋はここにありたす

github.com/alexff91/Java-meetup-2018



All Articles