Sawise salah sawijining wawancara kerja sing paling anyar, aku kaget ngerti manawa perusahaan sing daklamar isih nggunakake Laravel, kerangka PHP sing dakcoba udakara sepuluh taun kepungkur. Iku prayoga kanggo wektu, nanging yen ana siji pancet ing teknologi lan fashion padha, iku owah-owahan terus-terusan lan resurfacing saka gaya lan konsep & # x27; Yen sampeyan programmer JavaScript, sampeyan mbokmenawa wis kenal karo guyon lawas iki
Programmer 1: "Aku ora seneng karo kerangka JavaScript anyar iki!"
Programmer 2: "Ora usah kuwatir. Enteni wae nem sasi lan bakal ana siji liyane sing ngganti!"
Amarga penasaran, aku mutusake kanggo ndeleng persis apa sing kedadeyan nalika kita nyoba lawas lan anyar. Mesthine, web kasebut diisi pathokan lan pratelan, sing paling populer yaiku TechEmpower Web Framework Benchmarks kene . Kita ora bakal nindakake apa-apa sing meh rumit kaya saiki. Kita bakal tetep apik lan prasaja supaya artikel iki ora dadi Perang lan Perdamaian , lan sampeyan bakal duwe kasempatan sethitik kanggo tetep siyaga nalika sampeyan wis rampung maca & # x27; Caveats biasane ditrapake: iki bisa uga ora bisa digunakake ing mesin sampeyan, versi piranti lunak sing beda bisa mengaruhi kinerja, lan kucing Schrรถdinger bener-bener dadi kucing zombie sing setengah urip lan setengah mati ing wektu sing padha.
Kanggo tes iki, aku bakal nggunakake laptopku sing nganggo i5 cilik sing nganggo Manjaro Linux kaya sing ditampilake ing kene.
โฐโโค uname -a
Linux jimsredmi 5.10.174-1-MANJARO #1 SMP PREEMPT Tuesday Mar 21 11:15:28 UTC 2023 x86_64 GNU/Linux
โฐโโค cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 126
model name : Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz
stepping : 5
microcode : 0xb6
cpu MHz : 990.210
cache size : 6144 KB
Kode kita bakal duwe telung tugas sing gampang kanggo saben panyuwunan:
Apa jenis tes bodho iku, sampeyan bisa takon? Inggih, yen sampeyan ndeleng panjalukan jaringan kanggo kaca iki, sampeyan bakal weruh sing diarani sessionvars.js sing nindakake perkara sing padha.
Sampeyan ndeleng, kaca web modern minangka makhluk sing rumit, lan salah sawijining tugas sing paling umum yaiku caching kaca sing kompleks kanggo nyegah beban sing berlebihan ing server database.
Yen kita nggawe maneh kaca sing kompleks saben pangguna njaluk, mula kita mung bisa nglayani sekitar 600 pangguna saben detik.
โฐโโค wrk -d 10s -t 4 -c 100 http://127.0.0.1/system/index.en.html
Running 10s test @ http://127.0.0.1/system/index.en.html
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 186.83ms 174.22ms 1.06s 81.16%
Req/Sec 166.11 58.84 414.00 71.89%
6213 requests in 10.02s, 49.35MB read
Requests/sec: 619.97
Transfer/sec: 4.92MB
Nanging yen kita cache kaca iki minangka file HTML statis lan supaya Nginx cepet mbuwang metu jendhela kanggo pangguna, banjur kita bisa ngawula 32.000 pangguna saben detik, nambah kinerja dening faktor 50x.
โฐโโค wrk -d 10s -t 4 -c 100 http://127.0.0.1/system/index.en.html
Running 10s test @ http://127.0.0.1/system/index.en.html
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 3.03ms 511.95us 6.87ms 68.10%
Req/Sec 8.20k 1.15k 28.55k 97.26%
327353 requests in 10.10s, 2.36GB read
Requests/sec: 32410.83
Transfer/sec: 238.99MB
Statis index.en.html bagean sing dadi kanggo everyone, lan mung bagean sing beda-beda dening pangguna dikirim ing sessionvars.js. Iki ora mung nyuda beban database lan nggawe pengalaman sing luwih apik kanggo pangguna, nanging uga nyuda kemungkinan kuantum manawa server bakal nguap kanthi spontan ing pelanggaran inti warp nalika serangan Klingons.
Kode bali kanggo saben framework bakal duwe siji syarat prasaja: nuduhake pangguna carane kakehan padha refresh kaca kanthi matur "Count is x". Kanggo tetep prasaja, kita bakal adoh saka antrian Redis, komponen Kubernetes, utawa AWS Lambdas saiki.
Data sesi saben pangguna bakal disimpen ing database PostgreSQL.
Lan tabel database iki bakal dipotong sadurunge saben tes.
Semboyan Pafera sing prasaja nanging efektif yaiku ... ing njaba garis wektu sing paling peteng ...
Oke, dadi saiki kita bisa miwiti njupuk tangan kita reged. Kita bakal ngliwati persiyapan kanggo Laravel amarga mung akeh komposer lan artisan. dhawuh.
Kaping pisanan, kita bakal nyetel setelan basis data ing file .env
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=sessiontest
DB_USERNAME=sessiontest
DB_PASSWORD=sessiontest
Banjur kita bakal nyetel siji rute fallback sing ngirim saben panjalukan kanggo controller kita.
Route::fallback(SessionController::class);
Lan nyetel controller kanggo nampilake count. Laravel, minangka standar, nyimpen sesi ing basis data. Iku uga nyedhiyakake session()
fungsi kanggo antarmuka karo data sesi kita, supaya mung sawetara baris kode kanggo nerjemahake kaca kita.
class SessionController extends Controller
{
public function __invoke(Request $request)
{
$count = session('count', 0);
$count += 1;
session(['count' => $count]);
return 'Count is ' . $count;
}
}
Sawise nyiyapake php-fpm lan Nginx, kaca kita katon apik banget ...
โฐโโค php -v
PHP 8.2.2 (cli) (built: Feb 1 2023 08:33:04) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.2, Copyright (c) Zend Technologies
with Xdebug v3.2.0, Copyright (c) 2002-2022, by Derick Rethans
โฐโโค sudo systemctl restart php-fpm
โฐโโค sudo systemctl restart nginx
Paling ora nganti kita bisa ndeleng asil tes ...
PHP/Laravel
โฐโโค wrk -d 10s -t 4 -c 100 http://127.0.0.1
Running 10s test @ http://127.0.0.1
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.08s 546.33ms 1.96s 65.71%
Req/Sec 12.37 7.28 40.00 56.64%
211 requests in 10.03s, 177.21KB read
Socket errors: connect 0, read 0, write 0, timeout 176
Requests/sec: 21.04
Transfer/sec: 17.67KB
Ora, iku dudu typo. Mesin tes kita wis ilang saka 600 panjalukan per detik sing nggawe kaca rumit ... dadi 21 panjaluk per detik rendering "Count is 1".
Dadi apa sing salah? Apa ana sing salah karo instalasi PHP kita? Apa Nginx rada alon nalika interfacing karo php-fpm?
Ayo maneh kaca iki ing kode PHP murni.
<?php
// ====================================================================
function uuid4()
{
return sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
}
// ====================================================================
function Query($db, $query, $params = [])
{
$s = $db->prepare($query);
$s->setFetchMode(PDO::FETCH_ASSOC);
$s->execute(array_values($params));
return $s;
}
// ********************************************************************
session_start();
$sessionid = 0;
if (isset($_SESSION['sessionid']))
{
$sessionid = $_SESSION['sessionid'];
}
if (!$sessionid)
{
$sessionid = uuid4();
$_SESSION['sessionid'] = $sessionid;
}
$db = new PDO('pgsql:host=127.0.0.1 dbname=sessiontest user=sessiontest password=sessiontest');
$data = 0;
try
{
$result = Query(
$db,
'SELECT data FROM usersessions WHERE uid = ?',
[$sessionid]
)->fetchAll();
if ($result)
{
$data = json_decode($result[0]['data'], 1);
}
} catch (Exception $e)
{
echo $e;
Query(
$db,
'CREATE TABLE usersessions(
uid TEXT PRIMARY KEY,
data TEXT
)'
);
}
if (!$data)
{
$data = ['count' => 0];
}
$data['count']++;
if ($data['count'] == 1)
{
Query(
$db,
'INSERT INTO usersessions(uid, data)
VALUES(?, ?)',
[$sessionid, json_encode($data)]
);
} else
{
Query(
$db,
'UPDATE usersessions
SET data = ?
WHERE uid = ?',
[json_encode($data), $sessionid]
);
}
echo 'Count is ' . $data['count'];
Saiki kita wis nggunakake 98 baris kode kanggo nindakake apa papat baris kode (lan akeh karya konfigurasi) ing Laravel. (Mesthi, yen kita nindakake kesalahan sing tepat lan pesen sing diadhepi pangguna, iki kira-kira kaping pindho nomer baris.) Mbok menawa kita bisa nggawe 30 panjalukan saben detik?
PHP/Pure PHP
โฐโโค wrk -d 10s -t 4 -c 100 http://127.0.0.1
Running 10s test @ http://127.0.0.1
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 140.79ms 27.88ms 332.31ms 90.75%
Req/Sec 178.63 58.34 252.00 61.01%
7074 requests in 10.04s, 3.62MB read
Requests/sec: 704.46
Transfer/sec: 369.43KB
woy! Kayane ora ana sing salah karo instalasi PHP kita. Versi PHP murni nindakake 700 panjalukan saben detik.
Yen ora ana sing salah karo PHP, bisa uga kita salah ngatur Laravel?
Sawise njelajah web kanggo masalah konfigurasi lan tips kinerja, rong teknik sing paling populer yaiku cache data konfigurasi lan rute supaya ora diproses kanggo saben panyuwunan. Mulane, kita bakal njupuk saran lan nyoba tips iki.
โฐโโค php artisan config:cache
INFO Configuration cached successfully.
โฐโโค php artisan route:cache
INFO Routes cached successfully.
Kabeh katon apik ing baris printah. Ayo gawe pathokan maneh.
โฐโโค wrk -d 10s -t 4 -c 100 http://127.0.0.1
Running 10s test @ http://127.0.0.1
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.13s 543.50ms 1.98s 61.90%
Req/Sec 25.45 13.39 50.00 55.77%
289 requests in 10.04s, 242.15KB read
Socket errors: connect 0, read 0, write 0, timeout 247
Requests/sec: 28.80
Transfer/sec: 24.13KB
Saiki, kita wis nambah kinerja saka 21.04 dadi 28.80 panyuwunan per detik, munggah dramatis meh 37%! Iki bakal cukup nyengsemaken kanggo sembarang paket piranti lunak ... kajaba kasunyatan sing kita isih mung nindakake 1/24 saka jumlah panjalukan saka versi PHP murni.
Yen sampeyan mikir yen ana sing salah karo tes iki, sampeyan kudu ngobrol karo penulis kerangka Lucinda PHP. Ing asil tes, dheweke wis Lucinda ngalahake Laravel dening 36x kanggo panjalukan HTML lan 90x kanggo panjalukan JSON.
Sawise nyoba ing mesin dhewe karo Apache lan Nginx, aku ora duwe alesan kanggo mangu-mangu. Laravel pancen mung sing alon! PHP dhewe ora ala, nanging yen sampeyan nambahake kabeh proses ekstra sing ditambahake Laravel kanggo saben panyuwunan, mula angel banget kanggo nyaranake Laravel minangka pilihan ing taun 2023.
Akun PHP/Wordpress kanggo kira-kira 40% kabeh situs web ing web , nggawe framework sing paling dominan. Nanging kanthi pribadi, aku nemokake manawa popularitas ora kudu nerjemahake kualitas luwih saka aku duwe dorongan sing ora bisa dikendhaleni kanthi cepet kanggo panganan gourmet sing luar biasa saka restoran paling populer ing donya ... McDonald & # x27; Amarga kita wis nyoba kode PHP murni, kita ora bakal nyoba Wordpress dhewe, amarga apa wae sing ana gandhengane karo Wordpress mesthi bakal luwih murah tinimbang 700 panjaluk per detik sing diamati nganggo PHP murni.
Django minangka kerangka kerja populer liyane sing wis suwe. Yen sampeyan wis nggunakake ing sasi, sampeyan mbokmenawa fondly ngelingi antarmuka administrasi database spektakuler bebarengan karo carane ngganggu iku kanggo ngatur kabeh mung cara sing pengin. Ayo ndeleng kepiye kerjane Django ing 2023, utamane karo antarmuka ASGI anyar sing ditambahake ing versi 4.0.
Nyiyapake Django pancen padha karo nyetel Laravel, amarga loro-lorone saka umur arsitektur MVC apik lan bener. Kita bakal ngliwati konfigurasi sing mboseni lan langsung nyetel tampilan.
from django.shortcuts import render
from django.http import HttpResponse
# =====================================================================
def index(request):
count = request.session.get('count', 0)
count += 1
request.session['count'] = count
return HttpResponse(f"Count is {count}")
Patang baris kode padha karo versi Laravel. Ayo ndeleng carane performs & # x27;
โฐโโค python --version
Python 3.10.9
Python/Django
โฐโโค gunicorn --access-logfile - -k uvicorn.workers.UvicornWorker -w 4 djangotest.asgi
[2023-03-21 15:20:38 +0800] [2886633] [INFO] Starting gunicorn 20.1.0
โฐโโค wrk -d 10s -t 4 -c 100 http://127.0.0.1:8000/sessiontest/
Running 10s test @ http://127.0.0.1:8000/sessiontest/
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 277.71ms 142.84ms 835.12ms 69.93%
Req/Sec 91.21 57.57 230.00 61.04%
3577 requests in 10.06s, 1.46MB read
Requests/sec: 355.44
Transfer/sec: 148.56KB
Ora ala ing kabeh panjalukan 355 per detik. Iku mung setengah kinerja versi PHP murni, nanging uga 12x saka versi Laravel & # x27; Django vs. Laravel kayane ora ana kontes.
Kajaba saka kerangka kabeh-kalebu-pawon-sink sing luwih gedhe, ana uga kerangka sing luwih cilik sing mung nindakake sawetara persiyapan dhasar nalika ngidini sampeyan nangani liyane. Salah siji sing paling apik kanggo digunakake yaiku Flask lan pasangan ASGI Quart. Kula piyambak Kerangka PaferaPy dibangun ing ndhuwur Flask, supaya aku ngerti carane gampang iku rampung nalika njaga kinerja & # x27;
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Session benchmark test
import json
import psycopg
import uuid
from flask import Flask, session, redirect, url_for, request, current_app, g, abort, send_from_directory
from flask.sessions import SecureCookieSessionInterface
app = Flask('pafera')
app.secret_key = b'secretkey'
dbconn = 0
# =====================================================================
@app.route('/', defaults={'path': ''}, methods = ['GET', 'POST'])
@app.route('/<path:path>', methods = ['GET', 'POST'])
def index(path):
"""Handles all requests for the server.
We route all requests through here to handle the database and session
logic in one place.
"""
global dbconn
if not dbconn:
dbconn = psycopg.connect('dbname=sessiontest user=sessiontest password=sessiontest')
cursor = dbconn.execute('''
CREATE TABLE IF NOT EXISTS usersessions(
uid TEXT PRIMARY KEY,
data TEXT
)
''')
cursor.close()
dbconn.commit()
sessionid = session.get('sessionid', 0)
if not sessionid:
sessionid = uuid.uuid4().hex
session['sessionid'] = sessionid
cursor = dbconn.execute("SELECT data FROM usersessions WHERE uid = %s", [sessionid])
row = cursor.fetchone()
count = json.loads(row[0])['count'] if row else 0
count += 1
newdata = json.dumps({'count': count})
if count == 1:
cursor.execute("""
INSERT INTO usersessions(uid, data)
VALUES(%s, %s)
""",
[sessionid, newdata]
)
else:
cursor.execute("""
UPDATE usersessions
SET data = %s
WHERE uid = %s
""",
[newdata, sessionid]
)
cursor.close()
dbconn.commit()
return f'Count is {count}'
Kaya sing sampeyan ngerteni, skrip Flask luwih cendhek tinimbang skrip PHP murni. Aku nemokake manawa saka kabeh basa sing wis digunakake, Python bisa uga minangka basa sing paling ekspresif babagan keystrokes sing diketik. Kurang kurung lan kurung, dhaptar lan pangerten dict, lan pamblokiran adhedhasar indentasi tinimbang titik koma nggawe Python luwih gampang nanging kuat ing kemampuane.
Sayange, Python uga minangka basa tujuan umum sing paling alon, sanajan akeh piranti lunak sing wis ditulis. Jumlah perpustakaan Python sing kasedhiya kira-kira kaping papat luwih akeh tinimbang basa sing padha lan nyakup akeh domain, nanging ora ana sing ngomong yen Python cepet utawa performa ing njaba ceruk kaya NumPy.
Ayo ndeleng kepiye versi Flask dibandhingake karo kerangka kerja sadurunge.
Python/Flask
โฐโโค gunicorn --access-logfile - -w 4 flasksite:app
[2023-03-21 15:32:49 +0800] [2856296] [INFO] Starting gunicorn 20.1.0
โฐโโค wrk -d 10s -t 4 -c 100 http://127.0.0.1:8000
Running 10s test @ http://127.0.0.1:8000
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 91.84ms 11.97ms 149.63ms 86.18%
Req/Sec 272.04 39.05 380.00 74.50%
10842 requests in 10.04s, 3.27MB read
Requests/sec: 1080.28
Transfer/sec: 333.37KB
Skrip Flask kita bener-bener luwih cepet tinimbang versi PHP murni kita!
Yen sampeyan kaget karo iki, sampeyan kudu ngerti manawa aplikasi Flask nindakake kabeh wiwitan lan konfigurasi nalika miwiti server gunicorn, nalika PHP nglakokake maneh skrip saben ana panjaluk anyar. Iku & # x27; Setara karo Flask minangka sopir taksi sing enom lan semangat sing wis miwiti mobil lan ngenteni ing pinggir dalan, nalika PHP minangka sopir tuwa sing nginep ing omahe ngenteni telpon mlebu lan mung nyopir. liwat kanggo njupuk sampeyan. Dadi wong sekolah lawas lan teka saka dina ngendi PHP ana owah-owahan apik kanggo HTML kosong lan file SHTML, iku rada sedih kanggo รฉling carane akeh wektu wis liwati, nanging beda desain tenan nggawe hard kanggo PHP kanggo. saingan karo Python, Jawa, lan server Node.js sing mung tetep ing memori lan nangani request karo ease gesit saka juggler a.
Flask bisa dadi kerangka kerja paling cepet nganti saiki, nanging sejatine piranti lunak sing lawas. Komunitas Python ngalih menyang server ASGI asychronous anyar sawetara taun kepungkur, lan mesthi, aku dhewe wis ngalih bebarengan karo wong-wong mau.
Versi paling anyar saka Kerangka Pafera, PaferaPyAsync , adhedhasar Starlette. Senajan ana versi ASGI Flask disebut Quart, beda kinerja antarane Quart lan Starlette cukup kanggo kula kanggo rebase kode marang Starlette tinimbang.
Pemrograman asychronous bisa medeni kanggo akeh wong, nanging sejatine dudu konsep sing angel amarga wong-wong Node.js sing populer babagan konsep kasebut sajrone sepuluh taun kepungkur.
Kita biyen nglawan konkurensi karo multithreading, multiprocessing, komputasi sing disebarake, chaining janji, lan kabeh wektu sing nyenengake sing umure prematur lan ngrusak akeh programer veteran. Saiki, kita mung ngetik async
ing ngarep kita fungsi lan await
ing ngarep kode apa wae sing butuh sawetara wektu kanggo dieksekusi. Pancen luwih wicaksana tinimbang kode biasa, nanging luwih gampang digunakake tinimbang kudu ngatasi primitif sinkronisasi, ngirim pesen, lan ngrampungake janji.
File Starlette kita katon kaya iki:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Session benchmark test
import json
import uuid
import psycopg
from starlette.applications import Starlette
from starlette.responses import Response, PlainTextResponse, JSONResponse, RedirectResponse, HTMLResponse
from starlette.routing import Route, Mount, WebSocketRoute
from starlette_session import SessionMiddleware
dbconn = 0
# =====================================================================
async def index(R):
global dbconn
if not dbconn:
dbconn = await psycopg.AsyncConnection.connect('dbname=sessiontest user=sessiontest password=sessiontest')
cursor = await dbconn.execute('''
CREATE TABLE IF NOT EXISTS usersessions(
uid TEXT PRIMARY KEY,
data TEXT
)
''')
await cursor.close()
await dbconn.commit()
sessionid = R.session.get('sessionid', 0)
if not sessionid:
sessionid = uuid.uuid4().hex
R.session['sessionid'] = sessionid
cursor = await dbconn.execute("SELECT data FROM usersessions WHERE uid = %s", [sessionid])
row = await cursor.fetchone()
count = json.loads(row[0])['count'] if row else 0
count += 1
newdata = json.dumps({'count': count})
if count == 1:
await cursor.execute("""
INSERT INTO usersessions(uid, data)
VALUES(%s, %s)
""",
[sessionid, newdata]
)
else:
await cursor.execute("""
UPDATE usersessions
SET data = %s
WHERE uid = %s
""",
[newdata, sessionid]
)
await cursor.close()
await dbconn.commit()
return PlainTextResponse(f'Count is {count}')
# *********************************************************************
app = Starlette(
debug = True,
routes = [
Route('/{path:path}', index, methods = ['GET', 'POST']),
],
)
app.add_middleware(
SessionMiddleware,
secret_key = 'testsecretkey',
cookie_name = "pafera",
)
Kaya sing sampeyan ngerteni, cukup akeh disalin lan ditempel saka skrip Flask kita kanthi mung sawetara owah-owahan rute lan async/await
tembung kunci.
Pinten dandan bisa nyalin lan nempel kode tenan menehi kita?
Python/Starlette
โฐโโค gunicorn --access-logfile - -k uvicorn.workers.UvicornWorker -w 4 starlettesite:app 130 โต
[2023-03-21 15:42:34 +0800] [2856220] [INFO] Starting gunicorn 20.1.0
โฐโโค wrk -d 10s -t 4 -c 100 http://127.0.0.1:8000
Running 10s test @ http://127.0.0.1:8000
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 21.85ms 10.45ms 67.29ms 55.18%
Req/Sec 1.15k 170.11 1.52k 66.00%
45809 requests in 10.04s, 13.85MB read
Requests/sec: 4562.82
Transfer/sec: 1.38MB
Kita duwe juara anyar, Ladies lan purun! Dhuwur kita sadurunge yaiku versi PHP murni ing 704 panjalukan per detik, sing banjur disusul versi Flask kita kanthi panjaluk 1080 per detik. Skrip Starlette kita ngrusak kabeh pesaing sadurunge kanthi 4562 panjaluk per detik, tegese paningkatan 6x tinimbang PHP murni lan perbaikan 4x saka Flask.
Yen sampeyan durung ngganti kode WSGI Python menyang ASGI, saiki bisa dadi wektu sing apik kanggo miwiti.
Nganti saiki, kita mung nutupi kerangka PHP lan Python. Nanging, sebagรฉyan gedhรฉ donya bener-bener nggunakake Java, DotNet, Node.js, Ruby on Rails, lan teknologi liya kanggo situs web kasebut. Iki dudu ringkesan lengkap kabeh ekosistem lan bioma ing donya, supaya supaya ora nindakake program sing padha karo kimia organik, kita bakal milih mung kerangka kerja sing paling gampang kanggo ngetik kode. .
Kajaba sampeyan wis ndhelikake ing ngisor salinan K&R C utawa Knuth' Seni Pemrograman Komputer suwene limalas taun, sampeyan mbokmenawa wis krungu saka Node.js & # x27; Kita sing wis ana wiwit wiwitan JavaScript uga wedi banget, kaget, utawa loro-lorone ing negara JavaScript modern, nanging ora bisa nolak yen JavaScript wis dadi kekuwatan sing kudu dianggep ing server uga. minangka browser. Sawise kabeh, saiki kita duwe integer 64 bit asli ing basa kasebut! Iku luwih apik tinimbang kabeh sing disimpen ing 64 bit floats adoh!
ExpressJS mbokmenawa server Node.js paling gampang digunakake, supaya kita bakal nindakake app Node.js/ExpressJS cepet lan reged kanggo ngawula counter kita.
/**********************************************************************
* Simple session test using ExpressJS.
**********************************************************************/
var L = console.log;
var uuid = require('uuid4');
var express = require('express');
var session = require('express-session');
var MemoryStore = require('memorystore')(session);
var { Client } = require('pg')
var db = 0;
var app = express();
const PORT = 8000;
//session middleware
app.use(
session({
secret: "secretkey",
saveUninitialized: true,
resave: false,
store: new MemoryStore({
checkPeriod: 1000 * 60 * 60 * 24 // prune expired entries every 24h
})
})
);
app.get('/',
async function(req,res)
{
if (!db)
{
db = new Client({
user: 'sessiontest',
host: '127.0.0.1',
database: 'sessiontest',
password: 'sessiontest'
});
await db.connect();
await db.query(`
CREATE TABLE IF NOT EXISTS usersessions(
uid TEXT PRIMARY KEY,
data TEXT
)`,
[]
);
};
var session = req.session;
if (!session.sessionid)
{
session.sessionid = uuid();
}
var row = 0;
let queryresult = await db.query(`
SELECT data::TEXT
FROM usersessions
WHERE uid = $1`,
[session.sessionid]
);
if (queryresult && queryresult.rows.length)
{
row = queryresult.rows[0].data;
}
var count = 0;
if (row)
{
var data = JSON.parse(row);
data.count += 1;
count = data.count;
await db.query(`
UPDATE usersessions
SET data = $1
WHERE uid = $2
`,
[JSON.stringify(data), session.sessionid]
);
} else
{
await db.query(`
INSERT INTO usersessions(uid, data)
VALUES($1, $2)`,
[session.sessionid, JSON.stringify({count: 1})]
);
count = 1;
}
res.send(`Count is ${count}`);
}
);
app.listen(PORT, () => console.log(`Server Running at port ${PORT}`));
Kode iki luwih gampang ditulis tinimbang versi Python, sanajan JavaScript asli dadi rada angel nalika aplikasi dadi luwih gedhe, lan kabeh upaya kanggo mbenerake iki kayata TypeScript kanthi cepet dadi luwih verbose tinimbang Python.
Ayo ndeleng carane iki performs & # x27;
Node.js/ExpressJS
โฐโโค node --version v19.6.0
โฐโโค NODE_ENV=production node nodejsapp.js 130 โต
Server Running at port 8000
โฐโโค wrk -d 10s -t 4 -c 100 http://127.0.0.1:8000
Running 10s test @ http://127.0.0.1:8000
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 90.41ms 7.20ms 188.29ms 85.16%
Req/Sec 277.15 37.21 393.00 81.66%
11018 requests in 10.02s, 3.82MB read
Requests/sec: 1100.12
Transfer/sec: 390.68KB
Sampeyan bisa uga wis krungu kuna (kuna dening standar Internet anyways ...) folktales bab Node.js & # x27; kacepetan, lan crita sing biasane bener thanks kanggo karya spektakuler sing Google wis rampung karo mesin V8 JavaScript. Ing kasus iki sanadyan, sanajan app cepet kita outperforms script Flask, alam Utas siji dikalahakรฉ dening papat pangolahan async wielded dening Starlette Knight sing ngandika "Ni!".
Ayo njaluk bantuan liyane!
โฐโโค pm2 start nodejsapp.js -i 4
[PM2] Spawning PM2 daemon with pm2_home=/home/jim/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /home/jim/projects/paferarust/nodejsapp.js in cluster_mode (4 instances)
[PM2] Done.
โโโโโโฌโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโฌโโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโ
โ id โ name โ namespace โ version โ mode โ pid โ uptime โ โบ โ status โ cpu โ mem โ user โ watching โ
โโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโผโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโค
โ 0 โ nodejsapp โ default โ N/A โ cluster โ 37141 โ 0s โ 0 โ online โ 0% โ 64.6mb โ jim โ disabled โ
โ 1 โ nodejsapp โ default โ N/A โ cluster โ 37148 โ 0s โ 0 โ online โ 0% โ 64.5mb โ jim โ disabled โ
โ 2 โ nodejsapp โ default โ N/A โ cluster โ 37159 โ 0s โ 0 โ online โ 0% โ 56.0mb โ jim โ disabled โ
โ 3 โ nodejsapp โ default โ N/A โ cluster โ 37171 โ 0s โ 0 โ online โ 0% โ 45.3mb โ jim โ disabled โ
โโโโโโดโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโดโโโโโโโดโโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโ
Oke! Saiki iku malah papat ing papat perang! Ayo dadi pathokan!
โฐโโค wrk -d 10s -t 4 -c 100 http://127.0.0.1:8000
Running 10s test @ http://127.0.0.1:8000
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 45.09ms 19.89ms 176.14ms 60.22%
Req/Sec 558.93 97.50 770.00 66.17%
22234 requests in 10.02s, 7.71MB read
Requests/sec: 2218.69
Transfer/sec: 787.89KB
Isih ora cukup ing tingkat Starlette, nanging ora ala kanggo hack JavaScript limang menit cepet & # x27; Saka tesku dhewe, skrip iki bener-bener ditahan maneh ing tingkat antarmuka database amarga node-postgres ora ana sing efisien kaya psycopg kanggo Python. Ngalih menyang sqlite minangka driver database ngasilake luwih saka 3000 panjalukan per detik kanggo kode ExpressJS padha.
Wangsulan: Bab ingkang utama kanggo Wigati iku senadyan kacepetan eksekusi Python alon, frameworks ASGI bener bisa competitive karo solusi Node.js kanggo workloads tartamtu.
Dadi saiki, kita wis nyedhak menyang pucuk gunung, lan miturut gunung, maksudku skor benchmark paling dhuwur sing dicathet dening tikus lan wong lanang.
Yen katon ing paling saka pathokan framework kasedhiya ing web, sampeyan bakal sok dong mirsani sing ana rong basa sing kathah dominasi ndhuwur: C ++ lan Rust. Aku wis kerjo karo C ++ wiwit 90s, lan aku malah wis Win32 C ++ framework bali sadurunge MFC / ATL ana bab, supaya aku duwe akรจh pengalaman karo basa. Iku ora akeh fun karya karo soko nalika sampeyan wis ngerti, supaya kita bakal nindakake versi Rust tinimbang. ;)
Rust relatif anyar minangka adoh saka basa program, nanging dadi obyek penasaran kanggo kula nalika Linus Torvalds announced sing bakal nampa Rust minangka basa program kernel Linux. Kanggo kita programer lawas, iku bab padha ngomong sing fangled anyar hippie thingie anyar iki bakal dadi amandemen anyar kanggo Konstitusi AS.
Saiki, yen sampeyan dadi programmer sing berpengalaman, sampeyan cenderung ora cepet-cepet mlayu kaya sing ditindakake wong enom, utawa sampeyan bisa uga kobong amarga owah-owahan cepet ing basa utawa perpustakaan. (Sapa wae sing nggunakake versi pisanan AngularJS bakal ngerti apa sing dakkandhakake.) Rust isih ana ing tahap pangembangan eksperimen kasebut, lan aku rumangsa lucu yen akeh conto kode ing web ora malah. kompilasi maneh karo versi paket saiki.
Nanging, kinerja sing dituduhake dening aplikasi Rust ora bisa ditolak. Yen sampeyan durung tau nyoba ripgrep utawa fd-golek metu ing wit kode sumber gedhe, temtunipun kudu menehi wong muter . Malah kasedhiya kanggo umume distribusi Linux mung saka manajer paket. Sampeyan ngganti verbosity kanggo kinerja karo Rust ... a akeh saka verbosity kanggo a akeh saka kinerja.
Kode lengkap kanggo Rust rada gedhe, mula kita bakal mriksa panangan sing relevan ing kene:
// =====================================================================
pub async fn RunQuery(
db: &web::Data<Pool>,
query: &str,
args: &[&(dyn ToSql + Sync)]
) -> Result<Vec<tokio_postgres::row::Row>, tokio_postgres::Error>
{
let client = db.get().await.unwrap();
let statement = client.prepare_cached(query).await.unwrap();
client.query(&statement, args).await
}
// =====================================================================
pub async fn index(
req: HttpRequest,
session: Session,
db: web::Data<Pool>,
) -> Result<HttpResponse, Error>
{
let mut count = 1;
if let Some(sessionid) = session.get::<String>("sessionid")?
{
let rows = RunQuery(
&db,
"SELECT data
FROM usersessions
WHERE uid = $1",
&[&sessionid]
).await.unwrap();
if rows.is_empty()
{
let jsondata = serde_json::json!({
"count": 1,
}).to_string();
RunQuery(
&db,
"INSERT INTO usersessions(uid, data)
VALUES($1, $2)",
&[&sessionid, &jsondata]
).await
.expect("Insert failed!");
} else
{
let jsonstring:&str = rows[0].get(0);
let countdata: CountData = serde_json::from_str(jsonstring)?;
count = countdata.count;
count += 1;
let jsondata = serde_json::json!({
"count": count,
}).to_string();
RunQuery(
&db,
"UPDATE usersessions
SET data = $1
WHERE uid = $2
",
&[&jsondata, &sessionid]
).await
.expect("Update failed!");
}
} else
{
let sessionid = Uuid::new_v4().to_string();
let jsondata = serde_json::json!({
"count": 1,
}).to_string();
RunQuery(
&db,
"INSERT INTO usersessions(uid, data)
VALUES($1, $2)",
&[&sessionid, &jsondata]
).await
.expect("Insert failed!");
session.insert("sessionid", sessionid)?;
}
Ok(HttpResponse::Ok().body(format!(
"Count is {:?}",
count
)))
}
Iki luwih rumit tinimbang versi Python/Node.js...
Rust/Actix
โฐโโค cargo run --release
[2023-03-21T23:37:25Z INFO actix_server::builder] starting 4 workers
Server running at http://127.0.0.1:8888/
โฐโโค wrk -d 10s -t 4 -c 100 http://127.0.0.1:8888
Running 10s test @ http://127.0.0.1:8888
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 9.93ms 3.90ms 77.18ms 94.87%
Req/Sec 2.59k 226.41 2.83k 89.25%
102951 requests in 10.03s, 24.59MB read
Requests/sec: 10267.39
Transfer/sec: 2.45MB
Lan performa luwih akeh!
Server Rust kita nggunakake Actix/deadpool_postgres kanthi gampang ngalahake juara Starlette sadurunge kanthi +125%, ExpressJS kanthi +362%, lan PHP murni kanthi +1366%. (Aku bakal ninggalake delta kinerja karo versi Laravel minangka latihan kanggo maca.)
Aku wis ketemu sing sinau basa Rust dhewe wis luwih angel tinimbang basa liyane amarga wis akeh gotchas luwih saka apa aku wis katon njaba 6502 Majelis, nanging yen server Rust bisa njupuk ing 14x nomer kedhaftar minangka server PHP, banjur mbok menawa ana soko kanggo gained karo teknologi ngoper sawise kabeh. Pramila versi sabanjure Framework Pafera bakal adhedhasar Rust. Kurva sinau luwih dhuwur tinimbang basa skrip, nanging kinerja bakal migunani. Yen sampeyan ora bisa nglampahi wektu kanggo sinau Rust, banjur basis tumpukan teknologi ing Starlette utawa Node.js uga ora kaputusan ala.
Ing rong puluh taun kepungkur, kita wis lunga saka situs hosting statis sing murah menyang hosting bareng karo tumpukan LAMP kanggo nyewa VPS menyang AWS, Azure, lan layanan maya liyane. Saiki, akeh perusahaan sing marem nggawe keputusan desain adhedhasar sapa wae sing bisa ditemokake sing kasedhiya utawa paling murah amarga ana layanan awan sing trep nggawe gampang mbuwang luwih akeh hardware ing server lan aplikasi sing alon. Iki wis menehi keuntungan jangka pendek kanthi biaya utang teknis jangka panjang.
70 taun kepungkur, ana balapan antariksa gedhe antarane Uni Soviet lan Amerika Serikat. Uni Soviet menangakรฉ akรจh-akรจhรฉ tonggak sejarah awal. Dheweke duwe satelit pisanan ing Sputnik, asu pisanan ing ruang angkasa ing Laika, pesawat ruang angkasa rembulan pisanan ing Luna 2, wong lanang lan wadon pisanan ing ruang angkasa ing Yuri Gagarin lan Valentina Tereshkova, lan liya-liyane ...
Nanging padha alon accumulating utang technical.
Senadyan Uni Sovyรจt minangka sing pisanan kanggo saben prestasi kasebut, proses lan tujuan rekayasa kasebut nyebabake dheweke fokus marang tantangan jangka pendek tinimbang kelayakan jangka panjang. Dheweke menang saben-saben mlumpat, nanging saya kesel lan alon-alon nalika mungsuh terus maju menyang garis finish.
Sawise Neil Armstrong njupuk langkah sajarah ing rembulan ing televisi langsung, Amerika njupuk timbal, lan banjur tetep ana minangka program Soviet faltered. Iki ora beda karo perusahaan saiki sing fokus ing perkara gedhe sabanjure, bayaran gedhe sabanjure, utawa teknologi gedhe sabanjure nalika gagal ngembangake kabiasaan lan strategi sing tepat kanggo jangka panjang.
Dadi pisanan menyang pasar ora ateges sampeyan bakal dadi pemain dominan ing pasar kasebut. Utawa, njupuk wektu kanggo nindakake samubarang sing bener ora njamin sukses, nanging mesthi nambah kasempatan kanggo prestasi jangka panjang. Yen sampeyan pimpinan teknologi kanggo perusahaan sampeyan, pilih arah lan alat sing bener kanggo beban kerja sampeyan. Aja popularitas ngganti kinerja lan efisiensi.
Pengin ndownload file 7z sing ngemot skrip Rust, ExpressJS, Flask, Starlette, lan Pure PHP?
Babagan Penulis |
|
![]() |
Jim wis program wiwit entuk IBM PS / 2 bali sak 90s. Nganti saiki, dheweke isih luwih seneng nulis HTML lan SQL kanthi tangan, lan fokus ing efisiensi lan bener ing karyane. |