1. 程式人生 > >第二篇:SpringCloud之服務消費(Ribbon)

第二篇:SpringCloud之服務消費(Ribbon)

在微服務架構中,業務都會被拆分成一個獨立的服務,服務與服務的通訊是基於Http RESTful的。SpringCloud有兩種服務呼叫方式,一種是Ribbon+RESTTemplate,另一種是Feign。在這一篇文章首先講解下基於Ribbon+REST。

Ribbon簡介

Spring Cloud Ribbon是一個基於HTTP和TCP的客戶端負載均衡工具,它基於Netflix Ribbon實現。通過Spring Cloud的封裝,可以讓我們輕鬆地將面向服務的REST模版請求自動轉換成客戶端負載均衡的服務呼叫。Spring Cloud Ribbon雖然只是一個工具類框架,它不像服務註冊中心、配置中心、API閘道器那樣需要獨立部署,但是它幾乎存在於每一個Spring Cloud構建的微服務和基礎設施中。因為微服務間的呼叫,API閘道器的請求轉發等內容,實際上都是通過Ribbon來實現的,包括後續我們將要介紹的Feign,它也是基於Ribbon實現的工具。

所以,對Spring Cloud Ribbon的理解和使用,對於我們使用Spring Cloud來構建微服務非常重要。Ribbon是一個負載均衡客戶端,可以很好的控制http和tcp的一些行為。Feign預設集成了Ribbon。
Ribbon 已經預設實現了這些配置bean:

  • IClientConfig ribbonClientConfig: DefaultClientConfigImpl
  • IRule ribbonRule: ZoneAvoidanceRule
  • IPing ribbonPing: NoOpPing
  • ServerList ribbonServerList: ConfigurationBasedServerList
  • ServerListFilter ribbonServerListFilter: ZonePreferenceServerListFilter
  • ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer

服務提供

這一篇文章基於上一篇文章的工程,啟動sso-server 工程;啟動sso-serviceA工程,它的埠為8089;將serviceA的配置檔案的埠改為8090,並啟動,這時你會發現:sso-serviceA在sso-server註冊了2個例項,這就相當於一個小的叢集。訪問localhost:8088如圖所示:
在這裡插入圖片描述

服務呼叫

建一個服務消費者工程,取名為:service-ribbon
pom.xml檔案為

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot-ribbon</artifactId>
        <groupId>com.chenjay.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>sso-ribbon</artifactId>

</project>

在父工程的pom檔案中加入spring-cloud-starter-ribbon依賴

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

在工程的配置檔案指定服務的註冊中心地址為http://localhost:8088/eureka/,程式名稱為 service-ribbon,程式埠為8091。配置檔案application.yml如下:

server:
  port: 8091

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8088/eureka/

spring:
  application:
    name: service-ribbon

在工程的啟動類中,通過@EnableEurekaClient向服務中心註冊;並且向程式的ioc注入一個bean: RestTemplate;並通過@LoadBalanced註解表明這個restRemplate開啟負載均衡的功能。

@SpringBootApplication
@EnableEurekaClient
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

寫一個測試類HelloService,通過之前注入ioc容器的restTemplate來消費serviceA服務的“/hello”介面,在這裡我們直接用的程式名替代了具體的url地址,在Ribbon中它會根據服務名來選擇具體的服務例項,根據服務例項在請求的時候會用具體的url替換掉服務名,程式碼如下:

@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;

    public String helloService(String name) {
        return restTemplate.getForObject("http://SERVICEA/hello?name="+name,String.class);
    }
}

寫一個controller,在controller中用呼叫HelloService 的方法,程式碼如下:

@RestController
public class HelloController {

    @Autowired
    HelloService helloService;
    @GetMapping(value = "/hello")
    public String hello(@RequestParam String name){
        return helloService.helloService(name);
    }

}

測試

在瀏覽器上多次訪問http://localhost:8091/hello?name=chenjay,瀏覽器交替顯示:
在這裡插入圖片描述
在這裡插入圖片描述這說明當我們通過呼叫restTemplate.getForObject(“http://SERVICEA/hello?name=”+name,String.class)方法時,已經做了負載均衡,訪問了不同的埠的服務例項。

此時的架構

在這裡插入圖片描述

  • 一個服務註冊中心,sso-server,埠為8088
  • ss-oserviceA工程跑了兩個例項,埠分別為8089,8090,分別向服務註冊中心註冊
  • sso-ribbon埠為8091,向服務註冊中心註冊
  • 當sercvice-ribbon通過RestTemplate呼叫serviceA的hello介面時,因為用Ribbon進行了負載均衡,會輪流的呼叫serviceA:8089和8090 兩個埠的hello介面;

原始碼下載:https://github.com/chenjary/SpringCloud/tree/master/springboot-ribbon