SpringCloud(三)-手把手教你通過(guò)Rinbbon實(shí)現(xiàn)客戶端負(fù)載均衡

當(dāng)一個(gè)系統(tǒng)中有多個(gè)服務(wù)提供者微服務(wù)的時(shí)候即横,服務(wù)消費(fèi)者應(yīng)該如何去選擇哪個(gè)提供者去訪問(wèn)呢。Spring Cloud提供了Ribbon來(lái)提供客戶端的負(fù)載均衡功能,本文將通過(guò)搭建的方式來(lái)簡(jiǎn)單了解如何使用Ribbon實(shí)現(xiàn)負(fù)載均衡功能。

系列文章
SpringCloud(一)-手把手教你創(chuàng)建springcloud微服務(wù)父子項(xiàng)目
SpringCloud(二)-手把手教你搭建Eureka Server和Eureka Client
SpringCloud(三)-手把手教你通過(guò)Rinbbon實(shí)現(xiàn)客戶端負(fù)載均衡
SpringCloud(四)-手把手教你使用OpenFeign
SpringCloud(五)-手把手教你使用Hystrix配置服務(wù)熔斷和降級(jí)以及Hystrix Dashboard
SpringCloud(六)-手把手教你搭建SpringCloud Config配置中心
SpringCloud(七)-手把手教你使用消息總線Bus實(shí)現(xiàn)動(dòng)態(tài)刷新
SpringCloud(八)-手把手教你使用Stream消息驅(qū)動(dòng)

負(fù)載均衡分為客戶端負(fù)載均衡和服務(wù)端負(fù)載均衡怜俐,客戶端負(fù)載均衡就是客戶端去選擇具體的微服務(wù)進(jìn)行訪問(wèn),而服務(wù)端負(fù)載均衡則是通過(guò)中間件攔截客戶端的請(qǐng)求轉(zhuǎn)發(fā)給對(duì)應(yīng)的微服務(wù)吞滞。而Ribbon提供的則是客戶端的負(fù)載均衡功能佑菩,因此我們要在消費(fèi)端去裝配負(fù)載均衡功能盾沫。

1. Ribbon配置

1.1 消費(fèi)端配置Ribbon

找到我們的服務(wù)提供者springcloud-product-consumer-8200

1.1.1 修改pom.xml
 <!--ribbon -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>
1.1.2 添加注解

我們?cè)谂渲胷estTemplate的時(shí)候加上 @LoadBalanced 注解

package com.elio.springcloud.config;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestConfig {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

}
1.1.3 配置負(fù)載均衡規(guī)則

新增MyRule配置類,注意千萬(wàn)不要建在主啟動(dòng)類同一級(jí)目錄下殿漠,不然會(huì)有問(wèn)題赴精。

package rule;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyRule {

    @Bean
    public IRule getLoadBalancedRule(){
        return  new RoundRobinRule();
    }
}

MyRule位置
1.2 新增訪問(wèn)服務(wù)信息的API

現(xiàn)在服務(wù)消費(fèi)者和服務(wù)提供者的API不能很明確的顯示我們?cè)L問(wèn)的是哪個(gè)微服務(wù),因此需要新增一個(gè)查詢當(dāng)前訪問(wèn)微服務(wù)信息的api

1.2.1 服務(wù)提供者8100

我們找到服務(wù)提供者8100的controller新增geServieInfo方法

package com.elio.springcloud.controller;

import com.elio.springcloud.dto.Result;
import com.elio.springcloud.entity.Product;
import com.elio.springcloud.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

@RestController
@Slf4j
@RequestMapping("/")
public class ProductProviderController {

    @Resource
    private ProductService productService;

    @Value("${spring.application.name}")
    private String instantName;

    @Value("${server.port}")
    private String port;

    @GetMapping("product/provider/get/info")
    public Result geServieInfo(){
        return new Result(200, "查詢成功", "當(dāng)前服務(wù)名:"+instantName + " 當(dāng)前端口:"+port);
    }

    /**
     * 查詢
     * @param id
     * @return
     */
    @GetMapping("product/provider/get/{id}")
    public Result selectById(@PathVariable("id") Long id){
        return new Result(200, "查詢成功", productService.selectById(id));
    }

    /**
     * 刪除
     * @param id
     * @return
     */
    @GetMapping("product/provider/delete/{id}")
    public Result deleteById(@PathVariable("id") Long id){
        return new Result(200, "刪除成功", productService.deleteById(id));
    }

    /**
     * 修改
     * @param product
     * @return
     */
    @PostMapping("product/provider/update")
    public Result updateById(@RequestBody Product product){
        return new Result(200, "修改成功", productService.updateById(product.getId(), product.getName()));

    }

    /**
     * 新增
     * @return
     */
    @PutMapping( "product/provider/add")
    public Result insertById(@RequestBody Product product){
        return new Result(200, "修改成功", productService.insertOne(product));
    }
}

1.2.2 服務(wù)消費(fèi)者8200

找到服務(wù)消費(fèi)者項(xiàng)目绞幌,修改controller蕾哟,新增geServieInfo方法,然后注意將我們寫死的地址換成服務(wù)提供者微服務(wù)名

package com.elio.springcloud.controller;

import com.elio.springcloud.dto.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
public class ProductConsumerController {

    @Resource
    RestTemplate restTemplate;

    //public static String url = "http://localhost:8100/";
    public static String url = "http://springcloud-product-provider/";

    /**
     * 查詢
     * @return
     */
    @GetMapping("product/consumer/get/info")
    public Result selectById(){
        return new Result(200, "查詢成功",
                restTemplate.getForObject(url+"product/provider/get/info", Result.class));
    }

    /**
     * 查詢
     * @param id
     * @return
     */
    @GetMapping("product/consumer/get/{id}")
    public Result selectById(@PathVariable("id") Long id){

        return new Result(200, "查詢成功",
                restTemplate.getForObject(url+"product/provider/get/"+id, Result.class));
    }

}

1.3 服務(wù)提供者啟動(dòng)多個(gè)實(shí)例

在上面的兩篇文章中我們都是通過(guò)新增子項(xiàng)目來(lái)配置多個(gè)實(shí)例的,這種方法無(wú)腦而且麻煩莲蜘,因此接下來(lái)介紹第二種方法谭确。通過(guò)idea的啟動(dòng)配置來(lái)設(shè)置一個(gè)微服務(wù)在不同端口啟動(dòng)。

下拉 run的按鈕

選中服務(wù)提供者項(xiàng)目票渠,點(diǎn)擊左上角的復(fù)制按鈕

點(diǎn)擊復(fù)制

如圖為復(fù)制后的配置名逐哈, 我們修改名稱為ProductProvider8103


image.png

在VM options中,添加參數(shù) -Dserver.port=8103问顷,表示這個(gè)實(shí)例將在8103上運(yùn)行昂秃。

修改端口號(hào)

點(diǎn)擊了ok后,我們?cè)傧吕璻un按鈕杜窄,就可以看到配置的 ProductProvider8103了肠骆,然后點(diǎn)擊右邊的debug按鈕,可以在8103端口上啟動(dòng)服務(wù)提供者了塞耕。


ProductProvider8103

最后我們要注意的是服務(wù)提供者的實(shí)例名要不同蚀腿,不然的話只能注冊(cè)成功一個(gè),由于端口是不一樣的所以保證了實(shí)例名不一樣,服務(wù)名是一樣的扫外。

eureka:
  instance:
    instance-id: ${spring.application.name}:${server.port}

然后依次啟動(dòng)服務(wù)注冊(cè)中8300莉钙,服務(wù)提供者8100,8101畏浆,8103胆胰,服務(wù)消費(fèi)者8200,然后Eureka 服務(wù)中心中服務(wù)提供者會(huì)有三個(gè)實(shí)例刻获。

成功注冊(cè)
1.4 測(cè)試

在配置的過(guò)程中注意我提出的兩點(diǎn)注意,不然的話要么注冊(cè)不成功瞎嬉,要么就是實(shí)現(xiàn)不了負(fù)載均衡蝎毡。接下來(lái)就是測(cè)試負(fù)載均衡了,訪問(wèn)消費(fèi)者的api http://localhost:8200/product/consumer/get/info, 然后多刷新幾次氧枣,發(fā)現(xiàn)按照8100沐兵,8101,8103的順序訪問(wèn)服務(wù)提供者

8100
8101
8103

2. 總結(jié)

本文通過(guò)一個(gè)簡(jiǎn)單的配置例子來(lái)實(shí)現(xiàn)了Spring Cloud項(xiàng)目配置Ribbon來(lái)實(shí)現(xiàn)客戶端負(fù)載均衡的便监,其工作原理和工作流程也沒(méi)有涉及扎谎,這將在其它文章中解析碳想。
上篇文章中,我們拋出了兩個(gè)問(wèn)題毁靶,在這篇文章中我們已經(jīng)解決了胧奔,一個(gè)是解決服務(wù)地址寫死的問(wèn)題,另一個(gè)則是負(fù)載均衡的實(shí)現(xiàn)预吆。但是現(xiàn)有的項(xiàng)目還是存在一個(gè)問(wèn)題龙填,就是我們?cè)L問(wèn)服務(wù)提供者的接口時(shí),需要在方法中指出具體的地址拐叉,如果這個(gè)接口被多處訪問(wèn)以后需要修改的話就需要修改多次岩遗,這個(gè)問(wèn)題我們留在下篇文章中解決。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末凤瘦,一起剝皮案震驚了整個(gè)濱河市宿礁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蔬芥,老刑警劉巖梆靖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異坝茎,居然都是意外死亡涤姊,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門嗤放,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)思喊,“玉大人,你說(shuō)我怎么就攤上這事次酌『蘅危” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵岳服,是天一觀的道長(zhǎng)剂公。 經(jīng)常有香客問(wèn)我,道長(zhǎng)吊宋,這世上最難降的妖魔是什么纲辽? 我笑而不...
    開(kāi)封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮璃搜,結(jié)果婚禮上拖吼,老公的妹妹穿的比我還像新娘。我一直安慰自己这吻,他們只是感情好吊档,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著唾糯,像睡著了一般怠硼。 火紅的嫁衣襯著肌膚如雪鬼贱。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天香璃,我揣著相機(jī)與錄音这难,去河邊找鬼。 笑死增显,一個(gè)胖子當(dāng)著我的面吹牛雁佳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播同云,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼糖权,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了炸站?” 一聲冷哼從身側(cè)響起星澳,我...
    開(kāi)封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎旱易,沒(méi)想到半個(gè)月后禁偎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡阀坏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年如暖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忌堂。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡盒至,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出士修,到底是詐尸還是另有隱情枷遂,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布棋嘲,位于F島的核電站酒唉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏沸移。R本人自食惡果不足惜痪伦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望雹锣。 院中可真熱鬧流妻,春花似錦、人聲如沸笆制。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)在辆。三九已至证薇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間匆篓,已是汗流浹背浑度。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鸦概,地道東北人箩张。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像窗市,于是被迫代替她去往敵國(guó)和親先慷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345