Feign助您实现远程调用

152 阅读3分钟

Feign

服务调用

两个模块相互暴露接口一般获取的方式是类似在一个模块里面进行发送http请求给另一个模块,一般用restTemplate去解决,配置bean然后创建对象,在需要的地方进行获取注入然后引用get或者for,传入url和需要返回的数据类型的类,会自动映射进去。不需要导入依赖。

业务方向:

   @Autowired
   private RestTemplate restTemplate;

    @GetMapping("{orderId}")
    public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
        // 根据id查询订单并返回
        Order order = orderService.queryOrderById(orderId);
        String url  = "http://localhost:8081/user/"+ order.getUserId();
        order.setUser(restTemplate.getForObject(url, User.class));
        return order;
    }

配置类:

@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

@Bean
    public RestTemplate restTemplate() {
     return new RestTemplate();
    }
}

远程调用

由于之前的RestTemplate,在代码中并不美观而且他的封装做的也不好,因此引入新的远程调用工具。并且url复杂多的参数不方便操作,用Feigin后就可以封装成一个map的机制

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

然后在启动类上面增加注解@EnableFeignClients

@EnableFeignClients
@MapperScan("cn.order.mapper")
@SpringBootApplication
public class OrderApplication

增加Client的接口,然后自动装配就可以直接注入调用

@FeignClient("userservice")    //注意这里的写的是服务名称不需要加/
public interface UserClient {
//   创建一个接口来去发送信息,调用接口的方法就可以了,就相当于给这个服务发送了请求
    @GetMapping("/user/{id}")
    User findUserById(@PathVariable("id") Long id);
}

这样去访问localhost:8080/order/101(在之前的集群环境下实现),那么进行操作的时候就能实现负载均衡和远程调用的功能

日志配置

一般情况可在控制台去监视请求和响应的操作,那么显示日志信息的方法由两种,并且等级设置一般为basic最好

default代表的是全局,其他就是服务名称

第一种是配置文件

采用的是feign.client.config.xxx.loggerLevel

feign:
  client:
    config:
      default:   #这里就是全局配置
        loggerLevel: BASIC

第二种是java代码去配置Logger.level这个Bean,

如果在@EnableFeignClients注解声明就是全局生效,如果在@FeignClient也即是UserClient就是当前服务生效,以下实现代码

	@FeignClient(value = "userservice",configuration = FeignClientConfiguration.class)
public interface UserClient {
//   创建一个接口来去发送信息,倒是调用接口的方法就可以了
    @GetMapping("/user/{id}")
    User findUserById(@PathVariable("id") Long id);
}
//局部生效
@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)  全局生效
@MapperScan("cn.order.mapper")
@SpringBootApplication
public class OrderApplication {...

配置类:也就是配置后返回Logger.Level然后放到Bean里面,在注解的时候就调用他的类

public class FeignClientConfiguration {
    @Bean
    public Logger.Level feign(){
        return Logger.Level.BASIC;
    }
}

HttpClient代替URLConnection

实际就是引入依赖和进行配置文件的操作,需要在单独去查,这里贴一下代码

feign:
  httpclient:
    max-connections: 200
    max-connections-per-route: 50
    enabled: true

抽取出模块FeignClient

为了方便每个服务如果需要去都行远程调用一样的接口,那么在一个服务里面就需要写很多重复的Clients,因此进行一个提取,再利用模块导入就可以使用(maven)

那么基本操作没难度,有一个注意的是,在自动装配的时候就出现UseClient并没有因为在另一个模块所以没法注入,那么进行第一种解决方法就是扩大Springboot的扫描范围,但是这样显然对性能的要求会大很多,得不偿失,所以采用直接在选择的时候进行FeignClient进行指定包文件,或者进行指定字节码文件也行,推荐选择指定包文件指定

@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class, basePackages = "cn.clients")