SpringBoot Cloud是什麼
Spring Cloud是一個分布式的整體解決方案。 Spring Cloud 為開發者提供了在
分布式系統(配置管理,服務發現,熔斷,路由,微代理,控制總線,一次性token,全局瑣, leader選舉,分布式session,叢集狀态)中快速建構的工具,
使用Spring Cloud的開發者可以快速的啟動服務或建構應用、同時能夠快速和雲平台資源進行對接。
SpringCloud分布式開發五大常用元件
• 服務發現——Netflix Eureka (發現了 英 [,jʊ(ə)'riːkə] )
• 客服端負載均衡——Netflix Ribbon (緞帶 英 ['rɪbən] )
• 斷路器——Netflix Hystrix (斷路器)
• 服務網關——Netflix Zuul (路由網關)
• 分布式配置——Spring Cloud Config (配置)

https://www.processon.com/diagraming/5cef1a48e4b05d5b38bdb090
特别強調: springboot和springcloud如果版本不相容會報異常java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder.<init>([Ljava/lang/Class;)V
springcloud中eureka搭建
建一個空項目springboot-07-cloud,内有三個子子產品
- eureka-server (注冊中心)
- cloud-provider (服務提供者)
- cloud-consumer (消費者)
三個子子產品檔案結構如下
springboot-07-cloud base分支中三個子子產品如下
springboot-07-cloud中三個子子產品 | eureka-server (注冊中心) | cloud-provider (服務提供者) | cloud-consumer (消費者) |
pom.xml差別 | | | |
application.yml差別 | 預設eureka服務注冊中心也會将自己作為用戶端來嘗試注冊它自己,是以我們需要禁用它的用戶端注冊行為,将register-with-eureka置為false 若未禁用eureka服務注冊中心的用戶端注冊行為,需提供service-url注冊中心位址 | | |
特别注意: springboot和springcloud的版本有對應要求, 本樣例用的是
springboot <version>1.5.21.RELEASE</version> 對應 springbloud <spring-cloud.version>Edgware.SR6</spring-cloud.version>
在實際開發過程中,我們需要更詳細的版本對應:以倫敦地鐵站命名
spring-boot-starter-parent | spring-cloud-dependencies | ||||
---|---|---|---|---|---|
版本号 | 釋出日期 | 版本号 | 釋出日期 | ||
1.5.2.RELEASE | 2017年3月 | 穩定版 | Dalston.RC1 | 2017年未知月 | |
1.5.9.RELEASE | 2017年11月 | 穩定版 | Edgware.RELEASE | 2017年11月 | 穩定版 |
1.5.16.RELEASE | Edgware.SR5 | ||||
1.5.20.RELEASE | Edgware.SR5 | ||||
2.0.2.RELEASE | 2018年5月 | Finchley.BUILD-SNAPSHOT | 2018年未知月 | ||
2.0.6.RELEASE | Finchley.SR2 | ||||
2.1.4.RELEASE | Greenwich.SR1 | ||||
2.2.2.RELEASE | Hoxton.SR1 | 2019年 | |||
待更新... |
eureka-server (注冊中心)
EurekaServerApplication.java
注冊中心啟動入口 , 注意需要@EnableEurekaServer注解支援
package com.example.eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* 使用注冊中心步驟
* 1. application.yml配置
* 2. @EnableEurekaServer注解添加
*/
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
cloud-provider (服務提供者)
CloudProviderApplication.java
生産者啟動類, 不需要額外注解, 因為做了注冊到eureka上的配置, 就可以直接把@RestController注解的所有接口自動注冊到eureka注冊中心 , 供消費者調用.
package com.example.cloud.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CloudProviderApplication {
public static void main(String[] args) {
SpringApplication.run(CloudProviderApplication.class, args);
}
}
CloudProviderController.java
package com.example.cloud.provider.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CloudProviderController {
static int number;
@GetMapping("/buyTicket")
public String buyTicker(){
return "ticker "+ ++number;
}
}
cloud-consumer (消費者)
CloudConsumerApplication.java
消費者啟動入口 , 注意需要開啟@EnableDiscoveryClient注解
package com.example.cloud.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* cloud 用戶端調用時需要引入 @EnableDiscoveryClient 注解
*/
@SpringBootApplication
@EnableDiscoveryClient
public class CloudConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(CloudConsumerApplication.class, args);
}
}
MyConfiguration.java
需要把RestTemplate類組裝到springboot容器中, 專門用于調用eureka上發現的服務
package com.example.cloud.consumer.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class MyConfiguration {
@LoadBalanced//負載均衡
@Bean//需要把RestTemplate裝配進來,專門用于調用Eureka上發現的服務
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
CloudConsumberController.java
使用 http://localhost:8002/buyTicket 通路
package com.example.cloud.consumer.controller;
import com.netflix.discovery.converters.Auto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class CloudConsumberController {
@Autowired
RestTemplate restTemplate;
//http://localhost:8002/buyTicket
@GetMapping("/buyTicket")
public String buyTicker(){
String retData = restTemplate.getForObject("http://PROVIDER/buyTicket",String.class);//
retData = "成功購買" + retData;
return retData;
}
}
通路
通路springcloud的eureka-server 注冊中心 http://localhost:8761/
通路cloud-consumer消費者提供的controller接口 http://localhost:8002/buyTicket 後,浏覽器顯示如下
成功購買ticker 1
注意Status一欄顯示的是服務執行個體名, 預設取名規則為${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}} , 最後的寫法意為如果spring.application.instance_id沒有定義,則取server.port, 如果已定義了則舍掉server.port取spring.application.instance_id
遇見異常
Error creating bean with name 'gsonBuilder' defined in class path resource
異常詳情如下:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gsonBuilder' defined in class path resource [org/springframework/boot/autoconfigure/gson/GsonAutoConfiguration.class]:Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.google.gson.GsonBuilder]: Factory method 'gsonBuilder' threw exception; nested exception is java.lang.BootstrapMethodError: java.lang.NoSuchMethodError: com.google.gson.GsonBuilder.setLenient()Lcom/google/gson/GsonBuilder
那是因為整個項目沒有引入parent依賴 , 添加如下<parent>即可
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
Eureka服務心跳檢測(健康檢測機制)
1.Eureka服務端
在某一些時候注冊在Eureka的服務已經挂掉了,但是服務卻還留在Eureka的服務清單的情況。
Eureka服務端的配置application.yml:
server:
port: 9501
eureka:
instance:
hostname: 127.0.0.1
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server:
# 關閉自我保護機制
enable-self-preservation: false
# 每隔10s掃描服務清單,移除失效服務
eviction-interval-timer-in-ms: 10000
預設情況下,如果Eureka Server在一定時間内(預設90秒)沒有接收到某個微服務執行個體的心跳,Eureka Server将會移除該執行個體。但是當網絡分區故障發生時,微服務與Eureka Server之間無法正常通信,而微服務本身是正常運作的,此時不應該移除這個微服務,是以引入了自我保護機制。
自我保護模式正是一種針對網絡異常波動的安全保護措施,使用自我保護模式能使Eureka叢集更加的健壯、穩定的運作。
自我保護機制的工作機制是如果在15分鐘内超過85%的用戶端節點都沒有正常的心跳,那麼Eureka就認為用戶端與注冊中心出現了網絡故障,Eureka Server自動進入自我保護機制,此時會出現以下幾種情況:
1、Eureka Server不再從注冊清單中移除因為長時間沒收到心跳而應該過期的服務。
2、Eureka Server仍然能夠接受新服務的注冊和查詢請求,但是不會被同步到其它節點上,保證目前節點依然可用。
3、當網絡穩定時,目前Eureka Server新的注冊資訊會被同步到其它節點中。
是以Eureka Server可以很好的應對因網絡故障導緻部分節點失聯的情況,而不會像ZK那樣如果有一半不可用的情況會導緻整個叢集不可用而變成癱瘓。
# 該配置可以移除這種自我保護機制,防止失效的服務也被一直通路 (Spring Cloud預設該配置是 true)
eureka.server.enable-self-preservation: false
# 該配置可以修改檢查失效服務的時間,每隔10s檢查失效服務,并移除清單 (Spring Cloud預設該配置是 60s)
eureka.server.eviction-interval-timer-in-ms: 10
2.Eureka用戶端
Eureka用戶端的配置application.yml:
eureka:
instance:
# 每隔10s發送一次心跳
lease-renewal-interval-in-seconds: 10
# 告知服務端30秒還未收到心跳的話,就将該服務移除清單
lease-expiration-duration-in-seconds: 30
client:
serviceUrl:
defaultZone: http://localhost:9501/eureka/
server:
port: 9502
spring:
application:
name: service-hi
# 該配置訓示eureka用戶端需要向eureka伺服器發送心跳的頻率 (Spring Cloud預設該配置是 30s)
eureka.instance.lease-renewal-interval-in-seconds: 10
# 該配置訓示eureka伺服器在接收到最後一個心跳之後等待的時間,然後才能從清單中删除此執行個體 (Spring Cloud預設該配置是 90s)
eureka.instance.lease-expiration-duration-in-seconds: 30
SpringCloud:Eureka的健康檢測機制==>https://blog.csdn.net/akaks0/article/details/79512680
遺留問題
defaultZone 需要添加/eureka字尾? 是的預設就這樣.
我的git項目位址
https://gitee.com/KingBoBo/springboot-07-cloud base分支
入門篇
Eureka 服務的注冊和發現==>https://www.cnblogs.com/fangwu/p/8975990.html
進階篇
SpringBoot SpringCloud叢集==>https://www.cnblogs.com/whatlonelytear/p/10894161.html