欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringCloud Netfilx Ribbon負載均衡工具使用方法介紹

 更新時間:2022年12月12日 08:33:47   作者:幽默涵養(yǎng)miss u  
Ribbon是Netflix的組件之一,負責(zé)注冊中心的負載均衡,有助于控制HTTP和TCP客戶端行為。Spring Cloud Netflix Ribbon一般配合Ribbon進行使用,利用在Eureka中讀取的服務(wù)信息,在調(diào)用服務(wù)節(jié)點時合理進行負載

一、介紹

Spring Cloud Ribbon是一個基于HTTP和TCP的客戶端負載均衡工具,它基于Netflix Ribbon實現(xiàn)。通過Spring Cloud的封裝,可以讓我們輕松地將面向服務(wù)的REST模版請求自動轉(zhuǎn)換成客戶端負載均衡的服務(wù)調(diào)用。Spring Cloud Ribbon雖然只是一個工具類框架,它不像服務(wù)注冊中心、配置中心、API網(wǎng)關(guān)那樣需要獨立部署,但是它幾乎存在于每一個Spring Cloud構(gòu)建的微服務(wù)和基礎(chǔ)設(shè)施中。因為微服務(wù)間的調(diào)用,API網(wǎng)關(guān)的請求轉(zhuǎn)發(fā)等內(nèi)容,實際上都是通過Ribbon來實現(xiàn)的,包括后續(xù)我們將要學(xué)習(xí)的OpenFeign,它也是基于Ribbon實現(xiàn)負載均衡的遠程服務(wù)調(diào)用工具。所以,對Spring Cloud Ribbon的理解和使用,對于我們使用Spring Cloud來構(gòu)建微服務(wù)非常重要.

二、使用

@Service
public class ApplicationClientServiceImpl implements ApplicationClientService {
    /**
     * Ribbon提供的負載均衡器
     */
    @Autowired
    private LoadBalancerClient loadBalancerClient;
    @Override
    public String client() {
        ServiceInstance si = loadBalancerClient.choose("application-service");
        // 獲取Application Service IP。
        System.out.println(si.getHost());
        // 獲取Ip及端口。
        System.out.println(si.getInstanceId());
        // 端口 
        System.out.println(si.getPort());
        // 應(yīng)用程序名 application-service
        System.out.println(si.getServiceId());
        // URI http://Application Service IP:端口
        System.out.println(si.getUri().toString());
        return null;
    }
}

三、SpringWeb之RestTemplate基于Http協(xié)議的遠程訪問

要想使用RestRemplate必須自己配置

package com.bjsxt.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class MyConfig {
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

(1)控制器

@RestController
public class ServerController {
    @Value("${server.port}")
    private int port;
    /**
     * 返回類型為集合,泛型為自定類型。
     */
    @RequestMapping("/returnUsers")
    public List<User> returnUsers(int nums){
        List<User> result = new ArrayList<>();
        for(int i = 0; i < nums; i++){
            result.add(new User(100 + i, "姓名-" + i, 20+i));
        }
        return result;
    }
    /**
     * 任意請求方式, 返回值類型是集合。相對復(fù)雜的Java類型。
     * @return
     */
    @RequestMapping("/returnList")
    public List<String> returnList(int nums){
        List<String> result = new ArrayList<>();
        for(int i = 0; i < nums; i++){
            result.add("返回結(jié)果 - " + i);
        }
        return result;
    }
    /**
     * 任意請求,傳遞路徑地址參數(shù)
     * @param name
     * @param age
     * @return
     */
    @RequestMapping("/restfulParams/{name}/{age}")
    public String restfulParams(@PathVariable("name") String name,
                                @PathVariable int age){
        System.out.println("端口號: " + port + ", 任意請求方式,restful參數(shù), name = " +
                name + " ; age = " + age);
        return "restful參數(shù), name = " + name + " ; age = " + age;
    }
    /**
     * post請求,請求體傳遞參數(shù)。參數(shù)使用@RequestBody處理。
     */
    @PostMapping("/postBodyParams")
    public String postBodyParams(@RequestBody Map<String, String> params){
        System.out.println("端口號: " + port + " , post請求,有請求體參數(shù), params = " +
                params);
        return "post請求,請求體參數(shù), params = " + params;
    }
    /**
     * post請求,有參數(shù)
     */
    @PostMapping("/postWithParams")
    public String postWithParams(String name, int age){
        System.out.println("端口號: " + port + " , post請求,有參數(shù), name = " +
                name + " ; age = " + age);
        return "post請求有參數(shù) : name = " +
                name + " ; age = " + age;
    }
    /**
     * post請求,沒有參數(shù)
     */
    @PostMapping("/postNoParams")
    public String postNoParams(){
        System.out.println("端口號: " + port + " , post請求,沒有參數(shù)");
        return "post請求,沒有參數(shù)";
    }
    /**
     * get請求,包含參數(shù)
     */
    @GetMapping("/getWithParams")
    public String getWithParams(String name, int age){
        System.out.println("端口號: " + port + " 。 get請求,有參數(shù), name = "
                    + name + " ; age = " + age);
        return "get請求,包含參數(shù) : name = " + name + " ; age = " + age;
    }
    /**
     * get請求,沒有參數(shù)
     * @return
     */
    @GetMapping("/getNoParams")
    public String getNoParams(){
        System.out.println("端口號:" + port + "。 get請求,無參數(shù)。");
        return "get請求,無參數(shù)。";
    }
}

(2)無參數(shù)GET請求-getForObject

    /**
     * 發(fā)get請求。
     * 沒有請求參數(shù)
     *
     * <T> T getForObject(String url, Class<T> returnValueType, Object... params)
     * url - 要訪問的具體地址
     * returnValueType - 服務(wù)器返回的響應(yīng)體數(shù)據(jù)類型
     * params - 可選的請求參數(shù)
     * return - 響應(yīng)體中的具體內(nèi)容。
     */
    @Test
    public void testGetNoParams(){
        // 定義要訪問的地址是什么
        String url = baseUrl + "/getNoParams";
        // 發(fā)get請求。沒有參數(shù)
        String result = restTemplate.getForObject(url, String.class);
        System.out.println("服務(wù)器返回:" + result);
    }

(3)有參數(shù)GET請求-getForObject

    /**
     * get請求,有參數(shù)
     * <T> T getForObject(String url, Class<T> returnValueType, Object... params)
     * <T> T getForObject(String url, Class<T> returnValueType, Map params)
     * 傳遞參數(shù),就是處理請求地址url,并傳遞需要的參數(shù)。
     * 要傳遞參數(shù),則處理請求地址url。使用{名字}作為占位變量。傳遞參數(shù)的時候,
     * 可以根據(jù)占位變量從左至右的順序,使用可變長數(shù)組依次傳遞。
     * 也可以根據(jù)占位變量名稱,做指定傳遞,使用map集合傳遞,map的key就是占位變量名,
     * map的value,是要傳遞的請求參數(shù)。
     */
    @Test
    public void testGetWithParams(){
        String url = baseUrl + "/getWithParams?name={x}&age={y}";
        String result1 =
                restTemplate.getForObject(url, String.class,
                        "張三", "20");
        System.out.println("可變長數(shù)組傳遞參數(shù),服務(wù)器返回:" + result1);
        System.out.println("==========================================");
        Map<String, Object> params = new HashMap<>();
        params.put("x", "李四");
        params.put("y", 25);
        String result2 =
                restTemplate.getForObject(url, String.class, params);
        System.out.println("Map集合傳遞參數(shù),服務(wù)器返回:" + result2);
    }

(4)GET請求-getForEntity

    /**
     * 在RestTemplate中。除方法getForObject以外,還有g(shù)etForEntity。
     *  方法除返回值類型,其他一致。
     * <T> ResponseEntity<T> getForEntity(String url, Class<T> returnValueType,
     *       Object... params)
     * ResponseEntity - 包含響應(yīng)頭和響應(yīng)體。
     * 如果需要對響應(yīng)頭做特殊處理,使用getForEntity方法。
     */
    @Test
    public void testGetForEntity(){
        String url = baseUrl + "/getNoParams";
        ResponseEntity<String> entity =
                restTemplate.getForEntity(url, String.class);
        HttpHeaders headers = entity.getHeaders();
        for(String headerName : headers.keySet()){
            System.out.println("響應(yīng)頭: " + headerName + " = "
                    + headers.get(headerName));
        }
        System.out.println("響應(yīng)狀態(tài)碼: " + entity.getStatusCodeValue());
        System.out.println("響應(yīng)體數(shù)據(jù): " + entity.getBody());
    }

(5)無參數(shù)POST請求

    /**
     * post請求,沒有參數(shù)
     * <T> T postForObject(String url, Object body, Class<T> returnBodyType,
     *            Object... params);
     * <T> T postForObject(String url, Object body, Class<T> returnBodyType,
     *            Map params);
     * body參數(shù) - 使用post請求方式發(fā)請求的時候,請求體是什么?
     *   建議傳遞的對象類型是HttpEntity。
     *   如果對請求體沒有要求,可以傳遞null。
     */
    @Test
    public void testPostNoParams(){
        String url = baseUrl + "/postNoParams";
        String result =
                restTemplate.postForObject(url, null, String.class);
        System.out.println("post請求,無參數(shù),服務(wù)器返回:" + result);
    }

(6)post請求路徑地址傳遞參數(shù)

    /**
     * post請求,有參數(shù)
     * 1. 請求地址傳遞參數(shù)。 請求頭傳參。 傳參方式和get一樣。
     * 2. 請求體表單參數(shù)。 請求體傳參。 需要提供請求體數(shù)據(jù)
     */
    @Test
    public void testPostWithParamsPath(){
        String url = baseUrl + "/postWithParams?name={1}&age={2}";
        String result =
                restTemplate.postForObject(url, null, String.class,
                        "王五", 30);
        System.out.println(result);
    }

(7)post請求表單傳遞參數(shù)

    /**
     * spring web在處理請求頭和請求體的時候,
     * 需要HttpMessageConverter提供數(shù)據(jù)轉(zhuǎn)換處理。
     * HttpMessageConverter是接口,由Spring WEB定義。
     * 具體實現(xiàn),需要依賴不同的具體技術(shù)實現(xiàn)。
     * 一般都使用jackson做實現(xiàn)。請求頭和體數(shù)據(jù),都是基于JSON轉(zhuǎn)換的。
     */
    @Test
    public void testPostWithParamsForm(){
        String url = baseUrl + "/postWithParams";
        // 創(chuàng)建請求體信息。
        // 請求頭, 表單請求。  application/x-www-form-urlencoded
        HttpHeaders headers = new HttpHeaders();
        headers.add("content-type", "application/x-www-form-urlencoded");
        // 表單
        MultiValueMap<String, Object> form =
                new LinkedMultiValueMap<>();
        // add 提供一個 請求參數(shù) 名 = 值。
        form.add("name", "尼古拉斯.趙四");
        form.add("age", 40);
        // put 提供 鍵值對
        //form.put("name", Arrays.asList("尼古拉斯.趙四"));
        //List<Object> ages = new ArrayList<>();
        //ages.add(40);
        //form.put("age", ages);
        HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(form, headers);
        String result =
                restTemplate.postForObject(url, entity, String.class);
        System.out.println(result);
    }

(8)post請求請求體傳遞參數(shù)

    /**
     * post請求,有參數(shù)
     * 使用請求體傳遞參數(shù)。@RequestBody處理請求參數(shù)。
     *  1. 請求參數(shù)只能在請求體中,以字符串描述,且是一個完整的請求參數(shù)。此參數(shù)沒有名稱。如:JSON
     *  2. 請求頭 content-type的設(shè)置,和具體的參數(shù)值的格式相關(guān),如: JSON對應(yīng)的content-type是application/json
     *     如:xml字符串對應(yīng)的content-type是application/xml
     *  3. 請求體傳遞的參數(shù),只能由唯一的一個完整參數(shù)。可以同時攜帶表單參數(shù)和地址欄參數(shù)。
     */
    @Test
    public void testPostBodyParams(){
        String url = baseUrl + "/postBodyParams";
        // 創(chuàng)建請求參數(shù), 使用JSON格式的字符串,描述一個Map集合。
        String params = "{\"key1\":\"value1\", \"key2\":\"value2\"}";
        // 創(chuàng)建請求時,使用的請求體描述
        HttpHeaders headers = new HttpHeaders();
        headers.add("content-type", "application/json;charset=utf-8");
        HttpEntity<String> entity = new HttpEntity<>(params, headers);
        String result = restTemplate.postForObject(url, entity, String.class);
        System.out.println("返回結(jié)果:" + result);
    }
    @Test
    public void testPostBodyParams2(){
        // 可以使用簡單的處理方案,實現(xiàn)請求體傳遞JSON格式的數(shù)據(jù)
        // 使用postForObject(),第二個參數(shù),直接傳遞一個Java對象,作為請求體中傳遞的參數(shù)。
        // 參數(shù)沒有名字,由RestTemplate做數(shù)據(jù)轉(zhuǎn)換,默認使用JSON格式字符串做轉(zhuǎn)換結(jié)果。
        String url = baseUrl + "/postBodyParams";
        // 創(chuàng)建Map類型的參數(shù)對象
        Map<String, String> params = new HashMap<>();
        params.put("name", "測試");
        params.put("gender", "男");
        // 請求服務(wù)器。 直接傳遞java對象,默認請求頭content-type=application/json;charset=utf-8
        String result = restTemplate.postForObject(url, params, String.class);
        System.out.println("返回結(jié)果:" + result);
    }

(9)RestFUL傳遞參數(shù)

    /**
     * 使用get請求方式,傳遞restful參數(shù)
     */
    @Test
    public void testRestfulParams(){
        String url = baseUrl + "/restfulParams/{name}/{age}";
        // 訪問
        String result = restTemplate.getForObject(url, String.class, "restful", "15");
        System.out.println(result);
    }

(10)Exchange通用處理方案(處理相對復(fù)雜的結(jié)果類型例如自定義類型數(shù)組)

    /**
     * RestTemplate類型中的通用方法,exchange??梢蕴峤蝗我夥绞降恼埱?。
     * 且可以定義相對復(fù)雜的返回類型。如:帶有泛型要求的集合。
     *
     * <T> ResponseEntity<T> exchange(String url, HttpMethod requestMethod, HttpEntity http,
     *                                Class<T> returnType, Object... params)
     * <T> ResponseEntity<T> exchange(String url, HttpMethod requestMethod, HttpEntity http,
     *                                Class<T> returnType, Map params)
     * <T> ResponseEntity<T> exchange(String url, HttpMethod requestMethod, HttpEntity http,
     *                                ParameterizedTypeReference<T> returnType, Object... params)
     * <T> ResponseEntity<T> exchange(String url, HttpMethod requestMethod, HttpEntity http,
     *                                ParameterizedTypeReference<T> returnType, Map... params)
     */
    @Test
    public void testExchangeMethod(){
        String url = baseUrl + "/returnList?nums={1}";
        // 相對復(fù)雜的返回結(jié)果類型描述對象
        url = baseUrl + "/returnUsers?nums={1}";
        ParameterizedTypeReference<List<User>> type =
                new ParameterizedTypeReference<List<User>>() {};
        // 訪問遠程
        ResponseEntity<List<User>> entity =
                restTemplate.exchange(url, HttpMethod.GET, null, type, 3);
        List<User> body = entity.getBody();
        System.out.println(body);
    }

四、調(diào)用Application Service集群

基于RestTemplate和Ribbon實現(xiàn)Application Client調(diào)用Application Service集群

(1)編寫配置類

@Configuration
public class AppClientConfiguration {
    /**
     * 創(chuàng)建RestTemplate對象的方法,增加注解
     * LoadBalanced - 把Spring Cloud封裝的LoadBalancerClient于RestTemplate整合。
     * 讓RestTemplate自帶負載均衡能力。僅在當前的Ribbon環(huán)境中生效。
     * 邏輯是:
     *  請求  http://服務(wù)名稱/具體地址.  RestTemplate解析請求地址。
     *  把服務(wù)名稱解析出,作為參數(shù),調(diào)用LoadBalancerClient中的choose方法。
     *  把返回的ServiceInstance.getUri().toASCIIString()作為服務(wù)器地址,拼接上
     *  請求的具體地址。訪問遠程。
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

(2)發(fā)起遠程調(diào)用

@Service
public class ApplicationClientServiceImpl implements ApplicationClientService {
    @Autowired
    private RestTemplate restTemplate;
    //http://服務(wù)名
    private final String baseUrl = "http://eureka-client-app-service";
    @Override
    public String getNoParams() {
        String url = baseUrl + "/getNoParams";
        // 訪問
        String result = restTemplate.getForObject(url, String.class);
        System.out.println(result);
        return result;
    }
}

五、Ribbon負載均衡算法

Ribbon的負載均衡策略是通過不同的類型來實現(xiàn)的(都是IRule接口的實現(xiàn)),下表詳細介紹一些常用負載均衡策略及對應(yīng)的Ribbon策略類。

編號策略名稱策略對應(yīng)的類名實現(xiàn)原理
1輪詢策略(默認)RoundRobinRule輪詢策略表示每次都按照順序取下一個application service,比如一共有5個application service,第1次取第1個,第2次取第2個,第3次取第3個,以此類推
2權(quán)重輪詢策略(常用,中小型項目使用)WeightedResponseTimeRule1.根據(jù)每個application service的響應(yīng)時間分配一個權(quán)重,響應(yīng)時間越長,權(quán)重越小,被選中的可能性越低。 2.原理:一開始為輪詢策略,并開啟一個計時器,每30秒收集一次每個application service的平均響應(yīng)時間,當信息足夠時,給每個application service附上一個權(quán)重,并按權(quán)重隨機選擇application service,權(quán)重越高的application service會被高概率選中。
3隨機策略(不推薦,測試使用,開發(fā)使用)RandomRule從application service列表中隨機選擇一個
4最少并發(fā)數(shù)策略(應(yīng)用在硬件軟件環(huán)境一致的情況下,中小型項目使用)BestAvailableRule選擇正在請求中的并發(fā)數(shù)最小的application service,除非這個application service在熔斷中。
5重試策略。在“選定的負載均衡策略”基礎(chǔ)上進行重試機制RetryRule1.“選定的負載均衡策略”這個策略是輪詢策略RoundRobinRule 2.該重試策略先設(shè)定一個閾值時間段,如果在這個閾值時間段內(nèi)當選擇application service不成功,則一直嘗試采用“選定的負載均衡策略:輪詢策略”最后選擇一個可用的application service
6可用性敏感策略(一般在同區(qū)域內(nèi)服務(wù)集群環(huán)境中使用)AvailabilityFilteringRule過濾性能差的application service,有2種: 第一種:過濾掉在eureka中處于一直連接失敗application service 第二種:過濾掉高并發(fā)的application service
7區(qū)域敏感性策略(應(yīng)用在大型的,物理隔離分布式環(huán)境中)ZoneAvoidanceRule1.以一個區(qū)域為單位考察可用性,對于不可用的區(qū)域整個丟棄,從剩下區(qū)域中選可用的application service 2.如果這個ip區(qū)域內(nèi)有一個或多個實例不可達或響應(yīng)變慢,都會降低該ip區(qū)域內(nèi)其他ip被選中的權(quán)重。

指定負載均衡策略,新增Bean對象管理方法

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

到此這篇關(guān)于SpringCloud Netfilx Ribbon負載均衡工具使用方法介紹的文章就介紹到這了,更多相關(guān)SpringCloud Netfilx Ribbon內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 二叉樹遍歷特別篇之Morris遍歷

    Java 二叉樹遍歷特別篇之Morris遍歷

    二叉樹的遍歷(traversing binary tree)是指從根結(jié)點出發(fā),按照某種次序依次訪問二叉樹中所有的結(jié)點,使得每個結(jié)點被訪問依次且僅被訪問一次。四種遍歷方式分別為:先序遍歷、中序遍歷、后序遍歷、層序遍歷
    2021-11-11
  • spring boot項目打包成war在tomcat運行的全步驟

    spring boot項目打包成war在tomcat運行的全步驟

    這篇文章主要給大家介紹了關(guān)于spring boot項目打包成war在tomcat運行的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Java在Word中添加多行圖片水印

    Java在Word中添加多行圖片水印

    這篇文章主要介紹了Java在Word中添加多行圖片,圖文講解的很清晰,有對于這方面不懂得同學(xué)可以跟著研究下
    2021-02-02
  • 一個簡陋的java圖書管理系統(tǒng)

    一個簡陋的java圖書管理系統(tǒng)

    這篇文章主要為大家詳細介紹了一個簡陋的java圖書管理系統(tǒng),簡單的實現(xiàn)功能測試,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-07-07
  • java 反射機制

    java 反射機制

    本文主要介紹了java反射機制的相關(guān)知識,具有一定的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • JAVA中JSONObject對象和Map對象之間的相互轉(zhuǎn)換

    JAVA中JSONObject對象和Map對象之間的相互轉(zhuǎn)換

    這篇文章主要介紹了JAVA中JSONObject對象和Map對象之間的相互轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Java容器源碼LinkedList原理解析

    Java容器源碼LinkedList原理解析

    這篇文章主要介紹了Java容器源碼LinkedList原理解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11
  • Java并發(fā)Timer源碼分析

    Java并發(fā)Timer源碼分析

    這篇文章講述了java并發(fā)編程的相關(guān)知識點,并通過Timer源碼分析更深入的講解了java并發(fā)編程。
    2018-07-07
  • Java split()方法中的特殊符號舉例詳解

    Java split()方法中的特殊符號舉例詳解

    Java中的split方法可以將一個字符串按照指定的分隔符進行分割,返回一個字符串數(shù)組,這篇文章主要給大家介紹了關(guān)于Java split()方法中的特殊符號的相關(guān)資料,需要的朋友可以參考下
    2023-07-07
  • Java解析zip文件,并識別壓縮包里面的文件轉(zhuǎn)換成可操作的IO流方式

    Java解析zip文件,并識別壓縮包里面的文件轉(zhuǎn)換成可操作的IO流方式

    這篇文章主要介紹了Java解析zip文件,并識別壓縮包里面的文件轉(zhuǎn)換成可操作的IO流方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08

最新評論