{"id":20285450,"url":"https://github.com/mramshaw/microservices","last_synced_at":"2026-02-02T04:03:35.365Z","repository":{"id":92905289,"uuid":"94124446","full_name":"mramshaw/Microservices","owner":"mramshaw","description":"Some thoughts on Microservices","archived":false,"fork":false,"pushed_at":"2018-09-30T14:11:28.000Z","size":16,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-06-13T11:07:38.768Z","etag":null,"topics":["architecture","ci","ci-cd","continuous-delivery","continuous-deployment","continuous-integration","conways-law","devops","devsecops","domain-driven-design","microservice","microservices","noops","soa","software-architecture","teams"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mramshaw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-12T17:49:51.000Z","updated_at":"2019-05-27T14:29:35.000Z","dependencies_parsed_at":"2023-04-29T00:55:10.944Z","dependency_job_id":null,"html_url":"https://github.com/mramshaw/Microservices","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mramshaw/Microservices","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mramshaw%2FMicroservices","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mramshaw%2FMicroservices/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mramshaw%2FMicroservices/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mramshaw%2FMicroservices/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mramshaw","download_url":"https://codeload.github.com/mramshaw/Microservices/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mramshaw%2FMicroservices/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29004695,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-02T01:32:03.847Z","status":"online","status_checked_at":"2026-02-02T02:00:07.448Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["architecture","ci","ci-cd","continuous-delivery","continuous-deployment","continuous-integration","conways-law","devops","devsecops","domain-driven-design","microservice","microservices","noops","soa","software-architecture","teams"],"created_at":"2024-11-14T14:26:45.593Z","updated_at":"2026-02-02T04:03:35.350Z","avatar_url":"https://github.com/mramshaw.png","language":null,"readme":"# Microservices\n\nSome thoughts on Microservices\n\n## Background\n\nIn the software world, the first gradual step towards microservices seems to be introducing __CI__\n(Continuous Integration). This is probably a software engineering _\"best practice\"_ aimed at catching\nbuild-breaking issues as early as possible (it's pretty much a rite of passage for newer team members\nto _\"break the build\"_ - any developer who commits a lot of code will probably break the build sooner\nor later).\n\nThe reason why this is a big deal is that any build-breaking issues delay the overall release - _EVERYONE_ is blocked until the build is fixed (which is why advance warning of these issues is so important - and also why Microservices are so critical for larger codebases {more on this further down}). Anyone who has ever worked at a start-up where funding depended on meeting release targets will know how critical it is to be able to release in a timely fashion.\n\nOnce __CI__ is nailed down, the next step is generally some form of automated\nintegration and/or security testing followed by __CD__ (Continuous Delivery or\nContinuous Deployment) - usually aimed towards a staging area (in the case of\nContinuous Delivery the actual roll-out to production probably will still happen\naccording to a release cycle at this point - generally because it requires full\ndocumentation, while in the case of Continuous Deployment the roll-out will be\nto production but possibly __feature-flagged__).\n\n[Continuous Deployment means what it says, in that code is continuously deployed\nto production. But perhaps Continuous Delivery might more correctly be called\nContinuously Deployable, in that it is not continuously deployed to production\n(generally this requires a human decision) ___but could be___.]\n\n## Contents\n\n- [The monolith](#the-monolith)\n- [Slicing and dicing](#slicing-and-dicing)\n- [Conway's Law](#conways-law)\n- [The rewards of Microservices](#the-rewards-of-microservices)\n- [DevOps](#devops)\n- [Release agility](#release-agility)\n- [Testing](#testing)\n- [Security Testing](#security-testing)\n\n## The monolith\n\nThe software is now what is known as a __monolith__ or __BBoM__ (Big Ball of Mud). Which is probably fine for smaller codebases or where the developers are well-integrated and experienced. Teams (if they exist at all at this point) are usually vertically-oriented around core competencies (web, front-end, middleware, database, back-end, etc). There are tactics and strategies for advancing to the next step (if needed).\n\nThe next step is essentially ___cross-cutting___ - meaning it may well involve some reorganization (sometimes called _\"The Inverse Conway Manoeuvre\"_) but will definitely introduce increased complexity. The usual approach is to pick a non-critical service to be used as a pilot project - and to tread very carefully. The terminology is helpful here - this is referred to as _\"__strangling out a microservice__\"_. Signs that this may be necessary are when a development team is too large for the codebase (i.e. developers start stepping all over each other's code changes) or else there is a desire to be able to release different parts of the codebase independently of each other (for example, different __Docker__ or __rkt__ images). The front (customer-facing) end generally changes a lot faster (for cosmetic reasons) than the back-end, which might be a viable reason for separating these into two deliverables. [The eventual goal is to partition the system a lot more finely than this, but this is just a broad example of how different functional areas mutate at different speeds.]\n\n_Coupling_ and _Cohesion_ are issues here - the acid test for a Microservice is that it can be released on its own. If a new Docker image requires another Docker image (or - worse - multiple Docker images) to also be released at the same time, this is an indication of tight coupling. While this is very probably a good start in terms of migrating to the cloud, the eventual goal should be to have independent microservices.\n\nThe reorganization (if it occurs at all) will generally be towards something like _product teams_ (perhaps with product managers) and may involve slicing up the vertically-oriented core competency teams into horizontally-oriented product teams (like Amazon's so-called _\"__two-pizza teams__\"_). The general guideline is that each team should control the entire pipeline from the software to the customer.\n\n## Slicing and dicing\n\nHow the slicing and dicing occurs is tricky. Eric Evans's ___Domain-Driven Design___\n(the so-called _\"Blue Book\"_; its subtitle is _\"Tackling Complexity in the Heart of Software\"_)\noffers some guidelines on where to draw the boundaries between these _\"bounded contexts\"_\n(which is one of the trickiest problems around).\n\nHere are some further thoughts from Eric Evans, discussing\n[Domain-Driven Design at 10 Years](http://www.se-radio.net/2015/05/se-radio-episode-226-eric-evans-on-domain-driven-design-at-10-years/):\n\n\u003e The bounded context is a concept which in more traditional architectures, there\n\u003e weren't very good ways to implement that concept - you know, to really establish\n\u003e the boundary - so it seems to me that microservices has delivered us a practical\n\u003e and popular way of defining - and sticking to - those boundaries. And that's a\n\u003e big deal. And the emphasis on, you know, the micro: someone once asked me, what's\n\u003e the difference between microservices and the old SOA services? And I said: Well,\n\u003e I think part of it is the micro. These services are ... smaller. That's just a\n\u003e convention, of course, but it's an important convention: The idea that a very\n\u003e small piece of software could be very isolated, and uh, you know, do a narrow\n\u003e thing.\n\nThe point is that the software should be partitioned based upon _business_ (rather\nthan _technical_) needs.\n\n## Conway's Law\n\n ___Conway's Law___ is worth a look at this point:\n\n    http://en.wikipedia.org/wiki/Conway%27s_law\n\nFor more on the implications of Conway's Law for software architecture as well as\nteam structure at Avvo, Spotify, Adobe, and Microsoft (and also the myth of the\n\"full-stack developer\"), the following podcast may be of interest:\n\n    http://www.se-radio.net/2018/07/se-radio-episode-331-kevin-goldsmith-on-architecture-and-organizational-design/\n\nOne conclusion of interest is that trying to subvert Conway's Law can give rise to\ndysfunctional organizations - where there is a clear software architecture, having\nan org chart that matches that structure can serve to clarify and delineate code\n(and bug) responsibilities.\n\n## The rewards of Microservices\n\nFor those who arrive at the Microservices stage, the business rewards are supposed\nto be huge; each microservice can be rapidly iterated (speed of iteration is often\ncited as a competitive business advantage) and each microservice can be independently\ntested (each _bounded context_ is also a _failure boundary_). Each microservice team\nis free to innovate, also to use whichever language or stack they feel best suits\ntheir needs (subject to management approval of course) and the overall communications\noverhead is reduced as each team has its own internal scope - so that communication\nis simply needed to coordinate teams. The disadvantages are that the 'core competency'\nteams may have been broken up and the release process may have gotten more difficult\n(scripting and automation are generally used extensively to mitigate this last issue).\n\nThe problem with microservices is that bugs generally show up at higher levels, which\ncan be problematic. So integration testing gets harder and more complicated\n(_bulkheads_ and _circuit-breakers_ may be of use here).\n\n## DevOps\n\n[Originally called NoOps (as in, no Operations) - which turned out to be wildly\n over-optimistic.]\n\nThe general \"fullstack\" Kool-aid is that developers should do their own testing\nand releasing:\n\n\u003e ___“You build it, you run it.”___ - Werner Vogels, Amazon CTO\n\nHowever, the issue of the increased complexity of integration testing of microservices\nmay well argue for the continued existence of QA/Testing/Security/Release teams. On the\nplus side, problems in production can be quickly rolled back small-scale; a more granular\nrelease means finer control over the actual components. This makes for a much more\n_\"__agile__\"_ experience.\n\n## Release agility\n\nThis new agility manifests in partial or rolling deployments such as _canary deployments_,\n_blue-green deployments_, _red-black deployments_, _A/B deployments_ and the like.\nThe key value of these is that performance impacts can be evaluated __in production__\nand - if necessary - tuned or rolled-back. [A traditional approach has been a phased\nregional deployment - which assumes that all regions have equivalent performance\ncharacteristics. As this is usually __not__ the case, being able to monitor trial\ndeployments of microservices represents an attractive proposition.]\n\nPartial or rolling deployments are really a feature of component-based services - and\nare not specific to microservices. But, as discussed earlier, microservices probably\nrepresent the desired end-goal of component-based services.\n\nContainerization technologies such as __Docker__ and __rkt__ are a huge boon for\ndeployments. Whereas the _deployment unit_ was previously only built when the product\nwas deemed 'ready to ship' (generally towards the end of the development cycle),\nthe fungible unit of containerization is the ___image___ - which is usually built\nby the developer. This image is passed along through subsequent stages, but as an\n__immutable unit__ it has usually been very heavily tested by deployment time.\nThis means ___deployment___ is no longer an afterthought of the development cycle,\nit is now an integral part - at every stage.\n\nOne particularly attractive feature of this approach is that it is possible to make\n__micro-releases__ - as in release individual changes (which could be either bug fixes\nor requested new features) instead of a bundle of them - making it much easier to\nevaluate impact. Obviously the smaller the change to production, the easier it is to\ndebug or diagnose. Conversely, larger change bundles may be much harder to evaluate\nor triage.\n\n## Testing\n\nIn terms of testing, there are two types of errors: ___Type I___ is when the change\nis not implemented correctly and ___Type II___ represents an unintended breakage - meaning\nthat something that wasn't supposed to be affected actually _was_ affected. Either\nof these errors may be a result of differences between the production and development\nenvironments so being able to test in production (as in a _canary deployment_) can\nobviously be helpful. Type I (which is usually less common) is normally caught by\n_unit testing_ (as in __TDD__ or Test-Driven Development) whereas Type II is normally\ncaught by _integration testing_ or _QA_ (Quality Assurance). Testing for Type II errors\nis also known as [Regression testing](http://en.wikipedia.org/wiki/Regression_testing)\nwhile testing for Type I errors is sometimes referred to as __Non-Regression testing__.\n\nThe general point is that all of these testing efforts are reduced by smaller deployments\n(it may be necessary to release deployments more frequently to compensate for their smaller\nsize and scope).\n\n## Security Testing\n\n[Sometimes called DevSecOps.]\n\nOne of the advantages of a continuous build or CI/CD pipeline is that security can\nbe added to this pipeline, both in terms of vulnerability scanning ([Snyk](http://snyk.io/))\nas well as application security tests (probably best built into the regular tests).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmramshaw%2Fmicroservices","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmramshaw%2Fmicroservices","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmramshaw%2Fmicroservices/lists"}