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

执行相应的服务降级函数

 微信公众号

 

 

posted @ 2020-01-14 17:43  盲目的拾荒者  阅读(1079)  评论(0编辑  收藏  举报