Google Cloud Functions + Google PubSub + Google BigQuery

By | 11 July 2017

Öncelikle aşağıdaki açıklamalarla başlamak istedim;

Google Cloud Functions; Sunucu barındırmadan ve yönetmeden Node.js kodlarımızı yazarak, bu Node.js fonksiyonunu tetikleyerek istediğimiz işlemleri yaptırabiliyoruz. Bu fonksiyonu tetikleme yöntemleri; Http Request, Google Storage ve Google PubSub.

Google PubSub: Bağımsız uygulamalar arasında mesajlar gönderip almanıza izin veren tamamen yönetilen bir gerçek zamanlı mesajlaşma servisidir.

Google BigQuery: Büyük ölçekli veri analizi için hızlı, ekonomik ve tamamen yönetilen kurumsal veritabanı.

Bu yazıda Google Cloud Function için bir Node.js fonksiyonu yazacağız ve bunu PubSub ile tetikleyeceğiz. Gelen mesajdaki veriyi de Google Bigquery’e insert edeceğiz.

Google Pub/Sub sistemimizi inşa edelim; bunun için bir publisher ve bir subscriber ihtiyacım var. Mesajları göndereceğim tarafı Php ile Gcloud Client Library kullanarak yapıyorum.

composer require google/cloud

Kütüphanemizi kurduktan sonra publisher için dosyalarımızı oluşturmaya başlayabiliriz. Bulunduğumuz dizinde ‘class’ adında dizin oluşturup içine Gcloud sınıfını oluşturuyorum.

<?php

use Google\Cloud\ServiceBuilder;

class Gcloud
{
    private static $instance;

    //singleton yaklaşımı kullanılarak projede tek instance alınabilen class oluşturuluyor.
    public static function getInstance()
    {
        if (!self::$instance) {
            self::$instance = new Gcloud();
        }
        return self::$instance;
    }

    public function connection()
    {

        try {
            $gcloud = new ServiceBuilder([
                'keyFilePath' => './[project.json]',
                'projectId' => '[projectId]'
            ]);
        } catch (Exception $e) {
            echo "Connection failed: " . $e->getMessage();
            die;
        }

        return $gcloud;
    }

}

Gooogle projemize bağlantı sınıfını oluşturduktan sonra aşağıdaki gibi publisher
dosyamızı oluşturuyoruz.

<?php

require 'vendor/autoload.php';
require 'class/Gcloud.php';
//google cloud bağlantısını gerçekleştiriyoruz
$gcloudInstance = Gcloud::getInstance();
$gcloud = $gcloudInstance->connection();
//pubsub içinde topic set ediliyor.
$pubSub = $gcloud->pubsub();
$topic = $pubSub->topic('mertblog');
//10 tane mesaj göndermek için array set ettik.
$data = [1,2,3,4,5,6,7,8,9,10];
//tek seferde 1000 tane mesaj gönderebiliyoruz, bunun için batchCount oluşturduk
//100 saniyede gönderebileceğimiz mesaj limitli olduğu için 12 saniyelik bekleme süresi ekledik
//limitler ücretlere göre şekillenebiliyor. gönderilen datayı uygun formata getiriyoruz.
$batchCounter = 0;
$publishData = [];
foreach ($data as $key => $number) {
    if ($batchCounter < 1000) {
        $publishData[] = array(
            'data' => $number . '. Message',
            'attributes' => [
                'number' => $number
            ]
        );
        $batchCounter++;
    } else {
        sleep(12);
        $topic->publishBatch($publishData);
        $batchCounter = 0;
        $publishData = [];
        echo PHP_EOL . '1000 messages successfully sent!' . PHP_EOL;
    }
}

?>

Sıra geldi subscriber tarafını yazmaya ve buradaki kodlarımız Node.js ile geliştiriyoruz. Öncelikle aşağıdaki komutu girerek gerekli olan paketlerin kurulumunu yapıyoruz.

npm install --save google-cloud node-datetime

Kurulum tamamlandıktan sonra aşağıdaki gibi dosyamızı oluşturuyoruz.

const gcloud = require('google-cloud')({  //gcloud proje baglantisi gerceklestiriyor
    projectId: '[projectId]',
    keyFilename: './[project.json]'
});

const dt = dateTime.create();  //şuanki tarihi alacağımız obje set ediliyor.

const pubsub = gcloud.pubsub();  //pubsub objesi set ediliyor.
const bigquery = gcloud.bigquery();  //bigquery objesi set ediliyor.

exports.mertblog = function (event, callback) {  //mesajlar burada geliyor ve tetikleniyor
    const data = event.data.attributes;  //mesajın verisi alınıyor.

    let insertData = [{
        "number": data.number,       //bigquery insert data set ediliyor.
        "created_at": dt.format('Ymd')
    }];
    //bigquery insert işlemi gerçekleştiriyor.
    //mertblog dataseti içinde numbers tablosuna insert ediliyor.
    bigquery
        .dataset("mertblog")
        .table("numbers")
        .insert(insertData)
        .then((insertErrors) => {
            console.log('Inserted:');
            data.forEach((row) => console.log(row));

            if (insertErrors && insertErrors.length > 0) {
                console.log('Insert errors:');
                insertErrors.forEach((err) => console.log(JSON.stringify(err)));
            }
        })
        .catch((err) => {
            console.error('ERROR:', JSON.stringify(err));
        });




    callback();
};

Publisher tarafından mesajları gönderdiğimiz anda 10 tane mesaj gidiyor ve aynı
anda çalışan 10 tane Node.js fonksiyonu yazdığımız dosya çalışmaya başlıyor.
Ardından BigQuery insert işlemi gerçekleştiriliyor. Mesajları göndermeden önce
Google Cloud Functions’ı deploy etmemiz gerekiyor. Bunun için bilgisayarımızda Cloud SDK
kurulu olması gerekiyor ki terminal’den gcloud komutunu kullanabilelim. Kuruluma
buradan bakabilirsin. Deploy için aşağıdaki komut yeterli;

gcloud beta functions deploy mertblog --stage-bucket mertblogStorage --trigger-topic mertblog

Şimdi mesajları publisher edebilir ve BigQuery tarafına insert edebiliriz. Debug için Google Cloud arayüzünden Cloud Functions sekmesine gidilebilir. Bu yazıda anlatıcaklarım şimdilik bu kadar, bir daha ki yazıda görüşmek üzere… 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

*