單機(jī)程序中,可以通過語(yǔ)言級(jí)方法或函數(shù)實(shí)現(xiàn)調(diào)用。而在微服務(wù)中,應(yīng)用程序是部署在不用機(jī)器上的,每個(gè)服務(wù)實(shí)例都是一個(gè)進(jìn)程。因此服務(wù)之間的通信必須是進(jìn)程間的通信(IPC)。
交互風(fēng)格
客戶端和服務(wù)端交互方式可以在兩個(gè)維度考慮。
一個(gè)是一對(duì)一,一個(gè)是一對(duì)多
一個(gè)是同步/異步。
| 一到一 | 一個(gè)一對(duì)多 | |
|---|---|---|
| 同步 | 請(qǐng)求/響應(yīng) | - |
| 異步 | 通知 | 發(fā)布/訂閱 |
| 請(qǐng)求/異步響應(yīng) | 發(fā)布/異步響應(yīng) |
基于微服務(wù)的應(yīng)用程序,有的服務(wù)單個(gè)IPC就夠了,而有的可能需要多個(gè)組合。
同步
兩種比較流行的同步通信協(xié)議是REST和RPC。Spring Cloud Feign通信使用為REST。
比較流行的RPC框架:grpc ,Dubbo,Thrift。
異步
異步要求客戶端請(qǐng)求并不實(shí)時(shí)響應(yīng)。
當(dāng)一個(gè)請(qǐng)求過來,可能需要調(diào)用多個(gè)服務(wù),每個(gè)服務(wù)響應(yīng)時(shí)間都比較長(zhǎng),如果做成同步,可能響應(yīng)時(shí)間就過長(zhǎng)了。
這時(shí)候可能就要引入消息中間件了。
https://www.nginx.com/blog/building-microservices-inter-process-communication/ 更多信息
容錯(cuò)
在分布式系統(tǒng)中,存在部分失敗的風(fēng)險(xiǎn),由于客戶端和服務(wù)端是獨(dú)立部署的,因此服務(wù)可能無法及時(shí)響應(yīng)客戶端的請(qǐng)求。由于故障或維護(hù),服務(wù)可能會(huì)停機(jī)。或者服務(wù)可能會(huì)超載并且對(duì)請(qǐng)求的響應(yīng)速度非常慢。
Netflix Hystrix 提供了一些策略模式,包括
1.超時(shí)
2.斷路器
3.提供回退
4.限制未完成請(qǐng)求的數(shù)量
feign 聲明式調(diào)用
Feign makes writing java http clients easier
內(nèi)置了負(fù)載均衡,封裝了Ribbon
默認(rèn)使用的是HttpURLCollection實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求的,還可以使用HTTPClient和OKhttp
SB2.0 后改為 openfeign
pom.xml
<!--feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
啟動(dòng)類application.java 中添加注解: @EnableFeignClients 開啟FeignClient功能
寫一個(gè)Client:
@FeignClient("consul-server")
@FeignClient("consul-server")
public interface RemoteService {
@RequestMapping(value = "api",method = RequestMethod.GET)
String api(@RequestParam("api")String api);
}
啟動(dòng)consul-server,consul-server01 ,調(diào)用 curl http://localhost:8503/api/ 會(huì)輪訓(xùn)調(diào)用從server和server01
TODO
負(fù)載均衡是怎么實(shí)現(xiàn)的?
Hystrix 熔斷器
分布式系統(tǒng)中服務(wù)與服務(wù)之間依賴錯(cuò)綜復(fù)雜,當(dāng)某個(gè)服務(wù)出現(xiàn)故障時(shí),會(huì)導(dǎo)致調(diào)用其服務(wù)的其他服務(wù)出現(xiàn)遠(yuǎn)程調(diào)度的線程阻塞。
這也意味著你要把處理錯(cuò)誤的代碼當(dāng)成正常功能的代碼來處理
Hystrix 是Netflix公司是通過隔離服務(wù)的訪問點(diǎn)阻止聯(lián)動(dòng)故障的,并提供了故障解決方案,從而提高了整個(gè)分布式系統(tǒng)的彈性。
Hystrix
- 提供快速失敗機(jī)制
- 提供回退 fallback 方案
- 使用熔斷機(jī)制,防止故障擴(kuò)散到其他服務(wù)
- 監(jiān)控組件 Hystrix Dashboard ,可以使用Turbine聚合監(jiān)控
SpringCloud Feign中Hystrix的使用
在 consul-client上 pom.xml 中添加
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
application.yml
feign:
hystrix:
enabled: true # 開啟Feign熔斷
修改Feign RemoteService接口,添加fallback 快速失敗回調(diào)類
@FeignClient(value = "consul-server",fallback = HystrixClientFallback.class)
@Component
public class HystrixClientFallback implements RemoteService{
@Override
public String api(String api) {
return "Hystrix fallback ...";
}
}
啟動(dòng) consul-server,consul-client ,訪問:http://localhost:8053/api/
停掉 consul-server 在訪問 得到 Hystrix fallback ...
使用tuibine 聚合監(jiān)控
Hystrix Dashboard 監(jiān)控服務(wù)的熔斷器情況時(shí),最多只有一個(gè)Hystrix Dashboard 主頁(yè),服務(wù)數(shù)量很多時(shí),很不方便。
tuibine 可以監(jiān)控多個(gè)Hystrix Dashboard主頁(yè),集中進(jìn)行監(jiān)控
我們使用的是consul作為注冊(cè)中心,而tuibine默認(rèn)是使用eureka作為注冊(cè)中心,不把eureka排除的話會(huì)報(bào)
Field registration in o.s.c.c.s.ServiceRegistryAutoConfiguration$ServiceRegistryEndpointConfiguration required a single bean, but 2 were found:
類似于這個(gè)https://github.com/spring-cloud/spring-cloud-netflix/issues/1973**
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
Application.java 啟動(dòng)類 添加注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrixDashboard
@EnableTurbine
@EnableHystrix
public class HystrixDashboardTurbineApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixDashboardTurbineApplication.class, args);
}
}
application.yml
server:
port: 8504
spring:
cloud:
consul:
discovery:
health-check-path: /actuator/health
health-check-interval: 10s
instance-id: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
service-name: ${spring.application.name}
host: localhost
port: 8500
application:
name: hystrix-turbine
# boot:
# admin:
# client:
# url: http://localhost:8700
# spring admin
#management:
# endpoints:
# web:
# exposure:
# include: "*"
# endpoint:
# health:
# show-details: ALWAYS
turbine:
aggregator:
cluster-config: default #需要監(jiān)控的服務(wù)集群名
app-config: consul-client #需要監(jiān)控的服務(wù)名
cluster-name-expression: new String('default')
# instanceUrlSuffix:
# default: actuator/hystrix.stream #key是clusterConfig集群的名字,value是hystrix監(jiān)控的后綴,springboot2.0為actuator/hystrix.stream
啟動(dòng)后訪問:
http://localhost:8504/hystrix
可以看到

填寫
http://localhost:8504/turbine.stream ,monitor,開始進(jìn)去可能沒有數(shù)據(jù)
http://localhost:8504/hystrix/monitor?stream=http%3A%2F%2Flocalhost%3A8504%2Fturbine.stream%20
只啟動(dòng)兩個(gè) client 端
java -jar target/consul-client-0.0.1-SNAPSHOT.jar --server.port=8503
java -jar target/consul-client-0.0.1-SNAPSHOT.jar --server.port=8505
訪問http://localhost:8505/api/ 或者 http://localhost:8503/api/ 都行,多訪問幾次
就會(huì)得到,其中右下角4代表失敗次數(shù),Hosts=2代表集群有2個(gè)應(yīng)用

github 地址:
https://github.com/dudy0127/spring-cloud