之前负责的一个老项目需要做国产化环境迁移,业务代码本身改动不大,但底层的操作系统、数据库和部署方式几乎全部换了一遍。刚开始接触 openEuler 和 openGauss 时,确实有一种“又要踩一遍坑”的预感,真正把一套 Spring Boot 服务在国产化环境里跑通之后才发现,这套技术栈的成熟度已经比想象中高很多。所以想借这篇文章,把完整的适配过程记录下来,包括环境准备、数据库初始化、Spring Boot 连接配置、打包部署和常见问题排查。无论你是在做国产化适配,还是单纯想学习 openGauss,这篇文章都可以作为一份落地参考。
1. “中国人能飞”与国产化技术栈:一个开发者的理解
1.1 这个标题背后的技术背景
“中国人能飞”这个说法,放在技术语境里,可以理解成一种对国产基础软件快速发展的直观感受。过去很长一段时间,企业的后端应用基本上跑在 CentOS / Ubuntu 上,数据库首选 MySQL 或 Oracle,中间件和开发框架也以国外开源生态为主。这套组合虽然成熟稳定,但也带来了一个问题:底层技术底座一旦出现变化,整个业务系统都要跟着做适配。
最近几年,国产操作系统和国产数据库逐渐进入生产环境。以 openEuler 为代表的操作系统、以 openGauss 为代表的关系型数据库,开始在政务、金融、能源、制造业等场景中承担核心业务。对普通开发同学来说,这意味着一个很实际的需求:我熟悉的是 Spring Boot + MySQL 这一套技术组合,现在要迁移到 openEuler + openGauss,到底应该怎么做?
这篇文章要解决的就是这个问题。我会从零开始,把一套 Spring Boot 应用在 openEuler 系统上对接 openGauss 数据库的完整流程走一遍,让没有接触过国产化技术栈的开发者也能照着操作。
1.2 国产化技术栈包含哪些内容
这里说的国产化技术栈,通常指芯片、操作系统、数据库、中间件、办公软件等层面的自主技术体系。对于后端开发者来说,最常接触的是下面三层:
| 层次 | 常见产品 | 对应开发场景 |
|---|---|---|
| 操作系统 | openEuler、麒麟、统信 UOS | 服务器部署、容器镜像、CI/CD 运行环境 |
| 数据库 | openGauss、达梦、人大金仓 | 业务数据存储、事务处理、SQL 编写 |
| 中间件 / 开发框架 | Spring Boot / Spring Cloud、东方通等 | 业务应用开发、微服务治理 |
这些年国产数据库的发展速度非常快。以 openGauss 为例,它是一款开源关系型数据库,基于 PostgreSQL 内核发展而来,同时在性能、安全能力、SQL 兼容性上做了很多增强。也就是说,如果你熟悉 PostgreSQL 或 MySQL 的开发习惯,那么上手 openGauss 的代价并不高。
1.3 为什么值得学习一套国产化技术栈
从技术角度出发,学习国产化技术栈有几个实际收益。
一方面,它能扩展你的技术视野。openGauss 在 SQL 语法、索引设计、事务隔离级别、备份恢复等方面都有自己的实现细节,单纯凭借 MySQL 的经验去理解,会漏掉很多关键点。
另一方面,这类技能的需求正在增加。很多企业都在做存量系统的国产化适配改造,市场上熟悉 openGauss、openEuler 的开发者相对稀缺,如果你能在平时积累一些适配经验,在项目竞标、技术选型和面试中都会更从容。
最重要的一点是:国产化技术栈本质上仍然是 Linux 生态上的数据库和操作系统,核心知识和我们熟悉的 Java 后端开发并没有断裂。你不需要把以前学的 Spring Boot 知识推翻重来,只需要补充环境适配和配置层面的经验。这种“技术连续性”正是大家应该学习它的信心来源。
2. 环境准备与版本说明
2.1 硬件与操作系统
本文的示例环境基于 x86 架构服务器,操作系统使用 openEuler 22.03 LTS。如果你使用的是 aarch64(鲲鹏/飞腾)架构,安装步骤整体一致,但部分依赖包需要选择对应架构的版本。
openEuler 的安装方式有三种:
- 物理服务器安装:适合生产环境,通过 ISO 镜像安装。
- 虚拟机安装:适合学习和测试,使用 VMware 或 VirtualBox 都可以。
- 云服务器/容器环境:部分云厂商已经提供 openEuler 镜像,可以直接创建云主机。
本文推荐在虚拟机中完成学习验证,这样可以随时快照回滚,避免因为误操作导致环境损坏。
2.2 软件版本清单
| 组件 | 本文示例版本 | 说明 |
|---|---|---|
| 操作系统 | openEuler 22.03 LTS | 实际部署请以你手上的 ISO 版本为准 |
| 数据库 | openGauss 5.0.0 | openGauss 安装包可以从官网下载 |
| JDK | OpenJDK 1.8 或 11 | 本文示例使用 JDK 8 |
| 构建工具 | Maven 3.6+ | 用于项目编译打包 |
| 开发框架 | Spring Boot 2.7.x | 稳定版本,示例以 2.7 系列为主 |
版本需要根据你的项目实际情况调整,本文示例以常见环境为例,重点演示配置思路。安装 openGauss 之前,建议先确认服务器的 CPU 架构和操作系统版本,避免下载错误的安装包。
2.3 环境检查
登录 openEuler 之后,可以先执行几个基础命令,确认系统环境。
# 查看操作系统版本 cat /etc/openEuler-release # 查看 CPU 架构 uname -m # 查看内存和磁盘 free -h df -h # 查看防火墙状态 systemctl status firewalld如果内存小于 2GB,openGauss 跑起来会比较吃力,建议至少分配 4GB 内存。数据库安装目录需要预留足够的磁盘空间,一般建议 20GB 以上。
3. openGauss 数据库安装与初始化
3.1 创建 openGauss 专用系统用户
openGauss 不允许使用 root 用户直接初始化数据库,这是它的安全设计之一。安装之前需要创建一个普通系统用户,用来执行数据库的安装、初始化和启停操作。
这里假设我们创建一个名为omm的用户。
# 创建用户组和用户 groupadd dbgrp useradd -g dbgrp -m -s /bin/bash omm # 设置密码 passwd omm创建完成后,把安装包上传到服务器,并切换到omm用户进行后续操作。
3.2 软件安装与依赖检查
openGauss 安装包通常是一个tar.gz压缩包。解压之后里面包含install.sh脚本和lib、bin等目录。安装之前需要确保系统中有 Python、gcc 等基础依赖。
# 使用 omm 用户解压安装包 tar -zxvf openGauss-5.0.0-openEuler-x86_64.tar.gz # 进入解压目录,执行安装脚本 cd openGauss-5.0.0-openEuler-x86_64 ./install.sh -w "YourPassword@123" -p /opt/openGauss安装参数说明:
-w:指定数据库超级用户omm的初始密码,密码需要满足复杂度要求,建议包含大写字母、小写字母、数字和特殊字符。-p:指定数据库的安装目录,也可以使用默认目录。
安装脚本执行完毕之后,数据库会自动初始化并启动。如果中间报错,通常是缺少系统依赖导致的,需要根据错误提示补齐依赖包后重新执行。
3.3 启动数据库与配置远程访问
openGauss 默认监听本地地址,如果我们的 Spring Boot 应用部署在另一台服务器上,就需要修改监听配置,允许远程连接。
数据库配置文件位于安装目录下的data目录中,常见路径是/opt/openGauss/data。需要修改两个文件:
第一个是postgresql.conf,将listen_addresses配置为远程访问地址。
# 文件路径:/opt/openGauss/data/postgresql.conf listen_addresses = '*'第二个是pg_hba.conf,配置允许访问的客户端 IP 和认证方式。
# 文件路径:/opt/openGauss/data/pg_hba.conf # 根据自己的业务网段设置,这里示例允许整个 192.168.1.0/24 网段访问 host all all 192.168.1.0/24 md5修改之后重启数据库。
# 使用 omm 用户执行 gs_ctl restart -D /opt/openGauss/data3.4 创建业务数据库和账号
生产环境不允许直接使用超级用户omm连接业务数据库,正确的做法是创建一个独立的业务账号,并赋予最小权限。
使用gsql命令行工具连接数据库:
gsql -d postgres -p 5432连接成功后,执行下面的 SQL 创建业务数据库和账号:
-- 创建业务专用数据库 CREATE DATABASE demo_db; -- 创建业务账号,并设置密码 CREATE USER demo_user PASSWORD 'DemoUser@123'; -- 授权 GRANT ALL PRIVILEGES ON DATABASE demo_db TO demo_user;注意:openGauss 对密码复杂度有要求,如果密码过于简单,会直接报错。这一步也和常见的 MySQL 创建用户操作很相似,区别主要在于语法细节。
4. Spring Boot 项目搭建与数据库适配
4.1 创建 Maven 项目
我们可以用 IDE 直接创建一个 Spring Boot 项目,也可以手动维护 pom.xml。这里给出一个最基础的 Maven 配置,使用 Spring Boot 2.7.x 版本。
<!-- 文件路径:pom.xml --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.18</version> <relativePath/> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!-- Spring Boot Web 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- JDBC 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- MyBatis 可选,本文为了简化,使用 Spring JDBC 示例 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.3.2</version> </dependency> </dependencies>4.2 引入 openGauss 数据库驱动
openGauss 官方提供了 JDBC 驱动,安装方式有两种:
方式一:Maven 依赖
如果你的 Maven 仓库可以访问 openGauss 驱动,可以添加下面的依赖。不同版本坐标可能不同,请以官方文档为准。
<dependency> <groupId>org.opengauss</groupId> <artifactId>opengauss-jdbc</artifactId> <version>5.0.0</version> </dependency>方式二:手动安装本地 jar
如果上面这个坐标在你们仓库里拉取不到,可以到 openGauss 官网下载对应版本的 JDBC 驱动 jar 包,然后手动安装到本地 Maven 仓库。
mvn install:install-file \ -Dfile=opengauss-jdbc-5.0.0.jar \ -DgroupId=org.opengauss \ -DartifactId=opengauss-jdbc \ -Dversion=5.0.0 \ -Dpackaging=jar这里需要特别说明:openGauss 与 PostgreSQL 协议兼容,所以也有团队直接使用 PostgreSQL 的 JDBC 驱动连接 openGauss。但要获得完整的特性支持,更推荐使用 openGauss 官方驱动。
4.3 编写 application.yml 配置
在src/main/resources目录下创建application.yml,配置数据源信息。openGauss 的 JDBC URL 前缀是jdbc:opengauss://,这点和 MySQL 的jdbc:mysql://不同。
# 文件路径:src/main/resources/application.yml server: port: 8080 spring: datasource: driver-class-name: org.opengauss.Driver url: jdbc:opengauss://192.168.1.100:5432/demo_db username: demo_user password: DemoUser@123 jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 mybatis: mapper-locations: classpath:mapper/*.xml configuration: map-underscore-to-camel-case: true配置项解释:
driver-class-name:指定 openGauss 的 JDBC 驱动类。url:数据库连接地址,格式为jdbc:opengauss://IP:端口/数据库名。map-underscore-to-camel-case:开启下划线转驼峰,便于把数据库字段映射到 Java 实体类属性。
4.4 编写基础 CRUD 示例
为了方便验证数据库连接是否正常,我们创建一个简单的用户表,并实现新增、查询功能。
先创建数据库表:
-- 在 openGauss 中执行 CREATE TABLE sys_user ( id SERIAL PRIMARY KEY, username VARCHAR(50) NOT NULL, email VARCHAR(100), create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP );创建对应的实体类:
// 文件路径:src/main/java/com/example/demo/entity/SysUser.java package com.example.demo.entity; import java.time.LocalDateTime; public class SysUser { private Long id; private String username; private String email; private LocalDateTime createTime; // 省略 getter 和 setter,实际操作时需要补充完整 }创建 Mapper 接口:
// 文件路径:src/main/java/com/example/demo/mapper/SysUserMapper.java package com.example.demo.mapper; import com.example.demo.entity.SysUser; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @Mapper public interface SysUserMapper { int insert(@Param("username") String username, @Param("email") String email); SysUser findById(@Param("id") Long id); }创建 Mapper XML:
<!-- 文件路径:src/main/resources/mapper/SysUserMapper.xml --> <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.demo.mapper.SysUserMapper"> <insert id="insert"> INSERT INTO sys_user (username, email) VALUES (#{username}, #{email}) </insert> <select id="findById" resultType="com.example.demo.entity.SysUser"> SELECT id, username, email, create_time FROM sys_user WHERE id = #{id} </select> </mapper>创建 Service 和 Controller,提供一个测试接口:
// 文件路径:src/main/java/com/example/demo/controller/UserController.java package com.example.demo.controller; import com.example.demo.entity.SysUser; import com.example.demo.mapper.SysUserMapper; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/user") public class UserController { private final SysUserMapper sysUserMapper; public UserController(SysUserMapper sysUserMapper) { this.sysUserMapper = sysUserMapper; } @PostMapping public String add(@RequestParam String username, @RequestParam String email) { sysUserMapper.insert(username, email); return "success"; } @GetMapping("/{id}") public SysUser get(@PathVariable Long id) { return sysUserMapper.findById(id); } }到这里,一个最基本的 Spring Boot + openGauss 应用就已经完成了。
5. 部署到 openEuler 并验证
5.1 项目打包
在本地开发环境执行 Maven 打包命令。
mvn clean package -DskipTests打包成功后,在target目录下会生成一个可执行的 jar 包,例如demo-0.0.1-SNAPSHOT.jar。
5.2 上传并运行
将 jar 包上传到 openEuler 服务器,然后使用 Java 命令启动。
# 文件路径:假设 jar 包放在 /opt/app 目录下 java -jar /opt/app/demo-0.0.1-SNAPSHOT.jar如果想让应用在后台运行,可以使用nohup:
nohup java -jar /opt/app/demo-0.0.1-SNAPSHOT.jar > app.log 2>&1 &启动成功后,日志中会出现Started DemoApplication的提示。
5.3 接口验证
在服务器本地或本地开发机发起请求,验证接口是否正常。
# 新增用户 curl -X POST "http://192.168.1.100:8080/user?username=chinese&email=chinese@example.com" # 查询用户 curl "http://192.168.1.100:8080/user/1"如果新增接口返回success,查询接口返回用户数据,说明应用已经成功连接 openGauss 数据库。到这里,“中国人能飞”这个标题背后的技术路线,已经可以完整跑通了。
6. 常见问题与排查思路
在 openEuler + openGauss 环境下部署 Spring Boot 应用,最容易出问题的环节有三个:数据库安装、远程连接、JDBC 驱动兼容性。下面整理一份常见问题排查表。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| openGauss 安装脚本执行失败 | 系统缺少依赖包 | 根据日志安装 gcc、python3、libaio 等依赖后再执行 |
| 数据库启动失败 | data 目录权限错误 | 确认 data 目录属主为 omm 用户,使用 omm 用户启动 |
| 远程连接提示 no pg_hba.conf entry | pg_hba.conf 未配置客户端网段 | 在 pg_hba.conf 中加入正确的 IP 网段并重启数据库 |
| 连接时提示 password authentication failed | 密码密码复杂度不合规 | 使用包含大写、小写、数字、特殊字符的密码 |
| JDBC 驱动类找不到 | 缺少 opengauss-jdbc 依赖 | 确认 pom.xml 依赖或本地仓库 jar 是否安装成功 |
| MyBatis 执行 SQL 时报语法错误 | 分页或自增语法与 openGauss 不兼容 | 检查 SQL 中SERIAL、LIMIT等语法是否兼容 |
| 应用启动很慢或连接超时 | 防火墙未放行端口 | 检查防火墙规则,放行 5432 或 8080 端口 |
下面挑选几个高频问题再展开说明。
6.1 openGauss 数据库无法远程连接
如果本地gsql连接正常,但远程应用连接不上,优先检查三个地方:listen_addresses是否配置为*、pg_hba.conf是否加入了客户端网段、防火墙是否放行 5432 端口。
# 查看监听状态 ss -lntp | grep 5432如果端口没有监听,说明配置没有生效,需要重启数据库。如果端口已经监听但还是连不上,大概率是pg_hba.conf认证规则问题。
6.2 openGauss 密码复杂度不满足要求
openGauss 默认开启了密码复杂度校验。如果你在创建用户或连接时收到类似 “Password does not meet the complexity requirements” 的提示,需要修改密码为更复杂的组合,例如DemoUser@123这种大小写、数字、特殊字符混合的格式。
6.3 MyBatis 使用SERIAL自增主键的问题
openGauss 支持SERIAL类型,但如果你习惯 MySQL 的AUTO_INCREMENT,在 DDL 中就会报语法错误。解决办法是在建表时使用 openGauss 支持的语法,例如:
CREATE TABLE sys_user ( id BIGSERIAL PRIMARY KEY, username VARCHAR(50) NOT NULL );这也说明了一点:国产化适配不只是换一个数据库连接串那么简单,SQL 语法差异才是真正的隐性工作量。
7. 最佳实践与工程建议
7.1 数据库账号与权限最小化
生产环境千万不要用数据库超级账号omm来连接业务系统。每个应用都应该有独立的数据库账号,且只授予它需要的最小权限。例如下面的授权方式,可以让业务账号只能操作demo_db中的表,无法删除数据库。
GRANT USAGE ON SCHEMA public TO demo_user; GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO demo_user;7.2 密码与配置管理
在项目中不要把数据库密码明文写在代码仓库里。建议通过环境变量或配置中心注入。Spring Boot 项目可以使用${DB_PASSWORD}这种占位方式:
spring: datasource: url: ${DB_URL} username: ${DB_USERNAME} password: ${DB_PASSWORD}在启动服务器时再传入真实环境变量:
export DB_URL="jdbc:opengauss://192.168.1.100:5432/demo_db" export DB_USERNAME="demo_user" export DB_PASSWORD="DemoUser@123" java -jar demo.jar这样即使代码仓库泄露,也不会直接暴露生产数据库密码。
7.3 SQL 兼容性与迁移预检
从 MySQL 迁移到 openGauss 时,不要直接复制所有 SQL 脚本。建议先做一次全面的语法扫描,重点关注类型差异、自增策略、分页语法、函数名差异。常用的 MySQL 函数在 openGauss 中可能名称不同,需要提前用文档比对确认。
生产环境执行 DDL 之前,一定要在测试环境先跑一遍,并且把数据库备份做好。openGauss 提供了物理备份和逻辑备份工具,上线前务必演练一次恢复流程。
7.4 日志与监控
应用部署后,建议同时关注应用日志和数据库日志。Spring Boot 应用日志默认输出到控制台,生产环境需要配置logback或log4j2输出到文件并定期归档。数据库侧的慢查询日志也要开启,方便定位 SQL 性能问题。
7.5 版本锁定与可重复发布
部署脚本、依赖版本、应用版本都要做到可追溯。推荐把下面这些内容固定下来:
- JDK 版本
- openGauss 驱动版本
- Spring Boot 版本
- 初始化 SQL 脚本版本
- 部署脚本版本
版本一旦升级,必须走测试环境回归验证。
8. 结语:下一步可以做什么
这篇文章从“中国人能飞”这个标题出发,完整走了一遍国产化技术栈下的 Spring Boot 应用适配之旅。实际做下来你会发现,openEuler、openGauss 本质上仍然是 Linux 生态和关系型数据库,之前积累的 Java 开发能力完全可以复用到这个技术栈上,真正需要额外学习的,主要集中在安装部署、SQL 兼容性和运维习惯这几个方面。
如果你正打算在自己的项目里尝试这套技术组合,建议按照下面的顺序推进:先在一台虚拟机上安装 openEuler 和 openGauss,把命令行操作和数据库管理跑熟;再基于本文的 Spring Boot 示例项目,把 CRUD 接口跑通;最后再做一次完整的备份恢复演练。
把最基础的链路跑通之后,再去看分区表、物化视图、高级安全特性这些进阶功能,就会发现国产数据库能做的事情已经很多了。对于普通开发者来说,这既是新技能的积累,也是技术视野的一次扩展。