SpringCloud分佈式開發理解

談到SpringCloud最新接觸到的可能就是那五大"神獸",以前最早接觸分佈式開發是經過dubbo的RPC遠程過程調用,而dubbo給我得感受就是:雖然全部的主機物理上分佈了,可是對於用戶而言就彷彿是一個總體。而對咱們的java開發人員而言,分佈式開發的意義又是什麼呢?也就是說哪裏須要去使用分佈式開發呢,其實在任何一個項目裏面(MVC設計模式),業務操做是最爲核心的部分,而全部項目之中你的業務操做是否完成直接決定了你的項目自己是否健壯。以前太年輕...一直感受業務對一個追求技術培養得學者來講意義不大,大不了是一套CRUD,後來才發現這種想法就像是一頭還不知道本身獵物在哪裏的獅子同樣,還不清楚本身獵物得特性,就急着想去吃它身上的肉,可是什麼事都沒有絕對,若是真的是業務堆積,一堆技術含量很低的業務代碼CRUD的堆積就另當別論了...java

回到"五大神獸":

  • 服務發現——Netflix Eureka
  • 客服端負載均衡——Netflix Ribbon(Feign)
  • 斷路器——Netflix Hystrix
  • 服務網關——Netflix Zuul
  • 分佈式配置——Spring Cloud Config

下面咱們逐個研究一下SpingCloud分佈式這五個重點:

Eureka:

一個RESTful風格的服務,用來定位運行在業務流程管理開發平臺(AWS Enterprise BPM Platform)層的中間層服務。
1.Eureka服務器用做服務的註冊中心。(對比dubbo的註冊中心:zk redis等);
2.Eureka客戶端其實就是一個java客戶端,負責與服務器的交互,用做輪詢負責均衡,故障切換支持等。

Netflix在其生產環境中使用的是另外的客戶端,它提供基於流量、資源利用率以及出錯狀態的加權負載均衡。

依賴:nginx

<!--eureka server -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
    </dependency>

註解:git

  • @EnableEurekaServer:這個註解須要在springboot工程的啓動application類上加,表示啓動一個服務註冊中心;
  • @EnableEurekaClient:代表本身是一個eurekaclient;

配置:github

  • 註冊中心服務器:
server:
  port: 8761
# 默認狀況下erureka server也是一個eureka client ,必需要指定一個 server。eureka server的配置文件appication.yml 經過eureka.client.registerWithEureka:false和fetchRegistry:false來代表本身是一個eureka server.
eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  • 客戶端服務器:
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8762
spring:
  application:
    name: service-hi

Ribbon:

主要提供客戶側的軟件負載均衡算法。
Ribbon客戶端組件提供一系列完善的配置選項,好比鏈接超時、重試、重試算法等。 Ribbon是一個負載均衡客戶端,能夠很好的控制http和tcp的一些行爲。Feign默認集成了Ribbon。
Ribbon內置可插拔、可定製的負載均衡組件。
    一些經常使用的負載均衡策略: 
    1. 簡單輪詢負載均衡 
    2. 加權響應時間負載均衡 
    3. 區域感知輪詢負載均衡 
    4. 隨機負載均衡 
    Ribbon中還包括一下功能: 
    1. 易於與服務發現組件(好比Netflix的Eureka)集成 
    2. 使用Archaius完成運行時配置 
    3. 使用JMX暴露運維指標,使用Servo發佈 
    4. 多種可插拔的序列化選擇 
    5. 異步和批處理操做(即將推出) 
    6. 自動SLA框架(即將推出) 
    7. 系統管理/指標控制檯(即將推出)

依賴:redis

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

註解:算法

  • @EnableDiscoveryClient:向服務中心註冊;
  • @LoadBalanced:結合入職restRemplate的@Bean一塊兒使用,開始負載均衡功能;

配置:
application.yml:spring

#指定服務的註冊中心地址爲http://localhost:8761/eureka/
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
#程序端口爲8764
server:
  port: 8764
#程序名稱爲 service-ribbon
spring:
  application:
    name: service-ribbon

Feign:

Feign是一個聲明式的僞Http客戶端,它使得寫Http客戶端變得更簡單。使用Feign,只須要建立一個接口並註解。它具備可插拔的註解特性,可以使用Feign 註解和JAX-RS註解。Feign支持可插拔的編碼器和解碼器。Feign默認集成了Ribbon,並和Eureka結合,默認實現了負載均衡的效果。
簡而言之:
Feign 採用的是基於接口的註解
Feign 整合了ribbon

依賴:sql

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

註解:bootstrap

  • @EnableFeignClients:開啓Feign功能;
  • @FeignClient:在feign接口上加入此註解,經過@FeignClient("服務名"),來指定調用哪一個服務。(相似controller的@RequestMapping(value = "訪問路徑"))

配置:
application.yml設計模式

#服務註冊地址爲http://localhost:8761/eureka/
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
#端口號爲8765
server:
  port: 8765
#指定程序名爲service-feign
spring:
  application:
    name: service-feign

Hystrix:

Netflix開源了Hystrix組件,實現了斷路器模式,SpringCloud對這一組件進行了整合。較底層的服務若是出現故障,會致使連鎖故障。當對特定的服務的調用的不可用達到一個閥值(Hystric 是5秒20次)斷路器將會被打開。斷路打開後,可用避免連鎖故障,fallback方法能夠直接返回一個固定值。
斷路器的特色:
1.斷路器能夠防止一個應用程序屢次試圖執行一個操做,即極可能失敗,容許它繼續而不等待故障恢復或者浪費 CPU 週期,而它肯定該故障是持久的.
2.斷路器模式也使應用程序可以檢測故障是否已經解決。若是問題彷佛已經獲得糾正​​,應用程序能夠嘗試調用操做。
3.斷路器增長了穩定性和靈活性,以一個系統,提供穩定性,而系統從故障中恢復,並儘可能減小此故障的對性能的影響。它能夠幫助快速地拒絕對一個操做,即極可能失敗,而不是等待操做超時(或者不返回)的請求,以保持系統的響應時間。若是斷路器提升每次改變狀態的時間的事件,該信息能夠被用來監測由斷路器保護系統的部件的健康情況,或以提醒管理員當斷路器跳閘,以在打開狀態。

依賴:

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

註解:

  • @EnableHystrix:開啓Hystrix;
  • @HystrixCommand:在Service層的方法上加入,對方法建立熔斷器的功能,並指定了fallbackMethod熔斷方法,書寫對應名稱的方法;

PS:Feign中的斷路器:

Feign是自帶斷路器的,在D版本的SpringCloud中,它沒有默認打開。須要在配置文件中配置打開它,在配置文件加入配置:feign.hystrix.enabled=true

註解:

  • @FeignClient:在FeignClient的接口的註解中加上fallback屬性指定類,此類實現FeignClient的接口,並注入到IOC容器中(@Component),實現熔斷方法便可。

Hystrix Dashboard (斷路器:Hystrix 儀表盤):

依賴:

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

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

註解:

  • @EnableHystrixDashboard:配置到主程序啓動類中,開啓hystrixDashboard;

Zuul:

在微服務架構中,須要幾個基礎的服務治理組件,包括服務註冊與發現、服務消費、負載均衡、斷路器、智能路由、配置管理等,由這幾個基礎組件相互協做,共同組建了一個簡單的微服務系統。在SpringCloud微服務系統中,一種常見的負載均衡方式是:客戶端的請求首先通過負載均衡(zuul、Ngnix),再到達服務網關(zuul集羣),而後再到具體的服。,服務統一註冊到高可用的服務註冊中心集羣,服務的全部的配置文件由配置服務管理,配置服務的配置文件放在git倉庫,方便開發人員隨時改配置。相似nginx,反向代理的功能,不過netflix本身增長了一些配合其餘組件的特性。Zuul的主要功能是路由轉發和過濾器。路由功能是微服務的一部分,好比/api/user轉發到到user服務,/api/shop轉發到到shop服務。zuul默認和Ribbon結合實現了負載均衡的功能。

依賴:

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

註解:

  • @EnableZuulProxy:通常應用在入口applicaton類加上註解@EnableZuulProxy,開啓zuul的功能;

配置:

#指定服務註冊中心的地址爲http://localhost:8761/eureka/
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
#服務的端口爲8769
server:
  port: 8769
#服務名爲service-zuul
spring:
  application:
    name: service-zuul
#以/api-a/ 開頭的請求都轉發給service-ribbon服務
#以/api-b/ 開頭的請求都轉發給service-feign服務
zuul:
  routes:
    api-a:
      path: /api-a/**
      serviceId: service-ribbon
    api-b:
      path: /api-b/**
      serviceId: service-feign

zuul的服務過濾:zuul不只只是路由,而且還能過濾,作一些安全驗證。(實現:繼承ZuulFilter)

filterType:返回一個字符串表明過濾器的類型,
在zuul中定義了四種不一樣生命週期的過濾器類型,具體以下: 
    pre:路由以前
    routing:路由之時
    post: 路由以後
    error:發送錯誤調用
    filterOrder:過濾的順序
    shouldFilter:這裏能夠寫邏輯判斷,是否要過濾,本文true,永遠過濾。
    run:過濾器的具體邏輯。可用很複雜,包括查sql,nosql去判斷該請求到底有沒有權限訪問。

SpringCloudConfig:

1.SpringCloudConfig就是咱們一般意義上說的分佈式配置中心,將應用本來放在本地文件的配置抽取出來放在中心服務器上,從而可以提供更好的管理,發佈能力。
2.SpringCloudConfig分爲服務端和客戶端,服務端負責將git(或者svn)上存儲的配置文件發佈成REST接口,客戶端能夠從服務端RESTjie接口獲取配置。但客戶端並不能主動感知配置文件的變化,從而主動去獲取新的配置,它須要每一個客戶端經過POST方法觸發各自的/refresh請求,SpringCloudBus就經過一個輕量級消息代理鏈接分佈式系統節點。
3.能夠用於廣播狀態更改,(如配置更改)或者管理指令。
4.SpringCloudBus提供了經過POST方法訪問的endpoint/bus/refresh,這個接口一般由git的鉤子功能調用,用以通知各個SpringCloudConfig的客戶端去服務端更新配置。

依賴:

<!-- 服務端開始 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!-- 服務端結束 -->

<!-- 客戶端開始 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- 客戶端結束 -->

註解:

  • @EnableConfigServer:應用在程序的入口Application類上,表示開啓配置服務器的功能;

配置:
服務端:application.properties

spring.application.name=config-server
server.port=8888
#配置git倉庫地址
spring.cloud.config.server.git.uri=https://github.com/forezp/SpringcloudConfig/
#配置倉庫路徑
spring.cloud.config.server.git.searchPaths=respo
#配置倉庫的分支
spring.cloud.config.label=master
#訪問git倉庫的用戶名(若是Git倉庫爲公開倉庫,能夠不填寫用戶名和密碼)
spring.cloud.config.server.git.username=your username
#訪問git倉庫的用戶密碼
spring.cloud.config.server.git.password=your password

客戶端:bootstrap.properties

spring.application.name=config-client
spring.cloud.config.label=master
spring.cloud.config.profile=dev
spring.cloud.config.uri= http://localhost:8888/
server.port=8881
  • spring.cloud.config.label 指明遠程倉庫的分支
  • spring.cloud.config.profile
    • dev開發環境配置文件
    • test測試環境
    • pro正式環境
  • spring.cloud.config.uri= http://localhost:8888/指明配置服務中心的網址。

    http請求地址和資源文件映射以下:
      · /{application}/{profile}[/{label}]
      · /{application}-{profile}.yml
      · /{label}/{application}-{profile}.yml
      · /{application}-{profile}.properties
      · /{label}/{application}-{profile}.properties

PS:高可用配置中心:當服務實例不少時,都從配置中心讀取文件,這時能夠考慮將配置中心作成一個微服務,將其集羣化,從而達到高可用;

依賴:

<!-- 服務註冊中心依賴開始 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<!-- 服務註冊中心依賴結束 -->
<!-- 配置服務端依賴開始 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!-- 配置服務端依賴結束 -->

配置:
註冊中心:application.yml

#服務端口爲8889
server:
  port: 8889
# 做爲服務註冊中心的基本配置
eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

服務端:bootstrap.properties

spring.application.name=config-client
spring.cloud.config.label=master
spring.cloud.config.profile=dev
#spring.cloud.config.uri= http://localhost:8888/
#加上服務註冊地址爲http://localhost:8889/eureka/
eureka.client.serviceUrl.defaultZone=http://localhost:8889/eureka/
#是從配置中心讀取文件
spring.cloud.config.discovery.enabled=true
#配置中心的servieId,即服務名
spring.cloud.config.discovery.serviceId=config-server
server.port=8881

暫時先記錄這些;感謝網絡上大神方誌鵬的帖子: https://gitee.com/liudongyang/SpringCloudLearning

相關文章
相關標籤/搜索