[SpringCloud學習筆記3]SpringCloud服務調用(ribbon,openFeign)
標簽: 學習筆記 SpringCloud JAVA 分布式 java spring 其他
SpringCloud服務調用
這次學習的服務調用主要是ribbon和openFeign的應用
一、ribbon的負載均衡和RestTemplate
1.負載均衡
在調用eurake的時候,其pom文件默認幫我們調用了ribbon,所以能實現默認的輪詢方式的負載均衡功能.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-ribbon</artifactId>
<version>2.2.1.RELEASE</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
查詢ribbon源碼,其調用規則是IRule
package com.netflix.loadbalancer;
public interface IRule {
Server choose(Object var1);
void setLoadBalancer(ILoadBalancer var1);
ILoadBalancer getLoadBalancer();
}
查看其源碼可以發現其實現類
-
com.netflix.loadbalancer.RoundRobinRule 實現輪詢選擇
-
com.netflix.loadbalancer.RandomRule 實現隨機選擇
-
com.netflix.loadbalancer.RetryRule 先按照RoundRobinRule的策略獲取服務,如果獲取服務失敗則在指定時間內會進行重試
-
com.netflix.loadbalancer.WeightedResponseTimeRule 對RoundRobinRule的擴展,響應速度越快的實例選擇權重越大,越容易被選擇
-
com.netflix.loadbalancer.BestAvailableRule 會先過濾掉由于多次訪問故障而處于斷路器跳閘狀態的服務,然后選擇一個并發量最小的服務
-
com.netflix.loadbalancer.AvailabilityFilteringRule 先過濾掉故障實例,再選擇并發較小的實例
-
com.netflix.loadbalancer.ZoneAvoidanceRule 默認規則,復合判斷server所在區域的性能和server的可用性選擇服務器
默認調用的就是輪詢選擇
2.RestTemplate的方法區別
模板獲取對象方法有以下幾種
getForObject方法/getForEntity方法
postForObject/postForEntity方法
其實區別不大,就是object的返回值是json串,entitity返回的是一個帶有很多頭信息等等信息的對象
3.rule切換
1.新建子包
默認規則是輪詢,現在可以把它改成隨機,根據官網所述,不能將新的rule放入到@componetScan注解能夠掃描到的地方,所以先新建一個包.
2.新建一個Myrule類
@Component
public class MyRule {
@Bean
public IRule randomRule() {
return new RandomRule();
}
}
3.在主方法上聲明調用
//必須指定name和configuration
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MyRule.class)
4.輪詢算法源碼探究
輪詢算法底層還是挺簡單的,就是用CAS和一個循環.
源碼分析如下:
public class RoundRobinRule extends AbstractLoadBalancerRule {
//聲明一個AtomicInteger類
private AtomicInteger nextServerCyclicCounter;
private static final boolean AVAILABLE_ONLY_SERVERS = true;
private static final boolean ALL_SERVERS = false;
private static Logger log = LoggerFactory.getLogger(RoundRobinRule.class);
//初始化AtomicInteger參數為0
public RoundRobinRule() {
this.nextServerCyclicCounter = new AtomicInteger(0);
}
//初始化ILoadBalancer
public RoundRobinRule(ILoadBalancer lb) {
this();
this.setLoadBalancer(lb);
}
public Server choose(ILoadBalancer lb, Object key) {
//如果為空,那就提示沒有ILoadBalancer
if (lb == null) {
log.warn("no load balancer");
return null;
} else {
//如果ILoadBalancer非空,就開始計數
Server server = null;
int count = 0;
//開啟一個循環
while(true) {
//默認是10次為上限,每次重啟都會重置count
if (server == null && count++ < 10) {
//獲取所有可用的服務器
List<Server> reachableServers = lb.getReachableServers();
//獲取所有服務器
List<Server> allServers = lb.getAllServers();
//獲取所有可用的服務器數量
int upCount = reachableServers.size();
//獲取所有服務器數量
int serverCount = allServers.size();
if (upCount != 0 && serverCount != 0) {
//調用下面的incrementAndGetModulo函數來選擇幾號服務器
int nextServerIndex = this.incrementAndGetModulo(serverCount);
//調用對應編號服務器
server = (Server)allServers.get(nextServerIndex);
if (server == null) {
Thread.yield();
} else {
if (server.isAlive() && server.isReadyToServe()) {
//如果可以用就返回
return server;
}
server = null;
}
continue;
}
log.warn("No up servers available from load balancer: " + lb);
return null;
}
if (count >= 10) {
log.warn("No available alive servers after 10 tries from load balancer: " + lb);
}
return server;
}
}
}
//核心算法
private int incrementAndGetModulo(int modulo) {
//初始化參數,傳入modulo為總數
int current;
int next;
//每次用一次就+1%總數
do {
current = this.nextServerCyclicCounter.get();
next = (current + 1) % modulo;
} while(!this.nextServerCyclicCounter.compareAndSet(current, next));
//返回服務器編號
return next;
}
public Server choose(Object key) {
return this.choose(this.getLoadBalancer(), key);
}
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
二、openFeign的入門
Declarative REST Client: Feign creates a dynamic implementation of an interface decorated with JAX-RS or Spring MVC annotations
Feign是一個聲明式的web服務客戶端,讓編寫web服務客戶端變得非常容易,只需創建一個接口并在接口上添加注解即可
1.openFeign服務調用
1.修改pom
<!--openfeign里面引入了ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.編寫appliciation.yml
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/
3.編寫主方法
@SpringBootApplication
//開啟openfeign
@EnableFeignClients
public class FeignOrderMain80 {
public static void main(String[] args) {
SpringApplication.run(FeignOrderMain80.class,args);
}
}
4.開啟feign注解的接口服務
@Component
@FeignClient(name = "CLOUD-PAYMENT-SERVICE")
public interface FeignOrderService {
@GetMapping("/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) ;
}
5.控制層編寫
@RestController
@Slf4j
public class FeignPaymentController {
@Resource
FeignOrderService feignOrderService;
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
return feignOrderService.getPaymentById(id);
}
}
2.openFeign的超時控制
默認情況下,如果業務不在一秒內完成就會報出timeout的錯誤
There was an unexpected error (type=Internal Server Error, status=500).
Read timed out executing GET http://CLOUD-PAYMENT-SERVICE/payment/timeout
feign.RetryableException: Read timed out executing GET http://CLOUD-PAYMENT-SERVICE/payment/timeout
由于整合了ribbon,可以直接在yaml文件中進行修改
ribbon:
ReadTimeout: 5000
ConnectTimeout: 5000
3.日志增強
1.新建配置類
@Configuration
public class MyFeignConfig {
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
2.改寫Yml文件
logging:
level:
#以什么級別監視哪個接口
com.xiaoxiao.springcloud.service.FeignOrderService: debug
智能推薦
SpringCloud負載均衡和服務調用之【Ribbon、OpenFeign】
Ribbon(停更進維) 主要功能是提供客戶端的軟件負載均衡算法和服務調用(RestTemplate) 在Eureka的依賴下,已經自動引入了ribbon的依賴,默認實現了輪詢的負載均衡 更改Ribbon的負載規則為隨機 原理就是自定義一個類,實現IRule接口。官網明確提出自定義的配置類不能放在@ComponentScan所掃描的當前包及子包下,否則我們自定義的這個配置類就會被所有的Ribbon...
SpringCloud(H版&alibaba)筆記(四)-Ribbon、OpenFeign 負載均衡服務調用
目錄 一、Ribbon是什么 1.1 LB的分類: 二、再說一次RestTemplate 2.1 getForObject 方法與 getForEntity方法 三、 Ribbon負載均衡架構: 3.1 Ribbon在工作時分成兩步: 3.2 IRule繼承關系 四、代碼演示負載均衡 4.1 替換 4.2 Ribbon負載均衡算法: 4.3 根據RoundRobinRule輪詢的源碼進行編寫 五、...
SpringCloud框架學習筆記(三)-- Ribbon負載均衡服務調用
是什么? 總結:Ribbon其實就是一個軟負載均衡的客戶端組件,它可以和其他所需請求的客戶端結合使用,和eureka結合只是其中的一個實例 能干嗎? 負載均衡概念 Ribbon的工作 Ribbon演示: 首先在之前演示的時候,我們已經看到有輪詢的效果,這是因為eureka中已經集成了ribbon: RestTemplate的使用: Irule負載均衡算法 自帶的負載均衡算法: 修改8010的負載均...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
猜你喜歡
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...