<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>s1mple's blog</title>
        <link>https://s1mpleo.com</link>
        <description>Thoughts on Full-stack development, AI</description>
        <lastBuildDate>Tue, 30 Sep 2025 01:56:58 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>Feed for Node.js</generator>
        <language>zh-CN</language>
        <image>
            <title>s1mple's blog</title>
            <url>https://s1mpleo.com/favicon.png</url>
            <link>https://s1mpleo.com</link>
        </image>
        <copyright>All rights reserved 2025, Jago</copyright>
        <item>
            <title><![CDATA[使用Grafana监控服务器]]></title>
            <link>https://s1mpleo.com/blog/using-grafana</link>
            <guid>https://s1mpleo.com/blog/using-grafana</guid>
            <pubDate>Mon, 29 Sep 2025 00:43:03 GMT</pubDate>
            <description><![CDATA[在非 root 用户下安装和部署 Grafana 监控 CentOS 8]]></description>
            <content:encoded><![CDATA[<h2>监控原理</h2>
<p>node_exporter 会收集 CentOS 8 服务器的系统指标（如 CPU、内存、磁盘使用情况），并通过 Prometheus 将其暴露给 Grafana
<img src="/images/grafana-monitor.jpg" alt="Grafana监控原理">
由于没有 root 权限，我们将使用二进制包进行安装</p>
<h2>一、安装 node_exporter (在每一台被监控的 CentOS 8 上)</h2>
<ol>
<li>下载 node_exporter
访问 <a href="https://prometheus.io/download/#node_exporter">Prometheus 下载页面</a> 找到最新的 node_exporter for Linux amd64 的链接
在 CentOS 8 服务器上执行以下命令：</li>
</ol>
<pre><code class="language-bash">wget https://github.com/prometheus/node_exporter/releases/download/v1.9.1/node_exporter-1.9.1.linux-amd64.tar.gz
</code></pre>
<ol start="2">
<li>解压并运行</li>
</ol>
<pre><code class="language-bash">tar -xvf node_exporter-1.9.1.linux-amd64.tar.gz
cd node_exporter-1.9.1.linux-amd64
./node_exporter
# 或者在后台运行
nohup ./node_exporter &amp;
</code></pre>
<p><code>node_exporter</code> 默认运行在 <strong>9100</strong> 端口</p>
<h2>二、下载并安装 Prometheus (只需在一个监控服务器上安装)</h2>
<p>Prometheus 作为一个中间层，会定期从 <code>node_exporter</code> 拉取（scrape）监控数据并存储，然后 Grafana 再从 Prometheus 查询数据进行展示</p>
<ol>
<li>访问 <a href="https://prometheus.io/download/">Prometheus 官网下载页面</a>  获取最新的 Linux 版本链接</li>
</ol>
<p>使用<code>wget</code>命令下载并解压，步骤同上</p>
<ol start="2">
<li>配置 Prometheus</li>
</ol>
<p>编辑配置文件 <code>prometheus.yml</code>，文件的末尾有一个 <code>scrape_configs</code> 部分。默认情况下，它只监控 Prometheus 自己。</p>
<p>在 <code>scrape_configs</code> 下面<strong>添加一个新的 job</strong>，来监控 CentOS 8 服务器。假设被监控的 CentOS 8 服务器 IP 是 <code>192.168.1.100</code>，并且 <code>node_exporter</code> 在该服务器的 9100 端口上运行</p>
<pre><code class="language-yaml"># A scrape configuration containing exactly one endpoint to scrape:
# Here it&#39;s Prometheus itself.
scrape_configs:
  - job_name: &quot;prometheus&quot;
    static_configs:
      - targets: [&quot;localhost:9090&quot;]

  # 新增这个 job 来监控你的 CentOS 8 服务器
  - job_name: &quot;centos8-node&quot;
    # The scrape interval is how often Prometheus will poll the target.
    scrape_interval: 15s 
    static_configs:
      - targets: [&quot;192.168.1.100:9100&quot;] # &lt;--- 把这里换成你被监控服务器的 IP 和 node_exporter 端口
        labels:
          instance: &quot;CentOS8-Server-01&quot; # 可以给这个实例起个别名
</code></pre>
<p>如果你有多台服务器需要监控，可以在 <code>targets</code> 列表里继续添加，例如：<code>[&quot;192.168.1.100:9100&quot;, &quot;192.168.1.101:9100&quot;]</code></p>
<ol start="3">
<li>启动Prometheus</li>
</ol>
<pre><code class="language-bash">nohup ./prometheus --config.file=prometheus.yml &amp;
</code></pre>
<p><code>Prometheus </code> 默认运行在 <strong>9090</strong> 端口，访问 <code>http://&lt;监控服务器IP&gt;:9090/targets</code> 来检查 Prometheus 是否成功连接到了<code>node_exporter</code>。如果 &quot;State&quot; 显示为 &quot;UP&quot;，则表示一切正常</p>
<h2>三、下载并安装 Grafana (只需在一个监控服务器上安装)</h2>
<ol>
<li>下载解压流程同上，进入<code>bin</code>目录运行</li>
</ol>
<pre><code class="language-bash">cd grafana-10.1.5/bin
nohup ./grafana-server &amp;
</code></pre>
<ol start="2">
<li><p>访问 Grafana Web 界面</p>
<p> Grafana 默认运行在 <strong>3000</strong> 端口，访问 <code>http://&lt;服务器IP&gt;:3000</code></p>
<ul>
<li><strong>默认用户名</strong>：<code>admin</code></li>
<li><strong>默认密码</strong>：<code>admin</code></li>
</ul>
<p> 首次登录后，系统会提示修改密码</p>
</li>
<li><p>在 Grafana 中配置数据源和仪表盘</p>
<ul>
<li>添加 Prometheus 数据源</li>
</ul>
<ol>
<li><p>在左侧菜单中，点击齿轮图标 (Configuration) -&gt; <strong>Data Sources</strong>。</p>
</li>
<li><p>点击 <strong>Add data source</strong>。</p>
</li>
<li><p>选择 <strong>Prometheus</strong>。</p>
</li>
<li><p>在 <strong>HTTP</strong> -&gt; <strong>URL</strong> 字段中，填入 <code>http://localhost:9090</code> (Prometheus 默认的地址)。</p>
<p> <strong>一个更简单的临时方案（不推荐用于生产环境）：</strong> 如果不想单独安装 Prometheus，可以为每一台被监控的机器单独添加一个 Prometheus 数据源，URL 直接指向那台机器的 <code>node_exporter</code> 地址，例如 <code>http://&lt;被监控的CentOS8服务器IP&gt;:9100</code>。</p>
</li>
<li><p>点击 <strong>Save &amp; test</strong>。</p>
</li>
</ol>
<ul>
<li>导入 Node Exporter 仪表盘</li>
</ul>
<p> Grafana 社区有大量预置的仪表盘可供使用。</p>
<ol>
<li>在左侧菜单中，点击 “+” (Create) -&gt; <strong>Import</strong></li>
<li>在 <strong>Import via grafana.com</strong> 字段中，输入 <code>1860</code> (这是一个非常流行的 Node Exporter 仪表盘 ID)，<code>8919</code>也不错</li>
<li>点击 <strong>Load</strong></li>
<li>在下一个页面中，选择刚才创建的 Prometheus 数据源</li>
<li>点击 <strong>Import</strong>。</li>
</ol>
<p> 完成这些步骤后，应该就能在 Grafana 仪表盘上看到 CentOS 8 服务器的各项性能指标了</p>
</li>
</ol>
]]></content:encoded>
            <author>s1mplecode@yeah.net (Jago)</author>
        </item>
        <item>
            <title><![CDATA[什么是RPC]]></title>
            <link>https://s1mpleo.com/blog/what-is-rpc</link>
            <guid>https://s1mpleo.com/blog/what-is-rpc</guid>
            <pubDate>Sat, 20 Sep 2025 13:13:18 GMT</pubDate>
            <description><![CDATA[什么是RPC以及RPC的原理]]></description>
            <content:encoded><![CDATA[<h2>什么是 RPC？</h2>
<p>RPC（Remote Procedure Call） 即远程过程调用，通过名字我们就能看出 RPC 关注的是远程调用而非本地调用。</p>
<p>为什么要 RPC ？ 因为，两个不同的服务器上的服务提供的方法不在一个内存空间，所以，需要通过网络编程才能传递方法调用所需要的参数。并且，方法调用的结果也需要通过网络编程来接收。但是，如果我们自己手动网络编程来实现这个调用过程的话工作量是非常大的，因为，我们需要考虑底层传输方式（TCP 还是 UDP）、序列化方式等等方面。</p>
<p>RPC 能帮助我们做什么呢？  简单来说，通过 RPC 可以帮助我们调用远程计算机上某个服务的方法，这个过程就像调用本地方法一样简单。并且！我们不需要了解底层网络编程的具体细节。</p>
<p>举个例子：两个不同的服务 A、B 部署在两台不同的机器上，服务 A 如果想要调用服务 B 中的某个方法的话就可以通过 RPC 来做。</p>
<p>一言蔽之：RPC 的出现就是为了让你调用远程方法像调用本地方法一样简单。</p>
<h2>RPC 原理是什么？</h2>
<p>整个 RPC 的核心功能是由 5 个部分实现的：</p>
<ol>
<li>客户端（服务消费端） ：调用远程方法的一端。</li>
<li>客户端 Stub（桩） ： 这其实就是一代理类。代理类主要做的事情很简单，就是把你调用方法、类、方法参数等信息传递到服务端。</li>
<li>网络传输 ： 网络传输就是你要把你调用的方法的信息比如说参数啊这些东西传输到服务端，然后服务端执行完之后再把返回结果通过网络传输给你传输回来。网络传输的实现方式有很多种比如最基本的 Socket 或者性能以及封装更加优秀的 Netty（推荐）。</li>
<li>服务端 Stub（桩） ：这个桩就不是代理类了。我觉得理解为桩实际不太好，大家注意一下就好。这里的服务端 Stub 实际指的就是接收到客户端执行方法的请求后，去指定对应的方法然后返回结果给客户端的类。</li>
<li>服务端（服务提供端） ：提供远程方法的一端。</li>
</ol>
<p>具体原理图如下</p>
<p><img src="/images/RPC.jpg" alt="RPC原理图"></p>
<ol>
<li>服务消费端（client）以本地调用的方式调用远程服务；</li>
<li>客户端 Stub（client stub） 接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体（序列化）：RpcRequest；</li>
<li>客户端 Stub（client stub） 找到远程服务的地址，并将消息发送到服务提供端；</li>
<li>服务端 Stub（桩）收到消息将消息反序列化为 Java 对象: RpcRequest；</li>
<li>服务端 Stub（桩）根据RpcRequest中的类、方法、方法参数等信息调用本地的方法；</li>
<li>服务端 Stub（桩）得到方法执行结果并将组装成能够进行网络传输的消息体：RpcResponse（序列化）发送至消费方；</li>
<li>客户端 Stub（client stub）接收到消息并将消息反序列化为 Java 对象:RpcResponse ，这样也就得到了最终结果。over!</li>
</ol>
]]></content:encoded>
            <author>s1mplecode@yeah.net (Jago)</author>
        </item>
        <item>
            <title><![CDATA[问题记录]]></title>
            <link>https://s1mpleo.com/blog/issuerecord</link>
            <guid>https://s1mpleo.com/blog/issuerecord</guid>
            <pubDate>Wed, 27 Aug 2025 06:30:55 GMT</pubDate>
            <description><![CDATA[日常问题记录]]></description>
            <content:encoded><![CDATA[<h2>一、使用Slf4j并配置了logback.xml，控制台仍然不打印日志</h2>
<p>idea环境变量(Environment Variables), 添加：<code>LOG_CONSOLE_ENABLED=true</code></p>
<h2>二、Ignite执行Insert into语句报错：Failed to prepare update plan</h2>
<p>表中没有primary key，或者ignite.xml没有配置keyFieldName，导致primary key不是表中的字段，是_key: <code>&lt;property name=&quot;keyFieldName&quot; value=&quot;batchId&quot;/&gt;</code></p>
]]></content:encoded>
            <author>s1mplecode@yeah.net (Jago)</author>
        </item>
        <item>
            <title><![CDATA[博客部署]]></title>
            <link>https://s1mpleo.com/blog/blogdeploy</link>
            <guid>https://s1mpleo.com/blog/blogdeploy</guid>
            <pubDate>Wed, 27 Aug 2025 02:25:07 GMT</pubDate>
            <content:encoded><![CDATA[<p>在这里写你的文章内容...</p>
<h2>小标题</h2>
<p>文章正文内容。</p>
<h2>另一个小标题</h2>
<p>更多内容...</p>
<hr>
<blockquote>
<p>💡 <strong>提示</strong>: 记得更新文章的摘要和关键词以获得更好的 SEO 效果！</p>
</blockquote>
]]></content:encoded>
            <author>s1mplecode@yeah.net (Jago)</author>
        </item>
        <item>
            <title><![CDATA[s1mple头像]]></title>
            <link>https://s1mpleo.com/blog/s1mple</link>
            <guid>https://s1mpleo.com/blog/s1mple</guid>
            <pubDate>Wed, 27 Aug 2025 02:22:42 GMT</pubDate>
            <content:encoded><![CDATA[<p>在这里写你的文章内容...</p>
<h2>小标题</h2>
<p>文章正文内容。</p>
<h2>另一个小标题</h2>
<p>更多内容...</p>
<hr>
<blockquote>
<p>💡 <strong>提示</strong>: 记得更新文章的摘要和关键词以获得更好的 SEO 效果！</p>
</blockquote>
]]></content:encoded>
            <author>s1mplecode@yeah.net (Jago)</author>
        </item>
        <item>
            <title><![CDATA[博客模板使用介绍]]></title>
            <link>https://s1mpleo.com/blog/intro</link>
            <guid>https://s1mpleo.com/blog/intro</guid>
            <pubDate>Sat, 05 Apr 2025 13:10:00 GMT</pubDate>
            <description><![CDATA[这是一个 Nextjs 博客模板，本文会介绍这个模板的一些基本用法]]></description>
            <content:encoded><![CDATA[<p>这是一个 Nextjs 博客模板，本文会介绍这个模板的一些基本用法。</p>
<h2>1. 如何编写博客</h2>
<p>这个仓库的博客文件需要放在 <code>src/content/blog</code> 目录下，可以是 markdown 文件，也可以是 mdx 文件。</p>
<p>有以下这些元数据需要用户自行根据需要进行配置：</p>
<ul>
<li><code>title</code>: 博客标题</li>
<li><code>date</code>: 博客发布日期</li>
<li><code>updated</code>: 博客更新日期</li>
<li><code>keywords</code>: 博客关键词，优化 SEO</li>
<li><code>featured</code>: 是否放在首页</li>
<li><code>summary</code>: 博客摘要</li>
</ul>
<h2>2. 博客配置</h2>
<p>博客的所有配置都集中在 <code>src/lib/config.ts</code> 文件中，这样做的好处是：</p>
<ol>
<li>集中管理：所有配置都在一个文件中，方便维护和修改</li>
<li>类型安全：使用 TypeScript 可以获得类型检查和自动补全</li>
<li>复用性：避免重复的配置散落在各个文件中</li>
<li>一致性：确保所有地方使用相同的配置值</li>
</ol>
<h3>2.1 站点基本配置</h3>
<pre><code class="language-typescript">site: {
  title: &quot;你的博客标题&quot;,
  name: &quot;你的博客名称&quot;,
  description: &quot;博客描述&quot;,
  keywords: [&quot;关键词1&quot;, &quot;关键词2&quot;],
  url: &quot;https://你的域名.com&quot;,
  baseUrl: &quot;https://你的域名.com&quot;,
  image: &quot;https://你的域名.com/og-image.png&quot;,
  favicon: {
    ico: &quot;/favicon.ico&quot;,
    png: &quot;/favicon.png&quot;,
    svg: &quot;/favicon.svg&quot;,
    appleTouchIcon: &quot;/favicon.png&quot;,
  },
  manifest: &quot;/site.webmanifest&quot;,
}
</code></pre>
<p>这些配置用于：</p>
<ul>
<li>网站的基本信息展示</li>
<li>SEO 优化</li>
<li>浏览器标签页图标</li>
<li>社交媒体分享预览</li>
</ul>
<h3>2.2 作者信息配置</h3>
<pre><code class="language-typescript">author: {
  name: &quot;你的名字&quot;,
  email: &quot;你的邮箱&quot;,
  bio: &quot;个人简介&quot;,
}
</code></pre>
<p>作者信息会用于：</p>
<ul>
<li>首页展示</li>
<li>RSS 订阅源信息</li>
<li>博客文章的作者信息</li>
</ul>
<h3>2.3 社交媒体配置</h3>
<pre><code class="language-typescript">social: {
  github: &quot;https://github.com/你的用户名&quot;,
  x: &quot;https://x.com/你的用户名&quot;,
  xiaohongshu: &quot;https://www.xiaohongshu.com/user/profile/你的ID&quot;,
  wechat: &quot;你的微信二维码图片链接&quot;,
  buyMeACoffee: &quot;https://www.buymeacoffee.com/你的用户名&quot;,
}
</code></pre>
<p>这些链接会显示在：</p>
<ul>
<li>首页的社交媒体链接区域</li>
<li>导航栏的社交媒体图标</li>
</ul>
<h3>2.4 评论系统配置</h3>
<pre><code class="language-typescript">giscus: {
  repo: &quot;你的GitHub仓库名&quot;,
  repoId: &quot;仓库ID&quot;,
  categoryId: &quot;分类ID&quot;,
}
</code></pre>
<p>使用 Giscus 作为评论系统，需要：</p>
<ol>
<li>在 GitHub 上安装 Giscus 应用</li>
<li>在你的仓库中启用 Discussions</li>
<li>获取配置信息并填入这里</li>
</ol>
<h3>2.5 导航菜单配置</h3>
<pre><code class="language-typescript">navigation: {
  main: [
    { 
      title: &quot;文章&quot;, 
      href: &quot;/blog&quot;,
    },
    // 可以添加更多导航项
  ],
}
</code></pre>
<p>这里配置网站的导航菜单，支持：</p>
<ul>
<li>普通链接</li>
<li>带子菜单的下拉菜单</li>
</ul>
<h3>2.6 SEO 配置</h3>
<pre><code class="language-typescript">seo: {
  metadataBase: new URL(&quot;https://你的域名.com&quot;),
  alternates: {
    canonical: &#39;./&#39;,
  },
  openGraph: {
    type: &quot;website&quot; as const,
    locale: &quot;zh_CN&quot;,
  },
  twitter: {
    card: &quot;summary_large_image&quot; as const,
    creator: &quot;@你的推特用户名&quot;,
  },
}
</code></pre>
<p>这些配置用于：</p>
<ul>
<li>搜索引擎优化</li>
<li>社交媒体分享卡片</li>
<li>网站元数据</li>
</ul>
<h3>2.7 RSS 订阅配置</h3>
<pre><code class="language-typescript">rss: {
  title: &quot;你的博客标题&quot;,
  description: &quot;博客描述&quot;,
  feedLinks: {
    rss2: &quot;/rss.xml&quot;,
    json: &quot;/feed.json&quot;,
    atom: &quot;/atom.xml&quot;,
  },
}
</code></pre>
<p>这些配置用于生成：</p>
<ul>
<li>RSS 2.0 订阅源</li>
<li>JSON Feed</li>
<li>Atom 订阅源</li>
</ul>
<h2>3. 如何修改配置</h2>
<ol>
<li>打开 <code>src/lib/config.ts</code> 文件</li>
<li>根据你的需求修改相应的配置项</li>
<li>保存文件后，Next.js 会自动重新构建并应用新的配置</li>
</ol>
<p>注意事项：</p>
<ul>
<li>确保所有 URL 都是有效的</li>
<li>图片链接应该是可访问的</li>
<li>社交媒体链接要填写完整的 URL</li>
<li>配置修改后，建议检查网站的：<ul>
<li>首页展示</li>
<li>导航菜单</li>
<li>SEO 信息</li>
<li>社交媒体分享效果</li>
<li>RSS 订阅源</li>
</ul>
</li>
</ul>
<h2>4. 如何生成 RSS 订阅源</h2>
<p>修改 scripts/generate-rss.js 文件中的配置，然后运行：</p>
<pre><code class="language-bash">npm run generate-rss
</code></pre>
<h2>5. 如何生成 Sitemap</h2>
<p>修改 scripts/generate-sitemap.js 文件中的配置，然后运行：</p>
<pre><code class="language-bash">npm run generate-sitemap
</code></pre>
]]></content:encoded>
            <author>s1mplecode@yeah.net (Jago)</author>
        </item>
    </channel>
</rss>