$ node server.js
[loadbal|300457|tcp/9999] loadbalancer started
[service|300469|tcp/5000] cluster-node started on port 5000
[service|300471|tcp/5001] cluster-node started on port 5001
[service|300469|tcp/5000] cluster-node connected
[service|300471|tcp/5001] cluster-node connected
[loadbal|300457|tcp/9999] initing cluster-app
[03-16T14:40:27] ├☑ myservice: connected! # executed on cluster
[03-16T14:40:27] ├☑ myservice: ping! # executed on cluster {
"master": "./cluster/loadbalancer.js",
"workers": { // cpus
"serviceA":{ "worker":"./service/index.js", "count":1, "port":5000 },
"serviceB":{ "worker":"./service/index.js", "count":1, "port":5001 }
},
"remotes":[
{ "host":"192.23.4.56", "port":5000 }, // same app but runs on other server
{ "host":"192.23.4.56", "port":5001 }, // they become workers of this server
],
"remotes":[],
"accessKey": "test", // cluster management over rest/cli
"cli":false // thanks to npmjs.org/cluster-service
}cluster functions:
const service = require('./../cluster/service').service('myservice')
service.module.exports = {
async ping () {
let app = service.client.methods
app.log('ping!', 'myservice')
//log('local ping!')
return 123
}
}
service.init = async (app) => {
await app.log("connected!",'myservice')
await app.ping()
}- across cpu's thanks to cluster-service
- across servers thanks to ezrpc
- update/manage workers using REST/cli thanks to cluster-service
when using remotes, use env-var
upstream=main.myserver.orge.g. on remotes. By doing so,app.ping()will run through loadbalancermain.myserver.org.
all workers can execute / save data centrally on cluster/loadbalancer.js:
await app.set("foo.bar",[{x:1}]) // generates db.json
await app.get("foo.bar") ) // [{x:1}]
await app.find("foo.bar", {x:{$lt:2}}) // [{x:1}]
await app.findOne("foo.bar",{x:{$lt:2}}) // {x:1}
db.jsonnow contains{foo:{bar:[{x:1}]}}, which you can easily backup/edit
workers can easily use own databases:
const db = require('./server/db')({file:'mydb.json', ratelimit:1500})
db.accounts = {a:[{foo:1},{foo:2}]}
let some = db.find('accounts.a',{foo:{$lt:2}}) )
let one = db.findOne('accounts.a',{foo:{$lt:2}}) )
$ podman build -t elastinode
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
elasticnode latest 79988bafb26d 32 seconds ago 51.5MB
$ DOCKER_BUILDKIT=1 docker build -t elasticnode --output out
$ ls -la out/server
-rwxr-xr-x 1 44M mrt 16 16:10 out/servernot bad for a distributed scalable app no?
$ node test/test.js
[loadbal|301490|tcp/9999] loadbalancer started
[service|301502|tcp/5000] cluster-node started on port 5000
[service|301502|tcp/5000] cluster-node connected
[service|301503|tcp/5001] cluster-node started on port 5001
[loadbal|301490|tcp/9999] initing cluster-app
[service|301503|tcp/5001] cluster-node connected
[ { id: 'projectA', data: {} }, { id: 'projectB', data: {} } ]
connected
[03-16T14:50:15] ├☑ myservice: connected!
[03-16T14:50:15] ├☑ myservice: ping!
OK : app.ping => 123
done