资讯专栏INFORMATION COLUMN

Serverless在游戏、电商行业的一个运用场景示例

Fourierr / 2664人阅读

摘要:本文以使用阿里云函数计算为例,构建一个简单具体的为例,看看这种架构是如何达到快速开发和节约运维成本的。方案在本文中,我们运用阿里云函数计算表格存储,就能快速搭建这个服务,会自动去应对请求流量,同样函数计算也会根据流量自动。

摘要: Serverless 是一种架构理念,具有自己的独特的优势和适用场景。本文以使用阿里云函数计算为例,构建一个简单具体的microservice为例,看看这种架构是如何达到快速开发和节约运维成本的。

点此查看原文:http://click.aliyun.com/m/41322/

Serverless 是一种架构理念,具有自己的独特的优势和适用场景。本文以使用阿里云函数计算为例,构建一个简单具体的microservice为例,看看这种架构是如何达到快速开发和节约运维成本的。

应用场景1

某游戏公司刚开发完一个新的游戏,想要进行一些封闭测试,他们需要一个管理激活码的service来邀请有激活码的玩家来参与封闭测试,同时可能对积极参与封闭测试的玩家,等正式开服后,给予一定的礼包券码

应用场景2

某垂直领域的电商,刚刚起步,流量不是特别大,但发展势头不错。他们需要一个管理优惠码的service

针对上面所说的两个场景,无论是优惠码,激活码等相关码的管理,一般有如下四个:

生成码
使用码
验证码
删除码

传统方案

用户自己去架设服务器,配置数据库,再编写对应的服务,再配备相应的运维人员,总之,不管是硬件成本还是人力成本都不少。

serverless 方案
在本文中,我们运用阿里云API Gateway + 函数计算 + 表格存储(OTS),就能快速搭建这个服务,API Gateway 会自动 scale 去应对请求流量,同样函数计算也会根据流量自动 scale。开发方面,只需要实现好对应的逻辑函数即可。运维方面,省去了管理密匙、打安全补丁等工作,因为用户根本没有需要维护的机器。整个解决方案如下图:

从上图我们可以看出,主要有两个步骤:

函数计算作为 API 网关后端服务, 具体的教程可以参考官方教程和函数计算获取临时token
函数计算结合ots实现具体的逻辑,本文主要讲解这个过程, 并给出具体的代码。

具体步骤

1, 创建一个ots实例,并在实例中创建一张表;在本例中,是在华东2 region创建了code-ots实例,并在该实例中创建了一张表code, 主键是STRING类型


2, 创建对应的service,service下面创建4个函数,分别为gen_code, del_code, query_code, use_code, 具体的代码可以在本文最后附件下载,由于函数要访问ots,这边需要配置service可以读写ots的权限,相关授权教程可以参考函数计算实现流式处理大文件中的具体步骤第2步, 本文最后配置如下图,从下图可知,我们创建的service的服务角色是fc-ots-rw,该角色拥有对ots读写的权限。


具体function

1 生成码
配置event

{
    "num":1000,
    "start period":"2017-12-22 00:00:00",
    "end period":"2017-12-28 00:00:00",
}

通过这个配置的event,设置的目标是产生1000个码, 码的有效期在2017-12-22 00:00:00 至 2017-12-28 00:00:00,默认产生的状态都是UNACTIVED,未激活的

code

# -*- coding: utf-8 -*-
import uuid
import json
import time
from tablestore import *
from tablestore.retry import WriteRetryPolicy
  
table_name = "code"  # 具体的table
ots_name = "code-ots"  # ots 实例
BATCH_NUM =  200

def batch_write_row(client, start, end, num):
    put_row_items = []
    for i in range(0, num):
        uid_str = str(uuid.uuid1())
        primary_key = [("uuid", uid_str)]
        attribute_columns = [("start", start), ("end", end), ("status", "UNACTIVED")]
        row = Row(primary_key, attribute_columns)
        condition = Condition(RowExistenceExpectation.EXPECT_NOT_EXIST)
        item = PutRowItem(row, condition)
        put_row_items.append(item)

    request = BatchWriteRowRequest()
    request.add(TableInBatchWriteRowItem(table_name, put_row_items))
    result = client.batch_write_row(request)

    succ, fail = result.get_put()
    print ("check input table"s put results: is_all_succeed={0}; succ_num={1}; 
            fail_um={2}".format(result.is_all_succeed(), len(succ), len(fail)))
    
    for item in fail:
        print ("Put failed, error code: %s, error message: %s" % (item.error_code, item.error_message))
             
def upload_ots(context, num, start, end):
    endpoint = "https://{}.cn-shanghai.ots-internal.aliyuncs.com".format(ots_name)
    creds = context.credentials
    client = OTSClient(endpoint, creds.accessKeyId,  creds.accessKeySecret, ots_name, 
            sts_token = creds.securityToken, retry_policy = WriteRetryPolicy())
    
    while num > 0:
        w_num = num
        if num > BATCH_NUM:
            w_num = BATCH_NUM
        batch_write_row(client, start, end, w_num)
        num = num - w_num
            
def handler(event, context):
    evt = json.loads(event)
    num = int(evt["num"])
    start = evt["start period"]
    end = evt["end period"]
    start_t = time.mktime(time.strptime(start, "%Y-%m-%d %H:%M:%S"))
    end_t = time.mktime(time.strptime(end, "%Y-%m-%d %H:%M:%S"))
    print uuid.uuid1(), type(uuid.uuid1())
    upload_ots(context, num, start_t, end_t)
    return "ok"

2 使用码

配置event

{
   "uuid":"254804e8-e707-11e7-9c21-0242ac110004"
}

假设使用码254804e8-e707-11e7-9c21-0242ac110004,只有表中存在这个码并且这个码是UNACTIVED才返回SUCCESS,并且把该码的状态设置为ACTIVED。其他情况,比如不存在这个码,或者是存在这个码但是已经被激活使用过,都返回FAIL

code

# -*- coding: utf-8 -*-
from tablestore import *
from tablestore.retry import WriteRetryPolicy
import json

table_name = "code"
ots_name = "code-ots"

def update_row(client, uuid):
    primary_key = [("uuid",uuid)]
    update_of_attribute_columns = {
        "PUT" : [("status","ACTIVED")],
    }
    row = Row(primary_key, update_of_attribute_columns)
    condition = Condition(RowExistenceExpectation.EXPECT_EXIST, SingleColumnCondition("status", "UNACTIVED", ComparatorType.EQUAL)) 
    try:
        consumed, return_row = client.update_row(table_name, row, condition) 
        print ("Update succeed, consume %s write cu." % consumed.write)
    except Exception as e:
        return "FAILED"
    return "SUCCEED"
      
def handler(event, context):
    endpoint = "https://{}.cn-shanghai.ots-internal.aliyuncs.com".format(ots_name)
    creds = context.credentials
    client = OTSClient(endpoint, creds.accessKeyId,  creds.accessKeySecret, ots_name, 
            sts_token = creds.securityToken, retry_policy = WriteRetryPolicy())
    evt = json.loads(event)
    uuid = str(evt["uuid"])
    return update_row(client, uuid)

3 查询码

配置event

{
   "uuid":"254804e8-e707-11e7-9c21-0242ac110004"
}

假设查询码254804e8-e707-11e7-9c21-0242ac110004,只有表中不存在这个码返回NO EXISTED, 存在的话,则返回表中记录的状态

code

# -*- coding: utf-8 -*-
from tablestore import *
from tablestore.retry import WriteRetryPolicy
import time,json

table_name = "code"
ots_name = "code-ots"

def get_row(client, uuid):
    primary_key = [("uuid", uuid)]
    columns_to_get = []

    cond = CompositeColumnCondition(LogicalOperator.OR)
    cond.add_sub_condition(SingleColumnCondition("status", "UNACTIVED", ComparatorType.NOT_EQUAL))
    cond.add_sub_condition(SingleColumnCondition("status", "UNACTIVED", ComparatorType.EQUAL))

    consumed, return_row, next_token = client.get_row(table_name, primary_key, columns_to_get, cond, 1)
    print ("Read succeed, consume %s read cu." % consumed.read)

    if return_row is None:
        return "NO EXISTED"

    
    status = "UNKNOWN"
    for att in return_row.attribute_columns:
        print ("name:%s	value:%s	timestamp:%d" % (att[0], att[1], att[2]))
        if att[0] == "status":
            status = att[1]
        if att[0] == "start":
            start = att[1]
        if att[0] == "end":
            end = att[1]

    current_time = time.time()
    if current_time > end or current_time < start:
        status = "TIMEINVALID"
    return status   

def handler(event, context):
    endpoint = "https://{}.cn-shanghai.ots-internal.aliyuncs.com".format(ots_name)
    creds = context.credentials
    client = OTSClient(endpoint, creds.accessKeyId,  creds.accessKeySecret, ots_name, 
            sts_token = creds.securityToken, retry_policy = WriteRetryPolicy())
    evt = json.loads(event)
    uuid = str(evt["uuid"])
    return get_row(client, uuid)

4 删除码

配置event

{
   "uuid":"254804e8-e707-11e7-9c21-0242ac110004"
}

假设删除码254804e8-e707-11e7-9c21-0242ac110004,不管表中是否存在这个码,只要表中没有这个码了就是成功删除,除非ots sdk delete_row抛出异常

code

# -*- coding: utf-8 -*-
from tablestore import *
from tablestore.retry import WriteRetryPolicy
import json

table_name = "code"
ots_name = "code-ots"

def delete_row(client, uuid):
    primary_key = [("uuid",uuid)]
    row = Row(primary_key)
    condition = Condition(RowExistenceExpectation.IGNORE, SingleColumnCondition("status", "", ComparatorType.NOT_EQUAL))
    try:
        consumed, return_row = client.delete_row(table_name, row, condition) 
        print ("Delete succeed, consume %s write cu." % consumed.write)
    except:
        return "FAILED"
    
    return "SUCCEED"
      
def handler(event, context):
    endpoint = "https://{}.cn-shanghai.ots-internal.aliyuncs.com".format(ots_name)
    creds = context.credentials
    client = OTSClient(endpoint, creds.accessKeyId,  creds.accessKeySecret, ots_name, 
            sts_token = creds.securityToken, retry_policy = WriteRetryPolicy())
    evt = json.loads(event)
    uuid = str(evt["uuid"])
    return delete_row(client, uuid)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/11812.html

相关文章

  • Serverless游戏电商行业一个运用场景示例

    摘要:本文以使用阿里云函数计算为例,构建一个简单具体的为例,看看这种架构是如何达到快速开发和节约运维成本的。方案在本文中,我们运用阿里云函数计算表格存储,就能快速搭建这个服务,会自动去应对请求流量,同样函数计算也会根据流量自动。 摘要: Serverless 是一种架构理念,具有自己的独特的优势和适用场景。本文以使用阿里云函数计算为例,构建一个简单具体的microservice为例,看看这种...

    Anchorer 评论0 收藏0
  • 2019风向趋势分析报告——覆盖5G、人工智能、金融科技等领域

    摘要:往年回顾氪研究院长期追踪一级市场行业动态,深入调研各领域细分赛道最具代表性的企业,从行业发展环境成长性竞争格局未来趋势等角度进行分析与研究,输出了包含人工智能金融教育医疗交通文娱电商泛科技在内的上百份报告。 showImg(http://upload-images.jianshu.io/upload_images/13825820-d8888a77e920c16f.jpg?imageM...

    Moxmi 评论0 收藏0
  • 小程序上云,有点猛

    摘要:另外小程序云应用有一套高可用架构,提供监控预警能力。自主可控小程序云应用提供服务器,开发者可以拥有登录或重启,也可以修改密码。也就是说,服务器是由小程序云应用提供,但使用权归开发者。  前不久有一个朋友问我,到底是做什么端的小程序比较好?   我只问了一句,你的产品里是否涉及钱和服务,如果涉及这两者,建议你选择支付宝小程序。你可以通过其他小程序玩裂变,但如果你想做服务和商业,一定要考虑支付宝...

    jsdt 评论0 收藏0
  • 基于阿里云Serverless架构下函数计算最新应用场景详解(一)

    摘要:如果使用阿里云函数计算,您将高峰期每小时的访问日志,或者低谷期每小时的访问日志交给一个计算函数处理,并将处理结果存到中。下面结合阿里云的函数计算产品来讲解各个应用场景中架构以及如何解决的场景中的痛点。 摘要: Serverless概念是近年来特别火的一个技术概念,基于这种架构能构建出很多应用场景,适合各行各业,只要对轻计算、高弹性、无状态等场景有诉求的用户都可以通过本文来普及一些基础概...

    Eidesen 评论0 收藏0

发表评论

0条评论

Fourierr

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<