1. 程式人生 > >13.Spring-Cloud-Feign中配置Ribbon和Hystrix

13.Spring-Cloud-Feign中配置Ribbon和Hystrix

feign中對ribbon的配置

主要是在ribbon-core.jar檔案下,com.netflix.client.config包下,其中DefaultClientConfigImpl類為預設配置
配置客戶端和負載均衡器的最簡單方法是符合特定格式的屬性:
<clientName>.<namespace>.< propertyName > = <value>
可以在類路徑或作為系統屬性的檔案中定義屬性
預設情況下,“ribbon”應該是namespace。
如果沒有為指定的客戶端指定屬性,com.netflix.client.ClientFactory仍然會為所有必需的屬性建立客戶端和負載均衡器。預設值在這個類中指定為常量。
如果一個屬性丟失了clientName,那麼它將被解釋為一個適用於所有客戶端的屬性。例如
ribbon.ReadTimeout = 1000
這將為所有客戶端建立預設的ReadTimeout屬性。
您還可以通過構造DefaultClientConfigImpl的例項來程式設計設定屬性。
如果希望在不同的名稱空間中定義屬性,例如“foo”
myclient.foo.ReadTimeout = 1000

feign中對hystrix的配置

在對hystrix進行配置之前首先要確認feign.hystrix.enabled引數設定為true(開起Hystrix熔斷器保護),否則引數設定會關閉Feign客戶端的hystrix,其主要的配置是對HystrixCommand的配置,是在hystrix-core.jar檔案下com.netflix.hystrix.HystrixCommandProperties類中,如下截圖為某些引數配置

如配置全域性的超時時間:

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000//預設為1000ms即1s

服務呼叫者

   改造服務呼叫者

    controller


/**執行緒睡眠主要演示ribbon的服務重試機制,當超過消費者配置的連線超時時,進行第二次重連

* 不接收引數
* @return
* @throws InterruptedException 
*/
@SuppressWarnings("deprecation")
@RequestMapping(value = "/hello1", method = RequestMethod.GET)
public String hello() throws InterruptedException {
ServiceInstance instance = client.getLocalServiceInstance();
logger.info("/hello1,host:{},service_id:{}",instance.getHost(),instance.getServiceId());
//測試超時 
int sleep = new Random().nextInt(3000);
logger.info("sleep time:{}",sleep);
Thread.sleep(sleep);
return "hello spring cloud";
}


   啟動類服務消費者


package com.niugang;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

/**
 * feign版消費者
 * 
 * @author niugang
 *
 */
@SpringBootApplication
@EnableDiscoveryClient
//掃描宣告它們是feign客戶端的介面(通過@FeignClient)
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

   配置

#指定微服務的名稱後續在呼叫的時候只需要使用該名稱就可以進行服務的訪問
spring.application.name=feign-consumer
server.port=9001
#註冊中心地址
eureka.client.serviceUrl.defaultZone=http://testhost:8000/eureka/


#######################ribbon配置############################
#ribbon,制定服務配置,service-provide服務名
service-provide.ribbon.ConnectTimeout=500
service-provide.ribbon.ReadTimeout=2000
service-provide.OkToRetryOnAllOperations=true
#重試策略先嚐試訪問首選例項一次
service-provide.ribbon.MaxAutoRetries=1
#嘗試更換兩次例項進行重試
service-provide.ribbon.MaxAutoRetriesNextServer=2
#####################hystrix配置##############################
#開起feign客戶端的Hystrix支援,即開起熔斷器
feign.hystrix.enabled=true

   呼叫服務介面


package com.niugang.service;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.niugang.entity.User;
import com.niugang.fallback.ServiceProvideFallBack;
/**
 * 定義服務繫結介面
 *
 */
//宣告呼叫的服務
//value:呼叫服務的名
//fallback:配置服務降級類
@FeignClient(value="service-provide",fallback=ServiceProvideFallBack.class)
public interface ServiceProvide {
/**
* 呼叫服務的路徑,不傳引數
* @return
*/
    @RequestMapping(value="/hello1",method = RequestMethod.GET)
String  hello1();
    /**
     * 
     * 傳遞一個引數
     */
    @RequestMapping(value="/hello2",method = RequestMethod.GET)
    //@RequestParam裡面一定要寫引數名,否則讀取不到
  String  hello2(@RequestParam("name") String name);
    /**
     * 傳遞引數物件,這個需要Post請求
     * @return
     */
    @RequestMapping(value="/hello3",method = RequestMethod.POST)
  String  hello3(@RequestBody User user);
}

   服務降級類


package com.niugang.fallback;
import org.springframework.stereotype.Component;
import com.niugang.entity.User;
import com.niugang.service.ServiceProvide;
/**
 * 
 * 指定的Feign客戶端介面的服務降級類。fallback類必須實現這個Feign客戶端註解的介面,並且是一個有效的spring
 * bean.(即類上新增@component)
 *
 */
@Component
public class ServiceProvideFallBack implements ServiceProvide {
@Override
public String hello1() {
return "hello1 invoke fail";
}
@Override
public String hello2(String name) {
// TODO Auto-generated method stub
return "hello2 invoke fail";
}
@Override
public String hello3(User user) {
return "hello3 invoke fail";
}
}

   controller


package com.niugang.controller;


import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.niugang.entity.User;
import com.niugang.service.ServiceProvide;
@RestController
public class ComputeController {


private final Logger logger = org.slf4j.LoggerFactory.getLogger(ComputeController.class);


@Autowired
private ServiceProvide serviceProvide;
    /**
     * 無引數呼叫
     * @return
     */
@RequestMapping(value = "/feign-consumer", method = RequestMethod.GET)
public String feign() {
logger.info("start invoke sevice provide");
return serviceProvide.hello1();
}


@RequestMapping(value = "/feign-consumer1/{name}", method = RequestMethod.GET)
public String feign1(@PathVariable String name) {
logger.info("start invoke sevice provide");
return serviceProvide.hello2(name);
}


@RequestMapping(value = "/feign-consumer2/{username}/{phone}", method = RequestMethod.GET)
public String feign2(@PathVariable String username, @PathVariable String phone) {
logger.info("start invoke sevice provide");
User user = new User();
user.setUsername(username);
user.setPhone(phone);
return serviceProvide.hello3(user);
}


}

測試

啟動註冊中心,啟動服務類,啟動消費者

從控制檯列印的日誌可以看書,但執行緒睡眠超過2000ms時,消費者會常識第二次重連。

當停掉服務提供者:

執行相應的服務降級函式

執行相應的服務降級函式

                                                                               微信公眾號: 

                                               

                                                                             JAVA程式猿成長之路

                                                       分享學習資源,學習方法,記錄程式設計師生活。