Oleh Tom Preston-Werner ([email protected])
Ernie adalah implementasi server BERT-RPC yang menggunakan server Erlang untuk menerima koneksi masuk, dan kemudian mendelegasikan permintaan tersebut ke modul khusus yang dapat Anda tulis dalam bahasa apa pun (saat ini hanya dukungan Ruby dan Erlang yang disertakan).
Modul yang ditulis dalam Ruby atau bahasa non-Erlang dikenal sebagai modul "eksternal" dan Anda harus menentukan berapa banyak pekerja dari setiap modul yang harus dihasilkan. Permintaan terhadap modul-modul ini seimbang antar pekerja. Modul yang ditulis dalam Erlang dikenal sebagai modul "asli" dan dijalankan dalam runtime server Erlang. Karena ini dihasilkan sebagai proses yang ringan, tidak diperlukan penyeimbangan dan overhead komunikasi yang jauh lebih sedikit jika dibandingkan dengan modul eksternal.
Ernie mendukung beberapa modul heterogen. Misalnya, Anda dapat menjalankan modul Ruby eksternal yang menjalankan 10 pekerja dan modul Erlang asli yang berjalan secara bersamaan. Ernie melacak pengiriman permintaan ke modul yang tepat. Dengan menggunakan teknik yang disebut "shadowing", Anda dapat mengoptimalkan fungsi modul eksternal tertentu secara selektif dengan kode asli dan Ernie akan menangani pemilihan fungsi yang benar.
Lihat spesifikasi BERT-RPC selengkapnya di bert-rpc.org.
Ernie saat ini mendukung fitur BERT-RPC berikut:
call
cast
Ernie dikembangkan untuk GitHub dan saat ini dalam penggunaan produksi melayani jutaan permintaan RPC setiap hari. Stabilitas dan kinerjanya patut dicontoh.
Ernie mengikuti Versi Semantik untuk pembuatan versi rilis.
Langkah 1: Instal Erlang (R13B atau lebih tinggi).
http://www.erlang.org/download.html
Langkah 2: Instal Ernie:
$ [sudo] gem install ernie
Usage: ernie [command] [options]
-c, --config CONFIG Config file.
-p, --port PORT Port.
-l, --log-level Log level (0-4).
-a, --access-log LOGFILE Access log file.
-d, --detached Run as a daemon.
-P, --pidfile PIDFILE Location to write pid file.
--name NAME Erlang process name.
--sname SNAME Erlang short process name.
-E, --erlang ERLANG_OPTIONS Options passed to Erlang VM.
Commands:
Start an Ernie server.
reload-handlers Gracefully reload all of the external handlers
and use the new code for all subsequent requests.
stats Print a list of connection and handler statistics.
Examples:
ernie -d -p 9999 -c example.cfg
Start the ernie server in the background on port 9999 using the
example.cfg configuration file.
ernie reload-handlers -p 9999
Reload the handlers for the ernie server currently running on
port 9999.
ernie -c example.cfg -E '-run mymodule'
Start the ernie server with an additional erlang module called
'mymodule'
File konfigurasi Ernie ditulis sebagai rangkaian istilah Erlang bertitik. Setiap term adalah daftar 2 tupel yang menentukan opsi untuk sebuah modul.
Bentuk modul asli adalah:
[{module, Module},
{type, native},
{codepaths, CodePaths}].
Dimana Module adalah atom yang sesuai dengan nama modul dan CodePaths adalah daftar string yang mewakili jalur file yang harus ditambahkan ke jalur kode runtime. Jalur ini akan ditambahkan ke jalur kode dan harus menyertakan direktori modul asli dan direktori dependensi apa pun.
Bentuk modul eksternal adalah:
[{module, Module},
{type, external},
{command, Command},
{count, Count}].
Dimana Modul adalah atom yang sesuai dengan nama modul, Perintah adalah string yang menentukan perintah yang akan dijalankan untuk memulai pekerja, dan Hitung adalah jumlah pekerja yang akan dihasilkan.
Jika Anda menentukan modul asli dan modul eksternal dengan nama yang sama (dan dalam urutan itu), Ernie akan memeriksa modul asli untuk melihat apakah fungsi yang diminta telah diekspor dan menggunakannya jika ada. Jika tidak, maka modul tersebut akan kembali ke modul eksternal. Ini dapat digunakan untuk mengoptimalkan fungsi tertentu dalam modul secara selektif tanpa modifikasi apa pun pada kode klien Anda.
Dalam beberapa keadaan, sebaiknya membayangi suatu fungsi secara kondisional dalam modul eksternal berdasarkan sifat argumennya. Misalnya, Anda mungkin ingin permintaan math:fib(X)
dirutekan ke modul eksternal ketika X kurang dari 10, namun ditangani oleh modul asli ketika X 10 atau lebih besar. Hal ini dapat dicapai dengan mengimplementasikan fungsi math:fib_pred(X)
di modul asli. Perhatikan _pred
ditambahkan ke nama fungsi normal (pred adalah kependekan dari predikat). Jika fungsi seperti ini ada, Ernie akan memanggilnya dengan argumen yang diminta dan jika nilai yang dikembalikan true
modul asli akan digunakan. Jika nilai yang dikembalikan false
modul eksternal akan digunakan.
Contoh file konfigurasi berikut memberi tahu Ernie tentang dua modul. Istilah pertama mengidentifikasi modul asli 'nat' yang berada di file nat.beam di bawah direktori '/path/to/app/ebin'. Istilah kedua menentukan modul eksternal 'ext' yang akan memiliki 2 pekerja yang dimulai dengan perintah 'ruby /path/to/app/ernie/ext.rb'.
[{module, nat},
{type, native},
{codepaths, ["/path/to/app/ebin"]}].
[{module, ext},
{type, external},
{command, "ruby /path/to/app/ernie/ext.rb"},
{count, 2}].
Jika Anda meminta agar log akses ditulis (menggunakan opsi -a atau --access-log) maka semua permintaan akan dicatat ke file itu. Setiap permintaan dicetak dalam satu baris. Elemen baris log adalah sebagai berikut (dengan komentar di sisi kanan):
ACC type of message [ ACC | ERR ]
[2010-02-20T11:42:25.259750] time the connection was accepted
0.000053 seconds from connection to processing start
0.000237 seconds from processing start to finish
- delimiter
0 size of high queue at connect time
0 size of low queue at connect time
nat type of handler [ nat | ext ]
high priority [ high | low ]
- delimiter
{call,nat,add,[1,2]} message
Baris log ditulis ketika permintaan selesai sehingga mungkin tampak tidak berurutan sehubungan dengan waktu koneksi. Untuk memudahkan rotasi log, Ernie akan membuat file log akses baru jika file log saat ini dipindahkan atau dihapus.
Penangan asli ditulis sebagai modul Erlang biasa. Fungsi yang diekspor akan tersedia untuk klien BERT-RPC.
-module(nat).
-export([add/2]).
add(A, B) ->
A + B.
-> {call, nat, add, [1, 2]}
<- {reply, 3}
Termasuk dalam permata ini adalah perpustakaan bernama ernie
yang memudahkan untuk menulis penangan Ernie di Ruby. Yang harus Anda lakukan adalah menulis modul Ruby standar dan memaparkannya ke Ernie dan fungsi modul tersebut akan tersedia untuk klien BERT-RPC.
Menggunakan modul Ruby dan Ernie.expose:
require 'rubygems'
require 'ernie'
module Ext
def add(a, b)
a + b
end
end
Ernie.expose(:ext, Ext)
-> {call, nat, add, [1, 2]}
<- {reply, 3}
Anda dapat mengirimkan logging ke file dengan menambahkan baris berikut ke handler Anda:
logfile('/var/log/ernie.log')
loglevel(Logger::INFO)
Ini akan mencatat info startup, permintaan, dan pesan kesalahan ke log. Memilih Logger::DEBUG akan menyertakan responsnya (hati-hati, melakukan ini dapat menghasilkan file log yang sangat besar).
Biasanya penangan Ruby Ernie akan aktif setelah file dimuat. Anda dapat menonaktifkan perilaku ini dengan mengatur:
Ernie.auto_start = false
Ernie mempertahankan antrian prioritas Tinggi dan Rendah untuk koneksi masuk. Jika ada koneksi dalam antrian Prioritas tinggi, koneksi tersebut akan selalu diproses terlebih dahulu. Jika antrian berprioritas tinggi kosong, koneksi akan diproses dari antrian berprioritas rendah. Secara default, koneksi masuk ke antrian prioritas tinggi. Untuk memilih antrian, info BERP dalam bentuk berikut harus dikirimkan sebelum panggilan.
-- {info, priority, Priority}
Dimana Priority
adalah atom high
atau low
. Contoh urutan pemilihan antrian berprioritas rendah akan terlihat seperti berikut.
-> {info, priority, low}
-> {call, nat, add, [1, 2]}
<- {reply, 3}
Anda dapat melakukan panggilan BERT-RPC dari Ruby dengan permata BERTRPC:
require 'bertrpc'
svc = BERTRPC::Service.new('localhost', 8000)
svc.call.ext.add(1, 2)
# => 3
Jika Anda ingin meretas Ernie, mulailah dengan mem-forking repo saya di GitHub:
http://github.com/mojombo/ernie
Untuk mendapatkan semua dependensi, instal permata terlebih dahulu. Untuk menjalankan ernie dari sumber, Anda harus membuat kode Erlang terlebih dahulu:
rake ebuild
Cara terbaik untuk menggabungkan kembali perubahan Anda ke inti adalah sebagai berikut:
rake
Hak Cipta (c) 2009 Tom Preston-Werner. Lihat LISENSI untuk detailnya.