我提交的概述
wall-eve是一个网络应用程序,旨在为在线游戏市场提供汇总数据。
快速介绍夏娃在线及其市场
eve Online是一种MMORPG,可提供API,允许第三方的开发人员获取游戏中的大量数据。它提供了一个很好的机会来构建我们可以与其他玩家分享的有趣应用程序。
游戏的核心之一,交易,拥有自己的终点点,我们可以在当前购买和销售的不同对象的价格获得订单。
市场在地区(您可以将其视为州或国家 /地区)分开,每个地区都包含很多人(例如城市),人们将在这里买卖。
这将带领我们在哪里?
希望构建市场工具的开发人员将主要与返回区域返回订单的端点相互作用。
问题在于,该端点不会按项目返回汇总数据,而是所有订单。这意味着您可能必须拉出超过300页的10000个条目,然后将它们汇总以与它们合作。
它可能有点乏味,因为它通常需要使用并发,一种能够与大量数据一起使用的语言。
因此,已经有一段时间了,因为我想知道是否不可能提供API,该API将返回已经汇总的数据,并有可能使用一些查询参数过滤。让我们看看Redis如何帮助我。
应用设计
基本设计很简单,我们需要定期从游戏提供的端点获取数据,因此我拥有最新的数据。然后,我只需要通过API提供数据,然后用用户在请求中输入的值过滤其输出。
使用此描述,我们已经定义了2个服务:
- 将显示数据的API
- 将获取区域数据的索引
即使这2个服务足够,我们也缺乏正确控制索引的能力。
让我们谈谈我想到的更复杂的设计。
夏娃在线的某些地区的交易速度缓慢,并且被许多交易者忽略了。这意味着,这些区域的数据不一定需要在游戏的主要市场后立即进行更新。这将有助于减少I/O。
我希望能够安排索引,因此我可以优先考虑将哪些区域迅速拉动,哪个区域将延迟更长的时间。出现了2个新服务:
- 将确定下一个索引时间的调度程序
- 一个延迟器将使延迟作业在队列中保持直到流程为止 我在这里提供了2个服务,因此他们可以彼此独立发展
但是我仍然有问题。我如何优先考虑索引哪个区域?
我需要能够确定哪个区域很重要,并且要做到这一点,我将简单地收听对API的呼叫。如果经常通过API访问区域,则表明需要保持数据更新。否则,我们可以延迟索引,人们不会注意到它。
这是另一个服务:
- 心跳会听听对API的电话并存储它们的呼叫,因此我们可以稍后使用
但是,这样做,如果有人将API称为索引速率缓慢的区域,那么他可能会有太长时间之前没有更新的数据。
如果需要,我需要能够赶上索引,因此,即使前几首单击包含旧数据,以下命中也将具有新的数据。这导致创建我们的最后一项服务:
- 刷新也将听取对API的电话的收听,并确定我们是否需要赶上数据
我现在有6个服务可以一起工作。
技术实施
我将需要使用一些Redis功能来使此服务共同起作用。这是服务的模式
及以下,对工作流程和服务之间的相互作用的描述。
1.索引
此服务会收听流indexationAdd
,一旦消息到达,将启动索引。
该任务可能有点慢,需要1或2分钟,因此索引器可以小组工作以更快地消耗流。
索引需要获取区域的所有订单,但还需要获取其他一些数据,例如该地区的名称,项目的名称和其他名称。感谢游戏的API,我们可以得到它们,但是为了减少I/O,我们将它们存储在Redis中,以便以后更快地访问它们。
完成后,索引将将数据存储到redis中。数据基本上是按项目和位置汇总的,我们保留最高的买入价格,最低的卖出价格以及所有其他额外数据。通过这样做,我们在其不同地点的所有项目都有价格。
要存储此数据,我们使用JSON堆栈,因此我们可以使用索引并稍后简化搜索。
我们还将这些条目的TTL设置为24小时。通过执行此操作,我们确定未更新的数据将从Redis中删除,并且在索引工作流程存在问题的情况下也充当过时的缓存。
最后,该服务将带有区域的事件发送到流indexationFinished
2.调度
调度程序收听事件发送到流indexationFinished
,一旦消息到达,它将确定在哪个时候开始给定区域的新索引。
为此,它将读取存储在与区域相关的时间表表中的数据,以计算何时到期新的索引。
对于此演示,我保持数学简单。但是,这个想法是,如果在过去的5分钟内有API的呼叫,则需要在5分钟内安排索引。如果在最后一个小时内有API的电话,则需要在10分钟内安排索引。否则,我们将其延迟1小时。
然后将此信息存储在分类的集合中,分数等于前面计算的时间戳。
3.延迟器
现在,我们在排序集中有一个任务,我们需要确定何时真正启动索引。由于集合中的数据用最低的时间戳进行排序,因此我可以使用第一个项目,看看是否正确启动索引的时间是正确的。
如果可以的话,延迟器将在流indexationAdd
中的区域发送一个事件,并从排序集中删除条目。
4. API
现在,背景任务正在运行,我们可以向API的用户显示汇总数据。
为此,我们提供了一个端点/market
,需要作为查询参数location
和接受其他查询参数来帮助过滤返回的数据。
//List of query parameters
location #regionName, systemName, locationName, regionId, systemId, locationId
minBuyPrice
maxBuyPrice
minSellPrice
maxSellPrice
这些条目将与REDIS的搜索引擎一起使用以下索引
FT.CREATE denormalizedOrdersIx
ON JSON
PREFIX 1 denormalizedOrders:
SCHEMA
$.regionId AS regionId NUMERIC
$.systemId AS systemId NUMERIC
$.locationId AS locationId NUMERIC
$.typeId AS typeId NUMERIC
$.buyPrice AS buyPrice NUMERIC
$.sellPrice AS sellPrice NUMERIC
$.buyVolume AS buyVolume NUMERIC
$.sellVolume AS sellVolume NUMERIC
$.locationName AS locationName TEXT
$.systemName AS systemName TEXT
$.regionName AS regionName TEXT
$.typeName AS typeName TEXT
$.locationNameConcat AS locationNameConcat TEXT
$.locationIdTags AS locationIdTags TAG SEPARATOR ","
// Search with query parameter location that is a string
FT.SEARCH denormalizedOrdersIdx @locationNameConcat:(Dodixie IX Moon 20) @buyPrice:[5000000.00 10000000] @sellPrice:[6000000 20000000] LIMIT 0 10000
// Search with query parameter location that is a number
FT.SEARCH denormalizedOrdersIdx @locationIdsTag:{60011866} @buyPrice:[5000000.00 10000000] @sellPrice:[6000000 20000000] LIMIT 0 10000
使用它,我们可以轻松地仅服务用户想要的数据。
如我们所见,查询参数位置接受字符串或数字。就像这样减少用户拥有他要搜索的区域,系统或位置的确切ID的需求。
每个称为API的人都会将带有区域的事件apiEvent
发布到Pub/sub。
5.心跳
此服务仅收听发表在apiEvent
中的事件,以保存到与该区域相关的时间表表中,当调用API时。
6.刷新
正如我们之前看到的,来自没有大量访问的区域的数据以缓慢的速度索引。
为了帮助减少这个问题,我看看一个地区是否需要追赶。
为此,我研究了调度程序创建的排序集indexationDelayed
,如果该区域存在分数(从现在接收到事件时)和接下来的5分钟。
。
如果没有,我将一个事件与该区域一起发送到流indexationCatchup
,以便调度程序可以安排新的索引。
为了防止太多的追赶,我还存储了10分钟内按要求对该区域的追赶
7.安排追赶
工作流程的这一部分也由调度程序制作。它也听到indexationCatchup
并收到事件后,我们直接在流indexationAdd
中创建一个条目,以便索引可以尽快启动。
提交类别:
微服务Mavens
使用的语言
golang
链接到代码
Wall-Eve
Wall-Eve is an API that provide aggregated data from the market of the game Eve-Online.
Eve-Online is a MMORPG where trading is an important aspect of the game. The developers provide a lot of endpoints to help the development of third parties tool but the endpoint for the market does not provide aggregated data, meaning that most of the developers creating market application have to pull the data, aggregate it and then work with it.
Wall-Eve is a possible solution to this problem. It aggregate the data and let people retrieve informations using the API exposed by this application. They even can filter using some query parameters.
The application will refresh the data regurarly to provide up-to-data informations.
概述视频(可选)
这是一个简短的视频,解释了该项目及其使用方式:
它如何工作
在dev.to上检查有关如何工作的详细帖子。
- 查看Redis OM,客户库,用于与Redis合作作为多模型数据库。
- 使用RedisInsight在Redis中可视化您的数据。
- 注册free Redis database。