This slide deck addresses the importance of proper functional design for creating resilient distributed systems (not only, but also microservice-based systems).
It starts by explaining the pitfall that many developers fall into when getting started with resilience: Quite often the effects of the fundamentals, i.e., creating bulkheads and choosing the communication paradigm, on system robustness at runtime are heavily underrated. Instead, the pure technical measures like circuit breakers, backpressure, etc. are often overestimated.
Unfortunately, all technical measures will not help to create a robust system if the functional design leads to highly coupled services where the availability of one service functionally totally depends on the availability of another service. The same is true if you need to call many services that all need to be available to answer a client request.
To make it worse, most of the wide-spread design approaches like functional decomposition, DRY (don't repeat yourself), design for re-use or layered architecture exactly lead to those problems, i.e., they are not suitable for designing distributed systems.
This slide deck does not offer any silver bullets to solve the problem (and actually I believe there is no silver bullet), but at least a few guiding principles. Additionally, it shows how the choice of the communication paradigm influences the bulkhead design and this way creates more options to create a good service design that also supports resiliency on a functional level.
As always this slide deck is without the voice track, i.e., most of the information is missing. But I hope that the slides on their own also provide some helpful hints.
Remark: As the "dismiss reusability" slide tends to get quite some attention, one more remark about that slide: On the voice track I usually add "If you find something that is worth being made reusable, i.e., that it satisfies the commercial constraints of Fred Brooks 'Rule of 9' (see https://blog.codecentric.de/en/2015/10/the-broken-promise-of-re-use/ for details), do not put it in a service. Instead create a library and put the functionality in there. And make sure that changes to the library do not mean that all users have to upgrade at the same time, but that any library user can update whenever it fits the user's schedule. Otherwise, you would have introduced tight coupling through the back door again."