<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>开发实践 on 蛋蛋忧桑</title><link>https://dandansad.com/categories/%E5%BC%80%E5%8F%91%E5%AE%9E%E8%B7%B5/</link><description>Recent content in 开发实践 on 蛋蛋忧桑</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Tue, 28 Oct 2025 15:21:14 +0800</lastBuildDate><atom:link href="https://dandansad.com/categories/%E5%BC%80%E5%8F%91%E5%AE%9E%E8%B7%B5/index.xml" rel="self" type="application/rss+xml"/><item><title>.bash_profile配置-命令行工具代理</title><link>https://dandansad.com/2025/10/28/bash_profile%E9%85%8D%E7%BD%AE-%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7%E4%BB%A3%E7%90%86/</link><pubDate>Tue, 28 Oct 2025 15:21:14 +0800</pubDate><guid>https://dandansad.com/2025/10/28/bash_profile%E9%85%8D%E7%BD%AE-%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7%E4%BB%A3%E7%90%86/</guid><description>&lt;p&gt;mac的终端中要让命令行工具使用代理，在&lt;code&gt;.bash_profile&lt;/code&gt;中写入如下代码。用&lt;code&gt;proxy&lt;/code&gt;命令开启，&lt;code&gt;unproxy&lt;/code&gt;命令关闭。&lt;/p&gt;
&lt;p&gt;注意：命令默认是一次性的、临时生效的。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alias proxy&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; export http_proxy=socks5://127.0.0.1:7890;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; export https_proxy=socks5://127.0.0.1:7890;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; export all_proxy=socks5://127.0.0.1:7890;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; export no_proxy=socks5://127.0.0.1:7890;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; export HTTP_PROXY=socks5://127.0.0.1:7890;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; export HTTPS_PROXY=socks5://127.0.0.1:7890;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; export ALL_PROXY=socks5://127.0.0.1:7890;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; export NO_PROXY=socks5://127.0.0.1:7890;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alias unproxy&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; unset http_proxy;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; unset https_proxy;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; unset all_proxy;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; unset no_proxy;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; unset HTTP_PROXY;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; unset HTTPS_PROXY;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; unset ALL_PROXY;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; unset NO_PROXY&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>.vimrc配置文件</title><link>https://dandansad.com/2025/10/23/vimrc%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6/</link><pubDate>Thu, 23 Oct 2025 11:54:24 +0800</pubDate><guid>https://dandansad.com/2025/10/23/vimrc%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-nginx" data-lang="nginx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;----------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;基础设置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;----------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;开启语法高亮&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;syntax&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;on&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;显示行号&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;set&lt;/span&gt; &lt;span style="color:#e6db74"&gt;number&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;搜索高亮&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;set&lt;/span&gt; &lt;span style="color:#e6db74"&gt;hlsearch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;set&lt;/span&gt; &lt;span style="color:#e6db74"&gt;incsearch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;启用鼠标操作（可选）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;set&lt;/span&gt; &lt;span style="color:#e6db74"&gt;mouse=a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;显示状态栏&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;set&lt;/span&gt; &lt;span style="color:#e6db74"&gt;laststatus=2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;显示行末空格和制表符&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;set&lt;/span&gt; &lt;span style="color:#e6db74"&gt;list&lt;/span&gt; &lt;span style="color:#e6db74"&gt;listchars=tab:&amp;gt;-,trail:·&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;----------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;缩进设置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;----------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;set&lt;/span&gt; &lt;span style="color:#e6db74"&gt;autoindent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;set&lt;/span&gt; &lt;span style="color:#e6db74"&gt;smartindent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;set&lt;/span&gt; &lt;span style="color:#e6db74"&gt;expandtab&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;set&lt;/span&gt; &lt;span style="color:#e6db74"&gt;tabstop=4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;set&lt;/span&gt; &lt;span style="color:#e6db74"&gt;shiftwidth=4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;set&lt;/span&gt; &lt;span style="color:#e6db74"&gt;softtabstop=4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;----------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;TrueColor&lt;/span&gt; &lt;span style="color:#e6db74"&gt;支持&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;----------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;if&lt;/span&gt; &lt;span style="color:#e6db74"&gt;has(&amp;#34;termguicolors&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;set&lt;/span&gt; &lt;span style="color:#e6db74"&gt;termguicolors&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;endif&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>httpclient与hertzclient在处理Host header时的差别</title><link>https://dandansad.com/2025/08/22/httpclient%E4%B8%8Ehertzclient%E5%9C%A8%E5%A4%84%E7%90%86host-header%E6%97%B6%E7%9A%84%E5%B7%AE%E5%88%AB/</link><pubDate>Fri, 22 Aug 2025 16:41:32 +0800</pubDate><guid>https://dandansad.com/2025/08/22/httpclient%E4%B8%8Ehertzclient%E5%9C%A8%E5%A4%84%E7%90%86host-header%E6%97%B6%E7%9A%84%E5%B7%AE%E5%88%AB/</guid><description>&lt;p&gt;本文中的Host header、request.header.host、req.Header[&amp;ldquo;Host&amp;rdquo;]都指的是请求头中的“Host”字段。&lt;/p&gt;
&lt;h2 id="问题提出"&gt;&lt;a href="#%e9%97%ae%e9%a2%98%e6%8f%90%e5%87%ba" class="header-anchor"&gt;&lt;/a&gt;问题提出
&lt;/h2&gt;&lt;p&gt;在请求转发的过程中，需要从原请求中拿到一些信息来构造新的转发出去的请求，其中就有Host header的问题。一开始我使用的是httpclient，复制请求头的逻辑就是清除一些字段后直接全部复制过去（Host header不在清除范围内），此时程序正常运行。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Request&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Header&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;VisitAll&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;value&lt;/span&gt; []&lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Header&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Add&lt;/span&gt;(string(&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;), string(&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;当我将httpclient切换成hertzclient后，发现一模一样的复制请求头的逻辑遇到了404的错误。经过一番排查发现是httpclient和hertzclient两者对于request.header.host的处理方式不同。对于hertzclient来说，正确的方式应该是不复制请求头中的Host字段。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Request&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Header&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;VisitAll&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;value&lt;/span&gt; []&lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; string(&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Host&amp;#34;&lt;/span&gt; {	 &lt;span style="color:#75715e"&gt;// hertz框架中的client不会更改header.Host，所以不能用原来的Host&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Header&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Add&lt;/span&gt;(string(&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;), string(&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="httpclient"&gt;&lt;a href="#httpclient" class="header-anchor"&gt;&lt;/a&gt;httpclient
&lt;/h2&gt;&lt;p&gt;httpclient请求最终发送的 Host header 并不是取自 req.Header[&amp;ldquo;Host&amp;rdquo;]，而是由 req.Host 字段决定，如果 req.Host 为空，则默认为 req.URL.Host。&lt;/p&gt;
&lt;p&gt;所以说虽然我一开始直接把原始的、错误的 Host header 复制了过去，但是httpclient对请求的 Host header 进行了替换，没有用我设置的 Host header ，所以并没有出现问题。&lt;/p&gt;
&lt;h2 id="hertzclient"&gt;&lt;a href="#hertzclient" class="header-anchor"&gt;&lt;/a&gt;hertzclient
&lt;/h2&gt;&lt;p&gt;hertzclient最后发送的 Host header 就是取自 req.Header[&amp;ldquo;Host&amp;rdquo;] 的，所以说当我将原来的 request.header.host 写到新请求中后，hertzclient发送请求直接使用的是我设置的 Host header ，所以出现404的问题。&lt;/p&gt;
&lt;p&gt;如果说依然使用完整复制的方法，在最后需要用&lt;code&gt;req.Header.SetHost()&lt;/code&gt;替换原始的、错误的 Host header 。注意不是&lt;code&gt;req.SetHost()&lt;/code&gt;，这个方法是设置建立连接的主机地址。&lt;/p&gt;
&lt;h2 id="host-header作用"&gt;&lt;a href="#host-header%e4%bd%9c%e7%94%a8" class="header-anchor"&gt;&lt;/a&gt;Host header作用
&lt;/h2&gt;&lt;p&gt;那话说回来，为什么使用错误的Host header会出现404的问题呢？Host header究竟是起到什么样的作用呢？&lt;/p&gt;
&lt;p&gt;当一个网络请求发出去之后，网址会经过DNS解析为ip地址并建立连接，当连接到服务器后，则会用到 Host header 进行虚拟主机分流。&lt;/p&gt;
&lt;p&gt;而虚拟主机（Virtual Host）是一种服务器技术，它允许在同一台物理服务器（同一个IP地址）上运行多个网站。换句话说，你可以用一台服务器托管多个不同域名的网站，而不需要每个网站都分配一个独立的服务器。区分用户到底访问的是哪个网站的方式就是使用 Host header 进行分流。&lt;/p&gt;
&lt;p&gt;总体来说，一个请求的流程是：域名 → DNS 解析 → IP 地址 → 建立 TCP/SSL 连接 → 发送 HTTP 请求头 (Host) → 虚拟主机分流。&lt;/p&gt;
&lt;p&gt;这里举一个Nginx配置规则进行分流的例子：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-nginx" data-lang="nginx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;server&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;listen&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;80&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;server_name&lt;/span&gt; &lt;span style="color:#e6db74"&gt;www.example.com&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;root&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/var/www/example&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;server&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;listen&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;80&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;server_name&lt;/span&gt; &lt;span style="color:#e6db74"&gt;www.test.com&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;root&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/var/www/test&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;listen 80;&lt;/code&gt; → 表示监听 &lt;strong&gt;HTTP 默认端口 80&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;server_name&lt;/code&gt; → 表示这个虚拟主机匹配的域名。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;root&lt;/code&gt; → 表示网站的根目录，也就是请求 &lt;code&gt;/&lt;/code&gt; 时返回的文件位置。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nginx 的分流步骤可以总结为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;根据端口匹配 server 块&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里两个 server 都监听 80，所以都在候选列表中。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;根据 &lt;code&gt;Host&lt;/code&gt; 匹配 server_name&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nginx 会查找与请求 &lt;code&gt;Host&lt;/code&gt; 最匹配的 server 块。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;匹配成功 → 使用该 server 块的 root 和配置处理请求&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;没有匹配 → 使用默认 server&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nginx 会选择 &lt;code&gt;listen&lt;/code&gt; 指令中第一个或 &lt;code&gt;default_server&lt;/code&gt; 标记的 server 作为默认返回。&lt;/p&gt;</description></item><item><title>apollo配置实时生效：监听器与channel实现</title><link>https://dandansad.com/2025/08/20/apollo%E9%85%8D%E7%BD%AE%E5%AE%9E%E6%97%B6%E7%94%9F%E6%95%88%E7%9B%91%E5%90%AC%E5%99%A8%E4%B8%8Echannel%E5%AE%9E%E7%8E%B0/</link><pubDate>Wed, 20 Aug 2025 17:04:14 +0800</pubDate><guid>https://dandansad.com/2025/08/20/apollo%E9%85%8D%E7%BD%AE%E5%AE%9E%E6%97%B6%E7%94%9F%E6%95%88%E7%9B%91%E5%90%AC%E5%99%A8%E4%B8%8Echannel%E5%AE%9E%E7%8E%B0/</guid><description>&lt;h2 id="问题提出"&gt;&lt;a href="#%e9%97%ae%e9%a2%98%e6%8f%90%e5%87%ba" class="header-anchor"&gt;&lt;/a&gt;问题提出
&lt;/h2&gt;&lt;p&gt;Apollo 是携程开源的分布式配置管理中心，用于统一管理和动态更新应用配置，支持多环境、多命名空间、高可用部署，应用通过客户端 SDK 实现实时拉取和热刷新配置，无需重启即可生效，广泛应用于微服务架构中。本文主要就是探讨两种实现热刷新配置的方法：监听器与channel实现。两者主要的区别是：可以把监听器理解为“事件推送”，channel 理解为“事件拉取”&lt;/p&gt;
&lt;h2 id="监听器"&gt;&lt;a href="#%e7%9b%91%e5%90%ac%e5%99%a8" class="header-anchor"&gt;&lt;/a&gt;监听器
&lt;/h2&gt;&lt;p&gt;监听器的方式就是在主函数中注册监听器，apollo配置改变时通知调用监听器，执行是同步还是异步自行斟酌。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 监听器类型，接收 key 和 change&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ConfigChangeListener&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;change&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;agollo&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Change&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 全局监听器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ListenerManager&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;listenersMu&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sync&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;RWMutex&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;listeners&lt;/span&gt; []&lt;span style="color:#a6e22e"&gt;ConfigChangeListener&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalListenerManager&lt;/span&gt; = &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;ListenerManager&lt;/span&gt;{}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 注册监听器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;RegisterListener&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;listener&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ConfigChangeListener&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;globalListenerManager&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;listenersMu&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Lock&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;defer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalListenerManager&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;listenersMu&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Unlock&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;globalListenerManager&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;listeners&lt;/span&gt; = append(&lt;span style="color:#a6e22e"&gt;globalListenerManager&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;listeners&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;listener&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 通知监听器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;notifyListeners&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;change&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;agollo&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Change&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;globalListenerManager&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;listenersMu&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;RLock&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;defer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalListenerManager&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;listenersMu&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;RUnlock&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;listener&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;range&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalListenerManager&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;listeners&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 调用每个监听器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;listener&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;change&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 注册配置变更监听器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;apollo&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;RegisterListener&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;change&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;agollo&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Change&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;key&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;consts&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;HttpClientConfigKey&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#75715e"&gt;// 执行更新操作&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="channel实现"&gt;&lt;a href="#channel%e5%ae%9e%e7%8e%b0" class="header-anchor"&gt;&lt;/a&gt;channel实现
&lt;/h2&gt;&lt;p&gt;用 channel 事件消费机制来实现，是将配置变化封装为事件发送到 channel，客户端通过读取 channel 主动获取并处理配置更新。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ConfigChangeEvent&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Key&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Change&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;agollo&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ConfigChange&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;configChangeChan&lt;/span&gt; = make(&lt;span style="color:#66d9ef"&gt;chan&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ConfigChangeEvent&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 将 evt 发送到 channel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;evt&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ConfigChangeEvent&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Key&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Change&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;change&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;configChangeChan&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;evt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 将 evt 从 channel 中取出&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;evt&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;range&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;configChangeChan&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;evt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Key&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;consts&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;HttpClientConfigKey&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 执行更新操作&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>在 Golang 中复用 HTTP 连接</title><link>https://dandansad.com/2025/08/20/%E5%9C%A8-golang-%E4%B8%AD%E5%A4%8D%E7%94%A8-http-%E8%BF%9E%E6%8E%A5/</link><pubDate>Wed, 20 Aug 2025 16:31:52 +0800</pubDate><guid>https://dandansad.com/2025/08/20/%E5%9C%A8-golang-%E4%B8%AD%E5%A4%8D%E7%94%A8-http-%E8%BF%9E%E6%8E%A5/</guid><description>&lt;h2 id="问题提出"&gt;&lt;a href="#%e9%97%ae%e9%a2%98%e6%8f%90%e5%87%ba" class="header-anchor"&gt;&lt;/a&gt;问题提出
&lt;/h2&gt;&lt;p&gt;最近在实现一个转发大模型调用请求的中转功能，涉及到要构造client发送请求的内容，一开始我每次都是新建一个client来发送请求，这样的代码实现存在一些问题——每次都要构造新的client，并且要重新建立连接。后面了解到在Go中使用 HTTP 客户端（&lt;code&gt;http.Client&lt;/code&gt;）可以实现&lt;strong&gt;连接复用&lt;/strong&gt;，做到提高性能并减少 TCP 连接的重复建立。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 原始做法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;client&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Client&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;Timeout&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;consts&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;GetRequestTimeout&lt;/span&gt;(), &lt;span style="color:#75715e"&gt;// 设置请求超时时间&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;client&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Do&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;defer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Body&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Close&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 修改后做法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sharedHttpClient&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Do&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;defer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Body&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Close&lt;/span&gt;()&lt;span style="color:#75715e"&gt;// 必须关闭 Body 才能复用连接&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="原理探寻"&gt;&lt;a href="#%e5%8e%9f%e7%90%86%e6%8e%a2%e5%af%bb" class="header-anchor"&gt;&lt;/a&gt;原理探寻
&lt;/h2&gt;&lt;p&gt;在 Go 中，HTTP 客户端默认会复用 TCP 连接，只要使用同一个 &lt;code&gt;http.Client&lt;/code&gt; 实例，并且服务端支持 &lt;strong&gt;Keep-Alive&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;原因是 &lt;code&gt;http.Transport&lt;/code&gt; 内部维护了一个 &lt;strong&gt;连接池&lt;/strong&gt;。只要满足以下条件就可以进行连接复用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;使用同一个 &lt;code&gt;http.Client&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;响应的 &lt;code&gt;Body&lt;/code&gt; 被正确关闭。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;请求的 Host 相同。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;Transport&lt;/code&gt; 会根据空闲连接数和超时管理复用，可根据需求调整&lt;code&gt;Transport&lt;/code&gt;相关的参数。&lt;/p&gt;</description></item><item><title>流式与非流式有什么区别</title><link>https://dandansad.com/2025/08/20/%E6%B5%81%E5%BC%8F%E4%B8%8E%E9%9D%9E%E6%B5%81%E5%BC%8F%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB/</link><pubDate>Wed, 20 Aug 2025 15:59:58 +0800</pubDate><guid>https://dandansad.com/2025/08/20/%E6%B5%81%E5%BC%8F%E4%B8%8E%E9%9D%9E%E6%B5%81%E5%BC%8F%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB/</guid><description>&lt;h2 id="问题提出"&gt;&lt;a href="#%e9%97%ae%e9%a2%98%e6%8f%90%e5%87%ba" class="header-anchor"&gt;&lt;/a&gt;问题提出
&lt;/h2&gt;&lt;p&gt;最近在实现一个转发大模型调用请求的中转功能，因为现在的大模型都支持流式与非流式调用，所以我在实现的时候自然而然的想到了要不要区分两种调用方式，使用不同的代码逻辑。一开始写的时候分开了两个调用方式来写，后来发现这两种方式对于服务端来说实际没有区别，重点在于客户端的使用。&lt;/p&gt;
&lt;h2 id="原理探寻"&gt;&lt;a href="#%e5%8e%9f%e7%90%86%e6%8e%a2%e5%af%bb" class="header-anchor"&gt;&lt;/a&gt;原理探寻
&lt;/h2&gt;&lt;p&gt;首先看一下两种调用方式实际返回的数据。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;====&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;非流式调用返回&lt;/span&gt; &lt;span style="color:#f92672"&gt;====&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;choices&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;finish_reason&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;stop&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;index&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;logprobs&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; null,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;message&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Hello! How can I help you today?&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;reasoning_content&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;用户现在打招呼说Hello!，我要友好回应。所以回复“Hello! How can I help you today?” 这样友好又开放，邀请用户说明需求。&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;assistant&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;created&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1755675226&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;021755675225006530d45f3e18d6c5c13bff8621e54f4f6ee920a&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;model&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;doubao-1-5-thinking-vision-pro-250428&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;service_tier&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;default&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;object&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;chat.completion&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;usage&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;completion_tokens&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;45&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;prompt_tokens&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;70&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;total_tokens&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;115&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;prompt_tokens_details&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;cached_tokens&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;completion_tokens_details&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;reasoning_tokens&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;36&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;====&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;流式调用返回&lt;/span&gt; &lt;span style="color:#f92672"&gt;====&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;data: {&lt;span style="color:#e6db74"&gt;&amp;#34;choices&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;[{&lt;span style="color:#e6db74"&gt;&amp;#34;delta&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;{&lt;span style="color:#e6db74"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;reasoning_content&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;用户&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;assistant&amp;#34;&lt;/span&gt;},&lt;span style="color:#e6db74"&gt;&amp;#34;index&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;}],&lt;span style="color:#e6db74"&gt;&amp;#34;created&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1755675226&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;021755675226374530d45f3e18d6c5c13bff8621e54f4f6ec4025&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;model&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;doubao-1-5-thinking-vision-pro-250428&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;service_tier&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;default&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;object&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;chat.completion.chunk&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;usage&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;null}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;data: {&lt;span style="color:#e6db74"&gt;&amp;#34;choices&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;[{&lt;span style="color:#e6db74"&gt;&amp;#34;delta&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;{&lt;span style="color:#e6db74"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;reasoning_content&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;现在&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;assistant&amp;#34;&lt;/span&gt;},&lt;span style="color:#e6db74"&gt;&amp;#34;index&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;}],&lt;span style="color:#e6db74"&gt;&amp;#34;created&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1755675226&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;021755675226374530d45f3e18d6c5c13bff8621e54f4f6ec4025&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;model&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;doubao-1-5-thinking-vision-pro-250428&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;service_tier&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;default&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;object&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;chat.completion.chunk&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;usage&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;null}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...........
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;data: {&lt;span style="color:#e6db74"&gt;&amp;#34;choices&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;[{&lt;span style="color:#e6db74"&gt;&amp;#34;delta&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;{&lt;span style="color:#e6db74"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;assistant&amp;#34;&lt;/span&gt;},&lt;span style="color:#e6db74"&gt;&amp;#34;finish_reason&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;stop&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;index&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;}],&lt;span style="color:#e6db74"&gt;&amp;#34;created&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1755675226&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;021755675226374530d45f3e18d6c5c13bff8621e54f4f6ec4025&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;model&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;doubao-1-5-thinking-vision-pro-250428&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;service_tier&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;default&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;object&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;chat.completion.chunk&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;usage&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;null}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;data: [DONE]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可以看出，两种请求返回的格式是不一样的，非流式请求返回的是完整的json，而流式请求则是返回分块的json。&lt;/p&gt;
&lt;h2 id="服务端"&gt;&lt;a href="#%e6%9c%8d%e5%8a%a1%e7%ab%af" class="header-anchor"&gt;&lt;/a&gt;服务端
&lt;/h2&gt;&lt;p&gt;在服务端的实现中，实际上我们可以不用在意是流式还是非流式，我们可以统一采用流的方法返回请求体，是否真是流式形式实际上是取决于&lt;strong&gt;约定的返回格式&lt;/strong&gt;以及&lt;strong&gt;客户端处理方式&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 设置响应头&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;k&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;v&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;range&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Header&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;vv&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;range&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Header&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;k&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;vv&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 设置状态码&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Status&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;StatusCode&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 流式转发响应体&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;_&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; = &lt;span style="color:#a6e22e"&gt;io&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Copy&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Response&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;BodyWriter&lt;/span&gt;(), &lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Body&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// 处理错误&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;hlog&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;CtxErrorf&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;Error copying response body: %v&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;String&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;StatusInternalServerError&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;Error copying response body: %v&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;当然，由于我们此处是实现转发的功能，因此可以采用统一的方式。在原始的返回代码中，实际上会有些不同。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//----------非流式输出：传统请求处理----------//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/api/user-data&amp;#39;&lt;/span&gt;, (&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 同步获取所有数据（可能造成阻塞）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;userData&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fetchUserDataFromDB&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;analytics&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;generateUserAnalytics&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;userData&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;preferences&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getUserPreferences&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;userData&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 一次性返回完整JSON
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;({ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;userData&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;analytics&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;preferences&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//----------流式输出：实时数据分块传输----------//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/api/real-time-updates&amp;#39;&lt;/span&gt;, (&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 1. 设置流式响应头
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;setHeader&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;text/event-stream&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;setHeader&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Cache-Control&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;no-cache&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;setHeader&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Connection&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;keep-alive&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 2. 立即发送初始数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;write&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;event: init\ndata: Connection established\n\n&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 3. 创建数据流
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dataStream&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createRealTimeDataStream&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 4. 分块发送数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dataStream&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;data&amp;#39;&lt;/span&gt;, (&lt;span style="color:#a6e22e"&gt;chunk&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;write&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`data: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stringify&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;chunk&lt;/span&gt;)&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;\n\n`&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 5. 处理连接关闭
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;close&amp;#39;&lt;/span&gt;, () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dataStream&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;destroy&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;end&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="客户端"&gt;&lt;a href="#%e5%ae%a2%e6%88%b7%e7%ab%af" class="header-anchor"&gt;&lt;/a&gt;客户端
&lt;/h2&gt;&lt;p&gt;客户端的处理方式就是有明显分别了。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//----------非流式输出：传统请求处理（传统Fetch API使用）----------//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;loadUserData&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;response&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/api/user-data&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fullData&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;response&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 一次性渲染所有数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;renderUserProfile&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;fullData&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;userData&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;renderAnalytics&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;fullData&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;analytics&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;updatePreferencesUI&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;fullData&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;preferences&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;showErrorToast&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Failed to load data&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//----------流式输出：实时数据处理技术（使用EventSource）----------//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;eventSource&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;EventSource&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/api/real-time-updates&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;eventSource&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;addEventListener&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;init&amp;#39;&lt;/span&gt;, (&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;showConnectionStatus&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Connected to real-time feed&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;eventSource&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onmessage&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;data&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;parse&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;updateLiveDashboard&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;eventSource&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onerror&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;showConnectionStatus&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Connection lost - attempting to reconnect...&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;eventSource&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考资料"&gt;&lt;a href="#%e5%8f%82%e8%80%83%e8%b5%84%e6%96%99" class="header-anchor"&gt;&lt;/a&gt;参考资料
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://jishuzhan.net/article/1953334029515796482" target="_blank" rel="noopener"
 &gt;流式输出 vs 非流式输出 - 技术栈&lt;/a&gt;&lt;/p&gt;</description></item><item><title>昇思+香橙派 AI 开发实践：DeepSeek 全流程指南（基于 openEuler）</title><link>https://dandansad.com/2025/07/19/%E6%98%87%E6%80%9D%E9%A6%99%E6%A9%99%E6%B4%BE-ai-%E5%BC%80%E5%8F%91%E5%AE%9E%E8%B7%B5deepseek-%E5%85%A8%E6%B5%81%E7%A8%8B%E6%8C%87%E5%8D%97%E5%9F%BA%E4%BA%8E-openeuler/</link><pubDate>Sat, 19 Jul 2025 15:10:24 +0800</pubDate><guid>https://dandansad.com/2025/07/19/%E6%98%87%E6%80%9D%E9%A6%99%E6%A9%99%E6%B4%BE-ai-%E5%BC%80%E5%8F%91%E5%AE%9E%E8%B7%B5deepseek-%E5%85%A8%E6%B5%81%E7%A8%8B%E6%8C%87%E5%8D%97%E5%9F%BA%E4%BA%8E-openeuler/</guid><description>&lt;h1 id="一--环境准备"&gt;&lt;a href="#%e4%b8%80--%e7%8e%af%e5%a2%83%e5%87%86%e5%a4%87" class="header-anchor"&gt;&lt;/a&gt;一、 环境准备
&lt;/h1&gt;&lt;h2 id="1-镜像烧录"&gt;&lt;a href="#1-%e9%95%9c%e5%83%8f%e7%83%a7%e5%bd%95" class="header-anchor"&gt;&lt;/a&gt;1. 镜像烧录
&lt;/h2&gt;&lt;p&gt;镜像烧录可以在任何操作系统内执⾏，这⾥以在Windows系统为例，使用balenaEtcher⼯具，快速烧录镜像到Micro SD卡中。&lt;/p&gt;
&lt;p&gt;本章节所需的软/硬件如下：&lt;/p&gt;
&lt;p&gt;软件相关：balenaEtcher制卡⼯具、openEuler镜像&lt;/p&gt;
&lt;p&gt;硬件相关：TF卡（64G存储卡）、读卡器&lt;/p&gt;
&lt;h3 id="balenaetcher制卡具下载"&gt;&lt;a href="#balenaetcher%e5%88%b6%e5%8d%a1%e5%85%b7%e4%b8%8b%e8%bd%bd" class="header-anchor"&gt;&lt;/a&gt;balenaEtcher制卡⼯具下载
&lt;/h3&gt;&lt;p&gt;点击链接进行下载安装balenaEtcher⼯具即可。&lt;/p&gt;
&lt;p&gt;下载链接：&lt;a class="link" href="https://etcher.balena.io/%23download-etcher" target="_blank" rel="noopener"
 &gt;https://etcher.balena.io/#download-etcher&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-39.jpg"&gt;&lt;/p&gt;
&lt;h3 id="openeuler镜像下载"&gt;&lt;a href="#openeuler%e9%95%9c%e5%83%8f%e4%b8%8b%e8%bd%bd" class="header-anchor"&gt;&lt;/a&gt;openEuler镜像下载
&lt;/h3&gt;&lt;p&gt;点击链接下载openEuler镜像即可。&lt;/p&gt;
&lt;p&gt;下载链接：&lt;a class="link" href="http://www.orangepi.cn/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-AIpro%2820T%29.html" target="_blank" rel="noopener"
 &gt;http://www.orangepi.cn/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-AIpro(20T).html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-34.jpg"&gt;&lt;/p&gt;
&lt;h3 id="镜像烧录"&gt;&lt;a href="#%e9%95%9c%e5%83%8f%e7%83%a7%e5%bd%95" class="header-anchor"&gt;&lt;/a&gt;镜像烧录
&lt;/h3&gt;&lt;p&gt;将插入TF卡的读卡器与电脑连接，然后打开balenaEtcher⼯具，选择刚刚下载的镜像文件，然后选择TF卡进行烧录即可。&lt;/p&gt;
&lt;p&gt;注意：下载下来的镜像文件是.xz格式的压缩包，要先解压出.img文件，选择.img文件进行烧录。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-2.png"&gt;&lt;/p&gt;
&lt;p&gt;等待TF卡烧录完成拔出读卡器。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-35.jpg"&gt;&lt;/p&gt;
&lt;h2 id="2-连接开发板"&gt;&lt;a href="#2-%e8%bf%9e%e6%8e%a5%e5%bc%80%e5%8f%91%e6%9d%bf" class="header-anchor"&gt;&lt;/a&gt;2. 连接开发板
&lt;/h2&gt;&lt;p&gt;将烧录好的TF卡插入香橙派中，连接电源启动即可。TF卡一直插在香橙派中，不拔出。&lt;/p&gt;
&lt;p&gt;首次连接，我们需要使用HDMI线与显示屏相连，同时插入键盘鼠标才能完成配置操作。在联网后，记下香橙派的IP地址便可用Vscode、MobaXterm等远程连接的软件进行远程连接。&lt;/p&gt;
&lt;p&gt;本章节所需的软/硬件如下：&lt;/p&gt;
&lt;p&gt;软件：Vscode、MobaXterm（任选其一或多个皆可）&lt;/p&gt;
&lt;p&gt;硬件：OrangePi AIpro-20t规格⾹橙派、电源线、HDMI线、显⽰器、⿏&lt;/p&gt;
&lt;p&gt;标、键盘&lt;/p&gt;
&lt;h3 id="首次配置"&gt;&lt;a href="#%e9%a6%96%e6%ac%a1%e9%85%8d%e7%bd%ae" class="header-anchor"&gt;&lt;/a&gt;首次配置
&lt;/h3&gt;&lt;p&gt;开发板开机成功后进行登录操作。&lt;/p&gt;
&lt;p&gt;登录账号：HwHiAiUser，密码：Mind@123（root密码也是这个）&lt;/p&gt;
&lt;p&gt;进入桌面后，点击相应WiFi输入密码进行连接。连接成功后，右键选择“Connection Information”记录下香橙派的IP地址用于同一局域网下远程连接。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-33.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-36.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-37.jpg"&gt;&lt;/p&gt;
&lt;h3 id="mobaxterm连接"&gt;&lt;a href="#mobaxterm%e8%bf%9e%e6%8e%a5" class="header-anchor"&gt;&lt;/a&gt;MobaXterm连接
&lt;/h3&gt;&lt;p&gt;使用MobaXterm可以连接命令行也可以连接图形化界面。&lt;/p&gt;
&lt;p&gt;首先我们进行命令行的连接。点击上方的“Session”后选择“SSH”，然后填入香橙派IP地址，指定登录用户（可选）后，点击“OK”则远程连接成功。连接端口为22。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-40.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-38.jpg"&gt;&lt;/p&gt;
&lt;p&gt;连接远程桌面，我们也是点击上方的“Session”，但选择“VNC”，然后填入香橙派IP地址，连接端口为5901，点击“OK”则远程连接成功。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-42.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-43.jpg"&gt;&lt;/p&gt;
&lt;h3 id="vscode连接"&gt;&lt;a href="#vscode%e8%bf%9e%e6%8e%a5" class="header-anchor"&gt;&lt;/a&gt;Vscode连接
&lt;/h3&gt;&lt;p&gt;下载好Vscode后安装以下插件备用。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-3.png"&gt;&lt;/p&gt;
&lt;p&gt;点击“远程资源管理器”，点击SSH后的加号添加远程连接，输入“ssh HwHiAiUser@你的香橙派实际IP”后回车。然后选择刚刚添加的远程连接，点击箭头后输入密码即可连接成功。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-44.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-45.jpg"&gt;&lt;/p&gt;
&lt;p&gt;连接成功后需要注意，远程的插件要重新安装一下。想要在Vscode远程编辑器中运行Python代码，安装Python扩展即可。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-1.png"&gt;&lt;/p&gt;
&lt;h2 id="3-软件环境升级"&gt;&lt;a href="#3-%e8%bd%af%e4%bb%b6%e7%8e%af%e5%a2%83%e5%8d%87%e7%ba%a7" class="header-anchor"&gt;&lt;/a&gt;3. 软件环境升级
&lt;/h2&gt;&lt;h3 id="toolkit升级800_linux-aarch64"&gt;&lt;a href="#toolkit%e5%8d%87%e7%ba%a7800_linux-aarch64" class="header-anchor"&gt;&lt;/a&gt;Toolkit升级（8.0.0_linux-aarch64）
&lt;/h3&gt;&lt;p&gt;打开终端，使用root⽤⼾，root⽤⼾密码：Mind@123。&lt;/p&gt;
&lt;p&gt;su - root&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-46.jpg"&gt;&lt;/p&gt;
&lt;p&gt;删除镜像中已安装CANN包释放磁盘空间，防⽌安装新的CANN包时报错磁盘空间不⾜。&lt;/p&gt;
&lt;p&gt;cd /usr/local/Ascend/ascend-toolkit&lt;/p&gt;
&lt;p&gt;rm -rf *&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-47.jpg"&gt;&lt;/p&gt;
&lt;p&gt;下载链接：&lt;a class="link" href="https://www.hiascend.com/developer/download/community/result?module=cann&amp;amp;cann=8.0.0.beta1" target="_blank" rel="noopener"
 &gt;https://www.hiascend.com/developer/download/community/result?module=cann&amp;amp;cann=8.0.0.beta1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-48.jpg"&gt;&lt;/p&gt;
&lt;p&gt;选择Ascend-cann-toolkit_8.0.0_linux-aarch64.run进行下载。此处我使用wget命令进行下载。下载完成后赋予其执行权限，然后运行安装。安装过程中需要手动输入一次Y。&lt;/p&gt;
&lt;p&gt;wget &lt;a class="link" href="https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/CANN/CANN%208.0.0/Ascend-cann-toolkit_8.0.0_linux-aarch64.run" target="_blank" rel="noopener"
 &gt;https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/CANN/CANN%208.0.0/Ascend-cann-toolkit_8.0.0_linux-aarch64.run&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;chmod +x Ascend-cann-toolkit_8.0.0_linux-aarch64.run&lt;/p&gt;
&lt;p&gt;./Ascend-cann-toolkit_8.0.0_linux-aarch64.run &amp;ndash;install&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-49.jpg"&gt;&lt;/p&gt;
&lt;p&gt;出现Ascend-cann-toolkit_8.0.0_linux-aarch64 install success则安装成功。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-51.jpg"&gt;&lt;/p&gt;
&lt;p&gt;将source /usr/local/Ascend/ascend-toolkit/set_env.sh加入到/etc/profile文件末尾并加载环境变量。&lt;/p&gt;
&lt;p&gt;vi /etc/profile&lt;/p&gt;
&lt;p&gt;source /usr/local/Ascend/ascend-toolkit/set_env.sh&lt;/p&gt;
&lt;p&gt;source /etc/profile&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-50.jpg"&gt;&lt;/p&gt;
&lt;h3 id="kernels升级310b_800_linux-aarch64"&gt;&lt;a href="#kernels%e5%8d%87%e7%ba%a7310b_800_linux-aarch64" class="header-anchor"&gt;&lt;/a&gt;Kernels升级（310b_8.0.0_linux-aarch64）
&lt;/h3&gt;&lt;p&gt;打开终端，使用root⽤⼾，root⽤⼾密码：Mind@123。&lt;/p&gt;
&lt;p&gt;su - root&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-52.jpg"&gt;&lt;/p&gt;
&lt;p&gt;执⾏如下命令，获取开发板NPU型号。&lt;/p&gt;
&lt;p&gt;npu-smi info&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-53.jpg"&gt;&lt;/p&gt;
&lt;p&gt;下载链接：&lt;a class="link" href="https://www.hiascend.com/developer/download/community/result?module=cann&amp;amp;cann=8.0.0.beta1" target="_blank" rel="noopener"
 &gt;https://www.hiascend.com/developer/download/community/result?module=cann&amp;amp;cann=8.0.0.beta1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-56.jpg"&gt;&lt;/p&gt;
&lt;p&gt;选择Ascend-cann-kernels-310b_8.0.0_linux-aarch64.run进行下载。此处我使用wget命令进行下载。下载完成后赋予其执行权限，然后运行安装。安装过程中需要手动输入一次Y。&lt;/p&gt;
&lt;p&gt;wget &lt;a class="link" href="https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/CANN/CANN%208.0.0/Ascend-cann-kernels-310b_8.0.0_linux-aarch64.run" target="_blank" rel="noopener"
 &gt;https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/CANN/CANN%208.0.0/Ascend-cann-kernels-310b_8.0.0_linux-aarch64.run&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;chmod +x Ascend-cann-kernels-310b_8.0.0_linux-aarch64.run&lt;/p&gt;
&lt;p&gt;./Ascend-cann-kernels-310b_8.0.0_linux-aarch64.run –install&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-54.jpg"&gt;&lt;/p&gt;
&lt;p&gt;出现Ascend-cann-kernels-310b_8.0.0_linux-aarch64 install success则安装成功。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-57.jpg"&gt;&lt;/p&gt;
&lt;h3 id="mindspore升级mindspore250"&gt;&lt;a href="#mindspore%e5%8d%87%e7%ba%a7mindspore250" class="header-anchor"&gt;&lt;/a&gt;MindSpore升级（MindSpore2.5.0）
&lt;/h3&gt;&lt;p&gt;打开终端，使用HwHiAiUser用户。运行以下命令进行安装。&lt;/p&gt;
&lt;p&gt;pip install mindspore==2.5.0 -i &lt;a class="link" href="https://pypi.tuna.tsinghua.edu.cn/simple" target="_blank" rel="noopener"
 &gt;https://pypi.tuna.tsinghua.edu.cn/simple&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;运行以下命令进行检查是否安装成功。&lt;/p&gt;
&lt;p&gt;python -c &amp;ldquo;import mindspore;mindspore.set_device(&amp;lsquo;Ascend&amp;rsquo;);mindspore.run_check()&amp;rdquo;&lt;/p&gt;
&lt;p&gt;出现successfully则为成功。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-65.jpg"&gt;&lt;/p&gt;
&lt;h3 id="swap检查与配置"&gt;&lt;a href="#swap%e6%a3%80%e6%9f%a5%e4%b8%8e%e9%85%8d%e7%bd%ae" class="header-anchor"&gt;&lt;/a&gt;Swap检查与配置
&lt;/h3&gt;&lt;p&gt;打开终端，输⼊如下命令，检查Swap是否开启：&lt;/p&gt;
&lt;p&gt;free -m&lt;/p&gt;
&lt;p&gt;正确输出结果为：&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-55.jpg"&gt;&lt;/p&gt;
&lt;p&gt;如输出的结果中Swap部分为0，则可在终端中输入如下命令，配置Swap：&lt;/p&gt;
&lt;p&gt;sudo fallocate -l 16G /swapfile&lt;/p&gt;
&lt;p&gt;sudo chmod 600/swapfile&lt;/p&gt;
&lt;p&gt;sudo mkswap /swapfile&lt;/p&gt;
&lt;p&gt;sudo swapon /swapfile&lt;/p&gt;
&lt;p&gt;echo &amp;lsquo;/swapfile none swap sw 0 a&amp;rsquo;sudo tee -a /etc/fstab&lt;/p&gt;
&lt;p&gt;完成配置后可再通过 free -m 检查配置是否生效。&lt;/p&gt;
&lt;h3 id="gradio安装"&gt;&lt;a href="#gradio%e5%ae%89%e8%a3%85" class="header-anchor"&gt;&lt;/a&gt;Gradio安装
&lt;/h3&gt;&lt;p&gt;打开终端，输⼊如下命令，安装Gradio 4.44.0：&lt;/p&gt;
&lt;p&gt;pip uninstall gradio -y&lt;/p&gt;
&lt;p&gt;pip install gradio==4.44.0&lt;/p&gt;
&lt;h3 id="mindnlp安装"&gt;&lt;a href="#mindnlp%e5%ae%89%e8%a3%85" class="header-anchor"&gt;&lt;/a&gt;Mindnlp安装
&lt;/h3&gt;&lt;p&gt;打开终端，输⼊如下命令，安装Mindnlp（如已有最好先卸载，重新安装）：&lt;/p&gt;
&lt;p&gt;pip install git+https://github.com/mindspore-lab/mindnlp.git@0.4&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-64.jpg"&gt;&lt;/p&gt;
&lt;h3 id="其他python依赖安装"&gt;&lt;a href="#%e5%85%b6%e4%bb%96python%e4%be%9d%e8%b5%96%e5%ae%89%e8%a3%85" class="header-anchor"&gt;&lt;/a&gt;其他python依赖安装
&lt;/h3&gt;&lt;p&gt;在运行代码时，报错显示缺少什么包就使用pip安装什么包。&lt;/p&gt;
&lt;h1 id="二--运行代码"&gt;&lt;a href="#%e4%ba%8c--%e8%bf%90%e8%a1%8c%e4%bb%a3%e7%a0%81" class="header-anchor"&gt;&lt;/a&gt;二、 运行代码
&lt;/h1&gt;&lt;h2 id="1---下载代码"&gt;&lt;a href="#1---%e4%b8%8b%e8%bd%bd%e4%bb%a3%e7%a0%81" class="header-anchor"&gt;&lt;/a&gt;1. 下载代码
&lt;/h2&gt;&lt;p&gt;代码地址：&lt;a class="link" href="https://github.com/mindspore-courses/orange-pi-mindspore.git" target="_blank" rel="noopener"
 &gt;https://github.com/mindspore-courses/orange-pi-mindspore.git&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;打开终端，使用HwHiAiUser用户。找一个你存放代码的位置运行如下命令：&lt;/p&gt;
&lt;p&gt;git clone &lt;a class="link" href="https://github.com/mindspore-courses/orange-pi-mindspore.git" target="_blank" rel="noopener"
 &gt;https://github.com/mindspore-courses/orange-pi-mindspore.git&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;下载代码后，进入Online/training/01-DeepSeek-R1-Distill-Qwen-1.5B目录，目录中的三个py文件便是我们要运行的代码。&lt;/p&gt;
&lt;h2 id="2---运行代码"&gt;&lt;a href="#2---%e8%bf%90%e8%a1%8c%e4%bb%a3%e7%a0%81" class="header-anchor"&gt;&lt;/a&gt;2. 运行代码
&lt;/h2&gt;&lt;p&gt;可以使用Vscode远程连接开发环境，这样运行调试更为方便。连接步骤之前已经给出，连接成功后打开代码所在文件夹，打开相应代码点击右上角运行即可。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-58.jpg"&gt;&lt;/p&gt;
&lt;p&gt;分别给出三个py文件运行成功的截图。&lt;/p&gt;
&lt;h3 id="deepseek-r1-distill-qwen-15b-lorapy"&gt;&lt;a href="#deepseek-r1-distill-qwen-15b-lorapy" class="header-anchor"&gt;&lt;/a&gt;deepseek-r1-distill-qwen-1.5b-lora.py
&lt;/h3&gt;&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-59.jpg"&gt;&lt;/p&gt;
&lt;h3 id="deepseek-r1-distill-qwen-15b-gradiopy"&gt;&lt;a href="#deepseek-r1-distill-qwen-15b-gradiopy" class="header-anchor"&gt;&lt;/a&gt;deepseek-r1-distill-qwen-1.5b-gradio.py
&lt;/h3&gt;&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-60.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-61.jpg"&gt;&lt;/p&gt;
&lt;h3 id="deepseek-r1-distill-qwen-15b-jitpy"&gt;&lt;a href="#deepseek-r1-distill-qwen-15b-jitpy" class="header-anchor"&gt;&lt;/a&gt;deepseek-r1-distill-qwen-1.5b-jit.py
&lt;/h3&gt;&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-62.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/07/image-63.jpg"&gt;&lt;/p&gt;
&lt;h1 id="三常见问题"&gt;&lt;a href="#%e4%b8%89%e5%b8%b8%e8%a7%81%e9%97%ae%e9%a2%98" class="header-anchor"&gt;&lt;/a&gt;三、常见问题
&lt;/h1&gt;&lt;h2 id="1-无法连接外部网络"&gt;&lt;a href="#1-%e6%97%a0%e6%b3%95%e8%bf%9e%e6%8e%a5%e5%a4%96%e9%83%a8%e7%bd%91%e7%bb%9c" class="header-anchor"&gt;&lt;/a&gt;1. 无法连接外部网络
&lt;/h2&gt;&lt;p&gt;在连接WiFi后，可以在局域网内连接香橙派，但是香橙派无法访问外部网络。&lt;/p&gt;
&lt;p&gt;可以用以下方式解决：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;在运行命令&lt;code&gt;sudo ip route del default via 192.168.0.1 dev usb0&lt;/code&gt;后问题解决，可以访问外部网络。（每次重启后要重新执行命令）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;右键点击图形界面右上角的&lt;code&gt;“网络-&amp;gt;Edit Connections-&amp;gt;选择相应的问题连接（usb0）删除”&lt;/code&gt;即可。（永久生效）&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="2-运行代码时出现权限相关问题"&gt;&lt;a href="#2-%e8%bf%90%e8%a1%8c%e4%bb%a3%e7%a0%81%e6%97%b6%e5%87%ba%e7%8e%b0%e6%9d%83%e9%99%90%e7%9b%b8%e5%85%b3%e9%97%ae%e9%a2%98" class="header-anchor"&gt;&lt;/a&gt;2. 运行代码时出现权限相关问题
&lt;/h2&gt;&lt;p&gt;运行代码时出现“Permission denied”以及其他与当前登录用户相关的问题。&lt;/p&gt;
&lt;p&gt;可以用以下方式解决：&lt;/p&gt;
&lt;p&gt;从下载代码开始，全程使用HwHiAiUser用户，不要使用root用户。同时注意代码存放的位置，尽量放在HwHiAiUser用户目录下，避免引发文件权限的问题。&lt;/p&gt;
&lt;h2 id="3-运行代码时提示ascend显存不足"&gt;&lt;a href="#3-%e8%bf%90%e8%a1%8c%e4%bb%a3%e7%a0%81%e6%97%b6%e6%8f%90%e7%a4%baascend%e6%98%be%e5%ad%98%e4%b8%8d%e8%b6%b3" class="header-anchor"&gt;&lt;/a&gt;3. 运行代码时提示Ascend显存不足
&lt;/h2&gt;&lt;p&gt;运行代码时出现Ascend显存不足的相关提示信息，最后运行失败。有Free memory size is less than half of total memory size.Device 0 Device MOC total size:24823529472 Device MOC free size:9051504640 may be other processes occupying this card, check as: ps -ef|grep python提示的。&lt;/p&gt;
&lt;p&gt;可以用以下方式解决：&lt;/p&gt;
&lt;p&gt;首先使用&lt;code&gt;ps -ef | grep python&lt;/code&gt;命令查看是否有其他 Python 进程正在占用 NPU 导致显存不足，有则&lt;code&gt;kill&lt;/code&gt;相关进程。若无异常则使用&lt;code&gt;npu-smi info&lt;/code&gt;命令查看显存占用，如果发现异常最方便的方法就是使用&lt;code&gt;reboot&lt;/code&gt;命令重启设备。&lt;/p&gt;
&lt;h2 id="4-运行代码时有runtimeerror以及valueerror"&gt;&lt;a href="#4-%e8%bf%90%e8%a1%8c%e4%bb%a3%e7%a0%81%e6%97%b6%e6%9c%89runtimeerror%e4%bb%a5%e5%8f%8avalueerror" class="header-anchor"&gt;&lt;/a&gt;4. 运行代码时有RuntimeError以及ValueError
&lt;/h2&gt;&lt;p&gt;每次代码运行到训练或推理的部分就会报错。&lt;/p&gt;
&lt;p&gt;lora:&lt;code&gt;RuntimeError: aclnnGatherGetWorkspaceSize call failed, please check!&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;gradio:&lt;code&gt;RuntimeError: aclnnCumsumGetWorkspaceSize call failed, please check!&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;jit:&lt;code&gt;ValueError: Attention weights should be of size (1, 12, 6, 6), but is (1, 12, 6, 512)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;可以用以下方式解决：&lt;/p&gt;
&lt;p&gt;检查版本问题，尤其是Mindnlp的版本。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Toolkit版本：8.0.0_linux-aarch64
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Kernels版本：310b_8.0.0_linux-aarch64
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;MindSpore版本：MindSpore 2.5.0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mindnlp版本：mindnlp 0.4.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;即使Mindnlp版本号对应，但仍然建议你先卸载Mindnlp，然后运行&lt;code&gt;pip install git+https://github.com/mindspore-lab/mindnlp.git@0.4&lt;/code&gt;命令重新安装Mindnlp。&lt;/p&gt;
&lt;h2 id="5-jit第二次对话报错"&gt;&lt;a href="#5-jit%e7%ac%ac%e4%ba%8c%e6%ac%a1%e5%af%b9%e8%af%9d%e6%8a%a5%e9%94%99" class="header-anchor"&gt;&lt;/a&gt;5. jit第二次对话报错
&lt;/h2&gt;&lt;p&gt;运行jit的时候，在第二次对话的时候会报&lt;code&gt;RuntimeError: Sync stream error!&lt;/code&gt;错误。&lt;/p&gt;
&lt;p&gt;可以用以下方式解决：&lt;/p&gt;
&lt;p&gt;使用&lt;code&gt;reboot&lt;/code&gt;命令重启设备。&lt;/p&gt;</description></item><item><title>Hadoop配置——两个节点（master和slave1）</title><link>https://dandansad.com/2025/05/29/hadoop%E9%85%8D%E7%BD%AE-%E4%B8%A4%E4%B8%AA%E8%8A%82%E7%82%B9master%E5%92%8Cslave1/</link><pubDate>Thu, 29 May 2025 14:42:14 +0800</pubDate><guid>https://dandansad.com/2025/05/29/hadoop%E9%85%8D%E7%BD%AE-%E4%B8%A4%E4%B8%AA%E8%8A%82%E7%82%B9master%E5%92%8Cslave1/</guid><description>&lt;h2 id="配置要求"&gt;&lt;a href="#%e9%85%8d%e7%bd%ae%e8%a6%81%e6%b1%82" class="header-anchor"&gt;&lt;/a&gt;配置要求
&lt;/h2&gt;&lt;p&gt;目标是配置一个基本的 Hadoop 分布式集群：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;一台主节点：&lt;code&gt;master&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一台从节点：&lt;code&gt;slave1&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;支持：HDFS + YARN&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Java 已配置&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hadoop 已安装成功，路径在 &lt;code&gt;/opt/hadoop&lt;/code&gt;（你可替换为实际路径）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用 &lt;code&gt;hadoop version&lt;/code&gt; 命令测试&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注：前置参考资料在文末，建议先按照前置参考资料进行安装配置到 &lt;code&gt;hadoop version&lt;/code&gt; 命令成功执行步骤，再继续参照本文章。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="修改hostshostname"&gt;&lt;a href="#%e4%bf%ae%e6%94%b9hostshostname" class="header-anchor"&gt;&lt;/a&gt;修改hosts、hostname
&lt;/h2&gt;&lt;p&gt;hosts: /etc/hosts
集群所有主机IP地址与对应主机名
格式：IP（空）主机名&lt;/p&gt;
&lt;p&gt;hostname: /etc/hostname
主节点命名为master，子节点命名为slave1
把主机名直接写入此文件（只能保留一个名字），定义本机的主机名（可能需要重启生效）
使用 &lt;code&gt;sudo hostnamectl set-hostname 新主机名&lt;/code&gt; 设置（即时生效）
使用 &lt;code&gt;hostname&lt;/code&gt; 命令查看当前主机名&lt;/p&gt;
&lt;h2 id="ssh-配置免密"&gt;&lt;a href="#ssh-%e9%85%8d%e7%bd%ae%e5%85%8d%e5%af%86" class="header-anchor"&gt;&lt;/a&gt;SSH 配置免密
&lt;/h2&gt;&lt;h4 id="1-生成-ssh-密钥对如果尚未生成"&gt;&lt;a href="#1-%e7%94%9f%e6%88%90-ssh-%e5%af%86%e9%92%a5%e5%af%b9%e5%a6%82%e6%9e%9c%e5%b0%9a%e6%9c%aa%e7%94%9f%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;1. 生成 SSH 密钥对&lt;/strong&gt;（如果尚未生成）
&lt;/h4&gt;&lt;p&gt;在每台机器上执行：&lt;code&gt;ssh-keygen -t rsa&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;一路回车即可（不要设置密码短语）。&lt;/p&gt;
&lt;h4 id="2-将自己的公钥添加到目标机器的-authorized_"&gt;&lt;a href="#2-%e5%b0%86%e8%87%aa%e5%b7%b1%e7%9a%84%e5%85%ac%e9%92%a5%e6%b7%bb%e5%8a%a0%e5%88%b0%e7%9b%ae%e6%a0%87%e6%9c%ba%e5%99%a8%e7%9a%84-authorized_" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;2. 将自己的公钥添加到目标机器的 authorized_keys 中&lt;/strong&gt;
&lt;/h4&gt;&lt;p&gt;在 &lt;code&gt;master&lt;/code&gt; 上执行以下命令，把自己的公钥发给 &lt;code&gt;slave1&lt;/code&gt; ：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh-copy-id root@localhost
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh-copy-id root@slave1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;同理，在 &lt;code&gt;slave1&lt;/code&gt; 上执行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh-copy-id root@localhost
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh-copy-id root@master
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;从每台机器尝试 ssh 到其他机器（包括自己）进行验证：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh root@localhost
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh root@master
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh root@slave1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="配置hadoop的配置文件"&gt;&lt;a href="#%e9%85%8d%e7%bd%aehadoop%e7%9a%84%e9%85%8d%e7%bd%ae%e6%96%87%e4%bb%b6" class="header-anchor"&gt;&lt;/a&gt;配置Hadoop的配置文件
&lt;/h2&gt;&lt;h3 id="1-core-sitexml"&gt;&lt;a href="#1-core-sitexml" class="header-anchor"&gt;&lt;/a&gt;1. core-site.xml
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; hadoop.tmp.dir
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; file:/opt/hadoop/tmp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; location to store temporary files
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fs.defaultFS
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; hdfs://master:9000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="2-hdfs-sitexml"&gt;&lt;a href="#2-hdfs-sitexml" class="header-anchor"&gt;&lt;/a&gt;2. hdfs-site.xml
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dfs.replication
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dfs.namenode.name.dir
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; file:/opt/hadoop/tmp/dfs/name
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dfs.datanode.data.dir
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; file:/opt/hadoop/tmp/dfs/data
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="3-mapred-sitexml"&gt;&lt;a href="#3-mapred-sitexml" class="header-anchor"&gt;&lt;/a&gt;3. mapred-site.xml
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mapreduce.framework.name
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; yarn
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; yarn.app.mapreduce.am.env
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HADOOP_MAPRED_HOME&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/opt/hadoop
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mapreduce.map.env
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HADOOP_MAPRED_HOME&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/opt/hadoop
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mapreduce.reduce.env
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HADOOP_MAPRED_HOME&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/opt/hadoop
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="4-yarn-sitexml"&gt;&lt;a href="#4-yarn-sitexml" class="header-anchor"&gt;&lt;/a&gt;4. yarn-site.xml
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; yarn.resourcemanager.hostname
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; master
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; yarn.nodemanager.aux-services
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mapreduce_shuffle
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="5-workers以前叫-slaves"&gt;&lt;a href="#5-workers%e4%bb%a5%e5%89%8d%e5%8f%ab-slaves" class="header-anchor"&gt;&lt;/a&gt;5. workers（以前叫 slaves）
&lt;/h3&gt;&lt;p&gt;列出所有的从节点（一个 hostname 一行）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;slave1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="复制配置文件"&gt;&lt;a href="#%e5%a4%8d%e5%88%b6%e9%85%8d%e7%bd%ae%e6%96%87%e4%bb%b6" class="header-anchor"&gt;&lt;/a&gt;复制配置文件
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scp -r /opt/hadoop/etc/hadoop/ root@slave1:/opt/hadoop/etc/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="启动-hadoop"&gt;&lt;a href="#%e5%90%af%e5%8a%a8-hadoop" class="header-anchor"&gt;&lt;/a&gt;启动 Hadoop
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hdfs namenode -format
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;start-dfs.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;start-yarn.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="验证是否成功"&gt;&lt;a href="#%e9%aa%8c%e8%af%81%e6%98%af%e5%90%a6%e6%88%90%e5%8a%9f" class="header-anchor"&gt;&lt;/a&gt;验证是否成功
&lt;/h2&gt;&lt;p&gt;在 master 和 slave1 分别运行：&lt;code&gt;jps &lt;/code&gt;你应该看到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;master&lt;/strong&gt; 节点有：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;NameNode&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;SecondaryNameNode&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ResourceManager&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;slave1&lt;/strong&gt; 节点有：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;DataNode&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;NodeManager&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/05/image-5.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/05/image-6.png"&gt;&lt;/p&gt;
&lt;p&gt;然后运行以下命令进行测试，检查是否有问题：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hdfs dfs -ls /
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hdfs dfs -mkdir /testdir
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hdfs dfs -ls /
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#34;Hello Hadoop&amp;#34;&lt;/span&gt; &amp;gt; hello.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hdfs dfs -put hello.txt /testdir/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hdfs dfs -ls /testdir/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hdfs dfs -cat /testdir/hello.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hdfs dfs -get /testdir/hello.txt ./hello_from_hdfs.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hdfs dfs -rm /testdir/hello.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hdfs dfs -rmdir /testdir
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hdfs dfsadmin -report
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;如果出现问题请先检查防火墙是否开放相应端口。&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 开放端口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; p in &lt;span style="color:#ae81ff"&gt;9000&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;9870&lt;/span&gt; &lt;span style="color:#f92672"&gt;{&lt;/span&gt;50010..50020&lt;span style="color:#f92672"&gt;}&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;50075&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;8088&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;8042&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;9864&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;9866&lt;/span&gt; 9867; &lt;span style="color:#66d9ef"&gt;do&lt;/span&gt; firewall-cmd --permanent --add-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;p&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;/tcp; &lt;span style="color:#66d9ef"&gt;done&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; firewall-cmd --reload
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 关闭端口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; p in &lt;span style="color:#ae81ff"&gt;9000&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;9870&lt;/span&gt; &lt;span style="color:#f92672"&gt;{&lt;/span&gt;50010..50020&lt;span style="color:#f92672"&gt;}&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;50075&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;8088&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;8042&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;9864&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;9866&lt;/span&gt; 9867; &lt;span style="color:#66d9ef"&gt;do&lt;/span&gt; firewall-cmd --permanent --remove-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;p&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;/tcp; &lt;span style="color:#66d9ef"&gt;done&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; firewall-cmd --reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;注意：经过后期实践，发现以上端口没有涵盖Hadoop的所有所需开放端口，最方便的解决方法是暂时关闭防火墙。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="前置参考资料"&gt;&lt;a href="#%e5%89%8d%e7%bd%ae%e5%8f%82%e8%80%83%e8%b5%84%e6%96%99" class="header-anchor"&gt;&lt;/a&gt;前置参考资料
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://dandansad.com/2025/05/22/%e5%ae%89%e8%a3%85hadoop/" target="_blank" rel="noopener"
 &gt;https://dandansad.com/2025/05/22/%e5%ae%89%e8%a3%85hadoop/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>安装Hadoop</title><link>https://dandansad.com/2025/05/22/%E5%AE%89%E8%A3%85hadoop/</link><pubDate>Thu, 22 May 2025 14:40:19 +0800</pubDate><guid>https://dandansad.com/2025/05/22/%E5%AE%89%E8%A3%85hadoop/</guid><description>&lt;p&gt;&lt;strong&gt;注意：Hadoop（尤其是 3.x 及以下版本）不兼容 Java 9+ 的模块系统，如果之前安装了 Java 的更高版本，则需要重新安装更低版本进行配置。&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id="安装jdk"&gt;&lt;a href="#%e5%ae%89%e8%a3%85jdk" class="header-anchor"&gt;&lt;/a&gt;安装JDK
&lt;/h1&gt;&lt;h2 id="1下载jdk18安装包"&gt;&lt;a href="#1%e4%b8%8b%e8%bd%bdjdk18%e5%ae%89%e8%a3%85%e5%8c%85" class="header-anchor"&gt;&lt;/a&gt;1.下载JDK1.8安装包
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wget --no-check-certificate https://repo.huaweicloud.com/java/jdk/8u151-b12/jdk-8u151-linux-x64.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="2解压下载的jdk18安装包"&gt;&lt;a href="#2%e8%a7%a3%e5%8e%8b%e4%b8%8b%e8%bd%bd%e7%9a%84jdk18%e5%ae%89%e8%a3%85%e5%8c%85" class="header-anchor"&gt;&lt;/a&gt;2.解压下载的JDK1.8安装包
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tar -zxvf jdk-8u151-linux-x64.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="3移动并重命名jdk包"&gt;&lt;a href="#3%e7%a7%bb%e5%8a%a8%e5%b9%b6%e9%87%8d%e5%91%bd%e5%90%8djdk%e5%8c%85" class="header-anchor"&gt;&lt;/a&gt;3.移动并重命名JDK包
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mv jdk1.8.0_151/ /usr/java8
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="4配置java环境变量如果说不想修改原有使用的java版本可以跳过"&gt;&lt;a href="#4%e9%85%8d%e7%bd%aejava%e7%8e%af%e5%a2%83%e5%8f%98%e9%87%8f%e5%a6%82%e6%9e%9c%e8%af%b4%e4%b8%8d%e6%83%b3%e4%bf%ae%e6%94%b9%e5%8e%9f%e6%9c%89%e4%bd%bf%e7%94%a8%e7%9a%84java%e7%89%88%e6%9c%ac%e5%8f%af%e4%bb%a5%e8%b7%b3%e8%bf%87" class="header-anchor"&gt;&lt;/a&gt;4.配置Java环境变量（如果说不想修改原有使用的Java版本，可以跳过）
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#39;export JAVA_HOME=/usr/java8&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#39;export PATH=$PATH:$JAVA_HOME/bin&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;source /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="5查看java是否成功安装"&gt;&lt;a href="#5%e6%9f%a5%e7%9c%8bjava%e6%98%af%e5%90%a6%e6%88%90%e5%8a%9f%e5%ae%89%e8%a3%85" class="header-anchor"&gt;&lt;/a&gt;5.查看Java是否成功安装
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;java -version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="安装hadoop"&gt;&lt;a href="#%e5%ae%89%e8%a3%85hadoop" class="header-anchor"&gt;&lt;/a&gt;安装Hadoop
&lt;/h1&gt;&lt;h2 id="1下载hadoop安装包"&gt;&lt;a href="#1%e4%b8%8b%e8%bd%bdhadoop%e5%ae%89%e8%a3%85%e5%8c%85" class="header-anchor"&gt;&lt;/a&gt;1.下载Hadoop安装包
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wget --no-check-certificate https://repo.huaweicloud.com/apache/hadoop/common/hadoop-3.1.3/hadoop-3.1.3.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="2解压hadoop安装包至opthadoop"&gt;&lt;a href="#2%e8%a7%a3%e5%8e%8bhadoop%e5%ae%89%e8%a3%85%e5%8c%85%e8%87%b3opthadoop" class="header-anchor"&gt;&lt;/a&gt;2.解压Hadoop安装包至/opt/hadoop
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tar -zxvf hadoop-3.1.3.tar.gz -C /opt/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mv /opt/hadoop-3.1.3 /opt/hadoop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="3配置hadoop环境变量"&gt;&lt;a href="#3%e9%85%8d%e7%bd%aehadoop%e7%8e%af%e5%a2%83%e5%8f%98%e9%87%8f" class="header-anchor"&gt;&lt;/a&gt;3.配置Hadoop环境变量
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#39;export HADOOP_HOME=/opt/hadoop/&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#39;export PATH=$PATH:$HADOOP_HOME/bin&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#39;export PATH=$PATH:$HADOOP_HOME/sbin&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;source /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="4修改配置文件yarn-envsh和hadoop-envsh"&gt;&lt;a href="#4%e4%bf%ae%e6%94%b9%e9%85%8d%e7%bd%ae%e6%96%87%e4%bb%b6yarn-envsh%e5%92%8chadoop-envsh" class="header-anchor"&gt;&lt;/a&gt;4.修改配置文件yarn-env.sh和hadoop-env.sh
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#34;export JAVA_HOME=/usr/java8&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /opt/hadoop/etc/hadoop/yarn-env.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#34;export JAVA_HOME=/usr/java8&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /opt/hadoop/etc/hadoop/hadoop-env.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="5测试hadoop是否安装成功"&gt;&lt;a href="#5%e6%b5%8b%e8%af%95hadoop%e6%98%af%e5%90%a6%e5%ae%89%e8%a3%85%e6%88%90%e5%8a%9f" class="header-anchor"&gt;&lt;/a&gt;5.测试Hadoop是否安装成功
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hadoop version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="配置hadoop"&gt;&lt;a href="#%e9%85%8d%e7%bd%aehadoop" class="header-anchor"&gt;&lt;/a&gt;配置Hadoop
&lt;/h1&gt;&lt;h2 id="1修改hadoop配置文件-core-sitexml"&gt;&lt;a href="#1%e4%bf%ae%e6%94%b9hadoop%e9%85%8d%e7%bd%ae%e6%96%87%e4%bb%b6-core-sitexml" class="header-anchor"&gt;&lt;/a&gt;1.修改Hadoop配置文件 core-site.xml
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;a. 执行以下命令开始进入编辑页面。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vi /opt/hadoop/etc/hadoop/core-site.xml
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;b. 输入i进入编辑模式。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;c. 在节点内插入如下内容。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; hadoop.tmp.dir
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; file:/opt/hadoop/tmp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; location to store temporary files
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fs.defaultFS
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; hdfs://localhost:9000
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;d. 按Esc键退出编辑模式，输入:wq保存退出。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="2修改hadoop配置文件-hdfs-sitexml"&gt;&lt;a href="#2%e4%bf%ae%e6%94%b9hadoop%e9%85%8d%e7%bd%ae%e6%96%87%e4%bb%b6-hdfs-sitexml" class="header-anchor"&gt;&lt;/a&gt;2.修改Hadoop配置文件 hdfs-site.xml
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;a. 执行以下命令开始进入编辑页面。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vi /opt/hadoop/etc/hadoop/hdfs-site.xml
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;b. 输入i进入编辑模式。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;c. 在节点内插入如下内容。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dfs.replication
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dfs.namenode.name.dir
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; file:/opt/hadoop/tmp/dfs/name
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dfs.datanode.data.dir
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; file:/opt/hadoop/tmp/dfs/data
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;d. 按Esc键退出编辑模式，输入:wq保存退出。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="配置ssh免密登录"&gt;&lt;a href="#%e9%85%8d%e7%bd%aessh%e5%85%8d%e5%af%86%e7%99%bb%e5%bd%95" class="header-anchor"&gt;&lt;/a&gt;配置SSH免密登录
&lt;/h1&gt;&lt;h2 id="1执行以下命令创建公钥和私钥"&gt;&lt;a href="#1%e6%89%a7%e8%a1%8c%e4%bb%a5%e4%b8%8b%e5%91%bd%e4%bb%a4%e5%88%9b%e5%bb%ba%e5%85%ac%e9%92%a5%e5%92%8c%e7%a7%81%e9%92%a5" class="header-anchor"&gt;&lt;/a&gt;1.执行以下命令，创建公钥和私钥
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh-keygen -t rsa
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="2执行以下命令将公钥添加到authorized_keys文件中"&gt;&lt;a href="#2%e6%89%a7%e8%a1%8c%e4%bb%a5%e4%b8%8b%e5%91%bd%e4%bb%a4%e5%b0%86%e5%85%ac%e9%92%a5%e6%b7%bb%e5%8a%a0%e5%88%b0authorized_keys%e6%96%87%e4%bb%b6%e4%b8%ad" class="header-anchor"&gt;&lt;/a&gt;2.执行以下命令，将公钥添加到authorized_keys文件中
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd ~
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd .ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cat id_rsa.pub &amp;gt;&amp;gt; authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;输入如下命令，在环境变量中添加下面的配置
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vi /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;然后向里面加入如下的内容
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export HDFS_NAMENODE_USER&lt;span style="color:#f92672"&gt;=&lt;/span&gt;root
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export HDFS_DATANODE_USER&lt;span style="color:#f92672"&gt;=&lt;/span&gt;root
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export HDFS_SECONDARYNAMENODE_USER&lt;span style="color:#f92672"&gt;=&lt;/span&gt;root
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export YARN_RESOURCEMANAGER_USER&lt;span style="color:#f92672"&gt;=&lt;/span&gt;root
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export YARN_NODEMANAGER_USER&lt;span style="color:#f92672"&gt;=&lt;/span&gt;root
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;输入如下命令使改动生效
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;source /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="启动hadoop"&gt;&lt;a href="#%e5%90%af%e5%8a%a8hadoop" class="header-anchor"&gt;&lt;/a&gt;启动Hadoop
&lt;/h1&gt;&lt;h2 id="1执行以下命令初始化namenode"&gt;&lt;a href="#1%e6%89%a7%e8%a1%8c%e4%bb%a5%e4%b8%8b%e5%91%bd%e4%bb%a4%e5%88%9d%e5%a7%8b%e5%8c%96namenode" class="header-anchor"&gt;&lt;/a&gt;1.执行以下命令，初始化namenode
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hadoop namenode -format
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="2依次执行以下命令启动hadoop"&gt;&lt;a href="#2%e4%be%9d%e6%ac%a1%e6%89%a7%e8%a1%8c%e4%bb%a5%e4%b8%8b%e5%91%bd%e4%bb%a4%e5%90%af%e5%8a%a8hadoop" class="header-anchor"&gt;&lt;/a&gt;2.依次执行以下命令，启动Hadoop
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;start-dfs.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;start-yarn.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="3启动成功后执行以下命令查看已成功启动的进程"&gt;&lt;a href="#3%e5%90%af%e5%8a%a8%e6%88%90%e5%8a%9f%e5%90%8e%e6%89%a7%e8%a1%8c%e4%bb%a5%e4%b8%8b%e5%91%bd%e4%bb%a4%e6%9f%a5%e7%9c%8b%e5%b7%b2%e6%88%90%e5%8a%9f%e5%90%af%e5%8a%a8%e7%9a%84%e8%bf%9b%e7%a8%8b" class="header-anchor"&gt;&lt;/a&gt;3.启动成功后，执行以下命令，查看已成功启动的进程
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;jps
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/05/image-2.png"&gt;&lt;/p&gt;
&lt;h2 id="4打开浏览器访问如下地址显示如下界面则表示hadoop伪分布式环境搭建完成"&gt;&lt;a href="#4%e6%89%93%e5%bc%80%e6%b5%8f%e8%a7%88%e5%99%a8%e8%ae%bf%e9%97%ae%e5%a6%82%e4%b8%8b%e5%9c%b0%e5%9d%80%e6%98%be%e7%a4%ba%e5%a6%82%e4%b8%8b%e7%95%8c%e9%9d%a2%e5%88%99%e8%a1%a8%e7%a4%bahadoop%e4%bc%aa%e5%88%86%e5%b8%83%e5%bc%8f%e7%8e%af%e5%a2%83%e6%90%ad%e5%bb%ba%e5%ae%8c%e6%88%90" class="header-anchor"&gt;&lt;/a&gt;4.打开浏览器访问如下地址，显示如下界面则表示Hadoop伪分布式环境搭建完成
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Hadoop 版本&lt;/th&gt;
					&lt;th&gt;NameNode Web UI 默认端口&lt;/th&gt;
					&lt;th&gt;ResourceManager Web UI 默认端口&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Hadoop 2.x&lt;/td&gt;
					&lt;td&gt;50070&lt;/td&gt;
					&lt;td&gt;8088&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Hadoop 3.x 及以上&lt;/td&gt;
					&lt;td&gt;9870&lt;/td&gt;
					&lt;td&gt;8088&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/05/image-3-1024x496.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/05/image-4-1024x496.png"&gt;&lt;/p&gt;
&lt;h1 id="参考资料"&gt;&lt;a href="#%e5%8f%82%e8%80%83%e8%b5%84%e6%96%99" class="header-anchor"&gt;&lt;/a&gt;参考资料
&lt;/h1&gt;&lt;p&gt;&lt;a class="link" href="https://developer.aliyun.com/article/1509751" target="_blank" rel="noopener"
 &gt;Linux（阿里云）安装Hadoop(详细教程+避坑)-阿里云开发者社区&lt;/a&gt;&lt;/p&gt;</description></item><item><title>CentOS 安装 Redis</title><link>https://dandansad.com/2025/05/08/centos-%E5%AE%89%E8%A3%85-redis/</link><pubDate>Thu, 08 May 2025 13:35:50 +0800</pubDate><guid>https://dandansad.com/2025/05/08/centos-%E5%AE%89%E8%A3%85-redis/</guid><description>&lt;p&gt;对于 &lt;strong&gt;CentOS&lt;/strong&gt; 系统，如果你希望直接使用带有服务的 Redis 版本，可以选择使用 &lt;strong&gt;Redis 官方的源代码安装&lt;/strong&gt; 或者 &lt;strong&gt;从 EPEL 仓库安装 Redis&lt;/strong&gt;。通常在 CentOS 上，安装后会自动配置 Redis 作为一个 &lt;strong&gt;systemd 服务&lt;/strong&gt;，你可以通过 &lt;code&gt;systemctl&lt;/code&gt; 命令来管理它。&lt;/p&gt;
&lt;p&gt;经过实践，我推荐使用&lt;strong&gt;使用 EPEL 仓库安装 Redis&lt;/strong&gt; ，这样更为方便简单，不会有多余的麻烦。&lt;/p&gt;
&lt;h3 id="使用-epel-仓库安装-redis"&gt;&lt;a href="#%e4%bd%bf%e7%94%a8-epel-%e4%bb%93%e5%ba%93%e5%ae%89%e8%a3%85-redis" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;使用 EPEL 仓库安装 Redis&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;在 CentOS 上，Redis 提供了预编译的 RPM 包，你可以通过 &lt;code&gt;yum&lt;/code&gt; 安装它，并且安装后会自动创建一个 Redis 服务。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;步骤：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;启用 EPEL 仓库&lt;/strong&gt;：
CentOS 默认不包含 Redis 所需的 EPEL (Extra Packages for Enterprise Linux) 仓库。首先启用 EPEL 仓库： &lt;code&gt;sudo yum install epel-release&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;安装 Redis&lt;/strong&gt;：
安装 Redis 包： &lt;code&gt;sudo yum install redis&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;启动 Redis 服务&lt;/strong&gt;：
安装完成后，可以使用 &lt;code&gt;systemctl&lt;/code&gt; 启动 Redis 服务： &lt;code&gt;sudo systemctl start redis&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;设置 Redis 开机自启&lt;/strong&gt;：
如果希望 Redis 在开机时自动启动，可以使用以下命令： &lt;code&gt;sudo systemctl enable redis&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查 Redis 服务状态&lt;/strong&gt;：
使用以下命令检查 Redis 服务是否正常运行： &lt;code&gt;sudo systemctl status redis&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如上步骤，安装过程十分简单。所以说，强烈建议直接&lt;strong&gt;使用 EPEL 仓库安装 Redis&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;如果使用源码安装请注意源码编译安装的 Redis 版本，有些&lt;strong&gt;源码编译安装的 Redis 并没有包含 systemd 支持（libsystemd）&lt;/strong&gt;。当你在 &lt;code&gt;redis.service&lt;/code&gt; 中使用 &lt;code&gt;--supervised systemd&lt;/code&gt;时会出现错误，导致服务无法启动。而且源码安装如果想要启动服务，要创建 systemd 服务文件等等操作，比较繁琐。&lt;/p&gt;</description></item><item><title>DNS与CDN的区别?</title><link>https://dandansad.com/2025/05/04/dns%E4%B8%8Ecdn%E7%9A%84%E5%8C%BA%E5%88%AB/</link><pubDate>Sun, 04 May 2025 00:21:28 +0800</pubDate><guid>https://dandansad.com/2025/05/04/dns%E4%B8%8Ecdn%E7%9A%84%E5%8C%BA%E5%88%AB/</guid><description>&lt;h2 id="问题起因"&gt;&lt;a href="#%e9%97%ae%e9%a2%98%e8%b5%b7%e5%9b%a0" class="header-anchor"&gt;&lt;/a&gt;问题起因
&lt;/h2&gt;&lt;p&gt;在使用Cloudflare的过程中，接触到了DNS的相关内容，于是查找资料。然后在自己的个人网站上因为有使用jsDelivr的CDN服务，于是便有了疑惑——用户在访问网站时，DNS与CDN是怎样的一个解析过程，他们之间有什么区别？&lt;/p&gt;
&lt;h2 id="dns解析"&gt;&lt;a href="#dns%e8%a7%a3%e6%9e%90" class="header-anchor"&gt;&lt;/a&gt;DNS解析
&lt;/h2&gt;&lt;h3 id="什么是dns"&gt;&lt;a href="#%e4%bb%80%e4%b9%88%e6%98%afdns" class="header-anchor"&gt;&lt;/a&gt;什么是DNS？
&lt;/h3&gt;&lt;p&gt;DNS（Domain Name System）是互联网的域名解析系统，它的作用是将人们易记的域名（如 &lt;a class="link" href="https://www.example.com" target="_blank" rel="noopener"
 &gt;www.example.com&lt;/a&gt;）转换为计算机可识别的 IP 地址，从而让用户通过域名访问网站。DNS 由多个分层服务器组成，包括根服务器、顶级域服务器和权威服务器，整个解析过程类似查电话号码的过程，是互联网通信的基础服务之一。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/05/image-1024x740.png"&gt;&lt;/p&gt;
&lt;h3 id="为什么需要-dns"&gt;&lt;a href="#%e4%b8%ba%e4%bb%80%e4%b9%88%e9%9c%80%e8%a6%81-dns" class="header-anchor"&gt;&lt;/a&gt;为什么需要 DNS？
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;你可以记住 &lt;code&gt;www.baidu.com&lt;/code&gt;，但很难记住 &lt;code&gt;220.181.38.148&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;网站的 IP 地址可能会变，但域名不会变&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DNS 让用户用域名访问网站，而不是记 IP 地址&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dns-的核心工作机制"&gt;&lt;a href="#dns-%e7%9a%84%e6%a0%b8%e5%bf%83%e5%b7%a5%e4%bd%9c%e6%9c%ba%e5%88%b6" class="header-anchor"&gt;&lt;/a&gt;DNS 的核心工作机制
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;用户输入域名（如 &lt;code&gt;www.example.com&lt;/code&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;浏览器向本地 DNS 服务器请求 IP 地址&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果本地没有缓存，就逐级向上查询：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;根 DNS 服务器&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;顶级域（.com）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;权威 DNS 服务器（负责 example.com）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;找到 IP 后，返回给浏览器&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;浏览器用这个 IP 去访问目标服务器&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="常见-dns-类型"&gt;&lt;a href="#%e5%b8%b8%e8%a7%81-dns-%e7%b1%bb%e5%9e%8b" class="header-anchor"&gt;&lt;/a&gt;常见 DNS 类型
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;记录类型&lt;/th&gt;
					&lt;th&gt;作用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;A&lt;/td&gt;
					&lt;td&gt;将域名解析为 IPv4 地址&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;AAAA&lt;/td&gt;
					&lt;td&gt;将域名解析为 IPv6 地址&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CNAME&lt;/td&gt;
					&lt;td&gt;将域名指向另一个域名&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;MX&lt;/td&gt;
					&lt;td&gt;邮件服务器地址&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;TXT&lt;/td&gt;
					&lt;td&gt;文本记录（比如 SPF、验证用）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="cdn加速"&gt;&lt;a href="#cdn%e5%8a%a0%e9%80%9f" class="header-anchor"&gt;&lt;/a&gt;CDN加速
&lt;/h2&gt;&lt;h3 id="什么是cdn"&gt;&lt;a href="#%e4%bb%80%e4%b9%88%e6%98%afcdn" class="header-anchor"&gt;&lt;/a&gt;什么是CDN？
&lt;/h3&gt;&lt;p&gt;CDN（Content Delivery Network，内容分发网络）是一种通过分布在全球各地的边缘节点，将网站内容缓存并分发给用户的技术，目的是加快访问速度、降低服务器压力，并提升用户体验。当用户访问网站时，CDN 会将请求引导到距离用户最近的节点，从而实现更快、更稳定的内容加载。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/05/image-1-1024x735.png"&gt;&lt;/p&gt;
&lt;h3 id="为什么需要-cdn"&gt;&lt;a href="#%e4%b8%ba%e4%bb%80%e4%b9%88%e9%9c%80%e8%a6%81-cdn" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;为什么需要 CDN？&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;CDN 解决的是“&lt;strong&gt;距离远、访问慢、负载高&lt;/strong&gt;”的问题，主要有以下几个方面的需求：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;需求&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;⏱ 提高访问速度&lt;/td&gt;
					&lt;td&gt;缩短用户与服务器之间的物理距离，减少网络延迟&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🌎 提升全球可访问性&lt;/td&gt;
					&lt;td&gt;跨国/跨地区访问网站时更稳定&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;📉 减轻源站服务器压力&lt;/td&gt;
					&lt;td&gt;边缘节点承担大部分访问请求，避免源站过载&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🔐 增强安全性&lt;/td&gt;
					&lt;td&gt;隐藏源站 IP、防御 DDoS 攻击&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;📶 提升可用性和稳定性&lt;/td&gt;
					&lt;td&gt;某个节点故障时，可自动切换其他节点不中断服务&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="cdn-的工作机制"&gt;&lt;a href="#cdn-%e7%9a%84%e5%b7%a5%e4%bd%9c%e6%9c%ba%e5%88%b6" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;CDN 的工作机制&lt;/strong&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;内容分发&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;网站将资源（如图片、JS、CSS、视频等）通过 CDN 平台分发并缓存到全球各地的节点（边缘服务器）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DNS 解析调度&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;用户访问网站时，CDN 的 DNS 系统会将用户请求调度到&lt;strong&gt;最优的 CDN 节点&lt;/strong&gt;（基于距离、负载、网络状态等）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;内容访问&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果边缘节点已有缓存资源，直接返回&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果没有缓存，则回源站获取后缓存，并返回给用户（下次访问就命中缓存）&lt;/li&gt;
&lt;/ul&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;CDN 是通过“就近访问 + 智能调度 + 分布式缓存”来提升网站访问速度、稳定性和安全性的加速服务。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="完整流程"&gt;&lt;a href="#%e5%ae%8c%e6%95%b4%e6%b5%81%e7%a8%8b" class="header-anchor"&gt;&lt;/a&gt;完整流程
&lt;/h2&gt;&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/05/d43b3462648b12ee721226fcf3e14271.png"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;（1）用户访问域名 &lt;a class="link" href="https://www.huawei.com" target="_blank" rel="noopener"
 &gt;www.huawei.com&lt;/a&gt; 递归交给本地域名服务器去负责查询。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;（2）本地域名服务器经过迭代查询由 huawei.com 的域名服务器返回CNAME解析到的地址 &lt;a class="link" href="https://www.huawei.com.akadns.net" target="_blank" rel="noopener"
 &gt;www.huawei.com.akadns.net&lt;/a&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;（3）本地域名服务器去迭代查询 &lt;a class="link" href="https://www.huawei.com.akadns.net" target="_blank" rel="noopener"
 &gt;www.huawei.com.akadns.net&lt;/a&gt; 经过dig +trace 命令追踪发现又经过一次CNAME到 &lt;a class="link" href="https://www.huawei.com.lxdns.com" target="_blank" rel="noopener"
 &gt;www.huawei.com.lxdns.com&lt;/a&gt; ，具体原因没有深究，暂且认为此 &lt;a class="link" href="https://www.huawei.com.lxdns.com" target="_blank" rel="noopener"
 &gt;www.huawei.com.lxdns.com&lt;/a&gt; 为真正的CDN DNS域名服务器地址；本地域名服务器再次去迭代查询 &lt;a class="link" href="https://www.huawei.com.lxdns.com" target="_blank" rel="noopener"
 &gt;www.huawei.com.lxdns.com&lt;/a&gt; 的IP地址。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;（4）经过DNS全局负载均衡和区域负载均衡等一系列的智能调度，分配CDN节点，确定 &lt;a class="link" href="https://www.huawei.com.lxdns.com" target="_blank" rel="noopener"
 &gt;www.huawei.com.lxdns.com&lt;/a&gt; 的IP地址。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;全局负载均衡设备根据用户IP地址，以及用户请求的内容URL，选择一台用户所属区域的区域负载均衡设备。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;区域负载均衡设备会为用户选择一台合适的缓存服务器提供服务，选择的依据包括：根据用户IP地址，判断哪一台服务器距用户最近；根据用户所请求的URL中携带的内容名称，判断哪一台服务器上有用户所需内容；查询各个服务器当前的负载情况，判断哪一台服务器尚有服务能力。基于以上这些条件的综合分析之后，区域负载均衡设备会向全局负载均衡设备返回一台缓存服务器的IP地址。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;（5）返回CDN server（CDN节点）的IP地址。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;（6）返回CDN域名 &lt;a class="link" href="https://www.huawei.com.lxdns.com" target="_blank" rel="noopener"
 &gt;www.huawei.com.lxdns.com&lt;/a&gt; 的IP地址。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;（7）返回 &lt;a class="link" href="https://www.huawei.com" target="_blank" rel="noopener"
 &gt;www.huawei.com&lt;/a&gt; 对应 CDN域名 &lt;a class="link" href="https://www.huawei.com.lxdns.com" target="_blank" rel="noopener"
 &gt;www.huawei.com.lxdns.com&lt;/a&gt; 的IP地址&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;（8）用户访问 &lt;a class="link" href="https://www.huawei.com.lxdns.com" target="_blank" rel="noopener"
 &gt;www.huawei.com.lxdns.com&lt;/a&gt; 的IP地址对应的CDN server（CDN 节点），如果有缓存则直接到步骤11返回数据。如果没有则进行步骤9回源，再到步骤10，再到步骤11，返回数据。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="一些疑问"&gt;&lt;a href="#%e4%b8%80%e4%ba%9b%e7%96%91%e9%97%ae" class="header-anchor"&gt;&lt;/a&gt;一些疑问
&lt;/h2&gt;&lt;h3 id="如果cdn的记录是cname是不是还要再解析成ip"&gt;&lt;a href="#%e5%a6%82%e6%9e%9ccdn%e7%9a%84%e8%ae%b0%e5%bd%95%e6%98%afcname%e6%98%af%e4%b8%8d%e6%98%af%e8%bf%98%e8%a6%81%e5%86%8d%e8%a7%a3%e6%9e%90%e6%88%90ip" class="header-anchor"&gt;&lt;/a&gt;如果cdn的记录是cname，是不是还要再解析成ip
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;CNAME 记录&lt;/strong&gt;指的是把一个域名指向另一个域名。客户端（比如浏览器）在解析你的域名（如 &lt;code&gt;www.example.com&lt;/code&gt;）时，发现它是 CNAME 到另一个域名（如 &lt;code&gt;cdn.vendor.com&lt;/code&gt;）。然后，客户端会继续解析 &lt;code&gt;cdn.vendor.com&lt;/code&gt;，直到拿到最终的 &lt;strong&gt;A记录（IP 地址）&lt;/strong&gt;。&lt;strong&gt;最终访问仍然是通过 IP 地址完成的&lt;/strong&gt;，只是中间多了一个跳转。&lt;/p&gt;
&lt;p&gt;但要注意，&lt;strong&gt;解析过程中的所有域名查询（包括 CDN 的 CNAME）都是向 DNS 服务器发出的，而不是向 CDN 本身发出的&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;域名解析只与 DNS 服务器打交道，不和 CDN 本身通信。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="我没有配置相关dns解析记录为什么我的个人网站还能使用了jsdelivr的cdn服务"&gt;&lt;a href="#%e6%88%91%e6%b2%a1%e6%9c%89%e9%85%8d%e7%bd%ae%e7%9b%b8%e5%85%b3dns%e8%a7%a3%e6%9e%90%e8%ae%b0%e5%bd%95%e4%b8%ba%e4%bb%80%e4%b9%88%e6%88%91%e7%9a%84%e4%b8%aa%e4%ba%ba%e7%bd%91%e7%ab%99%e8%bf%98%e8%83%bd%e4%bd%bf%e7%94%a8%e4%ba%86jsdelivr%e7%9a%84cdn%e6%9c%8d%e5%8a%a1" class="header-anchor"&gt;&lt;/a&gt;我没有配置相关DNS解析记录，为什么我的个人网站还能使用了jsDelivr的CDN服务
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;你不是通过你的域名调用 jsDelivr，而是直接用 jsDelivr 的域名&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;举个例子，在 WordPress 的后台或插件里，引用的通常是类似这样的链接：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;https:&amp;amp;#47;&amp;amp;#47;cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这条链接的域名是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cdn.jsdelivr.net
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;也就是说：你根本没有把你自己的网站域名（如 &lt;code&gt;example.com&lt;/code&gt;）CNAME 到 jsDelivr，而是直接在代码中使用了 &lt;strong&gt;jsDelivr 的 CDN 域名&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;访问的流程如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;你的 WordPress 网站访问 cdn.jsdelivr.net&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;浏览器向 &lt;strong&gt;公共 DNS 服务器&lt;/strong&gt; 发起解析请求（比如 8.8.8.8）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DNS 服务器向 jsDelivr 的权威 DNS 查询&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;jsDelivr 返回就近 CDN 节点的 IP（通过它的 DNS 调度）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;浏览器拿到 IP → 访问 CDN 节点 → 获取资源&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你的网站并没有“配置” DNS，因为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;你只是“调用”了 jsDelivr 提供的链接&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;域名解析这件事交由浏览器和 jsDelivr 自己去处理了&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;情况&lt;/th&gt;
					&lt;th&gt;是否需要你配置 DNS&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;你用自己的域名接入 CDN（比如 &lt;a class="link" href="https://www.example.com" target="_blank" rel="noopener"
 &gt;www.example.com&lt;/a&gt; CNAME 到 yourcdn.example.net）&lt;/td&gt;
					&lt;td&gt;✅ 需要配置 DNS&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;你直接引用 CDN 提供的公共链接（如 cdn.jsdelivr.net）&lt;/td&gt;
					&lt;td&gt;❌ 不需要配置 DNS&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;你如果以后想让你自己的网站资源也通过 CDN 加速（比如图片、CSS、JS），那就要配置你自己域名的 CNAME 指向 CDN 节点了。&lt;/p&gt;
&lt;h3 id="配置cdn一般都是通过dns吗还有什么其他方法吗"&gt;&lt;a href="#%e9%85%8d%e7%bd%aecdn%e4%b8%80%e8%88%ac%e9%83%bd%e6%98%af%e9%80%9a%e8%bf%87dns%e5%90%97%e8%bf%98%e6%9c%89%e4%bb%80%e4%b9%88%e5%85%b6%e4%bb%96%e6%96%b9%e6%b3%95%e5%90%97" class="header-anchor"&gt;&lt;/a&gt;配置cdn一般都是通过dns吗，还有什么其他方法吗
&lt;/h3&gt;&lt;p&gt;是的，&lt;strong&gt;绝大多数情况下，配置 CDN 是通过 DNS 来实现的&lt;/strong&gt;，但它并不是唯一的方式。下面是完整的解释和对比：&lt;/p&gt;
&lt;h4 id="一主流方式通过-dns-配置-cdn最常见"&gt;&lt;a href="#%e4%b8%80%e4%b8%bb%e6%b5%81%e6%96%b9%e5%bc%8f%e9%80%9a%e8%bf%87-dns-%e9%85%8d%e7%bd%ae-cdn%e6%9c%80%e5%b8%b8%e8%a7%81" class="header-anchor"&gt;&lt;/a&gt;一、主流方式：通过 DNS 配置 CDN（最常见）
&lt;/h4&gt;&lt;p&gt;这是目前绝大多数网站接入 CDN 的标准做法。&lt;/p&gt;
&lt;h5 id="原理"&gt;&lt;a href="#%e5%8e%9f%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;原理：
&lt;/h5&gt;&lt;p&gt;你把你自己的网站域名（比如 &lt;code&gt;www.example.com&lt;/code&gt;）的 DNS 记录改为：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CNAME → cdn.example.cdnprovider.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;或者如果是根域名（不支持 CNAME）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;A 记录 → CDN 厂商提供的负载均衡 IP（如 Cloudflare 的 Anycast IP）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h5 id="特点"&gt;&lt;a href="#%e7%89%b9%e7%82%b9" class="header-anchor"&gt;&lt;/a&gt;特点：
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;适用于大部分 CDN 提供商（如 Cloudflare、阿里云 CDN、腾讯云 CDN、Akamai、jsDelivr 等）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;支持智能调度&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一般用户看不到 CDN 的存在&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="二其他方式不通过-dns也有但相对少见"&gt;&lt;a href="#%e4%ba%8c%e5%85%b6%e4%bb%96%e6%96%b9%e5%bc%8f%e4%b8%8d%e9%80%9a%e8%bf%87-dns%e4%b9%9f%e6%9c%89%e4%bd%86%e7%9b%b8%e5%af%b9%e5%b0%91%e8%a7%81" class="header-anchor"&gt;&lt;/a&gt;二、其他方式（不通过 DNS）也有，但相对少见：
&lt;/h4&gt;&lt;h5 id="1-直接使用-cdn-提供的-url"&gt;&lt;a href="#1-%e7%9b%b4%e6%8e%a5%e4%bd%bf%e7%94%a8-cdn-%e6%8f%90%e4%be%9b%e7%9a%84-url" class="header-anchor"&gt;&lt;/a&gt;1. &lt;strong&gt;直接使用 CDN 提供的 URL&lt;/strong&gt;
&lt;/h5&gt;&lt;h6 id="举例"&gt;&lt;a href="#%e4%b8%be%e4%be%8b" class="header-anchor"&gt;&lt;/a&gt;举例：
&lt;/h6&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h6 id="适用"&gt;&lt;a href="#%e9%80%82%e7%94%a8" class="header-anchor"&gt;&lt;/a&gt;适用：
&lt;/h6&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;公共库/资源&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不想改自己域名的 DNS&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h6 id="缺点"&gt;&lt;a href="#%e7%bc%ba%e7%82%b9" class="header-anchor"&gt;&lt;/a&gt;缺点：
&lt;/h6&gt;&lt;ul&gt;
&lt;li&gt;域名不是你自己的，缓存行为和品牌一致性无法控制&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="2-反向代理方式接入-cdn"&gt;&lt;a href="#2-%e5%8f%8d%e5%90%91%e4%bb%a3%e7%90%86%e6%96%b9%e5%bc%8f%e6%8e%a5%e5%85%a5-cdn" class="header-anchor"&gt;&lt;/a&gt;2. &lt;strong&gt;反向代理方式接入 CDN&lt;/strong&gt;
&lt;/h5&gt;&lt;p&gt;一些特殊情况，可以让 CDN 厂商作为反向代理直接部署在源站前，但这通常是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;企业内网、私有部署&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;定制的 CDN 网络&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安全/合规特殊场景&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这通常不通过 DNS，而是由 CDN 提供的边界设备（比如云防护墙）或专线统一接入。&lt;/p&gt;
&lt;h5 id="3-通过-web-应用接入插件或中间件"&gt;&lt;a href="#3-%e9%80%9a%e8%bf%87-web-%e5%ba%94%e7%94%a8%e6%8e%a5%e5%85%a5%e6%8f%92%e4%bb%b6%e6%88%96%e4%b8%ad%e9%97%b4%e4%bb%b6" class="header-anchor"&gt;&lt;/a&gt;3. &lt;strong&gt;通过 Web 应用接入（插件或中间件）&lt;/strong&gt;
&lt;/h5&gt;&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;WordPress 安装某个插件后自动为图片加上 CDN 前缀&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Web 应用自动切换资源路径，如从 &lt;code&gt;/static/&lt;/code&gt; → &lt;code&gt;https://cdn.yourdomain.com/static/&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种方式不依赖 DNS，而是代码层配置&lt;strong&gt;资源路径&lt;/strong&gt;实现 CDN 加速。&lt;/p&gt;
&lt;h4 id="总结"&gt;&lt;a href="#%e6%80%bb%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;总结：
&lt;/h4&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;接入方式&lt;/th&gt;
					&lt;th&gt;是否通过 DNS&lt;/th&gt;
					&lt;th&gt;是否常用&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;修改 CNAME/A 记录&lt;/td&gt;
					&lt;td&gt;✅ 是&lt;/td&gt;
					&lt;td&gt;⭐ 非常常用&lt;/td&gt;
					&lt;td&gt;最标准的接入方式&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;直接用 CDN 链接&lt;/td&gt;
					&lt;td&gt;❌ 否&lt;/td&gt;
					&lt;td&gt;✅ 较常用&lt;/td&gt;
					&lt;td&gt;用于公共库，不影响你自己的域名&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;反向代理模式&lt;/td&gt;
					&lt;td&gt;❌ 否&lt;/td&gt;
					&lt;td&gt;❗ 少数企业使用&lt;/td&gt;
					&lt;td&gt;高级部署方式，成本较高&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;应用层插件/CDN 前缀&lt;/td&gt;
					&lt;td&gt;❌ 否&lt;/td&gt;
					&lt;td&gt;✅ 在某些框架中常用&lt;/td&gt;
					&lt;td&gt;控制静态资源路径即可，不依赖 DNS&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="参考资料"&gt;&lt;a href="#%e5%8f%82%e8%80%83%e8%b5%84%e6%96%99" class="header-anchor"&gt;&lt;/a&gt;参考资料
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://zhuanlan.zhihu.com/p/26879931" target="_blank" rel="noopener"
 &gt;20分钟理解什么是网络、DNS与CDN - 知乎&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://blog.csdn.net/am45337908/article/details/87891995" target="_blank" rel="noopener"
 &gt;DNS解析与CDN加速-CSDN博客&lt;/a&gt;&lt;/p&gt;</description></item><item><title>正向代理和反向代理</title><link>https://dandansad.com/2025/05/03/%E6%AD%A3%E5%90%91%E4%BB%A3%E7%90%86%E5%92%8C%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/</link><pubDate>Sat, 03 May 2025 23:57:34 +0800</pubDate><guid>https://dandansad.com/2025/05/03/%E6%AD%A3%E5%90%91%E4%BB%A3%E7%90%86%E5%92%8C%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/</guid><description>&lt;h2 id="正向代理-vs-反向代理核心区别"&gt;&lt;a href="#%e6%ad%a3%e5%90%91%e4%bb%a3%e7%90%86-vs-%e5%8f%8d%e5%90%91%e4%bb%a3%e7%90%86%e6%a0%b8%e5%bf%83%e5%8c%ba%e5%88%ab" class="header-anchor"&gt;&lt;/a&gt;正向代理 vs 反向代理：核心区别
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;特性&lt;/th&gt;
					&lt;th&gt;正向代理（Forward Proxy）&lt;/th&gt;
					&lt;th&gt;反向代理（Reverse Proxy）&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;📌 代理的对象&lt;/td&gt;
					&lt;td&gt;代理客户端（用户）访问目标服务器&lt;/td&gt;
					&lt;td&gt;代理服务端（源站）响应外部请求&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🎯 主要用途&lt;/td&gt;
					&lt;td&gt;客户端访问内部或受控网络资源，缓存优化&lt;/td&gt;
					&lt;td&gt;实现负载均衡、隐藏后端、统一入口、安全防护&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🛠 配置位置&lt;/td&gt;
					&lt;td&gt;客户端或客户端网关&lt;/td&gt;
					&lt;td&gt;服务器端或网络边缘设备&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🌍 真实服务器&lt;/td&gt;
					&lt;td&gt;用户试图访问的目标服务器（如内部业务接口）&lt;/td&gt;
					&lt;td&gt;后端应用服务器（如 Web 服务、API 服务等）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🔒 隐藏谁的身份&lt;/td&gt;
					&lt;td&gt;隐藏客户端身份&lt;/td&gt;
					&lt;td&gt;隐藏服务端身份&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🗺 常见用途&lt;/td&gt;
					&lt;td&gt;内网访问控制、缓存加速、日志审计、流量统一出口&lt;/td&gt;
					&lt;td&gt;负载均衡、CDN、服务网关、应用防火墙（WAF）等&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;🌐 举例&lt;/td&gt;
					&lt;td&gt;企业出网网关代理、Squid、局域网 Web 缓存服务器&lt;/td&gt;
					&lt;td&gt;Nginx 反向代理、CDN 边缘节点、WAF 安全设备等&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;一句话区别：&lt;strong&gt;正向代理服务于客户端，反向代理服务于服务端。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="正向代理帮用户访问外部内容"&gt;&lt;a href="#%e6%ad%a3%e5%90%91%e4%bb%a3%e7%90%86%e5%b8%ae%e7%94%a8%e6%88%b7%e8%ae%bf%e9%97%ae%e5%a4%96%e9%83%a8%e5%86%85%e5%ae%b9" class="header-anchor"&gt;&lt;/a&gt;正向代理：帮&lt;strong&gt;用户&lt;/strong&gt;访问外部内容
&lt;/h2&gt;&lt;h3 id="-举例场景"&gt;&lt;a href="#-%e4%b8%be%e4%be%8b%e5%9c%ba%e6%99%af" class="header-anchor"&gt;&lt;/a&gt;🎯 举例场景：
&lt;/h3&gt;&lt;p&gt;员工（在公司内网）→ 配置正向代理服务器（如 Squid）→ 访问公司外部业务系统或 API（如 Salesforce）→ 响应数据返回 → 代理服务器转发给员工电脑
✅ &lt;strong&gt;你是主动用代理“出门”访问别人&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="-常见用途"&gt;&lt;a href="#-%e5%b8%b8%e8%a7%81%e7%94%a8%e9%80%94" class="header-anchor"&gt;&lt;/a&gt;📌 常见用途：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;控制与审计出网流量&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;加速常用资源访问（通过缓存）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;实现用户访问权限限制&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="反向代理帮服务器隐藏控制外部访问"&gt;&lt;a href="#%e5%8f%8d%e5%90%91%e4%bb%a3%e7%90%86%e5%b8%ae%e6%9c%8d%e5%8a%a1%e5%99%a8%e9%9a%90%e8%97%8f%e6%8e%a7%e5%88%b6%e5%a4%96%e9%83%a8%e8%ae%bf%e9%97%ae" class="header-anchor"&gt;&lt;/a&gt;反向代理：帮&lt;strong&gt;服务器&lt;/strong&gt;隐藏/控制外部访问
&lt;/h2&gt;&lt;h3 id="-举例场景-1"&gt;&lt;a href="#-%e4%b8%be%e4%be%8b%e5%9c%ba%e6%99%af-1" class="header-anchor"&gt;&lt;/a&gt;🎯 举例场景：
&lt;/h3&gt;&lt;p&gt;用户 → 访问 &lt;code&gt;www.example.com&lt;/code&gt;（其实是访问 CDN 或 Nginx）→ 代理判断请求 → 转发到后端服务器处理 → 返回内容
✅ &lt;strong&gt;你是访问“前台”，它替你决定后面由谁来服务&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="-常见用途-1"&gt;&lt;a href="#-%e5%b8%b8%e8%a7%81%e7%94%a8%e9%80%94-1" class="header-anchor"&gt;&lt;/a&gt;📌 常见用途：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;负载均衡&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CDN（其实就是分布式反向代理）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;隐藏真实源站 IP&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安全过滤（WAF）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HTTPS 统一入口&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>端口被占用的问题——Hyper-V</title><link>https://dandansad.com/2025/04/30/%E7%AB%AF%E5%8F%A3%E8%A2%AB%E5%8D%A0%E7%94%A8%E7%9A%84%E9%97%AE%E9%A2%98-hyper-v/</link><pubDate>Wed, 30 Apr 2025 20:30:51 +0800</pubDate><guid>https://dandansad.com/2025/04/30/%E7%AB%AF%E5%8F%A3%E8%A2%AB%E5%8D%A0%E7%94%A8%E7%9A%84%E9%97%AE%E9%A2%98-hyper-v/</guid><description>&lt;h2 id="问题描述"&gt;&lt;a href="#%e9%97%ae%e9%a2%98%e6%8f%8f%e8%bf%b0" class="header-anchor"&gt;&lt;/a&gt;问题描述
&lt;/h2&gt;&lt;p&gt;在端口被占用时，用命令查看占用的程序。但是没有结果输出，代表没有程序在占用。（实际上是“没有程序在此刻占用这个端口，但不排除有程序在随机保留着这个端口”）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;netstat &lt;span style="color:#f92672"&gt;-&lt;/span&gt;ano &lt;span style="color:#f92672"&gt;|&lt;/span&gt; findstr &lt;span style="color:#e6db74"&gt;&amp;#34;:7890&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这是因为电脑开启了 Hyper-V ，它会保留一部分 TCP/IP 端口供其虚拟交换机使用，这可能导致某些应用程序无法绑定到这些端口。我们可以用以下命令查看其保留的端口。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;#&lt;/span&gt; 查看 Hyper&lt;span style="color:#f92672"&gt;-&lt;/span&gt;v 启动后的保留端口范围
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;netsh &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ipv4&lt;/span&gt; show excludedportrange protocol&lt;span style="color:#f92672"&gt;=&lt;/span&gt;tcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/04/PixPin_2025-04-30_20-16-32-1024x514.png"&gt;&lt;/p&gt;
&lt;h2 id="临时解决方案排除单个端口重启可能失效"&gt;&lt;a href="#%e4%b8%b4%e6%97%b6%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88%e6%8e%92%e9%99%a4%e5%8d%95%e4%b8%aa%e7%ab%af%e5%8f%a3%e9%87%8d%e5%90%af%e5%8f%af%e8%83%bd%e5%a4%b1%e6%95%88" class="header-anchor"&gt;&lt;/a&gt;临时解决方案——排除单个端口（重启可能失效）
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;以管理员身份运行 PowerShell 或 CMD&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;停止 Hyper-V 相关服务&lt;/strong&gt;：&lt;code&gt;net stop winnat&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;手动添加端口排除&lt;/strong&gt;（例如释放 &lt;code&gt;7890&lt;/code&gt;）：&lt;code&gt;netsh int ipv4 delete excludedportrange protocol=tcp startport=7890 numberofports=1&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;protocol=tcp&lt;/code&gt;（或 &lt;code&gt;udp&lt;/code&gt;）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;startport=7890&lt;/code&gt;（你要释放的端口）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;numberofports=1&lt;/code&gt;（只释放 1 个端口）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;重启 WinNAT 服务&lt;/strong&gt;（恢复网络）：&lt;code&gt;net start winnat&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;验证是否成功&lt;/strong&gt;：&lt;code&gt;netsh int ipv4 show excludedportrange protocol=tcp | findstr &amp;quot;7890&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果无输出，说明 &lt;code&gt;7890&lt;/code&gt; 已不再被保留，可以正常使用。&lt;/p&gt;
&lt;p&gt;⚠️ &lt;strong&gt;注意&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;重启后可能失效&lt;/strong&gt;，因为 Hyper-V 可能会重新占用该端口。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果仍然无法使用，可能是其他服务占用了该端口（用 &lt;code&gt;netstat -ano | findstr &amp;quot;50000&amp;quot;&lt;/code&gt; 检查）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>OpenCloudOS 9.2安装 Anaconda</title><link>https://dandansad.com/2025/04/15/opencloudos-9-2%E5%AE%89%E8%A3%85-anaconda/</link><pubDate>Tue, 15 Apr 2025 00:11:21 +0800</pubDate><guid>https://dandansad.com/2025/04/15/opencloudos-9-2%E5%AE%89%E8%A3%85-anaconda/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;系统版本：
NAME=”OpenCloudOS”
VERSION=”9.2″
ID=”opencloudos”
ID_LIKE=”opencloudos”
VERSION_ID=”9.2″
PLATFORM_ID=”platform:oc9″
PRETTY_NAME=”OpenCloudOS 9.2″
ANSI_COLOR=”0;31″
CPE_NAME=”cpe:/o:opencloudos:opencloudos:9″
HOME_URL=”https://www.opencloudos.org/”
BUG_REPORT_URL=”https://bugs.opencloudos.tech/”&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;chmod +x Miniconda3-latest-Linux-x86_64.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./Miniconda3-latest-Linux-x86_64.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# or&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wget https://repo.anaconda.com/archive/Anaconda3-2023.03-Linux-x86_64.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;chmod +x Anaconda3-2023.03-Linux-x86_64.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./Anaconda3-2023.03-Linux-x86_64.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;source ~/.bashrc
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;conda --version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>OpenCloudOS 9.2安装MySQL</title><link>https://dandansad.com/2025/04/14/opencloudos-9-2%E5%AE%89%E8%A3%85mysql/</link><pubDate>Mon, 14 Apr 2025 23:49:30 +0800</pubDate><guid>https://dandansad.com/2025/04/14/opencloudos-9-2%E5%AE%89%E8%A3%85mysql/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;系统版本：
NAME=&amp;ldquo;OpenCloudOS&amp;rdquo;
VERSION=&amp;ldquo;9.2&amp;rdquo;
ID=&amp;ldquo;opencloudos&amp;rdquo;
ID_LIKE=&amp;ldquo;opencloudos&amp;rdquo;
VERSION_ID=&amp;ldquo;9.2&amp;rdquo;
PLATFORM_ID=&amp;ldquo;platform:oc9&amp;rdquo;
PRETTY_NAME=&amp;ldquo;OpenCloudOS 9.2&amp;rdquo;
ANSI_COLOR=&amp;ldquo;0;31&amp;rdquo;
CPE_NAME=&amp;ldquo;cpe:/o:opencloudos:opencloudos:9&amp;rdquo;
HOME_URL=&amp;ldquo;&lt;a class="link" href="https://www.opencloudos.org/%22" target="_blank" rel="noopener"
 &gt;https://www.opencloudos.org/"&lt;/a&gt;
BUG_REPORT_URL=&amp;ldquo;&lt;a class="link" href="https://bugs.opencloudos.tech/%22" target="_blank" rel="noopener"
 &gt;https://bugs.opencloudos.tech/"&lt;/a&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wget https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo yum install -y mysql80-community-release-el9-1.noarch.rpm
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo yum install -y mysql-server
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl enable mysqld
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl start mysqld
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl status mysqld
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql -uroot
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ALTER USER &lt;span style="color:#e6db74"&gt;&amp;#39;root&amp;#39;&lt;/span&gt;@&lt;span style="color:#e6db74"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt; IDENTIFIED BY &lt;span style="color:#e6db74"&gt;&amp;#39;NewPassw0rd!&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;FLUSH PRIVILEGES;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>对危险操作进行别名配置</title><link>https://dandansad.com/2025/03/23/%E5%AF%B9%E5%8D%B1%E9%99%A9%E6%93%8D%E4%BD%9C%E8%BF%9B%E8%A1%8C%E5%88%AB%E5%90%8D%E9%85%8D%E7%BD%AE/</link><pubDate>Sun, 23 Mar 2025 03:07:51 +0800</pubDate><guid>https://dandansad.com/2025/03/23/%E5%AF%B9%E5%8D%B1%E9%99%A9%E6%93%8D%E4%BD%9C%E8%BF%9B%E8%A1%8C%E5%88%AB%E5%90%8D%E9%85%8D%E7%BD%AE/</guid><description>&lt;p&gt;修改 &lt;code&gt;~/.bashrc&lt;/code&gt; 文件，适当位置加入以下代码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Alias configuration for dangerous operations&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 危险操作的别名配置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alias rm&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rm -i&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 删除文件前确认&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alias mv&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;mv -i&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 移动或覆盖文件前确认&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alias cp&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;cp -i&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 复制文件前确认&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alias rmrf&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;echo &amp;#34;Are you sure you want to run rm -rf? (y/n)&amp;#34; &amp;amp;&amp;amp; read answer &amp;amp;&amp;amp; [ &amp;#34;$answer&amp;#34; = &amp;#34;y&amp;#34; ] &amp;amp;&amp;amp; rm -rf&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 递归删除前确认&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alias overwrite&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;echo &amp;#34;Are you sure you want to overwrite the file? (y/n)&amp;#34; &amp;amp;&amp;amp; read answer &amp;amp;&amp;amp; [ &amp;#34;$answer&amp;#34; = &amp;#34;y&amp;#34; ] &amp;amp;&amp;amp; &amp;gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 覆盖文件前确认&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alias emptyfile&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;echo &amp;#34;Are you sure you want to empty the file? (y/n)&amp;#34; &amp;amp;&amp;amp; read answer &amp;amp;&amp;amp; [ &amp;#34;$answer&amp;#34; = &amp;#34;y&amp;#34; ] &amp;amp;&amp;amp; : &amp;gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 清空文件前确认&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alias exit&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;echo &amp;#34;Are you sure you want to exit? (y/n)&amp;#34; &amp;amp;&amp;amp; read answer &amp;amp;&amp;amp; [ &amp;#34;$answer&amp;#34; = &amp;#34;y&amp;#34; ] &amp;amp;&amp;amp; exit&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 退出终端前确认&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alias reboot&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;echo &amp;#34;Are you sure you want to reboot the system? (y/n)&amp;#34; &amp;amp;&amp;amp; read answer &amp;amp;&amp;amp; [ &amp;#34;$answer&amp;#34; = &amp;#34;y&amp;#34; ] &amp;amp;&amp;amp; reboot&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 重启系统前确认&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alias shutdown&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;echo &amp;#34;Are you sure you want to shutdown the system? (y/n)&amp;#34; &amp;amp;&amp;amp; read answer &amp;amp;&amp;amp; [ &amp;#34;$answer&amp;#34; = &amp;#34;y&amp;#34; ] &amp;amp;&amp;amp; shutdown&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 关机前确认&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alias kill9&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;echo &amp;#34;Are you sure you want to kill the process? (y/n)&amp;#34; &amp;amp;&amp;amp; read answer &amp;amp;&amp;amp; [ &amp;#34;$answer&amp;#34; = &amp;#34;y&amp;#34; ] &amp;amp;&amp;amp; kill -9&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 强制终止进程前确认&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后运行：&lt;code&gt;source ~/.bashrc&lt;/code&gt;&lt;/p&gt;</description></item><item><title>WSL2 Ubuntu ： MySQL 安装记录</title><link>https://dandansad.com/2025/03/17/wsl2-ubuntu--mysql-%E5%AE%89%E8%A3%85%E8%AE%B0%E5%BD%95/</link><pubDate>Mon, 17 Mar 2025 00:58:48 +0800</pubDate><guid>https://dandansad.com/2025/03/17/wsl2-ubuntu--mysql-%E5%AE%89%E8%A3%85%E8%AE%B0%E5%BD%95/</guid><description>&lt;h2 id="版本环境"&gt;&lt;a href="#%e7%89%88%e6%9c%ac%e7%8e%af%e5%a2%83" class="header-anchor"&gt;&lt;/a&gt;版本环境
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;WSL信息：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plaintext" data-lang="plaintext"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;WSL 版本： 2.3.26.0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;内核版本： 5.15.167.4-1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;WSLg 版本： 1.0.65
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;MSRDC 版本： 1.2.5620
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Direct3D 版本： 1.611.1-81528511
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;DXCore 版本： 10.0.26100.1-240331-1435.ge-release
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Windows 版本： 10.0.22631.5039
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Ubuntu版本：&lt;/strong&gt;
Ubuntu 24.04.1 LTS (GNU/Linux 5.15.167.4-microsoft-standard-WSL2 x86_64)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MySQL版本：&lt;/strong&gt;
Server version: 8.0.41-0ubuntu0.24.04.1 (Ubuntu)&lt;/p&gt;
&lt;h2 id="安装步骤"&gt;&lt;a href="#%e5%ae%89%e8%a3%85%e6%ad%a5%e9%aa%a4" class="header-anchor"&gt;&lt;/a&gt;安装步骤
&lt;/h2&gt;&lt;h3 id="1-更新apt软件包"&gt;&lt;a href="#1-%e6%9b%b4%e6%96%b0apt%e8%bd%af%e4%bb%b6%e5%8c%85" class="header-anchor"&gt;&lt;/a&gt;1. 更新apt软件包
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="2-安装mysql"&gt;&lt;a href="#2-%e5%ae%89%e8%a3%85mysql" class="header-anchor"&gt;&lt;/a&gt;2. 安装Mysql
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt install mysql-server -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="3-启用mysql服务"&gt;&lt;a href="#3-%e5%90%af%e7%94%a8mysql%e6%9c%8d%e5%8a%a1" class="header-anchor"&gt;&lt;/a&gt;3. 启用Mysql服务
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo service mysql start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可以使用以下命令检查是否成功启用。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo service mysql status
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;成功启用的输出示例，注意看Loaded和Active信息。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;●&lt;/span&gt; mysql&lt;span style="color:#f92672"&gt;.&lt;/span&gt;service &lt;span style="color:#f92672"&gt;-&lt;/span&gt; MySQL Community Server
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Loaded: loaded (&lt;span style="color:#f92672"&gt;/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;lib&lt;span style="color:#f92672"&gt;/&lt;/span&gt;systemd&lt;span style="color:#f92672"&gt;/&lt;/span&gt;system&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;.&lt;/span&gt;service; enabled; preset: enabled)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Active: active (running) since Mon &lt;span style="color:#ae81ff"&gt;2025&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;03&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;17&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;00&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;22&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;36&lt;/span&gt; CST; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;min &lt;span style="color:#ae81ff"&gt;49&lt;/span&gt;s ago
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Process: &lt;span style="color:#ae81ff"&gt;1513&lt;/span&gt; ExecStartPre&lt;span style="color:#f92672"&gt;=/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;share&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;-&lt;/span&gt;systemd&lt;span style="color:#f92672"&gt;-&lt;/span&gt;start pre (code&lt;span style="color:#f92672"&gt;=&lt;/span&gt;exited, status&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;SUCCESS)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Main PID: &lt;span style="color:#ae81ff"&gt;1521&lt;/span&gt; (mysqld)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Status: &lt;span style="color:#e6db74"&gt;&amp;#34;Server is operational&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Tasks: &lt;span style="color:#ae81ff"&gt;38&lt;/span&gt; (limit: &lt;span style="color:#ae81ff"&gt;9361&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Memory: &lt;span style="color:#ae81ff"&gt;358.7&lt;/span&gt;M ()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; CGroup: &lt;span style="color:#f92672"&gt;/&lt;/span&gt;system&lt;span style="color:#f92672"&gt;.&lt;/span&gt;slice&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;.&lt;/span&gt;service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└─&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1521&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;sbin&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysqld
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="4-查看mysql初始密码"&gt;&lt;a href="#4-%e6%9f%a5%e7%9c%8bmysql%e5%88%9d%e5%a7%8b%e5%af%86%e7%a0%81" class="header-anchor"&gt;&lt;/a&gt;4. 查看Mysql初始密码
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo cat /etc/mysql/debian.cnf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;示例输出：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Automatically generated for Debian scripts. DO NOT TOUCH!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[client]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;host &lt;span style="color:#f92672"&gt;=&lt;/span&gt; localhost
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;user &lt;span style="color:#f92672"&gt;=&lt;/span&gt; example
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;password &lt;span style="color:#f92672"&gt;=&lt;/span&gt; example
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;socket &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;run&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysqld&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysqld&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sock
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[mysql_upgrade]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;host &lt;span style="color:#f92672"&gt;=&lt;/span&gt; localhost
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;user &lt;span style="color:#f92672"&gt;=&lt;/span&gt; example
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;password &lt;span style="color:#f92672"&gt;=&lt;/span&gt; example
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;socket &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;run&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysqld&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysqld&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sock
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;记住用户名（user）和密码（password），等下登录要用。&lt;/p&gt;
&lt;h3 id="5-修改mysql中root用户密码"&gt;&lt;a href="#5-%e4%bf%ae%e6%94%b9mysql%e4%b8%adroot%e7%94%a8%e6%88%b7%e5%af%86%e7%a0%81" class="header-anchor"&gt;&lt;/a&gt;5. 修改Mysql中root用户密码
&lt;/h3&gt;&lt;p&gt;使用你刚刚记住的用户名和密码登录MySQL，输入密码进入MySQL终端&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql -uexample -p
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;按照如下指令顺序输入：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql&amp;gt; use mysql;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Reading table information for completion of table and column names
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;You can turn off this feature to get a quicker startup with -A
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Database changed
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql&amp;gt; ALTER USER &amp;#39;root&amp;#39;@&amp;#39;localhost&amp;#39; IDENTIFIED WITH mysql_native_password BY &amp;#39;yourpassword&amp;#39;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Query OK, 0 rows affected (0.01 sec)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;到这里MySQL的基本安装步骤就完成了，后续的配置按照正常MySQL配置即可。&lt;/p&gt;</description></item><item><title>解决程序无法读取数据库插入的新数据</title><link>https://dandansad.com/2025/03/16/%E8%A7%A3%E5%86%B3%E7%A8%8B%E5%BA%8F%E6%97%A0%E6%B3%95%E8%AF%BB%E5%8F%96%E6%95%B0%E6%8D%AE%E5%BA%93%E6%8F%92%E5%85%A5%E7%9A%84%E6%96%B0%E6%95%B0%E6%8D%AE/</link><pubDate>Sun, 16 Mar 2025 01:15:01 +0800</pubDate><guid>https://dandansad.com/2025/03/16/%E8%A7%A3%E5%86%B3%E7%A8%8B%E5%BA%8F%E6%97%A0%E6%B3%95%E8%AF%BB%E5%8F%96%E6%95%B0%E6%8D%AE%E5%BA%93%E6%8F%92%E5%85%A5%E7%9A%84%E6%96%B0%E6%95%B0%E6%8D%AE/</guid><description>&lt;h2 id="问题描述"&gt;&lt;a href="#%e9%97%ae%e9%a2%98%e6%8f%8f%e8%bf%b0" class="header-anchor"&gt;&lt;/a&gt;问题描述
&lt;/h2&gt;&lt;p&gt;有两个不同的守护进程，一个守护进程接收csi数据插入到数据库中，另一个守护进程从数据库中读取csi数据进行处理。&lt;/p&gt;
&lt;p&gt;在两个守护程序运行的过程中，从数据库中读取csi数据进行处理的守护进程在数据库中有新数据的情况下无法读取到数据库的新数据。经过排查发现，新数据确实被接收csi数据的守护进程成功插入，但是读取csi数据的守护进程并没有从数据库中读取到新数据，因此排除了数据库的问题和接收csi数据的守护进程的问题，将目光放在读取csi数据的守护进程上。&lt;/p&gt;
&lt;h2 id="问题解决"&gt;&lt;a href="#%e9%97%ae%e9%a2%98%e8%a7%a3%e5%86%b3" class="header-anchor"&gt;&lt;/a&gt;问题解决
&lt;/h2&gt;&lt;p&gt;经过一段时间的排查发现，很可能是读取csi数据的守护进程涉及到了 MySQL 的事务隔离级别和查询缓存的影响。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;事务隔离导致看不到新数据（设置正确的事务隔离级别：&lt;code&gt;READ COMMITTED&lt;/code&gt;，可以看到其他事务的提交）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;查询缓存导致总是返回旧数据（禁用缓存，每次都读取最新数据）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为了保险起见，还防止有以下问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;连接断开后无法自动重连（自动重连，使连接保持有效）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;事务未正确提交导致数据更新不及时（显式提交，确保事务正确提交）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="一些疑问"&gt;&lt;a href="#%e4%b8%80%e4%ba%9b%e7%96%91%e9%97%ae" class="header-anchor"&gt;&lt;/a&gt;一些疑问
&lt;/h2&gt;&lt;p&gt;在进行web程序的编写过程中，我从来没有遇到过因为事务隔离级别引发的问题。为什么spring不需要设置正确的事务隔离级别，可以读取新的数据呢？&lt;/p&gt;
&lt;p&gt;可能有以下几个原因：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Spring 默认的事务隔离级别就是 READ_COMMITTED&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Spring 的事务管理机制会自动处理事务的开启和提交&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Spring 使用连接池（如 HikariCP）管理数据库连接&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Spring JPA/MyBatis 等 ORM 框架会自动清除查询缓存&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;实际上 Spring 在底层都处理好了这些细节。而在 Python 中，我们需要自己处理这些数据库事务和连接的细节。&lt;/p&gt;
&lt;p&gt;示例代码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_fetch_csi_data&lt;/span&gt;(self, limit&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 1. 手动设置事务隔离级别&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cursor&lt;span style="color:#f92672"&gt;.&lt;/span&gt;execute(&lt;span style="color:#e6db74"&gt;&amp;#34;SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 2. 手动管理事务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;db_connection&lt;span style="color:#f92672"&gt;.&lt;/span&gt;commit() &lt;span style="color:#75715e"&gt;# 开启新事务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 3. 手动禁用查询缓存&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; query &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; SELECT /*+ NO_CACHE */ id, timestamp, csi_data
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; FROM raw_data
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; WHERE device_id = &lt;/span&gt;&lt;span style="color:#e6db74"&gt;%s&lt;/span&gt;&lt;span style="color:#e6db74"&gt; AND processed = 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; ORDER BY timestamp DESC
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; LIMIT &lt;/span&gt;&lt;span style="color:#e6db74"&gt;%s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 4. 手动提交事务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;db_connection&lt;span style="color:#f92672"&gt;.&lt;/span&gt;commit()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;except&lt;/span&gt; Error &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; e:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 5. 手动处理异常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;logger&lt;span style="color:#f92672"&gt;.&lt;/span&gt;error(&lt;span style="color:#e6db74"&gt;f&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;获取 CSI 数据时发生错误: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;e&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;close()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>解决跨域问题</title><link>https://dandansad.com/2025/03/16/%E8%A7%A3%E5%86%B3%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98/</link><pubDate>Sun, 16 Mar 2025 00:48:52 +0800</pubDate><guid>https://dandansad.com/2025/03/16/%E8%A7%A3%E5%86%B3%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98/</guid><description>&lt;h1 id="什么是跨域问题"&gt;&lt;a href="#%e4%bb%80%e4%b9%88%e6%98%af%e8%b7%a8%e5%9f%9f%e9%97%ae%e9%a2%98" class="header-anchor"&gt;&lt;/a&gt;什么是跨域问题？
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;跨域问题&lt;/strong&gt; 是指浏览器出于安全考虑，限制了从一个源（Origin）加载的网页脚本或资源与另一个源的资源进行交互的行为。这种限制是由浏览器的 &lt;strong&gt;同源策略（Same-Origin Policy）&lt;/strong&gt; 引起的。&lt;/p&gt;
&lt;p&gt;“跨域”指的是浏览器尝试访问的资源与当前页面的 &lt;strong&gt;源（Origin）&lt;/strong&gt; 不一致。&lt;strong&gt;源&lt;/strong&gt; 由以下三部分组成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;协议（Protocol）&lt;/strong&gt;：如 &lt;code&gt;http&lt;/code&gt;、&lt;code&gt;https&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;域名（Domain）&lt;/strong&gt;：如 &lt;code&gt;example.com&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;端口（Port）&lt;/strong&gt;：如 &lt;code&gt;80&lt;/code&gt;、&lt;code&gt;443&lt;/code&gt;（默认端口可以省略）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果两个 URL 的协议、域名和端口完全相同，则它们是 &lt;strong&gt;同源&lt;/strong&gt;；否则就是 &lt;strong&gt;跨源&lt;/strong&gt;（Cross-Origin）。&lt;/p&gt;
&lt;h4 id="示例"&gt;&lt;a href="#%e7%a4%ba%e4%be%8b" class="header-anchor"&gt;&lt;/a&gt;示例：
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;https://example.com&lt;/code&gt; 和 &lt;code&gt;https://example.com/api&lt;/code&gt; 是同源。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;https://example.com&lt;/code&gt; 和 &lt;code&gt;http://example.com&lt;/code&gt; 是跨源（协议不同）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;https://example.com&lt;/code&gt; 和 &lt;code&gt;https://api.example.com&lt;/code&gt; 是跨源（域名不同）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;https://example.com&lt;/code&gt; 和 &lt;code&gt;https://example.com:8080&lt;/code&gt; 是跨源（端口不同）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;跨域问题主要体现在以下场景中：&lt;/p&gt;
&lt;h4 id="1ajax-请求被阻止"&gt;&lt;a href="#1ajax-%e8%af%b7%e6%b1%82%e8%a2%ab%e9%98%bb%e6%ad%a2" class="header-anchor"&gt;&lt;/a&gt;（1）&lt;strong&gt;AJAX 请求被阻止&lt;/strong&gt;
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;当使用 &lt;code&gt;XMLHttpRequest&lt;/code&gt; 或 &lt;code&gt;Fetch API&lt;/code&gt; 发起跨域请求时，浏览器会阻止请求，除非服务器明确允许。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;例如：前端页面在 &lt;code&gt;https://example.com&lt;/code&gt; 下，尝试请求 &lt;code&gt;https://api.example.com&lt;/code&gt; 的数据时，会被浏览器阻止。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="2cookie-和-localstorage-无法访问"&gt;&lt;a href="#2cookie-%e5%92%8c-localstorage-%e6%97%a0%e6%b3%95%e8%ae%bf%e9%97%ae" class="header-anchor"&gt;&lt;/a&gt;（2）&lt;strong&gt;Cookie 和 LocalStorage 无法访问&lt;/strong&gt;
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;浏览器不允许脚本访问跨域的 Cookie 或 LocalStorage 数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;例如：&lt;code&gt;https://example.com&lt;/code&gt; 无法读取 &lt;code&gt;https://another.com&lt;/code&gt; 的 Cookie。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="3dom-操作受限"&gt;&lt;a href="#3dom-%e6%93%8d%e4%bd%9c%e5%8f%97%e9%99%90" class="header-anchor"&gt;&lt;/a&gt;（3）&lt;strong&gt;DOM 操作受限&lt;/strong&gt;
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;浏览器不允许脚本访问跨域 iframe 的内容。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;例如：&lt;code&gt;https://example.com&lt;/code&gt; 页面中嵌入了一个 &lt;code&gt;https://another.com&lt;/code&gt; 的 iframe，脚本无法访问 iframe 中的 DOM。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="4web-fonts-和图片加载受限"&gt;&lt;a href="#4web-fonts-%e5%92%8c%e5%9b%be%e7%89%87%e5%8a%a0%e8%bd%bd%e5%8f%97%e9%99%90" class="header-anchor"&gt;&lt;/a&gt;（4）&lt;strong&gt;Web Fonts 和图片加载受限&lt;/strong&gt;
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;某些资源（如字体、图片）的跨域加载可能会受到限制，除非服务器设置正确的 CORS 头。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="为什么要有同源策略限制"&gt;&lt;a href="#%e4%b8%ba%e4%bb%80%e4%b9%88%e8%a6%81%e6%9c%89%e5%90%8c%e6%ba%90%e7%ad%96%e7%95%a5%e9%99%90%e5%88%b6" class="header-anchor"&gt;&lt;/a&gt;为什么要有&lt;strong&gt;同源策略&lt;/strong&gt;限制？
&lt;/h1&gt;&lt;h4 id="1-防止数据泄露"&gt;&lt;a href="#1-%e9%98%b2%e6%ad%a2%e6%95%b0%e6%8d%ae%e6%b3%84%e9%9c%b2" class="header-anchor"&gt;&lt;/a&gt;1. &lt;strong&gt;防止数据泄露&lt;/strong&gt;
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果没有同源策略，恶意网站可以通过脚本访问其他网站的数据（如 Cookie、LocalStorage），导致用户隐私泄露。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;例如：用户在 &lt;code&gt;https://bank.com&lt;/code&gt; 登录后，访问了恶意网站 &lt;code&gt;https://evil.com&lt;/code&gt;，如果没有同源策略，&lt;code&gt;evil.com&lt;/code&gt; 可以读取 &lt;code&gt;bank.com&lt;/code&gt; 的 Cookie，从而窃取用户的银行账户信息。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="2-防止-csrf跨站请求伪造攻击"&gt;&lt;a href="#2-%e9%98%b2%e6%ad%a2-csrf%e8%b7%a8%e7%ab%99%e8%af%b7%e6%b1%82%e4%bc%aa%e9%80%a0%e6%94%bb%e5%87%bb" class="header-anchor"&gt;&lt;/a&gt;2. &lt;strong&gt;防止 CSRF（跨站请求伪造）攻击&lt;/strong&gt;
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;同源策略可以防止恶意网站伪造用户请求，执行未经授权的操作。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;例如：用户在 &lt;code&gt;https://bank.com&lt;/code&gt; 登录后，访问了恶意网站 &lt;code&gt;https://evil.com&lt;/code&gt;，&lt;code&gt;evil.com&lt;/code&gt; 可以伪造一个请求到 &lt;code&gt;https://bank.com/transfer&lt;/code&gt;，将用户的资金转走。同源策略可以阻止这种行为。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="3-防止恶意脚本注入"&gt;&lt;a href="#3-%e9%98%b2%e6%ad%a2%e6%81%b6%e6%84%8f%e8%84%9a%e6%9c%ac%e6%b3%a8%e5%85%a5" class="header-anchor"&gt;&lt;/a&gt;3. &lt;strong&gt;防止恶意脚本注入&lt;/strong&gt;
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;同源策略可以防止恶意脚本通过 iframe 或 AJAX 请求访问其他网站的内容。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;例如：如果没有同源策略，恶意网站可以通过 iframe 嵌入 &lt;code&gt;https://mail.com&lt;/code&gt;，并窃取用户的邮件内容。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="4-保护用户隐私"&gt;&lt;a href="#4-%e4%bf%9d%e6%8a%a4%e7%94%a8%e6%88%b7%e9%9a%90%e7%a7%81" class="header-anchor"&gt;&lt;/a&gt;4. &lt;strong&gt;保护用户隐私&lt;/strong&gt;
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;同源策略可以防止网站通过脚本获取用户的浏览历史、本地存储数据等隐私信息。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="如何解决跨域问题"&gt;&lt;a href="#%e5%a6%82%e4%bd%95%e8%a7%a3%e5%86%b3%e8%b7%a8%e5%9f%9f%e9%97%ae%e9%a2%98" class="header-anchor"&gt;&lt;/a&gt;如何解决&lt;strong&gt;跨域问题？&lt;/strong&gt;
&lt;/h1&gt;&lt;p&gt;常见的跨域解决方案包括：&lt;/p&gt;
&lt;h4 id="1cors跨域资源共享"&gt;&lt;a href="#1cors%e8%b7%a8%e5%9f%9f%e8%b5%84%e6%ba%90%e5%85%b1%e4%ba%ab" class="header-anchor"&gt;&lt;/a&gt;（1）&lt;strong&gt;CORS（跨域资源共享）&lt;/strong&gt;
&lt;/h4&gt;&lt;p&gt;CORS 是官方推荐的跨域解决方案。它通过在 &lt;strong&gt;服务器端设置 HTTP 响应头&lt;/strong&gt;，明确告诉浏览器允许哪些来源、方法和头部的跨域请求。&lt;/p&gt;
&lt;p&gt;服务器端配置示例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Spring Boot 中的 CORS 配置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;addCorsMappings&lt;/span&gt;(CorsRegistry registry) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; registry.&lt;span style="color:#a6e22e"&gt;addMapping&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/**&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 允许所有路径的跨域请求&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;allowedOriginPatterns&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 允许所有来源&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;allowedMethods&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;POST&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;PUT&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;DELETE&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 允许的请求方法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;allowedHeaders&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 允许的请求头&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;allowCredentials&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 是否允许带认证信息&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;maxAge&lt;/span&gt;(3600); &lt;span style="color:#75715e"&gt;// 预检请求的缓存时间&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;浏览器在发起跨域请求时，会先发送一个 &lt;strong&gt;预检请求（Preflight Request）&lt;/strong&gt;，询问服务器是否允许跨域请求。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;服务器通过设置 &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; 等响应头，明确告诉浏览器允许跨域请求。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;浏览器收到响应后，会根据响应头决定是否允许实际的请求。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="2jsonp"&gt;&lt;a href="#2jsonp" class="header-anchor"&gt;&lt;/a&gt;（2）&lt;strong&gt;JSONP&lt;/strong&gt;
&lt;/h4&gt;&lt;p&gt;JSONP 是一种利用 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 标签不受同源策略限制的特性来实现跨域请求的技术。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 标签不受同源策略限制，可以加载跨域的 JavaScript 文件。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;服务器返回的数据被包裹在一个回调函数中（如 &lt;code&gt;handleResponse&lt;/code&gt;），前端通过定义这个回调函数来处理数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;缺点是 &lt;strong&gt;只支持 GET 请求&lt;/strong&gt;，且安全性较低（无法处理错误和复杂的请求）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;特性&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 标签的跨域加载&lt;/th&gt;
					&lt;th&gt;同源策略的作用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;跨域加载 JavaScript&lt;/td&gt;
					&lt;td&gt;可以&lt;/td&gt;
					&lt;td&gt;不限制 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 标签的跨域加载，但限制了其他行为（如 AJAX 请求、Cookie 访问）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;跨域 AJAX 请求&lt;/td&gt;
					&lt;td&gt;不可以&lt;/td&gt;
					&lt;td&gt;阻止恶意网站通过 AJAX 请求访问其他网站的数据。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;跨域访问 Cookie&lt;/td&gt;
					&lt;td&gt;不可以&lt;/td&gt;
					&lt;td&gt;阻止恶意网站访问其他网站的 Cookie 和 LocalStorage。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;跨域 DOM 操作&lt;/td&gt;
					&lt;td&gt;不可以&lt;/td&gt;
					&lt;td&gt;阻止恶意网站通过 iframe 嵌入其他网站并操作其 DOM。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;跨域资源访问&lt;/td&gt;
					&lt;td&gt;部分可以（如 JavaScript 文件）&lt;/td&gt;
					&lt;td&gt;阻止恶意网站滥用其他网站的资源（如字体、图片）。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="3代理服务器"&gt;&lt;a href="#3%e4%bb%a3%e7%90%86%e6%9c%8d%e5%8a%a1%e5%99%a8" class="header-anchor"&gt;&lt;/a&gt;（3）&lt;strong&gt;代理服务器&lt;/strong&gt;
&lt;/h4&gt;&lt;p&gt;代理服务器的原理是让前端请求同源服务器，由同源服务器转发请求到目标服务器。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;浏览器只向同源服务器发起请求，避免了跨域问题。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;代理服务器将请求转发到目标服务器，并将响应返回给浏览器。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;由于代理服务器是服务器之间的通信，不受浏览器的同源策略限制。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="4websocket"&gt;&lt;a href="#4websocket" class="header-anchor"&gt;&lt;/a&gt;（4）&lt;strong&gt;WebSocket&lt;/strong&gt;
&lt;/h4&gt;&lt;p&gt;WebSocket 是一种全双工通信协议，不受同源策略限制。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;WebSocket 协议本身不受同源策略限制。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;它适用于实时通信场景（如聊天室、实时数据推送）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="5修改浏览器设置不推荐"&gt;&lt;a href="#5%e4%bf%ae%e6%94%b9%e6%b5%8f%e8%a7%88%e5%99%a8%e8%ae%be%e7%bd%ae%e4%b8%8d%e6%8e%a8%e8%8d%90" class="header-anchor"&gt;&lt;/a&gt;（5）&lt;strong&gt;修改浏览器设置（不推荐）&lt;/strong&gt;
&lt;/h4&gt;&lt;p&gt;在开发环境中，可以禁用浏览器的同源策略。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;禁用同源策略后，浏览器不再检查跨域请求，所有请求都会被允许。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缺点&lt;/strong&gt;：这会降低浏览器的安全性，容易受到恶意网站的攻击，因此 &lt;strong&gt;不推荐在生产环境中使用&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="个人总结"&gt;&lt;a href="#%e4%b8%aa%e4%ba%ba%e6%80%bb%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;个人总结
&lt;/h1&gt;&lt;p&gt;跨域问题主要就是浏览器出于安全的限制，如果在开发过程中遇到了需要跨域的情况，开发者就需要自行进行配置。可以从前端入手&lt;strong&gt;设置代理服务器&lt;/strong&gt;避免出现跨域，也可以从后端入手配置&lt;strong&gt;CORS跨域资源共享&lt;/strong&gt;解决。&lt;/p&gt;</description></item><item><title>防火墙工具引起的问题</title><link>https://dandansad.com/2025/03/10/%E5%85%B3%E4%BA%8E%E9%98%B2%E7%81%AB%E5%A2%99/</link><pubDate>Mon, 10 Mar 2025 01:05:50 +0800</pubDate><guid>https://dandansad.com/2025/03/10/%E5%85%B3%E4%BA%8E%E9%98%B2%E7%81%AB%E5%A2%99/</guid><description>&lt;h1 id="起因"&gt;&lt;a href="#%e8%b5%b7%e5%9b%a0" class="header-anchor"&gt;&lt;/a&gt;起因
&lt;/h1&gt;&lt;p&gt;因为觉得服务器的内存占用太高，但是不知道要清理哪些进程，于是重启了一下服务器。重启服务器之后Xshell连不上了，于是折腾了一个晚上，搞明白了关于防火墙的一些相关知识。&lt;/p&gt;
&lt;p&gt;同时突然想起之前一次使用firewall-cmd开放端口后，服务器也无法远程连接，可能也就是和今天学到的有关吧。&lt;/p&gt;
&lt;h1 id="各种防火墙工具"&gt;&lt;a href="#%e5%90%84%e7%a7%8d%e9%98%b2%e7%81%ab%e5%a2%99%e5%b7%a5%e5%85%b7" class="header-anchor"&gt;&lt;/a&gt;各种防火墙工具
&lt;/h1&gt;&lt;p&gt;在 Linux 系统中，有多种防火墙工具可供选择，每种工具都有其特点和适用场景。以下是常见防火墙工具的梳理，包括它们的异同、开机自启动方法以及常用命令。&lt;/p&gt;
&lt;h2 id="1-iptables"&gt;&lt;a href="#1-iptables" class="header-anchor"&gt;&lt;/a&gt;1. &lt;strong&gt;iptables&lt;/strong&gt;
&lt;/h2&gt;&lt;h3 id="特点"&gt;&lt;a href="#%e7%89%b9%e7%82%b9" class="header-anchor"&gt;&lt;/a&gt;特点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;底层工具&lt;/strong&gt;：直接操作 Linux 内核的 Netfilter 框架。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;静态规则&lt;/strong&gt;：规则是静态的，修改后需要手动保存。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;灵活性高&lt;/strong&gt;：适合需要精细控制规则的高级用户。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="开机自启动"&gt;&lt;a href="#%e5%bc%80%e6%9c%ba%e8%87%aa%e5%90%af%e5%8a%a8" class="header-anchor"&gt;&lt;/a&gt;开机自启动
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;iptables&lt;/code&gt; 本身不是一个服务，但可以通过以下方法实现开机自启动：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Debian/Ubuntu&lt;/strong&gt;：使用 &lt;code&gt;iptables-persistent&lt;/code&gt; 包。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo apt-get install iptables-persistent&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CentOS/RHEL&lt;/strong&gt;：使用 &lt;code&gt;iptables-services&lt;/code&gt; 包。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;sudo yum install iptables-services&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;sudo systemctl enable iptables&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;sudo systemctl start iptables&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="常用命令"&gt;&lt;a href="#%e5%b8%b8%e7%94%a8%e5%91%bd%e4%bb%a4" class="header-anchor"&gt;&lt;/a&gt;常用命令
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;查看规则：&lt;code&gt;sudo iptables -L -v -n&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;添加规则：&lt;code&gt;sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;保存规则：&lt;code&gt;sudo iptables-save &amp;gt; /etc/iptables/rules.v4&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;加载规则：&lt;code&gt;sudo iptables-restore &amp;lt; /etc/iptables/rules.v4&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2-firewalld"&gt;&lt;a href="#2-firewalld" class="header-anchor"&gt;&lt;/a&gt;2. &lt;strong&gt;firewalld&lt;/strong&gt;
&lt;/h2&gt;&lt;h3 id="特点-1"&gt;&lt;a href="#%e7%89%b9%e7%82%b9-1" class="header-anchor"&gt;&lt;/a&gt;特点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;动态管理&lt;/strong&gt;：支持运行时更新规则，无需重启服务。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;高级抽象&lt;/strong&gt;：使用 zones 和 services 简化配置。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;适合服务器&lt;/strong&gt;：常用于 CentOS、RHEL、Fedora。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="开机自启动-1"&gt;&lt;a href="#%e5%bc%80%e6%9c%ba%e8%87%aa%e5%90%af%e5%8a%a8-1" class="header-anchor"&gt;&lt;/a&gt;开机自启动
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;启用开机自启动：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;sudo systemctl enable firewalld&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo systemctl start firewalld&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="常用命令-1"&gt;&lt;a href="#%e5%b8%b8%e7%94%a8%e5%91%bd%e4%bb%a4-1" class="header-anchor"&gt;&lt;/a&gt;常用命令
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;查看状态：&lt;code&gt;sudo firewall-cmd --state&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;查看当前区域规则：&lt;code&gt;sudo firewall-cmd --list-all&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;添加服务：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;sudo firewall-cmd --zone=public --add-service=ssh --permanent&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;sudo firewall-cmd --reload&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;添加端口：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;sudo firewall-cmd --zone=public --add-port=80/tcp --permanent&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo firewall-cmd --reload&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="3-ufwuncomplicated-firewall"&gt;&lt;a href="#3-ufwuncomplicated-firewall" class="header-anchor"&gt;&lt;/a&gt;3. &lt;strong&gt;UFW（Uncomplicated Firewall）&lt;/strong&gt;
&lt;/h2&gt;&lt;h3 id="特点-2"&gt;&lt;a href="#%e7%89%b9%e7%82%b9-2" class="header-anchor"&gt;&lt;/a&gt;特点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;简单易用&lt;/strong&gt;：适合初学者或需要快速配置的场景。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;基于 iptables&lt;/strong&gt;：底层仍然使用 &lt;code&gt;iptables&lt;/code&gt;。（主要基于 iptables，也在逐步支持 nftables）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;适合桌面&lt;/strong&gt;：常用于 Ubuntu 和基于 Ubuntu 的发行版。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="开机自启动-2"&gt;&lt;a href="#%e5%bc%80%e6%9c%ba%e8%87%aa%e5%90%af%e5%8a%a8-2" class="header-anchor"&gt;&lt;/a&gt;开机自启动
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;启用开机自启动：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;sudo systemctl enable ufw&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo systemctl start ufw&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="常用命令-2"&gt;&lt;a href="#%e5%b8%b8%e7%94%a8%e5%91%bd%e4%bb%a4-2" class="header-anchor"&gt;&lt;/a&gt;常用命令
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;查看状态：&lt;code&gt;sudo ufw status&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;启用 UFW：&lt;code&gt;sudo ufw enable&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;允许服务：&lt;code&gt;sudo ufw allow ssh&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;允许端口：&lt;code&gt;sudo ufw allow 80/tcp&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;删除规则：&lt;code&gt;sudo ufw delete allow 80/tcp&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="4-nftables"&gt;&lt;a href="#4-nftables" class="header-anchor"&gt;&lt;/a&gt;4. &lt;strong&gt;nftables&lt;/strong&gt;
&lt;/h2&gt;&lt;h3 id="特点-3"&gt;&lt;a href="#%e7%89%b9%e7%82%b9-3" class="header-anchor"&gt;&lt;/a&gt;特点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;iptables 的继任者&lt;/strong&gt;：更高效、更灵活。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;统一框架&lt;/strong&gt;：支持 IPv4 和 IPv6。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;适合高级用户&lt;/strong&gt;：语法更复杂，但功能更强大。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="开机自启动-3"&gt;&lt;a href="#%e5%bc%80%e6%9c%ba%e8%87%aa%e5%90%af%e5%8a%a8-3" class="header-anchor"&gt;&lt;/a&gt;开机自启动
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;启用开机自启动：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;sudo systemctl enable nftables&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo systemctl start nftables&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="常用命令-3"&gt;&lt;a href="#%e5%b8%b8%e7%94%a8%e5%91%bd%e4%bb%a4-3" class="header-anchor"&gt;&lt;/a&gt;常用命令
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;查看规则：&lt;code&gt;sudo nft list ruleset&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;添加规则：&lt;code&gt;sudo nft add rule ip filter input tcp dport 22 accept&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;保存规则：&lt;code&gt;sudo nft list ruleset &amp;gt; /etc/nftables.conf&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;加载规则：&lt;code&gt;sudo nft -f /etc/nftables.conf&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="5-总结对比"&gt;&lt;a href="#5-%e6%80%bb%e7%bb%93%e5%af%b9%e6%af%94" class="header-anchor"&gt;&lt;/a&gt;5. &lt;strong&gt;总结对比&lt;/strong&gt;
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;工具&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
					&lt;th&gt;开机自启动方法&lt;/th&gt;
					&lt;th&gt;适用场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;iptables&lt;/td&gt;
					&lt;td&gt;静态规则，灵活性高&lt;/td&gt;
					&lt;td&gt;使用 iptables-persistent 或 iptables-services&lt;/td&gt;
					&lt;td&gt;高级用户、服务器&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;firewalld&lt;/td&gt;
					&lt;td&gt;动态管理，支持 zones 和 services&lt;/td&gt;
					&lt;td&gt;systemctl enable firewalld&lt;/td&gt;
					&lt;td&gt;服务器、云环境&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;UFW&lt;/td&gt;
					&lt;td&gt;简单易用，基于 iptables&lt;/td&gt;
					&lt;td&gt;systemctl enable ufw&lt;/td&gt;
					&lt;td&gt;桌面、简单服务器&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;nftables&lt;/td&gt;
					&lt;td&gt;iptables 的继任者，高效灵活&lt;/td&gt;
					&lt;td&gt;systemctl enable nftables&lt;/td&gt;
					&lt;td&gt;高级用户、现代 Linux 系统&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="6-如何选择"&gt;&lt;a href="#6-%e5%a6%82%e4%bd%95%e9%80%89%e6%8b%a9" class="header-anchor"&gt;&lt;/a&gt;6. &lt;strong&gt;如何选择？&lt;/strong&gt;
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果你需要精细控制规则，选择 &lt;strong&gt;iptables&lt;/strong&gt; 或 &lt;strong&gt;nftables&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果你是初学者或需要快速配置，选择 &lt;strong&gt;UFW&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果你需要动态管理规则，选择 &lt;strong&gt;firewalld&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="避免防火墙冲突"&gt;&lt;a href="#%e9%81%bf%e5%85%8d%e9%98%b2%e7%81%ab%e5%a2%99%e5%86%b2%e7%aa%81" class="header-anchor"&gt;&lt;/a&gt;避免防火墙冲突
&lt;/h1&gt;&lt;p&gt;防火墙冲突通常发生在同时使用多个防火墙工具（如 &lt;code&gt;iptables&lt;/code&gt;、&lt;code&gt;firewalld&lt;/code&gt;、&lt;code&gt;UFW&lt;/code&gt; 等）时，因为它们可能会修改相同的底层规则表（如 &lt;code&gt;iptables&lt;/code&gt; 或 &lt;code&gt;nftables&lt;/code&gt;），导致规则覆盖或不一致的行为。以下是避免防火墙冲突的方法：&lt;/p&gt;
&lt;h2 id="1-只使用一个防火墙工具"&gt;&lt;a href="#1-%e5%8f%aa%e4%bd%bf%e7%94%a8%e4%b8%80%e4%b8%aa%e9%98%b2%e7%81%ab%e5%a2%99%e5%b7%a5%e5%85%b7" class="header-anchor"&gt;&lt;/a&gt;1. &lt;strong&gt;只使用一个防火墙工具&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;这是避免冲突的最简单和最有效的方法。选择一个适合你需求的工具，并禁用其他工具。&lt;/p&gt;
&lt;h3 id="选择工具的建议"&gt;&lt;a href="#%e9%80%89%e6%8b%a9%e5%b7%a5%e5%85%b7%e7%9a%84%e5%bb%ba%e8%ae%ae" class="header-anchor"&gt;&lt;/a&gt;选择工具的建议
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;简单易用&lt;/strong&gt;：选择 &lt;strong&gt;UFW&lt;/strong&gt;（适合桌面用户或初学者）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;动态管理&lt;/strong&gt;：选择 &lt;strong&gt;firewalld&lt;/strong&gt;（适合服务器或需要频繁更新规则的场景）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;精细控制&lt;/strong&gt;：选择 &lt;strong&gt;iptables&lt;/strong&gt; 或 &lt;strong&gt;nftables&lt;/strong&gt;（适合高级用户）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2-禁用其他防火墙工具"&gt;&lt;a href="#2-%e7%a6%81%e7%94%a8%e5%85%b6%e4%bb%96%e9%98%b2%e7%81%ab%e5%a2%99%e5%b7%a5%e5%85%b7" class="header-anchor"&gt;&lt;/a&gt;2. &lt;strong&gt;禁用其他防火墙工具&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;如果你决定使用某个工具，请确保禁用其他工具。&lt;/p&gt;
&lt;h3 id="禁用-firewalld"&gt;&lt;a href="#%e7%a6%81%e7%94%a8-firewalld" class="header-anchor"&gt;&lt;/a&gt;禁用 firewalld
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl stop firewalld
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl disable firewalld
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="禁用-ufw"&gt;&lt;a href="#%e7%a6%81%e7%94%a8-ufw" class="header-anchor"&gt;&lt;/a&gt;禁用 UFW
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ufw disable
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="禁用-iptables如果使用-firewalld-或-ufw"&gt;&lt;a href="#%e7%a6%81%e7%94%a8-iptables%e5%a6%82%e6%9e%9c%e4%bd%bf%e7%94%a8-firewalld-%e6%88%96-ufw" class="header-anchor"&gt;&lt;/a&gt;禁用 iptables（如果使用 firewalld 或 UFW）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果你使用 &lt;code&gt;firewalld&lt;/code&gt; 或 &lt;code&gt;UFW&lt;/code&gt;，通常不需要手动禁用 &lt;code&gt;iptables&lt;/code&gt;，因为它们会管理 &lt;code&gt;iptables&lt;/code&gt; 规则。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果你直接使用 &lt;code&gt;iptables&lt;/code&gt;，请确保没有其他工具干扰。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="3-检查当前使用的工具"&gt;&lt;a href="#3-%e6%a3%80%e6%9f%a5%e5%bd%93%e5%89%8d%e4%bd%bf%e7%94%a8%e7%9a%84%e5%b7%a5%e5%85%b7" class="header-anchor"&gt;&lt;/a&gt;3. &lt;strong&gt;检查当前使用的工具&lt;/strong&gt;
&lt;/h2&gt;&lt;h3 id="检查-firewalld-是否运行"&gt;&lt;a href="#%e6%a3%80%e6%9f%a5-firewalld-%e6%98%af%e5%90%a6%e8%bf%90%e8%a1%8c" class="header-anchor"&gt;&lt;/a&gt;检查 firewalld 是否运行
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl status firewalld
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="检查-ufw-是否运行"&gt;&lt;a href="#%e6%a3%80%e6%9f%a5-ufw-%e6%98%af%e5%90%a6%e8%bf%90%e8%a1%8c" class="header-anchor"&gt;&lt;/a&gt;检查 UFW 是否运行
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ufw status
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="检查-iptables-规则"&gt;&lt;a href="#%e6%a3%80%e6%9f%a5-iptables-%e8%a7%84%e5%88%99" class="header-anchor"&gt;&lt;/a&gt;检查 iptables 规则
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo iptables -L -v -n
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="4-避免手动修改底层规则"&gt;&lt;a href="#4-%e9%81%bf%e5%85%8d%e6%89%8b%e5%8a%a8%e4%bf%ae%e6%94%b9%e5%ba%95%e5%b1%82%e8%a7%84%e5%88%99" class="header-anchor"&gt;&lt;/a&gt;4. &lt;strong&gt;避免手动修改底层规则&lt;/strong&gt;
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果你使用 &lt;code&gt;firewalld&lt;/code&gt; 或 &lt;code&gt;UFW&lt;/code&gt;，尽量避免直接使用 &lt;code&gt;iptables&lt;/code&gt; 或 &lt;code&gt;nftables&lt;/code&gt; 修改规则，因为这可能导致冲突。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果你需要直接操作底层规则，请确保了解工具之间的交互方式。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="5-规则持久化"&gt;&lt;a href="#5-%e8%a7%84%e5%88%99%e6%8c%81%e4%b9%85%e5%8c%96" class="header-anchor"&gt;&lt;/a&gt;5. &lt;strong&gt;规则持久化&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;确保规则在重启后仍然有效，避免因规则丢失而导致的安全问题。&lt;/p&gt;
&lt;h3 id="firewalld"&gt;&lt;a href="#firewalld" class="header-anchor"&gt;&lt;/a&gt;firewalld
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;--permanent&lt;/code&gt; 参数保存规则：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo firewall&lt;span style="color:#f92672"&gt;-&lt;/span&gt;cmd &lt;span style="color:#f92672"&gt;--&lt;/span&gt;zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public &lt;span style="color:#f92672"&gt;--&lt;/span&gt;add&lt;span style="color:#f92672"&gt;-&lt;/span&gt;service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;ssh &lt;span style="color:#f92672"&gt;--&lt;/span&gt;permanent
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sudo firewall&lt;span style="color:#f92672"&gt;-&lt;/span&gt;cmd &lt;span style="color:#f92672"&gt;--&lt;/span&gt;reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="ufw"&gt;&lt;a href="#ufw" class="header-anchor"&gt;&lt;/a&gt;UFW
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;启用 UFW 并添加规则：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ufw enable
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sudo ufw allow ssh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="iptables"&gt;&lt;a href="#iptables" class="header-anchor"&gt;&lt;/a&gt;iptables
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;iptables-save&lt;/code&gt; 保存规则：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo iptables-save &amp;gt; /etc/iptables/rules.v4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="6-示例从-firewalld-切换到-ufw"&gt;&lt;a href="#6-%e7%a4%ba%e4%be%8b%e4%bb%8e-firewalld-%e5%88%87%e6%8d%a2%e5%88%b0-ufw" class="header-anchor"&gt;&lt;/a&gt;6. &lt;strong&gt;示例：从 firewalld 切换到 UFW&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;如果你决定使用 UFW，可以按照以下步骤切换：&lt;/p&gt;
&lt;h4 id="停止并禁用-firewalld"&gt;&lt;a href="#%e5%81%9c%e6%ad%a2%e5%b9%b6%e7%a6%81%e7%94%a8-firewalld" class="header-anchor"&gt;&lt;/a&gt;停止并禁用 firewalld
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl stop firewalld
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl disable firewalld
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="启用-ufw"&gt;&lt;a href="#%e5%90%af%e7%94%a8-ufw" class="header-anchor"&gt;&lt;/a&gt;启用 UFW
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ufw enable
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="添加规则"&gt;&lt;a href="#%e6%b7%bb%e5%8a%a0%e8%a7%84%e5%88%99" class="header-anchor"&gt;&lt;/a&gt;添加规则
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ufw allow ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ufw allow http
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="检查状态"&gt;&lt;a href="#%e6%a3%80%e6%9f%a5%e7%8a%b6%e6%80%81" class="header-anchor"&gt;&lt;/a&gt;检查状态
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ufw status
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="7-总结"&gt;&lt;a href="#7-%e6%80%bb%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;7. &lt;strong&gt;总结&lt;/strong&gt;
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;只使用一个防火墙工具，避免同时启用多个工具。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;禁用其他工具，确保规则不会被覆盖。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;确保规则持久化，避免重启后丢失。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="默认防火墙工具"&gt;&lt;a href="#%e9%bb%98%e8%ae%a4%e9%98%b2%e7%81%ab%e5%a2%99%e5%b7%a5%e5%85%b7" class="header-anchor"&gt;&lt;/a&gt;默认防火墙工具
&lt;/h1&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;发行版&lt;/th&gt;
					&lt;th&gt;默认工具&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
					&lt;th&gt;其他支持工具&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Ubuntu&lt;/td&gt;
					&lt;td&gt;UFW&lt;/td&gt;
					&lt;td&gt;简单易用，适合初学者&lt;/td&gt;
					&lt;td&gt;iptables, firewalld, nftables&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Debian&lt;/td&gt;
					&lt;td&gt;UFW&lt;/td&gt;
					&lt;td&gt;简单易用，适合初学者&lt;/td&gt;
					&lt;td&gt;iptables, firewalld, nftables&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CentOS&lt;/td&gt;
					&lt;td&gt;firewalld&lt;/td&gt;
					&lt;td&gt;动态管理，支持 zones 和 services&lt;/td&gt;
					&lt;td&gt;iptables, nftables&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;RHEL&lt;/td&gt;
					&lt;td&gt;firewalld&lt;/td&gt;
					&lt;td&gt;动态管理，支持 zones 和 services&lt;/td&gt;
					&lt;td&gt;iptables, nftables&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Fedora&lt;/td&gt;
					&lt;td&gt;firewalld&lt;/td&gt;
					&lt;td&gt;动态管理，支持 zones 和 services&lt;/td&gt;
					&lt;td&gt;iptables, nftables&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Arch Linux&lt;/td&gt;
					&lt;td&gt;无默认工具&lt;/td&gt;
					&lt;td&gt;用户自行选择&lt;/td&gt;
					&lt;td&gt;iptables, nftables, firewalld&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;openSUSE&lt;/td&gt;
					&lt;td&gt;SuSEfirewall2 / firewalld&lt;/td&gt;
					&lt;td&gt;旧版使用 SuSEfirewall2，新版使用 firewalld&lt;/td&gt;
					&lt;td&gt;iptables, nftables&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;理论上，&lt;strong&gt;大多数防火墙工具可以在所有 Linux 发行版上使用&lt;/strong&gt;，但实际使用中可能会受到以下限制：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;发行版的默认工具&lt;/strong&gt;：不同发行版可能有自己的默认防火墙工具。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;软件包管理器的支持&lt;/strong&gt;：某些工具可能需要从源码编译安装，或者依赖特定的库。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;兼容性问题&lt;/strong&gt;：同时使用多个防火墙工具可能会导致规则冲突。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="但是强烈建议就用默认的工具或者使用非默认的工具时一定要禁用其他工具不要混用不同的防火墙工具导致规则覆盖或不一致的行为"&gt;&lt;a href="#%e4%bd%86%e6%98%af%e5%bc%ba%e7%83%88%e5%bb%ba%e8%ae%ae%e5%b0%b1%e7%94%a8%e9%bb%98%e8%ae%a4%e7%9a%84%e5%b7%a5%e5%85%b7%e6%88%96%e8%80%85%e4%bd%bf%e7%94%a8%e9%9d%9e%e9%bb%98%e8%ae%a4%e7%9a%84%e5%b7%a5%e5%85%b7%e6%97%b6%e4%b8%80%e5%ae%9a%e8%a6%81%e7%a6%81%e7%94%a8%e5%85%b6%e4%bb%96%e5%b7%a5%e5%85%b7%e4%b8%8d%e8%a6%81%e6%b7%b7%e7%94%a8%e4%b8%8d%e5%90%8c%e7%9a%84%e9%98%b2%e7%81%ab%e5%a2%99%e5%b7%a5%e5%85%b7%e5%af%bc%e8%87%b4%e8%a7%84%e5%88%99%e8%a6%86%e7%9b%96%e6%88%96%e4%b8%8d%e4%b8%80%e8%87%b4%e7%9a%84%e8%a1%8c%e4%b8%ba" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;但是强烈建议就用默认的工具或者使用非默认的工具时一定要禁用其他工具，不要混用不同的防火墙工具，导致规则覆盖或不一致的行为&lt;/strong&gt;！！！
&lt;/h3&gt;&lt;h1 id="前后端划分"&gt;&lt;a href="#%e5%89%8d%e5%90%8e%e7%ab%af%e5%88%92%e5%88%86" class="header-anchor"&gt;&lt;/a&gt;前后端划分
&lt;/h1&gt;&lt;h2 id="-后端内核级防火墙工具"&gt;&lt;a href="#-%e5%90%8e%e7%ab%af%e5%86%85%e6%a0%b8%e7%ba%a7%e9%98%b2%e7%81%ab%e5%a2%99%e5%b7%a5%e5%85%b7" class="header-anchor"&gt;&lt;/a&gt;✅ 后端（内核级防火墙工具）：
&lt;/h2&gt;&lt;p&gt;这些直接与 Linux 内核的网络过滤框架交互，负责执行具体的包过滤和网络规则：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;iptables&lt;/strong&gt;（旧的内核防火墙后端，广泛使用多年）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;nftables&lt;/strong&gt;（iptables 的继任者，设计更现代，已成为新的内核防火墙框架）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="-前端用户空间防火墙管理工具"&gt;&lt;a href="#-%e5%89%8d%e7%ab%af%e7%94%a8%e6%88%b7%e7%a9%ba%e9%97%b4%e9%98%b2%e7%81%ab%e5%a2%99%e7%ae%a1%e7%90%86%e5%b7%a5%e5%85%b7" class="header-anchor"&gt;&lt;/a&gt;✅ 前端（用户空间防火墙管理工具）：
&lt;/h2&gt;&lt;p&gt;这些工具提供更简化或结构化的接口，帮助用户管理底层防火墙规则（调用 iptables 或 nftables 实际应用规则）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;firewalld&lt;/strong&gt;（基于 zone 和服务概念的高级防火墙管理器，可以使用 iptables 或 nftables 作为后端）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;UFW（Uncomplicated Firewall）&lt;/strong&gt;（Ubuntu 上常见的防火墙简化工具，主要基于 iptables，也在逐步支持 nftables）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="总结对照表"&gt;&lt;a href="#%e6%80%bb%e7%bb%93%e5%af%b9%e7%85%a7%e8%a1%a8" class="header-anchor"&gt;&lt;/a&gt;总结对照表：
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;名称&lt;/th&gt;
					&lt;th&gt;类型&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;iptables&lt;/td&gt;
					&lt;td&gt;后端&lt;/td&gt;
					&lt;td&gt;旧版 Linux 防火墙核心组件，低层次规则设置&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;nftables&lt;/td&gt;
					&lt;td&gt;后端&lt;/td&gt;
					&lt;td&gt;新一代内核防火墙系统，功能更强，替代 iptables&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;firewalld&lt;/td&gt;
					&lt;td&gt;前端&lt;/td&gt;
					&lt;td&gt;支持动态规则和区域，默认使用 nftables（新系统）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;UFW&lt;/td&gt;
					&lt;td&gt;前端&lt;/td&gt;
					&lt;td&gt;面向用户简化命令行操作，默认基于 iptables（Ubuntu）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="防火墙和安全组"&gt;&lt;a href="#%e9%98%b2%e7%81%ab%e5%a2%99%e5%92%8c%e5%ae%89%e5%85%a8%e7%bb%84" class="header-anchor"&gt;&lt;/a&gt;防火墙和安全组
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;防火墙&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;是一种网络安全系统，用于监控和控制进出网络的流量。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;通常部署在单个服务器或网络边界（如路由器、网关）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;基于规则（如 IP 地址、端口、协议）来决定是否允许或拒绝流量。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;安全组&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;是一种虚拟防火墙，通常用于云计算环境（如 AWS、阿里云、腾讯云）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;作用于虚拟机实例（如云服务器）或网络接口。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;基于规则（如 IP 地址、端口、协议）来控制进出实例的流量。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;特性&lt;/th&gt;
					&lt;th&gt;防火墙&lt;/th&gt;
					&lt;th&gt;安全组&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;应用场景&lt;/td&gt;
					&lt;td&gt;物理服务器、网络边界&lt;/td&gt;
					&lt;td&gt;云计算环境中的虚拟机实例&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;实现方式&lt;/td&gt;
					&lt;td&gt;软件（如 iptables）或硬件&lt;/td&gt;
					&lt;td&gt;云计算平台的虚拟网络层&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;规则管理&lt;/td&gt;
					&lt;td&gt;静态，需手动保存&lt;/td&gt;
					&lt;td&gt;动态，修改后立即生效&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;部署位置&lt;/td&gt;
					&lt;td&gt;网络边界或单个主机&lt;/td&gt;
					&lt;td&gt;虚拟机实例或网络接口&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;性能&lt;/td&gt;
					&lt;td&gt;取决于硬件或软件实现&lt;/td&gt;
					&lt;td&gt;由云计算平台提供&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;管理复杂度&lt;/td&gt;
					&lt;td&gt;较高，适合高级用户&lt;/td&gt;
					&lt;td&gt;较低，适合普通用户&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;对于云服务器来说，安全组和防火墙相当于双重保障，在使用时如果发现某一端口开放了但是无法使用，就要查看安全组和防火墙是否都开放了该端口。&lt;/p&gt;
&lt;h1 id="相关问题分析"&gt;&lt;a href="#%e7%9b%b8%e5%85%b3%e9%97%ae%e9%a2%98%e5%88%86%e6%9e%90" class="header-anchor"&gt;&lt;/a&gt;相关问题分析
&lt;/h1&gt;&lt;h2 id="多个防火墙工具导致冲突"&gt;&lt;a href="#%e5%a4%9a%e4%b8%aa%e9%98%b2%e7%81%ab%e5%a2%99%e5%b7%a5%e5%85%b7%e5%af%bc%e8%87%b4%e5%86%b2%e7%aa%81" class="header-anchor"&gt;&lt;/a&gt;多个防火墙工具导致冲突
&lt;/h2&gt;&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-6.png"&gt;&lt;/p&gt;
&lt;p&gt;**问题原因：**之前的这一次问题可能就是由于我在Ubuntu上安装了firewall-cmd，然后使用firewall-cmd进行了端口配置，导致其他工具（ufw）的配置被覆盖了，22端口（SSH服务）也被关闭了，所以无法进行远程连接。&lt;/p&gt;
&lt;p&gt;**解决办法：**关闭和禁用其他防火墙服务，只保留一个防火墙工具，避免发生冲突。&lt;/p&gt;
&lt;h2 id="防火墙服务没有开启"&gt;&lt;a href="#%e9%98%b2%e7%81%ab%e5%a2%99%e6%9c%8d%e5%8a%a1%e6%b2%a1%e6%9c%89%e5%bc%80%e5%90%af" class="header-anchor"&gt;&lt;/a&gt;防火墙服务没有开启
&lt;/h2&gt;&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-7.png"&gt;&lt;/p&gt;
&lt;p&gt;**问题原因：**由于防火墙服务（ufw）没有开启，重启之后端口的相关配置没有被加载（22端口未开启），所以无法进行远程连接。&lt;/p&gt;
&lt;p&gt;**解决办法：**开启防火墙服务（开机自启动）。&lt;/p&gt;</description></item><item><title>MySQL 开启和关闭远程访问权限</title><link>https://dandansad.com/2025/03/04/mysql-%E5%BC%80%E5%90%AF%E5%92%8C%E5%85%B3%E9%97%AD%E8%BF%9C%E7%A8%8B%E8%AE%BF%E9%97%AE%E6%9D%83%E9%99%90/</link><pubDate>Tue, 04 Mar 2025 01:40:37 +0800</pubDate><guid>https://dandansad.com/2025/03/04/mysql-%E5%BC%80%E5%90%AF%E5%92%8C%E5%85%B3%E9%97%AD%E8%BF%9C%E7%A8%8B%E8%AE%BF%E9%97%AE%E6%9D%83%E9%99%90/</guid><description>&lt;h2 id="正文"&gt;&lt;a href="#%e6%ad%a3%e6%96%87" class="header-anchor"&gt;&lt;/a&gt;正文
&lt;/h2&gt;&lt;p&gt;在 MySQL 中，可以通过操作** mysql 数据库&lt;strong&gt;中的&lt;/strong&gt; user 表**来开启和关闭远程访问权限。&lt;/p&gt;
&lt;p&gt;如下所示：&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-5.png"&gt;&lt;/p&gt;
&lt;p&gt;MySQL 是通过用户名（user）和客户端ip（host）来唯一确定一个用户。&lt;code&gt;host&lt;/code&gt; 字段指定了允许用户连接的主机，它与 &lt;code&gt;user&lt;/code&gt; 字段一起组成一个用户账户的唯一标识（即 &lt;code&gt;'user'@'host'&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;也就是说，可以设置同一个用户名在不同的客户端登陆时的密码不同，登陆后的权限也不同。通过查看mysql.user的表结构也可以看出，host和user是作为联合主键存在的。&lt;/p&gt;
&lt;p&gt;所以说，我们只要修改相应的 host 字段就可以开启和关闭远程访问权限。host字段的常见值如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;localhost&lt;/code&gt;&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;表示用户只能从本地主机（即 MySQL 服务器所在的机器）连接。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;例如：&lt;code&gt;'root'@'localhost'&lt;/code&gt; 表示用户 &lt;code&gt;root&lt;/code&gt; 只能从本地连接。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;%&lt;/code&gt;&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;表示用户可以从任意主机连接。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;例如：&lt;code&gt;'user'@'%'&lt;/code&gt; 表示用户 &lt;code&gt;user&lt;/code&gt; 可以从任何 IP 地址或主机名连接。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;具体的 IP 地址或主机名&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;表示用户只能从指定的 IP 地址或主机名连接。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;例如：&lt;code&gt;'user'@'192.168.1.100'&lt;/code&gt; 表示用户 &lt;code&gt;user&lt;/code&gt; 只能从 IP 地址 &lt;code&gt;192.168.1.100&lt;/code&gt; 连接。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;127.0.0.1&lt;/code&gt;&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;表示用户只能从本地主机的环回接口（即 &lt;code&gt;localhost&lt;/code&gt; 的 IP 形式）连接。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;例如：&lt;code&gt;'user'@'127.0.0.1'&lt;/code&gt; 表示用户 &lt;code&gt;user&lt;/code&gt; 只能从 &lt;code&gt;127.0.0.1&lt;/code&gt; 连接。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;在修改 &lt;code&gt;mysql.user&lt;/code&gt; 表后，我们运行 &lt;code&gt;FLUSH PRIVILEGES;&lt;/code&gt; 命令就可以使更改生效。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;更多关于 host 字段的知识如下：&lt;/p&gt;
&lt;h2 id="补充资料"&gt;&lt;a href="#%e8%a1%a5%e5%85%85%e8%b5%84%e6%96%99" class="header-anchor"&gt;&lt;/a&gt;补充资料
&lt;/h2&gt;&lt;p&gt;在 MySQL 中，&lt;code&gt;mysql.user&lt;/code&gt; 表存储了用户账户和权限信息，其中 &lt;code&gt;host&lt;/code&gt; 字段是一个非常重要的字段，它决定了用户可以从哪些主机连接到 MySQL 服务器。&lt;/p&gt;
&lt;h3 id="mysqluser-表中的-host-字段"&gt;&lt;a href="#mysqluser-%e8%a1%a8%e4%b8%ad%e7%9a%84-host-%e5%ad%97%e6%ae%b5" class="header-anchor"&gt;&lt;/a&gt;&lt;code&gt;mysql.user&lt;/code&gt; 表中的 &lt;code&gt;host&lt;/code&gt; 字段
&lt;/h3&gt;&lt;h4 id="1-host"&gt;&lt;a href="#1-host" class="header-anchor"&gt;&lt;/a&gt;1. &lt;strong&gt;&lt;code&gt;host&lt;/code&gt; 字段的作用&lt;/strong&gt;
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;host&lt;/code&gt; 字段指定了允许用户连接的主机。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;它与 &lt;code&gt;user&lt;/code&gt; 字段一起组成一个用户账户的唯一标识（即 &lt;code&gt;'user'@'host'&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MySQL 通过 &lt;code&gt;user&lt;/code&gt; 和 &lt;code&gt;host&lt;/code&gt; 字段的组合来判断用户是否有权限连接到服务器。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="2-host"&gt;&lt;a href="#2-host" class="header-anchor"&gt;&lt;/a&gt;2. &lt;strong&gt;&lt;code&gt;host&lt;/code&gt; 字段的常见值&lt;/strong&gt;
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;localhost&lt;/code&gt;&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;表示用户只能从本地主机（即 MySQL 服务器所在的机器）连接。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;例如：&lt;code&gt;'root'@'localhost'&lt;/code&gt; 表示用户 &lt;code&gt;root&lt;/code&gt; 只能从本地连接。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;%&lt;/code&gt;&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;表示用户可以从任意主机连接。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;例如：&lt;code&gt;'user'@'%'&lt;/code&gt; 表示用户 &lt;code&gt;user&lt;/code&gt; 可以从任何 IP 地址或主机名连接。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;具体的 IP 地址或主机名&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;表示用户只能从指定的 IP 地址或主机名连接。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;例如：&lt;code&gt;'user'@'192.168.1.100'&lt;/code&gt; 表示用户 &lt;code&gt;user&lt;/code&gt; 只能从 IP 地址 &lt;code&gt;192.168.1.100&lt;/code&gt; 连接。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;127.0.0.1&lt;/code&gt;&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;表示用户只能从本地主机的环回接口（即 &lt;code&gt;localhost&lt;/code&gt; 的 IP 形式）连接。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;例如：&lt;code&gt;'user'@'127.0.0.1'&lt;/code&gt; 表示用户 &lt;code&gt;user&lt;/code&gt; 只能从 &lt;code&gt;127.0.0.1&lt;/code&gt; 连接。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="3-host"&gt;&lt;a href="#3-host" class="header-anchor"&gt;&lt;/a&gt;3. &lt;strong&gt;&lt;code&gt;host&lt;/code&gt; 字段的匹配规则&lt;/strong&gt;
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;MySQL 在验证用户连接时，会按照以下顺序匹配 &lt;code&gt;host&lt;/code&gt; 字段：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;精确匹配（例如 &lt;code&gt;'user'@'192.168.1.100'&lt;/code&gt;）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;通配符匹配（例如 &lt;code&gt;'user'@'%'&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果找不到匹配的记录，连接会被拒绝。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果有多个匹配的记录，MySQL 会选择最具体的一个。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;例如，&lt;code&gt;'user'@'192.168.1.100'&lt;/code&gt; 比 &lt;code&gt;'user'@'%'&lt;/code&gt; 更具体，因此会优先匹配。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="4-修改"&gt;&lt;a href="#4-%e4%bf%ae%e6%94%b9" class="header-anchor"&gt;&lt;/a&gt;4. &lt;strong&gt;修改 &lt;code&gt;host&lt;/code&gt; 字段&lt;/strong&gt;
&lt;/h4&gt;&lt;p&gt;如果需要修改用户的 &lt;code&gt;host&lt;/code&gt; 字段，可以使用以下 SQL 语句：&lt;/p&gt;
&lt;h5 id="修改用户的-host-值"&gt;&lt;a href="#%e4%bf%ae%e6%94%b9%e7%94%a8%e6%88%b7%e7%9a%84-host-%e5%80%bc" class="header-anchor"&gt;&lt;/a&gt;修改用户的 &lt;code&gt;host&lt;/code&gt; 值
&lt;/h5&gt;&lt;p&gt;UPDATE mysql.user SET host = &amp;lsquo;新的host值&amp;rsquo; WHERE user = &amp;lsquo;用户名&amp;rsquo; AND host = &amp;lsquo;旧的host值&amp;rsquo;;
FLUSH PRIVILEGES;&lt;/p&gt;
&lt;p&gt;例如，将用户 &lt;code&gt;user&lt;/code&gt; 的 &lt;code&gt;host&lt;/code&gt; 从 &lt;code&gt;localhost&lt;/code&gt; 改为 &lt;code&gt;%&lt;/code&gt;：&lt;/p&gt;
&lt;p&gt;UPDATE mysql.user SET host = &amp;lsquo;%&amp;rsquo; WHERE user = &amp;lsquo;user&amp;rsquo; AND host = &amp;rsquo;localhost&amp;rsquo;;
FLUSH PRIVILEGES;&lt;/p&gt;
&lt;h5 id="创建新用户时指定-host"&gt;&lt;a href="#%e5%88%9b%e5%bb%ba%e6%96%b0%e7%94%a8%e6%88%b7%e6%97%b6%e6%8c%87%e5%ae%9a-host" class="header-anchor"&gt;&lt;/a&gt;创建新用户时指定 &lt;code&gt;host&lt;/code&gt;
&lt;/h5&gt;&lt;p&gt;CREATE USER &amp;lsquo;用户名&amp;rsquo;@&amp;lsquo;host值&amp;rsquo; IDENTIFIED BY &amp;lsquo;密码&amp;rsquo;;&lt;/p&gt;
&lt;p&gt;例如，创建一个用户 &lt;code&gt;user&lt;/code&gt;，允许从任意主机连接：&lt;/p&gt;
&lt;p&gt;CREATE USER &amp;lsquo;user&amp;rsquo;@&amp;rsquo;%&amp;rsquo; IDENTIFIED BY &amp;lsquo;password&amp;rsquo;;&lt;/p&gt;
&lt;h4 id="5-查看"&gt;&lt;a href="#5-%e6%9f%a5%e7%9c%8b" class="header-anchor"&gt;&lt;/a&gt;5. &lt;strong&gt;查看 &lt;code&gt;mysql.user&lt;/code&gt; 表中的 &lt;code&gt;host&lt;/code&gt; 字段&lt;/strong&gt;
&lt;/h4&gt;&lt;p&gt;可以运行以下 SQL 语句查看 &lt;code&gt;mysql.user&lt;/code&gt; 表中的 &lt;code&gt;host&lt;/code&gt; 字段：&lt;/p&gt;
&lt;p&gt;SELECT user, host FROM mysql.user;&lt;/p&gt;
&lt;p&gt;输出示例：&lt;/p&gt;
&lt;p&gt;+&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;+&amp;mdash;&amp;mdash;&amp;mdash;&amp;ndash;+
| user | host |
+&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;+&amp;mdash;&amp;mdash;&amp;mdash;&amp;ndash;+
| root | localhost |
| user | % |
| testuser | 192.168.1.100 |
+&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;&amp;mdash;+&amp;mdash;&amp;mdash;&amp;mdash;&amp;ndash;+&lt;/p&gt;
&lt;h4 id="6-注意事项"&gt;&lt;a href="#6-%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9" class="header-anchor"&gt;&lt;/a&gt;6. &lt;strong&gt;注意事项&lt;/strong&gt;
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;安全性&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用 &lt;code&gt;%&lt;/code&gt; 允许从任意主机连接时，可能会增加安全风险。建议仅在必要时使用，并确保设置强密码。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;权限刷新&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;修改 &lt;code&gt;mysql.user&lt;/code&gt; 表后，必须运行 &lt;code&gt;FLUSH PRIVILEGES;&lt;/code&gt; 以使更改生效。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;备份&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在修改 &lt;code&gt;mysql.user&lt;/code&gt; 表之前，建议备份数据，以防止误操作。&lt;/p&gt;
&lt;h3 id="总结"&gt;&lt;a href="#%e6%80%bb%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;总结
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;mysql.user&lt;/code&gt; 表中的 &lt;code&gt;host&lt;/code&gt; 字段决定了用户可以从哪些主机连接到 MySQL 服务器。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;常见的 &lt;code&gt;host&lt;/code&gt; 值包括 &lt;code&gt;localhost&lt;/code&gt;、&lt;code&gt;%&lt;/code&gt;、具体的 IP 地址或主机名。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;可以通过 &lt;code&gt;UPDATE&lt;/code&gt; 语句修改 &lt;code&gt;host&lt;/code&gt; 字段，或通过 &lt;code&gt;CREATE USER&lt;/code&gt; 创建用户时指定 &lt;code&gt;host&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修改后需要运行 &lt;code&gt;FLUSH PRIVILEGES;&lt;/code&gt; 以使更改生效。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你有其他问题或需要进一步帮助，请告诉我！&lt;/p&gt;</description></item><item><title>从 Git 历史提交中删除文件</title><link>https://dandansad.com/2025/03/04/%E4%BB%8E-git-%E5%8E%86%E5%8F%B2%E6%8F%90%E4%BA%A4%E4%B8%AD%E5%88%A0%E9%99%A4%E6%96%87%E4%BB%B6/</link><pubDate>Tue, 04 Mar 2025 00:00:47 +0800</pubDate><guid>https://dandansad.com/2025/03/04/%E4%BB%8E-git-%E5%8E%86%E5%8F%B2%E6%8F%90%E4%BA%A4%E4%B8%AD%E5%88%A0%E9%99%A4%E6%96%87%E4%BB%B6/</guid><description>&lt;h1 id="注意"&gt;&lt;a href="#%e6%b3%a8%e6%84%8f" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;注意&lt;/strong&gt;！！！
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;亲测！！！两个方案都会在删除提交记录的同时把原文件删除！！！一定要记得备份文件再操作！！！如果仓库非常重要的话建议操作前备份整个仓库！！！&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id="方案一使用git-filter-repo工具"&gt;&lt;a href="#%e6%96%b9%e6%a1%88%e4%b8%80%e4%bd%bf%e7%94%a8git-filter-repo%e5%b7%a5%e5%85%b7" class="header-anchor"&gt;&lt;/a&gt;方案一：使用git filter-repo工具
&lt;/h1&gt;&lt;ol&gt;
&lt;li&gt;安装 git-filter-repo 工具&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pip install git-filter-repo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;运行命令删除example.txt文件提交记录，&amp;ndash;path后跟文件路径，如“src/main/resources/1.txt”&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git filter-repo --path example.txt --invert-paths
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="方案二使用git-filter-branch命令"&gt;&lt;a href="#%e6%96%b9%e6%a1%88%e4%ba%8c%e4%bd%bf%e7%94%a8git-filter-branch%e5%91%bd%e4%bb%a4" class="header-anchor"&gt;&lt;/a&gt;方案二：使用git filter-branch命令
&lt;/h1&gt;&lt;p&gt;运行命令删除example.txt文件提交记录，如果不在当前目录，请加上相对路径，如“src/main/resources/example.txt”：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git filter-branch --force --index-filter &amp;#39;git rm --cached --ignore-unmatch example.txt&amp;#39; --prune-empty --tag-name-filter cat -- --all
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="同步远程仓库"&gt;&lt;a href="#%e5%90%8c%e6%ad%a5%e8%bf%9c%e7%a8%8b%e4%bb%93%e5%ba%93" class="header-anchor"&gt;&lt;/a&gt;同步远程仓库
&lt;/h1&gt;&lt;p&gt;如果有远程 git 仓库，请在操作前先同步所有分支，删除文件后再执行以下命令。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;git push origin --force --all&lt;/code&gt;：强制推送所有分支。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;git push origin --force --tags&lt;/code&gt;：强制推送所有标签。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果有 fork 仓库的话，除了让 fork 仓库的所有人删除仓库，否则就没办法了。&lt;/p&gt;
&lt;h1 id="参考文章"&gt;&lt;a href="#%e5%8f%82%e8%80%83%e6%96%87%e7%ab%a0" class="header-anchor"&gt;&lt;/a&gt;参考文章
&lt;/h1&gt;&lt;p&gt;&lt;a class="link" href="https://geek-docs.com/git/git-questions/1694_git_git_how_to_remove_file_from_historical_commit.html" target="_blank" rel="noopener"
 &gt;Git Git: 如何从历史提交中删除文件|极客教程&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Linux 安装 MySQL 8.0.26</title><link>https://dandansad.com/2025/03/03/linux-%E5%AE%89%E8%A3%85-mysql-8-0-26/</link><pubDate>Mon, 03 Mar 2025 00:01:59 +0800</pubDate><guid>https://dandansad.com/2025/03/03/linux-%E5%AE%89%E8%A3%85-mysql-8-0-26/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;原文链接：&lt;a class="link" href="https://www.cnblogs.com/MrYoodb/p/15811199.html" target="_blank" rel="noopener"
 &gt;https://www.cnblogs.com/MrYoodb/p/15811199.html&lt;/a&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="1mysql-8026-下载"&gt;&lt;a href="#1mysql-8026-%e4%b8%8b%e8%bd%bd" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;1、MySQL 8.0.26 下载&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;官方网站下载 MySQL 8.0.26 安装包，下载地址：&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://downloads.mysql.com/archives/community" target="_blank" rel="noopener"
 &gt;https://downloads.mysql.com/archives/community&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;需要注意：Linux操作系统是32位还是64位，本案例采用Linux 64位操作系统进行讲解，通过wget命令下载安装包。&lt;/p&gt;
&lt;p&gt;使用df -lh命令查看，磁盘大小，尽量安装在比较大的磁盘下，防止空间不够使用。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos home]# df -lh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Filesystem Size Used Avail Use% Mounted on
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;devtmpfs 3.9G 0 3.9G 0% /dev
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tmpfs 3.9G 24K 3.9G 1% /dev/shm
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tmpfs 3.9G 604K 3.9G 1% /run
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/dev/vda1 50G 3.8G 44G 9% /
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tmpfs 783M 0 783M 0% /run/user/0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;通过上述命令可以看出根目录空间比较充足，那么就把安装包下载到home目录了，执行wget命令。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root&lt;span style="color:#960050;background-color:#1e0010"&gt;@&lt;/span&gt;VM&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;centos home]&lt;span style="color:#75715e"&gt;# wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;　　&lt;/p&gt;
&lt;h2 id="2解压缩文件"&gt;&lt;a href="#2%e8%a7%a3%e5%8e%8b%e7%bc%a9%e6%96%87%e4%bb%b6" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;2、解压缩文件&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;解压 mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz 文件，使用&lt;code&gt;tar -xvf mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz&lt;/code&gt; 命令。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos home]# tar -xvf mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql-8.0.26-linux-glibc2.12-x86_64/bin/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql-8.0.26-linux-glibc2.12-x86_64/bin/myisam_ftdump
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql-8.0.26-linux-glibc2.12-x86_64/bin/myisamchk
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql-8.0.26-linux-glibc2.12-x86_64/bin/myisamlog
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql-8.0.26-linux-glibc2.12-x86_64/bin/myisampack
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql-8.0.26-linux-glibc2.12-x86_64/bin/mysql
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;....
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql-8.0.26-linux-glibc2.12-x86_64/share/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql-8.0.26-linux-glibc2.12-x86_64/share/install_rewriter.sql
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql-8.0.26-linux-glibc2.12-x86_64/share/uninstall_rewriter.sql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="3移动文件"&gt;&lt;a href="#3%e7%a7%bb%e5%8a%a8%e6%96%87%e4%bb%b6" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;3、移动文件&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;将压缩包移动到usr/local目录下，并重命名文件为mysql，使用&lt;code&gt;mv /home/mysql-8.0.26-linux-glibc2.12-x86_64 /usr/local/mysql&lt;/code&gt;命令。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos home]# mv mysql-8.0.26-linux-glibc2.12-x86_64 /usr/local/mysql
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos home]# cd /usr/local/mysql/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos mysql]# ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;bin docs include lib LICENSE man README share support-files
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos mysql]# cd ..
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos local]# ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;bin etc games include lib lib64 libexec mysql qcloud sbin share src yd.socket.server
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos local]#
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;　　&lt;/p&gt;
&lt;h2 id="4创建数据存放目录"&gt;&lt;a href="#4%e5%88%9b%e5%bb%ba%e6%95%b0%e6%8d%ae%e5%ad%98%e6%94%be%e7%9b%ae%e5%bd%95" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;4、创建数据存放目录&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;在mysql根目录下新建一个目录data，主要用于存放数据库数据文件，使用&lt;code&gt;mkdir data&lt;/code&gt;命令。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos local]# cd mysql/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos mysql]# mkdir data
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos mysql]# ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;bin data docs include lib LICENSE man README share support-files
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos mysql]#
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="5创建用户组和用户"&gt;&lt;a href="#5%e5%88%9b%e5%bb%ba%e7%94%a8%e6%88%b7%e7%bb%84%e5%92%8c%e7%94%a8%e6%88%b7" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;5、创建用户组和用户&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;创建mysql用户组和mysql用户，使用&lt;code&gt;groupadd mysql&lt;/code&gt;和&lt;code&gt;useradd -g mysql mysql&lt;/code&gt;命令。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos mysql]# groupadd mysql
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos mysql]# useradd -g mysql mysql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="6改变mysql目录权限"&gt;&lt;a href="#6%e6%94%b9%e5%8f%98mysql%e7%9b%ae%e5%bd%95%e6%9d%83%e9%99%90" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;6、改变mysql目录权限&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;修改mysql目录权限，可以使用&lt;code&gt;chown -R mysql.mysql /usr/local/mysql/&lt;/code&gt;命令。&lt;/p&gt;
&lt;p&gt;修改mysql目录权限也可以通过&lt;code&gt;chown -R mysql .&lt;/code&gt;和&lt;code&gt;chgrp -R mysql .&lt;/code&gt;两个命令。注意：这两个命令都需要执行的，还有那个点不要忽视掉。&lt;/p&gt;
&lt;h2 id="7数据库初始化"&gt;&lt;a href="#7%e6%95%b0%e6%8d%ae%e5%ba%93%e5%88%9d%e5%a7%8b%e5%8c%96" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;7、数据库初始化&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;数据库初始化&lt;code&gt;./bin/mysqld --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --initialize&lt;/code&gt;命令，得到临时密码。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-2-centos mysql]# ./bin/mysqld --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --initialize
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2022-01-16T07:32:18.729960Z 0 [Warning] [MY-011070] [Server] &amp;#39;Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it&amp;#39; is deprecated and will be removed in a future release.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2022-01-16T07:32:18.729960Z 0 [System] [MY-013169] [Server] /usr/local/mysql/bin/mysqld (mysqld 8.0.26) initializing of server in progress as process 7691
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2022-01-16T07:32:18.740975Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2022-01-16T07:32:19.800287Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2022-01-16T07:32:21.721672Z 0 [Warning] [MY-013746] [Server] A deprecated TLS version TLSv1 is enabled for channel mysql_main
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2022-01-16T07:32:21.722106Z 0 [Warning] [MY-013746] [Server] A deprecated TLS version TLSv1.1 is enabled for channel mysql_main
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2022-01-16T07:32:21.787669Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: j-6lA2aXv=Pz
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;需要注意：记录一下mysql数据库的临时密码 j-6lA2aXv=Pz，后面安装步骤是需要使用的，否则需要重新安装数据库或其他方式获取密码，此处问题省略。&lt;/p&gt;
&lt;h2 id="8修改mycnf文件"&gt;&lt;a href="#8%e4%bf%ae%e6%94%b9mycnf%e6%96%87%e4%bb%b6" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;8、修改my.cnf文件&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;修改my.cnf文件，使用&lt;code&gt;vi /etc/my.cnf&lt;/code&gt;命令。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[mysqld]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; basedir &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;local&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; datadir &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;local&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;/&lt;/span&gt;data
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; socket &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;local&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sock
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; character&lt;span style="color:#f92672"&gt;-&lt;/span&gt;set&lt;span style="color:#f92672"&gt;-&lt;/span&gt;server&lt;span style="color:#f92672"&gt;=&lt;/span&gt;utf8
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; port &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3306&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sql_mode&lt;span style="color:#f92672"&gt;=&lt;/span&gt;NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [client]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; socket &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;local&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sock
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; default&lt;span style="color:#f92672"&gt;-&lt;/span&gt;character&lt;span style="color:#f92672"&gt;-&lt;/span&gt;set&lt;span style="color:#f92672"&gt;=&lt;/span&gt;utf8
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#[mysqld]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#datadir=/var/lib/mysql&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#socket=/var/lib/mysql/mysql.sock&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Disabling symbolic-links is recommended to prevent assorted security risks&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#symbolic-links=0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Settings user and group are ignored when systemd is used.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# If you need to run mysqld under a different user or group,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# customize your systemd unit file for mariadb according to the&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# instructions in http://fedoraproject.org/wiki/Systemd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#[mysqld_safe]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#log-error=/var/log/mariadb/mariadb.log&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#pid-file=/var/run/mariadb/mariadb.pid&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# include all files from the config directory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!includedir /etc/my.cnf.d&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;直接将上述配置内容复制到my.cnf文件中，或者自行修改，然后执行&lt;code&gt;:wq&lt;/code&gt;命令，保存并退出。&lt;/p&gt;
&lt;h2 id="9创建mysql服务"&gt;&lt;a href="#9%e5%88%9b%e5%bb%bamysql%e6%9c%8d%e5%8a%a1" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;9、创建mysql服务&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;1）将mysql.server启动文件复制到/etc/init.d目录，使用&lt;code&gt;cp -a /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld&lt;/code&gt;命令。&lt;/p&gt;
&lt;p&gt;2）赋予权限，使用&lt;code&gt;chmod +x /etc/rc.d/init.d/mysqld&lt;/code&gt;命令；&lt;/p&gt;
&lt;p&gt;3）使用&lt;code&gt;chkconfig --add mysqld&lt;/code&gt;创建mysql服务。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos mysql]# cp -a /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos mysql]# chmod +x /etc/rc.d/init.d/mysqld
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos mysql]# chkconfig --add mysqld
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;检查mysql服务是否生效，使用&lt;code&gt;chkconfig --list mysqld&lt;/code&gt;命令。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos mysql]# chkconfig --list mysqld
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Note: This output shows SysV services only and does not include native
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; systemd services. SysV configuration data might be overridden by native
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; systemd configuration.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; If you want to list systemd services use &amp;#39;systemctl list-unit-files&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; To see services enabled on particular target use
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#39;systemctl list-dependencies [target]&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysqld 0:off 1:off 2:on 3:on 4:on 5:on 6:off
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;　　&lt;/p&gt;
&lt;h2 id="10配置全局环境变量"&gt;&lt;a href="#10%e9%85%8d%e7%bd%ae%e5%85%a8%e5%b1%80%e7%8e%af%e5%a2%83%e5%8f%98%e9%87%8f" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;10、配置全局环境变量&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;编辑/etc/profile文件，使用&lt;code&gt;vi /etc/profile&lt;/code&gt;命令，在profile文件中添加如下两行配置，使用&lt;code&gt;:wq&lt;/code&gt;命令保存后退出。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; PATH&lt;span style="color:#f92672"&gt;=$&lt;/span&gt;PATH:&lt;span style="color:#f92672"&gt;/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;local&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;/&lt;/span&gt;bin:&lt;span style="color:#f92672"&gt;/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;local&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;/&lt;/span&gt;lib
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; PATH
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;设置环境变量立即生效使用&lt;code&gt;source /etc/profile&lt;/code&gt;命令。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos ~]# source /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos ~]#
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;　　&lt;/p&gt;
&lt;h2 id="11启动mysql服务"&gt;&lt;a href="#11%e5%90%af%e5%8a%a8mysql%e6%9c%8d%e5%8a%a1" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;11、启动mysql服务&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;启动mysql服务，使用&lt;code&gt;service mysql start&lt;/code&gt;命令；使用&lt;code&gt;service mysql status&lt;/code&gt;命令，查看是否启动成功。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root&lt;span style="color:#960050;background-color:#1e0010"&gt;@&lt;/span&gt;VM&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;centos &lt;span style="color:#f92672"&gt;~&lt;/span&gt;]&lt;span style="color:#75715e"&gt;# service mysql start&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Redirecting to &lt;span style="color:#f92672"&gt;/&lt;/span&gt;bin&lt;span style="color:#f92672"&gt;/&lt;/span&gt;systemctl start mysql&lt;span style="color:#f92672"&gt;.&lt;/span&gt;service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root&lt;span style="color:#960050;background-color:#1e0010"&gt;@&lt;/span&gt;VM&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;centos &lt;span style="color:#f92672"&gt;~&lt;/span&gt;]&lt;span style="color:#75715e"&gt;# service mysql status&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Redirecting to &lt;span style="color:#f92672"&gt;/&lt;/span&gt;bin&lt;span style="color:#f92672"&gt;/&lt;/span&gt;systemctl status mysql&lt;span style="color:#f92672"&gt;.&lt;/span&gt;service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;●&lt;/span&gt; mysqld&lt;span style="color:#f92672"&gt;.&lt;/span&gt;service &lt;span style="color:#f92672"&gt;-&lt;/span&gt; LSB: start &lt;span style="color:#f92672"&gt;and&lt;/span&gt; stop MySQL
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Loaded: loaded (&lt;span style="color:#f92672"&gt;/&lt;/span&gt;etc&lt;span style="color:#f92672"&gt;/&lt;/span&gt;rc&lt;span style="color:#f92672"&gt;.&lt;/span&gt;d&lt;span style="color:#f92672"&gt;/&lt;/span&gt;init&lt;span style="color:#f92672"&gt;.&lt;/span&gt;d&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysqld; bad; vendor preset: disabled)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Active: active (running) since Sun &lt;span style="color:#ae81ff"&gt;2022&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;01&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;16&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;55&lt;/span&gt; CST; &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;s ago
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Docs: man:systemd&lt;span style="color:#f92672"&gt;-&lt;/span&gt;sysv&lt;span style="color:#f92672"&gt;-&lt;/span&gt;generator(&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Process: &lt;span style="color:#ae81ff"&gt;27231&lt;/span&gt; ExecStart&lt;span style="color:#f92672"&gt;=/&lt;/span&gt;etc&lt;span style="color:#f92672"&gt;/&lt;/span&gt;rc&lt;span style="color:#f92672"&gt;.&lt;/span&gt;d&lt;span style="color:#f92672"&gt;/&lt;/span&gt;init&lt;span style="color:#f92672"&gt;.&lt;/span&gt;d&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysqld start (code&lt;span style="color:#f92672"&gt;=&lt;/span&gt;exited, status&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;SUCCESS)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; CGroup: &lt;span style="color:#f92672"&gt;/&lt;/span&gt;system&lt;span style="color:#f92672"&gt;.&lt;/span&gt;slice&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysqld&lt;span style="color:#f92672"&gt;.&lt;/span&gt;service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├─&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;27242&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt;bin&lt;span style="color:#f92672"&gt;/&lt;/span&gt;sh &lt;span style="color:#f92672"&gt;/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;local&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;/&lt;/span&gt;bin&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysqld_safe &lt;span style="color:#f92672"&gt;--&lt;/span&gt;datadir&lt;span style="color:#f92672"&gt;=/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;local&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;/&lt;/span&gt;data &lt;span style="color:#f92672"&gt;--&lt;/span&gt;pid&lt;span style="color:#f92672"&gt;-&lt;/span&gt;file&lt;span style="color:#f92672"&gt;=/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;local&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;/&lt;/span&gt;data&lt;span style="color:#f92672"&gt;/&lt;/span&gt;VM&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;centos&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pid
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└─&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;27408&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;local&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;/&lt;/span&gt;bin&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysqld &lt;span style="color:#f92672"&gt;--&lt;/span&gt;basedir&lt;span style="color:#f92672"&gt;=/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;local&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql &lt;span style="color:#f92672"&gt;--&lt;/span&gt;datadir&lt;span style="color:#f92672"&gt;=/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;local&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;/&lt;/span&gt;data &lt;span style="color:#f92672"&gt;--&lt;/span&gt;plugin&lt;span style="color:#f92672"&gt;-&lt;/span&gt;dir&lt;span style="color:#f92672"&gt;=/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;local&lt;span style="color:#f92672"&gt;/&lt;/span&gt;mysql&lt;span style="color:#f92672"&gt;/&lt;/span&gt;lib&lt;span style="color:#f92672"&gt;/&lt;/span&gt;plugin &lt;span style="color:#f92672"&gt;--&lt;/span&gt;user&lt;span style="color:#f92672"&gt;=&lt;/span&gt;mysql &lt;span style="color:#f92672"&gt;--&lt;/span&gt;log&lt;span style="color:#f92672"&gt;-&lt;/span&gt;error&lt;span style="color:#f92672"&gt;=&lt;/span&gt;VM&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;cent&lt;span style="color:#f92672"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Jan &lt;span style="color:#ae81ff"&gt;16&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;54&lt;/span&gt; VM&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;centos systemd[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]: Starting LSB: start &lt;span style="color:#f92672"&gt;and&lt;/span&gt; stop MySQL&lt;span style="color:#f92672"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Jan &lt;span style="color:#ae81ff"&gt;16&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;54&lt;/span&gt; VM&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;centos mysqld[&lt;span style="color:#ae81ff"&gt;27231&lt;/span&gt;]: Starting MySQL&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Logging to &lt;span style="color:#e6db74"&gt;&amp;#39;/usr/local/mysql/data/VM-0-4-centos.err&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Jan &lt;span style="color:#ae81ff"&gt;16&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;55&lt;/span&gt; VM&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;centos mysqld[&lt;span style="color:#ae81ff"&gt;27231&lt;/span&gt;]: SUCCESS&lt;span style="color:#f92672"&gt;!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Jan &lt;span style="color:#ae81ff"&gt;16&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;55&lt;/span&gt; VM&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;centos systemd[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]: Started LSB: start &lt;span style="color:#f92672"&gt;and&lt;/span&gt; stop MySQL&lt;span style="color:#f92672"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;　　&lt;/p&gt;
&lt;h2 id="12登录mysql修改密码"&gt;&lt;a href="#12%e7%99%bb%e5%bd%95mysql%e4%bf%ae%e6%94%b9%e5%af%86%e7%a0%81" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;12、登录mysql修改密码&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;登录mysql数据库，使用&lt;code&gt;mysql -uroot -p&lt;/code&gt;密码命令，临时密码是j-6lA2aXv=Pz。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[root@VM-0-4-centos ~]# mysql -uroot -p
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Enter password:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Welcome to the MySQL monitor. Commands end with ; or \g.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Your MySQL connection id is 13
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Server version: 8.0.26
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Copyright (c) 2000, 2021, Oracle and/or its affiliates.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Oracle is a registered trademark of Oracle Corporation and/or its
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;affiliates. Other names may be trademarks of their respective
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;owners.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Type &amp;#39;help;&amp;#39; or &amp;#39;\h&amp;#39; for help. Type &amp;#39;\c&amp;#39; to clear the current input statement.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;修改mysql临时密码，也就是将第七步数据库初始化生成的临时密码修改成自己需要设置的密码。&lt;/p&gt;
&lt;p&gt;修改mysql数据库密码，使用&lt;code&gt;ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';&lt;/code&gt;命令。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql&amp;gt; ALTER USER &amp;#39;root&amp;#39;@&amp;#39;localhost&amp;#39; IDENTIFIED WITH mysql_native_password BY &amp;#39;123456&amp;#39;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Query OK, 0 rows affected (0.01 sec)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;注意：此处123456修改为自己的需要密码即可。&lt;/p&gt;
&lt;h2 id="13设置mysql远程登录"&gt;&lt;a href="#13%e8%ae%be%e7%bd%aemysql%e8%bf%9c%e7%a8%8b%e7%99%bb%e5%bd%95" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;13、设置mysql远程登录&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;1）切换数据库，使用&lt;code&gt;use mysql;&lt;/code&gt;命令。&lt;/p&gt;
&lt;p&gt;2）修改mysql库中host值，使用&lt;code&gt;update user set host='%' where user='root' limit 1;&lt;/code&gt;命令。&lt;/p&gt;
&lt;p&gt;3）刷新mysql权限，使用&lt;code&gt;flush privileges;&lt;/code&gt;命令。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql&amp;gt; use mysql;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Reading table information for completion of table and column names
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;You can turn off this feature to get a quicker startup with -A
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Database changed
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql&amp;gt; update user set host=&amp;#39;%&amp;#39; where user=&amp;#39;root&amp;#39; limit 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Query OK, 1 row affected (0.01 sec)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Rows matched: 1 Changed: 1 Warnings: 0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql&amp;gt; flush privileges;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Query OK, 0 rows affected (0.00 sec)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mysql&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;　　&lt;/p&gt;
&lt;h2 id="14mysql客户端连接数据库"&gt;&lt;a href="#14mysql%e5%ae%a2%e6%88%b7%e7%ab%af%e8%bf%9e%e6%8e%a5%e6%95%b0%e6%8d%ae%e5%ba%93" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;14、mysql客户端连接数据库&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;客户端连接mysql数据库，连接名（自定义名称）、主机（IP）、端口号及用户名和密码，点击测试连接按钮，显示连接成功即可。&lt;/p&gt;
&lt;p&gt;注意：若提示无法连接，需要测试服务器3306端口是否开放。若服务器端可以通过查看防火墙情况，此时方式验证省略；而从客户端测试可以使用“telnet IP 端口号”命令。&lt;/p&gt;</description></item><item><title>wordpress更改固定链接后网页出现404</title><link>https://dandansad.com/2025/03/02/wordpress%E6%9B%B4%E6%94%B9%E5%9B%BA%E5%AE%9A%E9%93%BE%E6%8E%A5%E5%90%8E%E7%BD%91%E9%A1%B5%E5%87%BA%E7%8E%B0404/</link><pubDate>Sun, 02 Mar 2025 01:08:09 +0800</pubDate><guid>https://dandansad.com/2025/03/02/wordpress%E6%9B%B4%E6%94%B9%E5%9B%BA%E5%AE%9A%E9%93%BE%E6%8E%A5%E5%90%8E%E7%BD%91%E9%A1%B5%E5%87%BA%E7%8E%B0404/</guid><description>&lt;h2 id="问题描述"&gt;&lt;a href="#%e9%97%ae%e9%a2%98%e6%8f%8f%e8%bf%b0" class="header-anchor"&gt;&lt;/a&gt;问题描述
&lt;/h2&gt;&lt;p&gt;在wordpress后台更改固定链接结构后网页出现404的情况。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-1024x502.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-1-1024x543.png"&gt;&lt;/p&gt;
&lt;h2 id="解决方法"&gt;&lt;a href="#%e8%a7%a3%e5%86%b3%e6%96%b9%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;解决方法
&lt;/h2&gt;&lt;p&gt;在宝塔后台打开网站设置，在&lt;a class="link" href="https://dandansad.com/2025/03/02/%e4%bc%aa%e9%9d%99%e6%80%81/" target="_blank" rel="noopener"
 &gt;伪静态&lt;/a&gt;中加入以下代码。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-2.png"&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;if (-f $request_filename/index.html){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rewrite (.*) $1/index.html break;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;if (-f $request_filename/index.php){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rewrite (.*) $1/index.php;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;if (!-f $request_filename){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rewrite (.*) /index.php;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="问题原理"&gt;&lt;a href="#%e9%97%ae%e9%a2%98%e5%8e%9f%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;问题原理
&lt;/h2&gt;
 &lt;blockquote&gt;
 &lt;ul&gt;
&lt;li&gt;With Nginx there is no directory-level configuration file like Apache’s .htaccess or IIS’s web.config files. All configuration has to be done at the server level by an administrator, and WordPress cannot modify the configuration, like it can with Apache or IIS.（Nginx没有像Apache的.htaccess或IIS的web.config文件那样的目录级配置文件。所有配置都必须由管理员在服务器级别完成，WordPress无法修改配置，就像Apache或IIS一样。）&lt;/li&gt;
&lt;/ul&gt;

 &lt;/blockquote&gt;

 &lt;blockquote&gt;
 &lt;ul&gt;
&lt;li&gt;Since Nginx does not have .htaccess-type capability and WordPress cannot automatically modify the server configuration for you, it cannot generate the rewrite rules for you.（由于Nginx没有. htaccess类型功能，WordPress无法自动为您修改服务器配置，因此无法为您生成重写规则。）&lt;/li&gt;
&lt;/ul&gt;

 &lt;/blockquote&gt;

 &lt;blockquote&gt;
 
 &lt;/blockquote&gt;
&lt;p&gt;如果你的服务器是 &lt;strong&gt;Nginx&lt;/strong&gt;，那么 WordPress 自动生成的 &lt;code&gt;.htaccess&lt;/code&gt; 文件 &lt;strong&gt;不会生效&lt;/strong&gt;，因为 Nginx 根本不支持 &lt;code&gt;.htaccess&lt;/code&gt; 文件。&lt;code&gt;.htaccess&lt;/code&gt; 是 Apache 服务器的配置文件，而 Nginx 使用的是完全不同的配置方式。由于 Nginx 并不支持&lt;code&gt;.htaccess&lt;/code&gt;文件，因此你需要手动在Nginx配置中添加重写规则。&lt;/p&gt;
&lt;p&gt;添加的Nginx服务器的重写规则，作用如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;检查是否存在&lt;code&gt;index.html&lt;/code&gt;&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;if (-f $request_filename/index.html){ rewrite (.*) $1/index.html break; }&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果请求的URL对应一个目录，并且该目录下存在&lt;code&gt;index.html&lt;/code&gt;文件，Nginx会将请求重写到该&lt;code&gt;index.html&lt;/code&gt;文件并停止进一步处理。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查是否存在&lt;code&gt;index.php&lt;/code&gt;&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;if (-f $request_filename/index.php){ rewrite (.*) $1/index.php; }&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果请求的URL对应一个目录，并且该目录下存在&lt;code&gt;index.php&lt;/code&gt;文件，Nginx会将请求重写到该&lt;code&gt;index.php&lt;/code&gt;文件。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;默认重写到&lt;code&gt;index.php&lt;/code&gt;&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;if (!-f $request_filename){ rewrite (.*) /index.php; }&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果请求的URL不对应任何实际存在的文件或目录，Nginx会将请求重写到&lt;code&gt;index.php&lt;/code&gt;。这是WordPress处理路由的关键部分，所有的请求都会被发送到&lt;code&gt;index.php&lt;/code&gt;，然后由WordPress根据URL决定显示哪个页面。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这段代码的核心是将所有不匹配实际文件的请求重写到&lt;code&gt;index.php&lt;/code&gt;。这正是WordPress处理固定链接的方式。WordPress通过&lt;code&gt;index.php&lt;/code&gt;解析URL并显示相应的内容。&lt;/p&gt;
&lt;p&gt;不加重写规则时，服务器会按照默认行为尝试直接访问与URL路径对应的文件或目录。由于WordPress的固定链接不对应实际文件，因此会返回404错误。重写规则的作用是告诉服务器：“将所有不匹配实际文件或目录的请求交给 &lt;code&gt;index.php&lt;/code&gt; 处理。” 这样，WordPress才能根据URL路径动态生成内容。&lt;/p&gt;
&lt;h2 id="参考文章"&gt;&lt;a href="#%e5%8f%82%e8%80%83%e6%96%87%e7%ab%a0" class="header-anchor"&gt;&lt;/a&gt;参考文章
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://blog.csdn.net/weixin_45871499/article/details/106536778" target="_blank" rel="noopener"
 &gt;【图文解释】解决wordpress更改固定链接后网页出现404；站点创建成功页面无法显示_wordpress搭建的本地网站出现网页暂时无法打开-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://developer.wordpress.org/advanced-administration/server/web-server/nginx/" target="_blank" rel="noopener"
 &gt;Nginx – Advanced Administration Handbook | Developer.WordPress.org&lt;/a&gt;&lt;/p&gt;</description></item><item><title>修改 Linux 终端命令行提示符颜色</title><link>https://dandansad.com/2025/02/26/%E4%BF%AE%E6%94%B9-linux-%E7%BB%88%E7%AB%AF%E5%91%BD%E4%BB%A4%E8%A1%8C%E6%8F%90%E7%A4%BA%E7%AC%A6%E9%A2%9C%E8%89%B2/</link><pubDate>Wed, 26 Feb 2025 02:14:45 +0800</pubDate><guid>https://dandansad.com/2025/02/26/%E4%BF%AE%E6%94%B9-linux-%E7%BB%88%E7%AB%AF%E5%91%BD%E4%BB%A4%E8%A1%8C%E6%8F%90%E7%A4%BA%E7%AC%A6%E9%A2%9C%E8%89%B2/</guid><description>&lt;h2 id="临时设置-ps1"&gt;&lt;a href="#%e4%b8%b4%e6%97%b6%e8%ae%be%e7%bd%ae-ps1" class="header-anchor"&gt;&lt;/a&gt;临时设置 &lt;code&gt;PS1&lt;/code&gt;
&lt;/h2&gt;&lt;p&gt;PS（Prompt Sign）命令提示符，PS1是Linux终端用户的一个环境变量，用来定义命令行提示符的参数。在设定PS1环境变量时，需要用到预设的一些参数来设定PS1。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;查看当前PS1的设置：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;echo $PS1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;设置PS1示例：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PS1='[\033[01;32m]\u@\h[\033[00m]\n[\033[01;34m]\w[\033[00m]\$'&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PS1的常用参数以及含义：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;\d ：代表日期，格式为weekday month date，例如：&amp;#34;Mon Aug 1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;\H ：完整的主机名称
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;\h ：仅取主机名中的第一个名字
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;\t ：显示时间为24小时格式，如：HH：MM：SS
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;\T ：显示时间为12小时格式
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;\A ：显示时间为24小时格式：HH：MM
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;\u ：当前用户的账号名称
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;\v ：BASH的版本信息
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;\w ：完整的工作目录名称
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;\W ：利用basename取得工作目录名称，只显示最后一个目录名
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;\# ：下达的第几个命令
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;\$ ：提示字符，如果是root用户，提示符为 # ，普通用户则为 $
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="修改-bashrc-文件"&gt;&lt;a href="#%e4%bf%ae%e6%94%b9-bashrc-%e6%96%87%e4%bb%b6" class="header-anchor"&gt;&lt;/a&gt;修改 &lt;code&gt;~/.bashrc&lt;/code&gt; 文件
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;如果 &lt;code&gt;~/.bashrc&lt;/code&gt; 文件中无内容&lt;/strong&gt;，则直接在 &lt;code&gt;~/.bashrc&lt;/code&gt; 文件中写入：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PS1='[\033[01;32m]\u@\h[\033[00m]\n[\033[01;34m]\w[\033[00m]\$'&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;然后运行：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;source ~/.bashrc&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果 &lt;code&gt;~/.bashrc&lt;/code&gt; 文件中已有内容&lt;/strong&gt;，则先打开 &lt;code&gt;.bashrc&lt;/code&gt; 文件，查看是否存在 &lt;code&gt;force_color_prompt=yes&lt;/code&gt; 行。然后，删除其前面的注释（&lt;code&gt;#&lt;/code&gt; 符号）并保存文件（如果该行存在）。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/02/image-1024x694.png"&gt;&lt;/p&gt;
&lt;p&gt;查找定义 &lt;code&gt;PS1&lt;/code&gt; 变量的行。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/02/image-1-1024x411.png"&gt;&lt;/p&gt;
&lt;p&gt;接下来定义新的 &lt;code&gt;PS1&lt;/code&gt; 变量。但是，为了安全起见，我们将其注释掉，这样如果我们搞砸了，我们可以随时参考它。&lt;/p&gt;
&lt;p&gt;然后，我们将通过添加以下行来创建一个新的 &lt;code&gt;PS1&lt;/code&gt; 变量，该变量会为您的 Linux 终端提示符着色。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;PS1=&amp;#39;\&amp;amp;#91;\033&amp;amp;#91;1;32m\]\u\&amp;amp;#91;\033&amp;amp;#91;1;37m\]@\&amp;amp;#91;\033&amp;amp;#91;1;36m\]\h\&amp;amp;#91;\033&amp;amp;#91;00m\]:\&amp;amp;#91;\033&amp;amp;#91;1;34m\]\w\&amp;amp;#91;\033&amp;amp;#91;00m\]\$ &amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/02/image-2-1024x410.png"&gt;&lt;/p&gt;
&lt;p&gt;然后运行：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;source ~/.bashrc&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="常见问题"&gt;&lt;a href="#%e5%b8%b8%e8%a7%81%e9%97%ae%e9%a2%98" class="header-anchor"&gt;&lt;/a&gt;常见问题
&lt;/h2&gt;&lt;p&gt;如果没有正常加载效果，则检查以下文件，确保它们没有覆盖 &lt;code&gt;PS1&lt;/code&gt;：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/profile&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;~/.bash_profile&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;~/.profile&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;~/.bash_aliases&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/bash.bashrc&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="参考配置"&gt;&lt;a href="#%e5%8f%82%e8%80%83%e9%85%8d%e7%bd%ae" class="header-anchor"&gt;&lt;/a&gt;参考配置
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;PS1=&amp;#39;\[\033[01;31m\]\u\[\033[01;33m\]@\[\033[01;32m\]\h\[\033[00m\] \[\033[01;36m\][\D{%Y-%m-%d} \t]\[\033[01;37m\] : \[\033[01;33m\]\w\[\033[00m\]\n\[\033[01;34m\]\$\[\033[00m\] &amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;PS1=&amp;#34;\[\033[01;31m\]\u\[\033[00m\]@\[\033[01;32m\]\h\[\033[00m\][\[\033[01;33m\]\t\[\033[00m\]]:\[\033[01;34m\]\w\[\033[00m\]\n$ &amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考文章"&gt;&lt;a href="#%e5%8f%82%e8%80%83%e6%96%87%e7%ab%a0" class="header-anchor"&gt;&lt;/a&gt;参考文章
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://blog.csdn.net/lingeio/article/details/94559587" target="_blank" rel="noopener"
 &gt;Linux命令行提示符颜色格式设置_kali命令提示符只有白色-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://cn.linux-console.net/?p=34438" target="_blank" rel="noopener"
 &gt;如何在 Linux 上更改 Bash Shell 提示符的颜色&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>