排查Https请求超时的一些建议(下)

上篇内容我们介绍了排查Https请求超时的大体思路,主要强调了自查的重要性,以及一般情况下超时问题的排查流程与关注点。

下篇我们将内容聚焦到超时自查中一块十分重要的内容:在请求通过网卡发出之前,如何有效获取Https请求各阶段Trace记录。目的是为了更好的进行问题归因和为后续排查收集关键信息。

客户端发起Https请求的流程

我们还是以Golang语言作为背景,其标准库客户端请求流程如下:

对于上面每个步骤来说,我们既需要关注耗时,还需要关注它们是否存在错误,特别针对DNS解析我们还需额外关注DNS解析的结果

每个步骤的目地和原理这里不做介绍,比如:链接复用是什么;DNS解析是做什么用的,解析结果会影响什么等等。这里我们更加聚焦于怎么Trace每个步骤需要关注的信息。

Trace方案

Read More →

排查Https请求超时的一些建议(上)

超时问题

Https请求超时一般指的是从Https请求发起计时,在规定时间内没有返回响应,造成请求超时。使用Golang语言为例,默认客户端没有设置超时时间,即请求一直等待返回,我们可以通过下面代码设置客户端的请求超时为5秒:

var client = &http.Client{
    Timeout: time.Second * 5,
}

绝大多数情况下,超时请求会返回关键词为“context deadline exceeded (Client.Timeout exceeded while awaiting headers)”的错误信息,少数情况下也会因为超时导致的其他信息返回。

Golang语言也支持设置更细粒度的超时机制,例如在TCP链接建立阶段,在SSL握手阶段等等,主要是根据Https请求阶段来进行分解的。可以参考这边文章(The complete guide to Go net/http timeouts),文中讲解的比较透彻,借里面的一张图来说明更细粒度的请求超时拆解:

其中http.Client.Timeout就是文章开头代码所设置的超时时间,本文讨论的超时也是从这个点延伸出去的。其余的超时机制以及Trace它们方式会在下篇里做详细介绍。

问题发现

Read More →

聊聊服务端架构演化

我们先从一个需求入手:需要实现一个游戏好友系统。

比较常规的做法:

(为了更清晰讲述,这里屏蔽了一些模块细节:比如接入层、服务器框架、储存读写分离、分表、分桶、集群模式等,也未考虑异地互备与大陆外数据等细节)

简单的名词解释:

  • GameServer:用来接收、处理客户端常规请求的模块(根据游戏是否分区部署策略会有所不同,这里简化成单分区);
  • FriendServer:用来处理所有和好友相关内容的模块,可以多进程部署进行负载均衡;
  • RoleBaseInfo:用来储存用户简要信息;(这里可以简单理解成需要在好友列表上展示的信息)

那么整个处理流程如下:请求从GameServer转发至FriendServer,FriendServer根据好友列表信息拉取对应好友的RoleBaseInfo返回至客户端显示。

将来会引发的问题:

随着用户的增多,每次请求通过FriendServer去DB实时拉取系统整体负载会加大。

解决方案:所以为了成本考虑增加缓存,牺牲一定的实时性,空间换时间的策略。

新流程接入了缓存机制会把好友数据做缓存,分钟级定期更新(缓存也可以放GameServer,可以减少内网带宽消耗,但是造成模块边界模糊)。

Read More →

GameAISDK的UI识别点击

游戏对不同分辨率手机的适配没有统一的标准或者固定方案,这样会引发一些微妙的问题,我们先拿简单的分辨率缩放举例。

在传统的图像缩放中,对于目标点的偏移都是等比的。比如:从(100×200像素)->(200×400像素)图像中的UI坐标变化过程是这样:

矩形坐上角坐标原点,横向x轴,纵向y轴,后面均沿用此规则

传统图像缩放

对于游戏来说,因为大屏、异形屏的原因较难按照等比的方法来进行适配,而且部分游戏可能有自己独特的分辨率适配规则。实际情况可能如下:

游戏图像适配

这会导致一个什么样的问题?比如你有一段程序或者代码需要ClickUI(40,50)。在100×200原始分辨率下是有效的,但是换了200×400分辨率的手机可能会有适配问题,原本期望的ClickUI(80,100)无效了。实际需要ClickUI(80,120)才有效。

当然这里有一些其他的方式能取到不同分辨率下UI的精确坐标,游戏可以利用引擎,android原生app可以利用底层接口等等,但是这些不是本文讨论的内容。

GameAISDK点击UI的过程

Read More →

GameAISDK模仿学习研究

模仿学习(Imitation Learning,后面简称IL)的思想就和它的名字一样,借助“专家”示范样例,机器会记住这些样例,并模仿着做。

GameAISDK中的IL沿用了上述思路,使用训练集和验证集两个样本集,样本由截屏与行为的映射信息组成。训练成模型后传入截屏进行行为预测,预测结果为对应需要执行的行为。

一些名词解释

  • UI – 用户界面,这里指游戏里用户可以点击、滑动的特定按钮与区域;
  • SDKTool – GameAISDK自带的客户端工具,用来设置UI识别行为与样本录制;
  • Adb – Android调试工具;
  • Minicap – 效率很高的截屏工具;
  • LSTM – 长短期记忆人工神经网络;
  • GRU – LSTM变体,有比较优于LSTM;
Read More →

腾讯GameAISDK试用报告

腾讯在今年8月份的时候开源了自家基于AI的游戏自动化测试工具GameAISDK(https://github.com/Tencent/GameAISDK)。这个东西最吸引人的地方就是使用了CV+AI的技术来实现游戏自动化。

区别与以前的脚本或者UI自动化工具,对业务代码侵入少,技术前沿。

总体结论(个人主观)

总分100分的话,我给60分,主要槽点如下:

  • 各种BUG,文档教程与实际不一致;
  • 环境安装有些复杂,而且对安装环境限制比较死,如果不是Ubuntu或者Windows需要花大力气才能安装成功使用;
  • 强化学习DQN的方式基本是鸡肋;
  • 源代码里面很多tricky的地方,给阅读理解造成困扰;

下面我选取一下典型的例子来分析一下,可能每个点都提一下核心问题和总结,因为要展开说每个点都可以形成单独文章。

后面简称GameAISDK为工程。

Read More →

Mysql数据库被盗

九月初的时候,安装在云服务器上的Mysql被人盗了,数据被删,留下了一段勒索信息,所幸是Mysql除了我的博客数据外并没有什么重要的数据。

勒索信息大概意思是付0.06个比特币(当时行情价差不多4000RMB)就把Mysql数据还给我。这绝对是过高的预估了我的数据价值,这些数据去个0,顶多值400。

比较遗憾的一点是,因为我的疏忽,云服务器Mysql没有开启binlog,若直接通过Mysql数据文件恢复,会存在数据损失(因为库表内容已经被盗取者覆盖过了)。

硬盘快照自动短期备份设置只保留7天,但是数据库的修改是在7天之外,求助了官方说备份删除了就删除了,无法恢复(这点我是存疑的)。最终无奈只能恢复二年前的备份,然后云上的硬盘镜像最后一次永久备份是二年前,若恢复这个备份,会有若干评论交互和十几篇博文信息缺失。权衡之下无奈恢复了二年前的备份,再通过“外部网站备份”拷贝回原有的文章信息。

事情过程不复杂,只是思考了几点:

站在黑客角度

  • 瞎估值导致没收到勒索款。如果黑客只勒索200~300RMB我可能为了省事就付了,不过每个人心中都有一个哈姆雷特,这些数据值多少没一个标准;

站在受害者角度

  • 数据备份的重要性,即使是个人不重要的数据。定期的持久化备份,已经短期备份的数据覆盖率,最多能承受多少天的数据损失,最好心中有数;
  • 自己搭建的服务注意公网安全性。比如mysql,redis这些敏感的存储,需要注意里面账号的权限配置,尤其是安装第三方软件需要用到这些存储,如果需要自定义账号通过公网访问,一定要记得使用复杂密码。

这次mysql被盗可能是因为使用了Tars教程推荐公网权限的账号,并未修改密码导致的。

站在云服务角度

  • 没什么槽点。虽然无法恢复硬盘镜像,但是也是按照约定规则来,没什么好说的。

(全文结束)

网游串号问题研究

一篇迟来的文章,这个问题先在公司内部做了分享,然后才搬运到博客上面来。

2020年4月底《山海镜花》开服即炸服,随后玩家串号。作为一个游戏开发者,客观评估串号应该在网游事故中排第三。

个人心中的网游事故排名(同一量级下):

  1. 玩家数据损坏或者丢失;
  2. 游戏漏洞导致活动或者道具被刷,毁坏了游戏经济数值系统;
  3. 串号;

一二可能相对比较好理解,串号这个东西比较玄乎,为什么玩家A会登陆到玩家B账号上面进行操作?甚至连开发同学可能对这个问题开始都是一脸懵:怎么会这样?下面我们逐一来分析串号问题。

(所有分析站在全局角度,并不仅仅针对《山海镜花》的问题)

Read More →

学习Golang之服务器框架编写 – 名字发现服务

名字发现服务(后文简称Naming)一般使用在分布式系统中,当新节点加入时,如何让其他节点知道?

原始的做法是使用配置文件,对每个节点可相连的节点进行配置。这种方法费时费力还容易出错。所以现代系统中一般使用配置中心或者Naming对新加入的节点进行管理,让其他节点感知到它的存在,从而进行通信。

剔除节点的情形也类似,使用Naming机制能更方便的屏蔽失效节点。所以Blue也内置了一套简单的Naming。

Read More →

学习Golang之服务器框架编写 – CS网络通信

概况

blue 的整个CS网络通信设计参考了TarsGo( https://github.com/TarsCloud/TarsGo ),在其基础上做了一些优化与微创新。

目前只提供了基于TCP通信协议的相关接口,后续会加入UDP或者RUDP通信。

代码包里提供了一个简单的TCPClient封装,里面有连接服务器、收发包基本功能。一般来说用不到,因为使用go做客户端的比较少。目前仅仅在blue的样例中使用。

Read More →