概述:
由于公司多数测试人员还是在使用禅道,为了方便,就将禅道直接集成在我们的测试平台中
一般可以有几种实现方法
- 调用禅道的API集成
- 集成本地部署的禅道-可能有跨域问题,需要解决
由于我这里已经部署了一台本地的禅道系统,那么这里我将以最简单的方式集成,通过代理集成到测试平台系统中,代理这里我们又可以分为以下方式
- 前端vue代理
- 后端代理
- Nginx代理
一般我们选择nginx这种方式进行集成,能够高并发,满足业务需求使用,先来看看本地开发环境式如何使用
访问nginx的官网下载nginx
首页如下
在这里我下载的是中间的稳定版本下载在本地你任意一个磁盘,然后解压,解压后效果如下
打开nginx的配置文件,配置如下
worker_processes 1;
events { worker_connections 1024; }
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 81;
server_name 172.16.60.60;
# 前端系统代理(Vue)
location / {
proxy_pass http://localhost:9528;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
}
# 禅道代理(完美复刻直接访问环境)
location /zentao/ {
# 1. 目标地址:禅道服务器(与直接访问完全一致)
proxy_pass http://172.16.50.80/zentao/;
# 2. 复刻直接访问的请求头(关键!)
proxy_set_header Host 172.16.50.80; # 强制使用禅道原始 Host(直接访问时的 Host)
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Referer http://172.16.50.80/zentao/; # 模拟原域名 Referer
proxy_set_header User-Agent $http_user_agent; # 传递客户端浏览器信息
# 3. 复刻直接访问的 Cookie 环境(核心!)
proxy_cookie_path / /; # Cookie 路径与直接访问一致(根路径 /)
proxy_cookie_domain 172.16.50.80 172.16.60.60; # 将 Cookie 域名为 Nginx 服务器 IP
# 4. 关闭 Nginx 缓冲(确保请求与直接访问完全一致)
proxy_request_buffering off;
proxy_buffering off;
# 5. 移除安全限制头(允许表单提交和跳转)
proxy_hide_header Content-Security-Policy;
proxy_hide_header X-Frame-Options;
# 6. 重定向处理(登录后跳转 Nginx 地址)
proxy_redirect http://172.16.50.80/ http://172.16.60.60:81/; # 注意末尾斜杠!
}
}
}
注意
ngin每次配置操作,启用时最好都检查一下语法,windows操作命令如下
nginx -t 检查语法
nginx -s reload 重启nginx
nginx -s stop 停用
start nginx 启动
编写前端vue的页面展示部分以及路由
<template>
<div class="zentao-container">
<!-- 尺寸控制栏 -->
<div class="zentao-header">
<div class="header-title">禅道项目管理系统(rebort)</div>
<div class="header-actions">
<!-- 全屏切换按钮 -->
<el-button
icon="el-icon-full-screen"
size="mini"
@click="toggleFullScreen"
:title="isFullScreen ? '退出全屏' : '进入全屏'"
/>
<!-- 固定尺寸按钮(可选) -->
<el-button
icon="el-icon-sizer"
size="mini"
@click="resetSize"
title="重置尺寸"
/>
</div>
</div>
<!-- 禅道 iframe -->
<iframe
ref="zentaoIframe"
:src="iframeSrc"
class="zentao-iframe"
:style="{ height: iframeHeight, width: iframeWidth }"
sandbox="allow-same-origin allow-scripts allow-forms allow-top-navigation allow-popups"
/>
</div>
</template>
<script>
export default {
data() {
return {
iframeSrc: '/zentao/user-login.html', // 禅道登录页地址
iframeWidth: '100%', // 初始宽度(可固定为具体值,如 '1200px')
iframeHeight: '80vh', // 初始高度(80% 视窗高度,避免全屏)
isFullScreen: false // 全屏状态标记
};
},
methods: {
// 切换全屏/退出全屏
toggleFullScreen() {
const container = document.querySelector('.zentao-container');
if (!this.isFullScreen) {
// 进入全屏
if (container.requestFullscreen) {
container.requestFullscreen();
} else if (container.mozRequestFullScreen) { // Firefox
container.mozRequestFullScreen();
} else if (container.webkitRequestFullscreen) { // Chrome/Safari
container.webkitRequestFullscreen();
} else if (container.msRequestFullscreen) { // IE/Edge
container.msRequestFullscreen();
}
this.isFullScreen = true;
} else {
// 退出全屏
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
this.isFullScreen = false;
}
},
// 重置尺寸为初始值
resetSize() {
this.iframeWidth = '100%';
this.iframeHeight = '80vh';
this.isFullScreen = false;
// 若处于全屏状态,先退出全屏
if (document.fullscreenElement) {
document.exitFullscreen();
}
}
},
mounted() {
// 监听全屏状态变化(处理用户按 ESC 退出全屏的情况)
document.addEventListener('fullscreenchange', () => {
this.isFullScreen = !!document.fullscreenElement;
});
document.addEventListener('mozfullscreenchange', () => {
this.isFullScreen = !!document.mozFullScreenElement;
});
document.addEventListener('webkitfullscreenchange', () => {
this.isFullScreen = !!document.webkitFullscreenElement;
});
document.addEventListener('msfullscreenchange', () => {
this.isFullScreen = !!document.msFullscreenElement;
});
}
};
</script>
<style scoped>
/* 容器样式 */
.zentao-container {
position: relative;
width: 100%;
border: 1px solid #e6e6e6;
border-radius: 4px;
overflow: hidden;
}
/* 头部控制栏 */
.zentao-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 16px;
background-color: #f5f5f5;
border-bottom: 1px solid #e6e6e6;
}
.header-title {
font-weight: 500;
color: #333;
}
.header-actions {
display: flex;
gap: 8px;
}
/* iframe 样式 */
.zentao-iframe {
border: none;
transition: all 0.3s ease;
}
/* 全屏状态样式(可选) */
::v-deep .zentao-container:fullscreen {
background-color: #fff;
z-index: 9999;
}
::v-deep .zentao-container:-webkit-full-screen {
background-color: #fff;
z-index: 9999;
}
</style>
最终集成后效果如下
如果是在生产环境下使用,我们可能会考虑使用加密的方式
server {
listen 443 ssl; # 监听 HTTPS 端口
server_name project.example.com; # 生产环境域名
# SSL 证书配置(替换为实际证书路径)
ssl_certificate /etc/nginx/ssl/project.crt;
ssl_certificate_key /etc/nginx/ssl/project.key;
# SSL 安全配置
ssl_protocols TLSv1.2 TLSv1.3; # 禁用不安全协议
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 强制 HTTP 跳转 HTTPS
return 301 https://$host$request_uri;
}
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name project.example.com;
return 301 https://$host$request_uri;
}
限制请求速率,防止攻击
http {
# 配置请求限制
limit_req_zone $binary_remote_addr zone=zentao_req:10m rate=10r/s; # 限制单 IP 10 请求/秒
limit_conn_zone $binary_remote_addr zone=zentao_conn:10m; # 限制并发连接
}
server {
location /zentao/ {
proxy_pass http://172.16.50.80/zentao/;
# 应用请求限制
limit_req zone=zentao_req burst=20 nodelay; # 突发允许 20 请求
limit_conn zentao_conn 50; # 单 IP 最大 50 并发连接
}
}
静态资源缓存优化,较少后端请求
location ~* /zentao/(css|js|images|fonts)/ {
proxy_pass http://172.16.50.80;
proxy_cache zentao_cache; # 定义缓存区
proxy_cache_valid 200 304 8h; # 缓存 8 小时
proxy_cache_valid any 1m; # 非 200/304 缓存 1 分钟
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
add_header X-Proxy-Cache $upstream_cache_status; # 响应头显示缓存状态(HIT/MISS)
}
健康检查与自动恢复
通过 ngx_http_proxy_module
配置后端服务健康检查,避免请求转发到故障节点:
location /zentao/ {
proxy_pass http://172.16.50.80/zentao/;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504; # 失败时自动切换备用节点(需配合 upstream)
proxy_connect_timeout 3s; # 连接超时 3 秒
proxy_read_timeout 10s; # 读取超时 10 秒
}
日志与监控
- 访问日志:配置详细日志格式,记录请求来源、URL、状态码、响应时间,便于故障排查:
log_format main '$remote_addr [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time';
access_log /var/log/nginx/zentao_access.log main; # 禅道访问日志