51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

不用feign只用ribbon的请求是什么样子的?

不用feign只用ribbon的请求是什么样子的?

如果仅仅使用Ribbon+RestTemplate来进行服务间调用,每个接口都需要写很多的代码。 实际上可以使用Feign来完成声明式的服务调用

@RestController
@Configuration
public class HelloService {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
    @GetMapping("/hello/{name}")
    public String hello(@PathVariable String name){
        System.out.println("fgdffgfgf");
        return this.restTemplate().getForObject("http://serviceA/helloo/yubo",String.class);
    }
}

如果没有feign,只用ribbon的话,可以对于ServiceA做一个接口类和实现类。把上述代码挪到实现类中。而HelloService中可以改为如下代码

@RestController
public class HelloService {

	@Autowired
    private IserviceA serviceA;
    
    @GetMapping("/hello/{name}")
    public String hello(@PathVariable String name){
        System.out.println("fgdffgfgf");
        return serviceA.sayHello(name);
    }
}

这样仍然很麻烦。对服务A的每个接口,都需要在本地定义一个接口类和实现类。

2.用了feign之后的请求是什么样子的

理想情况下,ServiceA要提供接口的时候,也要提供一个Jar包出来。服务B不能为调用服务A写任何代码。服务B引入这个jar包即可。

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

在服务B的启动类加上注解 @EnableFeignClients在服务B做一个IServiceA类

@FeignClient("ServiceA")
public interface IServiceA{
    @RequestMapping(value = "/user/",method = RequestMethod.POST)
    String createUser(@RequestBody User user);

    @RequestMapping(value = "/user/{id}",method = RequestMethod.DELETE)
    String deleteUser(@PathVariable("id") Long id);
    
}

这就是Feign+ribbon整合的方式 但是目前还是很麻烦。没有写代码,但是还是写了一些接口。这些接口和服务A的接口定义一模一样。 所以我们希望所有的接口只在serviceA中一遍搞定。

  • 先在ServiceA中写一个接口A,controller类实现之

  • 也可以见一个模块叫service-a-api,把接口A放进来。然后把这个模块mvn install /deploy

  • serviceB引入这个jar包

<dependency>
  <groupId>com.zhss.demo</groupId>
  <artifactId>service-a-api</artifactId>
</dependency>
  • 然后,IServiceA extends jar包里的接口类,不需要写重复的
@FeignClient("ServiceA")
public interface IServiceA extends ServiceAInterface{  
}

3.feign的核心组件和自定义bean、配置

核心组件

  • 编码器解码器:如果调用接口的时候,传递的参数是一个对象。feign需要将这个对象进行encoder编码,变成json序列化。收到一个json以后,需要转换为对象。(ResponseEntityDecoder、SpringEncoder)

  • Logger: 打印接口调用请求的日志(Slf4jLogger)

  • Contract: 契约组件,负责解释别人家的注解,比如spring-mvc支持的@PathVariable\

@RequestMapping@RequestParam 等等,让feign可以和别人家的注解结合起来使用。(SpringMvcContract)

  • Feign.Builder: feign客户端的构造器。(HystrixFeign.Builder)

  • FeignClient: 使用feign最核心的入口。(LoadBalancerFeignClient)

自定义Bean

FeignClient(name="ServiceA",configuration = MyConfiguration.class)
public interface ServiceClient{
    
}
@Configuration
public class MyConfiguration{
    @Bean
    public RequestInterceptor requestInterceptor(){
        return new MyRequestInterceptor();//用来替换核心组件
    }
    @Bean
    public Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
    }
    //可以自定义很多bean,比如logger\Decoder...
}
public MyRequestInterceptor implements RequestInterceptor{
    @Override
    public void apply(RequestTemplate requestTemplate){
        requestTemplate.header("Content-Type","application/json");
    }
}

配置

举例:

feign:
	client:
  	config:
    	ServiceA:
      	connectTimeout: 5000
      	readTimeout: 5000
      	loggerLevel: full
      	decode404: false
logging.level.com.zhss.service.ServiceAclient:DEBUG
赞(5)
未经允许不得转载:工具盒子 » 不用feign只用ribbon的请求是什么样子的?