分类: 开发笔记

  • Nuxt 项目实战:集成必应 IndexNow 协议,几分钟内提升网站搜索引擎曝光度

    在 2026 年的今天,AI 搜索和实时内容已经成为主流。作为开发者,我们最沮丧的莫过于上午刚发布了一篇精心撰写的技术教程,下午却发现竞争对手的类似文章已经出现在搜索结果前列,而自己的网站连索引都还没建立。

    传统的 SEO 模式依赖搜索引擎的被动爬取,往往存在巨大的时间延迟。今天,我就在沈阳的办公室里,通过实战记录如何为 Nuxt.js SSR 项目 集成 IndexNow 协议。这套方案将让你在发布内容后,立刻通知必应(Bing)等搜索引擎前来抓取,将收录时间从几天缩短到几分钟。

    一、 什么是 IndexNow?

    简单来说,IndexNow 是一个开源的索引通知协议。它允许网站管理员直接向搜索引擎(如 Bing、Yandex、Naver 等)发送“Ping”请求,告知它们:“我有新内容了,请立即抓取这个 URL”。

    • 没有 IndexNow: 搜索引擎靠猜或定期扫描,发现新内容可能需要数天甚至数周。
    • 有了 IndexNow: 搜索引擎收到通知,立即(或在几分钟内)安排爬虫抓取。

    二、 我们的部署架构与挑战

    我的项目是基于 Nuxt 3 构建的 SSR(服务端渲染)应用。为了保证生产环境的纯净与安全,我采用了一种“极端”的部署方式:

    • 本地打包: 在 Windows 开发环境执行 npm run build
    • 只传产物: 仅上传 .output 文件夹 到 Linux 服务器,不上传源码、node_modules 或 package.json
    • 服务器运行: 使用 PM2 直接启动 .output/server/index.mjs

    挑战点: 由于服务器上没有 Node.js 的运行环境(或者为了安全不希望在服务器上执行脚本),IndexNow 的推送动作必须在本地打包后、上传服务器前完成

    三、 实战步骤:编写本地推送脚本

    我们需要在本地创建一个 Node.js 脚本来读取打包生成的 sitemap.xml,提取 URL,并发送给 IndexNow API。

    第一步:创建脚本目录

    在你的项目根目录下(与 .output 同级),创建一个 scripts 文件夹。

    第二步:创建推送脚本 (submit-indexnow.cjs)

    在 scripts 目录下新建文件 submit-indexnow.cjs。注意后缀是 .cjs,这是为了解决 ES 模块与 CommonJS 模块的兼容性问题(如果你的项目设置了 "type": "module")。

    请将以下代码复制进去,并替换其中的 域名 和 API密钥

    // scripts/submit-indexnow.cjs
    const https = require('https');
    const fs = require('fs');
    const path = require('path');
    
    // ================== 配置区 ==================
    // 替换为你的实际域名(不带 https://)
    const HOST = 'www.your-domain.com'; 
    
    // 替换为你在 Bing Webmaster Tools 中获取的 API 密钥
    const API_KEY = 'your_actual_api_key_here'; 
    
    // 密钥文件的访问地址,用于必应验证所有权
    const KEY_LOCATION = `https://${HOST}/${API_KEY}.txt`;
    // ===========================================
    
    /**
     * 1. 从本地打包生成的 sitemap.xml 中提取所有 URL
     * @returns {string[]} URL 列表
     */
    function getSitemapUrls() {
      // 拼接 sitemap.xml 的本地路径
      const sitemapPath = path.join(__dirname, '../.output/public/sitemap.xml'); 
      
      // 检查文件是否存在
      if (!fs.existsSync(sitemapPath)) {
        console.error('❌ 找不到 sitemap.xml,请确保已经执行过 npm run build');
        return [];
      }
    
      // 读取文件内容
      const xml = fs.readFileSync(sitemapPath, 'utf-8');
      
      // 使用正则提取 <loc> 标签中的 URL
      const urls = xml.match(/<loc>(.*?)<\/loc>/g)
                    ?.map(u => u.replace(/<\/?loc>/g, '').trim()) || [];
      
      console.log(`✅ 成功从 sitemap.xml 中提取了 ${urls.length} 个 URL`);
      return urls;
    }
    
    /**
     * 2. 发送 POST 请求到 IndexNow API
     * @param {string[]} urls URL 列表
     */
    function submitToIndexNow(urls) {
      if (urls.length === 0) {
        console.log('⚠️ 没有 URL 需要提交');
        return;
      }
    
      // 构建请求体
      const postData = JSON.stringify({
        host: HOST,
        key: API_KEY,
        keyLocation: KEY_LOCATION,
        urlList: urls
      });
    
      // 配置 HTTPS 请求选项
      const options = {
        hostname: 'api.indexnow.org',
        port: 443,
        path: '/indexnow',
        method: 'POST',
        headers: {
          'Content-Type': 'application/json; charset=utf-8',
          'Content-Length': Buffer.byteLength(postData)
        }
      };
    
      console.log(`🚀 正在向 IndexNow 提交 ${urls.length} 个 URL...`);
    
      const req = https.request(options, (res) => {
        let data = '';
        res.on('data', (chunk) => (data += chunk));
        res.on('end', () => {
          // 处理响应
          // 200: 成功 | 202: 已接收(首次提交或验证中)
          if (res.statusCode === 200 || res.statusCode === 202) {
            console.log('✅ IndexNow 提交成功!必应已接收通知。');
            console.log(`💡 状态码: ${res.statusCode} (${res.statusCode === 202 ? '密钥验证中/已排队' : '成功'})`);
          } else {
            console.error(`❌ 提交失败,API 状态码: ${res.statusCode}`);
            console.error('详细响应:', data);
          }
        });
      });
    
      // 处理请求错误
      req.on('error', (e) => {
        console.error(`❌ 请求网络错误: ${e.message}`);
      });
    
      // 写入数据并结束请求
      req.write(postData);
      req.end();
    }
    
    // --- 执行主流程 ---
    const urls = getSitemapUrls();
    submitToIndexNow(urls);

    第三步:本地打包与推送

    # 1. 构建项目,生成最新的 sitemap
    npm run build
    
    # 2. 运行脚本推送给必应
    node scripts/submit-indexnow.cjs

    第四步:服务器部署

    最后,将本地的 .output 文件夹上传至服务器,并重启 PM2 即可:

    pm2 restart migshare --update-env

    四、 常见问题与避坑指南

    通过这套“本地打包 ➡️ 本地读取 Sitemap 推送 ➡️ 上传纯静态产物”的工作流,我们既保证了生产环境的绝对干净与安全,又完美实现了必应搜索引擎的秒级通知。

    为什么文件后缀必须是 .cjs

    如果你的 package.json 中包含 "type": "module",Node.js 会默认将 .js 文件视为 ES 模块(ESM),而 ES 模块不支持 require() 语法。使用 .cjs 后缀可以强制 Node.js 以 CommonJS 模式运行该脚本,避免报错。

    为什么返回状态码 202?

    不要惊慌,202 是正常的!

    • 200 OK: 提交成功。
    • 202 Accepted: 请求已被接收,但必应正在验证你的密钥文件(.txt)。通常首次提交或密钥刚更新时会出现此状态。只要看到 202,说明你的请求已经进入队列,稍后就会生效。

    需要上传什么文件到服务器?

    除了 .output 文件夹外,你必须确保你的 API 密钥文件(例如 ca152f6c...txt)已经放置在服务器的网站根目录下,并且可以通过 https://www.your-domain.com/ca152f6c...txt 直接访问。否则,必应无法验证你的所有权,提交会失败。

    五、 总结

    通过这套“本地打包 -> 本地读取 Sitemap 推送 -> 上传纯静态产物”的工作流,我们完美解决了“服务器无源码/无环境”的限制。

    在 2026 年的沈阳,技术更新迭代极快,酒香也怕巷子深。利用 IndexNow 这样的协议,主动出击,让你的优质技术资源(如米格ONE分享站上的教程和源码)第一时间被搜索引擎发现,是现代开发者必备的技能之一。

    快去试试吧,让你的网站在搜索引擎中的曝光度飞起来!

  • 国内服务器一键脚本部署Sub2API,后台升级失败,手动升级教程

    我们拿v0.1.139举例

    1️⃣ 在你本地电脑浏览器打开:
    https://github.com/Wei-Shaw/sub2api/releases

    2️⃣ 往下翻到 Assets,下载 sub2api_linux_amd64.tar.gz

    根据自己服务器类型选择amd还是arm

    下载完成后把文件上传到服务器根目录/tmp 文件夹内,然后服务器终端操作命令

    #先停止服务+备份
    sudo systemctl stop sub2api
    sudo cp /opt/sub2api/sub2api /opt/sub2api/sub2api.bak.$(date +%Y%m%d)
    #先进入目录
    cd /tmp
    #然后执行以下命令解压
    
    tar -xzf sub2api_linux_amd64.tar.gz 
    
    #“sub2api_linux_amd64.tar.gz”这个是你传到目录的文件名字
    # 确认是否解压出来了
    ls -lh sub2api
    
    # 然后替换
    sudo mv sub2api /opt/sub2api/sub2api
    sudo chmod +x /opt/sub2api/sub2api
    sudo chown sub2api:sub2api /opt/sub2api/sub2api
    
    # 重启验证
    sudo systemctl restart sub2api
    /opt/sub2api/sub2api --version
  • Linux 安装 Apache, MySQL, PHP 搭建 Web 服务器

    一、安装前准备

    首先下载安装文件

    1. 下载安装包

    下载以下 7 个压缩包

    • Apache依赖包:apr-1.7.0.tar.gz、apr-util-1.6.1.tar.gz、pcre-8.45.tar.gz
    • Apache主程序:httpd-2.4.52.tar.gz
    • MySQL数据库:mysql-5.7.39-linux-glibc2.12-x86_64.tar.gz (⚠️注意:一定要下这种 linux-glibc 的通用二进制包,千万不要下 .rpm 包,小白用RPM包离线安装绝对会报错)
    • PHP依赖包:libxml2-2.9.14.tar.gz
    • PHP主程序:php-7.4.33.tar.gz

    下载地址

    https://resource.migshare.cn/static/202606/001/lamp_packages.zip

    下载完后,拷贝到服务器上。

    注意:接下来过程中如遇到错误提示,如系统未安装工具或权限等问题,请根据实际情况处理解决,最简单的方式就是把报错交给AI,按AI提供方案解决。

    2. 在服务器上解压并建目录

    • 把 lamp_packages.zip 放到服务器的 /opt 目录下。
    • 登录服务器,执行以下命令,创建目录并解压:

    创建统一存放目录

    sudo mkdir -p /lamp_install

    把压缩包解压到该目录

    sudo unzip /opt/lamp_packages.zip -d /lamp_install

    进入目录

    cd /lamp_install

    二、安装 Apache(网页服务器)

    Apache 必须按顺序安装它的 3 个依赖,最后再装自己。

    1. 安装 apr

    sudo tar -zxvf apr-1.7.0.tar.gz

    编译安装

    cd apr-1.7.0
    sudo ./configure --prefix=/usr/local/apr

    出现下面的提示不用担心,直接忽略就行

    make && sudo make install

    2. 安装 apr-util

    cd ..
    sudo tar -zxvf apr-util-1.6.1.tar.gz
    cd apr-util-1.6.1

    编译安装

    sudo ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr
    make && sudo make install

    安装如果遇到下图错误,表示在编译过程中,系统尝试在当前目录(/lamp_install/apr-util-1.6.1)下创建或写入一个名为 .make.dirs 的隐藏文件时,被拒绝了。

    不要着急按错误提示进行处理即可。

    解决步骤

    第一步:检查并修复源码目录权限

    请执行以下命令,将 /lamp_install 目录的所有权修改为当前用户 xhf,这样您就有权限在里面进行编译操作了:

    sudo chown -R xhf:xhf /lamp_install

    第二步:清理之前的编译残留

    由于之前的 make 失败,可能会留下一些残缺的临时文件。强烈建议先清理一下:

    make clean

    第三步:重新编译与安装

    权限修复并清理完毕后,重新执行标准的编译安装命令:

    make && sudo make install

    这样上面报错问题就解决了。

    如果报下面图问题,说明您的 Linux 系统中缺少了 Expat 库的开发包。

    apr-util 内置了对 XML 解析的支持,在编译其 XML 模块时需要依赖 Expat 库的头文件(即 expat.h)。如果没有安装这个开发包,编译器就会找不到该文件并中断编译。

    解决步骤

    请根据您的 Linux 发行版,使用包管理器安装对应的开发包:

    如果是 CentOS / RHEL 系统:

    sudo yum install expat-devel -y

    如果是 Ubuntu / Debian 系统:

    sudo apt-get install libexpat1-dev -y

    重新编译安装

    安装完依赖包后,由于之前编译中断,建议先清理一下缓存,然后重新执行编译和安装命令:

    make clean
    make && sudo make install

    成功截图

    3. 安装 pcre

    cd ..
    sudo tar -zxvf pcre-8.45.tar.gz
    cd pcre-8.45

    编译安装,编译安装如果遇到权限问题参考上面解决步骤即可。

    sudo ./configure --prefix=/usr/local/pcre
    make && sudo make install

    成功截图

    4. 安装 Apache 本体

    cd ..
    sudo tar -zxvf httpd-2.4.52.tar.gz
    cd httpd-2.4.52

    编译安装,编译安装如果遇到权限问题参考上面解决步骤即可。

    sudo ./configure --prefix=/usr/local/httpd --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-pcre=/usr/local/pcre
    make && sudo make install

    如果遇到下图问题,说明在编译 Apache (httpd) 时,链接器找不到 Expat 库(XML 解析库)的实现。

    根本原因:
    您在之前编译 apr-util 时,可能使用了 –with-expat=builtin(内置副本),或者系统当时没有安装 Expat 的开发包,导致生成的 libaprutil-1.so 动态链接库中缺失了 XML 相关的底层依赖。当 Apache 尝试链接这个库时,就会报找不到符号的错误。

    解决步骤

    要彻底解决这个问题,需要重新编译安装 apr-util,让它正确链接到系统的 Expat 库,然后再重新编译 Apache。

    第一步:安装系统级 Expat 开发包

    如果您之前没有安装,请先执行以下命令安装:

    CentOS / RHEL 系统:

    sudo yum install expat-devel -y

    Ubuntu / Debian 系统:

    sudo apt-get install libexpat1-dev -y

    如果出现截图中的问题,说明系统里是有 Expat 库的,但 APR-Util 在编译时没有正确链接到它。这通常是因为 APR-Util 的 configure 脚本没能自动检测到库的位置,或者缓存了错误的配置。

    请按照以下步骤强制重新编译 APR-Util:

    第一步:清理并重新配置 APR-Util

    进入你的 APR-Util 源码目录(根据你的截图应该是 /lamp_install/apr-util-1.6.1),执行以下命令:

    cd /lamp_install/apr-util-1.6.1

    清理之前的编译残留(非常重要)

    make clean

    重新配置–with-expat=/usr 是关键参数,强制指定使用系统的 expat

    sudo ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr --with-expat=/usr

    成功截图

    执行安装

    make && sudo make install

    如下图显示,说明 APR-Util 已经重新编译并安装成功了

    接下来的操作步骤

    请在终端中依次执行以下命令:

    进入 Apache 源码目录

    cd /lamp_install/httpd-2.4.52

    清理旧的编译文件(非常重要)

    为了避免旧的错误缓存干扰,必须执行 clean:

    make clean

    重新配置 Apache

    你需要再次告诉 Apache 去哪里找刚才修好的 APR 和 APR-Util。请确保路径与你之前安装的一致(通常是 /usr/local/apr 和 /usr/local/apr-util):

    sudo ./configure --prefix=/usr/local/httpd --enable-so --enable-rewrite --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util

    再次编译如果出现下图问题,意味着系统里缺少 PCRE 库的开发文件

    使用系统包管理器安装

    我使用的是 Ubuntu/Debian 系(根据之前的 apt-get 命令判断),直接用系统包管理器安装是最稳妥的,它会自动处理依赖和路径问题。

    安装旧版 PCRE (8.x) 开发包

    sudo apt-get install libpcre3-dev -y

    成功截图

    回到 Apache 源码目录并清理旧缓存

    cd /lamp_install/httpd-2.4.52
    make clean

    重新执行 Apache 的 configure 命令,关键参数:–with-pcre

    sudo ./configure --prefix=/usr/local/httpd --enable-so --enable-rewrite --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util

    成功截图

    sudo make && sudo make install

    验证安装是否成功

    安装完成后,你可以运行以下命令查看 Apache 的版本信息

    /usr/local/httpd/bin/apachectl -v

    启动 Apache 服务

    由于你是源码编译安装的,我们使用 apachectl 脚本来管理它:

    sudo /usr/local/httpd/bin/apachectl start

    验证是否启动成功,如果看到 “It works!” 的默认欢迎页面,就说明 Apache 已经完美运行了

    curl http://localhost

    三、安装 MySQL(数据库)

    MySQL 我们用的是免编译的二进制包,不需要 make,但需要手动初始化。

    1. 创建专属用户和目录

    sudo groupadd mysql
    sudo useradd -r -g mysql mysql
    sudo mkdir -p /data/mysql
    sudo chown -R mysql:mysql /data/mysql
    

    2. 解压并移动

    sudo tar -zxvf mysql-5.7.39-linux-glibc2.12-x86_64.tar.gz
    sudo mv mysql-5.7.39-linux-glibc2.12-x86_64 /usr/local/mysql
    

    3. 初始化数据库

    sudo /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql

    如遇到下图问题,说明您的 Linux 系统中缺少了 libaio(Linux 异步 I/O 库)。

    MySQL 在启动或初始化时,强依赖 libaio.so.1 这个共享库来进行高效的磁盘操作。如果系统中没有安装该库,mysqld 进程就会直接报错退出。

    解决步骤

    请根据您的 Linux 发行版,使用包管理器安装对应的依赖库:

    如果是 CentOS / RHEL 系统:

    sudo yum install libaio -y

    如果是 Ubuntu / Debian 系统:

    sudo apt-get update
    sudo apt-get install libaio-dev -y
    sudo ln -sf /usr/lib/x86_64-linux-gnu/libaio.so.1t64.0.2 /usr/lib/x86_64-linux-gnu/libaio.so.1
    sudo ldconfig
    

    重新初始化 MySQL

    sudo /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql

    成功截图

    临时密码:sTT,bmro26Z*

    sudo cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld

    作用:将 MySQL 安装包自带的服务控制脚本(mysql.server)复制到 Linux 系统的初始化脚本目录(/etc/init.d/)下,并重命名为 mysqld。

    目的:/etc/init.d/ 是 Linux 系统集中管理系统服务的目录。把脚本放在这里,就可以像管理系统自带服务一样来管理 MySQL。

    启动数据库

    sudo systemctl status mysqld.service 

    如果启动报下图错误,说明MySQL 正在尝试把错误日志写到 /usr/local/mysql/data/ 目录下,但是这个目录在您的系统中根本不存在!
    因为目录不存在,mysqld_safe 脚本无法创建日志文件,导致启动流程直接中断崩溃。

    结合您之前的操作,您初始化数据库时指定的数据目录是 /data/mysql,但 MySQL 默认还在寻找 /usr/local/mysql/data。

    解决步骤

    我们需要通过配置文件,彻底把 MySQL 的所有路径都指向您实际的 /data/mysql 目录。

    第一步:创建缺失的目录并赋予权限(保底操作)
    为了防止后续还有零散文件需要写入,我们先把这个默认目录也建出来:

    sudo mkdir -p /usr/local/mysql/data 
    sudo chown -R mysql:mysql /usr/local/mysql/data
    

    第二步:修改 MySQL 配置文件(核心修复)
    打开配置文件:

    sudo vim /etc/my.cnf

    在 [mysqld] 配置段下,明确指定数据目录和日志路径,确保 MySQL 不再乱找默认路径:

    [mysqld]
    user=mysql
    datadir=/data/mysql
    log-error=/data/mysql/myserver.err
    pid-file=/data/mysql/myserver.pid
    socket=/data/mysql/mysql.sock
    
    [client]
    socket=/data/mysql/mysql.sock
    

    (保存并退出:按 Esc,输入 :wq 回车)

    第三步:修改 systemd 服务文件(修复 PID 报错)
    日志最后一行提示 Can’t open PID file /run/mysqld/mysqld.pid,说明 systemd 还在找默认的 PID 路径。我们需要修改服务文件:

    sudo vim /etc/systemd/system/mysqld.service

    在 [Service] 段下,修改或添加 PID 文件路径,使其与配置文件一致:

    [Service]
    Type=simple
    User=mysql
    Group=mysql
    ExecStart=/usr/local/mysql/bin/mysqld_safe --user=mysql
    PIDFile=/data/mysql/myserver.pid
    

    完整的配置如下图

    (保存并退出)

    第四步:重载配置并启动

    sudo systemctl daemon-reload
    sudo systemctl start mysqld
    

    第五步:验证启动状态

    sudo systemctl status mysqld

    启动成功

    修改密码

    sudo /usr/local/mysql/bin/mysql -u root -p

    如果报下图错误,是因为 MySQL 客户端程序依赖 libncurses.so.5 这个动态链接库文件,但当前的 Ubuntu 24.04 系统中没有安装这个特定版本的库。

    由于 MySQL 5.7 等较旧版本对旧版库有硬编码依赖,而新版 Ubuntu 已经升级了该库,因此我们需要通过创建软链接的方式来“欺骗” MySQL,让它使用新版库文件。

    解决步骤

    第一步:查找系统中现有的高版本库文件

    首先,我们需要确认系统中实际存在的 libncurses 版本(通常是 .so.6 版本)。请执行:

    find / -name 'libncurses.so*'

    通常输出会包含类似 /usr/lib/x86_64-linux-gnu/libncurses.so.6 的路径。

    第二步:创建软链接

    假设上一步找到的文件路径是 /usr/lib/x86_64-linux-gnu/libncurses.so.6,我们将其链接为 MySQL 需要的 .so.5 版本:

    sudo ln -s /usr/lib/x86_64-linux-gnu/libncurses.so.6 /usr/lib/x86_64-linux-gnu/libncurses.so.5

    第三步:刷新动态链接器缓存

    sudo ldconfig

    第四步:重新测试登录

    sudo /usr/local/mysql/bin/mysql -u root -p

    重要预警:可能出现的“连环报错”

    在解决 libncurses.so.5 的问题后,当您再次执行登录命令时,极有可能会紧接着报出另一个极其相似的错误:
    libtinfo.so.5: cannot open shared object file: No such file or directory

    这是因为 libncurses 和 libtinfo 是一对依赖库,它们同时缺失了旧版本。如果您遇到了这个新报错,请使用完全相同的逻辑解决:

    查找现有版本

    find / -name 'libtinfo.so*'

    创建软链接

    sudo ln -s /usr/lib/x86_64-linux-gnu/libtinfo.so.6 /usr/lib/x86_64-linux-gnu/libtinfo.so.5

    刷新缓存

    sudo ldconfig

    再次登录 MySQL

    sudo /usr/local/mysql/bin/mysql -u root -p

    回车后,输入你刚才记下的临时密码(输入时屏幕不会显示,正常的)

    登录进去后,执行以下 SQL 语句把密码改成 123456(你可以自己定):

    ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
    exit;

    第五步:安装 PHP

    1. 安装 libxml2 依赖

    sudo tar -zxvf libxml2-v2.9.14.tar.gz
    cd libxml2-v2.9.14

    编译安装

    sudo ./autogen.sh --prefix=/usr/local/libxml2

    如果出现截图报错,系统提示您缺少编译 libxml2 所必需的三个核心工具:autoconf、automake 和 libtool。

    根据您提供的网页链接,这些都是 GNU 组织开发的标准开源工具。

    解决方案:一键安装依赖

    既然您使用的是基于 Debian/Ubuntu 的系统(从之前的 apt 命令推断),您可以使用以下命令一次性安装这三个工具以及 pkg-config(编译库时通常也需要它):

    sudo apt update
    sudo apt install autoconf automake libtool pkg-config
    

    再次执行编译安装

    sudo ./autogen.sh --prefix=/usr/local/libxml2
    sudo make -j$(nproc) && sudo make install
    

    成功截图

    2. 安装 PHP 本体

    cd ..
    sudo tar -zxvf php-7.4.33.tar.gz
    cd php-7.4.33

    编译安装

    sudo ./configure --prefix=/usr/local/php --with-apxs2=/lamp_install/httpd-2.4.52/support/apxs --with-mysqli=/usr/local/mysql/bin/mysql_config --with-libxml-dir=/usr/local/libxml2

    如果遇到截图中错误, 标识当前用户没有执行权限。

    解决方案

    你只需要给 apxs 文件添加执行权限即可。请依次执行以下命令:

    赋予执行权限

    chmod +x /lamp_install/httpd-2.4.52/support/apxs

    检查输出中是否包含 x(例如 -rwxr-xr-x),包含说明生效了

    重新运行 PHP 的 configure 命令 进行编译

    sudo ./configure --prefix=/usr/local/php --with-apxs2=/usr/local/httpd/bin/apxs --with-mysqli=/usr/local/mysql/bin/mysql_config  --with-libxml-dir=/usr/local/libxml2

    如果遇到下图问题,说明 PHP 的 configure 脚本在通过 pkg-config 工具寻找 libxml2 库时,没有找到对应的 .pc 描述文件

    虽然之前可能编译安装了 libxml2,但系统默认的 pkg-config 并不知道它被安装到了 /usr/local/libxml2 这个非标准路径下。

    我们需要手动告诉系统去哪里找它。请按照以下步骤操作:

    解决方案:设置 PKG_CONFIG_PATH 环境变量

    先确认你的 libxml2 描述文件在哪里

    执行以下命令查找 libxml-2.0.pc 文件的位置:

    find /usr/local/libxml2 -name "libxml-2.0.pc"

    设置环境变量并重新配置 PHP

    将找到的 pkgconfig 目录路径追加到 PKG_CONFIG_PATH 中

    PKG_CONFIG_PATH="/usr/local/libxml2/lib/pkgconfig:$PKG_CONFIG_PATH" \
    sudo -E ./configure \
    --prefix=/usr/local/php \
    --with-apxs2=/usr/local/httpd/bin/apxs \
    --with-mysqli=/usr/local/mysql/bin/mysql_config \
    --with-libxml-dir=/usr/local/libxml2
    

    安装

    make && sudo make install

    如果出现下图报错,不用担心,仍然是权限问题

    解决方案:给当前用户赋予源码目录的所有权

    我们需要把整个 PHP 源码目录的所有权交还给当前的普通用户。请依次执行以下命令:

    修复源码目录权限

    sudo chown -R xhf:xhf /lamp_install/php-7.4.33

    重新执行编译和安装,这个过程需要耐心等待

    make && sudo make install

    成功截图

    生成配置文件

    配置 php.ini 文件

    sudo cp /lamp_install/php-7.4.33/php.ini-development /usr/local/php/lib/php.ini

    重启 Apache 让配置生效

    sudo /usr/local/httpd/bin/apachectl restart

    终极验证:测试 PHP 是否正常工作

    创建一个 PHP 测试文件:

    sudo nano /usr/local/httpd/htdocs/info.php

    在文件中写入以下代码

    <?php
    phpinfo();
    ?>
    

    保存并退出(Ctrl+O 回车保存,Ctrl+X 退出)。

    命令行访问

    curl http://localhost/info.php

    如果出现下图的问题,不要担心我们继续解决下

    快速修复步骤:

    清理旧的编译缓存

    cd /lamp_install/php-7.4.33
    sudo make clean
    

    重新配置(去掉 apxs2,加上 fpm 和 opcache)

    PKG_CONFIG_PATH="/usr/local/libxml2/lib/pkgconfig:$PKG_CONFIG_PATH" \
    sudo -E ./configure \
    --prefix=/usr/local/php \
    --with-mysqli=/usr/local/mysql/bin/mysql_config \
    --with-libxml-dir=/usr/local/libxml2 \
    --enable-fpm \
    --with-fpm-user=nobody \
    --with-fpm-group=nogroup \
    --enable-opcache
    

    (注:这里去掉了 –with-apxs2,加上了 –enable-fpm 和 –enable-opcache)

    编译并安装

    sudo make && sudo make install

    配置并启动 PHP-FPM

    复制配置文件

    sudo cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf 
    sudo cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf

    启动 PHP-FPM

    sudo /usr/local/php/sbin/php-fpm

    让 Apache 代理请求给 PHP-FPM

    打开 Apache 配置文件:

    sudo nano /usr/local/httpd/conf/httpd.conf

    找到并取消以下两行的注释(启用代理模块):

    LoadModule proxy_module modules/mod_proxy.so
    LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
    

    在文件末尾添加一行,将所有 .php 请求转发给 FPM:

    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/usr/local/httpd/htdocs/$1

    按 Ctrl + O,然后按 回车键 保存。

    按 Ctrl + X 退出编辑器。

    在命令行执行以下命令,重启 Apache 让配置生效:

    sudo /usr/local/httpd/bin/apachectl restart

    再次验证

    curl http://localhost/info.php

    输出html代码说明成功了

    到此我们也就完成了linux安装LAMP的全部过程,坑很多遇到问题不要急,踩坑也是一种提升过程。

  • VMware Workstation虚拟机 安装Ubuntu镜像

    一、安装前准备

    首先下载Ubuntu 镜像

    以下是为您整理的 Ubuntu 官方及国内高速镜像下载地址:

    1. 官方下载渠道

    2. 国内高速镜像站(推荐)

    2.1 清华大学开源软件镜像站(推荐)

    2.2 阿里云镜像站

    2.3 其他优质镜像站

    我是通过清华大学开源软件镜像站进行下载的24.04,下载地址:https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/24.04/

    选择ubuntu-24.04.4-live-server-amd64.iso进行下载

    二、开始安装

    在 VMware 虚拟机中安装 Ubuntu 24.04.4 Server 版(无图形界面的服务器版)是一个非常标准且实用的操作。以下是为你整理的超详细图文级安装步骤:

    1. 虚拟机创建与配置

    1.1 新建虚拟机

    打开 VMware,点击“文件” -> “新建虚拟机”。

      也可以通过主页直接创建新的虚拟机。

      1.2 选择“典型(推荐)”,点击下一步

      1.3 加载镜像

      选择“安装程序光盘映像文件 (iso)”,浏览并选中你下载好的 ubuntu-24.04.4-live-server-amd64.iso 文件,点击“下一步“。

      1.4 命名与存储位置

      为虚拟机命名。强烈建议将存储位置修改为非 C 盘路径,点击“下一步“。

      1.5 磁盘大小设置

      设置最大磁盘大小,建议分配 30GB – 50GB(虚拟磁盘是动态分配的,不会立刻占用这么多空间),并选择“将虚拟磁盘存储为单个文件”,便于后续备份和移动,点击“下一步“。

      1.6 自定义硬件(关键)

      • 内存:建议设置为 4GB (4096 MB)(最低 2GB)。
      • 处理器:建议分配 2 核。
      • 网络适配器:保持默认的 NAT 模式(可上网且安全隔离)。
      • 显示器:取消勾选“加速 3D 图形”(Server 版无需图形加速,可避免兼容问题)。
      • 点击“关闭” -> “完成”。

      2. 系统安装过程

      2.1 引导与语言选择:启动虚拟机

      在引导界面选择 Try or install Ubuntu Server,按回车,没用这步则跳过。

      语言建议选择 English(便于后续排查问题),键盘布局默认 English (US),一路回车。

      选择继续(Continue)

      2.2 创建用户

      • Your name(你的姓名),随意填写
      • Your servers name(你的服务器名称),随意填写,用于同其他设备链接时使用
      • Pick a username(用户名),用于系统登录
      • Choose a password(登录密码),用于系统登录
      • Confirm your password(确认密码),同登录密码一致
      • 然后鼠标向下选择Done(完成),回车

      Continue(继续),回车

      2.3 安装 OpenSSH(必选)

      使用空格键勾选 Install OpenSSH server(前面出现 [X] 表示选中)。这一步非常重要,安装后才能使用 Xshell 等工具远程连接服务器。

      2.4 可选软件:直接跳过,移至 Done,回车

      等待系统更新完毕,这里需要等待一会。

      更新完成后,鼠标下移选择Reboot Now(立即重启),回车

      如果重启后报错

      别担心,这是一个非常经典的虚拟机安装报错,你的系统其实已经安装成功了

      这个报错的原因是:系统在安装完成后尝试自动卸载虚拟光驱(CD/DVD),但因为 VMware 默认将 ISO 镜像文件一直“连接”在虚拟机上,导致系统无法完成卸载动作。

      你只需要按照以下步骤处理,即可顺利进入系统:

      第一步:手动断开光驱连接(关键)

      在 VMware 虚拟机窗口底部状态栏,找到那个光盘图标(CD/DVD)。

      鼠标右键点击该图标,在弹出的菜单中选择 “断开连接”(Disconnect)。
      (此时光盘图标上会出现一个红色的禁止符号,表示已断开)

        第二步:重启虚拟机

        • 回到报错的虚拟机黑屏界面,按下键盘上的 回车键(Enter)。
        • 虚拟机会重新启动。这次因为光驱已经断开,系统就能正常引导进入登录界面了。

        输入登录用户名,回车

        输入密码,这里输入时不会显示出来,输入完直接回车就行

        登录成功

        输入ip addr 检查网络是否已链接成功,下图是已经链接成功,如果没有链接成功,需要配置下网络

        如果NAT模式用不习惯,可以通过vm虚拟机将网络适配改为桥接也可以。

      1. Linux离线安装nginx详细教程

        一、什么是离线安装?

        使用离线安装包进行软件安装的方式就叫离线安装。
        离线安装包又叫做完整安装包,包含所有的安装文件。与其相对的是在线安装,即在条件允许且网络良好的条件下采用网络安装的方式。在线安装方式的缺点是在不太好的网络状况下容易出现长时间等待或安装失败的情况,这种情况下只能进行离线安装。

        二、安装步骤

        1.安装nginx所需依赖

        1.1 安装gcc和gcc-c++

        1.1.1 下载依赖包

        gcc依赖下载镜像地址:
        官网:https://gcc.gnu.org/releases.html
        阿里云镜像站:http://mirrors.aliyun.com/centos/7/os/x86_64/Packages/
        CentOS 镜像站点:https://vault.centos.org/7.5.1804/os/x86_64/Packages/

        只需下载如下依赖即可:
        cpp-4.8.5-44.el7.x86_64.rpm
        gcc-4.8.5-44.el7.x86_64.rpm
        glibc-devel-2.17-317.el7.x86_64.rpm
        glibc-headers-2.17-317.el7.x86_64.rpm
        kernel-headers-3.10.0-1160.el7.x86_64.rpm
        libmpc-1.0.1-3.el7.x86_64.rpm
        mpfr-3.1.1-4.el7.x86_64.rpm
        gcc-c++-4.8.5-44.el7.x86_64.rpm
        libstdc++-4.8.5-44.el7.x86_64.rpm
        libstdc++-devel-4.8.5-44.el7.x86_64.rpm

        1.1.2 上传依赖包

        下载完成后,将依赖包上传到服务器,若权限不足不能上传,可以通过 sudo chmod -R 777 文件夹路径名命令增加权限

        1.1.3 安装依赖

        进入上传目录,输入rpm -Uvh *.rpm –nodeps –forc命令进行批量安装,出现下图则说明安装成功

        1.1.4 验证安装

        使用gcc-v和g++ -v命令查看版本,若出现版本详情则说明离线安装成功,如下图示:

        1.2 安装pcre

        1.2 安装pcre

        下载地址:http://www.pcre.org/

        1.2.2 上传解压安装包

        将下载好的安装包上传到服务器,并解压,解压命令tar -xvf pcre-8.45.tar.gz

        1.2.3 编译安装

        进入解压目录,依次执行以下命令:
        ./configure
        make
        make install

        1.3 下载安装zlib

        1. 3.1 下载zlib

        下载地址:http://www.zlib.net/

        1.3.2 上传解压安装包

        将下载好的安装包上传到服务器,并解压

        1.3.3 配置

        进入解压目录输入 ./configure

        1.3.4 编译安装

        进入解压目录输入make && make install

        1.4 下载安装openssl

        tips:检查是否已安装openssl,输入命令openssl version,若出现版本信息,则无需安装;若没有安装则继续安装

        1.4.1 下载

        地址:https://www.openssl.org/source/

        1.4.2 上传解压安装包

        将下载好的安装包上传到服务器,并解压

        1.4.3 配置

        进入解压目录输入 ./configure

        1.4.4 编译安装

        进入解压目录输入 make && make install

        1.4.5 验证

        安装完成后,控制台输入openssl version,出现版本信息则说明安装成功

        2. 下载安装nginx

        2.1 下载nginx安装包

        下载地址:https://nginx.org/en/download.html

        2.2 上传解压安装包

        将下载好的安装包上传到服务器,并解压

        2.3 配置

        进入解压目录进行配置安装地址:./configure --prefix=/home/develop/nginx

        2.4 编译

        make

        2.5 安装

        make install

        2.6 检查并启动

        2.6.1 检查

        进入安装目录下的sbin文件夹,输入./nginx -t,如下图则说明安装成功:

        2.6.2 启动

        启动nginx,命令:./nginx

        2.7 访问

        浏览器访问nginx,前提是80端口可以访问

        2.8 设置开启自启动

        tips:此步骤为可选项

        将nginx的sbin目录添加到rc.local文件中:
        #编辑rc.local文件 vim /etc/rc.local
        #在最后一行加入如下内容 /home/develop/nginx/sbin/nginx

        以上就是离线安装nginx的详细步骤,希望可以帮到有需要的小伙伴。

      2. Linux系统离线部署MySQL详细教程

        1、登录官网下载对应的安装包

        下载地址:MySQL :: Developer Zone

        2、将压缩包上传到服务器上,这里直接上传到/usr/local路径上

        使用sftp工具上传到/usr/local目录上

        3、解压压缩包

        4、将mysql-8.0.39-linux-glibc2.17-x86_64目录重命名为mysql

        在/usr/mysql/目录下

          5、创建用户组

          使用 groupadd 命令来创建一个名为 mysql 的用户组:

          接着创建一个同名的系统用户,并将其归属到刚才创建的 mysql 用户组中:

          -r 参数表示mysql 用户是系统用户,不可用于登录系统;
          -g 将用户mysql添加到用户组mysql中

          6、分配用户组,将文件属性、组属性改为mysql

          将文件的所有属性改为mysql用户

          将组属性改为mysql组

          7、创建新的数据目录(也可以使用默认的数据目录,一般在/var目录下)

          创建数据目录

          将新目录文件的所有属性改为mysql用户

          8、修改MySQL服务器配置文件

          添加如下配置信息

          9、初始化数据库

          先切换到mysql路径,再执行初始化

          –basedir 为mysql解压目录,–datadir 为mysql数据存放目录,就是在/etc/my.cnf配置的路径

          10、初始化后就可以查看mysql初始密码了

          11、加入到系统服务,启动mysql服务

          12、MySQL服务启动成功后,就可以登录到mysql数据库

          输入刚开始初始化后查看到的初始密码,即可完成进入mysql数据库

          如果想直接使用mysql -u root -p 直接登录,则需要先把mysql的路径映射链接到/usr/bin目录下

          13、更改mysql数据库登录初始密码

          刷新

          14、完成部署

          退出数据库,再次登录即可输入更改的密码,到此mysql已经部署完成,成功部署。

          15、部署时可能出现的问题

          1)初始化数据库报错

          初始化数据库的时候报“./mysqld:/lib64/libstdc++.so.6:version ‘CXXABI 1.3.11’ not found (required by ./mysqld)”

          此报错是缺少对应的libstdc++版本依赖问题,可以先查看对应的版本

          可以看到是缺少相应的版本依赖。

          解决办法

          可以看缺少那些依赖就安装对应的依赖版本
          使用rpm查看glibc版本,然后去官网下载对应的版本

          2)启动mysql服务报错

          启动mysql服务时可能会报“Starting MySQL.2024-09-20T09:32:58.959370Z mysqld safe error:log-errorr set to/var/log/mariadb/mariadb.log’,however file don’t exists.Create writable for us ‘mysql’”

          解决方法

          此错误时没有对应的目录和文件,进行创建目录和文件即可

        • 最新VMware虚拟机安装Linux系统教程

          篇教程中,我们将详细介绍如何在 VMware 虚拟机中安装 Linux 系统。VMware 是一个广泛使用的虚拟化平台,它支持在宿主操作系统上创建虚拟机,运行各种不同的操作系统。通过使用 VMware 虚拟机,我们可以方便地安装和测试 Linux 系统,或是在 Windows/macOS 上体验 Linux 系统。

          一、准备工作

          1、安装 VMware虚拟机

          官方最新正版VMware下载:https://pan.quark.cn/s/ef97c86cf637

          现在VMware虚拟机个人版免费无需激活,如果你安装的旧版本可以尝试安装这个最新版本。

          2、下载 Linux 系统镜像(ISO 文件)

          为了在虚拟机中安装 Linux,你需要下载 Linux 操作系统的镜像文件。

          官方最新Linux系统镜像下载:https://pan.quark.cn/s/554b299094d7

          二、创建 VMware 虚拟机

          启动 VMware:安装好 VMware 虚拟机后,打开 VMware虚拟机

          创建新虚拟机:

          点击中间的 “创建新的虚拟机”。

          在弹出的窗口中选择 “典型安装”模式,然后点击 下一步。

          选择安装介质:

          在安装光盘部分,选择 “安装光盘映像文件” 并点击 浏览。

          找到你下载的 Linux ISO 文件并选择它,然后点击 下一步。


          选择操作系统版本:

          VMware 会自动识别 ISO 文件中的操作系统类型。如果它没有自动识别,手动选择你要安装的 Linux 版本选择Centos 64位。

          命名虚拟机并选择存储位置:
          给虚拟机起个名字(例如:Ubuntu_VM),然后选择虚拟机文件的存储位置。默认存储位置通常在你的文档或虚拟机文件夹中。

          设置虚拟机硬件配置:

          默认设置适合大多数用户,但你可以根据需求修改 CPU 核心数、内存大小、硬盘大小等配置:
          内存:建议分配至少 2 GB 内存。
          CPU:建议分配 1 核心以上(视你的宿主机性能而定)。
          硬盘:建议设置 20 GB 或更大,选择 “Use an existing virtual disk”(使用现有虚拟硬盘)或 “Create a new virtual disk”(创建新的虚拟硬盘)。
          硬盘类型:推荐选择 SATA(默认选项),它兼容性较好。
          硬盘文件:虚拟机的硬盘文件(.vmdk)将存储在你选择的位置。

          完成虚拟机创建:
          配置完成后,点击 Finish(完成)来创建虚拟机。

          三、安装 Linux 操作系统

          启动虚拟机:

          在 VMware 中选择你创建的虚拟机,然后点击 开启此虚拟机(启动)。
          加载 ISO 文件:
          如果你选择的是从 ISO 文件启动,虚拟机会自动加载 Linux 安装程序。

          开始安装 Linux:

          启动后,你会看到 Linux 系统的安装界面(以 Ubuntu 为例,安装过程类似其他发行版)。
          选择 Install Ubuntu(安装 Ubuntu)选项开始安装。

          选择语言

          在安装界面中,首先选择你希望使用的语言(如中文、英文等)。

          选择时区:

          系统会要求你选择所在的时区,选择 China 或 UTC+08:00(中国标准时间)等。

          键盘布局选择:

          选择合适的键盘布局,通常默认的 English (US) 布局即可。如果你需要中文输入,可以选择 Chinese (Simplified)。

          软件选择

          这里是修改安装方式,最小安装是只有命令行界面(大佬可选择,当然如果是大佬应该也看不到这个文章)。这里我们选择 GNOME 桌面,然后点击完成

          选择不启用KDUMP(启用会占用内存),然后点击完成。

          磁盘分区:

          点击进入再点击返回即可,不点击不能安装

          开启网络:

          开始安装:

          点击 右下角(立即安装),开始安装过程。安装时间大约需要 10-30 分钟,具体取决于你虚拟机的配置和 ISO 文件的大小。

          此步骤需要设置ROOT密码。

          完成安装并重启虚拟机:

          安装完成后,系统会提示你 “Installation Complete”(安装完成)。点击立即重启。

          四、安装完成后的配置

          启动系统:

          安装 VMware Tools:

          为了优化虚拟机的性能,建议安装 VMware Tools。VMware Tools 提供了鼠标捕捉、共享文件夹、增强的显示分辨率等功能。
          在 VMware 中,点击 VM 菜单,选择 Install VMware Tools。
          通过命令行安装 VMware Tools,步骤如下:
          打开终端并进入 VMware Tools 的挂载目录: bash

          解压 VMware Tools 压缩包: bash

          运行 VMware Tools 安装程序: bash

          按照提示完成安装。

          调整分辨率:

          安装完 VMware Tools 后,你可以在虚拟机中自由调整屏幕分辨率。

          系统更新:

          安装完成后,强烈建议更新系统,以确保你拥有最新的安全补丁和软件包。
          执行以下命令更新 Ubuntu: bash

          五、总结

          通过上述步骤,你可以在 VMware 虚拟机中成功安装并运行 Linux 系统。虚拟化技术使得安装、管理和测试不同操作系统变得非常方便,也为开发、测试和学习提供了一个理想的环境。

          根据个人需求,你可以选择不同的 Linux 发行版,并在 VMware 环境中进行多样化的配置和测试。

        • Linux 与 Windows 常用命令对照表

          文件与目录管理

          功能描述Linux / macOS 命令Windows (CMD) 命令Windows (PowerShell) 命令
          列出当前目录内容ls / ls -ladirGet-ChildItem / ls
          切换目录cd /path/to/dircd \path\to\dirSet-Location / cd
          创建文件夹mkdir folder_namemd folder_nameNew-Item -ItemType Directory
          删除空文件夹rmdir folder_namerd folder_nameRemove-Item
          创建空文件touch 文件名type nul > 文件名 或 echo. > 文件名New-Item -ItemType “file” -Path “文件名”
          删除文件rm file.txtdel file.txtRemove-Item
          使用编辑器新建/编辑vim 文件名 或 nano 文件名notepad 文件名notepad 文件名
          递归删除文件夹及内容rm -rf folder_namerd /s /q folder_nameRemove-Item -Recurse -Force
          复制文件cp source destcopy source destCopy-Item
          移动/重命名文件mv old newmove old newMove-Item
          查找文件find /path -name “*.txt”dir /s *.txtGet-ChildItem -Recurse -Filter

          系统信息与进程管理

          功能描述Linux / macOS 命令Windows (CMD) 命令Windows (PowerShell) 命令
          查看当前用户whoamiwhoami$env:USERNAME
          查看主机名hostnamehostname$env:COMPUTERNAME
          查看系统资源(实时)top / htoptaskmgrGet-Process
          查看所有运行进程ps auxtasklistGet-Process
          强制结束进程kill -9 PIDtaskkill /F /PID PIDStop-Process -Id PID -Force
          查看磁盘空间df -hwmic logicaldisk get sizeGet-PSDrive
          查看内存信息free -msysteminfoGet-CimInstance Win32_OperatingSystem
          查看环境变量echo $PATHecho %PATH%$env:PATH

          网络操作

          功能描述Linux / macOS 命令Windows (CMD) 命令Windows (PowerShell) 命令
          查看IP地址ip addr / ifconfigipconfigGet-NetIPAddress
          测试网络连通性ping ip_or_domainping ip_or_domainTest-Connection
          路由追踪traceroute domaintracert domainTest-Connection -Traceroute
          查看开放端口/连接netstat -tulnnetstat -anoGet-NetTCPConnection
          DNS解析查询dig domain / nslookupnslookup domainResolve-DnsName
          下载文件wget url / curl -O urlcurl -o file urlInvoke-WebRequest

          文本处理与编辑

          功能描述Linux / macOS 命令Windows (CMD) 命令Windows (PowerShell) 命令
          查看文件内容cat file.txttype file.txtGet-Content
          分页查看文件less file.txtmore file.txtGet-Content -Page
          搜索文件内文本grep “text” file.txtfindstr “text” file.txtSelect-String
          统计行数/字数wc -l file.txt(无直接等价命令)(Get-Content).Count
          比较文件差异diff file1 file2fc file1 file2Compare-Object
        • Java实现格式转换为PDF的两种方案

          在Java中实现格式转换为PDF,通常需要借助第三方开源库。目前业界最常用且功能强大的两个库是 iText 和 Apache PDFBox

          以下我将为您提供基于这两种主流方案的完整逻辑与代码示例,涵盖最常见的三种转换场景:纯文本转PDF图片转PDF 以及 HTML网页转PDF

          方案一:使用 iText 库(推荐,API更高级)

          iText 提供了丰富的文档排版能力,非常适合生成复杂的报表或文档。

          1. 引入 Maven 依赖1. 引入 Maven 依赖

          <dependency>
              <groupId>com.itextpdf</groupId>
              <artifactId>itext7-core</artifactId>
              <version>7.2.5</version>
              <type>pom</type>
          </dependency>
          <!-- 如果需要HTML转PDF,还需要引入 pdfHTML -->
          <dependency>
              <groupId>com.itextpdf</groupId>
              <artifactId>html2pdf</artifactId>
              <version>4.0.3</version>
          </dependency>

          2. 完整转换工具类代码

          import com.itextpdf.html2pdf.HtmlConverter;
          import com.itextpdf.kernel.geom.PageSize;
          import com.itextpdf.kernel.pdf.PdfDocument;
          import com.itextpdf.kernel.pdf.PdfWriter;
          import com.itextpdf.layout.Document;
          import com.itextpdf.layout.element.Image;
          import com.itextpdf.layout.element.Paragraph;
          import com.itextpdf.io.image.ImageDataFactory;
          
          import java.io.*;
          import java.nio.charset.StandardCharsets;
          import java.nio.file.Files;
          import java.nio.file.Paths;
          
          public class PdfConverter {
          
              /**
               * 1. 纯文本 (TXT) 转换为 PDF
               */
              public static void textToPdf(String txtPath, String pdfPath) throws IOException {
                  // 读取文本内容
                  String content = new String(Files.readAllBytes(Paths.get(txtPath)), StandardCharsets.UTF_8);
                  
                  try (PdfWriter writer = new PdfWriter(pdfPath);
                       PdfDocument pdfDoc = new PdfDocument(writer);
                       Document document = new Document(pdfDoc, PageSize.A4)) {
                      
                      // 将文本按行分割并添加到PDF中
                      for (String line : content.split("\n")) {
                          document.add(new Paragraph(line));
                      }
                  }
              }
          
              /**
               * 2. 图片转换为 PDF
               */
              public static void imageToPdf(String imagePath, String pdfPath) throws Exception {
                  try (PdfWriter writer = new PdfWriter(pdfPath);
                       PdfDocument pdfDoc = new PdfDocument(writer);
                       Document document = new Document(pdfDoc, PageSize.A4)) {
                      
                      Image image = new Image(ImageDataFactory.create(imagePath));
                      // 缩放图片以适应A4纸张宽度
                      image.scaleToFit(PageSize.A4.getWidth(), PageSize.A4.getHeight()); 
                      document.add(image);
                  }
              }
          
              /**
               * 3. HTML 字符串/文件转换为 PDF
               */
              public static void htmlToPdf(String htmlContent, String pdfPath) throws IOException {
                  try (OutputStream os = new FileOutputStream(pdfPath)) {
                      // 核心方法:直接将HTML流转换为PDF流
                      HtmlConverter.convertToPdf(htmlContent, os);
                  }
              }
          
              // 测试入口
              public static void main(String[] args) throws Exception {
                  // 示例:HTML转PDF
                  String html = "<h1>Hello PDF</h1><p>这是一段由Java生成的PDF内容。</p>";
                  htmlToPdf(html, "output_from_html.pdf");
              }
          }

          方案二:使用 Apache PDFBox 库(轻量级,完全免费开源)

          PDFBox 在处理基础的文本写入和图片嵌入时非常稳定,适合不需要复杂排版的场景。

          1. 引入 Maven 依赖

          <dependency>
              <groupId>org.apache.pdfbox</groupId>
              <artifactId>pdfbox</artifactId>
              <version>2.0.24</version>
          </dependency>

          2. 基础文本写入示例

          import org.apache.pdfbox.pdmodel.PDDocument;
          import org.apache.pdfbox.pdmodel.PDPage;
          import org.apache.pdfbox.pdmodel.PDPageContentStream;
          import org.apache.pdfbox.pdmodel.font.PDType1Font;
          
          import java.io.IOException;
          
          public class PdfBoxConverter {
              public static void createSimplePdf(String pdfPath, String text) throws IOException {
                  try (PDDocument document = new PDDocument()) {
                      PDPage page = new PDPage();
                      document.addPage(page);
          
                      try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
                          contentStream.beginText();
                          contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12);
                          contentStream.newLineAtOffset(100, 700); // 设置文本起始坐标
                          contentStream.showText(text);
                          contentStream.endText();
                      }
                      document.save(pdfPath);
                  }
              }
          }

          核心开发建议与注意事项:

          1. 中文乱码问题:上述 iText 和 PDFBox 的基础示例使用的是默认英文字体。如果您的业务涉及中文转换,必须在代码中显式加载中文字体文件(如 msyh.ttf 微软雅黑),否则生成的PDF会出现乱码或方块。
          2. 资源释放:无论使用哪种库,务必确保 DocumentPdfWriter 或 ContentStream 等对象在使用后被正确关闭(推荐使用 Java 的 try-with-resources 语法),以防止内存泄漏和文件被占用无法删除。
          3. HTML转PDF的局限性:在使用 iText 的 html2pdf 模块时,它不支持所有的 CSS3 特性(如部分伪类 :hover 或 @import 规则)。对于复杂的网页,建议在转换前先将外部CSS内联化。