springcloud

SpringCloud

微服務概述

什麼是微服務

  • 目前的微服務並無一個統一的標準,通常是以業務來劃分
  • 將傳統的一站式應用,拆分紅一個個的服務,完全去耦合,一個微服務就是單功能業務,只作一件事。
  • 與微服務相對的叫巨石

微服務與微服務架構

  • 微服務是一種架構模式或者一種架構風格,提倡將單一應用程序劃分紅一組小的服務==獨立部署==,服務之間相互配合、相互協調,每一個服務運行於本身的==進程==中。
  • 服務與服務間採用輕量級通信,如HTTP的RESTful API等
  • 避免統一的、集中式的服務管理機制

微服務的優缺點

優勢

  1. 每一個服務足夠內聚,足夠小,比較容易聚焦
  2. 開發簡單且效率高,一個服務只作一件事情
  3. 開發團隊小,通常2-5人足以(固然按實際爲準)
  4. 微服務是鬆耦合的,不管開發仍是部署均可以獨立完成
  5. 微服務能用不一樣的語言開發
  6. 易於和第三方集成,微服務容許容易且靈活的自動集成部署(持續集成工具備Jenkins,Hudson,bamboo等)
  7. 微服務易於被開發人員理解,修改和維護,這樣可使小團隊更加關注本身的工做成果,而無需必定要經過合做才能體現價值
  8. 微服務容許你融合最新的技術
  9. ==微服務只是業務邏輯的代碼,不會和HTML,CSS或其餘界面組件融合==。
  10. ==每一個微服務均可以有本身的存儲能力,數據庫可自有也能夠統一,十分靈活==。

缺點

  1. 開發人員要處理分佈式系統的複雜性
  2. 多服務運維難度,隨着服務的增長,運維的壓力也會增大
  3. 依賴系統部署
  4. 服務間通信的成本
  5. 數據的一致性
  6. 系統集成測試
  7. 性能監控的難度

微服務的技術棧

微服務條目 落地技術
服務開發 SpringBoot,Spring,SpringMVC
服務配置與管理 Netflix公司的Archaius、阿里的Diamond等
服務註冊與發現 Eureka、Consul、Zookeeper等
服務調用 Rest、RPC、gRPC
服務熔斷器 Hystrix、Envoy等
負載均衡 Ribbon、Nginx等
服務接口調用(客戶端調用服務的簡化工具) Feign等
消息隊列 Kafka、RabbitMQ、ActiveMQ等
服務配置中心管理 SpringCloudConfig、Chef等
服務路由(API網關) Zuul等
服務監控 Zabbix、Nagios、Metrics、Specatator等
全鏈路追蹤 Zipkin、Brave、Dapper等
服務部署 Docker、OpenStack、Kubernetes等
數據流操做開發包 SpringCloud Stream(封裝與Redis,Rabbit,Kafka等發送接收消息)
事件消息總線 SpringCloud Bus

爲何選SpringCloud做爲微服務架構

選型依據

  1. 總體解決方案和框架的成熟度
  2. 社區熱度
  3. 可維護性
  4. 學習曲線

當前各大IT公司的微服務架構

  1. 阿里Dubbo/HSF
  2. 京東JSF
  3. 新浪Motan
  4. 噹噹DubboX

各微服務的框架對比

功能點/服務框架 Netflix/SpringCloud Motan gRPC Thrift Dubbo/DubboX
功能定位 完整的微服務架構 RPC框架,但整合了ZK或Consul,實現集羣環境的基本服務註冊/發現 RPC框架 RPC框架 服務框架
支持Rest 是,Ribbon支持多種可插拔的序列化選擇
支持RPC
支持多語言 是(Rest形式)
服務註冊/發現 是(Eureka) Eureka服務註冊表,Karyon服務端框架支持服務自注冊和健康檢查 是(zookeeper/consul)
負載均衡 是(服務端zuul+客戶端Ribbon) zuul-服務,動態路由 雲端負載均衡 Eureka(針對中間層服務器) 是(客戶端) 是(客戶端)
配置服務 Netflix Archaius SpringCloud Config Server集中配置 是(zookeeper提供)
服務調用鏈監控 是(zuul) Zuul提供邊緣服務,API網關
高可用/容錯 是(服務端Hystrix+客戶端Ribbon) 是(客戶端) 是(客戶端)
典型應用案例 Netflix Sina Google Facebook  
社區活躍度 通常 通常 2017年7月才重啓
學習難度 中等 通常 通常
文檔豐富度 通常 通常 通常
其餘 Spring Cloud Bus爲咱們應用程序帶來了更多管理端點 支持降級 Netflix內部在開發集成gRPC IDL定義 實踐公司比較多

SpringCloud入門概述

  • Spring的三大模塊:SpringBoot(構建),Spring Cloud(協調),Spring Cloud Data Flow(鏈接)

SpringCloud是什麼

  • 分佈式系統的簡化版(官方介紹)
  • SpringCloud基於SpringBoot提供了一整套微服務的解決方案,包括服務註冊與發現,配置中心,全鏈路監控,服務網關,負載均衡,熔斷器等組件,除了基於Netflix的開源組件作高度抽象封裝以外,還有一些選型中立的開源組件
  • SpringCloud利用SpringBoot的開發便利性巧妙地簡化了分佈式系統的基礎設施開發,SpringCloud爲開發人員提供了快速構建分佈式系統的一些工具,包括配置管理、服務發現、斷路器、路由、微代理、事件總線,全局所、決策精選、分佈式會話等等,他們均可以用SpringBoot的開發風格作到一鍵啓動和部署。
  • ==一句話歸納:SpringCloud是分佈式微服務架構下的一站式解決方案,是各個微服務架構落地技術的幾何體,俗稱微服務全家桶==

SpringCloud和SpringBoot的關係

SpringBoot:專一於快速方便的開發單個個體微服務(關注微觀)java

SpringCloud:關注全局的微服務協調治理框架,將SpringBoot開發的一個個單體微服務組合並管理起來(關注宏觀)mysql

  • ==SpringBoot能夠離開SpringCloud獨立使用,可是SpringCloud不能夠離開SpringBoot,屬於依賴關係==

Dubbo是怎麼到SpringCloud的?哪些優缺點去技術選型

目前成熟都互聯網架構(分佈式+服務治理Dubbo)

目前成熟都互聯網架構(分佈式+服務治理Dubbo)

對比

  Dubbo Spring
服務註冊中心 Zookeeper Spring Cloud Netfilx Eureka
服務調用方式 RPC REST API
服務監控 Dubbo-monitor Spring Boot Admin
斷路器 不完善 Spring Cloud Netflix Hystrix
服務網關 Spring Cloud Netflix Zuul
分佈式配置 Spring Cloud Config
服務跟蹤 Spring Cloud Sleuth
消息總線 Spring Cloud Bus
數據流 Spring Cloud Stream
批量任務 Spring Cloud Task

最大區別:ios

  • Spring Cloud拋棄了RPC通信,採用基於HTTP的REST方式。Spring Cloud犧牲了服務調用的性能,可是同時也避免了原生RPC帶來的問題。REST比RPC更爲靈活,不存在代碼級別的強依賴,在強調快速演化的微服務環境下,顯然更合適。
  • ==一句話:Dubbo像組裝機,Spring Cloud像一體機==
  • 社區的支持與力度:Dubbo曾經停運了5年,雖然重啓了,可是對於技術發展的新需求,仍是須要開發者自行去拓展,對於中小型公司,顯然顯得比較費時費力,也不必定有強大的實力去修改源碼

####總結git

  1. 解決的問題域不同:Dubbo的定位是一款RPC框架,Spring Cloud的目標是微服務架構下的一站式解決方案

SpringCloud的參考資料

構建SpringCloud工程

概述:SpringCloud工程由一個父工程和若干個Module組成github

==應該遵循的條件:約定 > 配置 > 編碼==web

RestTemplate類

介紹

RestTemplate是Spring提供的用於訪問Rest服務的客戶端模板工具集,提供了多種遠程訪問Http的方法算法

意義

在一些不涉及實現方法的模塊中(消費者),只須要調用其餘服務暴露出的接口便可知足的需求,使用RestTemplate類中的方法能夠發出須要的HTTP請求並獲得返回結果。(相似Ajax)spring

RestTemplate用法

RestTemplate restTemplate = new RestTemplate();
//url:請求地址
//requestMap:請求參數
//type.class:HTTP響應轉換成的對象類型
restTemplate.getForObject(url,type.class);
restTemplate.postForObject(url,requestMap,type.class);

構建父工程

  • 建立一個Maven父工程並命名GAV
  • 打包方式爲==POM==
  • 在pom.xml中定義各依賴的版本號(若Module中pom.xml的依賴沒有指定版本號,則會根據父工程的版本號加入依賴)
  • 加入通用的依賴和插件

構建Module

  • 在父工程下新建Maven的Module,打包方式爲jar
  • 通常來時GAV中 GV隨父工程,本身定義A便可
  • 在該Module下pom.xml中加入其它須要的依賴
  • 正常開發便可
  • 完成後先clean一下Maven項目,而後再install提供給其它模塊調用

添加其它Module的依賴方法

  • 直接引用其GAV便可
    <dependencies>
        <dependency>
            <groupId>com.lzl</groupId>
            <artifactId>microservice-api</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

配置該module下的yml

  • 微服務須要獨立的端口
  • ==微服務最重要的是取名字!!!!必定要給微服務配置一個名字!這個名字就是這個微服務對外暴露的名字!==
  • 配置該模塊下的其它相關配置(如本例配置了mybatis)
server:
  port: 8001

mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml
  type-aliases-package: com.XXX.entity
  mapper-locations:
  - classpath:mybatis/mapper/**/*.xml
spring:
  application:
    name: microservicecloud-dept   #爲這個服務取名,很是重要!!!!!
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/cloudDB01
    username: root
    password: 123456
    dbcp2:
      min-idle: 5         #最小鏈接數
      initial-size: 5    #初始化鏈接數
      max-total: 10      #最大鏈接數
      max-wait-millis: 200    #等待鏈接最長的超時時間

編寫主啓動類

  • 記得主啓動類放在根包下,com.xxx.xxx
package com.XXX;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Provider8001_APP {
    public static void main(String[] args) {
        SpringApplication.run(Provider8001_APP.class,args);
    }
}

SpringCloud添加組件的基本套路

  1. 新增這個組件的maven座標GAV
  2. 在啓動類上面標註啓動該組件(通常來講是@EnableXXXXX)
  3. 編寫業務邏輯代碼

Eureka服務註冊與發現

Eureka介紹及原理

理解

==Eureka就像一個物業管理公司,其餘微服務就像小區的住戶,每一個住戶入住時都要向物業管理公司註冊,並定時向物業公司交管理費==sql

介紹

  • Eureka是一個基於REST的服務,用於定位服務,以實現雲端中間層服務發現和故障轉移。
  • Eureka主管服務註冊與發現,在微服務中,之後了這二者,只須要使用服務的標識符(==就是那個在每一個服務的yml文件中取得服務名稱==),就能夠訪問到服務,不須要修改服務調用的配置文件
  • Eureka遵循AP原則(高可用,分區容錯性),由於使用了自我保護機制因此保證了高可用

原理

  • Eureka使用的是C-S結構(客戶端-服務端)
  • 兩大組件:Eureka Server(提供註冊服務)、 Eureka Client(JAVA客戶端,負責發送心跳)
  • 系統中的其餘微服務使用Eureka客戶端鏈接到Eureka服務端維持心跳鏈接(即註冊)。SpringCloud的其餘模塊能夠經過Eureka Server 來發現系統中的微服務並加以調用

Eureka的架構圖

Eureka服務註冊中心構建

加入服務端依賴

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

配置yml

  • ==理解:物業公司確定不向本身註冊本身,並確定知道本身在哪,不用參加檢索==
server:
  port: 7001
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false     #false表示不向註冊中心註冊本身
    fetch-registry: false           #false表示本身就是註冊中心,職責是維護實例,不參加檢索
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/    #設置eureka server的交互地址,即對外暴露的地址

添加啓動類

  • ==注意:要在類前加@EnableEurekaServer標註==
package com.XXX;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class Eureka7001_APP {
    public static void main(String[] args) {
        SpringApplication.run(Eureka7001_APP.class,args);
    }
}

驗證是否構建成功

啓動主程序,訪問該服務地址便可shell

向Eureka註冊中心註冊微服務

增長依賴

在要註冊的微服務的pom.xml文件中增長依賴

		<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>	

修改yml

  • 在application.yml中增長之內容,將客戶端註冊到服務列表內
  • ==理解:小區用戶要找到物業管理處的地址進行註冊==
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka

主啓動類增長註解

  • 增長@EnableEurekaClient註解
@SpringBootApplication
@EnableEurekaClient
public class Provider8001_APP {
    public static void main(String[] args) {
        SpringApplication.run(Provider8001_APP.class,args);
    }
}

actuator與微服務註冊完善

主機名稱與服務名稱的修改

  • 修改服務名稱,在yml中eureka節點下添加以下內容
 eureka:
  instance:
    instance-id: dept8001		#修改別名
    prefer-ip-address: true		#顯示IP地址

info內容的詳細信息修改

做用

在查看Eureka時點擊進入某個微服務的info時,能給查看者一些必要的信息,能夠幫助查看者快速的瞭解該微服務,開發中十分有意義。

修改方法
  1. ==當前工程==添加依賴
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
  1. ==總的父工程==的build節點下添加以下內容
<build>
        <finalName>microservicecloud</finalName>
        <resources>
            <resource>
             	<!--容許掃描該路徑下的資源文件-->
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <delimiters>
                     	<!--指定動態獲取以$標誌開頭結尾的信息-->
                        <delimit>$</delimit>
                    </delimiters>
                </configuration>
            </plugin>
        </plugins>
    </build>
  1. 在==當前工程== 的application.yml文件添加回顯信息
info:
  author: XXX
  build-version: $project.version$

Eureka的自我保護

介紹

Eureka的自我保護機制主要是爲了網絡異常時保持高可用設計的,當在Eureka中註冊的微服務超過設定是時間內(默認90秒)沒有向Eureka服務端發送心跳,該微服務會進入自我保護模式。在自我保護模式中,Eureka會保護服務註冊表中的信息,不會註銷任何服務實例,直至收到的心跳數恢復至閾值以上,該微服務退出自我保護模式。

理解

好死不如賴活:Eureka的設計哲學是寧肯保留錯誤的服務信息,也不盲目註銷可能健康的服務。因此異常的服務不會被註銷,而是進入了自我保護模式。

自我保護模式的開關

在Eureka Server模塊下的yml文件中添加配置信息便可,true表示打開自我保護模式;false表示關閉自我保護模式(不推薦)

  server:
    enable-self-preservation: false

Eureka的服務發現

介紹

系統中的微服務能夠經過Eureka的服務發現去得到在Eureka中註冊的服務的信息,這是一個對外暴露的接口。

使用方法(provider中)

  1. 注入DiscoveryClient 對象(spring包下的),在controller方法中獲取
@Autowired
private DiscoveryClient discoveryClient;    

@ResponseBody
@GetMapping("/provider/discovery")
public Object discovery(){
        List<String> list = discoveryClient.getServices();
        System.out.println(list);
        List<ServiceInstance> insList = discoveryClient.getInstances("MICROSERVICECLOUD-DEPT");
        for (ServiceInstance si:insList) {
            System.out.println(si.getHost() +"," + si.getServiceId() +"," +si.getPort() +"," +si.getUri() +"," +si.getMetadata());
        }
        return this.discoveryClient;
    }
  1. 在主啓動類中加入@EnableDiscoveryClient註解
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class Provider8001_APP {
    public static void main(String[] args) {
        SpringApplication.run(Provider8001_APP.class,args);
    }
}

使用方法(consumer中)

在controller方法中使用restTemplate對象調用provider中暴露的URL 並得到返回對象便可

@GetMapping("/discovery")
public Object discovery() {
        return restTemplate.getForObject(URL_PREFIX+"/provider/discovery",Object.class);
    }

Eureka的集羣配置

集羣

集羣就是在不一樣的機器上配置相同的服務來構建要一個大的運算總體

實現集羣

  1. 新建N個Eureka Server模塊
  2. 每一個模塊的pom.xml中加入與單個Eureka Server相同的依賴
  3. 每一個模塊加入主程序(記得加@EnableEurekaServer註解)
  4. 修改hosts文件(Win7的路徑是C:\Windows\System32\drivers\etc)
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
127.0.0.1 eureka7003.com
  1. 修改Eureka Server模塊的application.yml文件,加入集羣,主要修改兩個地方:
  • hostname:修改成hosts文件中映射的地址
  • service-url下的defaultZone節點:填入集羣中另外的server服務端的地址
server:
  port: 7001
eureka:
  instance:
    hostname: eureka7001.com    #hostname爲hosts文件中映射的地址
  client:
    register-with-eureka: false     #false表示不向註冊中心註冊本身
    fetch-registry: false           #false表示本身就是註冊中心,職責是維護實例,不參加檢索
    service-url:
      #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/    #設置eureka server的交互地址
      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/  #其餘兩個服務端的地址
  1. 修改Eureka Client模塊的application.yml文件,使其向集羣註冊服務
  • service-url下的defaultZone節點:填入集羣中須要向其註冊server服務端的地址
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
  1. 訪問地址
http://eureka7001.com:7001
http://eureka7002.com:7002
http://eureka7003.com:7003
  1. ==注:defaultZone中eureka/後綴是必須的,若是刪除,Server類不會報錯,可是Client註冊時會報404錯誤==

Eureka與Zookeeper對比

CAP設計原則不一樣

Eureka遵照AP,Zookeeper遵照CP(C:強一致性,A:高可用,P:分區容錯性,三者只能選其二,高併發下P必選)

網絡波動下二者的處理對比

Zookeeper Eureka
當網絡出現故障時,剩餘zk集羣會發起投票選舉新的leader,可是此過程會持續30~120s,此過程對於高併發來講十分漫長,會致使整個註冊服務的癱瘓,這是不可容忍的 在15分鐘內85%的節點都沒有心跳,則註冊中心 會認爲客戶端與之出現了網絡故障,則會進入自動保護模式。1.Eureka不會移除沒有收到心跳的服務;2.新的服務仍能在服務端註冊,可是暫時不會被同步到其餘節點上直到網絡穩定

結論

Eureka能夠很好的應對網絡故障致使部分節點失去鏈接的狀況,而不會像zookeeper那樣致使整個註冊服務系統的癱瘓。

Ribbon負載均衡

Spring Cloud Ribbon是基於Netflix Ribbon實現的一套==客戶端==負載均衡工具。Ribbon會自動幫助你基於某種規則(簡單輪詢、隨機鏈接等),也能夠實現自定義的負載均衡算法。

負載均衡

  • 英文名稱:Load Balance,微服務或分佈式集羣中經常使用的一種應用

  • 簡單來講負載均衡就是將用戶的請求ping平攤的分配到多個任務上,從而是系統達到HA(高可用)

  • 兩種負載均衡:

    1. 集中式LB:偏硬件,服務的消費方和提供方之間使用獨立的LB設施,由該設施負責把訪問請求以某種策略轉發至服務的提供方。
    2. 進程內LB:騙軟件, 將LB邏輯集成到消費方,消費方從服務註冊中心指導哪些地址可用,再本身選擇一個合適的服務器。

Ribbon初步配置

  • ==Ribbon是客戶端負載均衡工具!!!Ribbon是客戶端負載均衡工具!!!Ribbon是客戶端負載均衡工具!!!==因此應該配置在客戶端
  1. 加入依賴,由於Riboon須要依賴Eureka運行,因此要同時加入Eureka依賴
        <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>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
  1. 對實現類加入@LoadBalanced註解
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
        return  new RestTemplate();
    }
}
  1. 在application.yml文件中配置向註冊中心註冊,若是是做爲消費者模塊不提供服務,不該該註冊本身
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    register-with-eureka: false				#做爲消費者不提供服務,不該該註冊本身
  1. 主啓動類中加入@EnableEurekaClient註解
@SpringBootApplication
@EnableEurekaClient
public class Consumer80_APP {
    public static void main(String[] args) {
        SpringApplication.run(Consumer80_APP.class,args);
    }
}
  1. 以上步驟1~4完成後便可在controller中直接經過服務名訪問系統中的微服務,服務名做爲URI
private static final String URL_PREFIX = "http://MICROSERVICECLOUD-DEPT/";

Ribbon負載均衡實現

架構示意圖:

Ribbon負載均衡架構

實現方法

目標:構建provider集羣后consumer經過負載均衡輪詢調用在Eureka中註冊的服務

  1. 構建集羣,新開兩個provider模塊,將原provider的==代碼部分和pom.xml中依賴照搬==到新的provider中
  2. 將原provider中application.yml文件照搬到新provider,並修改端口號,若新的provider使用本身的數據庫,則修改數據庫信息(其餘配置也同樣,如修改別名)
  3. 集羣中服務名稱必須一致!!!
spring:
  application:
    name: microservicecloud-dept   #同一集羣下必須使用同一服務名!!!!!
  1. 啓動服務,進行測試
總結

Ribbon其實就是一個軟負載均衡的客戶端組件,能夠和其餘須要請求的客戶端結合使用。

Ribbon核心組件IRule

IRule:根據特定算法從服務列表中選取一個須要訪問的服務

七大方法

==IRule是一個接口,七大方法是其自帶的落地實現類==

  • RoundRobinRule:輪詢(默認方法)
  • RandomRule:隨機
  • AvailabilityFilteringRule:先過濾掉因爲屢次訪問故障而處於斷路器跳閘狀態的服務,還有併發的鏈接數量超過閾值的服務,而後對剩餘的服務進行輪詢
  • WeightedResponseTimeRule:根據平均響應時間計算服務的權重。統計信息不足時會按照輪詢,統計信息足夠會按照響應的時間選擇服務
  • RetryRule:正常時按照輪詢選擇服務,若過程當中有服務出現故障,在輪詢必定次數後依然故障,則會跳過故障的服務繼續輪詢。
  • BestAvailableRule:先過濾掉因爲屢次訪問故障而處於斷路器跳閘狀態的服務,而後選擇一個併發量最小的服務
  • ZoneAvoidanceRule:默認規則,符合判斷server所在的區域的性能和server的可用性選擇服務

切換規則方法

只需在==配置類==中配置一個返回具體方法的bean便可

@Bean
public IRule MyRule(){
        return new RandomRule();    
    }

自定義Ribbon負載均衡算法

配置及包位置

  1. 自定義的Ribbon算法類不能放在主啓動類所在的包及子報下(確切來講是不能放在@componentscan註解的包及子包下),不然會被全局應用到Ribbon服務中。應該把自定義算法類放在另外新建的包下,且這個類應該是爲==配置類==。(其實與普通切換負載均衡規則相似,只不過是位置不一樣而已,普通的能夠放在主啓動類所在的包,自定義的要放在外面的包下)
  2. 主啓動類添加@RibbonClient(name = "微服務名",configuration = XXX.class)註解指定須要用到負載均衡的微服務名及自定義算法的class對象。
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "MICROSERVICECLOUD-DEPT",configuration = MyRule.class)
public class Consumer80_APP {
    public static void main(String[] args) {
        SpringApplication.run(Consumer80_APP.class,args);
    }
}

####經過修改源代碼得到自定義算法

目標:每一個服務調用5次後再進行輪詢(調用次數不是很對,懶得改了)

package com.Rules;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.RoundRobinRule;
import com.netflix.loadbalancer.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;


public class MyRule extends AbstractLoadBalancerRule {

    private AtomicInteger nextServerCyclicCounter;
    private static final boolean AVAILABLE_ONLY_SERVERS = true;
    private static final boolean ALL_SERVERS = false;
    private int total = 0;
    private int currentIndex = 0;

    private static Logger log = LoggerFactory.getLogger(RoundRobinRule.class);

    public MyRule() {
        nextServerCyclicCounter = new AtomicInteger(0);
    }

    public MyRule(ILoadBalancer lb) {
        this();
        setLoadBalancer(lb);
    }

    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            log.warn("no load balancer");
            return null;
        }

        Server server = null;
        int count = 0;
        while (server == null && count++ < 10) {
            List<Server> reachableServers = lb.getReachableServers();
            List<Server> allServers = lb.getAllServers();
            int upCount = reachableServers.size();
            int serverCount = allServers.size();

            if ((upCount == 0) || (serverCount == 0)) {
                log.warn("No up servers available from load balancer: " + lb);
                return null;
            }
            if (total > 5) {
                total = 0;
                int nextServerIndex = incrementAndGetModulo(serverCount);
                currentIndex = nextServerIndex;
                server = allServers.get(nextServerIndex);
            }else {
                if (currentIndex>=serverCount) {
                    currentIndex = 0;
                }
                server = allServers.get(currentIndex);
                total++;
            }


            if (server == null) {
                /* Transient. */
                Thread.yield();
                continue;
            }

            if (server.isAlive() && (server.isReadyToServe())) {
                return (server);
            }

            // Next.
            server = null;
        }

        if (count >= 10) {
            log.warn("No available alive servers after 10 tries from load balancer: "
                    + lb);
        }
        return server;
    }

    /**
     * Inspired by the implementation of {@link AtomicInteger#incrementAndGet()}.
     *
     * @param modulo The modulo to bound the value of the counter.
     * @return The next value.
     */
    private int incrementAndGetModulo(int modulo) {
        for (;;) {
            int current = nextServerCyclicCounter.get();
            int next = (current + 1) % modulo;
            if (nextServerCyclicCounter.compareAndSet(current, next))
                return next;
        }
    }


    public Server choose(Object key) {
        return choose(getLoadBalancer(), key);
    }


    public void initWithNiwsConfig(IClientConfig clientConfig) {
    }
}

Feign負載均衡

Feign是一個聲明式WebService客戶端,使用方法時定義一個接口並在上面添加註解便可。Feign支持可拔插式的編碼器和解碼器。Spring Cloud對Feign進行了封裝,使其支持SpringMVC和HttpMessageConverters。Feign能夠與Eureka和Ribbon組合使用以支持負載均衡。

使用案例

  1. 新建Feign模塊,加入依賴(其實跟80消費者差很少,主要是多了Feign依賴)
    <dependencies>
        <dependency>
            <groupId>com.XXX</groupId>
            <artifactId>microservice-api</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</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-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <!--熱部署-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>
  1. 由於Feign開發實際上是面向接口編程,因此Feign接口能夠放在api模塊中供各模塊使用,因此要在api模塊中添加Feign依賴
  2. 在api中編寫接口,接口上添加@FeignClient註解,並經過value指定做用的微服務名
@FeignClient(value = "MICROSERVICECLOUD-DEPT")
public interface DeptClientService {

    @PostMapping("/dept")
    public boolean addDept(Dept dept);

    @GetMapping("/dept")
    public List<Dept> findAll();

    @GetMapping("/dept/{id}")
    public Dept findById(@PathVariable("id")Integer id);
}
  1. 在Feign模塊中編寫Controller,並注入FeignClient接口,直接調用service接口中的方法便可(由於聲明Feign接口時已經指定過微服務,因此訪問時會正確地找到微服務)
@RestController
@RequestMapping("/consumer")
public class ConsumerDeptController {
    @Autowired
    private DeptClientService service;

    @PostMapping("/dept")
    public boolean addDept(Dept dept){
        return service.addDept(dept);
    }

    @GetMapping("/dept")
    public List<Dept> findAll(){
        return service.findAll();
    }

    @GetMapping("/dept/{id}")
    public Dept findById(@PathVariable("id")Integer id){
        return service.findById(id);
    }
}
  1. 修改Feign模塊的主啓動類,加入@EnableFeignClients註解和@componentscan註解(主要是掃描api中聲明的接口)
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = {"com.XXX"})
@ComponentScan("com.XXX")
public class Consumer80Feign_APP {
    public static void main(String[] args) {
        SpringApplication.run(Consumer80Feign_APP.class,args);
    }
}
  1. 啓動後訪問,即會按照輪詢的方式調用provider集羣

總結

  • Feign經過接口方法調用REST服務,在Eureka中查找對應的服務
  • Feign集成了Ribbon技術,因此也支持負載均衡(輪詢)

Hystrix斷路器

分佈式系統面臨的問題

扇出

多個微服務互相調用的時候,若是A調用B、C,而B、C又繼續調用其餘微服務,這就是扇出(像一把扇子同樣慢慢打開。

服務雪崩

  • 刪除過程當中,若是某一個環節的服務出現故障或鏈接超時,就會致使前面的服務佔用愈來愈多的資源,進而引發系統崩潰,就是「雪崩效應」。
  • 對於高流量的應用來講,單一的後端依賴會致使服務器全部的資源都在幾秒鐘內飽和。比失敗更糟糕的是,這些應用程序還可能致使服務之間的延遲增長,備份隊列,線程和其餘系統資源緊張,致使整個系統發生更多的級聯故障。這些都表示須要==對故障和延遲進行隔離和管理==,以便單個依賴關係的失敗,不能取消整個應用程序或系統。

Hystrix介紹

  • Hystrix是一個用於處理分佈式系統延遲和容錯的開源庫。分佈式系統中,依賴避免不了調用失敗,好比超時,異常等。Hystrix能保證在出現問題的時候,不會致使總體服務失敗,避免級聯故障,以提升分佈式系統的彈性。
  • Hystrix相似一個「斷路器」,當系統中異常發生時,斷路器給調用返回一個符合預期的,可處理的FallBack,這樣就能夠避免長時間無響應或拋出異常,使故障不能再系統中蔓延,形成雪崩。

服務熔斷

  • 熔斷機制的註解是@HystrixCommand
  • 熔斷機制是應對雪崩效應的一種==鏈路保護機制==,通常存在於服務端
  • 當扇出鏈路的某個服務出現故障或響應超時,會進行==服務降級==,進而==熔斷該節點的服務調用==,快速返回「錯誤」的相應信息。、
  • Hystrix的熔斷存在閾值,缺省是5秒內20次調用失敗就會觸發
熔斷案例
  1. 構建一個新的provider module(如複製8001module)
  2. pom.xml加入hystrix依賴(必定要配合Eureka)
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
  1. application.xml中配置端口和Eureka信息(必配)和其餘框架的配置信息(可選,如mybatis)
  2. 編寫具體業務邏輯
  3. controller類中,在須要配置Fallback的方法上加入@@HystrixCommand(fallbackMethod = "XXX")註解,XXX爲FallBack方法名本例中做爲測試因此拋出了異常
    @ResponseBody
    @GetMapping("/dept/{id}")
    @HystrixCommand(fallbackMethod = "nullDeptFallBack")
    public Dept findById(@PathVariable("id")Integer id) {
        Dept dept = deptService.findById(id);
        if (null == dept){
            throw new RuntimeException("返回值爲空!");
        }
        return dept;
    }
  1. 根據須要配置FallBack的方法返回值編寫代碼
 public Dept nullDeptFallBack(@PathVariable("id")Integer id) {
        System.out.println(111);
        return new Dept().setId(id).setDeptName("nullName").setDbSource("nullDB");
    }
  1. 主啓動類中加入@EnableCircuitBreaker註解
  2. 開啓服務,測試

解耦與降級處理

降級
  • 當系統總體資源快不夠的時候,忍痛將部分服務暫時關閉,帶渡過難關後,再從新開啓。
  • 降級處理時在==客戶端==完成的,與服務端沒有關係
  • 理解:所謂降級,通常是從==總體負荷==考慮,當某個服務熔斷以後,服務器將再也不被調用,此時客戶端能夠本身準備一個本地的FallBack回調,返回一個缺省值。這樣作雖然服務水平降低,但好歹可用,比直接掛掉好。
爲何要解耦

若是按照上面的熔斷案例來作的話,Controller下的每一個方法,都要給其編寫一個FallBack方法,當方法慢慢變多,就會形成代碼膨脹,一個是增長編寫的工做量,另一個也會增大維護的難度,代碼的耦合度也會高,是十分不合理的,因此要將其解耦。

解耦思路

由於服務端的是經過實現接口訪問服務端的,若是在父接口上實現了FallBack方法,經過這樣一種方式去維護起來就能實現解耦,也順便完成了降級的機制。

解耦&降級案例
  1. 在api模塊中新建實現了FallbackFactory接口的類,其中泛型T就是咱們須要維護其FallBack的接口方法,並實現其create方法,在create方法中返回實現了T的對象,使用匿名內部類實現T。==注意:這個類必定要加@component註解!!這個類必定要加@component註解!!這個類必定要加@component註解!!==
import com.XXX.entity.Dept;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class DeptClientServiceFallBackFactory implements FallbackFactory<DeptClientService> {
    public DeptClientService create(Throwable throwable) {
        return new DeptClientService() {
            public boolean addDept(Dept dept) {
                return false;
            }

            public List<Dept> findAll() {
                return null;
            }

            public Dept findById(Integer id) {
                return new Dept().setId(id).setDeptName("服務器跪了,").setDbSource("遲點來吧");
            }
        };
    }
}
  1. 修改步驟1中傳入的泛型T接口,添加@FeignClient(fallbackFactory = T.class)註解
@FeignClient(value = "MICROSERVICECLOUD-DEPT",fallbackFactory = DeptClientServiceFallBackFactory.class)
public interface DeptClientService {

    @PostMapping("/dept")
    public boolean addDept(Dept dept);

    @GetMapping("/dept")
    public List<Dept> findAll();

    @GetMapping("/dept/{id}")
    public Dept findById(@PathVariable("id")Integer id);
}
  1. 修改consumer feign模塊的application.xml文件,開啓hystrix(注:在IDEA中可能沒有代碼提示,開啓的true也沒有正常高亮,但好像不須要作額外操做也不影響結果)
feign:
  hystrix:
    enabled: true
  1. 開啓服務並測試

HystrixDashboard服務監控

介紹:SpringCloud對Hystrix Dashboard進行了整合,能夠對經過Hystrix發起的請求進行準實時統計,並以報表和圖形的形式展現給用戶(包括每秒執行多少次請求成功和失敗等)。

配置案例
  1. 新建HystrixDashboard模塊,pom.xml文件加入HystrixDashboard依賴,其餘依賴包括Feign,Ribbon,Eureka(可參考80模塊的依賴)
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
        </dependency>
  1. application.yml文件中配置端口(如9001)
  2. provider類中確認要加入actuator依賴(此爲監控依賴)
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
  1. 編寫主啓動類,上標@EnableHystrixDashboard標註
@SpringBootApplication
@EnableHystrixDashboard
public class DashBoard9001_APP {
    public static void main(String[] args) {
        SpringApplication.run(DashBoard9001_APP.class,args);
    }
}
  1. 啓動服務進行測試,訪問地址:http://localhost:9001/hystrix,(根據配置端口號),==看到刺蝟表示已經配置好了==
如何監控
監控分析
  • 七色:進入監控界面後會有其中顏色的數字,其含義能夠對應右上角相同顏色的單詞表示的狀態,其值表明該狀態下觸發的次數
  • 一圈:圈的大小表明該服務的流量,圈越大流量越大
  • 一線:表明監控間隔中,服務被訪問的頻率的折線圖
  • 經過觀察這些就能夠在大量的實例中找出故障實例和高壓實例進行修復和維護。

Dashboard監控說明圖

Zuul路由網關

概述

  1. 代理:Zuul提供外部的請求轉發到具體的微服務實例中的服務

  2. 路由:Zuul能夠對外部訪問實現統一的入口

  3. 過濾:Zuul能夠對外部訪問進行干預,如請求校驗、服務聚合等

  4. Zuul須要配合Eureka使用,須要在Eureka中註冊並得到其餘微服務的信息

  5. 理解:Zuul就像大樓的保安,能夠請他找人(代理),找的人在外面叫什麼名字(路由),準不許你進樓(過濾)。由於保安屬於物業公司,因此保安要在物業公司註冊,所得到的信息也來源於物業公司(與Eureka的關係)。

基本配置

  1. 構建新的Zuul模塊並在pom.xml中加入依賴(Zuul和Eureka必須同時加入)
<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>
  1. 新建application.yml文件並配置(必定要向Eureka註冊,由於Zuul自己也是一個微服務)
server:
  port: 9527

spring:
  application:
    name: microservicecloud-zuul   #爲這個服務取名,很是重要!!!!!

eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: zuul.com
    prefer-ip-address: true
  1. 修改hosts文件(非必須,不過能更好看出效果)
127.0.0.0 zuul.com
  1. 建立主啓動類,並加入@EnableZuulProxy註解
@SpringBootApplication
@EnableZuulProxy
public class Zuul9527_APP {

    public static void main(String[] args) {
        SpringApplication.run(Zuul9527_APP.class,args);
    }
}
  1. 啓動測試,訪問規則:步驟3中指定映射+端口號+微服務名稱+訪問路徑。

    例子:http://zuul.com:9527/microservicecloud-dept/dept

路由訪問映射規則

服務名映射和統一公共前綴

當不向暴露真實的服務名時,能夠對服務名進行映射,只需在application.yml中配置便可,==具體做用看註釋==

zuul:
  routes:
  #dept0是能夠自定義的只是做爲區分,沒什麼具體意義
    dept0.serviceId: microservicecloud-dept		
    #路徑也是自定義的,支持通配符
    dept0.path: /dept10/**						
  #須要隱藏的服務名,可使用通配符,配置以後經過這個微服務名訪問就失效了
  ignored-services: microservicecloud-*
  #設置統一公共前綴,設置後訪問路徑:http://zuul.com:9527/nihao/dept10/dept/3
  prefix: /nihao								

==注:由於Zuul是針對外部訪問管理的,因此配置了隱藏的服務,在系統中其餘模塊進行服務名訪問時依然能夠正常運行的,這點能夠經過打開consumer模塊進行驗證!==

SpringCloud Config 分佈式配置中心

分佈式系統面臨的配置問題:微服務意味着將單體應用拆分紅一個個自服務,這些服務都是要相應的配置信息才能運行,隨着系統內微服務數量愈來愈多,配置信息也不斷地增多,因此一套集中式的、動態的配置管理設施是必不可少的。

概述

  • SpringCloud Config是一個提供外部集中式配置管理的設施,配置服務器爲各類不一樣的額微服務應用提供了一箇中心化的外部配置
  • SpringCloud Config分爲客戶端和服務端兩部分
    1. 服務端:分佈式配置中心,是一個獨立的微服務,用來鏈接併爲客戶端提供配置信息,加密/解密信息等訪問接口
    2. 客戶端:經過指定的配置中心獲取配置資源,cloud推薦用git來存儲配置信息
  • SpringCloud Config解決的問題:
    1. 集中管理配置文件
    2. 不一樣環境不一樣配置,動態化的配置更新
    3. 運行期間動態調整配置,再也不須要在每一個服務部署的機器上編寫配置文件,讓服務中心統一爲服務拉取配置文件
    4. 當配置發生變更時,服務不須要重啓便可感知配置變化並應用
    5. 將配置信息以REST接口形式暴露

![SpringCloud Config架構圖](E:\筆記\images\SpringCloud Config架構圖.png)

SpringCloud Config服務端與Github通信

目標:將配置文件部署在github,Config服務端從github獲取配置

案例

  1. 新建ConfigServer模塊並配置pom.xml
		<!-- springCloud Config -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-config-server</artifactId>
		</dependency>
		<!-- 避免Config的Git插件報錯:org/eclipse/jgit/api/TransportConfigCallback -->
		<dependency>
			<groupId>org.eclipse.jgit</groupId>
			<artifactId>org.eclipse.jgit</artifactId>
			<version>4.10.0.201712302008-r</version>
		</dependency>
  1. 創建遠程倉庫,並上傳配置文件。以下例
spring: 
    profiles: 
        active:
           - dev
---
spring:
    profiles: dev
    application:
        name: microservicecloud-config-XXX-dev
---
spring:
    profiles: test
    application:
        name: microservicecloud-config-XXX-test
  1. 在application.xml文件中配置github地址
server:
  port: 3344

spring:
  application:
    #爲這個服務取名,很是重要!!!!!
    name: microservicecloud-config
  cloud:
    config:
      server:
        git:
          # uri填github上倉庫地址
          uri: https://github.com/XXXX/SpringCloud_Configuration.git
  1. 編寫主啓動類,加入@EnableConfigServer註解
@SpringBootApplication
@EnableConfigServer
public class ConfigServer3344_APP {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServer3344_APP.class,args);
    }
}
  1. 啓動服務並嘗試訪問配置文件,有如下五種訪問配置規則
    • {application}:配置文件的文件名
    • {profile}:讀取的環境
    • {lable}:分支
/{application}/{profile}[/{lable}]
/{application}-{profile}.yml
/{lable}/{application}-{profile}.yml
/{application}-{profile}.properties
/{lable}/{application}-{profile}.properties

可用例子(返回格式可能不大相同,但返回值相同):

不可用例子:

bootstrap.yml介紹

  • bootstrap.yml比application.yml具備更高的優先級。
  • bootstrap.yml是系統級的資源配置項,application.yml是用戶級的資源配置項。
  • SpringCloud會建立"BootStrap Context"做爲"ApplicationContext"的==父上下文==。初始化的時候BootStrap Context負責從外部源加載配置屬性並解析。這兩個上下文共享一個"Environment",BootStrap 具備更高優先級,他們不會被本地配置覆蓋。

客戶端的配置與測試

介紹:客戶端主要是在==加載時==經過config server服務端得到github配置倉庫的地址,進而經過目標配置文件的文件名獲取相應的配置,最後將取得的配置對自身資源進行賦值並提供訪問

實現過程

1.建立遠程配置yml文件並上傳到github上。以下測試案例由於須要進行測試,因此配置了兩個profiles方便切換並觀察

spring: 
    profiles: 
        active:
           - dev
---
server: 
    port: 8201
spring:
    profiles: dev
    application:
        name: microservicecloud-config-client-dev
eureka:
    client: 
        service-url: 
            defaultZone: http://eureka-dev.com:7001/eureka/
---
server: 
    port: 8202
spring:
    profiles: test
    application:
        name: microservicecloud-config-client-test
eureka:
    client: 
        service-url: 
            defaultZone: http://eureka-dev.com:7001/eureka/
  1. 本地建立config client模塊,並配置好pom.xml,如下本組件是必選依賴
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
  1. 編寫bootstrap.yml配置文件,這個步驟比較關鍵,主要是根據此處的配置信息去尋找config server以得到github倉庫地址和配置中的目標配置文件文件名
spring:
  cloud:
    config:
      name: application_config #須要從github上讀取的資源名稱,注意沒有yml後綴名
      profile: test   #本次訪問的配置項
      label: master
      uri: http://config3344.com:3344  #本微服務啓動後先去找3344號服務,經過SpringCloudConfig獲取GitHub的服務地址
  1. application.yml文件在本module中實際上是可寫可不寫的,爲了習慣須要,仍是給他寫了個名字
spring:
  application:
    name: microservicecloud_config
  1. 修改host文件增長映射,和3344同樣
  2. 編寫主啓動類,沒什麼特別的,最基本的主啓動類
  3. 編寫controller,此步驟也比較關鍵,主要是利用@value註解賦值,若寫錯了bootstrap.yml中的配置文件名稱而沒有獲取到配置,啓動時這裏會拋出異常。@value中註解的參數便是目標配置文件中的參數值,使用El表達式獲取
@org.springframework.web.bind.annotation.RestController
public class RestController {
    @Value("${server.port}")
    private String port;
    @Value("${eureka.client.service-url.defaultZone}")
    private String eurekaZone;
    @Value("${spring.application.name}")
    private String name;


    @GetMapping("/config")
    @Override
    public String toString() {
        return "RestController{" +
                "port='" + port + '\'' +
                ", eurekaZone='" + eurekaZone + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}
  1. 先啓動config server服務,而後再啓用本client服務,根據profiles的值訪問對應的端口便可。如本例選擇的是test,則訪問端口爲:http://config3355.com:8202/config。(config3355.com爲hosts文件中配置了的映射)

SpringCloud的配置實戰

介紹:其實前面client的配置案例都是幫助理解這個組件爲主,並無很大的實際意義。。。。。。這節的案例中是配置一個Provider,一個eureka,他們的配置統一在github上獲取,實現統一配置分佈式管理和多環境變動,這個才比較有實戰意義。

實現過程

  1. 先寫好provider和Eureka的配置yml文件,這兩個文件和日常配置沒什麼不一樣,由於這裏主要是說config,因此就沒有配置集羣,上傳yml到github

Eureka配置文件示例:

spring: 
    profiles: 
        active:
           - dev
---
spring:
    profiles: dev
    application:
        name: microservicecloud-eureka-client-dev
server:
  port: 7001
eureka:
  instance:
    hostname: eureka7001.com    #hostname爲hosts文件中映射的地址
  client:
    register-with-eureka: false     #false表示不向註冊中心註冊本身
    fetch-registry: false           #false表示本身就是註冊中心,職責是維護實例,不參加檢索
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/   #設置eureka server的交互地址

---
spring:
    profiles: test
    application:
        name: microservicecloud-eureka-client-dev
server:
  port: 7001
eureka:
  instance:
    hostname: eureka7001.com    #hostname爲hosts文件中映射的地址
  client:
    register-with-eureka: false     #false表示不向註冊中心註冊本身
    fetch-registry: false           #false表示本身就是註冊中心,職責是維護實例,不參加檢索
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/    #設置eureka server的交互地址

Provider配置文件示例:

spring: 
    profiles: 
        active:
           - dev
---
server:
  port: 8001

mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml
  type-aliases-package: com.XXX.entity
  mapper-locations:
  - classpath:mybatis/mapper/**/*.xml
spring:
  profiles: dev
  application:
    name: microservicecloud-dept   #爲這個服務取名,很是重要!!!!!
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://192.168.88.246:3306/cloudDB01
    username: root
    password: 123456
    dbcp2:
      min-idle: 5         #最小鏈接數
      initial-size: 5    #初始化鏈接數
      max-total: 10      #最大鏈接數
      max-wait-millis: 200  #等待鏈接最長的超時時間
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/
  instance:
    instance-id: dept8001
    prefer-ip-address: true
---
server:
  port: 8001

mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml
  type-aliases-package: com.XXX.entity
  mapper-locations:
  - classpath:mybatis/mapper/**/*.xml
spring:
  profiles: test
  application:
    name: microservicecloud-dept   #爲這個服務取名,很是重要!!!!!
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://192.168.88.246:3306/cloudDB02
    username: root
    password: 123456
    dbcp2:
      min-idle: 5         #最小鏈接數
      initial-size: 5    #初始化鏈接數
      max-total: 10      #最大鏈接數
      max-wait-millis: 200  #等待鏈接最長的超時時間
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/
  instance:
    instance-id: dept8001
    prefer-ip-address: true
  1. 新開eureka和provide的模塊並在pom.xml中添加依賴,其餘必要依賴和以前的案例同樣,可是config的依賴必定要添加上
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
  1. 兩個模塊都要編寫bootstrap.yml文件,和上面的案例同樣
spring:
  cloud:
    config:
      name: application_config #須要從github上讀取的資源名稱,注意沒有yml後綴名
      profile: test   #本次訪問的配置項
      label: master
      uri: http://config3344.com:3344  #本微服務啓動後先去找3344號服務,經過SpringCloudConfig獲取GitHub的服務地址
  1. (可選)兩個模塊中編寫application.yml文件,能夠配置一下服務名
spring:
  application:
    name: microservicecloud_config
  1. 兩個模塊的主啓動類,Eureka的正常加EurekaServer註解,Provider加EurekaClient註解,不詳述
  2. 編寫Provider模塊的業務代碼
  3. 啓動測試,由於這兩個模塊都要經過3344ConfigServer爲其在github上獲取配置,因此要先啓動3344模塊,而後再一次啓動eureka和provider模塊,進行測試便可。
相關文章
相關標籤/搜索