從Tomcat到Spring Boot

暮夏八月是一年中最好的時節,近近地看到了涼爽的希望,卻還能享用暖熱的餘溫。距離Phil Webb發佈Spring Boot已經4年有餘,我們嘗試在這個夏天把這隻已經獨自在外遊蕩了19年的野貓Tomcat裝入春天的長靴。

從零開始安裝Spring Boot項目,使用內嵌的Tomcat引擎是比較容易的事情,各種中文教程已經數不勝數,那不是我們要談論的話題。在這裏我們要做的是以最小的代價把一個已有的Tomcat項目改造爲Spring Boot項目,以實現我們微服務改造的第一步。

對pom.xml的修改

添加spring-boot-maven-plugin

一般來說,在每一個pom.xml的結尾,都會有一個build段落,在這裏添加spring-boot-maven-plugin是必經的第一個步驟,添加完之後的完整段落如下:

    <build>
        <finalName>my-app</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <jvmArguments>-Xmx64m</jvmArguments>
                </configuration>
            </plugin>
        </plugins>
    </build>

在這裏,我們特別添加了一個configuration段落,設置-Xmx64m,這是因爲Tomcat缺省會分配物理內存的1/4爲堆內存,這樣我們一臺電腦最多隻能運行4Tomcat服務,內存就不夠用了。在這裏我們把heap size的最大尺寸設置爲只用64m,可以有效節省內存,最多會引起垃圾回收頻繁一些而已,這之間的平衡可以自己掌握。

添加spring-boot-starter-parent

Spring Boot是一個非常獨立的父母,它認爲所有與spring有關的依賴都是它的孩子,所以我們必須引入spring-boot-starter-parent,讓它來管理所有姓spring的孩子。

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath/>
    </parent>

由於Spring Boot自己管理所有spring依賴,你還需要把原先加在pom.xml裏的所有與spring有關的依賴(以及所有spring想要管理的依賴,例如com.fasterxml.jackson.core)全部刪掉,否則會造成版本衝突。比如這樣:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.1.RELEASE</version>
</dependency>

添加spring-boot-starter-web

Spring Boot唯一需要我們手工添加的依賴只有一個:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

有了這個依賴以後,Spring Boot項目啓動的時候就會內嵌一個Tomcat服務器。同時Spring Boot帶來的另外一個好處是:我們從此不必再依賴Tomcat,如果我們想換成其它引擎,只需要加上新引擎,排除掉Tomcat就可以了,假設我們想換成Undertow,只需要這樣設置:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

主程序入口

Application.java

傳統的Tomcat應用是讓Tomcat先啓動,然後加載我們的war文件,改造之後是Spring Boot先啓動,由Spring Boot來加載Tomcat,所以我們需要給我們的應用裏增加一個Application.java文件:

package com.domain.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

application.properties

傳統的Tomcat是把所有配置項放在webapp/WEB-INF/web.xml裏來管理的,Spring Boot不使用web.xml文件,它把所有配置項都放在resources/application.properties文件中,例如:

server.port=8090
server.servlet.context-path=/app

運行

至此爲止,就已經完成了從TomcatSpring Boot的遷移。我們可以通過maven運行Spring Boot來看一下效果:

mvn spring-boot:run

添加dubbo

如果以前的項目是由dubbo完成的,暫時還不想破壞原有架構,可以把dubbo集成到Spring Boot中來。

pom.xml

pom.xml中添加dubbo-spring-boot-starter依賴:

        <dependency>
            <groupId>com.alibaba.spring.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>1.0.2</version>
        </dependency>

這個dubbo-spring-boot-starter的最高版本是2.0.0,並且即便這個2.0.0已經被廢棄,更高的版本遷移到了incubator-dubbo-spring-boot-project上,但是由於我用的是dubbo較低的版本2.5.3,使用了比較方便的<dubbo:annotation>方式,所以不可能採用它的2.0.0版本,更加不可能使用incubator-dubbo-spring-boot-project(這個incubator-dubbo-spring-boot-project項目甚至不支持在application.properties文件中對dubbo做配置)。

Dubbo2.5.7以後廢棄了<dubbo:annotation>方式,改採@DubboComponentScan方式,我個人認爲這種新方式遠遠不如舊的<dubbo:annotation>方式簡便,所以目前或者以後也不準備遷移到更高版本的dubbo了。

Application.java

pom.xml中添加對dubbo的依賴後,還需要在Application.java中添加dubbo的自動配置功能:

import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;

@SpringBootApplication
@EnableDubboConfiguration

application.properties

然後在application.properties文件中添加dubbo的配置項:

spring.dubbo.appname=my-app
spring.dubbo.registry=zookeeper://myip.mydomain.com:2181

這個配置項功能很弱,但勉強夠用。雖然它會造成一些很難看的日誌

[2018-08-26 12:21:25] WARN  -  [DUBBO] ReferenceConfig(null) is not DESTROYED when FINALIZE, dubbo version: 2.5.3, current host: 192.168.1.2

但是鑑於這個插件已經被廢棄了,不會有人來解決這個問題,只能勉強這麼用了。

總結

以上就是從Tomcat遷移到Spring Boot所需要的所有改動。總計只是修改了pom.xml一個文件,新增了Application.javaapplication.properties兩個文件,新增代碼行數不超過20行,整個遷移過程還是比較簡便的。

當然,僅僅在代碼層面遷移到Spring Boot不是最終目的,我們還需要在pom.xml文件中把<packaging>war</packaging>改爲<packaging>jar</packaging>,這樣我們在執行mvn package之後,就可以java -jar myapp.jar來在服務器端進行部署。

更進一步,當以Spring Boot方式啓動的微服務越來越多的時候,服務治理將成爲一個難題,這時候就需要考慮引入Eureka或者甚至Kubernetes進行服務治理,那將是另外一個大話題了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章