---
title: 既存のTomcatユーザーが1アプリ1組み込みサーバーなマイクロサービスアーキテクチャ時代に簡単に追いつく方法
tags: ["Java", "Tomcat"]
categories: ["Middleware", "AppServer", "Tomcat"]
date: 2014-05-14T04:49:24Z
updated: 2014-05-14T04:49:24Z
---

**(2015-05-08追記) こんな記事書いていたけど、いま思うと実行可能なjar/war作るだけで"マイクロサービス"だとか言っちゃうなんで笑っちゃいますね。**

----

Javaのアプリケーションサーバーに(複数)アプリをデプロイしていく時代はもう終わったと言われ始めています。

<iframe src="http://www.slideshare.net/slideshow/embed_code/33115560" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px 1px 0; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="https://www.slideshare.net/ewolff/java-application-servers-are-dead" title="Java Application Servers Are Dead!" target="_blank">Java Application Servers Are Dead!</a> </strong> from <strong><a href="http://www.slideshare.net/ewolff" target="_blank">Eberhard Wolff</a></strong> </div>

ぼくも1月のJJUGナイトセミナーで「"war" is over」と宣言しましたね。

<iframe src="http://www.slideshare.net/slideshow/embed_code/30247918" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px 1px 0; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="https://www.slideshare.net/makingx/spring-4spring-boot-spring-jjug-jsug" title="Spring4とSpring Bootで作る次世代Springアプリケーション #jjug #jsug" target="_blank">Spring4とSpring Bootで作る次世代Springアプリケーション #jjug #jsug</a> </strong> from <strong><a href="http://www.slideshare.net/makingx" target="_blank">makingx</a></strong> </div>

### マイクロサービスアーキテクチャとは

1アプリ1組み込みサーバー構成は、Martin Fowlerらが書いた[マイクロサービスアーキテクチャ](http://martinfowler.com/articles/microservices.html)に向いています。

[microservices.io](http://microservices.io/)にまとまっていますが、図を見ると分かりやすいです。

これまでの伝統的な、1つのAPサーバーに複数のアプリをデプロイする方法は[モノシリックアーキテクチャ](http://microservices.io/patterns/monolithic.html)と説明されています。

![モノシリックアーキテクチャ](http://microservices.io/i/DecomposingApplications.011.jpg)

そして、小さい粒度でサービスを分割し、それぞれのサービスが1つのサーバーをもつ(複製すると複数だけど)のが[マイクロサービスアーキテクチャ](http://microservices.io/patterns/microservices.html)です。

![マイクロサービスアーキテクチャ](http://microservices.io/i/DecomposingApplications.027.jpg)

モノシリックアーキテクチャに対して、マイクロサービスアーキテクチャは

* 個々のサービスが小さいので開発しやすい
* 特定のサービスだけバージョンアップしやすい
* スケーラビリティが高い
* 1サービスで障害が起きた場合に、そこだけ切り離しやすい

などのメリットがあります。（反面、結合テストが大変などのデメリットもありますが・・）

上記の記事ではNetflix, Amazon,eBayなどがモノシリックアーキテクチャからマイクロサービスアーキテクチャに変わったと書かれています。

このようなアプリ開発に向いているJavaフレームワークとしては

* [Dropwizard](https://dropwizard.github.io/dropwizard/)
* [Spring Boot](http://projects.spring.io/spring-boot/)
* [Play Framework](http://www.playframework.com/)
* [Vert.x](http://vertx.io/)

などが挙げられています。

### 既存のTomcatユーザーだって追いつきたい
話を本題に。

DropwizardやSpring Bootがこのような作りに向いているとは言え、これらのフレームワークに移行するのが難しいケースはあると思います。既にTomcatにwarをデプロイしてる人は多いですよね。

そんな人でも大丈夫！伝統的Tomcatユーザーでも簡単に組み込みサーバー化できます。
[Tomcat Maven Plugin](http://tomcat.apache.org/maven-plugin-trunk/)を使えば、簡単に[実行可能jarファイルを作成できます](http://tomcat.apache.org/maven-plugin-trunk/executable-war-jar.html)。

試してみましょう。

#### 雛形プロジェクト生成

    $ mvn -B archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-webapp -Dversion=1.0.0 -DarchetypeArtifactId=maven-archetype-webapp
    $ cd my-webapp

でシンプルなWebプロジェクトを生成します。

#### tomcat7-maven-pluginの設定

pom.xmlを以下のように修正します。

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.mycompany.app</groupId>
      <artifactId>my-webapp</artifactId>
      <packaging>war</packaging>
      <version>1.0.0</version>
      <name>my-webapp Maven Webapp</name>
      <url>http://maven.apache.org</url>
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
      <build>
        <finalName>my-webapp</finalName>
        <!-- ここから -->
        <plugins>
          <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.3-SNAPSHOT</version>
            <executions>
              <execution>
                <id>tomcat-run</id>
                <goals>
                  <goal>exec-war-only</goal>
                </goals>
                <phase>package</phase>
                <configuration>
                  <path>/</path>
    	      <connectorHttpProtocol>org.apache.coyote.http11.Http11NioProtocol</connectorHttpProtocol>
    	      <finalName>${project.artifactId}.jar</finalName>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
        <!-- ここまで -->
      </build>
    </project>

細かいオプションは[こちら](http://tomcat.apache.org/maven-plugin-trunk/tomcat7-maven-plugin/exec-war-only-mojo.html)を参照。

#### ビルドする
`mvn pacakge`するだけ。簡単。

    $ mvn package
    $ cd target
    $ ls -lh
    total 17760
    drwxr-xr-x  2 maki  staff    68B  5 14 22:49 classes
    drwxr-xr-x  3 maki  staff   102B  5 14 22:49 maven-archiver
    drwxr-xr-x  5 maki  staff   170B  5 14 22:49 my-webapp
    -rw-r--r--  1 maki  staff   8.7M  5 14 22:49 my-webapp.jar
    -rw-r--r--  1 maki  staff   2.3K  5 14 22:49 my-webapp.war
    -rw-r--r--  1 maki  staff    86B  5 14 22:49 war-exec.manifest
    -rw-r--r--  1 maki  staff   266B  5 14 22:49 war-exec.properties

`my-webapp.jar`が出来ています。

#### 実行する 

    $ java -jar my-webapp.jar
    Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
    5 14, 2014 10:52:01 午後 org.apache.coyote.http11.Http11Protocol init
    情報: Initializing ProtocolHandler ["http-bio-8080"]
    5 14, 2014 10:52:01 午後 org.apache.catalina.core.StandardService startInternal
    情報: Starting service Tomcat
    5 14, 2014 10:52:01 午後 org.apache.catalina.core.StandardEngine startInternal
    情報: Starting Servlet Engine: Apache Tomcat/7.0.53
    5 14, 2014 10:52:03 午後 org.apache.catalina.util.SessionIdGenerator createSecureRandom
    情報: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [308] milliseconds.
    5 14, 2014 10:52:03 午後 org.apache.coyote.http11.Http11Protocol start
    情報: Starting ProtocolHandler ["http-bio-8080"]
    5 14, 2014 10:52:24 午後 org.apache.coyote.http11.Http11Protocol pause
    情報: Pausing ProtocolHandler ["http-bio-8080"]

[http://localhost:8080](http://localhost:8080) にアクセス。

![image](https://qiita-image-store.s3.amazonaws.com/0/1852/fb6f4335-f349-d440-1105-fdaf42e5ae2b.png)

画面がでましたね。実行可能jarのオプションは以下のような感じ。

    $ java -jar my-webapp.jar -h
    Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
    usage: java -jar [path to your exec war jar]
     -ajpPort <ajpPort>                     ajp port to use
     -clientAuth                            enable client authentication for
                                            https
     -D <arg>                               key=value
     -extractDirectory <extractDirectory>   path to extract war content,
                                            default value: .extract
     -h,--help                              help
     -httpPort <httpPort>                   http port to use
     -httpProtocol <httpProtocol>           http protocol to use: HTTP/1.1 or
                                            org.apache.coyote.http11.Http11Nio
                                            Protocol
     -httpsPort <httpsPort>                 https port to use
     -keyAlias <keyAlias>                   alias from keystore for ssl
     -loggerName <loggerName>               logger to use: slf4j to use slf4j
                                            bridge on top of jul
     -maxPostSize <maxPostSize>             max post size to use
     -obfuscate <password>                  obfuscate the password and exit
     -resetExtract                          clean previous extract directory
     -serverXmlPath <serverXmlPath>         server.xml to use, optional
     -uriEncoding <uriEncoding>             connector uriEncoding default
                                            ISO-8859-1
     -X,--debug                             debug

ポートを変えるときは

    $ java -jar my-webapp.jar -httpPort 8888
    Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
    5 14, 2014 10:56:38 午後 org.apache.coyote.http11.Http11NioProtocol init
    情報: Initializing ProtocolHandler ["http-nio-8888"]
    5 14, 2014 10:56:38 午後 org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
    情報: Using a shared selector for servlet write/read
    5 14, 2014 10:56:38 午後 org.apache.catalina.core.StandardService startInternal
    情報: Starting service Tomcat
    5 14, 2014 10:56:38 午後 org.apache.catalina.core.StandardEngine startInternal
    情報: Starting Servlet Engine: Apache Tomcat/7.0.53
    5 14, 2014 10:56:40 午後 org.apache.catalina.util.SessionIdGenerator createSecureRandom
    情報: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [330] milliseconds.
    5 14, 2014 10:56:40 午後 org.apache.coyote.http11.Http11NioProtocol start
    情報: Starting ProtocolHandler ["http-nio-8888"]

です。`-httpPort`を指定しないとpom.xmlで指定したConnector（`Http11NioProtocol`）が有効にならない・・・

あとはSpring MVCなどRESTfullなフレームワークで開発すると立派なマイクロサービスの一員ですね！
実行可能jarなのでsystem property等で外から設定を変えられるように設計する必要があります。

ちなみに[このblogも実行可能jarで動いています](https://github.com/making/categolj2-backend)。興味があれば[ダウンロード](https://github.com/making/categolj2-backend/releases)してみてください。

Java EEで開発したい！って方は[こちら](/#/entries/253)を参照してください。
