`
sillycat
  • 浏览: 2550780 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Serverless with NodeJS and TencentCloud 2020(1)Running with Component

 
阅读更多
Serverless with NodeJS and TencentCloud 2020(1)Running with Component

More configuration here
https://github.com/serverless-components/tencent-scf/blob/master/docs/configure.md

Check this file
> vi ~/.tencent.credentials
cat ~/.tencent.credentials
[default]
tencent_secret_id=AKIDNccOxHLLagcxxxxx
tencent_secret_key=uZzGI5dw2tU17Axxxxx

API gateway trigger Cloud Lambda
My serverless.yml is as follow:
taskmanager:
    component: "@serverless/tencent-scf"
    inputs:
      name: taskmanager
      codeUri: ./
      handler: handler.main_handler
      runtime: Nodejs8.9
      region: ap-shanghai
      description: Task Manager to Fetch Tasks
      memorySize: 128
      timeout: 60
      exclude:
        - .gitignore
        - .git/**
        - .serverless
        - .env
        - app.js
        - .DS_Stone
      events:
        #- timer:
        #    name: timer
        #    parameters:
        #      cronExpression: '*/5 * * * *'
        #      enable: true
        - apigw:
            name: manager_trigger
            parameters:
              protocols:
                - http
              description: Manager all Tasks
              environment: release
              endpoints:
                - path: /manager
                  method: GET

My nodeJS code handler.js is as follow:
'use strict';
const {OrderService} = require('./src/service');
const {DB} = require('async-mysql-wrapper');

exports.main_handler = async (event, context, callback) => {
    console.log("main_hander, event:" + JSON.stringify(event));
    DB.init({
        dbConnectionConfig: {
            host: process.env.MYSQL_DB_ADDRESS,
            user: process.env.MYSQL_DB_USER,
            database: process.env.MYSQL_DB_NAME,
            password: process.env.MYSQL_DB_PASSWORD,
            connectionLimit: process.env.MYSQL_DB_POOL_SIZE || 2,
            waitForConnections: true,
            dateStrings: true,
        },
        logLevel: 'debug'
    });
    await OrderService.calculateOrderInfo();
    return "success";
};

The service codes is like this index.js
const OrderService = require('./order-service');

module.exports = {
    OrderService,
}

The service codes is just normal business logic order-service.js
const {OrderDAO} = require('../model');
const LambdaService = require('./lambda-service');
const DateUtil = require('../util/date-util');
const _ = require('lodash');

const lookBackDays = process.env.LOOKBACK_DAYS || 30;
const batchSize = process.env.BATCH_SIZE || 2;

const Bottleneck = require('bottleneck');

const limiter = new Bottleneck({
    maxConcurrent: 1,
    minTime: process.env.RATE_TIME || 1000
});

class OrderService {

    static async calculateOrderInfo() {
        console.log("calculate get invoked at time: " + DateUtil.currentTime());
        const startDate = DateUtil.lookBackDays(lookBackDays);
        const endDate = DateUtil.lookBackDays(1);
        console.log("loading date between " + startDate + " " + endDate);
        const items = await OrderDAO.loadIDRange(startDate, endDate);
        if (items && items.length > 0) {
            console.log("start to send orders " + items.length);
            const chunks = _.chunk(items, batchSize);
            for(const chunk of chunks) {
                const ids = _.map(chunk, "id");
                const idStr = _.join(ids, ",");
                await limiter.schedule(() => LambdaService.callRunner('taskrunner', 'Event', { "message": idStr }) );
            }
        }
        console.log("All data were sent to runners at time: " + DateUtil.currentTime());
    }

}

module.exports = OrderService;

The sample project is services.task_runner.zip and services.task_manager.zip

The package.json dependencies looks like this:
{
  "name": "task-manager",
  "version": "1.0.0",
  "description": "Data Calculate Manager",
  "repository": {
    "type": "git",
    "url": "https://github.com/luohuazju/sales-services.git"
  },
  "license": "UNLICENSED",
  "scripts": {},
  "author": "Yiyi Kang",
  "dependencies": {
    "async-mysql-wrapper": "https://github.com/luohuazju/async-mysql-wrapper",
    "bottleneck": "2.19.5",
    "lodash": "4.17.15",
    "moment": "2.24.0",
    "mysql": "2.18.1",
    "tencentcloud-sdk-nodejs": "^3.0.117"
  },
  "devDependencies": {
    "dotenv": "6.2.0",
    "serverless-tencent-scf": "^0.1.36"
  }
}

The DAO layer will be simple after that index.js
const OrderDAO = require('./order-model');

module.exports = {
    OrderDAO,
}

The domain layer order-model.js is as follow:
const {Repository} = require('async-mysql-wrapper')

class OrderDAO extends Repository {

    constructor() {
        super('order', 'id', {
            'gmt_create': 'gmtCreate',
            'gmt_modified': 'gmtModified',
            'brand_id': 'brandID',
            'product_id': 'productID',
            'channel_id': 'channelID',
            'event_id': 'eventID',
            'employee_id': 'employeeID'
        })
    }

    async loadIDRange(startDate, endDate) {
        //select id, date from sales.order where date >='2019-12-20'  and date < '2019-12-21';
        const query = `SELECT id FROM ?? WHERE date >= ? and date < ?`;
        return await this.selectList(query, [this.tableName, startDate, endDate]);
    }

}

module.exports = new OrderDAO();


References:
https://github.com/tencentyun/serverless-tencent-scf
Demo Project
https://github.com/tencentyun/scf-demo-repo

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics