<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>匹配系统 on yafeiaa Blogs</title>
    <link>https://yafeiaa.github.io/tags/%E5%8C%B9%E9%85%8D%E7%B3%BB%E7%BB%9F/</link>
    <description>Recent content in 匹配系统 on yafeiaa Blogs</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 14 Jan 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://yafeiaa.github.io/tags/%E5%8C%B9%E9%85%8D%E7%B3%BB%E7%BB%9F/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Minimatch 轻量级匹配服务使用体验</title>
      <link>https://yafeiaa.github.io/posts/minimatch%E5%AD%A6%E4%B9%A0/</link>
      <pubDate>Wed, 14 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://yafeiaa.github.io/posts/minimatch%E5%AD%A6%E4%B9%A0/</guid>
      <description>&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;&#xA;&lt;p&gt;最近在一个项目中，了解到了minimatch这个轻量级匹配服务，并借助minimatch实现了简单的match-maker服务，进行了学习。&lt;/p&gt;&#xA;&lt;p&gt;在游戏服务器匹配场景中，Open Match 是一个成熟的解决方案，但它的架构相对复杂，需要部署多个 Kubernetes 组件。在本地开发、或者不希望额外管理open-match的复杂性，只想实现 match 核心逻辑，minimatch 是一个很好的选择。&lt;/p&gt;&#xA;&lt;h2 id=&#34;核心概念&#34;&gt;核心概念&lt;/h2&gt;&#xA;&lt;h3 id=&#34;1-frontend-服务&#34;&gt;1. Frontend 服务&lt;/h3&gt;&#xA;&lt;p&gt;Frontend 负责接收玩家的匹配请求，创建和管理 Ticket。每个 Ticket 包含玩家的搜索条件，如地区、等级、角色等。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 创建 Ticket&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ticket&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;pb&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Ticket&lt;/span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;SearchFields&lt;/span&gt;: &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;pb&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;SearchFields&lt;/span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;Tags&lt;/span&gt;: []&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Sprintf&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;region:%s&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;user&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Region&lt;/span&gt;),&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Sprintf&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;role:%s&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;user&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Role&lt;/span&gt;),&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;DoubleArgs&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;map&lt;/span&gt;[&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;]&lt;span style=&#34;color:#66d9ef&#34;&gt;float64&lt;/span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;: float64(&lt;span style=&#34;color:#a6e22e&#34;&gt;user&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Level&lt;/span&gt;),&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;2-backend-服务&#34;&gt;2. Backend 服务&lt;/h3&gt;&#xA;&lt;p&gt;Backend 是匹配的核心，它定期（每个 tick）从 Redis 获取活跃的 Tickets，执行匹配逻辑，并将匹配结果分配给 GameServer。&lt;/p&gt;&#xA;&lt;p&gt;Backend 包含三个关键组件：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;MatchProfile&lt;/strong&gt;：定义匹配规则，包括多个 Pool（匹配池），每个 Pool 可以设置过滤条件（如地区、等级范围）&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;MatchFunction&lt;/strong&gt;：实现具体的匹配算法，根据 Pool 中的 Tickets 生成 Match&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Assigner&lt;/strong&gt;：将匹配结果分配给 GameServer&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;3-匹配流程&#34;&gt;3. 匹配流程&lt;/h3&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;玩家请求 → Frontend 创建 Ticket → Redis 存储&#xA;                                    ↓&#xA;Backend 定时轮询（通过提前设置的tick） → 获取 Tickets → MatchFunction 匹配 → Assigner 分配 GameServer → 更新 Ticket 状态&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;实践与-agones-集成实现一个简单的match-maker&#34;&gt;实践：与 Agones 集成实现一个简单的match-maker&lt;/h2&gt;&#xA;&lt;h3 id=&#34;架构设计&#34;&gt;架构设计&lt;/h3&gt;&#xA;&lt;p&gt;我们将 minimatch 的 Frontend 和 Backend 集成到同一个服务中，通过 HTTP API 对外提供服务：&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
