1. 程式人生 > >(轉)Spring Cloud(一)

(轉)Spring Cloud(一)

(二期)22、微服務框架spring cloud(一)

【課程22】spirng c...簡介.xmind54KB

【課程22】spirng cl...架構.xmind0.5MB

【課程22】負載均...eign.xmind46.2KB

【課程22】基於rest...服務.xmind25.2KB

【課程22】微服務.xmind63.6KB

【課程22】註冊中...reka.xmind0.7MB

 

什麼是微服務

微服務英文名稱Microservice,Microservice架構模式就是將整個Web應用組織為一系列小的Web服務。這些小的Web服務可以獨立地編譯及部署,並通過各自暴露的API介面相互通訊。它們彼此相互協作,作為一個整體為使用者提供功能,卻可以獨立執行擴充套件。

需要功能或使用場景

1:我們把整個系統根據業務拆分成幾個子系統

 2:每個子系統可以部署多個應用,多個應用之間使用負載均衡

 3:需要一個服務註冊中心,所有的服務都在註冊中心註冊,負載均衡也是通過在註冊中心註冊的服務來使用一定策略來實現。

 4:所有的客戶端都通過同一個閘道器地址訪問後臺的服務,通過路由配置,閘道器來判斷一個URL請求由哪個服務處理。請求轉發到服務上的時候也使用負載均衡。

 5:服務之間有時候也需要相互訪問。例如有一個使用者模組,其他服務在處理一些業務的時候,要獲取使用者服務的使用者資料。

 6:需要一個斷路器,及時處理服務呼叫時的超時和錯誤,防止由於其中一個服務的問題而導致整體系統的癱瘓。

 7:還需要一個監控功能,監控每個服務呼叫花費的時間等。

設計原則
  • 單一職責原則
  • 服務自治原則
  • 輕量級通訊機制
  • 跨語言、平臺
  • 通訊體量輕,如REST
  • 微服務粒度
基於rest風格的微服務 專案例子見程式碼

可以試用spring的restTemplate做rest遠端呼叫。

  • 主要使用RestTemplate完成rest呼叫

(服務提供者)

 

(服務呼叫者)

 

優缺點
  • 適用場景有侷限,服務提供者對我介面不能發生變化,會直接影響到消費者。
  • 服務容災不法保證,容易造成服務雪崩
  • 適合較為簡單微服務系統
什麼是spirngCloud

spring cloud 為開發人員提供了快速構建分散式系統的一些工具,包括配置管理、服務發現、斷路器、路由、微代理、事件匯流排、全域性鎖、決策競選、分散式會話等等。它執行環境簡單,可以在開發人員的電腦上跑。另外說明spring cloud是基於springboot的,所以需要開發中對springboot有一定的瞭解。

 

開發工具集合,含有多個專案。

簡化了分散式開發。

  • 利用Spring boot的開發便利
  • 主要是基於對Netfix開源元件的進一步封裝
核心特性
  • 分散式/版本化配置
  • 服務註冊和發現
  • 路由
  • 服務和服務之間的呼叫
  • 負載均衡
  • 斷路器
  • 分散式訊息傳遞

這些特性都是由不同的元件來完成,在架構的演進過程中扮演著重要的角色

特點

1:約定優於配置

2:開箱即用、快速啟動

3:與springboot緊密結合

4:輕量級的元件

5:元件支援豐富,功能齊全

 

整體結構圖

 

從上圖可以看出Spring Cloud各個元件相互配合,合作支援了一套完整的微服務架構。 

  • 其中Eureka負責服務的註冊與發現,很好將各服務連線起來
  • Hystrix 負責監控服務之間的呼叫情況,連續多次失敗進行熔斷保護。
  • Hystrix dashboard,Turbine 負責監控 Hystrix的熔斷情況,並給予圖形化的展示
  • Spring Cloud Config 提供了統一的配置中心服務
  • 當配置檔案發生變化的時候,Spring Cloud Bus 負責通知各服務去獲取最新的配置資訊
  • 所有對外的請求和服務,我們都通過Zuul來進行轉發,起到API閘道器的作用
  • 監控我們使用Sleuth+Zipkin+springAdmin將所有的請求資料記錄下來,方便我們進行後續分析

 

Spring Cloud Config:配置管理開發工具包,可以讓你把配置放到遠端伺服器,目前支援本地儲存、Git以及Subversion。

 

Spring Cloud Bus:事件、訊息匯流排,用於在叢集(例如,配置變化事件)中傳播狀態變化,可與Spring Cloud Config聯合實現熱部署。

 

Spring Cloud Netflix:針對多種Netflix元件提供的開發工具包,其中包括Eureka、Hystrix、Zuul、Archaius等。

 

Netflix Eureka:雲端負載均衡,一個基於 REST 的服務,用於定位服務,以實現雲端的負載均衡和中間層伺服器的故障轉移。

 

Netflix Hystrix:容錯管理工具,旨在通過控制服務和第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。

 

Netflix Zuul:邊緣服務工具,是提供動態路由,監控,彈性,安全等的邊緣服務。

Netflix Archaius:配置管理API,包含一系列配置管理API,提供動態型別化屬性、執行緒安全配置操作、輪詢框架、回撥機制等功能。

 

Spring Cloud for Cloud Foundry:通過Oauth2協議繫結服務到CloudFoundry,CloudFoundry是VMware推出的開源PaaS雲平臺。

 Spring Cloud Sleuth:日誌收集工具包,封裝了Dapper,Zipkin和HTrace操作。 

Spring Cloud Data Flow:大資料操作工具,通過命令列方式操作資料流。

Spring Cloud Security:安全工具包,為你的應用程式新增安全控制,主要是指OAuth2。

Spring Cloud Consul:封裝了Consul操作,consul是一個服務發現與配置工具,與Docker容器可以無縫整合。

Spring Cloud Zookeeper:操作Zookeeper的工具包,用於使用zookeeper方式的服務註冊和發現。

Spring Cloud Stream:資料流操作開發包,封裝了與Redis,Rabbit、Kafka等傳送接收訊息。

Spring Cloud CLI:基於 Spring Boot CLI,可以讓你以命令列方式快速建立雲元件。

註冊中心-Eureka

(心跳檢測、健康檢查、負載均衡等)

Spring Cloud解決的第一個問題就是:服務與服務之間的解耦。很多公司在業務高速發展的時候,服務元件也會相應的不斷增加。服務和服務之間有著複雜的相互呼叫關係,經常有服務A呼叫服務B,服務B呼叫服務C和服務D ...,隨著服務化元件的不斷增多,服務之間的呼叫關係成指數級別的增長。

 

這樣最容易導致的情況就是牽一髮而動全身。經常出現由於某個服務更新而沒有通知到其它服務,導致上線後慘案頻發。這時候就應該進行服務治理,將服務之間的直接依賴轉化為服務對服務中心的依賴。

 

兩個元件組成

  • Eureka Server註冊中心
  • Eureka Client服務註冊

當然服務中心這麼重要的元件一但掛掉將會影響全部服務,因此需要搭建Eureka叢集來保持高可用性,生產中建議最少兩臺。隨著系統的流量不斷增加,需要根據情況來擴充套件某個服務,Eureka內部已經提供均衡負載的功能,只需要增加相應的服務端例項既可。那麼在系統的執行期間某個例項掛了怎麼辦?Eureka內容有一個心跳檢測機制,如果某個例項在規定的時間內沒有進行通訊則會自動被剔除掉,避免了某個例項掛掉而影響服務。 

 

因此使用了Eureka就自動具有了註冊中心、負載均衡、故障轉移的功能。 

編寫Eureka Server步驟

第一步、匯入Eurka座標

<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>2.0.3.RELEASE</version>
   <relativePath/> <!-- lookup parent from repository -->
</parent>
 
  
<properties>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
   <java.version>1.8</java.version>
   <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
 
  
<dependencies>
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
   </dependency>
 
  
   <!--actuator用於應用監控管理-->
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
   </dependency>
 
  
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
   </dependency>
</dependencies>
 
  
<dependencyManagement>
   <dependencies>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-dependencies</artifactId>
         <version>${spring-cloud.version}</version>
         <type>pom</type>
         <scope>import</scope>
      </dependency>
   </dependencies>
</dependencyManagement>

第二步、Applcation上添加註解

#開啟Eurka註冊中心服務
@EnableEurekaServer 

第三步、在aplication.yml上配置Eureka註冊資訊

server:
  port: 8761
eureka:
  client:
    #  表示是否將自己註冊到Eureka Servcer。
    register-with-eureka: false
    #  表示是否從Eureka Server獲取註冊資訊
    fetchRegistry: false
    serviceUrl:
     #  設定Eureka Server互動的地址
      defaultZone: http://localhost:8761/eureka/
spring:
  application:
    name: eureka-server-1

第四步、啟動專案,訪問http://localhost:8761 可以訪問到Eureka服務介面

兩個註解
# 開啟註冊服務發現功能
@EnableDiscoveryClient
 
  
# 開啟Eureka註冊中心服務功能
@EnableEurekaServer
自我保護模式

保護模式主要用於一組客戶端和Eureka Server之間存在網路分割槽場景下的保護。一旦進入保護模式,Eureka Server將會嘗試保護其服務登錄檔中的資訊,不再刪除服務登錄檔中的資料(也就是不會登出任何微服務)。

 

預設情況下,如果Eureka Server在一定時間內沒有接收到某個微服務例項的心跳,Eureka Server將會登出該例項(預設90秒)。但是當網路分割槽故障發生時,微服務與Eureka Server之間無法正常通訊,以上行為可能變得非常危險了——因為微服務本身其實是健康的,此時本不應該登出這個微服務。

 

Eureka通過“自我保護模式”來解決這個問題——當Eureka Server節點在短時間內丟失過多客戶端時(可能發生了網路分割槽故障),那麼這個節點就會進入自我保護模式。一旦進入該模式,Eureka Server就會保護服務登錄檔中的資訊,不再刪除服務登錄檔中的資料(也就是不會登出任何微服務)。當網路故障恢復後,該Eureka Server節點會自動退出自我保護模式。

 

綜上,自我保護模式是一種應對網路異常的安全保護措施。它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留),也不盲目登出任何健康的微服務。使用自我保護模式,可以讓Eureka叢集更加的健壯、穩定。

 

自我保護的條件:

一般情況下,微服務在Eureka上註冊後,會30秒定期傳送心跳,Eureka 通過心跳來判斷微服務是否健康,同時會定期刪除超過90秒沒有傳送心跳的服務。

 

有2種情況會導致Eureka Server收不到微服務的心跳,

1. 是微服務自身原因所致,比如故障或關閉;

2. 是微服務與eureka之間的網路出現故障。

 

通常(微服務自身的故障關閉)只會導致個別服務出現故障,一般不會出現大面積的故障,而(網路故障)通常會導致Eureka Server在短時間內無法收到大批心跳。

考慮到這個區別,Eureka設定了一個閥值,當判斷掛掉的服務的數量超過閥值時,Eureka Server認為很大程度上出現了網路故障,將不再刪除心跳過期的服務。

 

那這個閥值是多少呢?

1. 15分鐘之內是否低於85%;

2. Eureka Server在執行期間,會統計心跳失敗的比例在15分鐘之內是否低於85%

3. 這種演算法叫著Eureka Server的自我保護模式。

 

關閉自我保護模式(生產上不建議)

(關閉了自我保護之後,然後需要幾分鐘才能把失效的客戶端節點刪掉)

 

高可用

作為一個註冊中心,為了確保微服務能夠正常的註冊和發現,單機的eureka server肯定不能滿足這樣的需求,如果註冊中心掛掉,那麼線上的所有服務都會有影響,那麼需要有一個高可用的eureka server來支撐。

 

在eureka的服務治理設計中,所有的節點既是服務提供方,也是服務消費方,服務註冊中心也是,那麼eureka server的高可用實際上是將自己作為服務註冊到其他的註冊中心,這樣可以形成一組相互註冊的服務註冊中心,可以實現服務清單的同步,達到高可用的目的。

 

註冊中心節點之間相互註冊即可實現高可用部署。

 

(相互註冊)

假如3個以上也一樣,把其他的都註冊到自己的server上面,用逗號隔開。客戶端需要配置所有的Eureka server地址。

(客戶端)

如此可以保證註冊節點的高可用。

 

原理

在euerka 叢集中如果某臺伺服器宕機,euerka沒有zookeeper的選舉leader規則過程,客戶端請求會自動切換到新的euerka的節點上,當宕機的伺服器從恢復後,euerka會從新將其納入到euerka伺服器叢集中(實現高可用)

 

註冊中心地位

客戶端發現

  • eureka

服務端發現

  • nginx
  • zookeeper
新增許可權控制

eureka啟動之後,可以通過連結直接訪問到eureka。所以需要新增security。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

新增security的賬號密碼。

spring:
  security:
    user:
      name: admin
      password: admin

可以通過spring-boot-starter-sercurity對Eureka Server新增安全認證。預設情況下,將其新增到classpath後,會對每個請求進行CSRF檢查。Eureka並不會生成CSRF token,所以需要關掉對/eureka/*路徑下的檢查:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
  
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 關閉csrf
        http.csrf().ignoringAntMatchers("/eureka/**");
        super.configure(http);
    }
}

客戶端連線eureka的時候,defaultZone需要改動。

eureka:
  client:
    # 設定Eureka Server互動的地址
    service-url:
      defaultZone: http://admin:[email protected]:8761/eureka/
客戶端負載均衡-Ribbon

Spring Cloud Ribbon是基於HTTP和TCP的客戶端負載工具,它是基於Netflix Ribbon實現的。通過Spring Cloud的封裝,可以輕鬆地將面向服務的REST模板請求,自動轉換成客戶端負載均衡服務呼叫。

整合步驟

步驟一:匯入Ribbon座標(其實可以不用加,client直接有)

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

 

步驟二:為RestTemplate新增@@LoadBalanced註解,表示使用負載均衡演算法

 

@Bean
//為RestTemplate整合Ribbon的負載均衡能力
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

步驟三:eureka-client-2是被呼叫者的應用名稱。名稱為eureka-client-2應用的有多個。此時就會根據負載演算法呼叫生產者。

步驟四:改變負載均衡策略,配置形式,或者註解形式都可以(IRule)

ORDER:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

 

被呼叫方(生產者)可以通過注入loadBalancerClient檢視當前埠。

@Autowired
private LoadBalancerClient loadBalancerClient;

 

在Eureka server看到的效果:

@LoadBalanced

客戶端負載均衡的使用

LoadBalancerInterceptor

自定義Ribbon配置 脫離專案使用Ribbon

service.ribbon.listOfServers

宣告式REST呼叫-Feign

Feign可以建立宣告式、模板化的HTTP客戶端,進行微服務呼叫。使用簡單,建立一個介面,然後在介面上新增一些註解,程式碼就完成了。

程式碼如下:

第一步、匯入Feign座標,並在Application上添加註解@EnableFeignClients表示開啟Feign模組

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

第二步 :建立一個Feign介面,並新增@FeignClient註解

import com.itmuch.cloud.microserviceconsumermoviefeign.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
 
  
@FeignClient(name = "microservice-provider-user")
public interface UserFeignClient {
 
  
    @GetMapping(value = "/{id}")
    User findById(@PathVariable("id") Long id);
}

第三步、controller上地方

    @Autowired
    private UserFeignClient userFeignClient;
 
  
    @GetMapping("/user/{id}")
    public User findById(@PathVariable Long id) {
        return this.userFeignClient.findById(id);
    }

feign常見問題彙總: