2 分•作者: variety8675•9 天前
返回首页
最新
1 分•作者: Ashxius•9 天前
3 分•作者: fanf2•9 天前
1 分•作者: rustyconover•9 天前
1 分•作者: blagoysimandoff•9 天前
各位 HackerNews 的朋友们!
我最近为 ampledata(我的 AI 增强平台)添加了 API 和文档。这个想法很简单。给定一个表格中的一组行,你可以通过 API 调用 ampledata,它会运行一个工作流,通过搜索网络来丰富你选择的列,并提供引文和确切的来源。你可以将其视为一个带有引文的批量增强平台。
Ampledata 也是开源的,所以你可以随意自托管并使用你自己的 API 密钥。或者,如果你只是对这项技术感兴趣。
1 分•作者: momentmaker•9 天前
23 分•作者: wglb•9 天前
2 分•作者: bardhyliis•9 天前
各位 HN 的朋友们,我从零开始构建了一个游戏服务器编排器。作为一名独立开发者,我花了三年多的时间,每天近十个小时才最终完成它,我从 2023 年初开始着手。我现在 26 岁!
完成这个项目所需要研究的复杂性和技术细节,是我做梦也想不到的,但它确实完成了,这是我迄今为止最伟大的职业成就。
下面我将尝试介绍我的游戏服务器编排器的一些核心和最重要的功能。
1. **核心固定与 CCD 缓存对齐**
我研究并理解了 CPU 缓存的布局。我发现,如果我的游戏容器(使用 `docker run`)跨越不同的核心复杂芯片(CCD)或者与繁忙的邻居共享 SMT 同步线程,L3 缓存的颠簸会严重影响单核滴答效率。
然后,我使用 GRUB 将所有非游戏服务器进程严格固定在核心 0 和其 SMT 同步线程核心 12 上:
我禁用了 1000Hz 的定时器中断,以防止上下文切换,从而避免污染 L3 缓存。
我还将 RCU 卸载到核心 0 和 12,以避免对游戏容器产生任何微中断,将 100% 的性能留给游戏容器。
```
GRUB_CMDLINE_LINUX_DEFAULT="nomodeset isolcpus=1-11,13-23 nohz_full=1-11,13-23 rcu_nocbs=1-11,13-23"
```
至于游戏容器,正如我所提到的,我直接使用 `docker run`,因为 Swarm 是不必要的,而且实际上是糟糕的设计。我有一个编排器服务,它使用一个算法来计算哪个 CCD 核心最适合固定游戏服务器容器:
```
// Zen 4 核心复杂芯片 (CCD) 映射 (C#)
int siblingOffset = totalHardwareThreads / 2;
int coresPerCcd = siblingOffset / 2;
int getCcdId(int i) => ((i % siblingOffset) < coresPerCcd) ? 0 : 1;
int getSibling(int i) => (i < siblingOffset) ? (i + siblingOffset) : (i - siblingOffset);
```
我还设置内存限制和内存预留相等(`--memory == --memory-reservation`),以便内核将该 RAM 内存锁定为物理 RAM 并阻止交换使用,以避免“吵闹的邻居”问题。
正如您所见,编排器试图为游戏服务器找到性能最佳的线程,这意味着宿主机 CPU 会被碎片化。特别是对于这种情况,我有一个算法,可以在宿主机上模拟每个正在运行的游戏容器的最佳位置,然后动态地、实时地重新定位部分或全部容器,而无需重启容器或断开任何活动玩家的连接,使用:
```
docker update --cpuset-cpus="{cpuSet}" {containerName}
```
2. **eBPF/XDP + NFTABLES 利用以防止 DDoS 攻击**
由于游戏服务器经常受到 DDoS 攻击、机器人或其他攻击的轰炸,特别是因为各种原因,可能是所谓的“脚本小子”或者有时甚至是“输不起的玩家”,XD。
起初我尝试使用 UFW,但最终放弃了,因为它与 Docker 冲突,这一点我花了不少时间才意识到,因为我当时还在研究网络层的工作原理。
为了获得最佳保护,我决定为每个端口设置特定的连接速率限制。如果达到限制,我将使用黑名单,将攻击者的 IP 注册到其中,并设置一个特定的计时器,然后立即将这些被列入黑名单的 IP 注册到 eBPF 映射中。这些 IP 在禁令到期时会动态地从每个列表/映射中添加和删除。
不过,有一个 `AnonymousPipeClientStream` 的边缘情况,许多游戏有许多不同的模组和插件,这会增加数据包的速率。尽管我已尽力在默认速率限制规则中考虑到了这一点,但也允许游戏服务器所有者根据需要调整这些限制,类似于 Cloudflare 的方式,提供 4 种配置文件:标准、宽松、严格、攻击中。
我已经根据实际数据尽可能地优化了标准配置文件,它应该足以应对 99% 的服务器。其他配置文件可以在其他罕见情况下使用,例如用于大量模组的游戏服务器。
因此,DDoS 缓解的最佳方法是使用 nftables,并为每个游戏服务器端口设置限制,每个游戏端口都有 nftables 限制。
我还将 `rmem_max`/`wmem_max` 缓冲区增加到 16MB,这样特定的游戏容器线程在将映射数据直接注册到 RAM 时就不会阻塞。默认情况下,写入缓冲区非常小,大约 200KB。通过这样做,玩家滴答处理得更快。
由于用户需要管理游戏文件(上传/下载/编辑/删除等),我使用 fireqos 来优先处理游戏流量,这意味着游戏流量走“快车道”,并且永远不会因为客户端使用文件管理器进行操作而被限速,从而确保游戏保持无 ping 尖峰。
我还使用 TCP BBR 拥塞控制,而不是默认的 Linux CUBIC,后者未经优化,会导致“回弹”(rubber-banding),因为它假设游戏服务器和玩家之间存在丢包就一定是网络拥塞,结果降低了传输速度,从而导致延迟尖峰。
BBR 拥塞控制的作用是测量游戏服务器和玩家之间的实际带宽,并以玩家能够消耗的速度发送数据包,从而避免回弹。
我还使用 fq(公平队列),以避免单个游戏服务器所有者耗尽所有带宽,例如,当有人决定上传或下载大文件时。
```
# BBR 拥塞控制
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# UDP/TCP 缓冲区扩展
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
```
3. **SSR 缓存投毒解决方案**
为了避免 Angular SSR 缓存投毒,我有两个端点:`/graphql` - 公共的、只读的数据,直接缓存在 Cloudflare 上。此端点会立即拒绝任何认证头,通过拒绝整个请求,以防止缓存投毒并防止请求之间的任何状态共享。
第二个端点是 `/secure`,处理任何经过身份验证的数据,并且不缓存任何内容。此外,我所有的 Web 服务,如前端、API、数据库调用都使用我的私有 WireGuard 网格,增加了安全性。
此外,在 Node.js 的 SSR 过程中,我完全跳过了 TLS 握手,通过使用本地 Docker Swarm 网络直接访问我的 API,这增加了一点延迟。
-----
正如我所提到的,我是一名独立开发者,完全自费启动这个项目。我拥有两个裸金属节点,一个在欧洲,一个在美国中部。
今天,我的目标是在扩展之前,观察我的编排器在真实世界中的表现。因此,我邀请任何人通过使用我的免费试用版来启动一个游戏服务器,并尝试破坏我的系统。
如果有人愿意,可以直接访问 <a href="https://ray-hosting.com/en-US/free-trial" rel="nofollow">https://ray-hosting.com/en-US/free-trial</a> 注册以自动获得免费试用。它需要信用卡,仅用于防止滥用。或者,如果您不想提供信用卡(这是可以理解的),在我从我的管理面板直接为您启动试用后,您可以在注册后进行测试。只需在此处留下评论,我今天会关注此帖子。我非常希望听到关于架构、部署速度或您想讨论的任何其他方面的诚实想法和意见。
附注:我不是以英语为母语的人,所以写这个花了我很多时间,哈哈。另外,我的平台还有很多东西可以讲,但现在我有点累了。哈哈,非常感谢您的阅读。
1 分•作者: gtzi•9 天前
1 分•作者: andsoitis•9 天前
1 分•作者: mmarian•9 天前
1 分•作者: andsoitis•9 天前
2 分•作者: krylosov-aa•9 天前
pg-status 在后台轮询您的 PostgreSQL 主机,并以毫秒级的速度、全部从内存中回答“当前主库是谁?”、“哪个副本的延迟 ≤ 100ms?”、“哪个副本已经重放了这个 LSN?”等问题。使用 C 语言编写,占用约 9MB 内存。
1 分•作者: gidellav•9 天前
1 分•作者: birdculture•10 天前
3 分•作者: jethronethro•10 天前
1 分•作者: dfps•10 天前
本周大家都在问这个问题,新闻机构试图用 3 万亿美元来解释其规模,但并未真正做到,而是 resorted to 诸如将美元首尾相连能到达月球的距离等类比。
100 年前,美国最富有的人是洛克菲勒,他的财富约为 10 亿美元(估计在 7 亿至 12 亿美元之间)。
1900 年的 10 亿美元相当于 2026 年的 250 亿美元,这只是在作为消费者的购买力方面。
在 1900 年和 2026 年普遍存在的几乎所有指标上,马斯克都能购买更多。
马斯克可以用最低工资(7.25 美元)购买 1400 亿小时的工作,而洛克菲勒当时只能购买 45 亿小时。马斯克可以购买 7500 吨黄金,而洛克菲勒只能购买 1500 吨(5 倍)。美国农田 2.3 亿英亩,而洛克菲勒只能购买 5000 万英亩(5 倍)。铜 7000 万公吨,而洛克菲勒只能购买 300 万公吨(25 倍)。木材 1600 亿板英尺,而洛克菲勒只能购买 850 亿板英尺。
然而,洛克菲勒仍然更富有,因为他的财富使他能够做些什么并赋予他力量(法律限制金钱使用、劳动法、反垄断法等较少,因各种原因对法院的问责制较少)。在 20 世纪初,一个人几乎可以完全购买和拥有任何东西。(例如,1901 年卡内基以 4.8 亿美元的价格出售了卡内基钢铁公司,仅此一笔交易,摩根就获得了建造美国几乎所有东西的金属的实际垄断权,而如今 1 万亿美元可能买不到任何垄断。100 年前,几亿美元也足以救助一个国家(美国黄金耗尽时,摩根就曾这样做)。这种能力所涉及的杠杆作用显而易见。
在 2026 年,1 万亿美元只能让你成为一个庞大的参与者,众多参与者中的一员,以至于最大的参与者在经济上并不真正重要(尽管以马斯克为例,显然,我们都看重他除了经济之外的价值)。
金钱的价值在于拥有它能让你成为什么以及花费它能得到什么。可以认为(无论是否认真,我都不确定)在某个限制较少的非洲国家的一些亿万富翁,在他们的金钱所代表的意义上比马斯克更富有。还值得注意的是,尽管这可能显而易见,但在技术财富方面,今天的穷人比洛克菲勒更富有。
1 分•作者: CoreAi_HTCE•10 天前
21 分•作者: wizardforhire•10 天前
2 分•作者: pradeep1177•10 天前