To recap, when building microservices, you are essentially swapping out JVM method calls with synchronous HTTP calls or asynchronous messaging .

Whereas a method call execution is basically guaranteed (with the exception of your JVM exiting abruptly), a network call is, by default, unreliable.

It could work, it could also not work for various reasons: From the network being down or congested, to a new firewall rule being implemented to your message broker exploding.

To see what implications that has, let’s have a look at an exemplary BillingService example.

HTTP/REST Resilience Patterns

Say customers can buy e-books on your companies' website. For that, you just implemented a billing microservice, that your webshop can call to generate the actual PDF invoices.

For now, we’ll do that call synchronously, via HTTP. (It would make more sense to call that service asynchronously, because PDF generation doesn’t have to be instant from a user’s perspective. But we want to re-use this very example in the next section and see the differences.)

@Service class BillingService { @Autowired private HttpClient client; public void bill(User user, Plan plan) { Invoice invoice = createInvoice(user, plan); httpClient.send(invoiceRequest(user.getEmail(), invoice), responseHandler()); } }

Think about what kind of possible results that HTTP call could have. To generalize, you will end up with three possible results:

OK: The call went through and the invoice got created successfully. DELAYED: The call went through but took an unusually long amount of time to do so. ERROR: The call did not go through, maybe because you sent an incompatible request, or the system was down.

Handling errors, not just the happy-cases, is expected for any program. It is the same for microservices, even though you have to take extra care to keep all of your deployed API versions compatible, as soon as you start with individual microservice deployments and releases.

And if you want to go full-on chaos-monkey, you will also have to live with the possibility that your servers just get nuked during request processing and you might want the request to get re-routed to another, working instance.

An interesting 'warning' case is the delayed case. Maybe the responding’s microservice hard-disk is running full and instead of 50ms, it takes 10 seconds to respond. This can get even more interesting when you are experiencing a certain load, so that the unresponsiveness of your BillingService starts cascading through your system. Think of a slow kitchen slowly starting the block all the waiters of a restaurant.

This section obviously cannot give in-depth coverage on the microservice resilience topic, but serves as a reminder for developers that this is something to actually tackle and not ignore until your first release (which from experience, happens more often than it should)