SpringBoot系列—Spring Cloud快速入門

爲了解決單塊式架構可用性低,可伸縮性差,集中發佈的生命週期以及違反單一功能原則,微服務(Microservice)應運而生了,將功能按照邊界拆分爲單個服務,但是每個服務之間的通訊如何解決?Spring Cloud 的出現爲我們解決分佈式開發中常用的問題給出了完整的方案。Spring Cloud 基於Spring Boot ,爲我們提供了配置管理,服務發現,斷路器,代理服務等。基於Spring Cloud的開發特別適合在Docker或者其他專業的PaaS部署,所以又稱作原生雲應用。

spring cloud中文文檔:https://www.springcloud.cc/spring-cloud-dalston.html

理論基礎

1.配置服務

Spring Cloud 提供了 Config Server,可以集中存儲所有應用的配置文件,支持在文件系統或者git中放置的配置文件,用註解@EnableConfigServer啓用配置服務。

2.服務發現

Spring Cloud 通過 Netflix OSS 的 Eureka 來實現服務發現,服務發現的目的是爲了讓每個服務之間可以互相通信。Eureka Server爲微服務註冊中心,Spring Cloud 

使用註解的方式提供了Eureka服務端(@EnableEurekaServer)和客戶端(@EnableEurekaClient)。

3.路由網關

路由網關的作用是讓所有的微服務對外只有一個接口,我們只需要訪問一個網關地址,可以由網管將我們的請求代理到不同的服務中。Spring Cloud 通過 Zuul來實現的,

支持自動路由映射 Eureka Server 上註冊的服務。Spring Cloud 提供了註解@EnableZuulProxy啓用路由代理。

4.負責均衡

Spring Cloud 提供了Ribbon和Feign來實現負載均衡。在Spring Cloud 下,使用Ribbo直接注入一個RestTemplate對象即可,RestTemplate已經做好了負載均衡的配置;

使用Feign需要定義一個註解,有@FeignClient註解的接口,然後使用@RequestMapping註解到方法上映射遠程的REST服務,此方法也是做好負責均衡配置的。

5.斷路器

斷路器(Circuit Breaker)主要是爲了解決當某個方法調用失敗時,調用後備方法來達到容錯,阻止級聯錯誤等功能。Spring Cloud 使用註解 @EnableCircuitBreaker開啓斷

路器支持,使用 @HystrixCommand註解的fallbackMethod 來指定後備方法。還給我們提供了一個控制檯來監控斷路器的運行情況,通過註解@EnableHystrixDashboard來開啓。

實戰

新建模塊化的gradle項目cloud-main-manage,項目結構及其每個微服務功能說明如下:

springBootVersion = '1.5.4.RELEASE'
springCloudVersion = 'Dalston.SR1'


根目錄配置文件說明

settings.gradle 內容

rootProject.name = 'cloud-main-manager'
include 'discovery'
include 'config'
include 'person'
include 'ui'
include 'monitor'
build.gradle裏添加的dependency是對所有子模塊都有效的,在子模塊不需要額外添加這些依賴:

dependencies {
   compile('org.springframework.boot:spring-boot-starter-web')
   compile('org.springframework.boot:spring-boot-starter-actuator')
   compile('org.springframework.cloud:spring-cloud-starter')

   testCompile('org.springframework.boot:spring-boot-starter-test')
}
以下粘貼每個微服務的關鍵代碼,代碼說明都在對應的註釋裏

1.發現服務 discovery

dependencies {
   //服務發現依賴於Eureka Server
   compile('org.springframework.cloud:spring-cloud-starter-eureka-server')
}
@SpringBootApplication
@EnableEurekaServer //開啓對Eureka Server的支持
public class DiscoveryApplication {

   public static void main(String[] args) {
      SpringApplication.run(DiscoveryApplication.class, args);
   }
}
server:
  port: 8761 #當前Eureka Server的服務器端口號
eureka:
  instance:
    hostname: localhost #當前Eureka Server的hostname
  client:
    register-with-eureka: false #當前服務不需要註冊到Eureka Server
    fetch-registry: false

2.配置 config

dependencies {
   //配置服務依賴
   compile('org.springframework.cloud:spring-cloud-config-server')
   //Eureka客戶端依賴
   compile('org.springframework.cloud:spring-cloud-starter-eureka')
}
@SpringBootApplication
@EnableConfigServer//開啓配置服務器支持
@EnableEurekaClient//開啓Eureka Server的客戶端支持
public class ConfigApplication {
   public static void main(String[] args) {
      SpringApplication.run(ConfigApplication.class, args);
   }
}
#Spring Cloud 應用提供使用bootstrap.yml 負責從外部資源加載配置熟悉
spring:
  application:
    name: config #在Eureka Server 註冊的服務名爲config
  profiles:
    active: native #配置服務器使用本地配置(默認爲git)

eureka:
  instance:
    non-secure-port: ${server.port:8888} #若環境變量中的server.port有值則用,沒有用8080
    metadata-map:
      instanceId: ${spring.application.name}:${random.value} #配置在Eureka Server中的實例ID
  client:
    service-url:
      defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/ #Eureka客戶端設置Eureka Server的地址
#application.yml 配置其他應用所需的配置文件位於類路徑下的config目錄
#配置文件命名規則:應用名+profile.yml
spring:
  cloud:
    config:
      server:
        native:
          search-locations: classpath:/config

server:
  port: 8888

爲person服務提供配置文件

3.服務模塊 person

dependencies {
   // config server 配置依賴
   compile('org.springframework.cloud:spring-cloud-config-client')
   // Eureka 客戶端依賴
   compile('org.springframework.cloud:spring-cloud-starter-eureka')
}
@SpringBootApplication
@EnableDiscoveryClient //在這裏與@EnableEurekaClient的功能一樣
public class PersonApplication {

   public static void main(String[] args) {
      SpringApplication.run(PersonApplication.class, args);
   }
}
@RestController
public class PersonController {

    @Value("${my.message}")
    private String message;

    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public Person savePerson(@RequestBody String name){
        Person person = new Person(name);
        System.out.println(message);
        return person;
    }
}
spring:
  application:
    name: person
  cloud:
      config:
        enabled: true
        discovery:
          enabled: true
          service-id: CONFIG #指定Config Server的服務名,通過Eureka Server 發現Config Server。獲取person.yml

eureka:
  instance:
    non-secure-port: ${server.port:8082}
  client:
    service-url:
      defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/

4.UI模塊

dependencies {
   // config Server 配置依賴
   compile('org.springframework.cloud:spring-cloud-config-client')
   // Eureka 客戶端依賴
   compile('org.springframework.cloud:spring-cloud-starter-eureka')
   // 斷路器依賴
   compile('org.springframework.cloud:spring-cloud-starter-hystrix')
   // 支持路由網關依賴
   compile('org.springframework.cloud:spring-cloud-starter-zuul')
   // feign負責均衡依賴
   compile('org.springframework.cloud:spring-cloud-starter-feign')
   // ribbon負責均衡依賴
   compile('org.springframework.cloud:spring-cloud-starter-ribbon')
}
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients //開啓feign客戶端支持
@EnableCircuitBreaker // 開啓斷路器的支持
@EnableZuulProxy // 開啓網關代理支持
public class UiApplication {
   public static void main(String[] args) {
      SpringApplication.run(UiApplication.class, args);
   }
}

@FeignClient("person") //使用person調用person server,person爲服務名
public interface PersonService {
    @RequestMapping(method = RequestMethod.POST, value = "/save",
            produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    Person save(@RequestBody String name);
}
@Service
public class PersonHystrixService {

    @Autowired
    PersonService personService;

    //使用HystrixCommand的fallbackMethod參數指定,當本方法調用失敗時調用後路方法fallbackSave
    @HystrixCommand(fallbackMethod = "fallbackSave")
    public Person save(String name){
        return personService.save(name);
    }

    public Person fallbackSave(String name){
        Person person = new Person(name+"person service 異常");
        return person;
    }
}
注意:本方法與後來方法的參數要一致,否則程序異常:@HystrixCommand fallback method wasn't found

@RestController
public class PersonController {

    @Autowired
    PersonHystrixService personHystrixService;

    @RequestMapping(value = "/save",method = RequestMethod.GET)
    public Person save(){
        return personHystrixService.save("xianjj");
    }
}

配置省略

5.斷路器監控 monitor

dependencies {
   //斷路器依賴
   compile('org.springframework.cloud:spring-cloud-starter-hystrix-dashboard')
   compile('org.springframework.cloud:spring-cloud-starter-turbine')
}
@SpringBootApplication
@EnableEurekaClient
@EnableHystrixDashboard
@EnableTurbine
public class MonitorApplication {
   public static void main(String[] args) {
      SpringApplication.run(MonitorApplication.class, args);
   }
}

配置省略

運行

依次啓動discovery,config服務,其餘微服務部分順序啓動,最後啓動monitor。

1.訪問http://127.0.0.1:8761/,查看發現服務 Eureka Server


2.訪問UI服務的controller接口http://127.0.0.1/save

成功時返回:


關閉person服務,調用接口異常(feign找不到rest服務),執行後備方法


3.斷路器監控

訪問:http://127.0.0.1:8989/hystrix.stream

輸入:http://127.0.0.1/hystrix.stream



github源碼下載地址:https://github.com/jeofey/cloud-main-manage

該項目示例源碼下載http://download.csdn.net/detail/jeofey/9881810

Spring Cloud中文官方網站:https://www.springcloud.cc/

注意事項:

爲方便閱讀,在配置文件中添加了相應的註釋,若項目啓動時報異常:Caused by: org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 1

可以將application.yml文件中的註釋內容刪掉,再啓動;由於YMAL的語法校驗比較嚴格。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章