Here are some examples:
1. A chat service (race conditions, synchronization issues between the game server and chat service that had to be debugged using sequence diagrams)
2. A payment service that handled Facebook, PayPal, and other payment methods. (race conditions, complicated integration, difficulty upgrading for different products, complicated code base to handle multiple use cases)
3. An authentication service (complicated protocol, hard to integrate)
4. A worker service for handling bcrypt (because blocking a single threaded server for 0.5 seconds is not acceptable, race conditions)
5. A tracking service (could have probably just been a library you included instead of hitting an API)
Core issues:
- Race conditions
- Synchronization issues
- Complicated to upgrade/maintain for multiple products
- Become too generic and solve multiple problems (services tend to be used for multiple products in the company)
- Extremely difficult to debug
- Complicated error handling for when a service is not reachable
pro-tip: don't share databases between multiple products for each service, deploy a new service for every product with its own database.
I think I'm scratching the surface here, but I would be really careful with introducing this kind of architecture when you can do it all in one server.