ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

国产化麒麟系统部署SpringBoot+Vue3全栈项目实战指南

国产化麒麟系统部署SpringBoot+Vue3全栈项目实战指南 1. 项目背景与核心挑战最近在给一个政务项目做技术支撑客户那边指定要用国产化的麒麟操作系统后端是咱们熟悉的SpringBoot前端则是Vue 3。这个组合本身没什么稀奇但一放到国产化环境里从开发机到部署服务器的全链路就冒出来一堆在普通Linux上遇不到的“特色问题”。比如麒麟系统自带的软件源可能没有你想要的某个依赖的最新版或者某些基于glibc的二进制包在麒麟的musl libc环境下直接趴窝。更别提那些需要特定内核模块或驱动支持的场景了。所以这篇文章不是一篇简单的“安装Nginx配置反向代理”的教程。我想聊的是如何在一个以麒麟为代表的、可能带有定制化特性的Linux发行版上把一个前后端分离的项目从头到尾、稳定可靠地跑起来。这中间涉及到环境适配、依赖管理、服务配置和运维监控等一系列实操细节。如果你手头也有类似的国产化交付任务或者单纯想了解在非主流Linux发行版上部署Java和Node.js应用的完整流程那接下来的内容应该能帮你避开不少坑。2. 麒麟系统环境准备与依赖梳理部署的第一步永远不是急着去敲命令而是搞清楚你的“战场”环境。麒麟系统虽然底层也是Linux但不同的版本如桌面版、服务器版、针对不同CPU架构的版本和不同的更新状态其软件生态和系统配置可能存在差异。2.1 系统信息确认与基础环境配置首先通过SSH登录到你的麒麟服务器执行几个命令来摸清家底# 查看系统版本和内核信息 cat /etc/os-release uname -a # 查看CPU架构重要这决定了你后续要下载的JDK、Node.js是x86_64还是aarch64版本 arch记下这些信息。接下来更新系统包管理器并安装一些基础工具这些工具在后续的部署和排错中会经常用到# 假设使用的是yum包管理器麒麟服务器版常用 sudo yum update -y sudo yum install -y wget curl tar gzip vim net-tools lsof # 如果系统使用的是apt某些麒麟桌面版或衍生版则对应为 # sudo apt update sudo apt install -y wget curl tar gzip vim net-tools lsof这里有个小经验在国产化系统上默认的软件源速度有时不尽人意或者缺少一些较新的软件包。如果条件允许并且符合单位的安全规定可以考虑配置一个更快的国内镜像源比如清华源或阿里云源能极大提升后续安装依赖的速度。具体替换方法需要根据你的麒麟系统版本去对应镜像站查找指导。2.2 Java运行环境JRE/JDK安装与验证SpringBoot应用离不开Java环境。在麒麟上安装JDK我推荐直接使用Oracle JDK或OpenJDK的预编译压缩包而不是通过系统包管理器安装。原因有二一是版本可控避免系统源中的版本过旧二是避免与系统其他可能依赖的Java组件产生冲突。前往官网或国内镜像站下载根据你之前查到的CPU架构如x86_64或aarch64下载对应版本的JDK 8或JDK 11SpringBoot 2.x/3.x的常用版本的.tar.gz包。例如下载OpenJDK 11wget https://mirrors.tuna.tsinghua.edu.cn/Adoptium/11/jdk/x64/linux/OpenJDK11U-jdk_x64_linux_hotspot_11.0.22_7.tar.gz # 注意将URL中的x64替换为aarch64如果你的CPU是ARM架构。解压并配置环境变量# 创建统一的软件安装目录方便管理 sudo mkdir -p /usr/local/java sudo tar -zxvf OpenJDK11U-jdk_x64_linux_hotspot_11.0.22_7.tar.gz -C /usr/local/java/ # 编辑全局环境变量配置文件 sudo vim /etc/profile在文件末尾添加以下内容请将jdk-11.0.227替换为实际解压出的文件夹名export JAVA_HOME/usr/local/java/jdk-11.0.227 export JRE_HOME${JAVA_HOME}/jre export CLASSPATH.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH${JAVA_HOME}/bin:$PATH使配置生效并验证source /etc/profile java -version如果正确显示Java版本信息说明安装成功。这一步务必做我遇到过因为JAVA_HOME路径末尾多了个斜杠导致java -version报错的情况。2.3 Node.js与NPM环境安装对于Vue项目我们需要Node.js来构建build生产环境的静态文件。同样建议使用二进制包安装。下载Node.js二进制包访问Node.js官网或国内镜像选择Linux二进制包.tar.xz格式同样注意架构匹配。例如下载Node.js 18 LTS版本wget https://npmmirror.com/mirrors/node/v18.19.0/node-v18.19.0-linux-x64.tar.xz解压并配置sudo mkdir -p /usr/local/nodejs sudo tar -xJf node-v18.19.0-linux-x64.tar.xz -C /usr/local/nodejs/ # 编辑/etc/profile在刚才的Java配置后面追加 export NODE_HOME/usr/local/nodejs/node-v18.19.0-linux-x64 export PATH${NODE_HOME}/bin:$PATH生效并验证source /etc/profile node -v npm -v注意有些特别“纯净”或定制的麒麟系统镜像可能缺少Node.js运行所需的底层库如libstdc等。如果你在运行node命令时遇到类似“找不到动态链接库”的错误可能需要根据报错信息使用yum install或apt install来补充安装这些系统库。2.4 数据库与中间件准备根据你的SpringBoot项目配置可能需要MySQL、PostgreSQL、Redis等。在麒麟系统上优先考虑使用Docker容器化部署这些中间件。这能完美解决依赖库兼容性问题也便于版本管理和数据迁移。如果因为安全策略无法使用Docker则需通过系统包管理器安装。以MySQL 8.0为例可能需要先添加官方的MySQL软件源然后再安装。这个过程需要仔细核对麒麟系统的版本与MySQL源的兼容性否则很容易在安装过程中出现依赖冲突。3. 后端SpringBoot应用部署实战环境就绪后我们开始部署后端。目标是将SpringBoot的Jar包以一个稳定、可监控的系统服务形式运行起来。3.1 应用打包与传输在你的开发机器上使用Maven或Gradle将SpringBoot项目打包成可执行的Jar文件。# 在项目根目录下 mvn clean package -DskipTests打包后通常在target目录下会生成一个形如your-app-0.0.1-SNAPSHOT.jar的文件。通过scp命令或SFTP工具将这个Jar包上传到麒麟服务器的某个专用目录例如/home/yourname/app/backend/。建议为应用创建一个专属的系统用户来运行提升安全性sudo useradd -r -s /bin/false apprunner sudo mkdir -p /home/apprunner/backend sudo chown -R apprunner:apprunner /home/apprunner/backend # 然后将Jar包上传或移动到该目录并确保所属权正确3.2 创建Systemd服务单元使用Systemd来管理SpringBoot应用是目前最规范、最可靠的方式。它提供了自动重启、日志集成、开机自启等功能。创建服务配置文件sudo vim /etc/systemd/system/your-springboot-app.service编写服务单元内容以下是一个高度可用的配置模板你需要修改Description、ExecStart的Jar包路径、User以及Environment中的配置文件路径。[Unit] DescriptionYour SpringBoot Application Afternetwork.target syslog.target # 如果依赖数据库可以加上 Aftermysql.service 或 docker.service [Service] Typesimple Userapprunner Groupapprunner # 指定工作目录方便应用读写当前目录下的文件如日志 WorkingDirectory/home/apprunner/backend # 启动命令。这里假设使用外部application-prod.yml配置文件 ExecStart/usr/local/java/jdk-11.0.227/bin/java -jar -Dspring.profiles.activeprod -Dspring.config.location/home/apprunner/backend/config/application-prod.yml /home/apprunner/backend/your-app-0.0.1-SNAPSHOT.jar # 应用特定的环境变量例如设置时区 EnvironmentTZAsia/Shanghai # 如果应用需要访问某些特定路径可以在这里设置安全上下文针对SELinux/AppArmor麒麟可能有关似机制 # ReadWritePaths/var/lib/yourapp/data # 关键的重启策略 Restartalways RestartSec10 # 如果应用在120秒内没有成功启动则认为失败 StartLimitInterval120s StartLimitBurst3 # 资源限制根据实际情况调整 LimitNOFILE65536 LimitNPROC4096 # 标准输出和错误输出重定向到系统日志journalctl StandardOutputjournal StandardErrorjournal SyslogIdentifieryour-springboot-app [Install] WantedBymulti-user.target重要参数解析User/Group: 使用非root用户运行是基本的安全准则。WorkingDirectory: 设定后应用中的相对路径比如./logs/都会基于此目录。-Dspring.config.location: 这是一个好习惯。将生产环境的配置文件application-prod.yml放在Jar包外部与代码分离修改配置无需重新打包。Restartalways: 确保应用崩溃后自动重启。StartLimitInterval和StartLimitBurst: 防止应用在短时间内不断崩溃重启形成“重启风暴”。这里配置为120秒内最多重启3次超过后systemd会停止尝试需要人工介入排查。启动服务并设置开机自启# 重新加载systemd配置 sudo systemctl daemon-reload # 启动服务 sudo systemctl start your-springboot-app # 查看服务状态和实时日志 sudo systemctl status your-springboot-app sudo journalctl -u your-springboot-app -f # 启用开机自启 sudo systemctl enable your-springboot-app3.3 生产环境配置与外置化强烈建议将application.yml中所有与环境相关的配置数据库连接、Redis地址、第三方API密钥等抽取到一个独立的application-prod.yml文件中并放在Jar包外的目录如上面配置的/home/apprunner/backend/config/。这样做的好处是安全敏感信息不进入代码仓库和构建产物。灵活不同环境测试、生产只需替换配置文件无需重新构建。便捷修改配置后只需重启服务sudo systemctl restart your-springboot-app无需重新部署Jar包。你的application-prod.yml可能长这样spring: datasource: url: jdbc:mysql://localhost:3306/your_db?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai username: prod_user password: ${DB_PASSWORD:} # 可以考虑从环境变量读取更安全 redis: host: localhost port: 6379 password: ${REDIS_PASSWORD:} server: port: 8080 # 后端应用端口 servlet: context-path: /api # 统一API前缀 logging: file: name: /home/apprunner/backend/logs/app.log # 日志输出到外部文件便于收集 level: com.yourcompany: DEBUG4. 前端Vue项目构建与Nginx部署前端部分的核心在于将Vue源代码构建成静态文件HTML, CSS, JS然后通过一个高性能的Web服务器如Nginx对外提供服务。4.1 生产环境构建与优化在构建服务器可以是你的开发机也可以是麒麟服务器本身上进入Vue项目根目录。安装依赖并构建# 确保使用正确的Node.js版本可以使用nvm管理 npm install --registryhttps://registry.npmmirror.com # 使用国内镜像加速 npm run build # 默认会执行 vue-cli-service build执行成功后会在项目根目录下生成一个dist文件夹里面就是构建好的静态资源。构建配置要点环境变量在项目根目录创建.env.production文件定义生产环境变量如VUE_APP_API_BASE_URL/api。这个变量可以在代码中通过process.env.VUE_APP_API_BASE_URL访问用于动态配置后端API地址。路由模式如果使用Vue Router的history模式需要在Nginx配置中做额外的重写规则后面会讲。对于新手或简单项目使用hash模式URL带#可以省去这个麻烦。资源路径检查vue.config.js中的publicPath配置通常生产环境设置为./相对路径或/绝对路径取决于你的部署目录结构。4.2 Nginx安装与核心配置在麒麟服务器上安装Nginxsudo yum install -y nginx # 或使用 apt: sudo apt install -y nginxNginx的核心配置文件是/etc/nginx/nginx.conf但最佳实践是在/etc/nginx/conf.d/目录下为每个站点创建独立的.conf文件。创建前端站点配置sudo vim /etc/nginx/conf.d/your-vue-app.conf编写Nginx配置以下配置实现了静态文件服务、反向代理后端API、以及处理Vue Router的history模式。server { listen 80; server_name your-domain.com; # 替换为你的域名或服务器IP # 如果你有SSL证书建议启用443端口并配置HTTPS此处以HTTP为例 # 前端静态资源目录 root /home/apprunner/frontend/dist; index index.html index.htm; # 开启gzip压缩提升传输效率 gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/javascript application/xmlrss application/json; # 核心配置处理Vue Router的history模式 # 当请求的路径不是真实存在的文件或目录时将请求重定向到index.html location / { try_files $uri $uri/ /index.html; } # 反向代理后端API请求 # 假设你的SpringBoot应用运行在8080端口且设置了context-path/api location /api/ { # 重写URL去掉/api前缀或者根据后端需要传递 # rewrite ^/api/(.*)$ /$1 break; proxy_pass http://127.0.0.1:8080; # 后端服务地址 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 如果后端服务需要较长时间处理可调整超时时间 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } # 可选静态资源缓存策略减轻服务器压力 location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2?|ttf|svg|eot)$ { expires 1y; add_header Cache-Control public, immutable; access_log off; } # 错误页面配置 error_page 404 /index.html; # 对于SPA404也返回首页 error_page 500 502 503 504 /50x.html; location /50x.html { root /usr/share/nginx/html; } }部署静态文件并启动Nginx# 将之前构建好的dist文件夹内容上传到服务器指定目录 sudo mkdir -p /home/apprunner/frontend # 假设你已经将dist文件夹内容上传到了该目录 sudo chown -R nginx:nginx /home/apprunner/frontend # 确保Nginx进程有读取权限 # 测试Nginx配置语法 sudo nginx -t # 如果显示syntax is ok则重新加载配置 sudo systemctl reload nginx # 查看Nginx状态 sudo systemctl status nginx # 设置开机自启 sudo systemctl enable nginx4.3 防火墙与端口放行确保服务器的防火墙如firewalld或iptables允许HTTP(80)和HTTPS(443)端口以及后端SpringBoot应用可能用到的端口如8080如果它需要被外部直接访问的话但通常我们只通过Nginx反向代理访问。# 如果使用firewalld sudo firewall-cmd --permanent --add-servicehttp sudo firewall-cmd --permanent --add-servicehttps sudo firewall-cmd --reload # 如果使用较旧的iptables或firewalld未安装可能需要直接操作iptables规则谨慎操作5. 部署后的验证、监控与排错服务跑起来不是终点确保它稳定、可观测才是关键。5.1 基础功能验证端口监听检查sudo netstat -tlnp | grep -E (80|443|8080)确认Nginx和SpringBoot应用正在监听预期的端口。服务状态检查sudo systemctl status nginx sudo systemctl status your-springboot-app确保状态为active (running)。前端页面访问在浏览器中输入服务器IP或域名检查前端页面是否能正常加载样式和交互是否完整。API接口测试打开浏览器开发者工具F12的“网络(Network)”选项卡刷新页面查看对/api/前缀的请求是否成功状态码为200或业务正常码。也可以使用curl命令测试curl http://localhost/api/your-endpoint5.2 日志查看与监控日志是排错的第一手资料。Nginx访问日志与错误日志默认路径通常在/var/log/nginx/access.log和/var/log/nginx/error.log。使用tail -f命令可以实时查看。SpringBoot应用日志我们在application-prod.yml中指定了日志文件路径/home/apprunner/backend/logs/app.log。同样使用tail -f查看。Systemd Journal日志对于通过systemd管理的服务可以使用journalctl查看更详细的系统级日志这对于诊断服务启动失败特别有用# 查看某个服务的所有日志 sudo journalctl -u your-springboot-app # 实时跟踪最新日志 sudo journalctl -u your-springboot-app -f # 查看指定时间段的日志 sudo journalctl -u your-springboot-app --since 2024-01-01 00:00:00 --until 2024-01-02 00:00:005.3 常见问题与排错思路前端页面空白或资源加载失败404检查Nginx的root目录配置确认root指向的路径/home/apprunner/frontend/dist确实存在且包含index.html。检查文件权限确保Nginx进程用户通常是nginx对dist目录及其所有父目录至少有读取(r)和执行(x)权限。可以尝试sudo chmod -R 755 /home/apprunner/frontend/dist。检查Nginx错误日志tail -f /var/log/nginx/error.log看是否有权限拒绝等错误。前端页面能打开但所有API请求都失败502 Bad Gateway检查后端服务是否运行sudo systemctl status your-springboot-app。检查后端端口是否监听sudo netstat -tlnp | grep :8080。检查Nginx的proxy_pass地址确保proxy_pass http://127.0.0.1:8080;中的端口与后端服务实际监听端口一致。检查后端服务日志查看SpringBoot应用日志看是否有启动异常或处理请求时的错误。Vue Router的history模式刷新后404确认Nginx配置这是最常见原因。必须确保在location /块中配置了try_files $uri $uri/ /index.html;。这条指令的意思是Nginx会先尝试寻找请求路径对应的真实文件如/css/app.css如果找不到再尝试寻找目录如果还找不到最后将请求交给/index.html处理由Vue应用内部的路由器来解析路径。检查vue.config.js中的publicPath如果部署在子路径如http://domain.com/myapp/需要将publicPath设置为/myapp/并且Nginx的root和try_files配置也要相应调整。SpringBoot应用启动失败查看详细日志使用sudo journalctl -u your-springboot-app -xe查看启动失败的详细原因。常见原因Java版本不匹配应用编译版本与运行环境版本不一致。用java -version确认。端口被占用Address already in use。使用sudo lsof -i:8080查看哪个进程占用了端口。数据库连接失败检查application-prod.yml中的数据库连接字符串、用户名、密码以及数据库服务是否已启动并可访问。配置文件路径错误检查systemd服务文件中-Dspring.config.location指定的路径和文件是否存在且格式正确。内存不足JVM因内存不足无法启动。可以在systemd服务文件的ExecStart行调整JVM参数例如-Xms256m -Xmx512m。6. 进阶考量安全、性能与持续集成基础部署完成后为了项目的长期稳定运行还需要考虑以下几个方面。6.1 安全加固建议使用非root用户运行服务我们已经在前面的systemd配置中使用了apprunner用户这很好。配置HTTPS使用Let‘s Encrypt等免费证书服务为你的域名申请SSL证书并在Nginx中配置443端口强制HTTP跳转到HTTPS。这是现代Web应用的标配。限制不必要的端口暴露确保防火墙只开放80、443等必要端口。后端SpringBoot的端口如8080不应该对公网开放只允许本机127.0.0.1或内部网络访问通过Nginx反向代理来暴露API。定期更新关注麒麟系统、Nginx、Java、Node.js的安全更新并及时在测试环境验证后应用到生产环境。敏感信息管理数据库密码、API密钥等绝不要硬编码在配置文件中。可以使用环境变量传入或者使用专门的密钥管理服务。在systemd服务文件中可以通过Environment指令设置环境变量。6.2 性能优化点Nginx优化调整Worker进程和连接数根据服务器CPU核心数在/etc/nginx/nginx.conf的events块中调整worker_connections在顶层调整worker_processes。启用缓存对于不常变动的API响应可以考虑使用Nginx的proxy_cache进行缓存。静态资源缓存如前面配置所示为图片、CSS、JS等静态资源设置长期缓存并添加immutable属性。SpringBoot优化JVM调优根据应用实际内存使用情况在systemd服务文件的ExecStart中调整JVM堆内存-Xms,-Xmx、垃圾回收器等参数。连接池配置优化数据库连接池如HikariCP和Redis连接池的参数避免连接泄露或不足。启用GZIP压缩在application-prod.yml中配置server.compression.enabledtrue对API响应进行压缩。前端构建优化代码分割与懒加载利用Vue Router的懒加载和Webpack的动态导入将代码拆分成多个小块减少首屏加载体积。CDN引入公共库将Vue、Vuex、Element-Plus等稳定的大型库通过CDN引入减小vendor.js的体积。6.3 简单的持续部署思路对于小型团队或个人项目可以建立一个简单的自动化部署流程。在服务器上搭建Git仓库在服务器上创建一个裸仓库bare repo。配置Git Hooks在裸仓库的hooks/post-receive脚本中编写自动化脚本。这个脚本会在你本地git push到服务器后自动执行。自动化脚本内容脚本可以包含以下步骤cd到前端和后端项目的实际部署目录。git pull拉取最新代码。对于后端运行mvn clean package如果服务器有Maven环境然后systemctl restart your-springboot-app。对于前端运行npm install npm run build然后将新的dist目录内容复制到Nginx的root目录下。可以加入简单的测试和回滚逻辑。这样每次代码更新后只需要一个git push命令就能自动完成构建和部署极大提升了效率。当然对于更复杂的项目建议使用Jenkins、GitLab CI/CD或GitHub Actions等成熟的CI/CD工具。
返回列表