<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>技术文章 &#8211; wqh博客</title>
	<atom:link href="https://wangqianhong.com/category/%E6%8A%80%E6%9C%AF%E6%96%87%E7%AB%A0/feed/" rel="self" type="application/rss+xml" />
	<link>https://wangqianhong.com</link>
	<description>和而不同</description>
	<lastBuildDate>Sun, 12 Oct 2025 15:17:39 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://wangqianhong.com/wp-content/uploads/2020/09/cropped-1-1-1-32x32.png</url>
	<title>技术文章 &#8211; wqh博客</title>
	<link>https://wangqianhong.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Selenium（一） &#124; Debian环境搭建</title>
		<link>https://wangqianhong.com/2024/05/selenium-debian%e7%8e%af%e5%a2%83%e6%90%ad%e5%bb%ba/</link>
					<comments>https://wangqianhong.com/2024/05/selenium-debian%e7%8e%af%e5%a2%83%e6%90%ad%e5%bb%ba/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Sat, 04 May 2024 00:36:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Selenium]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=3874</guid>

					<description><![CDATA[<p>Python + Selenium 完全可以在 Debian 上运行。大致流程分两步： 安装 Goo&#8230; <a href="https://wangqianhong.com/2024/05/selenium-debian%e7%8e%af%e5%a2%83%e6%90%ad%e5%bb%ba/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">Selenium（一） &#124; Debian环境搭建</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2024/05/selenium-debian%e7%8e%af%e5%a2%83%e6%90%ad%e5%bb%ba/">Selenium（一） | Debian环境搭建</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>Python + Selenium 完全可以在 Debian 上运行。大致流程分两步：</p>



<ol><li>安装 Google Chrome 浏览器</li><li>安装 Python、Selenium 及对应的 ChromeDriver</li></ol>



<p>下面以 Debian 11 (“Bullseye”) 为例，演示具体命令。</p>



<h3>在 Debian 上安装 Google Chrome</h3>



<p>Google 官方并不把 Chrome 放到 Debian 默认源，需要先添加 Google 的 apt 仓库。</p>



<pre class="wp-block-preformatted"># 1. 更新本地包列表
<code>sudo apt update</code>

# 2. 安装必要工具
<code>sudo apt install -y wget gnupg2 apt-transport-https ca-certificates</code>

# 3. 导入 Google 的公钥
<code>wget -q -O - https://dl.google.com/linux/linux_signing_key.pub \
| sudo gpg --dearmor -o /usr/share/keyrings/google-linux-signing-keyring.gpg</code>

# 4. 添加 Google Chrome 的 apt 源
<code>echo "deb [signed-by=/usr/share/keyrings/google-linux-signing-keyring.gpg] \
http://dl.google.com/linux/chrome/deb/ stable main" \
| sudo tee /etc/apt/sources.list.d/google-chrome.list</code>

# 5. 再次更新并安装 Chrome
<code>sudo apt update
sudo apt install -y google-chrome-stable</code></pre>



<p>安装完成后，你可以用 <code>google-chrome --version</code> 验证版本。</p>



<h3>安装 Python、Selenium 及 ChromeDriver</h3>



<h4>安装 Python 和 pip</h4>



<p>Debian 11 默认带有 Python3，但可以确保安装最新：</p>



<pre class="wp-block-code"><code>sudo apt install -y python3 python3-venv python3-pip</code></pre>



<h4>安装 Selenium</h4>



<pre class="wp-block-preformatted"># 建议在 virtualenv 中安装
<code>python3 -m venv ~/selenium-env
source ~/selenium-env/bin/activate</code>

# 安装 Selenium 库
<code>pip install --upgrade pip
pip install selenium</code></pre>



<p>如果安装比较慢，可以使用国内镜像源：</p>



<pre class="wp-block-code"><code>pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple</code></pre>



<p>安装 ChromeDriver</p>



<p>ChromeDriver 必须与 Chrome 浏览器版本匹配。可手动下载，也可用 <code>webdriver-manager</code> 自动管理。</p>



<h5>方案 A：手动下载</h5>



<ol><li>查询 Chrome 版本： <code>google-chrome --version </code># 比如输出：Google Chrome <code>115.0.5790.98</code></li><li>到 <a href="https://chromedriver.storage.googleapis.com/index.html">https://chromedriver.storage.googleapis.com/index.html</a> 找到对应的 “115.0.5790.98” 版本，下载 Linux x64 zip。</li><li>解压并移动到 <code>/usr/local/bin</code>： <code>wget -O chromedriver_linux64.zip \ https://chromedriver.storage.googleapis.com/115.0.5790.98/chromedriver_linux64.zip unzip chromedriver_linux64.zip sudo mv chromedriver /usr/local/bin/ sudo chmod +x /usr/local/bin/chromedriver</code></li></ol>



<h5>方案 B：自动管理（推荐开发环境）</h5>



<pre class="wp-block-code"><code>pip install webdriver-manager</code></pre>



<p>在脚本中使用时，示例代码：</p>



<pre class="wp-block-code"><code>from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service

# 自动下载并启动
service = Service(ChromeDriverManager().install())
options = webdriver.ChromeOptions()
# 如果在无头服务器上运行，加上下面两行：
# options.add_argument('--headless')
# options.add_argument('--no-sandbox')

driver = webdriver.Chrome(service=service, options=options)
driver.get("https://www.example.com")
print(driver.title)
driver.quit()</code></pre>



<p>完成以上步骤后，就可以在 Debian 上用 Python + Selenium + ChromeDriver 驱动真实的 Chrome 浏览器来做自动化测试或爬虫／RPA 了。</p>
<p><a rel="nofollow" href="https://wangqianhong.com/2024/05/selenium-debian%e7%8e%af%e5%a2%83%e6%90%ad%e5%bb%ba/">Selenium（一） | Debian环境搭建</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2024/05/selenium-debian%e7%8e%af%e5%a2%83%e6%90%ad%e5%bb%ba/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Docker 清理</title>
		<link>https://wangqianhong.com/2024/04/docker-%e6%b8%85%e7%90%86/</link>
					<comments>https://wangqianhong.com/2024/04/docker-%e6%b8%85%e7%90%86/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Sat, 27 Apr 2024 09:38:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[Docker]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=3869</guid>

					<description><![CDATA[<p>docker在使用的过程中会越来越臃肿，可以用下面的命令瘦身 Volume 用于持久化和共享容器数据&#8230; <a href="https://wangqianhong.com/2024/04/docker-%e6%b8%85%e7%90%86/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">Docker 清理</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2024/04/docker-%e6%b8%85%e7%90%86/">Docker 清理</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>docker在使用的过程中会越来越臃肿，可以用下面的命令瘦身</p>



<p>Volume 用于持久化和共享容器数据，清理不再使用的 Volume 可以释放磁盘空间。常用的清理方法有：</p>



<ol><li><strong>查看现有 Volume</strong></li></ol>



<pre class="wp-block-code"><code># 列出所有 Volume
docker volume ls

# 只列出“悬空”（dangling，即未被任何容器使用）的 Volume
docker volume ls -f dangling=true</code></pre>



<ol start="2"><li><strong>删除单个 Volume</strong></li></ol>



<pre class="wp-block-code"><code># 删除指定名字的 Volume
docker volume rm VOLUME_NAME</code></pre>



<ol start="3"><li><strong>一键清理所有“悬空”Volume</strong></li></ol>



<pre class="wp-block-code"><code># 交互式确认
docker volume prune

# 或者跳过确认
docker volume prune -f</code></pre>



<p>此命令会删除所有未被任何容器使用的 Volume。</p>



<ol start="4"><li><strong>清理所有未使用的 Docker 资源（网络、镜像、容器、Volume）</strong><br>如果想一并清理所有未使用的资源，可以用：</li></ol>



<pre class="wp-block-code"><code>docker system prune --volumes</code></pre>



<p>它会：</p>



<ul><li>删除所有停止的容器</li><li>删除所有未用的网络</li><li>删除所有 dangling 镜像（中间层）</li><li>删除所有未使用的 Volume</li></ul>



<p>加上 <code>-a</code> 可以连同未被容器直接引用但不是 dangling 的镜像一并清理：</p>



<pre class="wp-block-code"><code>docker system prune -a --volumes</code></pre>



<ul><li><strong>谨慎操作</strong>：清理 Volume 会永久丢失其中的数据，务必确认不再需要或已做好备份。</li><li><strong>定期检查</strong>：在开发环境中频繁创建/删除容器，很容易积累大量悬空 Volume，可考虑配置 CI/CD 或定时任务自动执行 <code>docker volume prune -f</code>。</li><li><strong>脚本化清理</strong>：如果想针对名称模式或创建日期做更精细的清理，可以结合 <code>docker volume ls --format '{{.Name}} {{.CreatedAt}}'</code> 输出，再用 shell 脚本过滤并依次 <code>docker volume rm</code>。</li></ul>



<p>这样，你就可以根据需要，按容器级别或全局一次性地清理 Docker Volume，释放磁盘空间。</p>
<p><a rel="nofollow" href="https://wangqianhong.com/2024/04/docker-%e6%b8%85%e7%90%86/">Docker 清理</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2024/04/docker-%e6%b8%85%e7%90%86/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Debian系统配置</title>
		<link>https://wangqianhong.com/2024/04/debian%e7%b3%bb%e7%bb%9f%e9%85%8d%e7%bd%ae/</link>
					<comments>https://wangqianhong.com/2024/04/debian%e7%b3%bb%e7%bb%9f%e9%85%8d%e7%bd%ae/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Tue, 16 Apr 2024 06:20:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[Debian]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=3865</guid>

					<description><![CDATA[<p>Vim配置 修改 ~/.vimrc Debian软件源更新 使用清华的软件源 /etc/apt/so&#8230; <a href="https://wangqianhong.com/2024/04/debian%e7%b3%bb%e7%bb%9f%e9%85%8d%e7%bd%ae/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">Debian系统配置</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2024/04/debian%e7%b3%bb%e7%bb%9f%e9%85%8d%e7%bd%ae/">Debian系统配置</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<h3>Vim配置</h3>



<p>修改 <code>~/.vimrc</code></p>



<pre class="wp-block-code"><code>" 基础设置
set nocompatible        " 关闭兼容模式
set encoding=utf-8
set fileencodings=utf-8,gbk,latin1

" 界面美化
syntax on               " 启用语法高亮
set number              " 显示行号
set relativenumber      " 显示相对行号
set cursorline          " 高亮当前行
set showcmd             " 显示命令
set ruler               " 显示光标位置
set laststatus=2        " 总是显示状态栏
set wildmenu            " 命令行补全增强
set lazyredraw          " 执行宏时不重绘

" 编辑行为
set tabstop=4           " 一个 tab 显示 4 个空格
set shiftwidth=4        " 自动缩进使用 4 个空格
set expandtab           " 用空格代替 tab
set autoindent          " 自动缩进
set smartindent         " 智能缩进
set backspace=2         " 支持用退格删除缩进

" 搜索
set hlsearch            " 高亮搜索
set incsearch           " 增量搜索
set ignorecase          " 忽略大小写
set smartcase           " 智能大小写

" 鼠标支持
set mouse=n             " 在 Normal 模式下启用鼠标支持

" 系统剪贴板（需要 vim-gtk3 支持）
set clipboard=unnamedplus

" 中文支持优化
set helplang=cn
set langmenu=zh_CN.UTF-8
language messages zh_CN.UTF-8</code></pre>



<h3>Debian软件源更新</h3>



<p>使用清华的软件源 /etc/apt/source.list</p>



<pre class="wp-block-code"><code>deb http://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware</code></pre>



<p></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2024/04/debian%e7%b3%bb%e7%bb%9f%e9%85%8d%e7%bd%ae/">Debian系统配置</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2024/04/debian%e7%b3%bb%e7%bb%9f%e9%85%8d%e7%bd%ae/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>如何开发一个AI应用</title>
		<link>https://wangqianhong.com/2024/04/%e5%a6%82%e4%bd%95%e5%bc%80%e5%8f%91%e4%b8%80%e4%b8%aaai%e5%ba%94%e7%94%a8/</link>
					<comments>https://wangqianhong.com/2024/04/%e5%a6%82%e4%bd%95%e5%bc%80%e5%8f%91%e4%b8%80%e4%b8%aaai%e5%ba%94%e7%94%a8/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Mon, 08 Apr 2024 06:10:17 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[AI]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=3836</guid>

					<description><![CDATA[<p>开发一个完整的AI应用需要系统化的知识体系，以下是构成AI应用核心能力的四个关键环节及其技术细节与关&#8230; <a href="https://wangqianhong.com/2024/04/%e5%a6%82%e4%bd%95%e5%bc%80%e5%8f%91%e4%b8%80%e4%b8%aaai%e5%ba%94%e7%94%a8/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">如何开发一个AI应用</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2024/04/%e5%a6%82%e4%bd%95%e5%bc%80%e5%8f%91%e4%b8%80%e4%b8%aaai%e5%ba%94%e7%94%a8/">如何开发一个AI应用</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>开发一个完整的AI应用需要系统化的知识体系，以下是构成AI应用核心能力的四个关键环节及其技术细节与关联关系的详细说明：</p>



<h3>大语言模型（Large Language Model, LLM）</h3>



<p><strong>核心价值</strong>：作为AI应用的认知中枢，承担核心推理与内容生成任务</p>



<p><strong>技术要点</strong>：</p>



<ol start="1"><li><strong>模型架构</strong>：</li></ol>



<ul><li>Transformer架构：基于自注意力机制的编码器-解码器结构</li><li>参数规模：从70亿到1.8万亿参数不等（如Llama-2到GPT-4架构）</li><li>预训练范式：自监督学习（掩码语言建模、下一句预测等）</li></ul>



<ol start="2"><li><strong>关键技术演进</strong>：</li></ol>



<pre class="wp-block-code"><code>   graph LR
     BERT-->RoBERTa-->DeBERTa
     GPT-2-->GPT-3-->GPT-4
     T5-->FLAN-T5-->PaLM</code></pre>



<ol start="3"><li><strong>应用场景</strong>：</li></ol>



<ul><li>文本生成（代码/文案/故事）</li><li>问答系统</li><li>多模态理解（文本+图像/视频）</li></ul>



<ol start="4"><li><strong>优化方向</strong>：</li></ol>



<ul><li>量化压缩（4-bit/8-bit量化）</li><li>微调方法（LoRA/P-Tuning）</li><li>推理加速（vLLM/TensorRT-LLM）</li></ul>



<p></p>



<h3>Embedding技术</h3>



<p><strong>核心价值</strong>：实现语义到向量空间的映射，构建AI认知的数学基础</p>



<p><strong>技术解析</strong>：</p>



<ol><li><strong>特征表示方法</strong>：</li></ol>



<ul><li>静态嵌入：Word2Vec/GloVe</li><li>动态嵌入：BERT/ELMo</li><li>多模态嵌入：CLIP/ImageBind</li></ul>



<ol start="2"><li><strong>数学特性</strong>：</li></ol>



<ul><li>维度：主流模型输出768-4096维向量</li><li>相似度计算：余弦相似度/欧氏距离</li><li>空间性质：保持语义拓扑结构（king &#8211; man + woman = queen）</li></ul>



<ol start="3"><li><strong>性能指标</strong>：</li></ol>



<pre class="wp-block-code"><code>   # 相似度计算示例
   from sklearn.metrics.pairwise import cosine_similarity
   similarity = cosine_similarity(query_embedding, doc_embeddings)</code></pre>



<ol start="4"><li><strong>优化策略</strong>：</li></ol>



<ul><li>领域自适应训练</li><li>降维处理（PCA/t-SNE）</li><li>混合嵌入融合</li></ul>



<p></p>



<h3>向量数据库（Vector Database）</h3>



<p><strong>核心价值</strong>：构建AI应用的长期记忆系统，实现高效语义检索</p>



<p><strong>架构设计</strong>：</p>



<pre class="wp-block-code"><code>graph TD
    A&#91;数据输入] --> B&#91;Embedding模型]
    B --> C&#91;向量化处理]
    C --> D&#91;索引构建]
    D --> E&#91;存储优化]
    E --> F&#91;查询接口]</code></pre>



<p><strong>核心技术要素</strong>：</p>



<ol start="1"><li><strong>索引算法</strong>：</li></ol>



<ul><li>树状结构：ANNOY</li><li>图结构：HNSW</li><li>量化方法：PQ(Product Quantization)</li></ul>



<ol start="2"><li><strong>性能对比</strong>： 数据库类型 查询速度 内存占用 精度 FAISS 10ms 低 高 Milvus 15ms 中 极高 Pinecone 20ms 高 极高</li><li><strong>关键技术</strong>：</li></ol>



<ul><li>混合检索（向量+标量）</li><li>动态更新（增量索引）</li><li>分布式架构</li></ul>



<p></p>



<h3>提示工程（Prompt Engineering）</h3>



<p><strong>核心价值</strong>：构建人机交互的语义桥梁，释放LLM最大潜能</p>



<p><strong>方法论体系</strong>：</p>



<ol start="1"><li><strong>核心范式</strong>：</li></ol>



<ul><li>Zero-shot提示</li><li>Few-shot提示</li><li>Chain-of-Thought</li></ul>



<ol start="2"><li><strong>设计模式</strong>：</li></ol>



<pre class="wp-block-code"><code>   # 结构化提示模板
   prompt_template = """
   &#91;系统指令] 你是一个资深金融分析师
   &#91;背景知识] 当前市场处于牛市阶段
   &#91;输入数据] {user_input}
   &#91;输出要求] 用Markdown格式输出分析报告
   """</code></pre>



<ol start="3"><li><strong>优化技术</strong>：</li></ol>



<ul><li>自动提示生成（AutoPrompt）</li><li>梯度引导优化（ProGen）</li><li>多模态提示设计</li></ul>



<ol start="4"><li><strong>评估指标</strong>：</li></ol>



<ul><li>任务完成度（0-1）</li><li>输出相关性（BLEU/ROUGE）</li><li>事实准确性（FactScore）</li></ul>



<p></p>



<h3>系统集成</h3>



<p><strong>典型架构</strong>：</p>



<pre class="wp-block-code"><code>sequenceDiagram
    用户->>前端: 输入查询
    前端->>API网关: 转发请求
    API网关->>LLM: 生成初步响应
    LLM->>向量数据库: 检索相关知识
    向量数据库-->>LLM: 返回相关文档
    LLM->>提示引擎: 优化输出格式
    提示引擎-->>用户: 返回最终响应</code></pre>



<p><strong>性能优化点</strong>：</p>



<ol><li>端到端延迟控制（&lt;2s）</li><li>缓存策略（请求/响应缓存）</li><li>负载均衡（模型并行/流水线并行）</li></ol>



<p></p>



<h3>典型应用场景</h3>



<ol start="1"><li><strong>智能客服系统</strong>：</li></ol>



<ul><li>意图识别（Embedding）</li><li>知识检索（向量数据库）</li><li>对话生成（LLM+Prompt）</li></ul>



<ol start="2"><li><strong>企业知识库</strong>：</li></ol>



<ul><li>文档向量化（Embedding）</li><li>语义搜索（向量数据库）</li><li>摘要生成（LLM）</li></ul>



<ol start="3"><li><strong>推荐系统</strong>：</li></ol>



<ul><li>用户画像嵌入</li><li>内容相似度匹配</li><li>个性化生成</li></ul>



<p>这四个核心环节构成了现代AI应用的基石，实际开发中需要根据具体场景进行深度优化和定制。例如在医疗领域，可能需要使用领域专用的BioBERT模型，配合医学知识图谱的向量化存储，并通过严谨的提示工程确保输出的专业性。技术选型时需要平衡计算资源、响应延迟和准确率等关键指标，最终构建出高效可靠的AI应用系统。</p>
<p><a rel="nofollow" href="https://wangqianhong.com/2024/04/%e5%a6%82%e4%bd%95%e5%bc%80%e5%8f%91%e4%b8%80%e4%b8%aaai%e5%ba%94%e7%94%a8/">如何开发一个AI应用</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2024/04/%e5%a6%82%e4%bd%95%e5%bc%80%e5%8f%91%e4%b8%80%e4%b8%aaai%e5%ba%94%e7%94%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Hugo 介绍</title>
		<link>https://wangqianhong.com/2022/10/hugo-%e4%bb%8b%e7%bb%8d/</link>
					<comments>https://wangqianhong.com/2022/10/hugo-%e4%bb%8b%e7%bb%8d/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Sat, 22 Oct 2022 00:36:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[Go]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=3898</guid>

					<description><![CDATA[<p>概览 Hugo 是用 Go 写的高速静态站点生成器（Static Site Generator），以&#8230; <a href="https://wangqianhong.com/2022/10/hugo-%e4%bb%8b%e7%bb%8d/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">Hugo 介绍</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/10/hugo-%e4%bb%8b%e7%bb%8d/">Hugo 介绍</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<h3>概览</h3>



<p>Hugo 是用 <strong>Go</strong> 写的高速静态站点生成器（Static Site Generator），以超快的构建速度、灵活的模板系统和丰富的功能集合著称，适合博客、文档、公司站、Landing Page 等场景。 (<a href="https://github.com/gohugoio/hugo">GitHub</a>)</p>



<h3>核心特点</h3>



<ul><li><strong>极快的构建速度</strong>：能在秒级甚至毫秒/页级别生成大型站点（这也是 Hugo 的主要卖点）。 (<a href="https://gohugo.io/?utm_source=chatgpt.com">gohugo.io</a>)</li><li><strong>单个二进制即可运行</strong>：Hugo 是一个可独立运行的二进制 CLI，安装/部署非常简单。 (<a href="https://github.com/gohugoio/hugo">GitHub</a>)</li><li><strong>基于文件的内容模型</strong>：内容通常用 Markdown（或其他格式）放在 <code>content/</code>，通过 front matter（YAML/TOML/JSON）控制元数据与 taxonomies（分类/标签）。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li><li><strong>强大的模板系统</strong>：使用 Go template 引擎，支持短代码（shortcodes）、布局继承、局部模板、数据模板等。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li><li><strong>内建资源处理（assets）</strong>：支持 image processing、SCSS/SASS 管道、JS/CSS 压缩、Fingerprinting 等静态资源管线。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li><li><strong>多语言/国际化（i18n）支持</strong>：内建多语言站点支持。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li><li><strong>丰富的主题生态</strong>：有官方/社区维护的主题库，可直接套用或作为起点。 (<a href="https://github.com/gohugoio/hugoThemesSiteBuilder?utm_source=chatgpt.com">GitHub</a>)</li></ul>



<h3>关键概念</h3>



<ul><li><strong>content/</strong>：你的 Markdown 文件和目录结构（每个文件是一个“页面”或文章）。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li><li><strong>layouts/</strong>：模板目录（决定最终 HTML 的呈现）。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li><li><strong>archetypes/</strong>：新建文章的模板（如 <code>hugo new</code> 时使用）。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li><li><strong>shortcodes</strong>：在 Markdown 中使用的可复用模板片段（比如嵌入视频、响应式图集等）。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li><li><strong>data/</strong>：可以放 JSON/YAML/TOML 的数据文件，在模板中直接读取并渲染（适合制作动态目录或外部数据驱动的页面）。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li></ul>



<h3>内部实现 &amp; 技术亮点</h3>



<ul><li>用 <strong>Go</strong> 实现：跨平台构建、单二进制分发，编译后的二进制体积小、启动快。 (<a href="https://github.com/gohugoio/hugo">GitHub</a>)</li><li>模板基于 Go 的 <code>text/template</code>/<code>html/template</code>，性能与安全性好，但模板语法与某些其他 SSG（如 Liquid）略有差异，需要适应。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li><li>静态资源处理（image resizing、Sass/SCSS、concat/minify、fingerprint）内置在 Hugo 的管道里，减少额外构建工具依赖。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li></ul>



<h3>常用命令</h3>



<p>假设已安装 <code>hugo</code> 二进制（见安装文档）：</p>



<pre class="wp-block-code"><code># 新建站点
hugo new site mysite

# 本地预览（开发服务器，实时热重载）
hugo server -D

# 新建一篇文章（会根据 archetype 自动填 front matter）
hugo new posts/my-first-post.md

# 生成静态站点（输出到 public/）
hugo -v

# 指定输出目录
hugo --destination ./dist
</code></pre>



<p>（这些命令与教程在官方文档/入门页可查到）。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</p>



<h3>部署与托管</h3>



<p>Hugo 生成静态文件后可托管到任何静态站点主机或 CDN：</p>



<ul><li><strong>GitHub Pages</strong>（通过 gh-pages 或 actions 自动部署）。 (<a href="https://gohugo.io/host-and-deploy/host-on-github-pages/?utm_source=chatgpt.com">gohugo.io</a>)</li><li><strong>Netlify</strong>（支持自动构建、预览分支、表单、函数等）。 (<a href="https://docs.netlify.com/build/frameworks/framework-setup-guides/hugo/?utm_source=chatgpt.com">Netlify Docs</a>)</li><li><strong>Cloudflare Pages / AWS S3 + CloudFront / Vercel</strong> 等静态托管或边缘平台均可。 (<a href="https://developers.cloudflare.com/pages/framework-guides/deploy-a-hugo-site/?utm_source=chatgpt.com">Cloudflare Docs</a>)</li></ul>



<h3>生态与社区</h3>



<ul><li><strong>主题库</strong>：官方/社区主题集中在 themes.gohugo.io（也有 GitHub 仓库索引）。 (<a href="https://github.com/gohugoio/hugoThemesSiteBuilder?utm_source=chatgpt.com">GitHub</a>)</li><li><strong>活跃发布与维护</strong>：Hugo 发布频繁（可查看 Releases 页面与官方 News 列表），社区活跃。 最近若干次小版本和功能更新详见 Releases。 (<a href="https://github.com/gohugoio/hugo/releases?utm_source=chatgpt.com">GitHub</a>)</li><li><strong>文档齐全</strong>：官方文档覆盖安装、模板、管道、部署等，适合查阅与学习。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li></ul>



<h3>优点 / 适用场景</h3>



<p><strong>优点</strong></p>



<ul><li>构建速度快（大型站点也能秒级完成）。 (<a href="https://gohugo.io/?utm_source=chatgpt.com">gohugo.io</a>)</li><li>无需运行时服务器（生成静态文件后可放 CDN），运维成本低。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li><li>内置丰富的功能（图像处理、管道、多语言、taxonomy），减少外部工具依赖。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li></ul>



<p><strong>适用场景</strong></p>



<ul><li>个人/团队博客、技术文档站、公司站、产品落地页、知识库（非交互式）等。 (<a href="https://gohugo.io/?utm_source=chatgpt.com">gohugo.io</a>)</li></ul>



<h3>缺点 / 需要注意的点</h3>



<ul><li><strong>不是动态应用框架</strong>：对需要用户交互（登录、动态评论、实时功能）的场景，需要额外接入服务（如 Netlify Functions、第三方评论、后台 API）。</li><li><strong>模板学习曲线</strong>：Go template 的语法/模板逻辑对新手可能有点不直观（尤其从 Liquid/Handlebars 转来）。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li><li><strong>部分高级功能依赖构建时逻辑</strong>：例如需要 CMS（内容管理后台）可以用 Netlify CMS、Forestry、Netlify CMS 等第三方或 headless CMS 来配合。<br>（这些是选择 SSG 时通用的权衡点。）</li></ul>



<h3>实操建议</h3>



<ol><li>先在本地用 <code>hugo new site</code> + 一个社区主题 快速搭建并用 <code>hugo server -D</code> 调试。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li><li>把站点托管在 Git 仓库，配置 CI（GitHub Actions / GitLab CI / Netlify）在 push 时自动 <code>hugo</code> 构建并部署到静态托管服务。 (<a href="https://gohugo.io/host-and-deploy/host-on-github-pages/?utm_source=chatgpt.com">gohugo.io</a>)</li><li>若要图像优化或 Sass 管理，优先尝试 Hugo 内置的资源管道，必要时再补充外部构建工具。 (<a href="https://gohugo.io/about/introduction/?utm_source=chatgpt.com">gohugo.io</a>)</li></ol>



<h3>参考与文档</h3>



<ul><li>官方 GitHub 仓库（源码、Issues、Releases）：gohugoio/hugo。 (<a href="https://github.com/gohugoio/hugo">GitHub</a>)</li><li>官方站点与文档（入门、模板、管道、部署）：gohugo.io。 (<a href="https://gohugo.io/?utm_source=chatgpt.com">gohugo.io</a>)</li><li>Releases（查看最近版本、变更日志）：GitHub Releases。 (<a href="https://github.com/gohugoio/hugo/releases?utm_source=chatgpt.com">GitHub</a>)</li><li>主题库（themes.gohugo.io / 主题索引仓库）。 (<a href="https://github.com/gohugoio/hugoThemesSiteBuilder?utm_source=chatgpt.com">GitHub</a>)</li></ul>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/10/hugo-%e4%bb%8b%e7%bb%8d/">Hugo 介绍</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2022/10/hugo-%e4%bb%8b%e7%bb%8d/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Debian中的vi开启鼠标右键功能</title>
		<link>https://wangqianhong.com/2022/10/debian%e4%b8%ad%e7%9a%84vi%e5%bc%80%e5%90%af%e9%bc%a0%e6%a0%87%e5%8f%b3%e9%94%ae%e5%8a%9f%e8%83%bd/</link>
					<comments>https://wangqianhong.com/2022/10/debian%e4%b8%ad%e7%9a%84vi%e5%bc%80%e5%90%af%e9%bc%a0%e6%a0%87%e5%8f%b3%e9%94%ae%e5%8a%9f%e8%83%bd/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Fri, 14 Oct 2022 12:53:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[Debian]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=3863</guid>

					<description><![CDATA[<p>debian系统中用鼠标右键粘贴时，会导致后面内容出错，可以修改vi的配置/usr/share/vi&#8230; <a href="https://wangqianhong.com/2022/10/debian%e4%b8%ad%e7%9a%84vi%e5%bc%80%e5%90%af%e9%bc%a0%e6%a0%87%e5%8f%b3%e9%94%ae%e5%8a%9f%e8%83%bd/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">Debian中的vi开启鼠标右键功能</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/10/debian%e4%b8%ad%e7%9a%84vi%e5%bc%80%e5%90%af%e9%bc%a0%e6%a0%87%e5%8f%b3%e9%94%ae%e5%8a%9f%e8%83%bd/">Debian中的vi开启鼠标右键功能</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>debian系统中用鼠标右键粘贴时，会导致后面内容出错，可以修改vi的配置<code>/usr/share/vim/vim90/defaults.vim</code></p>



<pre class="wp-block-preformatted">把<code>set mouse=a</code>修改为<code>set mouse-=a</code></pre>



<p>报错修改就可以正常使用鼠标右键功能</p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/10/debian%e4%b8%ad%e7%9a%84vi%e5%bc%80%e5%90%af%e9%bc%a0%e6%a0%87%e5%8f%b3%e9%94%ae%e5%8a%9f%e8%83%bd/">Debian中的vi开启鼠标右键功能</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2022/10/debian%e4%b8%ad%e7%9a%84vi%e5%bc%80%e5%90%af%e9%bc%a0%e6%a0%87%e5%8f%b3%e9%94%ae%e5%8a%9f%e8%83%bd/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Bleve 查询时如何处理特殊字符</title>
		<link>https://wangqianhong.com/2022/10/bleve-%e6%9f%a5%e8%af%a2%e6%97%b6%e5%a6%82%e4%bd%95%e5%a4%84%e7%90%86%e7%89%b9%e6%ae%8a%e5%ad%97%e7%ac%a6/</link>
					<comments>https://wangqianhong.com/2022/10/bleve-%e6%9f%a5%e8%af%a2%e6%97%b6%e5%a6%82%e4%bd%95%e5%a4%84%e7%90%86%e7%89%b9%e6%ae%8a%e5%ad%97%e7%ac%a6/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Sun, 09 Oct 2022 02:43:23 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[Bleve]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=3849</guid>

					<description><![CDATA[<p>Bleve（https://github.com/blevesearch/bleve）是一个全文检索&#8230; <a href="https://wangqianhong.com/2022/10/bleve-%e6%9f%a5%e8%af%a2%e6%97%b6%e5%a6%82%e4%bd%95%e5%a4%84%e7%90%86%e7%89%b9%e6%ae%8a%e5%ad%97%e7%ac%a6/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">Bleve 查询时如何处理特殊字符</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/10/bleve-%e6%9f%a5%e8%af%a2%e6%97%b6%e5%a6%82%e4%bd%95%e5%a4%84%e7%90%86%e7%89%b9%e6%ae%8a%e5%ad%97%e7%ac%a6/">Bleve 查询时如何处理特殊字符</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>Bleve（<a href="https://github.com/blevesearch/bleve" target="_blank" rel="noreferrer noopener">https://github.com/blevesearch/bleve</a>）是一个全文检索库，用于Go语言。它支持各种查询类型。</p>



<p>Bleve在存储mime_type字段，有类似“image/jpeg”这样数据的时候，我们可以设置字段的Analyzer为keyword，不分词查询：</p>



<pre class="wp-block-code"><code>fileMapping := bleve.NewIndexMapping()
fileMapping.DefaultAnalyzer = "keyword"
docMapping := bleve.NewDocumentMapping()
// 关键字类型字段，不分词
keywordField := bleve.NewKeywordFieldMapping()
docMapping.AddFieldMappingsAt("mime_type", keywordField)
fileMapping.AddDocumentMapping("file", docMapping)
index, err = bleve.New(path, fileMapping)
if err != nil {
	return err
}</code></pre>



<p>可以使用下面代码查看keyword是否生效：</p>



<pre class="wp-block-code"><code>// 获取 mime_type 字段的所有词条
fieldDict, _ := index.FieldDict("mime_type")
defer fieldDict.Close()

for {
	termEntry, err := fieldDict.Next()
	if err != nil || termEntry == nil {
		break
	}
	fmt.Printf("Term: %s\n", termEntry.Term)
}</code></pre>



<p>如果结果是Term: image/jpeg，就表示映射设置成功了</p>



<p>当使用NewPrefixQuery时，可以保证查询的时候，对关键词使用keyword分析器，不进行分词查询</p>



<pre class="wp-block-code"><code>prefixQuery := bleve.NewPrefixQuery(mimeType)
prefixQuery.SetField("mime_type")
prefixSearch := bleve.NewSearchRequest(prefixQuery)
prefixResults, err := index.Search(prefixSearch)
if err != nil {
	return err
}
fmt.Printf("前缀查询结果数: %d", prefixResults.Total)</code></pre>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/10/bleve-%e6%9f%a5%e8%af%a2%e6%97%b6%e5%a6%82%e4%bd%95%e5%a4%84%e7%90%86%e7%89%b9%e6%ae%8a%e5%ad%97%e7%ac%a6/">Bleve 查询时如何处理特殊字符</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2022/10/bleve-%e6%9f%a5%e8%af%a2%e6%97%b6%e5%a6%82%e4%bd%95%e5%a4%84%e7%90%86%e7%89%b9%e6%ae%8a%e5%ad%97%e7%ac%a6/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Nextcloud文档在线协作Collabora服务的部署</title>
		<link>https://wangqianhong.com/2022/09/nextcloud%e6%96%87%e6%a1%a3%e5%9c%a8%e7%ba%bf%e5%8d%8f%e4%bd%9ccollabora%e6%9c%8d%e5%8a%a1%e7%9a%84%e9%83%a8%e7%bd%b2/</link>
					<comments>https://wangqianhong.com/2022/09/nextcloud%e6%96%87%e6%a1%a3%e5%9c%a8%e7%ba%bf%e5%8d%8f%e4%bd%9ccollabora%e6%9c%8d%e5%8a%a1%e7%9a%84%e9%83%a8%e7%bd%b2/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Sun, 04 Sep 2022 08:56:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[nextcloud]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=3718</guid>

					<description><![CDATA[<p>搭建个人文件系统，采用了NextCloud + Collabora 的方式搭建，方便大家分享文档和保&#8230; <a href="https://wangqianhong.com/2022/09/nextcloud%e6%96%87%e6%a1%a3%e5%9c%a8%e7%ba%bf%e5%8d%8f%e4%bd%9ccollabora%e6%9c%8d%e5%8a%a1%e7%9a%84%e9%83%a8%e7%bd%b2/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">Nextcloud文档在线协作Collabora服务的部署</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/09/nextcloud%e6%96%87%e6%a1%a3%e5%9c%a8%e7%ba%bf%e5%8d%8f%e4%bd%9ccollabora%e6%9c%8d%e5%8a%a1%e7%9a%84%e9%83%a8%e7%bd%b2/">Nextcloud文档在线协作Collabora服务的部署</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>搭建个人文件系统，采用了NextCloud + Collabora 的方式搭建，方便大家分享文档和保存文档使用，并可以在线协助编辑文档。</p>



<h3>部署mysql</h3>



<p>首先部署数据库，如果只是测试，也可以不安装数据库，直接使用sqlite做数据库即可，但如果是生产环境，建议使用其他数据库：</p>



<pre class="wp-block-code"><code>docker run --name nextcloud_db -e TZ='Asia/Shanghai' -e MYSQL_ROOT_PASSWORD='你的密码' -e MYSQL_DATABASE=nextcloud -e MYSQL_USER=nextcloud -e MYSQL_PASSWORD='你的密码' -v /你的路径/mysql_data:/var/lib/mysql -p 3306:3306  -td  mysql:8.4</code></pre>



<h3>部署nextcloud</h3>



<pre class="wp-block-code"><code>docker run --name nextcloud -e TZ='Asia/Shanghai' -e MYSQL_HOST=localhost:3306 -e MYSQL_DATABASE=nextcloud -e MYSQL_USER=nextcloud -v /你的路径/collabora_data:/var/www/html/data -p 8080:80  -td  nextcloud:production</code></pre>



<p>部署完成之后，通过http://&lt;服务器IP>:8080 完成配置</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="563" height="828" src="https://wangqianhong.com/wp-content/uploads/2024/11/image.png" alt="" class="wp-image-3722" srcset="https://wangqianhong.com/wp-content/uploads/2024/11/image.png 563w, https://wangqianhong.com/wp-content/uploads/2024/11/image-204x300.png 204w" sizes="(max-width: 563px) 100vw, 563px" /></figure>



<h3>部署collabora</h3>



<pre class="wp-block-code"><code>docker run --name nextcloud_collabora -e TZ='Asia/Shanghai' -e domain=服务器IP -e username=admin -e password='你的密码'  -e "extra_params=--o:ssl.enable=false" --cap-add MKNOD -p 9980:9980  -td  collabora/code:24.04.9.1.1</code></pre>



<p>安装完成之后，访问http://&lt;服务器IP>:9980 如果页面显示ok，表示安装成功</p>



<h3>安装netcloud office插件</h3>



<p>由于自动下载安装插件需要翻墙，所以这里需要下载离线安装包，并手动安装</p>



<p>访问<a href="https://apps.nextcloud.com/" target="_blank" rel="noreferrer noopener">https://apps.nextcloud.com/</a>，搜索collabora online和nextcloud office，然后下载离线安装包 richdocuments和richdocumentscode</p>



<pre class="wp-block-preformatted">#把安装包复制到对应的目录下面
<code>docker cp richdocumentscode.tar.gz nextcloud:/var/www/html/apps</code>

#进入容器
<code>docker exec -it -uroot nextcloud /bin/bash</code>

#解压文件并修改权限
<code>tar -zxvf richdocumentscode.tar.gz</code>
<code>chown www-data:www-data richdocumentscode -R</code>

#另一个安装包也是同样的操作
</pre>



<p>退出容器，然后重启</p>



<pre class="wp-block-code"><code>docker restart nextcloud</code></pre>



<p>重启之后，在<code>http://&lt;服务器IP>:8080/settings/apps/disabled</code>下面启用Collabora Online &#8211; Built-in CODE Server和Nextcloud Office插件</p>



<p>然后在<code>http://&lt;服务器IP>:8080/settings/admin/richdocuments</code>下选择使用自有服务器，设置collabora的服务器地址：</p>



<pre class="wp-block-code"><code>http://&lt;服务器IP>:9980/</code></pre>



<p>点击保存，在上面会显示连接成功</p>



<pre class="wp-block-preformatted">Collabora Online 服务器可以访问。
Collabora Online Development Edition 24.04.9.1 55317ef
<strong>浏览器使用的 URL：</strong> <code>http://&lt;服务器IP>:9980</code>
<strong>Collabora 使用的 Nextcloud URL：</strong> <code>http://&lt;服务器IP>:8080</code> <em>(Determined from the browser URL)</em></pre>



<p></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/09/nextcloud%e6%96%87%e6%a1%a3%e5%9c%a8%e7%ba%bf%e5%8d%8f%e4%bd%9ccollabora%e6%9c%8d%e5%8a%a1%e7%9a%84%e9%83%a8%e7%bd%b2/">Nextcloud文档在线协作Collabora服务的部署</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2022/09/nextcloud%e6%96%87%e6%a1%a3%e5%9c%a8%e7%ba%bf%e5%8d%8f%e4%bd%9ccollabora%e6%9c%8d%e5%8a%a1%e7%9a%84%e9%83%a8%e7%bd%b2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>OpenSSL 自签名证书</title>
		<link>https://wangqianhong.com/2022/08/openssl-%e8%87%aa%e7%ad%be%e5%90%8d%e8%af%81%e4%b9%a6/</link>
					<comments>https://wangqianhong.com/2022/08/openssl-%e8%87%aa%e7%ad%be%e5%90%8d%e8%af%81%e4%b9%a6/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Thu, 25 Aug 2022 12:47:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[openssl]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=3705</guid>

					<description><![CDATA[<p>使用 OpenSSL 生成 TLS 自签名证书和自签名 CA 通常包括以下几个步骤： 生成自签名 C&#8230; <a href="https://wangqianhong.com/2022/08/openssl-%e8%87%aa%e7%ad%be%e5%90%8d%e8%af%81%e4%b9%a6/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">OpenSSL 自签名证书</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/08/openssl-%e8%87%aa%e7%ad%be%e5%90%8d%e8%af%81%e4%b9%a6/">OpenSSL 自签名证书</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>使用 OpenSSL 生成 TLS 自签名证书和自签名 CA 通常包括以下几个步骤：</p>



<h3>生成自签名 CA 证书</h3>



<p>首先，生成 CA 私钥和 CA 自签名证书。CA 证书用于签署 TLS 服务器证书</p>



<pre class="wp-block-code"><code>openssl genrsa -out ca.key 4096</code></pre>



<p>这将生成一个 4096 位的 RSA 私钥并保存为 <code>ca.key</code> 文件。</p>



<pre class="wp-block-code"><code>openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt</code></pre>



<ul><li>-x509 表示生成自签名证书</li><li>-new 表示创建一个新的证书请求</li><li>-nodes 表示不对私钥加密</li><li>-key ca.key 表示使用之前生成的 ca.key 私钥</li><li>-days 3650 表示证书有效期为 3650 天（约 10 年）</li><li>-out ca.crt 表示将证书保存为 ca.crt</li></ul>



<p>提示填写证书的信息（如国家代码、组织名、域名等），这些信息会包含在 CA 证书中。</p>



<h3>生成服务器的私钥和证书请求 (CSR)</h3>



<p>接下来，为服务器生成私钥和证书签名请求 (CSR)：</p>



<pre class="wp-block-code"><code>openssl genrsa -out server.key 2048</code></pre>



<p>这将生成一个 2048 位的 RSA 私钥并保存为 server.key。</p>



<pre class="wp-block-code"><code>openssl req -new -key server.key -out server.csr</code></pre>



<ul><li>-new 表示生成一个新的证书请求</li><li>-key server.key 表示使用刚才生成的服务器私钥</li><li>-out server.csr 表示生成的 CSR 文件名为 server.csr</li></ul>



<p>在此过程中，需要填写有关服务器的信息，最重要的是 Common Name (CN)，应填写服务器域名或 IP 地址。</p>



<h3>用 CA 签署服务器证书</h3>



<p>现在，使用之前生成的自签名 CA 证书和私钥来签署服务器证书请求。</p>



<pre class="wp-block-code"><code>openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 825 -sha256</code></pre>



<ul><li>-req 表示基于证书请求 (CSR) 生成证书</li><li>-CA ca.crt 表示使用 CA 证书来签署服务器证书</li><li>-CAkey ca.key 表示使用 CA 的私钥来签署证书</li><li>-CAcreateserial 表示自动生成一个 ca.srl 文件，保存 CA 的序列号</li><li>-out server.crt 表示将生成的服务器证书保存为 server.crt</li><li>-days 825 表示证书的有效期为 825 天</li><li>-sha256 表示使用 SHA256 进行签名</li></ul>



<h3>验证生成的证书</h3>



<p>可以使用以下命令来检查生成的证书是否有效：</p>



<pre class="wp-block-code"><code>openssl x509 -in server.crt -text -noout</code></pre>



<p>这将显示 server.crt 的详细信息。</p>



<h3>配置 TLS</h3>



<ul><li>ca.crt 是自签名 CA 证书，可以分发给客户端，供其信任</li><li>server.crt 是服务器证书，用于配置在你的服务器上</li><li>server.key 是服务器私钥，用于安全连接</li></ul>



<p>你可以将这些文件用于设置 HTTPS 服务器或其他 TLS 应用。</p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/08/openssl-%e8%87%aa%e7%ad%be%e5%90%8d%e8%af%81%e4%b9%a6/">OpenSSL 自签名证书</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2022/08/openssl-%e8%87%aa%e7%ad%be%e5%90%8d%e8%af%81%e4%b9%a6/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Nominatim 地址编码</title>
		<link>https://wangqianhong.com/2022/08/nominatim-%e5%9c%b0%e5%9d%80%e7%bc%96%e7%a0%81/</link>
					<comments>https://wangqianhong.com/2022/08/nominatim-%e5%9c%b0%e5%9d%80%e7%bc%96%e7%a0%81/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Sun, 21 Aug 2022 01:40:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[Nominatim]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=3686</guid>

					<description><![CDATA[<p>在平时开发应用中，经常会有通过经纬度获取地址信息的需求，这种需要可以通过高德等地图软件提供的收费AP&#8230; <a href="https://wangqianhong.com/2022/08/nominatim-%e5%9c%b0%e5%9d%80%e7%bc%96%e7%a0%81/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">Nominatim 地址编码</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/08/nominatim-%e5%9c%b0%e5%9d%80%e7%bc%96%e7%a0%81/">Nominatim 地址编码</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>在平时开发应用中，经常会有通过经纬度获取地址信息的需求，这种需要可以通过高德等地图软件提供的收费API处理，也可以自己搭建地址编码服务器。</p>



<h3>Nominatim</h3>



<p>Nominatim（<a href="https://github.com/osm-search/Nominatim" target="_blank" rel="noreferrer noopener">https://github.com/osm-search/Nominatim</a>）是一个可以按名称和地址来搜索OSM中的数据，并生成OSM点的合成地址的工具（反向地理编码）。可用在http://nominatim.openstreetmap.org找到这个工具。Nominatim也用在<a href="http://www.openstreetmap.org/" target="_blank" rel="noreferrer noopener">OpenStreetMap首页</a>的<a href="http://wiki.openstreetmap.org/wiki/Search" target="_blank" rel="noreferrer noopener">搜索</a>工具栏中，同时也为<a href="http://wiki.openstreetmap.org/wiki/MapQuest" target="_blank" rel="noreferrer noopener">MapQuest Open Initiative</a>提供搜索支持。</p>



<p><strong>数据导入阶段</strong></p>



<p>读取原始OSM数据，并提取对地理编码有用的所有信息。这部分由osm2pgsql完成，该工具也可用于导入渲染数据库。它使用osm2pgsql/src/output-gatetter中的特殊地名词典输出插件。[ch]pp.导入的结果可以在数据库表中找到。</p>



<p><strong>地址计算或索引阶段</strong></p>



<p>从位置获取数据，并添加地理编码所需的其他信息。它按重要性对地点进行排名，将属于一起的对象链接在一起，并计算地址和搜索索引。大部分工作是通过数据库触发器在PL/pgSQL中完成的，可以在sql/functions/目录中的文件中找到。</p>



<p><strong>搜索前端</strong></p>



<p>实现了实际的API。它接受用户的搜索和反向地理编码查询，查找数据并以请求的格式返回结果。这部分是用PHP编写的，可以在lib/和website/目录中找到。使用apache。</p>



<h3>Docker compose安装</h3>



<pre class="wp-block-code"><code>services:
    nominatim:
        container_name: nominatim
        image: mediagis/nominatim:4.4
        ports:
            - "5432:5432"
            - "8080:8080"
        environment:
            TZ: Asia/Shanghai
            PBF_URL: https://download.geofabrik.de/asia/china-latest.osm.pbf
            REPLICATION_URL: https://download.geofabrik.de/asia/china-updates/
            NOMINATIM_PASSWORD: 123456
            IMPORT_WIKIPEDIA: "true"
            IMPORT_US_POSTCODES: "true"
            IMPORT_GB_POSTCODES: "true"
            REPLICATION_UPDATE_INTVAL: 86400
            THREADS: 16
        volumes:
            - type: bind
              source: /home/test/nominatim/data/db
              target: /var/lib/postgresql/14/main
            - type: bind
              source: /home/test/nominatim/data/flatnode
              target: /nominatim/flatnode
        shm_size: 1gb
</code></pre>



<p>5432是PostgreSQL数据库的端口，8080是服务启动之后提供的web接口端口</p>



<p>PBF_URL：数据包地址</p>



<p>REPLICATION_URL：更新包地址</p>



<p>NOMINATIM_PASSWORD：数据库密码</p>



<p>IMPORT_WIKIPEDIA：导入wiki数据</p>



<p>IMPORT_US_POSTCODES：导入美国邮编</p>



<p>IMPORT_GB_POSTCODES：导入邮编</p>



<p>REPLICATION_UPDATE_INTVAL：更新间隔，单位秒</p>



<p>THREADS：解析地址的线程</p>



<p>如果docker下载osm.pbf很慢，也可以用下载工具下完之后，映射到docker里面：</p>



<pre class="wp-block-code"><code>#PBF_URL: https://download.geofabrik.de/asia/china-latest.osm.pbf
PBF_PATH: /nominatim/data/osm/planet-latest.osm.pbf

volumes:
  - /home/test/nominatim/data/osm:/nominatim/data/osm</code></pre>



<p>这里使用中国的pbf，安装解析过程比较长（可能需要2、3天的时间），具体时间由服务器配置决定。</p>



<p>看到日志出现下面的内容表示服务启动成功：</p>



<pre class="wp-block-preformatted">LOG: database system was shut down at 2022-08-16 05:33:06 UTC
LOG: database system is ready to accept connections</pre>



<h3>全球地址数据</h3>



<p>如果使用全量pbf数据，替换PBF_URL和REPLICATION_URL 的链接：<a href="https://ftp5.gwdg.de/pub/misc/openstreetmap/planet.openstreetmap.org/pbf/planet-latest.osm.pbf">https://ftp5.gwdg.de/pub/misc/openstreetmap/planet.openstreetmap.org/pbf/planet-latest.osm.pbf</a></p>



<p><a href="https://ftp5.gwdg.de/pub/misc/openstreetmap/planet.openstreetmap.org/replication/day/">https://ftp5.gwdg.de/pub/misc/openstreetmap/planet.openstreetmap.org/replication/day/</a></p>



<p>全量数据对硬件要求比较高，而且解析时间更长，可能需要一周的时间：</p>



<pre class="wp-block-preformatted">- 16 core CPU (set THREADS variable to number of cores/threads available)
- 64GB RAM
- 1.5TB (NVMe) SSD storage</pre>



<h3>接口API</h3>



<p><a href="https://nominatim.org/release-docs/develop/api/Overview/">https://nominatim.org/release-docs/develop/api/Overview/</a></p>



<p>这里主要介绍其中的3个</p>



<h4>健康检查（/search?q=avenue%20pasteur）</h4>



<pre class="wp-block-preformatted">[]</pre>



<h4>逆地址编码（/reverse?lat=28.259719364765736&amp;lon=112.91566526653007&amp;format=jsonv2&amp;accept-language=zh）</h4>



<pre class="wp-block-preformatted">{
&nbsp; &nbsp; "place_id": 52339186,
&nbsp; &nbsp; "licence": "Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright",
&nbsp; &nbsp; "osm_type": "node",
&nbsp; &nbsp; "osm_id": 3569911293,
&nbsp; &nbsp; "lat": "-41.2903464",
&nbsp; &nbsp; "lon": "174.7779487",
&nbsp; &nbsp; "category": "place",
&nbsp; &nbsp; "type": "house",
&nbsp; &nbsp; "place_rank": 30,
&nbsp; &nbsp; "importance": 0.00000999999999995449,
&nbsp; &nbsp; "addresstype": "place",
&nbsp; &nbsp; "name": "",
&nbsp; &nbsp; "display_name": "138, Wakefield Street, Te Aro, 惠灵顿 / 惠靈頓 / 威靈頓, 6011, 紐西蘭/新西兰",
&nbsp; &nbsp; "address": {
&nbsp; &nbsp; &nbsp; &nbsp; "house_number": "138",
&nbsp; &nbsp; &nbsp; &nbsp; "road": "Wakefield Street",
&nbsp; &nbsp; &nbsp; &nbsp; "suburb": "Te Aro",
&nbsp; &nbsp; &nbsp; &nbsp; "city": "惠灵顿 / 惠靈頓 / 威靈頓",
&nbsp; &nbsp; &nbsp; &nbsp; "county": "惠灵顿 / 惠靈頓 / 威靈頓",
&nbsp; &nbsp; &nbsp; &nbsp; "state": "惠灵顿 / 惠靈頓 / 威靈頓",
&nbsp; &nbsp; &nbsp; &nbsp; "ISO3166-2-lvl4": "NZ-WGN",
&nbsp; &nbsp; &nbsp; &nbsp; "postcode": "6011",
&nbsp; &nbsp; &nbsp; &nbsp; "country": "紐西蘭/新西兰",
&nbsp; &nbsp; &nbsp; &nbsp; "country_code": "nz"
&nbsp; &nbsp; },
&nbsp; &nbsp; "boundingbox": [
&nbsp; &nbsp; &nbsp; &nbsp; "-41.2903964",
&nbsp; &nbsp; &nbsp; &nbsp; "-41.2902964",
&nbsp; &nbsp; &nbsp; &nbsp; "174.7778987",
&nbsp; &nbsp; &nbsp; &nbsp; "174.7779987"
&nbsp; &nbsp; ]
}</pre>



<h4>ID详情（/details?osmtype=W&amp;osmid=1274999787&amp;format=json&amp;accept-language=zh）</h4>



<pre class="wp-block-preformatted">{
&nbsp; &nbsp; "place_id": 73967428,
&nbsp; &nbsp; "parent_place_id": 74020996,
&nbsp; &nbsp; "osm_type": "N",
&nbsp; &nbsp; "osm_id": 3569911293,
&nbsp; &nbsp; "category": "place",
&nbsp; &nbsp; "type": "house",
&nbsp; &nbsp; "admin_level": 15,
&nbsp; &nbsp; "localname": "138",
&nbsp; &nbsp; "names": [],
&nbsp; &nbsp; "addresstags": {
&nbsp; &nbsp; &nbsp; &nbsp; "city": "Wellington",
&nbsp; &nbsp; &nbsp; &nbsp; "housenumber": "138",
&nbsp; &nbsp; &nbsp; &nbsp; "postcode": "6011",
&nbsp; &nbsp; &nbsp; &nbsp; "street": "Wakefield Street",
&nbsp; &nbsp; &nbsp; &nbsp; "suburb": "Te Aro"
&nbsp; &nbsp; },
&nbsp; &nbsp; "housenumber": "138",
&nbsp; &nbsp; "calculated_postcode": "6011",
&nbsp; &nbsp; "country_code": "nz",
&nbsp; &nbsp; "indexed_date": "2024-08-13T00:20:54+00:00",
&nbsp; &nbsp; "importance": 9.99999999995449e-6,
&nbsp; &nbsp; "calculated_importance": 9.99999999995449e-6,
&nbsp; &nbsp; "extratags": [],
&nbsp; &nbsp; "calculated_wikipedia": null,
&nbsp; &nbsp; "rank_address": 30,
&nbsp; &nbsp; "rank_search": 30,
&nbsp; &nbsp; "isarea": false,
&nbsp; &nbsp; "centroid": {
&nbsp; &nbsp; &nbsp; &nbsp; "type": "Point",
&nbsp; &nbsp; &nbsp; &nbsp; "coordinates": [
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 174.7779487,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -41.2903464
&nbsp; &nbsp; &nbsp; &nbsp; ]
&nbsp; &nbsp; },
&nbsp; &nbsp; "geometry": {
&nbsp; &nbsp; &nbsp; &nbsp; "type": "Point",
&nbsp; &nbsp; &nbsp; &nbsp; "coordinates": [
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 174.7779487,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -41.2903464
&nbsp; &nbsp; &nbsp; &nbsp; ]
&nbsp; &nbsp; }
}</pre>



<h3>压力测试</h3>



<p>使用lua脚本进行压力测试</p>



<pre class="wp-block-code"><code>-- 设置随机数种子
math.randomseed(os.time())

-- 随机生成经度和纬度的函数
function generate_random_coordinates()
        local longitude = math.random() * 360 - 180 -- &#91;-180, 180]
        local latitude = math.random() * 180 - 90 -- &#91;-90, 90]
        return longitude, latitude
end

-- 定义请求的函数，wrk会在每次请求之前调用这个函数
request = function()
        -- 生成随机的经纬度
        local longitude, latitude = generate_random_coordinates()

    -- 构建带有随机经纬度的请求URL
    local url = "/reverse?lon=" .. string.format("%.6f", longitude) .. "&amp;lat=" .. string.format("%.6f", latitude).."&amp;format=jsonv2&amp;accept-language=zh"

    -- 返回 GET 请求，包含自定义的 URL
    --print(url)
    return wrk.format("GET", url)
end

-- 定义返回的函数
response = function(status, headers, body)
        if status ~= 200 then
                print(body)
        return
      </code></pre>



<p>测试命令</p>



<pre class="wp-block-preformatted"><code>wrk -t100 -c10000 -d600s -s request.lua --latency http://localhost:8080</code>

开启100个线程，模拟10000个连接，持续600秒，结果如下：
Running 10m test @ http://localhost:8080
100 threads and 10000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 32.97ms 38.66ms 1.99s 92.99%
Req/Sec 70.11 61.57 2.96k 89.25%
Latency Distribution
50% 24.34ms
75% 42.52ms
90% 64.47ms
99% 116.16ms
2609713 requests in 10.00m, 1.22GB read
Socket errors: connect 0, read 17012, write 50793, timeout 26407
Requests/sec: 4349.02
Transfer/sec: 2.08MB</pre>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/08/nominatim-%e5%9c%b0%e5%9d%80%e7%bc%96%e7%a0%81/">Nominatim 地址编码</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2022/08/nominatim-%e5%9c%b0%e5%9d%80%e7%bc%96%e7%a0%81/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
