4 ms·
A few questions: a) How do you prevent technical debt? It seems to be more difficult due to APIs which shouldn't have breaking changes. In theory you could alw
by nawitus 12y ago
A few questions:
a) How do you prevent technical debt? It seems to be more difficult due to APIs which shouldn't have breaking changes. In theory you could always version up the APIs and serve both versions or just add a new API for a breaking change, but these solutions seems awkward.
b) How do you start developing multiple microservices at the same time? I would expect APIs to change a lot in the beginning, which would mean that updating one microservice would break another. Perhaps that is acceptable before the first "stable release" of a microservice.
- bigdubs 12y agoHonestly, I've been following along with these trends a lot and it seems like the answers for 1&2 come down to team size. If you have a bigger team, with more development inertia microservices can seem amazing and the tradeoffs are worth it (repeated work vs. development tempo). To a small team that doesn't have the inertial issues to generate the benefits of microservices, it seems like they are nice in theory but have too much overhead to supplant monolithic approaches.
- jacques_chester 12y ago> How do you start developing multiple microservices at the same time? Same as any other project: Develop from the outside in. In practice, trying to develop in the "optimal order' leads to speculative development that will be wasted.
- HeyLaughingBoy 12y agoI really wish the team I'm on could understand this!
- mercurial 12y agoNothing prevents you from having multiple microservices sharing the same codebase. That said, the "it's just like the web" model doesn't sound fantastic to me. It sounds like your app now depends on contracts which are only enforced by good practices, not by something strongly typed you can check at compile time, unless you use something like protocol buffers to generate the boilerplate.
- jacques_chester 12y agoThis is where the test-driven world, which in my experience is strongest on the dynamic language side of programming, has come back around full circle. In microservices, everything is dynamically typed. There is no single binary produced by a single compiler performing whole-program checks of consistency. Even tools like protobufs don't help when code bases drift, or someone introduces a foreign tool, or someone upgrades versions and introduces a subtle mismatch, or some doesn't know you call their service and shuts it down ... Turns out that driving from tests, and starting those tests from the outermost consumer, is a fairly well-proved way of coping with such conditions.
- nawitus 12y agoThis reminded me of the AngularJS team deciding to go with (optional) runtime type checking over compile-time checking (which is what TypeScript has done to JavaScript). Their reasoning was that you can use runtime checking for REST responses, which can be argued to somewhat reduce the need for writing tests.
- mercurial 12y ago> There is no single binary produced by a single compiler performing whole-program checks of consistency. Even tools like protobufs don't help when code bases drift, or someone introduces a foreign tool, or someone upgrades versions and introduces a subtle mismatch, or some doesn't know you call their service and shuts it down ... Static typing is not a panacea, but large codebase plus dynamic typing everywhere sounds like a recipe for disaster. No matter the amount of testing. > Turns out that driving from tests, and starting those tests from the outermost consumer, is a fairly well-proved way of coping with such conditions. You need tests no matter what. However, static typing means a much greater confidence in your codebase.
- jacques_chester 12y agoAs soon as you distribute your system, you have dynamic typing, whether you like it or not. At runtime you are inspecting incoming messages and then routing them to code. It doesn't matter what language the code is written in, it will need to route and validate the messages at runtime. The type system cannot provide compile-time assurances of behaviour, because it cannot create a single consistent binary which enforces the guarantees. Your only remaining tool is to drive code from tests and only from tests.
- vzaneric 12y agohttp://en.wikipedia.org/wiki/Outside%E2%80%93in_software_development http://en.wikipedia.org/wiki/Outside%E2%80%93in_software_dev...
- danudey 12y agoThis is basically it. Designing a game? Build the Game service, with all your game logic. Need users and authentication now? Start writing an Identity service, and so on. The only difference is that instead of starting to write some Identity class and use it in your Game service, you write some Identity class and expose it via a REST API, and then provide an interface library that interfaces with that REST API. Call it IdentityInterface or libidentity or something. Pydentity, whatever. It makes an HTTP request, gets a serialized object, unserializes it, and returns it. For simplicity, put all your public models in that library, and it gets shared by both the Identity service and the Game service. Those models represent an object and what you can do with it. In the Identity service is where all of that actually happens. This is also how you solve the 'multiple microservices at the same time' problem; your interface library provides the public interface, and the backend REST API is the 'private' API used by the public interface. You make changes to the backend API and the public library and no one notices, or you make incompatible changes to the public service and fix everything before you deploy; ideally, you add new APIs, migrate services over, then deprecate the old ones. In the end, each service sees the world as fundamentally the same; there's a library with classes and functionality, and you use that to do things. If you design it right, it's never obvious from your code that you're accessing a different service elsewhere in your infrastructure.
- jacques_chester 12y agoThe problem is that microservices are not objects. They leak reality into your problem domain in a way that simply cannot be made to go away. If regular object oriented programming languages had method calls that randomly failed, were delayed, sent multiple copies of a response, changed how they behaved without warning, sent half-formed responses ... then yes it would be the same. Distributed systems are hard, because you cannot change things in two places simultaneously. All synchronisation is limited by the bits you can push down a channel up to, but not exceeding, the speed of light. In a single computer system this problem can be hidden from the programmer. In a distributed system, it cannot. Probably the most devastating critique of the position that "it's just OO modeling!" came in A Note on Distributed Computing, published in 1994 by Waldo, Wyant, Wollrath and Kendall[0]: "We look at a number of distributed systems that have attempted to paper over the distinction between local and remote objects, and show that such systems fail to support basic requirements of robustness and reliability. These failures have been masked in the past by the small size of the distributed systems that have been built. In the enterprise-wide distributed systems foreseen in the near future, however, such a masking will be impossible." [0] http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.7628 http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.7...