以下是关于 Spring Boot + Vue 前后端开发的打包、测试、监控、预先编译和容器部署 的详细说明,涵盖从开发到生产部署的全流程:
1. 打包
1.1 后端(Spring Boot)
打包方式
使用 Maven 或 Gradle 打包成可执行的 JAR/WAR 文件:
xml
<!-- pom.xml 配置 Spring Boot Maven 插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
执行命令:
bash
mvn clean package # 生成 target/*.jar 文件
Docker 包装
创建 Dockerfile
:
dockerfile
# 使用官方 JDK 基础镜像
FROM openjdk:8-jdk-alpine
# 复制构建好的 JAR 包
COPY target/*.jar app.jar
# 暴露端口
EXPOSE 8080
# 运行命令
ENTRYPOINT ["java", "-jar", "app.jar"]
1.2 前端(Vue)
打包配置
使用 Vue CLI 的 build
命令生成静态资源:
bash
npm run build # 生成 dist/ 目录
Vue 配置示例(vue.config.js)
javascript
module.exports = {
// 指定输出目录
outputDir: 'dist',
// 静态资源公共路径(用于部署到子路径)
publicPath: process.env.NODE_ENV === 'production' ? '/vue/' : '/',
// 配置代理解决开发环境跨域
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
pathRewrite: { '^/api': '' }
}
}
}
};
2. 测试
2.1 后端测试
单元测试(JUnit + Mockito)
java
@SpringBootTest
class UserControllerTest {
@Autowired
private UserController userController;
@MockBean
private UserService userService;
@Test
void testGetUser() {
// 模拟 UserService 的返回值
when(userService.getUser(1L)).thenReturn(new User(1L, "John"));
// 调用 Controller 方法
ResponseEntity<User> response = userController.getUser(1L);
// 断言结果
assertEquals("John", response.getBody().getName());
}
}
集成测试(SpringBootTest)
java
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ApplicationTests {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void testHealthCheck() {
ResponseEntity<String> response = restTemplate.getForEntity("/health", String.class);
assertEquals(200, response.getStatusCodeValue());
}
}
性能测试(JMeter)
- 使用 JMeter 脚本模拟高并发请求,测试接口响应时间。
- 配置线程组、HTTP 请求、断言和监听器(如聚合报告)。
2.2 前端测试
单元测试(Jest)
javascript
// user.test.js
import { getUser } from './user';
test('getUser should return user data', () => {
expect(getUser(1)).toEqual({ id: 1, name: 'Alice' });
});
E2E 测试(Cypress)
javascript
// cypress/integration/example_spec.js
describe('访问首页', () => {
it('加载首页并验证标题', () => {
cy.visit('/');
cy.get('h1').contains('欢迎来到 Vue 应用');
});
});
静态代码分析(ESLint)
在 package.json
中配置:
json
{
"eslintConfig": {
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
]
}
}
3. 监控
3.1 后端监控
Spring Boot Actuator
-
依赖配置:
xml<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
-
配置
application.yml
:yamlmanagement: endpoints: web: exposure: include: "health,info,metrics"
-
常用端点:
/actuator/health
:健康检查。/actuator/metrics
:性能指标(如内存、CPU、HTTP 请求耗时)。
Prometheus + Grafana
-
集成 Prometheus :
添加依赖:
xml<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency>
访问
/actuator/prometheus
获取指标数据。 -
Grafana 配置:通过 Prometheus 数据源创建仪表盘。
日志监控(ELK Stack)
-
日志配置(Logback) :
xml<configuration> <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <destination>localhost:4560</destination> </appender> <root level="INFO"> <appender-ref ref="LOGSTASH" /> </root> </configuration>
3.2 前端监控
错误跟踪(Sentry)
-
Vue 插件配置 :
javascriptimport * as Sentry from '@sentry/vue'; Sentry.init({ dsn: 'https://[email protected]/456', integrations: [ new Sentry.BrowserTracing(), new Sentry.Vue({ Vue }) ], });
性能监控(APM)
- 使用 New Relic 或 Datadog 的前端 SDK 监控页面加载时间、API 响应时间。
4. 预先编译
4.1 后端预编译
-
Maven 编译阶段:
bashmvn compile # 仅编译 Java 代码
-
构建缓存 :利用 Maven 的
~/.m2/repository
缓存依赖,减少重复下载。
4.2 前端预编译
Webpack 配置优化
-
代码分割(Code Splitting):
javascript// vue.config.js chainWebpack(config) { config.optimization.splitChunks({ chunks: 'all', minSize: 30000, minChunks: 1, maxAsyncRequests: 5, maxInitialRequests: 3, automaticNameDelimiter: '~', name: true, cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, priority: -10 }, default: { minChunks: 2, priority: -20, reuseExistingChunk: true } } }); }
-
Tree Shaking:通过 ES6 模块化自动删除未使用的代码。
-
环境变量管理:
bash# .env.development VUE_APP_API_URL=http://localhost:8080/api
5. 容器部署
5.1 Docker 部署
Dockerfile(后端)
dockerfile
# 基础镜像
FROM openjdk:8-jdk-alpine
# 设置工作目录
WORKDIR /app
# 复制构建好的 JAR 包
COPY target/*.jar app.jar
# 暴露端口
EXPOSE 8080
# 启动命令
CMD ["java", "-jar", "app.jar"]
Dockerfile(前端)
dockerfile
# 使用 Nginx 作为静态资源服务器
FROM nginx:alpine
# 复制 Vue 打包后的 dist 目录到 Nginx 默认目录
COPY dist/ /usr/share/nginx/html/
# 暴露端口
EXPOSE 80
Docker Compose(多服务部署)
yaml
version: '3'
services:
backend:
build: ./spring-boot
ports:
- "8080:8080"
environment:
SPRING_PROFILES_ACTIVE: prod
frontend:
build: ./vue
ports:
- "80:80"
5.2 Kubernetes 部署
部署 YAML 文件
yaml
# 后端 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-boot-deploy
spec:
replicas: 3
selector:
matchLabels:
app: spring-boot
template:
metadata:
labels:
app: spring-boot
spec:
containers:
- name: spring-boot
image: your-registry/spring-boot:latest
ports:
- containerPort: 8080
---
# 前端 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: vue-deploy
spec:
replicas: 2
selector:
matchLabels:
app: vue
template:
metadata:
labels:
app: vue
spec:
containers:
- name: vue
image: your-registry/vue:latest
ports:
- containerPort: 80
---
# 服务(Service)
apiVersion: v1
kind: Service
metadata:
name: spring-boot-service
spec:
selector:
app: spring-boot
ports:
- protocol: TCP
port: 8080
targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: vue-service
spec:
selector:
app: vue
ports:
- protocol: TCP
port: 80
targetPort: 80
---
# Ingress(路由配置)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vue-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: spring-boot-service
port:
number: 8080
5.3 CI/CD 流水线(GitHub Actions)
示例工作流(.github/workflows/ci-cd.yml)
yaml
name: CI/CD Pipeline
on:
push:
branches: [ main ]
jobs:
build-backend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'adopt'
- name: Build with Maven
run: mvn clean package -DskipTests
build-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Build Vue
run: npm run build
deploy:
needs: [build-backend, build-frontend]
runs-on: ubuntu-latest
steps:
- name: Push Docker Images
uses: docker/build-push-action@v3
with:
context: ./spring-boot
push: true
tags: registry.example.com/spring-boot:latest
env:
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
- name: Deploy to Kubernetes
run: |
kubectl apply -f k8s/deployment.yaml
kubectl rollout status deployment/spring-boot-deploy
kubectl apply -f k8s/frontend-deployment.yaml
kubectl rollout status deployment/vue-deploy
6. 总结
- 打包:后端用 Maven/Gradle,前端用 Vue CLI,生成可部署的 JAR 和静态资源。
- 测试:后端用 JUnit + Mock,前端用 Jest + Cypress。
- 监控:后端用 Actuator + Prometheus/Grafana,前端用 Sentry + APM。
- 编译优化:代码分割、Tree Shaking、环境变量管理。
- 部署:Docker 包装 + Kubernetes 部署,结合 CI/CD 实现自动化流水线。
通过以上步骤,可以高效地完成前后端分离应用的开发、测试、监控和部署。