How to communicate microservices
- @FeignClient (ApiClient)
- Kafka (Use Event)
- RestTemplate (communicate with REST API)
- Circuit Breaker (Fault Tolerant Design Pattern)
Spring Cloud
a framework for building robust cloud(strong and healthy) applications. (= microservices)
Spring Cloud Stream
A lightweight event-driven microservices framework to quickly build applications that can connect to external systems. Simple declarative model to send and receive messages using Apache Kafka(middleware) or RabbitMQ between Spring Boot apps.
@FeignClient
- Microservices communication method in Spring Boot
- @EnableFeignClients
user-service
build.gradle
1
2
3
dependencies {
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-openfeign', version: '2.1.1.RELEASE'
}
user-service
1
2
3
4
@EnableFeignClients
public class ApiClientConfiguration {
...
}
departments-service
1
2
3
4
5
6
7
8
@FeignClient(name = "user", contextId = "userEnvironmentSetting", url = "${...}")
@RequestMapping(path="/users", consumes = "application/json")
interface UserEnvironmentSettingClient {
@Override
@GetMapping("/users/environmentSetting")
Map<String, String> getEnvironmentSetting();
}
- name : LoadBalancer client name
- contextId : bean name instead of name if present
- issue : λμΌ name μΌλ‘ λκ°μ class μμ μ§μ νλ©΄ μ€λ₯ λ°μ
- reference: https://techblog.woowahan.com/2630/
RestTemplate
- Spring Http communication template (Rest API μλΉμ€λ₯Ό μμ² ν μλ΅λ°μ λ μ£Όλ‘ μ¬μ©)
- For communiating over the microservices
- Synchronize (Async : org.springframework.web.client.AsyncRestTemplate)
- will be deprecated
build.gradle
1
implementation 'org.springframework.boot:spring-boot-starter-web'
RestTemplate VS WebCLient
| Β | RestTemplate | WebCLient |
|---|---|---|
| Β | Sync | Async (= AsyncRestTemplate) |
| Dependency | implementation βorg.springframework.boot:spring-boot-starter-webβ | implementation βorg.springframework.boot:spring-boot-starter-webfluxβ |
- reference
https://backtony.github.io/spring/2021-07-12-spring-basic-8/
https://blog.naver.com/hj_kim97/222295259904
https://sjh836.tistory.com/141
Blocking VS Non-Blocking VS Sync VS Async
- Blocking / Non-blocking
- λ€λ₯Έ μ£Όμ²΄κ° μμ ν λ μμ μκ² μμ μ μμ μ λν μ μ΄κΆμ΄ μλμ§ μλμ§
| Β | Blocking | Non-blocking |
|---|---|---|
| Β | νΈμΆλ ν¨μκ° μμ μ μμ
μ λͺ¨λ λ§μΉ λκΉμ§ νΈμΆν ν¨μμκ² μ μ΄κΆμ λκ²¨μ£Όμ§ μκ³ λκΈ°νκ² λ§λ λ€λ©΄ (executes βin seriesβ) | νΈμΆλ ν¨μκ° λ°λ‘ 리ν΄ν΄μ νΈμΆν ν¨μμκ² μ μ΄κΆμ λκ²¨μ£Όκ³ , νΈμΆν ν¨μκ° λ€λ₯Έ μΌμ ν μ μλ κΈ°νλ₯Ό μ€ μ μμΌλ©΄ (executes in parallel) |
| Example | μ§μμ΄ μμ¬μκ² μλ₯λ₯Ό μ μΆνκ³ , μμ¬κ° μλ₯λ₯Ό λ€ μ½μ λκΉμ§ μ리μμ κΈ°λ€λ¦¬λ μν© | μ§μμ΄ μμ¬μκ² μλ₯λ₯Ό μ μΆνμ§λ§, μμ¬κ° μλ₯λ₯Ό λ€ μ½μ΄λ³Ό λμ μ리μ κ°μ μμ μ μΌμ μ²λ¦¬νλ μν© |
- Sync / Async
- κ·Έκ²μ μμ²ν μμκ° μ§μΌμ§λκ° μλκ° (νΈμΆλλ ν¨μμ μμ μλ£ μ¬λΆλ₯Ό λκ° μ κ²½μ°λ)
| Β | Synchronous | Asynchronous |
|---|---|---|
| Β | μμ
μ λμμ μννκ±°λ, λμμ λλκ±°λ, λλλ λμμ μμν¨ (κ²°κ³Όλ₯Ό 리ν΄λ°μμ λ λ°λ‘ κ·Έ κ²°κ³Όμ μ§μ€ν¨ / scheduled, real-time) | μμ, μ’
λ£κ° μΌμΉνμ§ μμΌλ©° λλλ λμμ μμμ νμ§ μμ (κ²°κ³Όλ₯Ό λ°λ‘ μ²λ¦¬νμ§ μμλ λ¨ / on your own time, no need schedule / use callback) |
| Β | When a work is requested, the result value of the request is directly returned. | When a work is requested, the result value of the request is indirectly received |
| Β | μμ²μ λ³΄λΈ ν μλ΅μ λ°μμΌμ§λ§ λ€μ λμμ΄ μ΄λ£¨μ΄μ§ | μΉ νμ΄μ§ μ 체λ₯Ό μλ‘κ³ μΉ¨ νμ§μκ³ λ°μ΄ν°λ₯Ό λΆλ¬μ€λ λ°©μ |
| Β | λΉλκΈ° λ°©μμ λΉν΄ μ€κ³κ° λ§€μ° κ°λ¨νκ³ μ§κ΄μ μ΄μ§λ§ κ²°κ³Όκ° μ£Όμ΄μ§ λ κΉμ§ μ무 κ²λ λͺ»νκ³ λκΈ°ν΄μΌν¨ | λΉλκΈ° λ°©μμ μ΄μ©ν κ²½μ°, νμν λΆλΆμ λ°μ΄ν°λ§ λΆλ¬μ μ¬μ© κ°λ₯. κ²°κ³Όκ° μ£Όμ΄μ§λλ° μκ°μ΄ 걸리λλΌλ κ·Έ μκ°λμ λ€λ₯Έ μμ μ ν μ μμΌλ―λ‘ μμμ ν¨μ¨μ μ¬μ© κ°λ₯ |
| Example | μμ¬κ° μλ₯λ₯Ό λ€ μ½κ³ κ²°κ³Όλ₯Ό 리ν΄ν΄μ£Όλ©΄ μ§μμ λ°λ‘ κ·Έ κ²°κ³Όμ κ΄μ¬μ κ°κ² λ©λλ€. | μμ¬κ° 리ν΄ν κ²°κ³Όλ₯Ό λ°λ‘ μ²λ¦¬ν μ§, λμ€μ μ²λ¦¬ν μ§λ₯Ό κ²°μ ν μ μμ΅λλ€. |
common used : sync-blocking, sync-nonblocking, async-nonblocking (most efficient)
![img (1)]()
reference
https://studyandwrite.tistory.com/486
https://baek-kim-dev.site/38
CircuitBreaker (Design pattern using netfilx hystrix)
- Hystrix
- library form Netflix (spring-cloud-starter-netflix), isolates the points of access between the services, stops cascading failures across thhem and provides the fallback options
- Fallback
- provides an alternative solution during a service request failure
- Circuit Breaker Pattern
- prevents failure cascading and gives a default behavior when services fail
- Netflix Hystrix
- allows us to introduce fault tolerance and latency tolerance by isolating failure and by preventing them from cascading into the other part of the system building a more robust distributed application.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Service
public class GreetingService {
@HystrixCommand(fallbackMethod = "defaultGreeting")
public String getGreeting(String username) {
return new RestTemplate()
.getForObject("http://localhost:9090/greeting/{username}",
String.class, username);
}
private String defaultGreeting(String username) {
return "Hello User!";
}
}
- @EnableCircuitBreaker
- will scan the classpath for any compatible Circuit Breaker implementation.
1
2
3
4
5
6
7
@SpringBootApplication
@EnableCircuitBreaker
public class RestConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(RestConsumerApplication.class, args);
}
}
Hystrix VS Resilience4J
- common feature : fault tolerant library
| Hystrix | Resilience4J |
|---|---|
| embraces an Object-Oriented design where calls to external systems have to be wrapped in a HystrixCommand offering multiple functionalities. | relies on function composition to let you stack the specific decorators you need. |

- reference
https://engineering.linecorp.com/ko/blog/circuit-breakers-for-distributed-services/
https://www.baeldung.com/spring-cloud-netflix-hystrix
https://digitalvarys.com/what-is-circuit-breaker-design-pattern/
API Gateway (Load balancing)
Service : Cloud-gateway
spring-cloud-starter-gateway
bulid.gradle
1
2
3
dependencies {
compile 'org.springframework.cloud:spring-cloud-starter-gateway:2.1.0.RELEASE'
}
application.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server:
port: 9191
spring:
cloud:
gateway:
routes:
- id: USER-SERVICE
url: ${cloud-gateway.user-url}
predicates:
- Path=/users/ **
- id: DEPARTMENT-SERVICE
url: ${cloud-gateway.department-url}
predicates:
- Path=/departments/ **
filter:
- name: CircuitBreaker
args:
name: USER-SERVICE
fallbackuri: forward:/userServiceFallBack
cloud-gateway:
user-url: http://cloud-user-service:9001
department-url: http://cloud-department-service:9002
Meaning:
when you call http://localhost:9191/users/1, it goes to http://localhost:9001/users/1
when you call http://localhost:9191/departments/1, it goes to http://localhost:9002/departments/1
reference : https://cloud.spring.io/spring-cloud-gateway/reference/html/#configuration
Spring-boot-starter-actuator
bulid.gradle
1
2
3
dependencies {Β
compile("org.springframework.boot:spring-boot-starter-actuator")
}
application.yml
From spring boot 2.x, you have to custom management part in application.yml because the default setting is not exposing most datas.
1
2
3
4
5
management:
endpoints:
web:
exposure:
include: health
Meaning : expose the health information
1
2
3
4
5
management:
endpoints:
web:
exposure:
exclude: env, beans
Meaning : expose the information except for env, beans
the property exclude is prior than include, so if you declared some information on exclude, you canβt see it even if you declared that on include.
- reference : https://jeong-pro.tistory.com/160
Spring Cloud Stream
- μ΄λ²€νΈ μ€μ¬ microservcieλ₯Ό ꡬμΆνκΈ° μν νλ μμν¬
- Apache Kafka λλ RabbitMQ λ±μ μ¬μ©νμ¬ Spring Boot μ΄ν리μΌμ΄μ κ³Ό λ©μΈμ§λ₯Ό 보λ΄κ³ λ°μ.
https://saramin.github.io/2019-08-28-2/

Comments powered by Disqus.