10 Common Microservice Pitfalls and How to Avoid Them

This article shares ten frequent microservice problems—from improper service splitting and distributed transaction failures to configuration chaos, logging fragmentation, database sharing, API incompatibility, CI bottlenecks, missing monitoring, and team collaboration issues—offering concrete solutions, best‑practice principles, and code examples to help engineers build robust, maintainable microservice systems.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
10 Common Microservice Pitfalls and How to Avoid Them

1. Wrong Splitting

Typical scenario: Splitting services by code package name.

Consequences:

Order query needs to call four services

Interface latency rises from 50 ms to 350 ms

Trace logs explode in volume

Correct approach: Split based on business capabilities.

Splitting principles:

Single responsibility (one service solves one problem)

Team autonomy (a two‑pizza team can deliver independently)

Data autonomy (service owns its database)

2. Distributed Transaction Issues

Bad example: Cross‑service database operations.

@Transactional
// local transaction ineffective
public void createOrder(OrderDTO dto) {
    // 1. order service writes DB
    orderService.save(dto);
    // 2. call stock service
    stockFeignClient.deduct(dto.getSkuId());
}

Consequences: Order created but stock not deducted → oversell.

Solution: Saga pattern + reliable events.

Code implementation:

@SagaStart
public void createOrder(OrderDTO dto) {
    Saga.with("freezeStock", () -> stockClient.freeze(dto))
        .with("saveOrder", () -> orderService.save(dto))
        .compensate("saveOrder", () -> orderService.delete(dto.getId()))
        .compensate("freezeStock", () -> stockClient.unfreeze(dto))
        .execute();
}

3. Cascading Failure (Avalanche)

Scenario: Service A → B → C, C timeout causes the whole chain to collapse.

Defense: Circuit breaker + fallback + timeout.

@FeignClient(name = "stock-service", configuration = FeignConfig.class, fallback = StockFallback.class)
public interface StockClient {
    @GetMapping("/deduct")
    @TimeLimiter(fallbackMethod = "defaultResult")
    CompletableFuture<Boolean> deduct(@RequestParam String skuId);
}
// circuitBreaker config
circuitBreaker:
  failureRateThreshold: 50
  waitDurationInOpenState: 10s
  slidingWindowSize: 20

4. Configuration Management Chaos

Anti‑pattern: Config files scattered across services.

├── user-service
│   ├── application-dev.yml
│   ├── application-prod.yml
├── order-service
│   ├── application-dev.yml
│   └── application-prod.yml

Consequences:

Changing log level requires redeploying many services

Production may accidentally use dev configuration

Correct solution: Centralized configuration center.

Key config example:

spring:
  cloud:
    nacos:
      config:
        server-addr: 192.168.1.10:8848
        file-extension: yaml
        shared-configs:
          - data-id: common.yaml # public config

5. Log Tracing Fragmentation

Problem: Logs from different services are not correlated.

[user-service] user query success userId=100
[order-service] order creation failed userId=100
[payment-service] payment timeout userId=100

Pain: Need to stitch three log systems to reconstruct the call chain.

Solution: Sleuth + Zipkin full‑trace.

Log format:

2023-08-20 14:30 [user-service,7a3b,9f2c] INFO User query
2023-08-20 14:30 [order-service,7a3b,d8e1] ERROR Order creation failed

7a3b is the global Trace ID; 9f2c/d8e1 are service IDs.

6. Database Splitting Issues

Wrong practice: Services share a database.

Consequences:

Order table lock blocks user registration

Cannot scale services independently

Correct design: Vertical database splitting.

Sharding strategy example:

// user ID modulo sharding
public String determineDatabase(Long userId) {
    int dbIndex = (int)(userId % 4);
    return "user_db_" + dbIndex;
}

7. API Compatibility Issues

Incident: Order service upgraded to v2 API without notifying the payment service.

Solution: Three‑version strategy.

/v1/createOrder (old)
/v2/createOrder (new)
/v3/createOrder (pre‑release)

Spring Cloud gray release example:

spring:
  cloud:
    gateway:
      routes:
        - id: order_v2
          uri: lb://order-service
          predicates:
            - Header=version,v2
          filters:
            - StripPrefix=1

8. Continuous Integration Bottlenecks

Typical problem: 120 services built independently cause pipeline congestion.

Optimization:

Layered builds

Parallel builds

// Jenkinsfile parallel stage
stage('Parallel Build') {
    parallel {
        stage('Service A') { steps { sh './build-serviceA.sh' } }
        stage('Service B') { steps { sh './build-serviceB.sh' } }
    }
}

9. Missing Monitoring

Painful lessons:

Disk filled for eight hours without detection

Database connection pool exhausted causing a site‑wide crash

Golden monitoring stack:

Key alert rules example:

rules:
- alert: HighErrorRate
  expr: sum(rate(http_server_requests_errors_total[5m])) > 0.5
  for: 2m
- alert: DBConnectionExhausted
  expr: db_connections_active > db_connections_max * 0.9
  for: 1m

10. Team Collaboration Issues

Reality: Different teams use different tech stacks and deployment methods.

User team – Java + MySQL – K8s

Order team – Go + Postgres – VM

Payment team – Node + Mongo – Serverless

Solution:

10.1 Unified Technical Conventions

RESTful API standards

Global error‑code definitions

Log format standards

Health‑check endpoint

/actuator/health

10.2 Shared Infrastructure

Conclusion

Microservices bring many challenges; only with solid practical experience can they be built well.

Three‑layer defense system and Ten commandments of microservices are summarized:

Service granularity should follow business capability, not code size

Use eventual consistency for cross‑service transactions

Configure circuit‑breaker thresholds

Centralize configuration management

Propagate full‑trace IDs across all services

Each service should own its database

API versions must remain compatible for at least two iterations

Adopt layered build pipelines

Achieve 100% coverage of core metric monitoring

Establish cross‑team technical conventions

Microservices are about reorganizing organizational relationships, not merely a technology upgrade.
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Distributed SystemsBackend ArchitectureMicroservicesservice design
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.