About the topic:
Wix transitioned from monolith to microservices around 8 years ago. Or did it? We have hundreds of microservices in production with teams working on separate independent services or groups of services with decoupled deployments and SLAs. Sounds like a microservice architecture, but there is a dark truth to it – single platform (jvm), shared libraries (framework), fat clients (binary dependencies). In industry it is called a distributed monolith. There is no easy way or incentive to get rid of it. But there is a way!
Let me tell you a story on how much fun it was, what path we took and where we are now with getting to a proper polyglot microservice architecture.
John About Vilius:
Guild Master @ Wix with experience in different roles and companies (enterprise, start-up, you name it). No matter how much life/circumstances are pushing me to lead/management roles, I always find ways to come back and keep on hacking.
Twitter: https://twitter.com/viliusl
GitHub: https://github.com/viliusl
5. AGENDA
Microservices and Distributed Monolith
(DM)
Why am I talking about DM in first place?
Short history and joys of adding 2nd stack
Decomposing Distributed Monolith
6. “Microservice architectural style is an
approach to developing a single
application as a suite of small services,
each running in its own process and
communicating with lightweight
mechanisms, often an HTTP resource
API”
Martin Fowler
25. “Target or this project is to enable
coding front-end servers in Wix using
Node.js. We are aiming at the
pattern of front-end servers and
service-servers – a pattern that is
used in different companies”
Yoav Abrahami
47. // todo - talk to Vilius about that
var url = req => req.protocol + '://' + req.get('host') + req.originalUrl;
// todo - add petri enricher
return new WixRpcClientSupport(
reqContext.get(wixRequestContext),
rpcSigner.get(options.rpcSigningKey),
wixSessionEnricher.get(wixSession),
biEnricher.get(wixBi)
);
module.exports.addTo = app => {
app.get('/health/is_alive', (req, res) => res.send('Alive'));
};
Some TODOs
55. "health monitoring - protocol" >> {
"/health/is_alive responds with failure" >> {
healthTestDependency.becomeUnavailable()
eventually {
queryIsAliveAPI must beUnavailable
}
}
"/health/is_alive responds with success" >> {
healthTestDependency.becomeAvailable()
eventually {
queryIsAliveAPI must beSuccessfulWith("Alive")
}
}
"health tests executed with three retries" >> {
stabilizeInHealthyState()
healthTestDependency.becomeFlaky(consecutiveFailures = 1)
holds(samples = 100, sleep = 50.milliseconds) {
queryIsAliveAPI must beSuccessful
}
}
Generic tests
Using testkits;
Platform-agnostic.
56. class NodeComplianceE2E extends BaseComplianceE2E
with HealthAll
with SecurityAll
with I18nAll
with PetriAll
with BiAll
with WebAll
with NodeMetricKeys
with NodeBiKeys
with RpcAll {
LogbackTestHelper.initLogger()
override protected def systemUnderTest: MainService =
new LocalNodeService
}
Easy to add another
stack
App with exposed
APIs
Adapters
Runner
64. “can I actually take a team of
engineers who are interested in X
becoming a legit thing in my service
and actually build something without
convincing the rest of the company?”
Ben Christensen,
Facebook
Node.js is just a coincidence, there is nothing Node.js specific really – but first things first.
Vilius from Vilnius;
Backend engineer, 3 years with wix, currently working on Node.js @ wix.
If you haven’t been to Vilnius – find a reason and come over – adding extra office space, nice town
Vilius from Vilnius;
Backend engineer, 3 years with wix, currently working on Node.js @ wix, feel like fullstack or nostack
If you haven’t been to Vilnius – find a reason and come over – adding extra office space, nice town
These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.
We do microservice architecture in wix – at least we have many traits of it
Important part is required
- Service logic drifts to client (performance considerations, optimizations, etc.);
- Service api becomes opaque – no other way to consume a service but via official library;
- You have to decide what to do with those 10s of clients that are sitting in your codebase;
- transitive dependencies, coupling to frameworks….
- example – different threading model for a different SLA - maybe more concrete example (petri, cassandra);
- technical decisions of service provider leaks into my service;
Nearly impossible - hard, not feasible?
And this is not smth you should prioritze in microservices architecture
represents lost benefits of microservice architecture - we are paying the costs of distributed system without getting the benefits:
polyglot - core technologies where a broad of engineers are familiar with; different languages/platforms serve different goals/problems;
organizational/technical decoupling - teams can evolve technically without coupled collbaroation between them;
temporal decoupling - can an individual team upgrade their networking - EXAMPLE?
can we upgrade to newer version of 'guava'?
It’s how internet is built!
- Consume with any language and technology;
- Iterate and change over time;
- No dependency on service implementation;
You don’t need official libraries for that
Standartization… - you can choose to use or reimplement;
Compliancy/contract… - automated tools to verify you compliance/gatekeeper to production.
jackson
- disregarding that engineers doing that are not really bright
- And this is what I'm gonna concentrate on
- It started 2 years ago;
- still ongoing;
given a pre-node-js state, where all stack was composed of single platform
the change would be to swap public-facing part with Node.js
It’s how internet is built!
- Consume with any language and technology;
- Iterate and change over time;
- No dependency on service implementation;
don't think we would do it in multiple platforms now
You don’t need official libraries for that
- HTTP API’s, JSON-RPC2
- obeying to json datatypes, little jvm leakage.
For next stack could be introduced in less than a year - maybe our platform, business requirements will change in a way, where go will be the right tool for the job in many new endevours.