This stops short at all the really interesting stuff of microservices. Where's the service discovery? Failover? Secret storage? Communication?
Besides that, I don't agree with putting dependency injection in a microservice. Why bother? In a sense, microservices are a breath of fresh air, because they're supposed to "fit in one developer's head." If you're already adding layers of indirection, you're making the code harder to reason about for no good reason.
Yep - yet another half-baked project that someone is using for internet points. I'm really getting sick of people re-inventing the wheel poorly.
The number of available tools is really getting out of hand and I wish projects like this wouldn't suck away resources from established, functional projects.
I am developing something similar with effe [1] and effe-tool [2] (completely WIP), that are suppose to be an open source implementation of AWS lambda.
I am facing problems similar to the one of the author, and I can see why he made some choices but I disagree on most.
In my opinion we should aim to a tool to build single executables and another tool to package those executable in a docker container.
Also I am doing my best to have as little as possible configurations, configurations are needed to deploy your application, and deployment is a different kind of problem.
I must say that is HARD, mainly for the constrain of go.
I would love to attach metadata to a go package, configuration would became a no-issues.
I would love to build my packages in a dynamic way, eg. these file is the scaffolding, those other are the custom logic, go compile and create a single artefact. However this seems impossible.
Go is a nice language but its tool really kill creativity.
What Go really needs for microservices is a library equivalent to Finagle[0]. GRPC is getting there, but we need some community standards for RPC, circuit breaking, exponential backoff, zipkin-like debugging etc...
We do not have a Go implementation yet, but at Datawire.io we are working on a IDL that compiles into a number of target languages and generates client and server code with all those features. Go is on our TODO list after we add Ruby support.
I feel the same problems with scaffolding / boilerplate, but I'm not sure I want to bring in Ruby / Cucumber to run my acceptance testing. These are just as easily written in Go too.
Typically via HTTP using JSON. Frequently though people realize JSON is a bad format for exchange between many services at scale so they will switch to something like protobufs/thrift/avro.
The HTTP part is not a requirement either, as there are microservices that talk via application specific tcp protocols , udp, or if they are housed on the same machine memory mapped files.
interesting read. i started using go for small api integrations, server-based networking work - i like the language - i have to admit it is ugly though
I'm the author of this post and thanks for the feedback, just wanted to make a few comments...
1. Half baked
Not sure I think this is a fair comment, it implies a lack of care, I do however think that work in progress is a fair assessment and actually I state this myself, the approach taken is an evolutionary one. With every use, identify improvements and make them so next time things are better. The more we share our learnings the faster the industry will advance and to many Microservices patterns are still a new approach, there are huge learnings to be had, some from personal experiences other from avoiding the failings of others. Just trying to share what I know in the hope it might help someone else.
2. Dependency Injection
I was fairly confident this is a marmite (love or hate) approach with Go, there are some threads out there longer than the complete works of Shakespeare arguing if it is needed or not. For me it helps with decoupling when taking a test first approach and this is the main reason I choose to use it as a pattern. I have written services with and without DI, I definitely prefer with, I did say it was opinionated :)
3. Service Discovery, Failover, Storage, etc
This is a huge topic in itself yet from people I speak to when discussing Microservices is something that often comes up. I personally hope that service discovery will be picked up at a Platform level by Mesosphere, Kubernetes or new PAAS providers like Docker Cloud or Google Container Service. At present I am using Consul, Consul Registrator, and HA Proxy but the bigger and more complicated the system the bigger this problem becomes and I am not 100% happy with things in this space. Storage is best avoided where possible, Docker certainly introduces problems with mutability, S3 is an option at the moment for shared storage but there are interesting things in the works with Docker Volumes. Event Sourcing is another huge area for Microservices, effectively decoupling them removes many of the problems around failover but this in itself huge complicated area. In general developing for failure is a good approach, deciding how things fail should be a cross functional requirement when discussing the features.
4. Feature Toggles
Good call and in fact at my day job we use these extensively, in fact we could not deploy without them. At the moment this is not a problem I have had to tackle and therefore have not added this feature. I suspect this is something that will affect me in the future once I move from writing new services to changing and maintaining existing ones. Feature toggling in microservices opens up a completely new approach, do you toggle in the service code or with a different copy of the service itself and toggle within the service routing?
Really appreciate all the comments, I have certainly learned some stuff and I'm really looking forward to where the industry will head in the next 12 months.
[+] [-] remmelt|10 years ago|reply
Besides that, I don't agree with putting dependency injection in a microservice. Why bother? In a sense, microservices are a breath of fresh air, because they're supposed to "fit in one developer's head." If you're already adding layers of indirection, you're making the code harder to reason about for no good reason.
[+] [-] anon987|10 years ago|reply
The number of available tools is really getting out of hand and I wish projects like this wouldn't suck away resources from established, functional projects.
[+] [-] artpepper|10 years ago|reply
DI + properly defined interfaces shouldn't make code harder to reason about.
[+] [-] siscia|10 years ago|reply
I am facing problems similar to the one of the author, and I can see why he made some choices but I disagree on most.
In my opinion we should aim to a tool to build single executables and another tool to package those executable in a docker container.
Also I am doing my best to have as little as possible configurations, configurations are needed to deploy your application, and deployment is a different kind of problem.
I must say that is HARD, mainly for the constrain of go.
I would love to attach metadata to a go package, configuration would became a no-issues.
I would love to build my packages in a dynamic way, eg. these file is the scaffolding, those other are the custom logic, go compile and create a single artefact. However this seems impossible.
Go is a nice language but its tool really kill creativity.
[1]: https://github.com/siscia/effe
[2]: https://github.com/siscia/effe-tool
[+] [-] jzelinskie|10 years ago|reply
[0]: https://github.com/twitter/finagle
[+] [-] m_sahaf|10 years ago|reply
[+] [-] chuhnk|10 years ago|reply
[+] [-] meddlepal|10 years ago|reply
Check us out!
[0]: https://github.com/datawire/datawire-connect
[1]: https://github.com/datawire/quark
[+] [-] ane|10 years ago|reply
[+] [-] snikch|10 years ago|reply
Liking all the rest :ok_hand:.
[+] [-] Bedon292|10 years ago|reply
[+] [-] morenoh149|10 years ago|reply
[+] [-] nickjackson|10 years ago|reply
Deals with Service Discovery, metrics, tracing, gRPC, and all sorts.
[1]: https://github.com/micro/micro
[+] [-] touristtam|10 years ago|reply
[+] [-] Kiro|10 years ago|reply
[+] [-] kasey_junk|10 years ago|reply
The HTTP part is not a requirement either, as there are microservices that talk via application specific tcp protocols , udp, or if they are housed on the same machine memory mapped files.
[+] [-] misiti3780|10 years ago|reply
[+] [-] hactually|10 years ago|reply
[+] [-] jacksonnic|10 years ago|reply
I'm the author of this post and thanks for the feedback, just wanted to make a few comments...
1. Half baked Not sure I think this is a fair comment, it implies a lack of care, I do however think that work in progress is a fair assessment and actually I state this myself, the approach taken is an evolutionary one. With every use, identify improvements and make them so next time things are better. The more we share our learnings the faster the industry will advance and to many Microservices patterns are still a new approach, there are huge learnings to be had, some from personal experiences other from avoiding the failings of others. Just trying to share what I know in the hope it might help someone else.
2. Dependency Injection I was fairly confident this is a marmite (love or hate) approach with Go, there are some threads out there longer than the complete works of Shakespeare arguing if it is needed or not. For me it helps with decoupling when taking a test first approach and this is the main reason I choose to use it as a pattern. I have written services with and without DI, I definitely prefer with, I did say it was opinionated :)
3. Service Discovery, Failover, Storage, etc This is a huge topic in itself yet from people I speak to when discussing Microservices is something that often comes up. I personally hope that service discovery will be picked up at a Platform level by Mesosphere, Kubernetes or new PAAS providers like Docker Cloud or Google Container Service. At present I am using Consul, Consul Registrator, and HA Proxy but the bigger and more complicated the system the bigger this problem becomes and I am not 100% happy with things in this space. Storage is best avoided where possible, Docker certainly introduces problems with mutability, S3 is an option at the moment for shared storage but there are interesting things in the works with Docker Volumes. Event Sourcing is another huge area for Microservices, effectively decoupling them removes many of the problems around failover but this in itself huge complicated area. In general developing for failure is a good approach, deciding how things fail should be a cross functional requirement when discussing the features.
4. Feature Toggles Good call and in fact at my day job we use these extensively, in fact we could not deploy without them. At the moment this is not a problem I have had to tackle and therefore have not added this feature. I suspect this is something that will affect me in the future once I move from writing new services to changing and maintaining existing ones. Feature toggling in microservices opens up a completely new approach, do you toggle in the service code or with a different copy of the service itself and toggle within the service routing?
Really appreciate all the comments, I have certainly learned some stuff and I'm really looking forward to where the industry will head in the next 12 months.
Nic