Spring Cloud Ribbon
是一個基于Http
和TCP
的客戶端負載均衡工具,基于Netflix Ribbon
實現(xiàn)的盹憎。它不像服務(wù)注冊中心况褪、配置中心碎绎、API網(wǎng)關(guān)那樣獨立部署寒砖,但是它幾乎存在于每個微服務(wù)的基礎(chǔ)設(shè)施中逗宁。
Ribbon架構(gòu)圖
Ribbon負載均衡策略
Ribbon
默認的策略是輪詢凄杯,我們可以自定義負載策略來覆蓋默認的错洁,當(dāng)然也可以通過配置指定使用哪些策略。
負載均衡概念
負載均衡技術(shù)在現(xiàn)有網(wǎng)絡(luò)結(jié)構(gòu)之上提供了一種廉價戒突、有效屯碴、透明的方法,來擴展網(wǎng)絡(luò)設(shè)備和服務(wù)器的帶寬膊存、增加吞吐量导而、加強網(wǎng)絡(luò)數(shù)據(jù)處理能力、提高網(wǎng)絡(luò)的靈活性和可用性隔崎。它有兩方面的含義:首先今艺,大量的并發(fā)訪問或數(shù)據(jù)流量分擔(dān)到多臺節(jié)點設(shè)備上分別處理,減少用戶等待響應(yīng)的時間爵卒;其次虚缎,單個重負載的運算分擔(dān)到多臺節(jié)點設(shè)備上做并行處理,每個節(jié)點設(shè)備處理結(jié)束后钓株,將結(jié)果匯總实牡,返回給用戶陌僵,系統(tǒng)處理能力得到大幅度提高。
負載均衡是對系統(tǒng)的高可用创坞,網(wǎng)絡(luò)壓力的緩解和處理能力擴容的重要手段之一碗短。
硬件負載均衡:
主要通過在服務(wù)節(jié)點之間安裝專門的負載均衡設(shè)備,比如F5
詳細參照百度百科:https://baike.baidu.com/item/F5%E6%96%B9%E6%A1%88/1121377?fr=aladdin
軟件負載均衡
實現(xiàn)方式有兩種题涨,分別是服務(wù)端的負載均衡和客戶端的負載均衡
服務(wù)端負載均衡:在服務(wù)端安裝一些具有均衡負載功能或者模塊的軟件來完成請求的分發(fā)工作偎谁,比如Nginx
。
當(dāng)瀏覽器向后臺發(fā)出請求的時候纲堵,會首先向反向代理服務(wù)器發(fā)送請求巡雨,反向代理服務(wù)器會根據(jù)客戶端部署的ip:port
映射表以及負載均衡策略,來決定向哪臺服務(wù)器發(fā)送請求席函,一般會使用到nginx
反向代理技術(shù)鸯隅。
客戶端負載均衡:當(dāng)瀏覽器向后臺發(fā)出請求的時候,客戶端會向服務(wù)注冊器(例如Eureka Server
)向挖,拉取注冊到服務(wù)器的可用服務(wù)信息,然后根據(jù)負載均衡策略炕舵,直接命中哪臺服務(wù)器發(fā)送請求何之。這整個過程都是在客戶端完成的,并不需要反向代理服務(wù)器的參與咽筋。
在微服務(wù)中最基本的兩個角色是服務(wù)提供者與服務(wù)消費者溶推。
服務(wù)提供者:服務(wù)的被調(diào)用方(為其他服務(wù)提供服務(wù)的服務(wù))
服務(wù)消費者:服務(wù)的調(diào)用方(依賴其他服務(wù)的服務(wù))
之前我們已經(jīng)嘗試了好幾種服務(wù)注冊方式,注冊了服務(wù)奸攻,肯定需要被調(diào)用的蒜危,也就是消費。
服務(wù)調(diào)用方式實現(xiàn)方式RestTemplate+Ribbon
使用RestTemplate
消費SpringBoot
的Restful
服務(wù)
前提
需要一個服務(wù)注冊中心睹耐,兩個服務(wù)提供者和一個消費者
因為只有兩個以上的服務(wù)提供者提供相同的服務(wù)才可以體現(xiàn)出負載均衡
服務(wù)注冊中心和服務(wù)提供者都使用Spring Cloud Eureka
實現(xiàn)服務(wù)提供者的Restful接口
之前已經(jīng)實現(xiàn)過服務(wù)注冊中心和服務(wù)提供者
不過之前的服務(wù)提供者并沒有提供接口給消費者使用
@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()+" 對應(yīng)的端口號 :"+ip;
System.out.println("調(diào)用的服務(wù)是: " + discoveryClient.getServices()+" 對應(yīng)的端口號 :"+ip);
return services;
}
}
實現(xiàn)服務(wù)消費者Ribbon
一開始肯定打算是引入Spring Cloud Ribbon
依賴辐赞,不過Spring Cloud Eureka
依賴中已經(jīng)有
Ribbon
的依賴了。單獨引入Ribbon
依賴可能注冊不了服務(wù)
在項目的外部
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>
在項目啟動類上添加@EnableEurekaClient
注解响委,消費者和服務(wù)提供者一樣,都需要到注冊中心中注冊
并且使用@bean
像Spring
容器中注入一個restTemplate
對象窖梁,@LoadBalanced
注解表明這個
restRemplate
開啟負載均衡的功能赘风。
@SpringBootApplication
@EnableEurekaClient
public class SpringcloudConsumerRibbonApplication {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(SpringcloudConsumerRibbonApplication.class, args);
}
}
下面來寫一個簡單的服務(wù)消費類
@RestController
public class RibbonController {
@Autowired
RestTemplate restTemplate;
@GetMapping("/consumer")
public String getMsg() {
return restTemplate.getForObject("http://springcloud-eureka-client/client", String.class);
}
}
restTemplate
可以發(fā)送Get
,Post
纵刘,Put
邀窃,Delete
等請求
Get
調(diào)用getForEntity()
方法
Post
調(diào)用postForObject()
方法
Put
調(diào)用put()
方法
Delete
調(diào)用delete()
方法
getForEntity
的第一個參數(shù)為我要調(diào)用的服務(wù)的地址,這里我調(diào)用了服務(wù)提供者提供的
/client
接口(Eureka
客戶端中已寫好)假哎,getForEntity
第二個參數(shù)String.class
表示我希望返回的body
類型是String
注意這里是通過服務(wù)名調(diào)用而不是服務(wù)地址瞬捕,如果寫成服務(wù)地址就沒法實現(xiàn)客戶端負載均衡了鞍历。
調(diào)用spring boot
服務(wù)的時候,需要將服務(wù)的URL
寫死或者是寫在配置文件中,一旦ip
地址發(fā)生了變化山析,都需要改動程序堰燎,并重新部署服務(wù),使用Ribbon
的時候笋轨,可以有效的避免這個問題秆剪。
restTemplate
的所有用法可以參考
官方說明文檔: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
整體項目結(jié)構(gòu)
Eureka服務(wù)端 端口號是9090
兩個Eureka客戶端 端口號分別是8081
和8082
相同的服務(wù)名springcloud-eureka-client
Ribbon消費者客戶端 端口號是9999
啟動服務(wù)進行測試
先啟動服務(wù)端再啟動客戶端,客戶端啟動順序沒要求
訪問http://localhost:9090服務(wù)注冊中心
在服務(wù)注冊中心可以看到爵政,服務(wù)提供者和消費者都注冊好了
對服務(wù)提供者的Restful
服務(wù)進行消費
訪問http://localhost:9999/consumer可以看到消費的服務(wù)名和端口
刷新下頁面
繼續(xù)刷新就調(diào)用另一個端口的服務(wù)了
我試著刷新了11次頁面仅讽,在控制臺可以看到調(diào)用情況
說明已經(jīng)消費了Eureka
客戶端提供的服務(wù),而且Ribbon
已經(jīng)默認實現(xiàn)了負載均衡
在整個程序中钾挟,最關(guān)鍵的就是在RestTemplate上標記的@LoadBalanced
注解洁灵,Spring Cloud Ribbon
通過注解@LoadBalanced
來實現(xiàn)負載均衡
深入了解@LoadBalanced
注解可以參考:
https://blog.csdn.net/qq_26562641/article/details/53332269