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時,消費者會常識第二次重連。

當停掉服務提供者:

輸入:http://localhost:9001/feign-consumer

執行相應的服務降級函數

輸入:http://localhost:9001/feign-consumer1/zhangsan

執行相應的服務降級函數

 微信公眾號

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM