Bermula dari project yang sedang saya kerjakan di kantor yaitu aplikasi iOS, pada kesempatan ini saya akan share sedikit mengenai dasar - dasar pada swift :D.

Apa Itu Swift ?

Swift adalah bahasa pemrograman yang digunakan untuk membangun aplikasi untuk produk apple seperti iOS, OSX dan lain sebagainya.

Terdapat 2 bahasa pemrograman yang dapat kita gunakan untuk mengembangkan aplikasi untuk produk apple yaitu Objective-C dan Swift. Pada artikel ini, penulis hanya membahas mengenai bahasa pemrograman swift untuk versi 3, untuk migrasi versi swift 3 silahkan lihat di migration swift 3.

Mengapa Menggunakan Swift ?

Mungkin beberapa developer swift pemula pasti akan bertanya, mengapa kita menggunakan swift ? mengapa tidak menggunakan Objective-C ?, Baiklah kita akan membahas satu - persatu.

Pada zaman sekarang, para developer core dari berbagai bahasa pemrograman akan membuatkan sebuah bahasa dimana bahasa ini lebih mudah dimengerti manusia, berbeda dengan developer apple, mereka membuat bahasa pemrograman swift ini sendiri lebih dekat dengan mesin layaknya bahasa C, C++ dan Objective-C sehingga akan meningkatkan performance dari aplikasi.

Swift sendiri dibangun dengan paradigma yang berbeda dengan Objective-C, dimana bahasa pemrograman swift lebih mudah dibaca jika anda beralirah ke bahasa pemrograman berorientasi object seperti java, javascript, ruby dan lain sebagainya. Jika anda dulu nya adalah developer bahasa C atau C++ maka anda akan lebih mudah membaca source code Objective-C. Jika anda adalah developer pemula, penulis sarankan untuk mempelajari bahasa pemrograman swift 3 karena Objective-C dan swift adalah bahasa pemrograman yang berbeda dan tidak ada kaitan dari kedua nya.

Jika anda adalah seorang developer android, terlebih jika anda telah terbiasa menggunakan bahasa pemrograman kotlin maka anda tidak akan terlalu susah jika migrasi dari android ke iOS. Bahkan anda akan memiliki learning curve yang lebih cepat.

Latihan Swift

Pada artikel ini, penulis menggunakan IBM Swift Sandbox karena kita hanya akan latihan cli dengan menggunakan bahasa pemrograman swift 3. IBM Swift Sandbox adalah salah satu editor cli online untuk latihan bahasa pemrograman swift, disana terdapat 2 versi yaitu swift versi 2 dan versi 3. Pada artikel ini, penulis akan menggunakan swift 3.

Latihan Variabel Pada Swift

Secara default, pada IBM Swift Sandbox akan menampilkan source code seperti berikut.

print("Hello world!")

Source code diatas berfungsi untuk menampilkan sebuah tulisan Hello Word! :-). Tahap selanjutnya tulisankan code seperti berikut.

let nama: String = "rizki mufrizal"
print(nama)

Codingan diatas berfungsi untuk membuat sebuah variabel dengan tipe data string, lalu kita inisialisasi dengan sebuah string lalu kita tampilkan. Di dalam swift terdapat 2 cara untuk mendeklarasikan variabel yaitu dengan menggunakan let dan var, dimana let berfungsi sebagai constanta atau immutable sehingga hanya bisa diinisialisasi sekali saja, berbeda dengan var yang bersifat mutable sehingga dapat diubah - ubah. Silahkan ubah source code diatas menjadi seperti berikut.

let nama: String = "rizki mufrizal"
nama = "ganti aja"
print(nama)

maka akan muncul error seperti berikut.

ERROR at line 5, col 6: cannot assign to value: 'nama' is a 'let' constant
nama = "ganti aja"
~~~~ ^
NOTE at line 4, col 1: change 'let' to 'var' to make it mutable
let nama: String = "rizki mufrizal"
^~~
var

Lalu silahkan ubah seperti berikut.

var nama: String = "rizki mufrizal"
nama = "ganti aja"
print(nama)

maka hasil nya akan sukses dikarenakan kita ingin mengubah value yang ada di dalam variabel nama.

Latihan Function Pada Swift

Sama seperti bahasa lain, swift juga dapat menggunakan function / method. Function / method pada swift juga dapat mengembalikan nilai berdasarkan tipe data nya dan juga dapat berupa void atau tidak mengembalikan nilai.

Berikut adalah contoh jika mengambalikan nilai.

func perjumlahan(angka1: Int, angka2: Int) -> Int {
    return angka1 + angka2
}
print("hasilnya adalah : \(perjumlahan(angka1: 2, angka2: 3))")

Diatas adalah contoh jika kita mengembalikan nilai, dan pada source code diatas kita menggunakan fungsi \() dimana fungsi tersebut adalah fungsi untuk mengeksekusi sebuah function atau variabel yang berada di dalam sebuah string atau “” (kutip dua).

Berikut adalah contoh jika function / method yang tidak mengembalikan nilai.

func perjumlahan(angka1: Int, angka2: Int) {
    print("hasilnya adalah : \(angka1 + angka2)")
}
perjumlahan(angka1: 2, angka2: 3)

Latihan Array Pada Swift

Pada latihan ini, kita akan membuat sebuah struct / record. Apa itu struct / record ?

Struct / record adalah kumpulan data dengan type yang berbeda

Sekilas memang mirip dengan array, akan tetepi terdapat perbedaan dimana array mempunyai banyak data dengan type data yang sama sedangkan struct / record memiliki data yang banyak dan memiliki type data yang berbeda. Jika kita menggunakan java, maka struct / record sama dengan class domain / entity / pojo. Berikut adalah contoh penggunaan array struct pada swift 3.

struct Barang {
    var idBarang: String?
    var namaBarang: String?
    var jumlahBarang: Int?
}

var barangs = [Barang]()

barangs.append(Barang(idBarang: "B001", namaBarang: "Rinso", jumlahBarang: 10))

for b in barangs {
    print("id Barang     : \(b.idBarang)")
    print("Nama Barang   : \(b.namaBarang)")
    print("Jumlah Barang : \(b.jumlahBarang)")
}

Maka hasilnya akan seperti berikut.

id Barang     : Optional("B001")
Nama Barang   : Optional("Rinso")
Jumlah Barang : Optional(10)

Agar tulisan Optional hilang maka tambahkan ! seperti berikut.

struct Barang {
    var idBarang: String?
    var namaBarang: String?
    var jumlahBarang: Int?
}

var barangs = [Barang]()

barangs.append(Barang(idBarang: "B001", namaBarang: "Rinso", jumlahBarang: 10))

for b in barangs {
    print("id Barang     : \(b.idBarang!)")
    print("Nama Barang   : \(b.namaBarang!)")
    print("Jumlah Barang : \(b.jumlahBarang!)")
}

Maka hasilnya akan seperti berikut.

id Barang     : B001
Nama Barang   : Rinso
Jumlah Barang : 10

Sekian artikel mengenai Belajar Swift, jika ada saran dan komentar silahkan isi dibawah dan terima kasih :)

Pada artikel ini, penulis akan membahas mengenai salah satu protokol Authorization yang banyak digunakan dikalangan developer. Sebelum memasuki pembahasan mengenai OAuth2, kita akan membahas terlebih dahulu mengenai Authentication dan Authorization.

Apa Itu Authentication ?

Authentication adalah suatu proses untuk menentukan identitas seseorang.

Untuk menentukan identitas seseorang kita dapat menggunakan kerahasiaan informasi seperti contoh berikut

Kerahasiaan Informasi Deskripsi
Password Hanya pengguna yang mengetahui password
PIN Hanya pengguna yang mengetahui PIN
private key hanya pengguna yang memiliki private key

Dari kerahasiaan informasi diatas, kita dapat menentukan identitas seseorang, misalnya ketika seseorang login pada sebuah aplikasi, jika dia menggunakan username dan password yang benar maka sudah dipastikan bahwa yang login tersebut adalah pengguna sebenarnya.

Selain kerahasiaan informasi, untuk menentukan identitas seseorang kita dapat menggunakan keunikan dari seorang pengguna, contohnya.

Keunikan Informasi Deskripsi
Retina Hanya dimiliki oleh satu pengguna
Fingerprint Hanya dimiliki oleh satu pengguna

Setiap pengguna pasti mempunyai keunikan informasi seperti fingerprint, dimana fingerprint antara 1 pengguna dengan pengguna lain pasti memiliki perbedaan. Perbedaan ini dapat kita lihat dari garis - garis sidik jari yang berbeda - beda.

Apa Itu Authorization ?

Authorization adalah proses dimana kita akan memberikan hak akses kepada pihak ketiga untuk dapat melakukan akses data yang kita miliki.

Proses authorization akan dilakukan jika anda telah melakukan authentication, karena authentication diperlukan untuk identifikasi user yang akan memberikan hak akses datanya. Berikut adalah contoh penggunaan authorization, misalnya anda memiliki akun google, kemudian anda ingin melakukan registrasi pada layanan web lain, pada web tersebut terdapat fitur login/register dengan menggunakan akun google, maka kita dapat menggunakan fitur tersebut. Pada saat fitur tersebut kita gunakan maka nantinya google akan menanyakan apakah kita memberikan hak akses agar aplikasi tersebut dapat mengakses data kita yang terdapat pada google. Jika memberikan hak akses maka web tersebut akan mendapatkan data kita, jika tidak maka google tidak akan memberikan data anda. Proses diatas adalah salah satu contoh dari proses authorization pada aplikasi.

Apa Itu OAuth2 ?

OAuth2 adalah kepanjangan dari open authorization dimana OAuth2 banyak digunakan dikalangan developer sebagai proses authorization sebuah aplikasi.

Dengan menggunakan protokol ini, maka aplikasi pihak ketiga dapat mengakses data dari aplikasi yang telah kita bangun. Di dalam OAuth2 terdapat beberapa grant type diantaranya adalah :

Grant Type Authorization Code

Pada grant type ini, kita akan menggunakan generate code yang berasal dari authorization server untuk ditukarkan dengan sebuah token, dimana token ini kita gunakan untuk mengakses sebuah resource / API.

Berikut adalah gambar flow untuk Authorization Code :

oauth_authorization_code

Gambar diatas saya ambil dari dokumentasi oracle. Gambar diatas menjelaskan bahwa ketika kita menggunakan OAuth2, maka kita seharusnya menggunakan 2 server, yaitu yang satu bertugas sebagai authorization server, dimana server ini yang akan memberikan hak akses kepada apilkasi pihak ketiga. Sedangkan server yang satu nya lagi sebagai resource server atau sebagai penyedia API.

Ketika ada aplikasi pihak ketiga akan mengakses API, API akan terlebih dahulu bertanya kepada authorization server, apakah token yang dikirim valid atau tidak, jika valid maka resource server akan memberikan resource yang dibutuhkan dan jika teryata tidak valid maka akan menampilkan bahwa aplikasi tersebut tidak berhak melakukan akses terhadap resource tersebut.

Pada flow ini, user nantinya akan melakukan login pada authorization server, dimana url pada login tersebut terdapat client id dan authorization type dari aplikasi yang akan akan mengakses resource tersebut. Ketika user melakukan approve, authorization server akan melakukan redirect ke aplikasi pihak ketiga dengan membawa sebuah code, dimana code ini akan digunakan oleh aplikasi pihak ketiga untuk menukarkan nya dengan access token, setelah berhasil ditukarkan maka code ini tidak dapat digunakan lagi. Setelah mendapatkan access token, aplikasi pihak ketiga dapat melakukan akses terhadap resource yang telah di approve. Authorization Code biasanya digunakan oleh aplikasi - aplikasi yang dapat menyimpan client id dan client secret secara aman, contonya seperti Java, NodeJS, Ruby, PHP, dan lain sebagainya.

Grant Type Resource Owner Password Credentials

Pada grant type ini, kita akan menggunakan username dan password langsung dari owner nya. Grant type ini biasanya digunakan jika aplikasi yang dibangun merupakan aplikasi pribadi atau pembuat aplikasi berasal dari perusahaan yang sama, contohnya adalah ketika kita melakukan login pada aplikasi facebook.

Flow ini tidak direkomendasikan lagi dikarenakan aplikasi pihak ketiga diharuskan mengirimkan username dan password user sehingga memungkinkan aplikasi pihak ketiga dapat menggunakan akun owner nya. berikut adalah gambar flow grant type resource owner password credentials yang saya ambil dari dokumentasi oracle.

oauth_resource_owner_password_credentials.png

Grant Type Client Credentials

Grant type selanjutnya adalah client credentials, dimana grant type ini biasanya digunakan oleh aplikasi - aplikasi yang telah menjalin kerja sama dengan suatu perusahaan. Masing - masing aplikasi pihak ketiga akan mendapatkan client id dan client secret, dengan menggunakan client id dan client secret, mereka menukarkan nya dengan access token, pada flow ini, tidak diberikan refresh token, hanya terdapat access token, sehingga apabila access token expired maka mereka diwajibkan untuk mengirim kembali client id dan client secret tersebut untuk ditukarkan dengan access token. berikut adalah gambar grant type client credentials yang saya ambil dari dokumentasi oracle.

oauth_client_credentials.png

Grant Type Implicit Client

Grant type yang terakhir adalah implicit client, grant type ini biasanya digunakan untuk client yang tidak dapat menyimpan client secret dengan aman, contohnya seperti Angular JS, Vue JS, React JS dan lain sebagainya. Pada flow ini, terdapat beberapa langkah yang akan dijalankan, berikut adalah langkah - langkahnya :

  • user mengakses aplikasi pihak ketiga dan melakukan login.
  • aplikasi pihak ketiga akan melakukan redirect ke halaman login authorization server
  • user melakukan approve
  • aplikasi pihak ketiga mendaptkan code, kemudian ditukarkan dengan access token
  • aplikasi pihak ketiga mengakses resource dengan access token tersebut
  • resource server akan menanyakan apakah access token valid atau tidak kepada authorization server.

Pada grant type ini, biasanya authorization server tidak akan memberikan refresh token dikarenakan penyimpanan refresh token yang tidak aman. Berikut adalah gambar grant type implicit client yang saya ambil dari dokumentasi digital ocean.

oauth2_implicit_client.png

Kata - Kata Asing Pada OAuth2

Pada tulisan diatas terdapat beberapa kata - kata asing, berikut adalah penjelasan nya.

  • Client id : adalah id yang mewakili dari 1 client yang akan mengakses resource / API
  • Client Secret : adalah pasangan dari client id, bisa disebut juga sebagai password nya
  • access token : token yang digenerate oleh authorization server, token ini memiliki massa nya sehingga tidak dapat digunakan dalam jangka waktu yang lama.
  • refresh token : token ini digunakan untuk meminta access token yang baru dikarenakan access token yang lama telah expired.
  • resource server : server yang menyediakan data / API.
  • authorization server : server yang melakukan pengecekan authentication dan authorization.

Best Practice Implementasi OAuth2

Best practice yang saya buat pada artikel ini berasal dari flow teknologi Spring OAuth2. Mungkin beberapa dari anda akan bertanya, mengapa menggunakan spring ? mengapa tidak menggunakan teknologi lain ?, yups menurut pengalaman saya, dari beberapa project yang pernah saya kerjakan, spring adalah salah satu framework yang sangat banyak menyediakan fitur - fitur yang dibutuhkan terutama untuk kebutuhan OAuth2 dibandingkan framework lain misalnya seperti sails js, express js dan sebagainya. Contohnya jika pada node js, saya menggunakan oauth2orize, dimana library tersebut tidak menyediakan schema database dan tidak support untuk strategy in memory token store dan remote token service, Sehingga kita wajib membuat schema tersendiri dan harus menyesuaikan sendiri.

Strategi OAuth2

Strategi yang biasanya saya gunakan jika menggunakan Spring OAuth2 :

  • Authorization dan Resource server berada di dalam 1 war / aplikasi, contoh ini biasanya menggunakan in memory token sehingga antara Authorization dan Resource server biasanya saling bekerja sama.
  • Authorization dan Resource server berada pada server yang berbeda atau dapat dikatakan bahwa mereka berbeda war / aplikasi. Untuk metode ini, kita mempunyai 3 strategi yaitu :
    • Remote token service, dimana Authorization server akan menggunakan in memory token, resource server akan melakukan pengecekan melalui protokol http apakah token valid atau invalid.
    • Sharing database, biasanya saya akan menggunakan strategi ini, mengapa demikian ? dikarenakan saya biasanya ingin agar data seperti grant type, expired token dan lain nya dapat berjalan secara dinamis sehingga kita tidak perlu ribet untuk mengubah codingan lagi. Schema OAuth2 pada Spring OAuth2 dapat anda lihat di schema sql atau anda dapat menggunakan schema yang saya gunakan di schema sql.
    • Http Session Redis, pada strategi ini biasanya antara resource dan authorization server akan melakukan koneksi ke redis, dimana semua token akan disimpan ke redis. Apabila resource server akan diakses, resource server akan melakkan pengecekan pada redis. Jika anda menggunakan spring maka anda dapat menggunakan Spring Session. Ketika anda melakukan authentication, jika credential anda sesuai maka token akan disimpan ke redis, ketika token tersebut expired maka token tersebut akan dihapus dari redis.

Penggunaan Token

Setiap client biasanya bisa memiliki lebih dari 1 grant type yang telah kita jelaskan diatas. Bagaimana jika client memiliki banyak aplikasi, apakah setiap token yang digenerate akan disimpan di database ? bagaimana jika client tersebut memiliki banyak grant type ? nah ini merupakan dilema yang pernah saya temui pada saat membangun OAuth2 pada node js dikarenakan saya membuatnya mulai dari 0. Dikarenakan saya masih kurang paham mengenai OAuth2, saya mencoba membuat sebuah project OAuth2 dengan strategy sharing database pada Spring OAuth2, dan teryata flow dari Spring OAuth2 telah terstruktur, bahkan spring OAuth2 menyediakan custom token dengan menggunakan token extractor, tidak hanya custom token, kita juga dapat melakukan custom output token, misalnya kita ingin token yang digenerate adalah token JWT (Json Web Token). Berikut adalah flow yang harus anda terapkan jika anda membuat OAuth2 secara manual dengan menggunakan sharing database, flow ini berdasarkan referensi dari Spring OAuth2.

  • Silahkan buat schema database seperti schema Spring OAuth2 diatas.
  • Setiap grant type, hanya memiliki 1 access token dan refresh token.
  • Pada saat generate token, kita akan melakukan pengecekan terlebih dahulu pada database, jika client id suatu client memiliki token maka kita akan cek apakah token tersebut telah expired atau belum, jika expired maka kita akan generate ulang token, token yang baru akan diupdate di database dan token tersebut kita berikan kepada client tersebut, jika token tidak expired maka kita tinggal mengembalikan token tersebut, jika token belum tersedia berdasarkan client id dan grant type maka kita generate token baru dan simpan ke database.
  • Pada saat refresh token, kita juga akan cek terlebih dahulu, apakah token telah expired atau belum, jika expired maka token baru akan digenerate dan diupdate yang ada di database, jika tidak expired maka kita kembalikan token yang ada di database.

Berdasarkan flow diatas, dapat kita simpulkan bahwa setiap 1 client bisa mempunyai banyak grant type. Dimana setiap 1 client dengan 1 grant type hanya memiliki 1 token yang berlaku meskipun mereka memiliki banyak aplikasi, Jadi jika si client mempunyai 4 grant type, maka dia memiliki 4 token dimana token tersebut mempunya hak akses yang berbeda - beda, bisa saja yang 1 hanya memiliki hak akses read, yang satu nya hanya untuk write dan yang satu nya lagi untuk read dan write.

Bagi anda yang ingin melihat contoh source code codingan, silahkan lihat di Spring OAuth2 Custom. Sekian artikel mengenai Belajar OAuth2, jika ada saran dan komentar silahkan isi dibawah dan terima kasih :)

Bicara mengenai database, seorang database administrator harus mengetahui seluk beluk dari database, salah satunya adalah proses backup dan restore database. Database tanpa backup adalah suatu hal yang sangat fatal dikarenakan jika suatu waktu terjadi sesuatu pada database production maka hilang sudah semua harapan :D. Pada artikel ini, penulis akan mencoba membuat sebuah backup data lalu kita akan restore.

Perlengkapan Project

Untuk membuat virtual database maka kita akan menggunakan docker, bagi anda yang belum mengerti tentang docker, silakan baca artikel Belajar Docker. Silahkan jalan docker anda, jika anda pengguna linux maka secara default service docker akan berjalan, jika anda pengguna osx maka anda harus menjalankan docker terlebih dahulu. Berikut adalah arsitektur yang akan kita gunakan untuk membuat backup dan restore database mongodb.

arsitektur-backup-restore.svg

Dari gambar diatas, kita dapat melihat bahwa nantinya akan ada 2 container, dimana container tersebut berisi database production dan database backup. Biasanya antara database production dan backup berada pada server yang berbeda.

Membuat Backup Database

Sebelum kita membuat backup database, kita akan melakukan setup docker terlebih dahulu, silahkan buka terminal anda, lalu jalankan perintah berikut untuk mendownload image mongodb.

docker pull mongo

Setelah selesai, silahkan anda membuat docker-compose.yml karena kita akan menggunakan docker compose. Isikan source code seperti berikut.

mongodb-production:
  container_name: mongodb-production
  image: mongo:latest
  ports:
    - 27000:27017

mongodb-backup:
  container_name: mongodb-backup
  image: mongo:latest
  links:
    - mongodb-production
  ports:
    - 27001:27017

Dari konfigurasi diatas dapat kita lihat bahwa container mongodb-backup membutuhkan dependency dari mongodb-production. Untuk menjalankan kedua docker diatas, silahkan gunakan perintah berikut.

docker-compose up

Jika berhasil maka di terminal anda akan muncul seperti berikut.

Screen Shot 2017-02-08 at 2.43.17 PM.png

Langkah selanjutnya kita akan membuat file shell script, bagi anda yang belum paham shell script, silahkan baca pada artikel Belajar Shell Script. Silahkan buat sebuah file dengan nama mongodb-backup.sh, kemudian isikan codingan seperti berikut.

#!/bin/bash
# author Rizki Mufrizal

HOST="127.0.0.1"
PORT="27017"
REMOTE_DB="2016"
USER=""
PASS=""
PATH_BACKUP="/var/database-backup"

mongodump --db=$REMOTE_DB --username=$USER --password=$PASS --host=$HOST --port=$PORT --out=$PATH_BACKUP

Untuk parameter environment seperti nama database, username, password dan lain - lain kita langsung membuat per variabel sehingga nantinya hanya perlu diubah pada bagian variabel saja. Untuk melakukan backup, kita akan menggunakan mongodump, dimana mongodump ini mempunya beberapa parameter diantaranya adalah database yang diremote, username, password, host, port dan folder backup. Karena file shell script ini akan kita gunakan di dalam container docker maka kita harus melakukan setting ulang dockernya. Silahkan buat sebuah file dengan nama Dockerfile kemudian isikan codingan seperti berikut.

FROM mongo:latest

RUN mkdir /backup-restore
WORKDIR /backup-restore
ADD . /backup-restore

Setelah selesai, sekarang jalankan perintah berikut untuk menghapus container yang lama.

docker stop $(docker ps -a -q) && docker rm $(docker ps -a -q)

Setelah selesai, kemudian kita akan membuat image baru dengan perintah berikut.

docker build -t rizki.mufrizal/mongo-backup .

Jika berhasil maka akan muncul output seperti berikut.

Sending build context to Docker daemon 10.24 kB
Step 1/4 : FROM mongo:latest
 ---> 59dbd3885751
Step 2/4 : RUN mkdir /backup-restore
 ---> Running in f7710c593a1b
 ---> 7eeacbf6f587
Removing intermediate container f7710c593a1b
Step 3/4 : WORKDIR /backup-restore
 ---> 89413f734f6d
Removing intermediate container 019a58f8d2ba
Step 4/4 : ADD . /backup-restore
 ---> c593b1efba36
Removing intermediate container 3129347a292d
Successfully built c593b1efba36

Karena ada perubahan konfigurasi, maka kita harus melakukan perubahan pada file docker-compose.yml seperti berikut.

mongodb-production:
  container_name: mongodb-production
  image: mongo:latest
  ports:
    - 27000:27017

mongodb-backup:
  container_name: mongodb-backup
  image: rizki.mufrizal/mongo-backup
  links:
    - mongodb-production
  ports:
    - 27001:27017

Lalu jalankan kembali docker compose dengan perintah.

docker-compose up

Test Backup Data

Setelah selesai melakukan konfigurasi, langkah selanjutnya kita akan mencoba mengakses database mongodb yang versi production dengan perintah berikut.

docker exec -i -t mongodb-production /bin/bash

Kemudian silahkan akses cli mongodb dengan perintah.

mongo

Kemudian jalankan perintah berikut untuk mengakses / membuat database.

use belajar-backup;

Kemudian untuk membuat sebuah collection, silahkan jalankan perintah berikut.

db.createCollection('tb_barang');

Untuk melakukan insert, silahkan jalankan perintah berikut.

db.tb_barang.insert(
  [
    { nama_barang: 'rinso', jumlah_barang: 10, harga_barang: 500 },
    { nama_barang: 'aqua', jumlah_barang: 50, harga_barang: 100 },
    { nama_barang: 'floridina', jumlah_barang: 10, harga_barang: 5000 }
  ]
);

Untuk melihat data di mongodb, anda dapat menggunakan perintah berikut.

db.tb_barang.find().pretty();

berikut adalah hasil outputnya.

{
	"_id" : ObjectId("589afba9f2586584e62c70da"),
	"nama_barang" : "rinso",
	"jumlah_barang" : 10,
	"harga_barang" : 500
}
{
	"_id" : ObjectId("589afba9f2586584e62c70db"),
	"nama_barang" : "aqua",
	"jumlah_barang" : 50,
	"harga_barang" : 100
}
{
	"_id" : ObjectId("589afba9f2586584e62c70dc"),
	"nama_barang" : "floridina",
	"jumlah_barang" : 10,
	"harga_barang" : 5000
}

Setelah selesai, sekarang saatnya untuk membuat backup database, silahkan akses cli mongodb yang versi backup dengan perintah berikut.

docker exec -i -t mongodb-backup /bin/bash

Secara otomatis kita akan berada di folder backup-restore, di dalam folder tersebut terdapat file mongodb-backup.sh yang telah kita buat, akan tetapi host yang digunakan pastinya akan berbeda dikarenakan berbeda container, untuk mengecek host database mongodb versi production silahkan jalankan perintah berikut.

printenv | grep MONGO

Berikut adalah hasil outputnya.

MONGODB_PRODUCTION_PORT_27017_TCP_PROTO=tcp
MONGO_VERSION=3.4.2
MONGODB_PRODUCTION_ENV_GPG_KEYS=0C49F3730359A14518585931BC711F9BA15703C6
MONGODB_PRODUCTION_ENV_GOSU_VERSION=1.7
MONGODB_PRODUCTION_PORT_27017_TCP_ADDR=172.17.0.2
MONGODB_PRODUCTION_ENV_no_proxy=*.local, 169.254/16
MONGO_PACKAGE=mongodb-org
MONGODB_PRODUCTION_NAME=/mongodb-backup/mongodb-production
MONGODB_PRODUCTION_PORT_27017_TCP_PORT=27017
MONGODB_PRODUCTION_ENV_MONGO_PACKAGE=mongodb-org
MONGODB_PRODUCTION_ENV_MONGO_MAJOR=3.4
MONGODB_PRODUCTION_PORT=tcp://172.17.0.2:27017
MONGO_MAJOR=3.4
MONGODB_PRODUCTION_ENV_MONGO_VERSION=3.4.2
MONGODB_PRODUCTION_PORT_27017_TCP=tcp://172.17.0.2:27017

Kemudian silahkan buka kembali file mongodb-backup.sh lalu ubah konfigurasinya seperti berikut.

#!/bin/bash
# author Rizki Mufrizal

HOST=${MONGODB_PRODUCTION_PORT_27017_TCP_ADDR}
PORT=${MONGODB_PRODUCTION_PORT_27017_TCP_PORT}
REMOTE_DB="belajar-backup"
USER=""
PASS=""
PATH_BACKUP="/var/database-backup"

mongodump --db=$REMOTE_DB --username=$USER --password=$PASS --host=$HOST --port=$PORT --out=$PATH_BACKUP

Setelah selesai, silahkan berikan hak akses untuk execute dengan perintah.

chmod a+x mongodb-backup.sh

Kemudian jalankan file tersebut dengan perintah.

./mongodb-backup.sh

Jika berhasil maka akan muncul output seperti berikut.

2017-02-08T13:00:52.092+0000	writing belajar-backup.tb_barang to
2017-02-08T13:00:52.095+0000	done dumping belajar-backup.tb_barang (3 documents)

Untuk memastikan bahwa database anda telah di backup, silahkan cek path folder backup anda, tadinya kita membuat path back up database di /var/database-backup, berikut adalah hasilnya jika berhasil.

Screen Shot 2017-02-08 at 8.04.14 PM.png

Melakukan Restore Database

Pada tahap sebelumnya kita telah berhasil membuat backup database, nah sekarang kita akan melakukan restore database, sebelumnya, untuk mempermudah kita akan menggunakan Robomongo untuk mengakses database production. Silahkan download dan lakukan instalasi, jika telah selesai, silahkan buka robomongo anda, lalu lakukan konfigurasi seperti berikut.

Screen Shot 2017-02-08 at 8.14.42 PM.png

mengapa kita menggunakan port 27000 ? ya dikarenakan konfigurasi forward port yang ada pada docker. Sehingga setiap kita mengakses port 27000 maka docker akan melakukan forward ke port 27017. Jika anda melakukan akses database dan collection nya maka akan muncul output seperti berikut.

Screen Shot 2017-02-08 at 8.15.21 PM.png

Sekarang silahkan klik kanan di databasenya kemudian pilih menu drop database, maka secara otomatis database dihapus, nah sekarang kita akan melakukan restore. Silahkan akses terminal untuk database mongodb versi backup. Kemudian jalankan perintah berikut untuk melakukan restore database.

mongorestore /var/database-backup/belajar-backup/ --host=${MONGODB_PRODUCTION_PORT_27017_TCP_ADDR} --port=${MONGODB_PRODUCTION_PORT_27017_TCP_PORT} --db="belajar-backup" --username="" --password=""

Jika berhasil maka akan muncul output seperti berikut.

2017-02-08T13:25:30.559+0000	the --db and --collection args should only be used when restoring from a BSON file. Other uses are deprecated and will not exist in the future; use --nsInclude instead
2017-02-08T13:25:30.560+0000	building a list of collections to restore from /var/database-backup/belajar-backup dir
2017-02-08T13:25:30.561+0000	reading metadata for belajar-backup.tb_barang from /var/database-backup/belajar-backup/tb_barang.metadata.json
2017-02-08T13:25:32.837+0000	restoring belajar-backup.tb_barang from /var/database-backup/belajar-backup/tb_barang.bson
2017-02-08T13:25:32.841+0000	no indexes to restore
2017-02-08T13:25:32.841+0000	finished restoring belajar-backup.tb_barang (3 documents)
2017-02-08T13:25:32.841+0000	done

Output diatas menandakan bahwa database telah berhasil direstore :D. Sekian artikel mengenai Membuat Backup dan Restore Pada MongoDB, semoga bermanfaat dan terima kasih :)

Setelah sekian lama tidak update blog, nah kali ini penulis akan membuat sebuah artikel mengenai bagaimana cara membuat RESTful Web Service dengan menggunakan Framework Spring Boot :). Spring Boot merupakan salah satu project dari pivotal yaitu sebuah perusahaan yang mengembangkan framework spring. Bagi anda yang belum kenal dengan spring framework bisa membaca artikel di Belajar Spring Framework. Karena spring framework merupakan salah satu framework dari bahasa pemrograman java maka anda diwajibkan untuk melakukan instalasi java, bagi anda yang belum melakukan instalasi java dapat membaca artikel Instalasi Perlengkapan Coding Java.

Setup Project

Pada artikel ini, kita akan menggunakan groovy yaitu salah satu bahasa scripting yang dikembangkan diatas JVM (java virtual machine) dimana bahasa groovy ini dapat diinterpretasikan atau dikompilasi. Masih terdapat bahasa pemrograman lain yang dikembangkan diatas JVM seperti scala, kotlin, jruby, jython dan lain sebagainya. Di blog pribadi saya, terdapat salah satu pembahasan bahasa pemrograman diatas yaitu kotlin, bagi anda yang ingin membaca tentang kotlin, silahkan akses di Instalasi Perlengkapan Coding Kotlin.

Untuk melakukan setup project spring boot, kita dapat mengenerate projectnya melalui start spring.io. Silahkan isikan konfigurasi seperti berikut.

Screen Shot 2017-01-12 at 6.10.31 PM.png

Kemudian silahkan pilih menu generate project. Maka secara otomatis akan dibuatkan sebuah project spring boot dengan menggunakan bahasa pemrograman groovy :D. Disini kita akan menggunakan database mongodb dan menggunakan arsitektur HATEOAS (Hypermedia as the Engine of Application State). HATEOAS adalah salah satu constraint untuk membangun sebuah RESTful Web Service, dimana HATEOAS ini merupakan level 3 pada constraint RESTful Web Service. Pembahasan mengenai HATEOAS akan dibahas pada artikel berikutnya :).

Silahkan extract file yang telah didownload. Pada artikel ini, kita akan menggunakan IntellIJ IDE. Silahkan buka IDE tersebut lalu import project spring boot, berikut adalah struktur project jika dilihat dari IDE tersebut.

Screen Shot 2017-01-12 at 10.03.00 PM.png

Langkah Pertama silahkan Buat Struktur aplikasi seperti berikut.

Screen Shot 2017-01-13 at 11.31.01 AM.png

Silahkan buka class Barang yang ada di package domain. Kemudian ubah codingannya menjadi seperti berikut.

package com.rizki.mufrizal.belajar.spring.boot.domain

import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.Document
import org.springframework.data.mongodb.core.mapping.Field

/**
 *
 * @Author Rizki Mufrizal <mufrizalrizki@gmail.com>
 * @Web <https://RizkiMufrizal.github.com>
 * @Since 12 January 2017
 * @Time 10:13 PM
 * @Project Belajar-Spring-Boot
 * @Package com.rizki.mufrizal.belajar.spring.boot.domain
 * @File Barang
 *
 */
@Document(collection = "tb_barang")
class Barang implements Serializable {

    @Id
    @Field(value = "id_barang")
    String idBarang

    @Field(value = "nama_barang")
    String namaBarang

    @Field(value = "jenis_barang")
    JenisBarang jenisBarang

    @Field(value = "tanggal_kadaluarsa")
    Date tanggalKadaluarsa

    @Field(value = "harga_satuan_barang")
    BigDecimal hargaSatuanBarang

    @Field(value = "jumlah_barang_tersedia")
    Integer jumlahBarangTersedia

}

Dari codingan diatas dapat kita lihat bahwa penulisan sintak java dan groovy sangat lah mirip, dimana terdapat perbedaan yaitu groovy tidak mengharuskan developer untuk menulis titik koma (;). Pada artikel ini, penulis menggunakan database mongodb maka pada saat mendeklarasikan domain / class pojo kita menggunakan annotation @Document dimana annotation tersebut mewakili dari collection yang ada di database mongodb. Untuk mendeklarasikan jenis barang, kita menggunakan enum class, silahkan buat sebuah enum class dengan nama JenisKelamin, Kemudian isikan codingan seperti berikut.

package com.rizki.mufrizal.belajar.spring.boot.domain

/**
 *
 * @Author Rizki Mufrizal <mufrizalrizki@gmail.com>
 * @Web <https://RizkiMufrizal.github.com>
 * @Since 12 January 2017
 * @Time 10:15 PM
 * @Project Belajar-Spring-Boot
 * @Package com.rizki.mufrizal.belajar.spring.boot.domain
 * @File JenisBarang
 *
 */
enum JenisBarang {
    gas, padat, cair
}

Setelah selesai, tahap selanjutnya silahkan buka class Penjualan untuk aksi transaksi, kemudian isikan codingan seperti berikut.

package com.rizki.mufrizal.belajar.spring.boot.domain

import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.Document
import org.springframework.data.mongodb.core.mapping.Field

/**
 *
 * @Author Rizki Mufrizal <mufrizalrizki@gmail.com>
 * @Web <https://RizkiMufrizal.github.com>
 * @Since 12 January 2017
 * @Time 10:17 PM
 * @Project Belajar-Spring-Boot
 * @Package com.rizki.mufrizal.belajar.spring.boot.domain
 * @File Penjualan
 *
 */
@Document(collection = "tb_penjualan")
class Penjualan implements Serializable {

    @Id
    @Field(value = "id_penjualan")
    String idPenjualan

    @Field(value = "tanggal_transaksi")
    Date tanggalTransaksi

    @Field(value = "nama_pembeli")
    String namaPembeli

    @Field(value = "total_harga")
    BigDecimal totalHarga

}

Sama seperti sebelumnya, class ini berisi tentang domain / class pojo. Kemudian buka class PenjualanDetail lalu masukkan codingan seperti berikut.

package com.rizki.mufrizal.belajar.spring.boot.domain

import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.DBRef
import org.springframework.data.mongodb.core.mapping.Document
import org.springframework.data.mongodb.core.mapping.Field

/**
 *
 * @Author Rizki Mufrizal <mufrizalrizki@gmail.com>
 * @Web <https://RizkiMufrizal.github.com>
 * @Since 12 January 2017
 * @Time 10:20 PM
 * @Project Belajar-Spring-Boot
 * @Package com.rizki.mufrizal.belajar.spring.boot.domain
 * @File PenjualanDetail
 *
 */
@Document(collection = "tb_penjualan_detail")
class PenjualanDetail implements Serializable {

    @Id
    @Field(value = "id_penjualan_detail")
    String idPenjualanDetail

    @Field(value = "jumlah_barang")
    Integer jumlahBarang

    @Field(value = "total_harga_per_barang")
    BigDecimal totalHargaPerBarang

    @DBRef(lazy = true)
    Penjualan penjualan

    @DBRef(lazy = true)
    Barang barang

}

Pada domain PenjualanDetail terdapat sedikit tambahkan yaitu annotation DBRef dimana annotation ini berfungsi sebagai relasi antara collection. Terdapat 1 Penjualan dengan banyak Penjualan Detail dan begitu pula dengan barang, sehingga relasi ini menghasilkan relasi one to many dari penjualan ke penjualan detail dan dari barang ke penjualan detail.

Langkah selanjutnya silahkan buka file BarangRepository, kemudian isikan codingan seperti berikut.

package com.rizki.mufrizal.belajar.spring.boot.repository

import com.rizki.mufrizal.belajar.spring.boot.domain.Barang
import org.springframework.data.mongodb.repository.MongoRepository
import org.springframework.data.rest.core.annotation.Description
import org.springframework.data.rest.core.annotation.RepositoryRestResource

/**
 *
 * @Author Rizki Mufrizal <mufrizalrizki@gmail.com>
 * @Web <https://RizkiMufrizal.github.com>
 * @Since 12 January 2017
 * @Time 10:23 PM
 * @Project Belajar-Spring-Boot
 * @Package com.rizki.mufrizal.belajar.spring.boot.repository
 * @File BarangRepository
 *
 */
@RepositoryRestResource(collectionResourceRel = "barang", path = "barang", collectionResourceDescription = @Description("API Barang"))
interface BarangRepository extends MongoRepository<Barang, String> {

}

class BarangRepository adalah sebuah class interface dimana di dalam class ini kita melakukan extends terhadap class MongoRepository sehingga melalui class ini kita dapat melakukan process create read update dan delete. Spring data mongodb telah menyediakan fungsi paging, sorting dan lain sebagainya, bahkan kita dapat melakukan custom terhadap query yang kita butuhkan. Dikarenkan project ini menggunakan spring data rest maka kita tidak lagi memerlukan membuat controller maupun service, sehingga dari class respository sudah dapat dilakukan proses manipulasi data. Bagaimana kita dapat mengetahui url / end point yang digunakan ? kita dapat mengetahuinya melalui path yang ada di annotation RepositoryRestResource. Untuk end point / url process create update, read dan delete secara otomatis akan dibuatkan berdasarkan method http. Berikut adalah daftar listnya :

Method Http Deksripsi
GET Untuk mengambil data
POST Untuk menyimpan data
PUT Untuk merubah data
DELETE Untuk menghapus data

Selanjutnya silahkan buka class PenjualanRepository kemudian isikan codingan seperti berikut.

package com.rizki.mufrizal.belajar.spring.boot.repository

import com.rizki.mufrizal.belajar.spring.boot.domain.Penjualan
import org.springframework.data.mongodb.repository.MongoRepository
import org.springframework.data.rest.core.annotation.Description
import org.springframework.data.rest.core.annotation.RepositoryRestResource

/**
 *
 * @Author Rizki Mufrizal <mufrizalrizki@gmail.com>
 * @Web <https://RizkiMufrizal.github.com>
 * @Since 12 January 2017
 * @Time 10:25 PM
 * @Project Belajar-Spring-Boot
 * @Package com.rizki.mufrizal.belajar.spring.boot.repository
 * @File PenjualanRepository
 *
 */
@RepositoryRestResource(collectionResourceRel = "penjualan", path = "penjualan", collectionResourceDescription = @Description("API Penjualan"))
interface PenjualanRepository extends MongoRepository<Penjualan, String> {

}

Sama seperti class sebelumnya, selanjutnya silahkan buka class PenjualanDetailRepository kemudian isikan codingan seperti berikut.

package com.rizki.mufrizal.belajar.spring.boot.repository

import com.rizki.mufrizal.belajar.spring.boot.domain.PenjualanDetail
import org.springframework.data.mongodb.repository.MongoRepository
import org.springframework.data.rest.core.annotation.Description
import org.springframework.data.rest.core.annotation.RepositoryRestResource
import org.springframework.data.rest.core.annotation.RestResource

/**
 *
 * @Author Rizki Mufrizal <mufrizalrizki@gmail.com>
 * @Web <https://RizkiMufrizal.github.com>
 * @Since 12 January 2017
 * @Time 10:26 PM
 * @Project Belajar-Spring-Boot
 * @Package com.rizki.mufrizal.belajar.spring.boot.repository
 * @File PenjualanDetailRepository
 *
 */
@RepositoryRestResource(collectionResourceRel = "penjualan_detail", path = "penjualan_detail", collectionResourceDescription = @Description("API Penjualan detail"))
interface PenjualanDetailRepository extends MongoRepository<PenjualanDetail, String> {

}

Kemudian tahap terakhir silahkan buka file application.properties yang ada di folder resouces, kemudian isikan codingan berikut.

#konfigurasi mongodb
spring.data.mongodb.database=belajar_spring_boot
spring.data.mongodb.host=127.0.0.1
spring.data.mongodb.port=27017

#konfigurasi HATEOAS
spring.hateoas.use-hal-as-default-json-media-type=true

endpoints.cors.allowed-methods = POST, GET, OPTIONS, DELETE, PUT
endpoints.cors.allowed-origins = '*'
endpoints.cors.exposed-headers = accept, authorization, x-requested-with, content-type
endpoints.cors.max-age = 3600

#konfigurasi jackson
spring.jackson.serialization.indent-output=true

#konfigurasi spring data rest
spring.data.rest.base-path=/api

Setelah selesai, tahap terakhir kita akan menjalankan aplikasi web nya dengan perintah.

mvn clean spring-boot:run

Berikut adalah output ketika dijalankan.

Screen Shot 2017-01-13 at 10.06.11 PM.png

Kemudian kita lakukan testing menggunakan postman, berikut adalah proses menyimpan data untuk barang

Screen Shot 2017-01-13 at 10.10.46 PM.png

berikut adalah proses menyimpan data untuk penjualan

Screen Shot 2017-01-13 at 10.11.27 PM.png

berikut adalah proses menyimpan data untuk penjualan detail

Screen Shot 2017-01-13 at 10.26.38 PM.png

Bagi anda yang ingin melihat source code codingan, silahkan lihat di Belajar Spring Boot. Sekian artikel mengenai Membuat RESTful Web Service Dengan Framework Spring Boot dan terima kasih :)

Apa Itu Load Balancing ?

Load Balancing adalah sebuah teknik untuk melakukan distribusi beban trafik pada dua atau lebih jalur koneksi secara seimbang sehingga setiap jalur koneksi akan menerima beban trafik yang sama.

Load balancing ini sangat banyak digunakan oleh perusahaan - perusahaan skala besar. Load balancing biasanya sering digunakan untuk kebutuhan trafik web yang sangat tinggi seperti web e-commerce. Load balancing biasanya digunakan pada saat sebuah server jika user yang melakukan akses server tersebut telah melebihi jumlah maksimal. Ketika user yang mengakses melebihi kapasitas maka dengan menggunakan teknik load balancing, beban trafik tersebut akan dialihkan ke server yang lain.

Mengapa web Menggunakan Load Balancing ?

Berikut adalah alasan mengapa web menggunakan load balancing :

  • Untuk mempercepat waktu reponse sebuah web. Dengan menggunakan teknik load balancing maka yang akan menerima request tidak hanya 1 server, sehingga mempercepat waktu response sebuah web. 1 web server dapat menerima banyak request, sedangkan 1 server biasanya kita memiliki 1 web server, bayangkan saja jika kita mempunyai 5 dan masing - masing server mempunyai 1 web server maka waktu response sebuah web akan meningkat sangat pesat.

  • Dengan menggunakan load balancing kita akan mengurangi error pada system, misalnya jika kita mempunyai 5 server, lalu masing - masing server tersebut mempunyai web server yang menjalankan web yang telah kita deploy, karena kita menggunakan load balancing, jika salah satu server mati maka web kita akan tetap berjalan karena server lain akan menghandle request web tersebut.

Apa Itu HAProxy ?

HAProxy adalah salah satu software yang mendukung load balancing dan proxy untuk protokol TCP dan HTTP.

Pada artikel ini, penulis akan mencoba menggunakan teknologi HAProxy, salah satu keunggulan HAProxy adalah dapat melayani semua port TCP seperti 8080, 3000, 9000 dan lain - lain. Berikut adalah fitur - fitur dari HAProxy :

  • Dapat melakukan load balancing untuk banyak server
  • Dapat membuat load balancing master - slave sehingga apabila load balancing yang master mati maka akan digantikan oleh slave
  • Dapat digunakan oleh banyak service seperti email, database, web server dan lain - lain.
  • Terdapat statistik load balancing sehingga mempermudah kita memantau beban trafik
  • Jika salah satu server mati, maka beban trafik ke server tersebut akan dihentikan.

Berikut adalah gambar dari arsitektur HAProxy

arsitektur-haproxy.png

Membuat Load Balancing Dengan HAProxy Dan Docker

Bagi anda yang belum mengerti docker, silahkan baca artikel Belajar Docker. Karena kita tidak memiliki server beneran maka kita akan mencoba menggunakan docker sebagai visualisasi server. Untuk melakukan uji terhadap aplikasi web, maka penulis telah membuat contoh aplikasi web java, silahkan download di Belajar Load Balancing, Karena aplikasi ini adalah aplikasi java web maka anda perlu melakukan instalasi java untuk melakukan build web java tersebut, bagi anda yang belum melakukan instalasi java, silakan lihat di artikel Instalasi Perlengkapan Coding Java. Berikut adalah beberapa teknologi yang akan kita gunakan untuk load balancing :

  • Web Server : jetty web server
  • Framework Aplikasi Web : Spring Boot, Spring Data JPA
  • database : MariaDB
  • Pooling Database : HikariCP
  • Visualisasi Server : Docker
  • Sistem Operasi : Ubuntu, Debian
  • Load Balancing : HAProxy

Dan berikut adalah arsitektur yang akan kita gunakan untuk membuat load balancing.

Arsitektur Haproxy Load Balancing.svg

Dari gambar diatas dapat kita lihat bahwa kita menggunakan 4 server, dimana 1 server menghadle database, 2 server menghadle web dan 1 server lagi khusus untuk load balancing dengan menggunakan HAProxy. User akan melakukan akses terhadap server load balancing, lalu HAProxy secara otomatis akan meneruskan request tersebut ke server selanjutnya, sebelumnya meneruskan request, HAProxy akan melakukan pengecekan terlebih dahulu dengan menggunakan algoritma load balancing, biasanya yang paling sering digunakan adalah algoritma Round Robin, algoritma ini biasanya akan membagikan beban trafik secara bergiliran ke setiap server.

Jika project Belajar Load Balancing telah anda download, kemudian jalankan perintah.

mvn clean package docker:build

Tunggu hingga proses selesai, nantinya akan terbentuk sebuah image dengan nama rizki.mufrizal/belajar.spring.boot.load.balancing, konfigurasi docker tersebut berada pada folder src/main/docker. Disana terdapat 2 file yaitu Dockerfile. File Dockerfile berisi konfigurasi server untuk menjalankan aplikasi web java. Langkah selanjutnya, silahkan buat sebuah file docker-compose.yml di root project anda, lalu masukkan codingan seperti berikut.

mariadb:
  container_name: mariadb-server
  image: mariadb:10.1.16
  environment:
    - MYSQL_ROOT_PASSWORD=root
    - MYSQL_DATABASE=microservicespringboot
    - MYSQL_USER=rizki
    - MYSQL_PASSWORD=mufrizal

server1-belajar-load-balancing:
  container_name: server1-belajar-load-balancing
  image: rizki.mufrizal/belajar.spring.boot.load.balancing
  links:
    - mariadb
  ports:
    - 8081:8080

server2-belajar-load-balancing:
  container_name: server2-belajar-load-balancing
  image: rizki.mufrizal/belajar.spring.boot.load.balancing
  links:
    - mariadb
  ports:
    - 8082:8080

Konfigurasi diatas berfungsi untuk membuat 3 container secara sekaligus, dimana container pertama bernama mariadb yang dikhususkan untuk server database, 2 container lagi berisi aplikasi java, dimana kedua server ini memiliki link ke server database mariadb. Untuk menjalankan ketiga container tersebut, silahkan akses folder root project dengan terminal anda, lalu jalankan perintah berikut.

docker-compose up

Kemudian silahkan cek apakah 3 container tersebut telah berjalan atau tidak dengan perintah.

docker ps

Pada saat penulis menjalankan perintah diatas, penulis berhasil menjalankan 2 container, sedangkan 1 container lagi tidak jalan, mengapa demikian ? biasanya ini sering terjadi karena start up database mariadb yang lebih lambat dari pada start up aplikasi web java. Untuk mengatasi hal ini, silahkan hentikan container yang sedang jalan dengan perintah CTRL + c lalu jalankan kembali dengan perintah docker-compose up. Jika telah berjalan ketiga container tersebut, silahkan cek web tersebut melalui browser anda, anda dapat melakukan pengecekan pada localhost:8081 dan localhost:8082.

Langkah selanjutnya kita akan membuat 1 container lagi yang berfungsi sebagai load balancing. Silahkan jalankan perintah berikut untuk menjalankan container untuk load balancing.

docker run --link server1-belajar-load-balancing --link server2-belajar-load-balancing --name server3-belajar-load-balancing -p 8083:80 -p 9001:9000 -it ubuntu:latest

Maka anda dapat melakukan akses CLI container tersebut, silahkan jalankan perintah berikut untuk melakukan update, upgrade, instalasi HAProxy dan editor nano.

apt update && apt dist-upgrade -y && apt install haproxy nano -y

Nah setelah selesai, tahap selanjutnya kita akan memulai konfigurasi HAProxy, silahkan jalankan perintah berikut untuk mengetahui environment variabel yang ada di dalam server untuk load balancing, environment variabel ini berfungsi agar kita dapat mengetahui IP dari server yang akan menangani request web.

printenv | grep SERVER

mengapa kita menggunakan key SERVER ? ini dikarenakan kita menggunakan kata - kata server pada saat membuat nama container. Jika berhasil maka akan muncul output seperti berikut.

Screenshot from 2016-08-12 23-03-33.png

Kita akan menggunakan environment berikut untuk konfigurasi IP dan PORT.

  • SERVER1_BELAJAR_LOAD_BALANCING_PORT_8080_TCP_ADDR
  • SERVER2_BELAJAR_LOAD_BALANCING_PORT_8080_TCP_ADDR
  • SERVER1_BELAJAR_LOAD_BALANCING_PORT_8080_TCP_PORT
  • SERVER2_BELAJAR_LOAD_BALANCING_PORT_8080_TCP_PORT

Setelah mengetahui environment variabel nya, langkah selanjutnya silahkan jalankan perintah berikut untuk menghapus konfigurasi haproxy.

rm /etc/haproxy/haproxy.cfg

Kemudian jalankan perintah berikut untuk membuat dan mengedit konfigurasi haproxy.

nano /etc/haproxy/haproxy.cfg

Kemudian masukkan codingan seperti berikut.

global
    user daemon
    group daemon
    daemon
    log 127.0.0.1 daemon
    maxconn 4096
    chroot /var/lib/haproxy

defaults
    log global
    retries 2
    timeout connect 3000
    timeout server 5000
    timeout client 5000

listen http
    bind 0.0.0.0:80
    mode http
    option tcplog
    log global
    mode http
    option httplog
    option dontlognull
    balance roundrobin
    retries 3
    option redispatch
    maxconn 2000
    timeout connect 5000
    timeout client 50000
    timeout server 50000
    server web1 ${SERVER1_BELAJAR_LOAD_BALANCING_PORT_8080_TCP_ADDR}:${SERVER1_BELAJAR_LOAD_BALANCING_PORT_8080_TCP_PORT} check
    server web2 ${SERVER2_BELAJAR_LOAD_BALANCING_PORT_8080_TCP_ADDR}:${SERVER2_BELAJAR_LOAD_BALANCING_PORT_8080_TCP_PORT} check
    cookie web1 insert nocache
    cookie web2 insert nocache

listen stats
    bind 0.0.0.0:9000
    mode http
    stats enable
    stats hide-version
    balance
    timeout client 5000
    timeout connect 4000
    timeout server 30000
    stats uri /haproxy_stats
    stats realm HAProxy\ Statistics
    stats refresh 10s
    stats auth admin:admin

Dari konfigurasi diatas dapat dilihat bahwa kita membuat 2 konfigurasi untuk 2 server yaitu pada bagian server web1 dan server web2. Pada bagian tersebut kita akan mendeklarasikan IP dan PORT dari server yang akan kita buat load balancing. Untuk mempermudah monitoring load balancing, kita menggunakan monitor status dari HAProxy, konfigurasinya terdapat pada listen stats. Kemudian silahkan restart HAProxy dengan perintah.

/etc/init.d/haproxy restart

Jika berhasil akan muncul output seperti berikut.

Restarting haproxy haproxy                                                  [ OK ]

Uji Coba Load Balancing

Akhirnya selesai juga konfigurasinya, tahap terakhir adalah melakukan uji coba :D. Untuk melakukan uji coba, silahkan akses localhost:8083 maka jika berhasil akan muncul output seperti berikut.

Screenshot from 2016-08-13 15-35-33.png

Jika anda sering melakukan reload, maka sebanarnya load balancing tersebut akan berjalan, anda dapat melihatnya melalui output docker pada terminal, berikut adalah contohnya.

Screenshot from 2016-08-13 15-38-04.png

Dari gambar diatas dapat kita lihat bahwa terdapat 2 server yang menghandle request secara bergantian, yaitu server 1 dengan warna hijau dan server 2 dengan warna kuning. Anda juga dapat melakukan monitoring melalui url localhost:9001/haproxy_stats, jika diminta password silahkan masukkan username admin dan password admin, dan jika berhasil maka akan muncul output seperti berikut.

Screenshot from 2016-08-13 15-41-05.png

Uji Coba Load Balancing Dengan JMeter

Untuk melakukan uji coba kehandalan atau uji coba performance sebuah aplikasi, kita dapat menggunakan aplikasi JMeter. Silahkan download aplikasi tersebut lalu jalankan file ApacheJMeter.jar di dalam folder bin. Jika berhasil maka akan muncul output seperti berikut.

Screenshot from 2016-08-13 15-46-25.png

Lalu klik kanan pada test plan, pilih menu add lalu pilih threads(users) dan pilih menu thread. Pada bagian number of thread silahkan isikan angka 1000 seperti gambar berikut.

Screenshot from 2016-08-13 15-48-05.png

Kemudian pilih Thread Group lalu pilih menu add, pilih menu sampler dan pilih menu HTTP Request. Pada kolom Server Name or IP isikan localhost, pada port number isikan 8083 dan pada kolom path isikan / seperti gambar berikut.

Screenshot from 2016-08-13 15-51-13.png

Kemudian pilih kembali thread Group lalu pilih menu add, pilih menu listener dan pilih menu view results in table. Lalu silahkan pilih menu run dan pilih start maka secara otomatis JMeter akan melakukan request sebanyak 1000 request dalam 1 second, jika load balancing bekerja sesuai dengan harapan, beban bekerja secara merata pada tiap server dan spesifikasi perangkat komputer telah sesuai maka anda akan mendapatkan semua status request menjadi success. Berikut adalah output pada JMeter setelah melakukan test request.

Screenshot from 2016-08-13 15-57-22.png

Bagi anda yang ingin melihat source code codingan, silahkan lihat di Belajar Load Balancing. Sekian artikel mengenai belajar load balancing dan terima kasih :)