1.首先配置Ribbon
Spring Cloud Ribbon是一個基於HTTP和TCP的客戶端負載均衡工具,它基於Netflix Ribbon實現。通過Spring Cloud的封裝,可以讓我們輕鬆地將面向服務的REST模版請求自動轉換成客戶端負載均衡的服務調用。Spring Cloud Ribbon雖然只是一個工具類框架,它不像服務註冊中心、配置中心、API網關那樣需要獨立部署,但是它幾乎存在於每一個Spring Cloud構建的微服務和基礎設施中。因爲微服務間的調用,API網關的請求轉發等內容,實際上都是通過Ribbon來實現的,包括後續我們將要介紹的Feign,它也是基於Ribbon實現的工具。所以,對Spring Cloud Ribbon的理解和使用,對於我們使用Spring Cloud來構建微服務非常重要。
配置Ribbon非常簡單,只需要在引導類中添加@LoadBalance就可以了
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
public class ServiceCustomerApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceCustomerApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
LoadBalance默認是計數器,循環去調用生產者,如果需要改配置改成隨機的就需要在application.yml配置中添加
service-provider:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
然後配置hystrix
Hystrix,英文意思是豪豬,全身是刺,看起來就不好惹,是一種保護機制。
Hystrix也是Netflix公司的一款組件。
主頁:https://github.com/Netflix/Hystrix/
那麼Hystix的作用是什麼呢?具體要保護什麼呢?
Hystix是Netflix開源的一個延遲和容錯庫,用於隔離訪問遠程服務、第三方庫,防止出現級聯失敗。
1.
服務降級:優先保證核心服務,而非核心服務不可用或弱可用。
用戶的請求故障時,不會被阻塞,更不會無休止的等待或者看到系統崩潰,至少可以看到一個執行結果(例如返回友好的提示信息) 。
服務降級雖然會導致請求失敗,但是不會導致阻塞,而且最多會影響這個依賴服務對應的線程池中的資源,對其它服務沒有響應。
觸發Hystix服務降級的情況:
- 線程池已滿
- 請求超時
下面就來配置一下hystrix(需要在消費者端配置)
首先引入啓動器
在pom.xml中引入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
然後在引導類中添加EnableCirCuitBreaker
這裏可以使用@SpringCloudApplication代替(@SpringBootApplication+@EnableDiscoveryClient+@EnableCircuitBreaker)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class ServiceCustomerApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceCustomerApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
然後配置需要設置負載均衡的類
package com.w.service.controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.w.service.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@Controller
@RequestMapping("/customer/user")
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("{id}")
@ResponseBody
@HystrixCommand(fallbackMethod = "findCallBack")
public String findById(@PathVariable("id") Integer id) {
return restTemplate.getForObject("http://service-provider/user/" + id, String.class);
}
public String findCallBack(Integer id){
return "服務器列表繁忙。。。";
}
}
這個方法爲局部方法,如果想把所有的方法都添加上,需要在類上添加註解@DefaultProperties(defaultFallback = "熔斷方法名稱"),同時這個方法必須爲無參數方法
package com.w.service.controller;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.w.service.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@Controller
@RequestMapping("/customer/user")
@DefaultProperties(defaultFallback = "findCallBack")
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("{id}")
@ResponseBody
@HystrixCommand
public String findById(@PathVariable("id") Integer id) {
return restTemplate.getForObject("http://service-provider/user/" + id, String.class);
}
public String findCallBack(){
return "服務器列表繁忙。。。";
}
}
同時可以設置超時時間
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 6000 # 設置hystrix的超時時間爲6000ms
2服務熔斷
2.1熔斷原理
熔斷器,也叫斷路器,其英文單詞爲:Circuit Breaker
熔斷狀態機3個狀態:
- Closed:關閉狀態,所有請求都正常訪問。
- Open:打開狀態,所有請求都會被降級。Hystix會對請求情況計數,當一定時間內失敗請求百分比達到閾值,則觸發熔斷,斷路器會完全打開。默認失敗比例的閾值是50%,請求次數最少不低於20次。
- Half Open:半開狀態,open狀態不是永久的,打開後會進入休眠時間(默認是5S)。隨後斷路器會自動進入半開狀態。此時會釋放部分請求通過,若這些請求都是健康的,則會完全關閉斷路器,否則繼續保持打開,再次進行休眠計時