Spring Cloud Ribbon(服務(wù)消費(fèi)者)

Spring Cloud Ribbon 是一個(gè)基于HttpTCP的客戶端負(fù)載均衡工具,基于Netflix Ribbon實(shí)現(xiàn)的。它不像服務(wù)注冊(cè)中心、配置中心、API網(wǎng)關(guān)那樣獨(dú)立部署,但是它幾乎存在于每個(gè)微服務(wù)的基礎(chǔ)設(shè)施中。

Ribbon架構(gòu)圖

1258b858-c697-32e3-8f9e-b2623f7c6862.png

Ribbon負(fù)載均衡策略

6944619-0355d316f5df9b3f.png

Ribbon默認(rèn)的策略是輪詢,我們可以自定義負(fù)載策略來(lái)覆蓋默認(rèn)的,當(dāng)然也可以通過(guò)配置指定使用哪些策略。

負(fù)載均衡概念

負(fù)載均衡技術(shù)在現(xiàn)有網(wǎng)絡(luò)結(jié)構(gòu)之上提供了一種廉價(jià)、有效、透明的方法,來(lái)擴(kuò)展網(wǎng)絡(luò)設(shè)備和服務(wù)器的帶寬、增加吞吐量、加強(qiáng)網(wǎng)絡(luò)數(shù)據(jù)處理能力、提高網(wǎng)絡(luò)的靈活性和可用性。它有兩方面的含義:首先,大量的并發(fā)訪問(wèn)或數(shù)據(jù)流量分擔(dān)到多臺(tái)節(jié)點(diǎn)設(shè)備上分別處理,減少用戶等待響應(yīng)的時(shí)間;其次,單個(gè)重負(fù)載的運(yùn)算分擔(dān)到多臺(tái)節(jié)點(diǎn)設(shè)備上做并行處理,每個(gè)節(jié)點(diǎn)設(shè)備處理結(jié)束后,將結(jié)果匯總,返回給用戶,系統(tǒng)處理能力得到大幅度提高。

負(fù)載均衡是對(duì)系統(tǒng)的高可用,網(wǎng)絡(luò)壓力的緩解和處理能力擴(kuò)容的重要手段之一。

硬件負(fù)載均衡:

主要通過(guò)在服務(wù)節(jié)點(diǎn)之間安裝專門(mén)的負(fù)載均衡設(shè)備,比如F5
詳細(xì)參照百度百科:https://baike.baidu.com/item/F5%E6%96%B9%E6%A1%88/1121377?fr=aladdin

軟件負(fù)載均衡

實(shí)現(xiàn)方式有兩種,分別是服務(wù)端的負(fù)載均衡和客戶端的負(fù)載均衡
服務(wù)端負(fù)載均衡:在服務(wù)端安裝一些具有均衡負(fù)載功能或者模塊的軟件來(lái)完成請(qǐng)求的分發(fā)工作,比如Nginx。

當(dāng)瀏覽器向后臺(tái)發(fā)出請(qǐng)求的時(shí)候,會(huì)首先向反向代理服務(wù)器發(fā)送請(qǐng)求,反向代理服務(wù)器會(huì)根據(jù)客戶端部署的ip:port映射表以及負(fù)載均衡策略,來(lái)決定向哪臺(tái)服務(wù)器發(fā)送請(qǐng)求,一般會(huì)使用到nginx反向代理技術(shù)。

QQ截圖20180626191547.png

客戶端負(fù)載均衡:當(dāng)瀏覽器向后臺(tái)發(fā)出請(qǐng)求的時(shí)候,客戶端會(huì)向服務(wù)注冊(cè)器(例如Eureka Server),拉取注冊(cè)到服務(wù)器的可用服務(wù)信息,然后根據(jù)負(fù)載均衡策略,直接命中哪臺(tái)服務(wù)器發(fā)送請(qǐng)求。這整個(gè)過(guò)程都是在客戶端完成的,并不需要反向代理服務(wù)器的參與。

在微服務(wù)中最基本的兩個(gè)角色是服務(wù)提供者與服務(wù)消費(fèi)者。
服務(wù)提供者:服務(wù)的被調(diào)用方(為其他服務(wù)提供服務(wù)的服務(wù))
服務(wù)消費(fèi)者:服務(wù)的調(diào)用方(依賴其他服務(wù)的服務(wù))

之前我們已經(jīng)嘗試了好幾種服務(wù)注冊(cè)方式,注冊(cè)了服務(wù),肯定需要被調(diào)用的,也就是消費(fèi)。
服務(wù)調(diào)用方式實(shí)現(xiàn)方式RestTemplate+Ribbon
使用RestTemplate消費(fèi)SpringBootRestful服務(wù)

前提

需要一個(gè)服務(wù)注冊(cè)中心,兩個(gè)服務(wù)提供者和一個(gè)消費(fèi)者
因?yàn)橹挥袃蓚€(gè)以上的服務(wù)提供者提供相同的服務(wù)才可以體現(xiàn)出負(fù)載均衡
服務(wù)注冊(cè)中心和服務(wù)提供者都使用Spring Cloud Eureka

實(shí)現(xiàn)服務(wù)提供者的Restful接口

之前已經(jīng)實(shí)現(xiàn)過(guò)服務(wù)注冊(cè)中心和服務(wù)提供者
不過(guò)之前的服務(wù)提供者并沒(méi)有提供接口給消費(fèi)者使用

@RestController
public class DiscoveryController {
    @Autowired
    private DiscoveryClient discoveryClient;
    @Value("${server.port}")
    private String ip;

    @GetMapping("/client")
    public String client() {
        String services = "調(diào)用的服務(wù)是: " + discoveryClient.getServices()+" 對(duì)應(yīng)的端口號(hào) :"+ip;
        System.out.println("調(diào)用的服務(wù)是: " + discoveryClient.getServices()+" 對(duì)應(yīng)的端口號(hào) :"+ip);
        return services;
    }
}

實(shí)現(xiàn)服務(wù)消費(fèi)者Ribbon

一開(kāi)始肯定打算是引入Spring Cloud Ribbon依賴,不過(guò)Spring Cloud Eureka依賴中已經(jīng)有
Ribbon的依賴了。單獨(dú)引入Ribbon依賴可能注冊(cè)不了服務(wù)

QQ截圖20180626163952.png

在項(xiàng)目的外部Jar包目錄中可以發(fā)現(xiàn)Spring Cloud Eureka依賴中已經(jīng)有Ribbon的依賴了
所以,主要引入的依賴和Eureka客戶端的一樣

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

在項(xiàng)目啟動(dòng)類上添加@EnableEurekaClient注解,消費(fèi)者和服務(wù)提供者一樣,都需要到注冊(cè)中心中注冊(cè)
并且使用@beanSpring容器中注入一個(gè)restTemplate對(duì)象,@LoadBalanced注解表明這個(gè)
restRemplate開(kāi)啟負(fù)載均衡的功能。

@SpringBootApplication
@EnableEurekaClient
public class SpringcloudConsumerRibbonApplication {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

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

下面來(lái)寫(xiě)一個(gè)簡(jiǎn)單的服務(wù)消費(fèi)類

@RestController
public class RibbonController {
    @Autowired
    RestTemplate restTemplate;
    @GetMapping("/consumer")
    public String getMsg() {

        return restTemplate.getForObject("http://springcloud-eureka-client/client", String.class);
    }
}

restTemplate可以發(fā)送GetPost,Put,Delete等請(qǐng)求
Get調(diào)用getForEntity()方法
Post調(diào)用postForObject()方法
Put調(diào)用put()方法
Delete調(diào)用delete()方法

getForEntity的第一個(gè)參數(shù)為我要調(diào)用的服務(wù)的地址,這里我調(diào)用了服務(wù)提供者提供的
/client接口(Eureka客戶端中已寫(xiě)好),getForEntity第二個(gè)參數(shù)String.class表示我希望返回的body類型是String

注意這里是通過(guò)服務(wù)名調(diào)用而不是服務(wù)地址,如果寫(xiě)成服務(wù)地址就沒(méi)法實(shí)現(xiàn)客戶端負(fù)載均衡了。
調(diào)用spring boot服務(wù)的時(shí)候,需要將服務(wù)的URL寫(xiě)死或者是寫(xiě)在配置文件中,一旦ip地址發(fā)生了變化,都需要改動(dòng)程序,并重新部署服務(wù),使用Ribbon的時(shí)候,可以有效的避免這個(gè)問(wèn)題。

restTemplate的所有用法可以參考
官方說(shuō)明文檔:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

在配置文件中加入相關(guān)配置

spring:
  application:
    name: eureka-consumer-ribbon
server:
  port: 9999
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9090/eureka

整體項(xiàng)目結(jié)構(gòu)

Eureka服務(wù)端 端口號(hào)是9090
兩個(gè)Eureka客戶端 端口號(hào)分別是80818082 相同的服務(wù)名springcloud-eureka-client
Ribbon消費(fèi)者客戶端 端口號(hào)是9999

啟動(dòng)服務(wù)進(jìn)行測(cè)試

先啟動(dòng)服務(wù)端再啟動(dòng)客戶端,客戶端啟動(dòng)順序沒(méi)要求
訪問(wèn)http://localhost:9090服務(wù)注冊(cè)中心

QQ截圖20180626171326.png

在服務(wù)注冊(cè)中心可以看到,服務(wù)提供者和消費(fèi)者都注冊(cè)好了

對(duì)服務(wù)提供者的Restful服務(wù)進(jìn)行消費(fèi)

訪問(wèn)http://localhost:9999/consumer可以看到消費(fèi)的服務(wù)名和端口

QQ截圖20180626171745.png

刷新下頁(yè)面
QQ截圖20180626171834.png

繼續(xù)刷新就調(diào)用另一個(gè)端口的服務(wù)了
我試著刷新了11次頁(yè)面,在控制臺(tái)可以看到調(diào)用情況
QQ截圖20180626172315.png

QQ截圖20180626172322.png

說(shuō)明已經(jīng)消費(fèi)了Eureka客戶端提供的服務(wù),而且Ribbon已經(jīng)默認(rèn)實(shí)現(xiàn)了負(fù)載均衡

在整個(gè)程序中,最關(guān)鍵的就是在RestTemplate上標(biāo)記的@LoadBalanced注解,Spring Cloud Ribbon通過(guò)注解@LoadBalanced 來(lái)實(shí)現(xiàn)負(fù)載均衡

深入了解@LoadBalanced注解可以參考:
https://blog.csdn.net/qq_26562641/article/details/53332269

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容