Què és fibjs?
fibjs és un marc de desenvolupament de servidors d'aplicacions dissenyat per al desenvolupament de backend web. Està construït sobre el motor JavaScript de Google V8 i utilitza una solució de concurrència diferent de les devolució de trucades tradicionals. fibjs utilitza fibra (fibra) per aïllar la complexitat empresarial causada per trucades asíncrones a nivell de marc, reduint en gran mesura la dificultat de desenvolupament i reduint els problemes de rendiment causats pel processament asíncron freqüent a l'espai de l'usuari.
Per raons històriques, JavaScript s'utilitza principalment per gestionar la interfície d'usuari del navegador. El desenvolupament de la interfície d'usuari és un model típic d'un sol fil basat en esdeveniments, de manera que JavaScript ha anat formant progressivament el processament asíncron com a paradigma de programació principal.
Amb l'èxit de JavaScript, cada cop més persones comencen a aplicar JavaScript a altres escenaris. Al mateix temps, la gent és cada cop més conscient que, en molts escenaris, el processament asíncron no és l'opció més adequada.
Retorn a la natura, desenvolupament àgil
fibjs utilitza fibra (fibra) a nivell de marc per aïllar la complexitat empresarial causada per les trucades asíncrones i encapsula el processament d'E/S asíncrona en trucades síncrones més intuïtives. Els enginyers només necessiten escriure codi d'acord amb la lògica empresarial síncrona habitual i gaudir de la gran comoditat que ofereix el processament asíncron.
El codi següent s'ha extret de la documentació del mòdul mysql:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32conn.beginTransaction(err => {
if (err) {
throw err;
}
conn.query('INSERT INTO posts SET title=?', title,
(error, results, fields) => {
if (error) {
return conn.rollback(() => {
throw error;
});
}
var log = 'Post ' + results.insertId + ' added';
conn.query('INSERT INTO log SET data=?', log,
(error, results, fields) => {
if (error) {
return conn.rollback(() => {
throw error;
});
}
conn.commit((err) => {
if (err) {
return conn.rollback(() => {
throw err;
});
}
console.log('success!');
});
});
});
});
En fibjs, es fa el mateix treball, el codi és el següent:
1
2
3
4
5
6conn.trans(() => {
var result = conn.execute('INSERT INTO posts SET title=?', title);
var log = 'Post ' + results.insertId + ' added';
conn.execute('INSERT INTO log SET data=?', log);
});
console.log('success!');
Si busqueu la simplicitat, fins i tot podeu escriure el codi així:
1
2
3
4conn.trans(() => conn.execute('INSERT INTO log SET data=?',
'Post ' + conn.execute('INSERT INTO posts SET title=?', title).insertId +
' added'));
console.log('success!');
Mitjançant la comparació, podem veure clarament les diferències que comporten els diferents estils de programació. Menys codi significa menys errors, i amb menys codi, la lògica del codi es fa més clara. En aquest cas, es beneficiaran tant les tasques de desenvolupament com de manteniment.
Abraça l'alta energia
Tot i que és relativament fàcil escalar un servidor per millorar la capacitat de resposta, el rendiment segueix sent una de les consideracions importants a l'hora d'escollir un marc de desenvolupament. Amb la introducció d'ES7, l'async es va introduir a JavaScript com a nou model de desenvolupament asíncron. No obstant això, mentre gaudim de l'estil de programació síncrona que ofereix async, també hem d'afrontar el seu impacte en el rendiment.
Per comparar les diferències de rendiment aportades per diferents estils de programació, podem utilitzar el següent codi de prova:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39var count = 1000;
async function test_async(n) {
if (n == count)
return;
await test_async(n + 1);
}
function test_callback(n, cb) {
if (n == count)
return cb();
test_callback(n + 1, () => {
cb();
});
}
function test_sync(n) {
if (n == count)
return;
test_sync(n + 1);
}
async function test() {
console.time("async");
await test_async(0);
console.timeEnd("async");
console.time("callback");
test_callback(0, () => {
console.timeEnd("callback");
});
console.time("sync");
test_sync(0);
console.timeEnd("sync");
}
test();
Amb l'última versió 8, els resultats d'execució d'aquest codi són els següents:
1
2
3async: 0.539ms
callback: 0.221ms
sync: 0.061ms
A partir dels resultats de la prova, podem veure clarament que quan s'utilitza àmpliament l'async, el servidor passarà molt de temps processant les trucades i les devolucions de les funcions asíncrones. També ho hem trobat en algunes proves reals d'aplicacions del costat del servidor. Tanmateix, aquesta caiguda dràstica del rendiment és completament inacceptable.
En canvi, fibjs utilitza tecnologia de fibra, aprofita al màxim les característiques del propi llenguatge JavaScript i maximitza el rendiment superior del motor V8. Els enginyers poden maximitzar fàcilment el rendiment del servidor.
Trieu paradigmes amb flexibilitat sense ser segrestat
Escollir utilitzar fibjs no vol dir que hàgiu d'utilitzar un estil de desenvolupament sincrònic. De fet, fibjs admet diversos paradigmes de programació asíncrona que coneixeu i pot canviar de manera flexible entre estils síncrons i asíncrons.
Tanmateix, tant si són funcions de devolució de trucada com si són asincròniques, tenen un defecte fatal, que és la contagiositat. Si una funció és una funció de devolució de trucada o asíncrona, totes les altres funcions que en depenen també han de ser funcions de devolució de trucada o asíncrona. En el desenvolupament de programari a gran escala, això comportarà grans costos de desenvolupament.
Preneu com a exemple un escenari de desenvolupament de servidor senzill. A l'inici del projecte, vam optar per emmagatzemar les dades de la sessió a la memòria, en aquest moment, podem llegir i emmagatzemar directament les dades mitjançant la sincronització, i desenvolupar funcions empresarials completes basades en això. A mesura que l'escala empresarial s'amplia, hem d'emmagatzemar les dades de sessió a Redis o MongoDB. En aquest moment, hem de canviar les operacions relacionades amb la sessió al mode asíncron.
En teoria, podem modificar cada funció una per una perquè s'ajustin als requisits de les funcions dependents, però això requereix que entenem completament tots els mòduls i tinguem la capacitat de modificar-los. Això és gairebé impossible quan diverses persones es desenvolupen de manera col·laborativa o utilitzen mòduls de tercers.
Per tant, en tots els mòduls comuns, s'han de proporcionar interfícies tant síncrones com asíncrones per equilibrar la relació entre asincronia i rendiment. Els desenvolupadors habituals solen optar per proporcionar només interfícies asíncrones, cosa que provoca problemes de rendiment.
En fibjs podeu resoldre problemes similars fàcilment i evitar la propagació incontrolada d'async explícit:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17var util = require('util');
function session_get(sid) {
return sdata;
}
async function async_session_get(sid) {
return sdata;
}
function callback_session_get(sid, cb) {
cb(null, sdata);
}
data = session_get(sid);
data = util.sync(async_session_get)(sid);
data = util.sync(callback_session_get)(sid);
fibjs proporciona la funció util.sync, que pot convertir funcions de devolució de trucada o funcions asíncrones en funcions síncrones i cridar-les directament. D'aquesta manera, podem integrar fàcilment mòduls de diferents paradigmes de programació i minimitzar els costos de desenvolupament, transformant-los en paradigmes sincronitzats, evitant de manera efectiva el desastre provocat pel contagi del paradigma.
Comença a experimentar
Estàs preparat per tenir una gran experiència de desenvolupament? Per tant, comencem amb la instal·lació.