快速开始
一分钟上手,零门槛配置 —— 单个 jar 启动,不需要任何外部组件。文本教程 + 视频教程 + PDF 文档下载
配套 PDF 文档
三份文档最近一次基于 v2.0.0 版整理,适合离线阅读、内网分发与打印存档。先看产品介绍了解能力与选型,再按角色选择操作手册。
方式一:直接下载 jar(推荐)
二十五种驱动随包内置(MySQL、MariaDB、Oracle、SQL Server、DB2、PostgreSQL、openGauss、达梦、人大金仓、OceanBase、TiDB、GoldenDB、TDSQL、PolarDB、GreatDB、UPDRDB、KunDB、RASESQL、SeaboxSQL、瀚高、海量、崖山、Doris、MongoDB 原生驱动、H2;
MySQL / PostgreSQL 协议产品复用对应驱动),下载后 java -jar 就能跑 —— 不需要源码、不需要 Maven,也不用手动往服务器放驱动 jar
(仅华为 GaussDB、GBase、神通 Oscar、SAP HANA、ClickHouse、Hive、Impala、Elasticsearch、MongoDB(Atlas SQL)与自定义数据库需要自备厂商驱动)。
java -jar jync.jar
方式二:自行构建(git clone + Maven)
环境要求
JDK 17 或以上 · 内存 ≥ 512MB · 端口 8080 · Maven 3.6+(仅方式二自行构建时需要)
构建
git clone https://github.com/vfaner/jync.git cd jync mvn clean package -DskipTests
产物:target/jync.jar(可执行 fat jar)
启动
java -jar target/jync.jar
访问 http://localhost:8080 即可。
首次启动会自动创建 ./data(元数据)、./logs(运行日志)目录。
生产配置(重要)
在 jar 同级目录创建 application.yml:
server:
port: 8080
sync:
poll-interval: 2000 # 全局轮询间隔(毫秒)
batch-size: 500 # 增量轮询 / CDC 回放每批行数(在线流量,保持小)
fetch-size: 1000 # 增量读取的结果集批量
full-load-batch-size: 2000 # 仅首次全量:每批行数(1-20000,建议 1000-5000)
full-load-fetch-size: 2000 # 仅首次全量:源端结果集批量(1-20000)
full-load-parallelism: 2 # 全量并行 worker 数(1-8,建议 1-4,受连接池约束)
chunk-size: 100000 # 全量每块行数,每块提交+写检查点;0 = 不分块
initial-load-insert-first: true # 空表用 INSERT 代替 upsert
defer-secondary-indexes: true # 新建表先灌数据、全量完成后再建非唯一二级索引(实测快约 40%)
max-pool-size: 5 # 每库连接池上限(须容纳并行度)
safety-lag-ms: 1000
lock-ttl-ms: 300000
crypto-password: "" # 留空 = 首次启动自动生成,保存到 data/jync.key
crypto-salt: "" # 留空 = 同上;如需自管密钥再显式填写
# ai:
# enabled: false # 内网/离线环境取消注释:关闭 AI 辅助(隐藏菜单,不调用大模型)
# metrics: # 性能监控采样;默认值见下,全部可省略
# enabled: true # 总开关:关闭后不再产生新样本,已存样本保留到过期清理
# retention-days: 7 # 样本保留天数(<=0 不清理)
# app-interval-ms: 60000 # 进程样本:CPU / 堆与 GC / 线程数 / 主机负载
# task-interval-ms: 60000 # 每个同步任务的吞吐与延迟样本
# db-interval-ms: 300000 # 连接健康与库内指标(连接采样会打开会话)
# db-initial-delay-ms: 30000 # 启动后首次连接采样延迟,避免重启后性能页空着
# capacity-interval-ms: 3600000 # 表数 / 行数 / 占用空间(开销最大)
# prometheus-token: "" # /api/metrics/prometheus 抓取令牌;留空则端点关闭(404)
app:
login:
# 应急通道:关闭本地登录后若外部认证不可用,设为 true(或启动时加 JYN_RESET_LOGIN=true),
# 启动一次会重新开启本地登录并保存;修好后改回 false。
reset-on-startup: false
# 内网/离线环境取消注释:关闭版本更新检查(不再访问 GitHub/Gitee,一键升级入口同步隐藏)
# update-check:
# enabled: false
crypto-password 与 crypto-salt 用于加密存储的数据库连接密码。v1.7.5 起全新部署留空即可——首次启动会自动生成强密钥并保存到数据库同目录的 <库名>.key(如 data/jync.key),无需手工修改默认值;备份数据库时必须连同该 key 一起备份(key 丢了,已保存的连接密码就要在界面上重填)。从旧版本升级请保持默认值不动,它是历史密文的解密钥匙;想自己管理密钥(环境变量 / K8s Secret)再显式填写。
sync.ai.enabled 与 app.update-check.enabled 两行开关的注释并重启,应用将不再发起任何外网请求——AI 菜单整体隐藏、AI 起草在发请求前直接拦截;开机版本预热检查关闭,设置页显示「已关闭更新检查」。默认均为开启,联网部署无需修改。
0 0 2 * * ? 会在本地时间上午 10 点触发;部署时请固定 -Duser.timezone(容器用 TZ)。任务详情页会显示「下次自动运行」及其实时区。
外部元数据库(可选)
不想要 H2 文件库时,把 spring.datasource.* 指向已有数据库即可,表结构由 ddl-auto: update 在首启自动创建。
| 元数据库 | 驱动类 | URL 示例 | 验证状态 |
|---|---|---|---|
| H2(默认) | org.h2.Driver | jdbc:h2:file:./data/jync; | 默认路径 |
| MySQL 8 | com.mysql.cj.jdbc. | jdbc:mysql://db:3306/jync? | 有容器契约测试 |
| PostgreSQL 16 | org.postgresql.Driver | jdbc:postgresql://db:5432/jync | 有容器契约测试 |
| Oracle 23 | oracle.jdbc. | jdbc:oracle:thin:@//db:1521/FREEPDB1 | 有容器契约测试 |
spring:
datasource:
url: "jdbc:mysql://db:3306/jync?useUnicode=true&characterEncoding=utf8"
username: jync
password: change-me
driver-class-name: com.mysql.cj.jdbc.Driver # 能按 URL 推断时可省略
也可用 SPRING_DATASOURCE_URL / SPRING_DATASOURCE_USERNAME / SPRING_DATASOURCE_PASSWORD / SPRING_DATASOURCE_DRIVER_CLASS_NAME 环境变量覆盖。要点:
先建库:MySQL 用 CREATE DATABASE jync DEFAULT CHARACTER SET utf8mb4;,其余类型建空库即可。所需 JDBC 驱动已随包内置,不用另外放 jar。
验证范围:MySQL 8、PostgreSQL 16、Oracle 23 有真实数据库契约测试(建表、自增主键、@Lob 往返、批量更新/删除、聚合查询)。SQL Server 与国产库未逐一实测为元数据库;PostgreSQL / Oracle 兼容族(金仓、openGauss、瀚高、Vastbase、达梦、崖山等)理论上同族可用,但 Hibernate 方言识别因驱动而异,上生产前请先在测试环境用同一驱动启动验证。
换库不是迁移:改用外部元数据库等于从一份空元数据开始,原 H2 里的连接、任务、游标与检查点不会自动带过去;新部署可以直接用,已有部署请保留原 H2 或自行迁移这些数据。
多副本的前提:H2 的 AUTO_SERVER=TRUE 只能同机多进程共享;跨主机多实例必须使用上表中的外部元数据库。
SYNC_CRYPTO_PASSWORD / SYNC_CRYPTO_SALT:自动生成的密钥依附于本地 <库名>.key,外部元数据库场景没有这个文件,留空会退回发行包里的公开默认密钥。
后台常驻
方式 A:systemd(推荐)
[Unit] Description=Jync Database Sync After=network.target [Service] Type=simple User=jync WorkingDirectory=/opt/jync ExecStart=/usr/bin/java -Xms512m -Xmx1g -Duser.timezone=Asia/Shanghai -jar /opt/jync/jync.jar \ --spring.config.additional-location=file:/opt/jync/application.yml Restart=always RestartSec=10 [Install] WantedBy=multi-user.target
additional-location(叠加覆盖),不要用 spring.config.location:后者会替换全部默认配置位置,jar 内置的 application.yml 将不再被读取——国际化(spring.messages.basename)、自动建表(spring.jpa.hibernate.ddl-auto)等内置键全部丢失,症状是登录页显示 ??login.title_zh_CN?? 之类标记、全新部署不建表,甚至直接启动失败。外部文件只需写你要覆盖的键。
sudo systemctl daemon-reload sudo systemctl enable --now jync sudo systemctl status jync
方式 B:nohup(快速验证)
cd /opt/jync nohup java -jar jync.jar --spring.config.additional-location=file:./application.yml > /dev/null 2>&1 &
即使是 nohup 临时启动,也建议带上 additional-location 让外部 application.yml 生效(生产口令、端口等覆盖项都在里面);纯体验内置默认配置时才可省略该参数。
使用流程
① 数据库连接 → 新建连接时先选用途「源 / 目标」,分别建好源库和目标库连接 → 点击「测试连接」确认可用
② 同步任务 → 新建同步任务 → 选择源库与目标库(下拉只列出对应用途的连接)
③ 进入同步任务详情 → 勾选要同步的表/视图/存储过程 → 配置同步选项 → 保存
④ 点击「立即同步」验证一次(运行中再次点击会在本轮结束后自动补跑一轮),或点击「启动同步」开始持续轮询
⑤ 在「变更日志」查看每次同步的明细
方式三:Docker(容器化部署)
docker compose 一条命令启动
仓库自带多阶段构建 Dockerfile(构建用 Maven + JDK 17,运行镜像仅含 JRE、非 root 用户运行、内置 HEALTHCHECK)与 docker-compose.yml。
元数据库(/app/data)与日志(/app/logs)通过宿主机目录持久化,重建或升级镜像不丢数据。
git clone https://github.com/vfaner/jync.git cd jync docker compose up -d --build # 浏览器打开 http://localhost:8080(默认账号 admin / view,密码 123456,登录后请立即修改)
不想用 Compose,也可以直接用 Docker:
docker build -t jync:2.0.0 . docker run -d --name jync -p 8080:8080 \ -v "$PWD/data:/app/data" -v "$PWD/logs:/app/logs" \ -e TZ=Asia/Shanghai --restart unless-stopped jync:2.0.0
JYN_COOKIE_SECURE=true,嵌入 iframe 时再设 JYN_COOKIE_SAME_SITE=None;多实例时通过 SPRING_DATASOURCE_URL 把 H2 换成外部 MySQL / PostgreSQL / Oracle)。
完整的环境变量、TLS、多实例扩容、镜像升级与排障说明见仓库
docs/deploy-container.md ↗。
方式四:Kubernetes
Kustomize 清单,一条命令部署
仓库内 deploy/k8s/ 提供 Kustomize 清单:Namespace、2 Gi 的 H2 数据卷(PVC)、Deployment、Service 与可选 Ingress。
Deployment 默认单副本 + Recreate,以非 root 用户运行,并用 GET /login 做启动、存活与就绪探针。
git clone https://github.com/vfaner/jync.git cd jync docker build -t jync:2.0.0 . # kind / minikube 需先把镜像载入集群: # kind load docker-image jync:2.0.0 # minikube image load jync:2.0.0 kubectl apply -k deploy/k8s/ kubectl -n jync rollout status deploy/jync kubectl -n jync port-forward svc/jync 8080:80 # 浏览器打开 http://localhost:8080(默认账号 admin / view,密码 123456,登录后请立即修改)
ReadWriteOnce,副本数必须保持 1;要多副本先把元数据库换成外部 MySQL / PostgreSQL / Oracle,再调大 replicas。
② 推到自建镜像仓库时改 deploy/k8s/kustomization.yaml 的 images,imagePullPolicy 按需改成 Always。
③ 没装 Ingress Controller 就删掉 ingress.yaml 及它在 kustomization 中的引用;走 HTTPS 时设 JYN_COOKIE_SECURE=true,并把 Ingress 的域名、TLS 与代理超时改成实际值。
配置项
application.yml 中的主要配置(sync.* 与相关开关)
| 键 | 默认 | 说明 |
|---|---|---|
poll-interval | 2000 | 轮询间隔(毫秒) |
batch-size | 500 | 增量轮询与 CDC 回放每个 JDBC 批次的行数(在线流量,保持小) |
fetch-size | 1000 | 增量读取的源库结果集批量 |
full-load-batch-size | 2000 | 仅首次全量:每个 JDBC 批次行数,取值 1–20000,建议 1000-5000(LOB 表 500-2000)。调优见 功能页 |
full-load-fetch-size | 2000 | 仅首次全量:源库结果集批量,取值 1–20000;MySQL 源逐行流式读取时该值不参与 |
chunk-size | 100000 | 初始全量每块行数,每块独立提交并写检查点;必须大于 0,小于等于 0 表示关闭分块(整表加载) |
full-load-parallelism | 2 | 全量并行 worker 数,取值 1–8,建议 1-4。有主键的表都可并行:整数前导键按区间切分,其余键形态按采样边界切分;无主键表顺序加载。实际值受连接池压制:源与目标配置不同需 max-pool-size ≥ 并行度+1,同一配置需 ≥ 2×并行度+2 |
initial-load-insert-first | true | 目标为空表时用 INSERT 代替 upsert(Oracle 实测约 2.3 倍);表已有数据仍走幂等写入。旧键 oracle-initial-load-insert-first 仍作为别名兼容 |
defer-secondary-indexes | true | 新建表的非唯一二级索引延到首次全量提交后再建(50 万行 2 索引实测端到端快约 42%);主键与唯一索引仍立即创建,只同步结构时也全部立即创建 |
max-pool-size | 5 | 每个数据库连接池的最大连接数 |
max-retries | 3 | 连续失败多少次后标记任务为 ERROR |
safety-lag-ms | 1000 | 时间戳水位线回退量,避免晚提交的事务被跳过 |
row-count-audit-interval-ms | 60000 | 行数审计间隔(毫秒) |
row-count-repair-max-rows | 1000 | 行数审计发现缺口时,按主键切段只补缺失行的行数上限;0 关闭定点修补,退回清空游标整表重载 |
delete-compare-max-rows | 0 | 删除比对的内存上限行数。超过即改为按主键键序分页比对;0 关闭分块(整表比对)。表大时分块可把内存从「整表所有键」降到「一页键」 |
pool-wait-ms | 10000 | 同一连接配置上的任务排队退让的等待上限。拿不到连接位置则本轮让出、下个周期重试,而不是整轮失败;0 表示不等待 |
cdc.pg.wal-retention-warn-bytes | 4 GiB | PostgreSQL 逻辑复制槽滞留 WAL 的告警阈值(字节),超过在状态面板标红并写 WARN;0 关闭告警 |
cdc.max-transaction-rows / max-transaction-bytes | 1000000 / 512 MiB | 单个源事务的缓冲上限,超限按非瞬态失败停车而不是无限吃内存;0 不限。大事务场景建议在源库拆分或调高上限 |
stuck-threshold-ms | 1800000 | 轮询多久无进展视为卡死并告警;0 关闭 |
max-unindexed-scan-rows | 1000000 | 无索引游标列的探测上限;超过后停止 COUNT 探测并只告警一次;0 关闭 |
alert.evaluate-interval-ms / initial-delay-ms | 60000 / 45000 | Webhook 告警的评估周期与首次延迟(毫秒)。告警只读运行状态,不改变同步、CDC 或 ETL 任务的行为 |
metrics.enabled / retention-days | true / 7 | 性能采样总开关与样本保留天数;关闭后不再产生新样本,已存样本保留到过期清理,不影响同步链路 |
metrics.app-interval-ms / task-interval-ms / db-interval-ms / capacity-interval-ms | 60000 / 60000 / 300000 / 3600000 | 进程样本(CPU、堆与 GC、线程数、主机负载)、任务吞吐、连接健康与库内指标、表数 / 行数 / 占用空间各自的采样间隔。进程与任务样本只读本机数据;连接采样会打开会话,库内指标读取数据库自身的统计视图;目录统计只对 MySQL、Oracle、SQL Server、PostgreSQL、DB2 可用 |
metrics.db-initial-delay-ms | 30000 | 启动后首次连接采样的延迟(毫秒)。默认 30 秒,避免重启后性能页长时间停留在「暂无样本」;连接多或源库较慢时可适当调大 |
metrics.prometheus-token | (留空) | Prometheus 抓取令牌。留空时 /api/metrics/prometheus 返回 404;配置后请求头需带 Authorization: Bearer <token>(也可用环境变量 JYN_METRICS_TOKEN) |
full-compare-max-rows | 20000 | 自动选用全表比对的行数上限;任务级手动选择不受此限制,超限或按当前间隔负担过重时详情页与启动日志会提示 |
lock-ttl-ms | 300000 | 同步锁租约时长(毫秒) |
crypto-password | (留空自动生成) | 密码加密密钥。全新部署留空即自动生成并保存到数据库同目录的 <库名>.key;显式填写则以配置为准;从旧版本升级保持默认值不动 |
crypto-salt | (留空自动生成) | 加密盐值(十六进制)。规则同上;显式填写时必须是合法十六进制 |
ai.enabled | true | AI 辅助转换总开关。置 false 则菜单隐藏,即使库中存在已启用的提供商,AI 起草/流式接口也会在发出请求前直接拦截,不产生任何大模型调用 |
app.update-check.enabled | true | 设置页是否检查 GitHub/Gitee 最新版本。开机预热与后台刷新均在关闭后停止,一键升级入口同步隐藏,本地版本号与更新说明照常显示;纯内网建议置 false |
app.login.reset-on-startup | false | 应急通道:关闭本地登录后若外部认证不可用,置 true(或启动时加 JYN_RESET_LOGIN=true)启动一次,会重新开启本地登录并保存;修好后改回 false |
调度设置 按任务
调度分三层:全局默认、任务级覆盖与日志 CDC 常驻消费。全局默认是 sync.poll-interval(默认 2000 毫秒,生效范围收敛到 200ms–24h);任务详情页打开「自定义调度」可单独填写轮询间隔或 Cron,留空即继承全局默认;CDC 任务由长驻消费者实时回放,不参与轮询调度。调度在任务启动后才注册,运行中的任务需要先停止才能修改调度与同步对象。
Cron 使用 Quartz 语法,6 段或 7 段、秒在最前,填写后优先于轮询间隔;表达式在保存与启动时都会校验,非法值直接拒绝。Cron 按服务器时区求值(见上方时区提示);错过的触发会在有空闲线程时补跑一次,而不是静默跳过一整天。
0/2 * * * * ? 每 2 秒 0 0/5 * * * ? 每 5 分钟 0 30 2 * * ? 每天 02:30 0 0 8 ? * MON-FRI 工作日 08:00
连接密码使用 Spring Security Crypto 的 AES-256 加密后存储,
带 enc: 前缀标记以避免重复加密,并兼容加密启用前写入的明文。
元数据库:默认使用 H2 文件库(./data/jync.mv.db),单机开箱即用。
需要多实例或更高可靠性时,可改用外部 MySQL 8、PostgreSQL 16 或 Oracle 23,驱动、URL 与注意事项见
外部元数据库。换库前请停服并备份原 ./data 与密钥文件;
外部元数据库没有本地 <库名>.key,必须显式设置 SYNC_CRYPTO_PASSWORD / SYNC_CRYPTO_SALT。
登录与权限
除登录页与 SSO 入口外,所有页面和接口都必须登录后才能访问
| 用户名 | 角色 | 初始密码 | 权限 |
|---|---|---|---|
admin | 管理员 | 123456 | 全部操作 |
view | 访客 | 123456 | 只读 |
权限按 HTTP 方法判定 设计要点
权限不是按页面枚举的,而是按 HTTP 方法判定:本工具所有的写操作都是 POST, 没有任何 GET 会改动状态,所以规则只有一条 —— POST 一律要求管理员。 这样以后新增接口不会漏配。
管理员
新建/编辑/删除数据库连接、同步任务、AI 供应商;勾选同步对象、启停同步、立即同步、重置进度;起草和保存存储过程转换、清理变更日志。
访客
能看到全部页面和全部数据(看板、连接列表、同步任务详情的勾选状态、变更日志都能看、能选、能复制),但界面上不会出现任何写操作按钮,直接构造请求打接口也会被拒。
app_user 表里对应那行,重启后会重新种回初始密码。
企业统一认证 v1.8.0
管理员可在「配置管理 → 外部认证」(/external-auth)接入企业现有身份体系。三种方式互斥生效,
同一时刻只按配置中的那一种判定身份;外部用户只保留会话,不写入本地 app_user 表,也没有本地改密入口。
账号密码(OA 接口)
Jync 服务端把账号密码 POST 到管理员填写的登录接口,支持表单或 JSON。密码只经过内存,不落库、不写日志。
网关头
网关 / 反向代理完成登录后传递用户标识。Jync 只采信直接 TCP 对端位于回环或 app.security.trusted-proxies 内的请求,网关必须剥离客户端伪造的身份头。
票据 / SSO
登录中心签发一次性 ticket 后跳回 /sso/entry?ticket=...,Jync 在服务端调用校验地址,校验通过才建立会话;入口按客户端 IP 限流。
POST /login 也会被拒绝;
若外部认证随后不可用,以 JYN_RESET_LOGIN=true 启动一次即可重新打开本地登录并保存,修好外部配置后去掉变量重启。
反向代理或 iframe 嵌入场景另需设置 JYN_COOKIE_SAME_SITE(默认 lax;None 必须同时启用 HTTPS 并设置 JYN_COOKIE_SECURE=true)。
网关头模式要求 Jync 部署在网关之后,不能直接暴露到公网。
升级
下载新版 jar 替换即可,元数据库使用 ddl-auto: update,表结构会自动演进
sudo systemctl stop jync cp jync.jar /opt/jync/jync.jar # 自行构建则是 cp target/jync.jar sudo systemctl start jync
./data 目录。
停机期间源库产生的变更会在重启后由游标机制自动补齐,不会丢失。
升到 v1.2.0 时会自动给连接记录加一列保存用途,启动日志出现
Backfilled source/target role... 即源 / 目标归类完成,详见
更新日志 v1.2.0。
oa_auth_config 表,该表随 ./data 一起备份;
外部认证默认关闭,本地账号登录行为与 1.7.8 一致。新增环境变量 JYN_RESET_LOGIN 与
JYN_COOKIE_SAME_SITE,不设置即使用默认值。旧地址 /oa/settings 会 302 到
/external-auth。本次不改变任何同步、CDC 或类型映射路径。