SpringCloud 微服务 + VUE 打包部署到 tomcat

问题背景

使用微服务 + vue 开发达到发版测试阶段时,需要从 dev 版打包出一份测试 beta 版。由于微服务自带 tomcat 容器,如果想使用一个 tomcat 同时运行前端后端服务,就需要进行一些配置。

部署前台

运行 npm run buildnpm run-script build 指令打包前端静态资源,其文件默认在项目的 dist 文件夹下。将 dist 文件夹下的文件复制到 tomcat 的 webapp 文件夹下的指定目录中,如:app ,配置 tomcat 的 conf 文件夹下的 server.xml 文件,在 server 标签下配置 service:

1
2
3
4
5
6
7
8
9
10
11
12
<Service name="Catalina">
<Connector port="8888" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">

<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>
</Engine>
</Service>

这样访问 localhost:8888/app 就可以访问到前端服务。

部署后台

使用 jar 直接运行

spring cloud 的每个 Project 可以直接打成 jar 包运行,打包后运行:

1
java -jar [包名].jar

即可启动服务。

使用 war 部署

如果想打包成 war 放在 tomcat 中,就需要取消使用自带的容器,并打包成 war:

1
<packaging>war</packaging>

标记内置 servlet container 的依赖为 provided :

1
2
3
4
5
6
7
8
9
10
11
12
13
<dependencies>
<!-- … -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- … -->
</dependencies>

增加一个启动类(与原来的入口类 ApplicationBootstrap 放在同级目录下):

1
2
3
4
5
6
7
8
9
10
11
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;

public class SpringBootStartApplication extends SpringBootServletInitializer
{
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
//ApplicationBootstrap 是原来 springboot的启动类
return builder.sources(ApplicationBootstrap.class);
}
}

Spring cloud 打成 war 后部署到 tomcat ,就不再使用 application.properties 文件中配置的端口,因为该文件中所配置的是 spring boot 内置的 tomcat 端口号, 打成war包部署在独立的tomcat上之后, 需要单独配置服务。

在 tomcat 的 webapp 文件夹同级新建 api-server 文件夹,把微服务打包生成的 war 文件解压到该文件夹下的 ROOT 文件夹中(也可以直接打包成 ROOT.war 文件),并配置 tomcat 配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<Service name="api-server">

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

<Engine name="api-server" defaultHost="localhost">

<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
</Realm>

<Host name="localhost" appBase="api-server" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>
</Engine>
</Service>