ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于WEB的个人知识管理系统部署指南:从zip解压到实战运行

基于WEB的个人知识管理系统部署指南:从zip解压到实战运行 简介基于WEB的个人知识管理系统完整源码包面向计算机相关专业毕业生或初、中级Web开发者是一份毕业设计级别的项目范本。系统围绕知识采集、分类、存储、检索与共享等核心功能展开结合Python后端与HTML/CSS/JS前端可帮助读者理解个人知识管理平台的完整实现路径。压缩包共505个文件约21.42MB主要包含Python脚本、HTML页面、CSS样式、JavaScript交互文件以及图片和字体图标等静态资源另附部署相关配置文件便于梳理项目结构和运行环境。目前已有44人学习适合作为毕业设计参考或Web开发练手项目。通过源码可掌握个人知识管理系统的前后端设计、数据库配置与基础部署方式也能借鉴其中文件分类、模块划分与静态资源组织思路为自己的项目或论文提供落地参考。1. 基于WEB的个人知识管理系统一个 zip 包里的核心资产是什么刚拿到一个基于WEB的个人知识管理系统.zip 时多数人的第一反应是解压后立刻打开 README找启动类。但这类 zip 能不能真正跑起来往往不取决于代码而取决于三样东西数据库初始化脚本是否完整、上传目录是否写死、以及这套系统有没有做历史版本表。这个标题描述的是一个打包成压缩包的 Web 端个人知识库能录入笔记、打标签、按标题和正文检索、上传附件并保留修改历史。它适合两类人一类是文档和代码片段散落各处、想用私有系统做归集的普通用户另一类是刚学完 Web 开发、需要一个完整项目练手并部署上线的新手工程师。下面按我实际部署这类系统的顺序来讲。2. 解压前先验包zip 完整性、伪加密与目录结构zip 包最常见的问题不是代码报错而是包本身不完整。下载中断、存储介质坏道、甚至打包工具版本差异都会让 zip 在解压中段报 CRC 错误。我拿到包的第一件事永远是先测试完整性而不是直接右键解压。这一步花不了十秒钟但能省下后续排错一两个小时。2.1 先验证 zip 是否完整unzip -t 与文件列表检查# 测试 zip 压缩包完整性不实际解压 unzip -t PersonalKM.zip # 输出末尾为 No errors detected in compressed data 才说明包完整这条命令的 -t 参数表示 test archive integrity只校验不释放文件。压缩包比较大的时候会跑一会儿但值得等。校验通过后再看一眼包内的顶层目录结构避免解压出几百个文件后找不到入口。# 查看包内顶层文件列表确认源码、脚本和文档都在 unzip -l PersonalKM.zip | head -50-l 参数只列出文件不实际解压。后面接 head -50 是为了避免输出太长刷屏。看输出时重点确认三样东西是否在列表里数据库脚本目录通常叫 db/ 或 sql/、项目说明README 或部署文档、源码目录src/ 或 war 包。如果这三样缺一样项目大概率跑不起来或者跑起来也是个半成品。还有一种情况文件列表能正常打开文件名和目录结构都看得到但一解压就提示要密码输入包里文档写的密码也无效。这大概率是 zip 伪加密。所谓伪加密是文件头的加密标志位被改动数据本身没有加密很多压缩工具会误判为加密包。网上流传的课程设计、毕业设计源码包里偶尔会有这种操作。遇到这种情况先别急着找什么 zip 密码移除工具那些工具对真加密都不一定有效对伪加密更是白费功夫。常见做法是用 ZipCenOp.jar 这类小工具把加密标志位修复回未加密状态再正常解压。先判断是不是伪加密比盲目试密码重要得多。2.2 看懂 web 项目目录源码、配置、脚本和说明文件各在哪解压完成后先别急着用 IDEA 打开。大多数这种 web 项目压缩包目录结构是固定的几块源码目录、资源目录、数据库脚本目录、文档。先把结构认清楚后面改配置才不会乱翻。下面这张表是我在解压后第一遍翻目录时对照的常见布局目录或文件通常放什么部署时要不要动src/main/java 或 src/业务代码通常不用src/main/resourcesapplication.yml、application.properties必须改db/ 或 sql/建库脚本、初始化数据需要手动导入README.md 或 部署文档启动步骤和默认账号按它做再按下文校验upload/ 或 files/附件上传目录改成配置控制# 列出解压后二级目录确认配置和脚本的位置 ls -la find . -maxdepth 2 -type d | sortfind 命令用 maxdepth 2 限制深度避免把 target、node_modules 这类目录全打出来。重点看 db/ 或 sql/ 目录下有没有 init.sql 一类的脚本文件以及 src/main/resources 下有没有 application.yml 或 application.properties。有些版本的包会把建表 SQL 写在 src/main/resources 下的 schema.sql 或 data.sqlSpring Boot 启动时会自动执行但个人建议还是手动建库导入。自动执行建表脚本在权限、字符集、重复执行时都可能出幺蛾子手动导入一次心里有底。2.3 三个必改配置数据库连接、服务端口与上传目录确认结构后去 src/main/resources 下找 application.yml 或 application.properties。对大多数这种单体 web 项目真正影响能否启动的只有三个配置数据库连接、服务端口、上传目录。其他配置保持默认能跑但这三个不改跑起来也会在功能上翻车。server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/personal_kb?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: kb_user password: your-password driver-class-name: com.mysql.cj.jdbc.Driver servlet: multipart: max-file-size: 20MB max-request-size: 50MB kb: upload-dir: ${user.dir}/upload逐个说参数含义。server.port 是服务端口本地调试默认 8080如果被占用了改成 8081 或 8090 都行。spring.datasource.url 里那三个参数不能省useUnicodetrue 和 characterEncodingutf8 管中文不乱码serverTimezoneAsia/Shanghai 管时间字段差八小时的问题。driver-class-name 在 MySQL 8.0 下必须是 com.mysql.cj.jdbc.Driver老配置里常见的 com.mysql.jdbc.Driver 在新驱动里会直接报错或弃用警告。spring.servlet.multipart 的 max-file-size 和 max-request-size 是上传附件的大小上限如果打算拿这套系统存 PDF 或压缩包20MB 是个比较合理的起步值。最后是 kb.upload-dir: ${user.dir}/upload。这里面 ${user.dir} 是 Java 的系统属性表示当前工作目录项目启动时在哪就在哪。这样配置的好处是项目从一台机器挪到另一台机器上传目录自动跟着走不用改代码改路径。如果这里写的是 /home/xxx/upload 或 D:\upload 这类绝对路径换环境必炸这个问题后面专门讲。3. 把 zip 跑成本地服务MySQL 建库、连接配置与启动验证配置改完就该建库、连库、启动。这一步是大多数人卡住的地方。从现象上看问题往往不是代码写错了而是数据库环境和项目预期的不一致。下面按步骤来每一步都说明为什么这么做。3.1 建库建用户不要用 root 直接跑业务字符集选 utf8mb4先建库。这里按最常见的 Spring Boot MySQL 单体结构来讲。如果你是照着 MySQL 8.0 zip 包在 Windows 上手动安装的方式配的环境初始化时多半用了 --initialize-insecureroot 初始密码为空登录之后第一件事是改 root 密码而不是直接拿 root 给项目用。我给这套系统单独建一个用户权限只留给 personal_kb 库这样就算应用被攻破数据库也不至于整个暴露。CREATE DATABASE IF NOT EXISTS personal_kb DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci; CREATE USER kb_userlocalhost IDENTIFIED BY Kb_2024_secure; GRANT ALL PRIVILEGES ON personal_kb.* TO kb_userlocalhost; FLUSH PRIVILEGES; USE personal_kb; SOURCE /path/to/init.sql;字符集选 utf8mb4 而不是 utf8原因是 utf8mb4 才能完整存储 emoji 和生僻字。个人知识库最常见的使用场景就是往笔记里粘贴网页文章、代码片段里面偶尔带个 emoji 是常有的事。如果建库时用了老的 utf8插入时会报 Incorrect string value 错误或者 emoji 被存成问号。COLLATE 用 utf8mb4_general_ci 就够这种个人项目不需要纠结排序规则的细微差别。SOURCE 语句导入 SQL 脚本时注意脚本路径不要有中文目录很多 MySQL 客户端在中文路径下会报找不到文件。如果脚本是用 GBK 编码存的导入前先转一下编码# 把 GBK 编码的初始化脚本转成 UTF-8 再导入 iconv -f gbk -t utf8 init.sql -o init_utf8.sql这一步不是每次都需要但如果导入后表里的中文全是乱码回过来检查脚本原始编码是值得的。3.2 改连接配置YAML 里的 URL、驱动、时区与特殊字符密码建好库后回到 application.yml 把账号密码对上。这里最容易翻车的不是账号密码写错而是驱动和参数没对齐。spring: datasource: url: jdbc:mysql://localhost:3306/personal_kb?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalseallowPublicKeyRetrievaltrue username: kb_user password: Kb_2024_secure driver-class-name: com.mysql.cj.jdbc.Driverurl 里多出来的 useSSLfalse 和 allowPublicKeyRetrievaltrue 是本地环境的两个兜底参数。前者告诉客户端本地连接不需要 SSL 加密后者解决 MySQL 8.0 默认认证插件 caching_sha2_password 在部分老驱动下需要手动获取公钥的问题。注意 allowPublicKeyRetrievaltrue 在本地开发可以开但如果把这套系统部署到公网服务器这个参数会带来中间人风险公网环境建议换成新驱动或者改认证插件后面避坑章会再讲。密码里有特殊字符时YAML 和 URL 各有一层转义。YAML 里密码如果含 #会被当成注释截断必须加引号包起来比如 password: abc#123。JDBC URL 里密码含 、:、/ 这类字符时要做 URL 编码比如密码是 abc123URL 里写成 abc%40123。这类问题报错信息往往很诡异不是 Access denied 就是 Unknown database排查时先怀疑特殊字符。3.3 启动项目并验证命令行启动、日志判断与 curl 探活配置改完启动。常见做法是用 Maven 直接跑或者打成可执行 jar 再跑。第一次建议先用 mvn spring-boot:run好处是报错直接看控制台不用反复打包。# 开发阶段直接启动 mvn spring-boot:run # 或者打成可执行 jar 再启动 mvn clean package -DskipTests java -jar target/personal-kb-0.0.1-SNAPSHOT.jar-DskipTests 是跳过测试用例。很多这类 zip 包自带的测试用例和当前数据库环境根本不匹配跑测试反而会中途失败。打成 jar 后注意文件名要从 target 目录里实际生成的名字复制版本号后缀不一定和我写的这个一样。启动后的成功标志不是弹出一个窗口而是日志里出现这两行之一Started Application in x secondsTomcat started on port(s): 8080看到其中任一行服务就算起来了。然后用 curl 从命令行探活# 从命令行探活返回 200 或 302 都算正常 curl -I http://localhost:8080/返回 200 说明首页直接可访问返回 302 说明被重定向到登录页这同样是正常的因为很多知识管理系统首页就需要登录。真正的问题是 Connection refused那说明服务没起来回头看日志。3.4 局域网打不开检查监听地址和防火墙而不是怀疑项目服务起来了但局域网里别人访问不到这是另一个高频问题。症状很典型本机 localhost 能打开换成 192.168.x.x 就打不开。先看配置里有没有写死监听地址application.yml 里如果写了 server.address127.0.0.1把它删掉或者改成 0.0.0.0。再查防火墙Windows 上 8080 端口的入站规则没放行局域网自然进不来。# Linux 上确认服务监听在哪个地址 ss -tlnp | grep 8080看输出里的监听地址如果是 127.0.0.1:8080说明服务只监听回环地址只有本机能访问如果是 0.0.0.0:8080 或 [::]:8080说明监听所有网卡问题就在防火墙。Windows 上放行端口是在控制面板的高级安全 Windows Defender 防火墙里新建一条入站规则端口填 8080允许连接。这类问题十有八九是监听地址和防火墙二选一项目代码本身没问题。4. 跑通个人知识管理核心链路录入、标签、检索与历史版本系统跑起来后真正决定它值不值得长期用的是核心功能链路是否完整。个人知识管理系统的本质就是内容的增删改查加检索但有三件事是普通笔记工具容易忽视的结构化分类、全文检索、历史版本。下面按最小可用方案来拆。4.1 三张核心表文章表、分类表与历史版本表我通常按三张核心表起步文章表、分类表、历史版本表。标签先不拆关联表个人规模用逗号分隔足够。CREATE TABLE kb_category ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL UNIQUE, sort_order INT DEFAULT 0 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE kb_article ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(200) NOT NULL, content MEDIUMTEXT, category_id INT, tags VARCHAR(255), create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_category (category_id), INDEX idx_update_time (update_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE kb_article_history ( id INT AUTO_INCREMENT PRIMARY KEY, article_id INT NOT NULL, content MEDIUMTEXT, saved_at DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_article_id (article_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;几个字段的理由说一下。content 用 MEDIUMTEXT 是因为要存富文本 HTML 源码一条长笔记几十 KB 很常见VARCHAR 不够用。tags 字段用 VARCHAR(255) 存逗号分隔的标签比如java,spring,踩坑记录个人规模下这样最省事检索时用 LIKE 模糊匹配即可。等标签多到需要统计报表的时候再拆成文章和标签的关联表不迟一开始就上三张关联表反而让录入页面复杂。update_time 加 ON UPDATE CURRENT_TIMESTAMP让 MySQL 在每次 UPDATE 时自动改时间代码里不用手动赋值列表排序直接用这个字段。kb_article_history 表只存 article_id、content、saved_at这就是历史版本的底子。很多人拿这套系统当管理源码的工具每次改配置前想知道上一个版本长什么样有这张表就不用慌这也是个人知识管理系统支持查看不同版本的基础。4.2 录入与编辑富文本保存、附件上传与 PDF 导出页面端常见做法是 jQuery 加现成的富文本编辑器后端是一个保存接口。各家编辑器 API 略有差异但取内容的方式都是类似 editor.getHtml()。下面这段是页面里保存按钮的处理逻辑纯前端部分。// 保存按钮把富文本内容和基本信息一起提交 $(#btn-save).click(function () { const data { title: $(#title).val(), content: editor.getHtml(), // 富文本编辑器取 HTML 片段 categoryId: $(#category).val(), tags: $(#tags).val() }; $.ajax({ url: /api/article, type: POST, contentType: application/json, data: JSON.stringify(data), success: function (res) { if (res.code 0) location.href /article/detail/ res.data.id; } }); });提交用 JSON 而不是传统表单是因为富文本内容可能很大传统表单编码在这种场景下偶发截断。editor.getHtml() 取到的是 HTML 片段而不是纯文本回显时要用编辑器自带的 setHtml 或 innerHTML 渲染用 text() 输出会把所有样式和图片都丢掉。附件上传和正文保存是两条路。附件用 FormData 走 POST 到 /api/upload服务端把文件落到上传目录数据库里只存相对路径比如 /upload/2024/11/xxx.pdf。数据库不存 base64那是给数据库添堵个人库也一样。至于导出 PDF浏览器自带的打印功能就够页面上放一个打印按钮调 window.print()用户选另存为 PDF 就行不用引入第三方库。这个方案在知识管理的笔记导出场景下就是最省事的 web 页面 pdf 打印实现。4.3 检索先用参数化 LIKE 跑通再考虑中文分词检索对个人知识库是刚需。第一版不用上搜索引擎参数化 LIKE 足够用到几千条笔记。SELECT id, title, update_time FROM kb_article WHERE title LIKE CONCAT(%, ?, %) OR content LIKE CONCAT(%, ?, %) ORDER BY update_time DESC LIMIT 20;几个点值得注意。CONCAT(%, ?, %) 用的是参数绑定关键词里即使有单引号、百分号也不会被当成 SQL 注入这是 MyBatis 里写 prepared statement 的正确姿势。千万别在 Mapper XML 里写 WHERE title LIKE %${keyword}%这种字符串拼接是 SQL 注入重灾区个人系统也扛不住。列表页只查 title 和 update_time不查 content因为列表页不需要展示正文少一次大字段的 IO页面响应会明显快。LIMIT 20 是兜底手段LIKE 查询走全表扫描数据量上去之后就算慢也不会一次把几万行全捞出来。如果 title 和 content 都用同一个关键词注意参数要传两次一个给 title 的 LIKE一个给 content 的 LIKE。内容里的关键词命中频率更高所以这个查询在大多数场景下是按正文搜出来的结果多。4.4 历史版本给知识条目一份“后悔药”给知识条目做版本历史的实现很简单每次保存前把库里当前这条内容先复制到历史表再更新主表。用户看到的是最新版历史表里留的是每一个旧快照。// 保存前先把旧内容归档到历史表 KbArticle old articleMapper.selectById(articleId); if (old ! null) { historyMapper.insert(old.getId(), old.getContent()); } // 再执行更新 articleMapper.update(article);这段逻辑要包在事务里否则会出现归档成功但更新失败的脏状态。Spring 里加 Transactional 注解即可默认传播级别 REQUIRED 就够。selectById 是详情接口里已经在用的方法这里顺手复用不用额外写查询。这个设计看起来笨但它是所有方案里最可靠的。正文越存越大时可以考虑只存 diff但个人场景没必要完整快照最简单、恢复最省心。回滚操作就是从 kb_article_history 表里取最近一条 saved_at 记录把 content 写回 kb_article顺手把当前版本也插进历史表。这相当于是你自己的 Git commit不需要多复杂的算法。版本历史表建好之后很多编辑事故都能救回来这是我认为个人知识管理系统最值得做的一个功能。5. 部署避坑zip 解压、MySQL 8.0、端口与上传路径的五处高频翻车点这部分是血泪经验汇总。这些坑单独看都不难解决但组合在一起足够让一个第一次部署这类项目的人折腾一整天。每一条都按现象、原因、解决的顺序写。5.1 zip 伪加密能看到列表却解压不出来别急着暴力破解现象文件列表能看文件名目录结构清清楚楚但一解压就提示输入密码输入包里 README 写的密码也没用。原因这是 zip 伪加密文件头的加密标志位被改过数据本身并没有加密。很多压缩工具读到标志位就当加密包处理。网上流传的源码包里偶尔会出现这种情况真正的密码可能根本不存在。解决先确认是不是伪加密。能预览到完整文件列表但解压要密码、密码还不对基本可以判断是伪加密。处理方式是用 ZipCenOp.jar 这类小工具把加密标志位修掉再正常解压。别一上来就下载暴力破解工具那些工具对真加密都未必有效对伪加密更是浪费时间。网上搜 zip 密码移除出来的工具大多是撞库式的费时费力还不一定出结果。5.2 中文文件名乱码压缩包编码要按源系统解压现象在 Windows 上解压出来的文件名正常在 Linux 服务器上解压后全是乱码类似缂佸瓨鏂囦欢 这样的内容但解压出来的文件内容里中文正常。原因Windows 压缩工具按本地编码GBK 或 GB2312写文件名ZIP 格式本身不记录文件名编码Linux 的 unzip 默认按 UTF-8 解码于是乱码。这不是项目的问题是压缩包编码的问题。解决Linux 下解压时指定编码# 按 GBK 编码解压文件名 unzip -O gbk PersonalKM.zip注意 -O 参数不是所有 unzip 版本都支持某些精简版会报 invalid option。不支持时用 7-Zip 在 Windows 上指定代码页解压或者用 Python 的 zipfile 模块手动处理文件名编码。项目本身的内部编码是 UTF-8 没问题的乱码只发生在文件名这一层进系统看界面不会影响。5.3 MySQL 8.0 认证插件报错命令行能登、程序连不上现象mysql -u kb_user -p 在命令行里能正常登录但项目一启动就报 Access denied for user kb_userlocalhost或者报 Public Key Retrieval is not allowed。原因MySQL 8.0 默认的认证插件是 caching_sha2_password而项目里用的 JDBC 驱动版本偏老不认这个插件。命令行客户端是新版的没问题程序里用的老驱动就翻车了。解决两个方向选一个。方向一是把数据库用户改回老认证插件ALTER USER kb_userlocalhost IDENTIFIED WITH mysql_native_password BY Kb_2024_secure; FLUSH PRIVILEGES;方向二是升级驱动。常见做法是让 JDBC 驱动版本对齐 MySQL 版本MySQL 8.0 就用 8.0.x 的驱动。如果不想改数据库用户也不想升驱动连接串里加 allowPublicKeyRetrievaltrue 也能走通 caching_sha2_password但这是让客户端从服务器明文拉公钥公网环境有风险本地开发可以用生产别这么干。5.4 端口被占用启动失败别先怀疑配置先查谁占着 8080现象启动日志里没有出现 Started Application最后几行是 Port 8080 was already in use或者 Web server failed to start。原因本机已经有别的进程占用了 8080 端口。常见的是本机跑过其他 Spring Boot 项目没关干净或者开发工具的内置服务占着端口。解决先查端口占用再决定是杀进程还是改端口。# Linux / macOS 查谁占用 8080 lsof -i :8080 # Windows 查谁占用 8080 netstat -ano | findstr :8080找到 PID 之后任务管理器里结束进程。如果这个端口被重要服务占着不想动直接把 application.yml 里的 server.port 改成 8081、8090 都行个人系统不需要死守 8080。改完重启问题解决。这类问题最坑的地方在于新手容易以为是项目配置错了反复改数据库配置其实和数据库一点关系都没有。5.5 上传路径写死换电脑、换服务器必翻车现象本机上传的图片和附件显示正常把项目拷到另一台机器或服务器上再打开详情页图片全部 404。原因代码或配置文件里写了绝对路径比如 /Users/xxx/upload 或 D:\upload。换机器后这个路径不存在或者系统不同路径格式不一样附件自然读不到。解决路径交给配置项控制不要写死。前面已经说过的 kb.upload-dir: ${user.dir}/upload 就是干这个的系统在哪个目录启动上传目录就在哪个目录下。同时数据库里存相对路径页面显示时用当前访问的地址拼完整 URL不要把 http://localhost:8080/xxx 这种字符串直接写进数据库。迁移时只需要把项目目录整个拷走附件跟着项目走。顺带提一句 web 安全的底线如果这套系统只在本机跑那没什么可担心的。如果哪天要部署到云服务器上登录页和接口的 XSS 与 SQL 注入过滤要检查一遍尤其是富文本内容存的是 HTML渲染前要做白名单过滤不能让用户往里面塞任意的 script 标签。个人系统也经不住公网扫描器的折腾。6. 进阶把本地方案升级成长期可用的个人知识库6.1 一条命令备份全部笔记mysqldump 与定时任务数据备份是个人知识库的救命稻草。很多人笔记存了好几年突然有一天 disk 坏了或者误删了库才发现根本没有备份策略。mysqldump 是最简单的方案# 手动备份一次文件名带日期 mysqldump -u kb_user -p personal_kb kb_backup_$(date %Y%m%d_%H%M%S).sql第一次手动执行成功后确认备份文件物理存在再去配定时任务。Linux 下用 crontab# 每天凌晨 2 点备份cron 里 % 号要转义 0 2 * * * mysqldump -u kb_user -pKb_2024_secure personal_kb /home/kb/backup/kb_$(date \%Y\%m\%d).sqlcrontab 里 % 是特殊字符必须写成 %。Windows 上用任务计划程序套一条 bat 命令也能实现。恢复时执行 mysql -u kb_user -p personal_kb 备份文件.sql 即可。备份文件建议保留最近 30 天可以加个 find 命令定期清理个人库量级不大也不需要多复杂的备份策略。6.2 部署到服务器nginx 反向代理与静态资源缓存跑通本地后很多人的下一步是部署到家里的 NAS 或云服务器。常见做法是 jar 起在 8080前面用 nginx 做反向代理把 80 端口的请求转给 8080这样访问时不用带端口号nginx 顺手还能做静态资源缓存。server { listen 80; server_name kb.example.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location ~* \.(js|css|png|jpg|woff2)$ { proxy_pass http://127.0.0.1:8080; expires 7d; } }proxy_pass 指向 127.0.0.1:8080注意这里写的是回环地址因为 nginx 和应用在同一台机器上。静态资源缓存那一行 expires 7d让浏览器把 js、css、图片缓存 7 天页面刷新速度会有明显提升。这就是个人场景里最实用的 web 缓存比上 Redis 省事得多也符合 nginx 高性能 web 服务器的常规用法。局域网自己用的话nginx 都可以不装直接 8080 访问。部署到云服务器时记得把数据库绑定 127.0.0.1应用里也用 localhost 连库别让 MySQL 端口暴露在公网上这是最基本的 web 安全底线。6.3 换掉 LIKE 的时机中文全文检索升级路线数据到几万条之后LIKE 全表扫开始变慢搜索响应能明显感觉到延迟。这时先别急着上 ElasticsearchMySQL 自带的全文索引加 ngram 解析器对中文支持已经不错。ALTER TABLE kb_article ADD FULLTEXT INDEX ft_article_content (title, content) WITH PARSER ngram;ngram 解析器把中文按 n 字切分MySQL 5.7.6 以上和 8.0 都支持。建好索引后查询改用 MATCH AGAINSTSELECT id, title FROM kb_article WHERE MATCH(title, content) AGAINST(关键词 IN NATURAL LANGUAGE MODE);这一步能撑到十万条左右的量级个人知识库基本到不了这个规模。真到了还不够用的时候再考虑独立检索引擎。但到那个阶段你会先遇到另一个问题数据怎么同步到搜索引擎那已经是另一个项目了不是这套 web 系统该操心的事。我现在拿到这类 zip第一件事永远是找数据库脚本和上传路径配置而不是急着把项目跑起来。先确认数据能导出、能备份、能迁移再谈界面好不好看。备份命令第一次手动执行成功之前不要相信任何自动备份策略。历史版本表和归档流程先做上笔记多了以后你会感谢当初的自己。希望帮到你。本文还有配套的精品资源点击获取
返回列表