tencent cloud

云函数

动态与公告
产品动态
产品公告
新手指引
产品简介
产品概述
相关概念
工作原理
产品优势
应用场景
相关产品
购买指南
计费概述
计费方式
计费项与计费方式
函数算力支持
免费额度
产品定价
计费示例
欠费与停服说明
快速入门
使用控制台创建一个事件函数
操作指南
配额管理
函数管理
Web 函数管理
日志管理
并发管理
触发器管理
函数 URL
自定义域名
版本管理
别名管理
权限管理
运行实例管理
插件管理
监控与告警管理
网络配置
层管理
执行配置
扩展存储管理
DNS 缓存配置
资源托管模式管理
近离线资源托管模式
工作流
触发器
触发器概述
触发器事件消息结构汇总
API 网关触发器
COS 触发器
CLS 触发器
定时触发器
CKafka 触发器
Apache Kafka 触发器
MQTT 触发器
触发器配置描述
MPS 触发器
CLB 触发器说明
云 API 触发器
开发指南
基本概念
测试云函数
环境变量
依赖安装
使用容器镜像
使用 Docker 安装依赖
错误类型与重试策略
死信队列
云函数接入数据库
自动化部署
云函数状态码
常见错误码解决方法
开发者工具
Serverless Web IDE
函数间调用 SDK
第三方工具
代码开发
Python
Node.js
Golang
PHP
Java
Custom Runtime
使用镜像部署函数
Web 框架部署
通过命令行完成框架部署
快速部署 Egg 框架
快速部署 Express 框架
快速部署 Flask 框架
快速部署 Koa 框架
快速部署 Laravel 框架
快速部署 Nestjs 框架
快速部署 Nextjs 框架
快速部署 Nuxtjs 框架
快速部署 Django 框架
实践教程
最佳实践概述
云产品联合解决方案
业务开发相关实践
实时音视频 TRTC
对象存储 COS
消息队列 CKafka
日志服务CLS
负载均衡 CLB
视频处理 MPS
内容分发网络 CDN
云数据仓库 PostgreSQL
云点播 VOD
短信 SMS
Elasticsearch Service
定时任务
视频处理
客户案例
腾讯在线教育
在线教育行业案例
游戏聊天系统
腾讯互娱国际(IEGG)
API 文档
History
Introduction
API Category
Making API Requests
Other APIs
Namespace APIs
Layer Management APIs
Async Event Management APIs
Trigger APIs
Function APIs
函数和层的状态说明
Data Types
Error Codes
SDK文档
常见问题
通用问题
Web 函数相关问题
计费相关问题
网络相关问题
日志相关问题
SCF 工具相关问题
事件处理相关问题
API 网关触发器相关问题
相关协议
Service Level Agreement
联系我们
词汇表
文档云函数客户案例游戏聊天系统

游戏聊天系统

PDF
聚焦模式
字号
最后更新时间: 2024-12-02 20:36:45

客户简介

社交,是游戏文玩家的一项基本需求。在游戏中,成熟稳定的聊天系统担负着玩家交流的重要使命。本文分享了江娱互动使用腾讯云云函数的真实案例,介绍如何通过云函数升级游戏中的聊天系统。
江娱互动在《世界争霸》和《农场小镇》两款产品中都使用了自研聊天系统。随着在线人数逐渐增多,系统的稳定性和成本面临着更多考验。需进一步升级技术栈,以保障性能为前提,同时尽量减少人力和资源成本的花费。最终选择了使用腾讯云云函数,原因如下:
云函数无需服务器,仅需关注业务逻辑代码,省去运维烦恼。
按量付费的计费模式,避免业务低谷期的资源浪费,减少了成本开支。非常适用于游戏聊天系统 API 这种复杂度低的中小型需求。
接下来我们只需关注如何将现有系统无缝迁移,即云函数如何满足目前所有的特定需求。

客户需求

需求1:仅修改少量代码

原有的部分 API 采用 swoole 作为底层扩展,部署在腾讯云云服务器 CVM 上,并使用腾讯云负载均衡接收外部请求。代码层面使用了 composer 进行包管理,HTTP 业务框架采用了开源框架 easywoole。
若变更为云函数方案,则非代码层面将由腾讯云 API 网关及云函数来提供服务,代码层依然需使用 composer 进行包管理。而原有基于 swoole 的 HTTP 框架将无法继续使用,修改代码的重点则集中在框架部分。如下图所示:

主要修改思路如下:
1. 确定逻辑入口,确保用一个云函数来处理所有请求。 入口其实是一个路由,我们需要定义一种简单的路由格式,在云函数入口代码处得到需要的信息,转给原有的类进行处理并返回特定的内容。以下是一个简单的 url 格式示例:
https://url/controller/action?query
只需要解析云函数给出的 path,就能得到 controller 和 action,做出判断后调用相应类的方法后返回。基于这样的入口,原有的逻辑处理类就可以被调用到了。
2. 处理原来的逻辑处理类的父类,弃用框架后需要实现一个基本功能的父类。例如,获取 qerystring 内容、解析 body、返回统一格式的返回值等。 下图中以 PHP 为示例,不同的开发语言思路类似。代码还需进一步修改,例如,增加数据库配置信息(可使用云函数中的环境变量来传递)及原有耗时任务的异步操作等。
date_default_timezone_set('Asia/Shanghai');
require_once__DIR__ . "/vendor/autoload.php";
function run($event, $context)
{
$path = $event->path;
//解析path
list($controller, $action) = parsePath($path);
$controllerClassName = "\\\\App\\\\HttpController\\\\" . ucwords($controller);
if(!class_exists($controllerClassName)){
return return404();
}
$controllerClass = new $controllerClassName($event, $context);
//避免在 HttpController 目录下放置的不应该被外部调用的类被调用
if(!controllerClassName instanceof \\App\\BaseController){
return return404();
}
if(!method_exists($controllerClass, $action)){
return return404();
}
try{
return $controllerClass->$action();
}catch(Throwable $e){
return return500();
}
}

需求2:快速发布

快速发布的能力是不可或缺的,在迁移过程中,会反复进行各种测试。在进行迁移时云函数的本地测试功能尚未支持 PHP,所以在使用 API 网关与云函数组合时,发布流程为:
1. 开发代码
2. 部署云函数 $LATEST 版本
3. 基于 $LATEST 版本生成新版本号
4. API 网关对应路径切换版本
5. API 网关发布测试版本
6. API 网关线上使用版本切换
发布的过程较为复杂,在迁移开始时,步骤3尚未支持 API 调用,无法实现自动化部署,目前已支持了该能力。但也可以使用 API 网关直接指向云函数的 $LATEST 版本,再部署云函数的方案。该方案较为简单,但仅适用于测试阶段,不适用于线上阶段的发布。 我们采用了两者结合的方式,稳定的功能使用稳定版本的发布流程,而新功能则新建一个 API 路径并指向 $LATEST 版本,随时进行发布也不会影响线上功能。

问题及解决方案

在发布 API 网关时,有时会遇到资源超限的情况,查明是由于云函数的并发实例数量限制,当发布新的 API 版本时,会请求进入新的实例而旧的实例未释放。两种实例数量和超过限制,此时需向腾讯云申请提高限额。

需求3:内网互通

此次为系统迁移,但原有的系统中仍然有部分内容需要继续使用。因此需要云函数可以与原有的 CVM 内网进行通信,结合云函数本身支持部署到已有的内网中,内网互通很容易实现。

问题及解决方案

由于我们的 API 服务需要向外发出请求,而内网云函数在系统迁移时不具备直接访问外网的能力,通过 NAT 网关实现了云函数访问公网的功能。详情请参见 在私有网络中配置 NAT 网关
注意:
通过 NAT 网关的解决问题时,建议给云函数单独分配一个子网。因为使用已有的子网绑定 NAT 网关,会导致出口 IP 变化。若该子网下的机器 IP 恰好在某些白名单下,则会造成影响。

需求4:日志查询

原有的日志采用直接落盘,定期压缩转储的方式。而系统迁移到云函数后,需采用云函数的日志机制。云函数可直接投递日志到腾讯云日志服务中,任何输出的信息都会直接作为日志被投递,需要根据实际需求规划日志内容。
我们把函数入口的原始信息、URL 路径、客户端 IP、解析后的参数以及业务日志等都进行了输出,方便快速定位和查询。另外,不需要单独输出一次返回值,云函数可自行打印。
注意:
在开启日志投递后,需打开索引才可查看日志。若日志内容包含索引分词符,则设置索引时需从分词符中删除对应关键字,否则内容会被分割。
在系统迁移时,云函数日志部分还存在着不足之处,例如云函数与 API 网关的日志是分离的。HTTP 的原始入口是 API 网关,这就导致一些问题跟进较困难。目前了解到云函数和 API 网关日志的 RequestId 已经打通,可以很方便地通过同一个 ID 查询到同一次请求的日志。

需求5:耗时任务处理

原有的方案是使用 swoole 的 task 处理耗时任务,由于云函数的 PHP 环境支持 swoole,初步尝试了如下图所示的改造方案:
$p = "1";
$process = new \\swoole_process(function (\\swoole_process $worker) use ($p){
echo $p;
sleep(3);
echo $p;
});
$pid = $process->start();
但通过该方案制造出的进程不能完全掌控。经测试发现,打印出的日志属于其他请求,同时也无法确定进程的计时及生命周期,所以采用了更为保险的“消息队列”方案。
选用了腾讯云的消息队列服务 CKafka,通过封装一个通用结构的消息体并发给 CKafka,CKafka 会触发另一个云函数(运行着耗时任务的代码)。采用通用结构时,可以忽略消息队列的主题,若有任何想要异步操作的任务,只需写在被 CKafka 触发的云函数中,再把需要触发的云函数名和参数发给 CKafka 即可。如下图所示:


问题及解决方案

Ckafka 主题默认仅创建一个分区,如消费速度不理想,可尝试新增分区。新增后,云函数侧需删除触发器再重新添加。

需求6:配置文件更新

该系统中的配置文件是需要经常更新的大文本。例如,聊天服务中会涉及到的屏蔽词库,该文件容量大且会频繁更新。
原有方案为:配置文件单独具备 git 库,策划提交后执行 jenkins,再由 jenkins 上传文件到 CVM 并进行 reload。 系统迁移到云函数后,无法单独上传配置文件,仅支持将文件放置在代码中。方案也更新为:策划提交 git,jenkins 从 git 获取文件后上传至 COS,云函数再从 COS 拉取。如下图所示:


问题及解决方案

性能问题,云函数拉取 COS 有一定耗时,因此不能每一个请求就拉取一次文件。意味着需要把每一次拉取的内容存放在内存中,但无法统一管理云函数的内存,无法保证实时变更。 采用了折中方案,比较内存中保存文件内容和上一次拉取时间,如果超过5分钟,则重新拉取。可以保证相对的实时性和性能,也可满足目前的需求。如下图所示:
private static $fileContent = null;
private static $lastTime = 0;

public static function refresh(){
self::$fileContent = self::readFromCos("words.txt");
}

public static function getFileContent(){
if(time() - self::$lastTime > 300 || empty(self::$fileContent)){
self::refresh();
self::$lastTime = time();
}
return self::$fileContent;
}

客户价值

至此,系统迁移过程中的需求都已实现,迁移工作得以顺利推进。迁移到云函数之后的优势如下:
无需维护 API 服务器,无需考虑 CPU、内存的问题,请求量增加时也无需考虑是否增加 CVM。
监控内容比较详细,可以更好地查看整体的运行效率。例如,查看是否存在慢请求、访问趋势,是否有错。
使用消息队列拆分后,解耦彻底,且可确保消息不会丢失。消息队列触发云函数的方法适用于不断累积形式的慢任务。
版本管理功能改进后可随时切换版本,无需再重新拉取代码分支发布。
腾讯云云函数给江娱互动带来了众多优势及便利,江娱互动也在规划还有哪些功能可以继续使用:
无状态的 HTTP 服务。例如,客服消息接收、支付回调接口。
无须返回的异步任务。例如,微信小游戏上报玩家排名。
定时任务。例如,定期给玩家推送相关的活动信息。

帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈