fananchong2
这个作者很懒,什么都没留下…
展开
-
思考(九十四)跨服跨区消息处理
future 拿到结果,不会阻塞运行它的线程(协程遇到 IO ,先会被切走;这样,1 区 bfserver1 上的某个玩家 PA,它的公会是 GC ,先与它已经被分配在 1 区 bfserver2。这样,remote_call_v2 函数,对逻辑代码隐藏了架构细节。,很多系统,同样需要消息路由,也会有开头的 2 个问题。先有以上功能,且跑稳定后,可以再讨论进一步优化内容。没有什么黑魔法,就是通过路由表,做消息转发。因此,把角色登录中的分配资源的模块抽象出。接下来,顺着这里的思路,继续深挖。原创 2024-03-23 14:49:20 · 163 阅读 · 0 评论 -
思考(九十三):网络加速器简单实现设计
【代码】网络加速器简单实现设计。原创 2023-12-26 11:15:04 · 340 阅读 · 0 评论 -
思考(九十二):DBProxy实现多级存储和事务处理
加载时,可以不加载到 Redis (看作一种优化)。游戏逻辑不像静态网页应用,数据很快就会被业务逻辑修改,然后写 Redis 成热数据。原创 2023-11-05 00:00:45 · 485 阅读 · 0 评论 -
思考(九十一):C++线上内存泄漏检测机制
常见的内存泄漏分析器,如: tcmalloc heap-profiler 、 valgrind 、 asan 、 bcc/memleak 等,要么比较重、要么需要 -O0 ,没法在线上使用。笔者使用的是 tcmalloc ,这里介绍下 tcmalloc 的 hook 方法。这样,就可以在 malloc/free 时,处理一些自己的埋点逻辑。有了以上的技术支持,同时需要考虑线上性能问题,需要轻量处理。而线上的内存泄漏问题,没有分析工具,会造成排查问题困难。因为没有合适的工具,导致排查问题,没有方向。原创 2022-12-18 21:17:57 · 710 阅读 · 1 评论 -
思考(九十):熔断器介绍
gobreaker star 数虽然多些,但是看过实现,比 circuitbreaker 差不少。生活中,当用电电流过载时,直接熔断,避免火灾等事故的发生。也使用了 circuitbreaker 包,因此质量是可以保证的。软件开发中,也需要引入熔断器,避免服务器过载。原创 2022-12-11 17:12:20 · 652 阅读 · 0 评论 -
思考(八十九):WAL 实现
WAL(Write Ahead Log) 预写日志,是数据库系统中常见的一种手段,用于保证数据操作的原子性和持久性。甚至可以在游戏框架层: DB 框架级别、事务框架级别,引入 WAL 重底层保证其可靠性。在游戏开发中,某些重要模块,如邮件、充值、商城等,都可以引入 WAL 保证其可靠性。原创 2022-09-18 12:58:52 · 575 阅读 · 0 评论 -
思考(八十八):使用 protobuf 自定义选项,做数据多版本管理
versionpb";}}}}自定义选项说明定义message版本定义message字段的版本定义enum版本定义enum枚举值的版本。原创 2022-07-31 17:46:59 · 960 阅读 · 0 评论 -
思考(八十七):协议加密与压缩
加密参考主流成熟做法,如 HTTPS。具体过程见下图:协议加密分为两个阶段:阶段1阶段2前端,使用加密消息,开始登录游戏加密算法目前网络流量压缩算法,主流的有:C++ 版,一般会在 zstd lz4 中选择Golang 版,生态上,snappy 支持的好些优化点前后端压缩后,可以对比下原串长度。压缩后比原串长,则可以原串发送这样需要提供一个 flag ,标识发送的消息是否是压缩过的.........原创 2022-06-22 16:55:45 · 280 阅读 · 0 评论 -
思考(八十六):主从实现思路
游戏服务架构中,通常会有些单点的控制服、路由服等这些单点服务故障,会导致整个系统无法正常运作通常会对这些服务,实施主从部署,达成高可用本文介绍一种通用的主从实现方式通常,根据服务对数据的处理方式,可以归为 2 类:对于无状态服务,保证失效服务能及时重启即可因此文本主要针对有状态服务,如何实现通用的主从方案从零开始实现主从的话,涉及很多挑战:由于节点故障、网络分区等已是常态以上 2 个问题,要完美的解决,达到生产环境中的规格是有难度的面对这种经典的问题,已经有不少产品提供了解决方案其中, Raft 协议,提供原创 2022-06-19 22:31:03 · 229 阅读 · 0 评论 -
思考(八十五):IM 服务设计思路
IM 服务器IM 服务器,在游戏开发中,俗称聊天服一般有内嵌在游戏服架构内,与外置于游戏服架构外外置于游戏服架构外的聊天服,通常就是完整的 IM 服务器设计目标消息可靠,不丢失无状态,易扩展高性能服务类型介绍设计以下服务:服务类型说明Gateway网关,保持玩家连接APIAPI 服, HTTP Web 服务,处理除聊天流程外的逻辑,如注册账号、鉴权、好友管理、群组管理等等Single单聊消息处理服务Group群组消息处理服务(有可重组的缓原创 2022-04-10 22:46:10 · 2872 阅读 · 0 评论 -
思考(八十四):再论排行榜服务(二)
最终一致性问题在本系列 思考(八十四):再论排行榜服务 中提到,使用分段同步排名的方法,达到排行榜的最终一致性从程序角度,是合理的。但是具体业务,如榜单结算、玩家查看排行榜,会遇到一个问题:榜上的数据可能有出入因为分段同步的是rank db最终排名,这个排名时刻在变化,会导致 rank 服务中的缓存排名出现出入因此需要引入,排行榜快照概念排行榜快照从使用者角度,不能容忍的是排名数据有出入。而提前告知,排名数据会延迟 xx 秒(分、小时)更新,反而能得到使用者的理解、认同因此最终一致性要同原创 2021-09-11 13:09:48 · 390 阅读 · 0 评论 -
思考(八十四):再论排行榜服务
排行榜服务本系列,前面文章讨论过排行榜服务,现在看来,太复杂了最近需要,重新思考设计了下,欢迎讨论架构+----------------+| http query api +-------------------++----------------+ | | v+----------------+原创 2021-09-03 15:37:51 · 397 阅读 · 0 评论 -
思考(八十三):gRPC-go、net.Conn、syscall.Syscall与性能优化
性能最近对程序做性能优化,发现syscall.Syscall的占比前 Top2从syscall.Syscall出发,经过一系列分析优化,程序性能提升了 3 倍下面来还原下整个过程syscall.Syscall通过go tool pprof工具分析,查看 Top5Top1 是 runtime.futex ,互斥量消耗Top2 是 syscall.Sycall,系统调用,会引起协程切换(这里直接导致线程切换)。协程切换也会引起互斥量消耗。因此优先排查syscall.Sycall利用go too原创 2021-07-11 19:02:32 · 1410 阅读 · 0 评论 -
思考(八十二):C++ Go 程序性能对比
背景最近,对 go 版本战斗 API 服,做了性能优化。使用 C++ 重写了 战斗 API 服战斗 API 服 逻辑功能很简单:有 gRPC 服务Cgo 调用客户端提供的 .a 战斗库而用 C++ 重写的理由,大致有以下几个方面考量:Cgo 调用,比纯 C++ 调用会有消耗根据服务特点,每次 Cgo 调用涉及了较多的 go cgo 间的内存拷贝C++ 可以严格控制线程切换,减少线程间切换消耗测试结构对比C++ 版本:Go 版本:分析说明:C++ 版本性能是 Go 版本原创 2021-06-21 19:34:37 · 3352 阅读 · 0 评论 -
思考(八十一):日志数据去重、归类
错误日志生产环境中,通常会持续触发,甚至刷屏因此,数据分析这块,可以把错误日志做下去重、归类以避免某些错误,因为被刷屏,导致没抓到实现思路日志数据打到 es 上根据一些特征值,抓取 es 日志数据。存入 csv 文件从 csv 中读取日志数据,利用字符串相似度算法,去重错误日志实作例子 - 抓取 es 日志数据# -*- coding: utf8 -*-import argparseimport jsonimport osimport pandasfrom pandasql原创 2021-04-28 16:35:59 · 778 阅读 · 0 评论 -
思考(八十):日志数据分析
日志数据分析在生产实践中,日志数据分析通常做的都不是很好。有以下几个原因:日志数据不合理,渠道多样,造成分析困难没有固化分析过程,导致重复分析。即不懂的需要维护、迭代本文给出一个日志数据分析方法,还解决以上问题数据埋点分析基于数据,因此首要解决日志数据落地问题目前大区大服的框架下,基本上会有非常多的服务节点因此,目前常见的会把数据打到 elasticsearch 中比如前置 kibana ,来查询日志做数据分析,自然可以基于 elasticsearch ,把它看做数据库,提取有用的原创 2021-04-25 18:27:50 · 700 阅读 · 0 评论 -
思考(七十九):服务发现与 DNS
服务发现每个项目的实现过程中,都绕不开服务发现的话题最近多次在云平台上部署容器服务,并通过主机名、DNS 服务,解决了项目从单机到多主机部署难点与简化部署配置流程特别是,当引入容器多主机部署时,如何让部署能脱离IP自动化部署这也是 Kubenets 基于 DNS 作为服务发现的原因本文将介绍服务发现实现的演进过程,带领读者走进最佳的服务发现实现方式V1:基于配置文件实现服务互连最开始,互联网之初,项目都很小大多数都是直接把服务信息写入配置文件服务启动,读取配置来实现服务间互连扩容或缩容,原创 2021-03-13 18:19:44 · 630 阅读 · 0 评论 -
思考(七十八):服务器端被动刷新机制
服务器端被动刷新经历过太多项目,会在服务器端逻辑 loop 中添加这种检查,诸如:遍历背包,检查物品是否过期遍历任务,检查任务是否过期等等在 C++ 服务器端中,这里的问题,主要是定时遍历,会耗 CPU而在 Golang 服务器端中,除了定期遍历检查会耗 CPU 外,还涉及 ** Session 秒级定时器,造成协程每秒切换数与 session 规模呈正比问题**会到消耗大量 CPUSession 秒级定时器问题上一章已做过分析: https://blog.youkuaiyun.com/u0132原创 2021-02-02 12:20:29 · 549 阅读 · 1 评论 -
思考(七十七):一个 goroutine 的性能问题
问题在压力测试中,今天遇到一个问题:7w 玩家在线不做任何操作, 5 台测试机,每台 CPU 均占用 20% 的消耗其中,主要进程消耗占用:每台机器空跑,占用了 20% CPU ,有点浪费问题排查(一)使用 go tool pprof http://haidao-03:20101/debug/pprof/profile 命令, top50 下:可以看到最耗时的是 runtime.schedule ,其次是 runtime.futex有了初步的印象,再具体看下性能消耗调用链。执行 go原创 2021-01-28 19:21:20 · 541 阅读 · 0 评论 -
思考(七十六):Golang 编程之 Mock 模式
Mock 模式Mock 模式本质上就是工厂模式生产实践中,提到 Mock ,潜台词是把这个系统支持工厂模式吧,那样就可以替换掉旧实现,从而达成XXX因此提到 Mock ,通常是要对项目做改造而 Mock 模式的重要意义在于:最小限度适配、最少量的代码改动稳健过渡,灰度期可以轻松互切具体实现;甚至打回并行开发,不会让功能升级成为开发路径上的路障Mock 模式对逐步改造老项目至脱胎换骨,起着至关重要的作用。是一把锋利的手术刀Mock 的切入点找好切入点是,成功实施 Mock 模式的基础原创 2020-11-03 18:12:16 · 873 阅读 · 0 评论 -
思考(七十五):Golang 编程之有限状态机
有限状态机有限状态机(英语:finite-state machine,缩写:FSM)又称有限状态自动机(英语:finite-state automation,缩写:FSA),简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型。用于编程中,有以下优点:统一退出逻辑代码容易维护,只需要写好代码片段易扩展,同理只需要扩展编写代码片段以下以 2 个项目中的实际例子,来展示下有限状态机的威力压测工具应用有限状态机压测工具,会模拟每个账号行为:从登陆开始(包括登陆中的原创 2020-10-09 12:16:23 · 826 阅读 · 0 评论 -
思考(七十四):一个游戏后端分布式事务架构介绍
游戏后端分布式事务特点网络上能搜到的各种分布式事务方案,要么效率太低,要么实现过于复杂,基本上不适合用于游戏后端。游戏后端中涉及的分布式事务特点:要足够快写逻辑简单,即对于码农无感知事务级别上略低,比如写磁盘最后1秒丢失,这种可以接受如果游戏架构上能解决分布式事务问题,可以显著减低公司的运维成本本文给出一个分布式事务的解决方案,基本上能解决上述痛点被忽视的主角:内存事务先看下面一段伪代码:func foo() { defer func() { if r :=原创 2020-09-06 00:35:36 · 2381 阅读 · 1 评论 -
思考(七十三):Excel 数值表的相关
Excel To CSV服务器端如果直接使用 Excel 文件加载资源,会非常慢使用 https://github.com/360EntSecGroup-Skylar/excelize 库, 380 KB+ 的资源,大约要消耗 20s+因此,必须事先使用工具,转成其他可快速加载的格式可选的格式很多:CSVProtobufJson最佳的格式,一定会是 Protobuf ,可以在多版本共存的环境中,发挥向前兼容的特性这里,项目上的折中,实践了 Excel To CSV并分析总结相关要点原创 2020-08-25 15:26:24 · 366 阅读 · 0 评论 -
思考(七十二):Golang 统一错误处理与报警
recovergolang recover 错误恢复机制,并搭配协程,让 golang 程序可以很健壮,并不易 crash同时,项目时间一长,会有各种花式 recover 代码在笔者写这片文章前,当前项目中,有 200+ 段 recover 代码同时, golang panic 信息需要及时到达给程序,避免 panic 信息在日志文件中刷屏,而程序却不知情因此需要统一错误处理,实现诸如报警等公共功能的基础上,让程序可以自定义某些错误处理实现实现方案默认 golang 错误处理,都长这样:de原创 2020-07-28 18:15:03 · 1418 阅读 · 0 评论 -
思考(七十一):Protobuf oneof 实现消息分发
oneof官方文档介绍: https://developers.google.com/protocol-buffers/docs/reference/go-generated#oneof需要科学上网,所以直接摘录下内容,方便查阅:Oneof FieldsFor a oneof field, the protobuf compiler generates a single field with an interface type isMessageName_MyField. It also gene原创 2020-07-20 14:35:22 · 3701 阅读 · 1 评论 -
思考(七十):跨区服的业务逻辑服设计
背景不少服务器架构都分区,但是又有跨区业务,比如:按账号级别的好友系统按账号级别的聊天系统按账号级别的公会系统等等这些功能代码要独立出来才能实现,这点是毋庸置疑的主要需要考虑以下问题:跨区服的业务逻辑服需要解耦与单个区服内服务器的链路关系跨区服的业务逻辑服又有可能与单个区服内服务器有业务交互(比如单个区服内服务器需要获取本次请求结果这种,不是单纯的Push)跨区服的业务逻辑服需要有简单(模式化的)编程方式本文提供一种通过 MQ 来解决以上问题架构图这里说的跨区服的业务逻辑原创 2020-07-08 19:24:13 · 749 阅读 · 0 评论 -
思考(六十九):一种基于消息总线的功能可插拔的服务器架构
架构图 +--------------------+ +----------------+ +----------------+ | | | NODE 1 | | NODE 2 | | TOPIC ROUTE INFO | | | | |原创 2020-07-01 18:35:57 · 521 阅读 · 0 评论 -
思考(六十八):租约机制在登录与路由中的应用
背景在游戏登录过程中,涉及分配玩家的服务器资源,这个信息也会用于后续的某些路由考虑到登录过程的复杂性与一些切实的需求:重复登录保持会话与服务资源的亲和性问题新旧会话创建与销毁的并发问题服务器节点失效切换服务资源,维持高可用性问题路由缓存一致性各种异常情况下,路由缓存的正确性问题本人经过多次的实践迭代,终于通过租约机制完美的解决分布式过程中的服务资源分配及路由访问问题租约机制租约机制是分布式锁中的一种解决方案,具备简单兼具性能的优点主要有以下特点:没有重互斥原创 2020-06-13 15:31:34 · 595 阅读 · 0 评论 -
思考(六十七):按段(segment)分片的数据库应用
问题在使用数据库的应用中,通常会通过对 ID 做 hash 映射到分库分表,达成压力均摊在实际实施过程中,通常会有 2 个问题:当实例进行扩容时,必须停服维护, rehash 用户数据不同实例压力分担不均,通常 ID 越大的那些实例压力大因此,实作中,通常会使用按段(segment)划分维护数据集本文,举 3 个例子来阐述其思想:美团 Leaf-segment 数据库方案实现分布式ID生成器永不迁移数据和避免热点的 MySQL 横向扩展方案Redis 集群的按哈希槽实现分片Lea原创 2020-05-24 11:24:51 · 685 阅读 · 0 评论 -
思考(六十六):无状态服务的数据存取与事务处理
痛点一每次存取数据量太大,影响性能比如,背包数据,每次请求操作都存取背包数据,会影响机房内流量与数据库性能痛点二一次请求,通常会涉及多次数据存取,程序 panic 会导致只提交部分数据到数据库这涉及到无状态服务如何让便利的逻辑编写同时兼具事务内置 LRUCache 解决大数量量存取无状态服务,主要是解绑数据与服务进程间的一一对应关系即请求到达任何一个服务进程,都能正确处理该请求因...原创 2020-05-01 20:29:59 · 912 阅读 · 0 评论 -
思考(六十五):微服务中的向前兼容问题
背景在游戏小区小服架构中,开发者通常只需要考虑向后兼容问题而游戏架构微服务化后,通常还需要考虑向前兼容问题向后兼容向后兼容通常相对简单,因为在旧版本上维护新开发内容,只要考虑不删档这个因素即可衡量是否成功向后兼容,看服务版本更新是否需要删档,删档即表示向后兼容失败!向前兼容向前兼容则相对复杂些,通常会有以下几个应用场景,会涉及到向前兼容:同一大区同时给多个版本的客户端提供服务...原创 2020-04-06 22:38:37 · 959 阅读 · 0 评论 -
思考(六十四):游戏中的角色ID问题
游戏中的账号与角色关系数据库时期的游戏,会有以下字段来定位账号与角色数据:账号账号 ID角色 ID以至于到现在,程序做游戏时会全部或部分照搬典型的,至少会有账号与角色ID,并需要维护它们的对应关系关系数据库特点关系数据库也可以使用字符串做主键但是出于性能考虑,程序不约而同的会把整型作为主键因为关系数据库通常做 where 、 join 等操作,整型键明显性能优于字符串型键...原创 2020-03-02 18:49:44 · 1509 阅读 · 2 评论 -
思考(六十三):微服务架构中的时序问题
问题微服务架构中调用关系异常复杂,容易发生时序问题,而导致系统漏洞比如,下面的时序图,玩家先买一个道具,然后进副本:ShopServiceBattleServiceMoneyService1.1 查询 Gold1.2 购物处理1.3 扣除 Gold2.1 查询 Gold2.2 进入条件检查ShopServiceBattleServiceMoneyService考虑到外挂、玩家点快了、网络异...原创 2020-02-26 22:29:14 · 1148 阅读 · 0 评论 -
思考(六十二):全服匹配服实现思路
全服匹配服实现思路1. Redis 防止单键假设有多个 key 参与匹配,比如等级( level )、战力( fightpoint )、段位( grade )那么可以每类 key 分为 N 个,比如key_level_1 到 key_level_Nkey_fightpoint_1 到 key_fightpoint_Nkey_grade_1 到 key_grade_N要匹配的玩家随机 ...原创 2020-02-19 23:22:58 · 1268 阅读 · 0 评论 -
思考(六十一):MMO 微服务架构思路推演
MMO 微服务架构思路推演传统的 MMO 架构有很多局限性,主要有以下几点:承载量有限基于这种架构上, BigWord 无缝世界实现非常复杂无法融入微服务这种更先进架构中因此,本人提出一种 MMO 微服务架构,并以此架构为基础,借 MMO 典型玩法,来推演这种架构是否符合要求并解决上述 3 个问题架构图 ...原创 2020-01-15 17:25:51 · 4231 阅读 · 6 评论 -
思考(六十):游戏后端数据的存取优化参考
前言通常游戏后端数据存取会一刀切的使用以下某种方式:使用数据库方式优点缺点全部使用内存数据库TPS 高内存成本高;落地、数据维护难全部使用关系数据库TPS 低落地、数据维护易全部使用内存数据库(缓存)+关系数据库TPS 高仅适用于 KEY-VALUE 型功能就本人最近一段时间的数据优化总结来看,每种数据的使用,都会有独特的优化三个目标做数...原创 2019-09-22 01:01:42 · 1149 阅读 · 1 评论 -
思考(五十九):如何正确的测试网络库
基准测试不同的测试环境,对网络库的测试结果都会产生影响因此评价一个网络库是否达标,均要在相同测试环境下进行,才具备可比性这就是基准测试合理的测试环境目前来看,有以下几种测试环境:同一主机同局域网内,多台云机同局域网内,多台物理机互联网而影响网络库测试结果的因素有:CPU 主频、核数网卡性能网络延时综合考虑的话:对于网络库来说,更容易跑满 CPU 、 虚拟网卡...原创 2019-07-22 18:08:26 · 878 阅读 · 0 评论 -
思考(五十八):基于 go-micro 实现聊天服的思路
基于 go-micro 实现聊天服github 上有个 goim ,主要是为弹幕服做的,改成聊天服也有些工作量将 goim 实现弹幕的思路,与 go-micro 结合,应该能达成快速开发聊天服,且足够应对主业务不是聊天为主的应用细节如下:1. 账号登录聊天服+----------------+ +----------------+ ...原创 2019-07-02 15:17:22 · 918 阅读 · 0 评论 -
思考(五十七):一处 string 字段竞态问题引发的 crash
string 字段多协程竞态通常写代码比较注意一些数据结构、容器的多协程竞态,比如 slice 、 map对于 string 字段的多协程竞态,非常容易忽视这里举例说明,项目中遇到的问题竞态代码代码片段1 (协程1 中执行)func (s *Server) loginOnWindows(p *common.Proto, ch *Channel) (err error) { req :...原创 2019-06-24 18:34:39 · 400 阅读 · 0 评论 -
思考(五十六):Golang 编程之工厂模式
工厂模式工厂模式: 在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象micro/go-micro 在插件的可插拔上使用了工厂模式micro/go-micro 工厂模式的应用以Registry的etcd 插件为例1. 接口摘自: https://github.com/micro/go-micro/blob/master/registry/registr...原创 2019-06-23 14:48:51 · 628 阅读 · 0 评论