-
-
Notifications
You must be signed in to change notification settings - Fork 757
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Microservices - current state #939
Comments
I know @claustres has been doing the work around From my perspective on a module basis, From an architectural perspective I found that instead of forcing to split everything up right at the beginning you can actually get pretty far with the monolith. With When we do split up our APIs it usually happens more naturally on a per-responsibility basis. They then just communicate with each other through Feathers clients using all the infrastructure that is already in place. My question for you (and others that are asking about this) would be:
|
A monolith might be a good way to start, and the conventional feathers service definitely is service oriented and would make it super easy to pluck it out and put it on a different server later on. But there are a lot of benefits to being able to split up feathers services into separate servers, which might become apparent with scale. Disclaimer: I have not worked at large scale so the points below are just my thoughts, and I have been thinking a lot about it, because we have to transition from current feathers monoliths to a distributed system soon.
As I said before feathers already let's you write service oriented code. But if something like a more polished version of feathers-distributed was baked in, it would've been magical and in my opinion make feathers the near perfect framework in Node.js it definitely deserves to be. I am already in love with it, and appreciate all the hard work put into it. As for now, I have two feathers based monoliths and I have written a sort of a REST only client in one for the other. Which is ofcourse in no way ideal but lets me get on with it for now. // client
import feathers from '@feathersjs/client';
import errors from '@feathersjs/errors';
import ax from 'axios';
export default class FeathersClient {
constructor(opts) {
const { url, token } = opts;
const client = feathers();
const restClient = feathers.rest(url);
const axios = ax.create({ headers: { 'X-Access-Token': token } });
client.configure(restClient.axios(axios));
this.client = client;
}
async create(rawData) {
const { service, method, args: { id, data, params } = {} } = rawData;
const proxy = this.client.service(service);
const methodMap = {
find: () => proxy.find(params),
get: () => proxy.get(id, params),
create: () => proxy.create(data, params),
update: () => proxy.update(id, data, params),
patch: () => proxy.patch(id, data, params),
remove: () => proxy.remove(id, params)
};
try {
const res = await methodMap[method]();
return res;
} catch (error) {
throw new (errors[error.name] || errors.BadRequest)(error.message);
}
}
} // usage
this.use('/server1', new FeathersClient(server1Config));
/**
.
.
.
*/
export default class ServiceA {
setup(app) {
this.otherServer = app.service('/server1')
}
async find() {
const res = await this.otherServer.create({
service: 'someServiceOnServer1',
method: 'patch',
args: { id, data, params }
})
}
} The ideal behaviour however would have been, one could simply do this. export default class ServiceA {
setup(app) {
// service discovery
this.someServiceOnServer1 = app.service('/someServiceOnServer1')
}
async find() {
const res = await this.someServiceOnServer1.patch(id, data, params)
}
} |
wow, I was just about to write a response @daffl's excellent response however I really cannot say it any better than @subodhpareek18 As @subodhpareek18 said, neither large monoliths or distributed microservices are easy but breaking things down into services means:
I just feel that given the current capabilities of feathers and its great developer experience, if we could extend that to a well designed microservices capability (with gateway functionality) I really think it would become the absolute champion framework. |
Micro-service is a recurrent raised issue, I think an article in the blog or a dedicated section in the doc would be great to avoid this popping up again an again (I can help). Like @daffl from my perspective on a module basis, feathers-distributed has no open bug issues and about fifty downloads a month so I'm assuming that it works for the people using it. Unfortunately we did not yet test it on our production infrastructure so we warn that for us it is still in beta, however if someone told us it has been successfully used in production we can change the README 😅 I must confess I have some trouble with the microservices trend. Splitting things up with a well-defined boundary and interface is something probably as old as programming is and known as modularity. IMHO microservices are more a deployment issue than anything else: deploying all modules in the same process space (a.k.a. monolith) or in different process space (a.k.a. microservices).
Of course this changes how you code a little bit because you need to use some inter-process communication layer and if you want to support auto-scaling (i.e. scale on-the-fly) something like service discovery. You also have to manage load balancing. This makes a best solution almost impossible to be found because you can reuse a lot of different tools depending on your needs on these subjects. I agree you can go pretty far with the monolith and feathers-sync. I would say it is something between the true monolith and the true microservices, i.e. you scale your entire app not its underlying modules/services according to their workload. It does not handle auto-scaling as well and this is why we launched feathers-distributed. The goal is to make the communication layer, service discovery and load balancing transparent from the programmer perspective based on the simple cote module. You can create modules/services as usual and simply choose to deploy them in microservices easily if required.
You could of course split up your API "by hand" on a per-responsibility basis as @daffl said and just communicate with each other through Feathers clients using all the infrastructure that is already in place. However this will require more manual work, will create a tight coupling with your underlying infrastructure and will not allow auto-scaling unless you create some discovery mechanism. Last but not least I would like to answer some of your ideas:
I hope this comment helped the debate and don't forget that you can help building a great feathers-distributed 👍 |
Moleculerjs has nice microservice features and seems to gain traction. There is an adapter to feathers services: https://github.com/zygos/moleculer-adapter-feathers#readme |
I've just published a new library to distribute FeathersJS apps over the network with inter-service communication using HTTP protocol. The feathers-http-distributed module was built as preparation for migrating all our FeathersJS services to Kubernetes, though it can be used for a broad range of use cases besides Kubernetes. Enjoy! |
I love feathers having used it for a number of projects to date. I find it's real sweet spot to be applications that have a single backend service or for creating http based microservices. However when considering it's use in a more advanced microservices design that I'd feel happy running in production, I find various roadblocks:
I realise a lot of these topics have been covered in various issues and posts however I was looking for more of a 'current state of the world' view and recommendations moving forward. I guess I'm looking to stay as much on the happy/proven path without having to bake my own functionality where possible.
I'm more than happy to contribute if some of the above capabilities are lacking currently.
The text was updated successfully, but these errors were encountered: