SpringCloud系列(23)--手寫實現負載輪詢算法

前言:在上一篇文章中我們介紹了關于負載輪詢算法的原理以及看了源代碼,而本章節內容則是著重于我們自己手寫一個負載輪詢算法

1、分別編寫provider-payment8001、provider-payment8002這兩個子項目的PaymentController類,增加一個/payment/lb接口

provider-payment8001

package com.ken.springcloud.controller;import com.ken.springcloud.entities.CommonResult;
import com.ken.springcloud.entities.Payment;
import com.ken.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import java.util.List;@RestController
@Slf4j
public class PaymentController {@Resourceprivate PaymentService paymentService;@Value("${server.port}")private String serverPort;@Resourceprivate DiscoveryClient discoveryClient;@PostMapping("/payment/insert")public CommonResult insert(@RequestBody Payment payment) {int result = paymentService.insert(payment);log.info("插入結果{}",result);if(result > 0) {return new CommonResult(200,"插入數據庫成功,提供服務的端口號為" + serverPort,result);}else {return new CommonResult(500,"插入數據庫失敗",result);}}@GetMapping("/payment/get/{id}")public CommonResult insert(@PathVariable("id") Long id) {Payment payment = paymentService.getPaymentById(id);log.info("查詢結果{}",payment);if(payment != null) {return new CommonResult(200,"查詢成功,提供服務的端口號為" + serverPort,payment);}else {return new CommonResult(500,"沒有對應的數據,查詢失敗,查詢id" + id,payment);}}@GetMapping("/payment/discovery")public Object discovery() {//獲取eureka內的服務List<String> services = discoveryClient.getServices();for (String service : services) {log.info("***service:" + service);}//獲取服務名為CLOUD-PAYMENT-SERVICE下的實例List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");for (ServiceInstance instance : instances) {log.info(instance.getServiceId()+"\t"+instance.getHost()+"\t"+instance.getPort()+"\t"+instance.getUri());}return this.discoveryClient;}@GetMapping("/payment/lb")public String getPaymentLB() {//返回當前服務的端口號return serverPort;}}

provider-payment8002?

package com.ken.springcloud.controller;import com.ken.springcloud.entities.CommonResult;
import com.ken.springcloud.entities.Payment;
import com.ken.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;@RestController
@Slf4j
public class PaymentController {@Resourceprivate PaymentService paymentService;@Value("${server.port}")private String serverPort;@PostMapping("/payment/insert")public CommonResult insert(@RequestBody Payment payment) {int result = paymentService.insert(payment);log.info("插入結果{}",result);if(result > 0) {return new CommonResult(200,"插入數據庫成功,提供服務的端口號為" + serverPort,result);}else {return new CommonResult(500,"插入數據庫失敗",result);}}@GetMapping("/payment/get/{id}")public CommonResult insert(@PathVariable("id") Long id) {Payment payment = paymentService.getPaymentById(id);log.info("查詢結果{}",payment);if(payment != null) {return new CommonResult(200,"查詢成功,提供服務的端口號為" + serverPort,payment);}else {return new CommonResult(500,"沒有對應的數據,查詢失敗,查詢id" + id,payment);}}@GetMapping("/payment/lb")public String getPaymentLB() {//返回當前服務的端口號return serverPort;}}

2、在com.ken.springcloud包下新建名為lb的包,用于存儲負載均衡相關的代碼?

效果圖:

3、在lb包下新建一個名為LoadBalancer的接口類

效果圖:

4、編寫LoadBalancer接口類
package com.ken.springcloud.lb;import org.springframework.cloud.client.ServiceInstance;import java.util.List;public interface LoadBalancer {ServiceInstance instances(List<ServiceInstance> sserviceINstances);}

5、在lb包下新建一個名為MyBL的類

效果圖:

6、編寫MyLB類,使其實現LoadBalancer接口類
package com.ken.springcloud.lb;import org.springframework.cloud.client.ServiceInstance;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;@Component
public class MyLB implements LoadBalancer{private AtomicInteger atomicInteger = new AtomicInteger(0);/*** 獲取當前是第幾次的請求* @return*/public final int getAndIncrement() {//atomicInteger的期望值int current;int next;do {current = this.atomicInteger.get();next = current >= Integer.MAX_VALUE ? 0 : current + 1;}while (!this.atomicInteger.compareAndSet(current,next));//比較atomicInteger對象當前的值和期望值current,如果atomicInteger對象當前的值和期望值current相同,則把atomicInteger對象當前的值修改為next,并返回trueSystem.out.println("next:" + next);return next;}@Overridepublic ServiceInstance instances(List<ServiceInstance> serviceInstances) {//通過請求數模以提供服務的服務數獲取需要提供服務的服務實例下標int index = getAndIncrement() % serviceInstances.size();//返回提供服務的服務實例return serviceInstances.get(index);}
}

7、編寫consumer-order80這個子項目的OrderController類,增加一個/payment/lb接口
package com.ken.springcloud.controller;import com.ken.springcloud.entities.CommonResult;
import com.ken.springcloud.entities.Payment;
import com.ken.springcloud.lb.LoadBalancer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;
import java.net.URI;
import java.util.List;@RestController
@Slf4j
public class OrderController {//public static final String PAYMENT_URL = "http://localhost:8001";public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";@Resourceprivate RestTemplate restTemplate;@Resourceprivate LoadBalancer loadBalancer;@Resourceprivate DiscoveryClient discoveryClient;@PostMapping("/consumer/insert")public CommonResult<Payment> insert(Payment payment) {log.info("payment:{}",payment);return restTemplate.postForObject(PAYMENT_URL + "/payment/insert",payment,CommonResult.class);}/*** 返回對象為響應體中數據轉化成的對象,基本上可以理解為Json* @param id* @return*/@GetMapping("/consumer/get/{id}")public CommonResult<Payment> getPayment(@PathVariable("id") Long id) {return restTemplate.getForObject(PAYMENT_URL + "/payment/get/" + id,CommonResult.class);}/*** 返回對象為ResponseEntity對象,包含了響應中的一些重要信息,比如響應頭、響應狀態碼、響應體等* @param id* @return*/@GetMapping("/consumer/getForEntity/{id}")public CommonResult<Payment> getPayment2(@PathVariable("id") Long id) {ResponseEntity<CommonResult> entity =  restTemplate.getForEntity(PAYMENT_URL + "/payment/get/" + id,CommonResult.class);if(entity.getStatusCode().is2xxSuccessful()) {return entity.getBody();}else {return new CommonResult<>(500,"異常");}}@GetMapping("/consumer/payment/lb")public String getPaymentLB() {//獲取服務名為CLOUD-PAYMENT-SERVICE下的實例List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");if (instances == null || instances.size() <= 0) {return null;}//獲取提供接口服務的服務實例ServiceInstance serviceInstance = loadBalancer.instances(instances);//獲取接口地址URI uri = serviceInstance.getUri();//請求服務接口return restTemplate.getForObject(uri + "/payment/lb",String.class);}}

8、分別啟動eureka-server7001、eureka-server7002、provider-payment8001、provider-payment8002、consumer-order80,然后在瀏覽器地址欄輸入
http://localhost/consumer/payment/lb?并回車調用接口,可以看到接口調用成功,并會按照預想的那樣輪詢地分別訪問provider-payment8001和provider-payment8002服務

效果圖:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/14771.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/14771.shtml
英文地址,請注明出處:http://en.pswp.cn/web/14771.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++中引用的全面解析與實戰應用

C中的引用作為一種強大的特性&#xff0c;不僅能夠提升代碼的效率和清晰度&#xff0c;還能在一定程度上保障數據的安全性。本文將深入探討引用的各個方面&#xff0c;包括其定義、使用場景、類型、與指針的區別&#xff0c;并通過實例加以說明。 引用的定義與基本概念 引用可…

探究Python中的元組:不可變性與多重用途

元組是 Python 中的另一種重要數據結構&#xff0c;與列表相似&#xff0c;但具有一些關鍵區別。讓我們來詳細了解一下 Python 中的元組&#xff0c;包括基本語法、常用命令、示例代碼、應用場景、注意事項和總結。 基本語法 創建元組 在 Python 中&#xff0c;元組使用圓括…

Py之llama-parse:llama-parse(高效解析和表示文件)的簡介、安裝和使用方法、案例應用之詳細攻略

Py之llama-parse&#xff1a;llama-parse(高效解析和表示文件)的簡介、安裝和使用方法、案例應用之詳細攻略 目錄 llama-parse的簡介 llama-parse的安裝和使用方法 1、安裝 2、使用方法 第一步&#xff0c;獲取API 密鑰 第二步&#xff0c;安裝LlamaIndex、LlamaParse L…

AI爆文寫作:經常做這四個小練習,讓你解鎖爆文標題的秘籍,讓你的標題炸裂吸晴!

文章目錄 一、無法吸引眼球的標題二、標題炸裂的秘籍練習1:洞察受眾的渴望與恐懼。練習2:運用感官語言,用生動的描述和具體細節,在讀者心中勾勒出一幅畫面。練習3:展示變化。練習4:用意外轉折激發好奇心。一、無法吸引眼球的標題 這樣的標題: [如何通過閱讀改變人生」「…

LeetCode 1542.找出最長的超贊子字符串:前綴異或和(位運算)

【LetMeFly】1542.找出最長的超贊子字符串&#xff1a;前綴異或和&#xff08;位運算&#xff09; 力扣題目鏈接&#xff1a;https://leetcode.cn/problems/find-longest-awesome-substring/ 給你一個字符串 s 。請返回 s 中最長的 超贊子字符串 的長度。 「超贊子字符串」需…

<string.h>中部分庫函數的模擬實現

前言 嗨&#xff0c;我是firdawn&#xff0c;本章將簡單介紹&#xff0c;<string.h>中部分庫函數的模擬實現&#xff0c;如strncpy&#xff0c;strncat&#xff0c;memcpy&#xff0c;memmove。在本文片末&#xff0c;還講簡單介紹判斷機器大小端的函數實現&#xff0c;…

VSCode SAP Systems配置HTTPS訪問SAP

第一次訪問提示&#xff0c;Self-Signed 證書 解決辦法&#xff1a;https訪問SAP Fiori網站&#xff0c;導出SSL證書為DER格式保存到硬盤上 雙擊DER文件&#xff0c;導入到系統 退出VSCode&#xff0c;再次啟動 Test Connection, 提示 The system URL is using a hostname …

服務器攻防-中間件安全,weblogic(沒怎么搞懂)

1.weblogic-工具 jboss 1.弱口令 直接輸入admin就就去了 2.反序列化&#xff08;不是很懂java) jenkins glassfish 讀密碼文件 讀取 就可以知道它的密碼 我們就可以寫腳本

使用DataGrip連接跳板機后再連接遠程服務器的mysql數據庫

相比配置本地數據庫就是多了一步SSH/SSL配置。 添加新的mysql連接&#xff0c;選擇SSH/SSL&#xff0c;勾選Use SSH tunnel&#xff1a; 點擊右邊的…配置跳板機連接&#xff0c;輸入賬號密碼&#xff0c;然后保存&#xff1a; 接著配置General&#xff0c;里面填上要連接的數…

一款數字化管理平臺源碼:云MES系統(附架構圖、流程)技術架構:springboot + vue-element-plus-admin

制造生產企業打造數字化生產管控的系統&#xff0c;從原材料、生產報工、生產過程、質檢、設備、倉庫等整個業務流程的管理和控制&#xff0c;合理安排生產計劃、實時監控生產、優化生產工藝、降低不良產出和運營成本&#xff1b; 技術架構&#xff1a;springboot vue-elemen…

DHT11獲取數據傳輸到PC端

1.DHT11的時序數據 a : dht 1 b &#xff1a;dht 0延時30ms c&#xff1a; dht 1 卡d點&#xff1b;while(dht1); 卡e點 while(!dht) 卡f點&#xff1a;while(dht) 卡g點&#xff1a;while(!dht) 有效數據都是高電平&#xff0c;持續時間不一樣&#xff0c;50us讀&#…

Go語言實現人臉檢測(Go的OpenCV綁定庫)

文章目錄 OpenCVGithub官網安裝環境變量 Go的OpenCV綁定庫Github文檔安裝搜索視頻設備ID顯示視頻檢測人臉 OpenCV Github https://github.com/opencv/opencv/ 官網 https://opencv.org/ 安裝 brew install opencv brew upgrade opencv安裝目錄 cd /usr/local/opt/opencv…

子比主題ACG美化插件[全開源]

WordPress插件是一種可以擴展和增強WordPress網站功能的應用程序。子比主題ACG美化插件聽起來像是一個專門為ACG&#xff08;動畫、漫畫、游戲&#xff09;愛好者設計的美化插件&#xff0c;它可能包含多種功能來改善網站的外觀和用戶體驗。 內置功能開關100意味著這個插件提供…

基于CNN卷積神經網絡的金融數據預測matlab仿真,對比BP,RBF,LSTM

目錄 1.程序功能描述 2.測試軟件版本以及運行結果展示 3.核心程序 4.本算法原理 4.1 反向傳播網絡&#xff08;BP&#xff0c;多層感知器MLP&#xff09; 4.2 徑向基函數網絡&#xff08;RBF&#xff09; 4.3 卷積神經網絡&#xff08;CNN&#xff09; 4.4 長短期記憶網…

六(1)、RTKLIB源碼解析 — rnx2rtkp.c

目錄 一、前言 二、main中的參數說明 三、main中的代碼解讀 3.1 總體邏輯框架

計算機網絡套接字知識(非常詳細)從零基礎入門到精通

本節重點 認識IP地址, 端口號, 網絡字節序等網絡編程中的基本概念; 學習socket api的基本用法; 一、預備知識 1.理解源IP地址和目的IP地址 ?在IP數據包頭部中&#xff0c;有兩個IP地址&#xff0c;分別叫做源IP地址和目的IP地址。 思考: 我們光有IP地址就可以完成通信了…

Kotlin Flow應用舉例,launchIn 和collect用法及區別

launchIn 和 collect 都可以用于處理 MutableStateFlow<Message> 消息流&#xff0c;但它們有不同的用途和使用場景。 collect 用于在協程中收集消息流的最新值。它會一直監聽消息流&#xff0c;并在每次消息流的值發生變化時執行指定的代碼塊。 launchIn 用于在協程作…

【30天精通Prometheus:一站式監控實戰指南】第7天:postgres_exporter從入門到實戰:安裝、配置詳解與生產環境搭建指南,超詳細

親愛的讀者們&#x1f44b; ??歡迎加入【30天精通Prometheus】專欄&#xff01;&#x1f4da; 在這里&#xff0c;我們將探索Prometheus的強大功能&#xff0c;并將其應用于實際監控中。這個專欄都將為你提供寶貴的實戰經驗。&#x1f680; ??Prometheus是云原生和DevOps的…

Java基礎之異常(簡單易懂)

異常 1.JAVA異常體系 &#xff08;1&#xff09;Throwable類(表示可拋)是所有異常和錯誤的超類&#xff0c;兩個直接子類為Error和Exception,分別表示錯誤和異常;其中異常類Exception又分為運行時異常和非運行時異常&#xff0c;這兩個異常有很大區別&#xff0c;運行時異常也…

代碼隨想錄算法訓練營第三十一天| 貪心算法理論基礎、LeetCode455.分發餅干、LeetCode376. 擺動序列 、LeetCode53. 最大子序和

貪心算法理論基礎&#xff1a; 貪心算法沒有類似遞歸、回溯的套路。主要的思想可以理解為&#xff1a;用局部最優找全局最優。 #LeetCode 455. Assign Cookies #LeetCode 455. 視頻講解&#xff1a;貪心算法&#xff0c;你想先喂哪個小孩&#xff1f;| LeetCode&#xff1a;4…