作为SNG应届生入职的传统,都会参加SNG的mini项目,每组大概10人,在短短10天的时间里开发一个相对完善的APP。这对整个团队来说是一件十分有挑战的事情,小组内只有两个人负责后台架构/开发,通过云平台部提供给我的支持,我们在腾讯云上搭建了一套相对简单但是功能基本符合需求的后台系统。本文将对后台jia'g'o'o进行简单的介绍。
【产品】丢丢
【产品介绍】
一款利用LBS的失物招领APP,支持发布带有地理位置的失物招领信息、关键字匹配失物资讯推送失主。
【后台架构分析】
因为是在后台层面分析,我们主要在技术层面进行介绍。产品的主要功能相对简单,主要实现
-
丢失物品的发布
-
拾到物品的发布
-
将捡到物品跟失主丢失的物品匹配,将匹配物品推送给失主的功能。
其中,主服务的逻辑处理需要至少有两台服务器,防止一台挂掉。其次,数据库也需要有准备,对于本产品来说,更偏重查询的使用。最后,影响性能的是匹配发布丢失物品的人是否与捡到物品信息匹配,再推送的相应丢失人的手机上,这就要考虑怎样处理回更加节省时间,提高效率。
【云服务需求清单】
-
因为初始资金只有1000元人民币,考虑到mini项目的后台压力不大,所以均购买了相对低配的产品:
-
主服务器:标准型S1,1核2GB,1Mbps,云硬盘,基础网络。(广州二区)
-
备服务器:标准型S2,1核2GB,1Mbps,云硬盘,基础网络。(广州三区)
-
消息处理、推送服务器:标准型S1,1核2GB,1Mbps,云硬盘,基础网络。(广州三区)
-
负载均衡:腾讯云LB,基础网络。
-
数据库:云储存Mysql,最低配,主/备异步复制。
-
消息缓存:云存储Redis,主从,最低配。
【架构图】

【说明】
- 负载均衡:负载均衡的配置十分简单

只需要绑定后端的实例就可以了,LB默认监听后端的8080端口,而且可以修改对应的权重,因此只要把后端实例的Nginx/Apache端口改成8080即可。
Apache:

Nginx:

-
由于开发周期短,便于开发和调试,我们选择了php作为后台语言,选择了larvel框架进行开发,有兴趣的同学可以移步laravel.com/进行详细了解。服务器选… 16.04.01 LST 64位,php7.1版本语言,nginx做接入。
-
有了框架,数据库的链接就显得十分方便,直接用数据库的内网ip和相应端口,数据库名称即可链接。如图为laravel的数据库配置,具体值配置到了环境变量里:

- 最为耗时的工作是匹配丢失物品和捡到物品,laravel框架有一个叫做queue的神奇功能。“Laravel 队列为不同的后台队列服务提供统一的API,例如Beanstalk,Amazon SQS, Redis,甚至其他基于关系型数据库的队列。队列的目的是将耗时的任务延时处理,比如发送邮件,从而大幅度缩短Web请求和相应的时间。”
所以,果断把最浪费时间的东西丢到redis里面,这里不仅可以使用redis,Amazon SQS等,也可以使用rabbitmq,mysql,只不过,经过尝试,redis是最快的。
public function handle()
{
// 最新上传的捡到物品。
$newFoundItems = FoundItem::where("state",0)->orderBy('updated_at', 'DESC')->first();
$foundItem = json_encode($newFoundItems);
// 丢失物品列表
$lostItems = LostItem::where("state",0)->get();
foreach ($lostItems as $item) {
$lostItem = json_encode($item);
$job = (new PushService($foundItem,$lostItem));
dispatch($job);
}
}
一旦有新的捡到物品,就将它跟丢失的物品作对比,把这些处理用Job的形式,丢到redis里面,有专门的服务器去处理redis里面的任务。
- 说到redis,腾讯云的redis有个小坑,“它的密码不是它的密码”,仔细看使用示例之后你会发现,它的密码是“实例名称:密码”,还以为代码写的有问题,导致redis连接失败。


- 后台有一个专门的服务器,用于计算匹配,推送消息。
/**
* Execute push job.
*
* @return void
*/
public function handle()
{
$foundItem = json_decode($this->foundItems, true);
$lostItem = json_decode($this->lostItems, true);
$distance = $this->getDistance((string)$foundItem["latitude"], (string)$foundItem["longitude"], (string)$lostItem["latitude"], (string)$lostItem["longitude"]);
$sendMessage = "附近有人找到了你丢失的类似物品,快来看看吧!";
if($foundItem["category"]==$lostItem["category"])
{
if ($distance < 5000) {
// 查找device_token
$device_token = PersonalInfo::select("device_token")->where("qqtoken", "")->first();
$pushMessage = new PushMessage();
$pushMessage->pushMessage($device_token["$device_token"], $sendMessage);
}
}
}
- 队列的消费需要一个守护进程监听,这里使用的事python的supervisor如下图所示,我们的消息推送服务器上开启了20个进程同事监听这一个队列,当有消息需要处理的时候,可以最多达到20个并行处理。到此为止,就是后台的简单概况。
[program:push_service]
process_name=%(program_name)s_%(process_num)02d
command=php /home/ubuntu/laravel/didi/artisan queue:work --queue=default --sleep=3 --tries=3
autostart=true
autorestart=true
user=root
numprocs=20
redirect_stderr=true
stdout_logfile=/home/ubuntu/laravel/didi/storage/push_service.log
【总结】
Mini项目,9个人十天的时间,确实有很多考虑不到的地方,跟我厂动辄上亿上千万响应级别的项目,简直是五战的渣渣,但也是一个项目从0到1的实践,踩过了很多坑,也积累了很多经验。
也希望给后面mini项目的同学留个参考,做的简陋,供大家吐槽。
虽然我们的项目
很小,但是对于正常中小型企业的项目,在腾讯云上构建确实是省时省力,减小了不少运维成本,性能也不错,虽然都是低配服务器,但是压测结果还是很理想。
平时在云上搭个小博客啊,建个小网站玩还是挺爽的。
【吐槽】
大概学生身份还没转换回来,这几台服务器就花了接近500块,对于学生来说压力还是有点大啊。亚马逊云学生1年免费,google学生送USD300,我云也要向大厂看齐啊。
镜像、快照貌似不能用啊,要是真的扩容上百台,还是要累死运维哥哥的啊。
【最后】
腾讯云的运营GGMM,看我宣传这么卖力,送张优惠券啊?