SpringCloud入门【三】——使用feign服务远程调用

文章讲述了在微服务架构中,为何从Ribbon转向使用Feign的原因,包括Feign的便捷性,它默认集成负载均衡,提供接口方式调用服务,而Ribbon需要结合RestTemplate且已停止维护。此外,文章还介绍了如何通过Feign进行远程服务调用,配置负载均衡,以及Feign的性能优化和最佳实践,包括使用连接池和代码结构优化。
摘要由CSDN通过智能技术生成

一、为什么不使用ribbon而使用feign

1、feign更方便

首先看ribbon的导入依赖可以看出ribbon和eureka是来自同一个组织Netflix,所以在eureka中使用ribbon是很方便的。

<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring‐cloud‐starter‐netflix‐ribbon</artifactId>
</dependency>

但nacos比eureka好用许多,现在使用nacos的项目更多,早点的spring-cloud-alibaba版本也是将ribbon集成在自家的库里面的

但是较新版本的spring-cloud-alibaba已经舍弃了这个依赖

而且feign 默认集成了 Ribbon,默认实现了负载均衡,只需要创建一个接口并注解,就能很轻松的调用各服务提供的 HTTP 接口,明显更好用。

2、替代RestTemplate

RestTemplate 使用的是: spring-web 包下面的http 模块的http包中的API。 也就是Spring 自己封装的一套的httpclient API, 下面还是走java 的HttpurlConnection 建立连接然后传输数据。从名字也可以看出其是作为一个模板类可以在项目中使用。类似的还有RedisTemplate 等工具类。可以单独使用,单独使用的时候相当于直接连接到url, 不走微服务里面的服务发现以及负载均衡等机制。

ribbon的远程调用需要结合RestTemplate,加上@LoadBalanced才能使用,在创建模板时可读性差,参数复杂。

String url = "http://userservice/user/" + id;
User user = restTemplate.getForObject(url,User.class)

而feign就可以简化这一步骤,以接口的形式不仅可读性高,还可以重复使用

@FeignClient("userservice")
public interface UserClient {
    @GetMapping("/user/{id})
    User findById(@PathVariable("id) Long id);
}

3、ribbon已经停止维护

现在ribbon已经从springcloud的官方组件中移除,springcloud推荐使用Spring Cloud Loadbalancer来处理负载均衡

二、远程服务调用

1、创建需要远程服务的实例

user-service负责查用户信息

 如图所示服务创建成功

2、引入依赖 

order-service需要查用户信息,在pom文件中引入feign的依赖

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

因为新版本的openfeign不包含loadbalanced,所以要引入依赖

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

3、服务调用 

 声明客户端接口

使用客户端接口获取数据

 如图所示访问成功

三、负载均衡配置 

首先给user-service加入一些输出信息方便观看

调用三次请求

发现userservice1 、userservice2、userservice3分别调用了一次,是自带以轮询方式负载均衡的

1、创建配置类

如图所示我创建了两个负载均衡方式,随机和轮询 

随机的

@SpringBootApplication
@LoadBalancerClient(name = "userservice",configuration = RandomLoadBalancerConfig.class)
public class OrderService1Application {
    public static void main(String[] args) {
        SpringApplication.run(OrderService1Application.class,args);
    }
}

 轮询的

public class RoundLoadBalancerConfig {
    @Bean
    ReactorLoadBalancer<ServiceInstance> roundLoadBalancer(Environment environment,
                                                           LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RoundRobinLoadBalancer(loadBalancerClientFactory
                .getLazyProvider(name, ServiceInstanceListSupplier.class),
                name);
    }
}

2、修改启动类

 到启动类配置以随机方式负载均衡到userservice

发送10次请求,查看结果

四、feign自定义配置

 1、以yml文件方式配置

feign:
  client:
    config:
      user-service:   #这里如果是default则是默认配置,如果是服务名则只是针对改服务
        logger-level: FULL #包括NONE、BASIC、HEADERS、FULL四种
        decoder:      #把查询到的数据解码
        encoder:      #请求参数编码,通过http请求发送
        contract:     #支持的注解格式,默认是SpringMVC的注解
        retryer:      #失败重试机制,默认没有,但集成的ribbon中有,所以相当于有

 2、以java代码方式配置

先注入bean,这里可以注入多个bean

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

}

而后如果全局配置,则放到@EnableClientConfiguration这个注解中

@EnableClientConfiguration(defaultConfiguration = FeignClientConfiguration.class)

如果局部配置,则放到@FeignClient这个注解中

@FeignClient(value = "userservice",configuration = FeignClientConfiguration.class)

五、feign的性能优化

feign是一个申明式客户端,只负责把申明变成请求,最终发送请求用的是别的客户端,feign的底层客户端实现有三种

URLConnection:  //默认实现,不支持连接池
Apache HttpClient: //支持连接池
OKHttp: //支持连接池

建立连接池可以减少重复握手,因此需要切换客户端,两个带连接池的客户端依赖如下所示,引入其中一种即可。

<dependency>
      <groupId>io.github.openfeign</groupId>
      <artifactId>feign-httpclient</artifactId>
</dependency>
<dependency>
      <groupId>io.github.openfeign</groupId>
      <artifactId>feign-okhttp</artifactId>
</dependency>

httpclient的yml文件的配置如下

feign:
  httpclient:
    enabled: true #开启feign对httpclient的支持
    max-connections: 200  #最大连接数
    max-connections-per-route: 50 #每个路径的最大连接数

okhttp的yml文件配置貌似只用启用支持这一条

 六、feign的最佳实践

1、以继承的方式优化

通过项目结构可以看出,order-service通过feign创建userclient去调用user-service服务

对比Userclient里的findUser接口和user-service里的user,发现两者的路由一样

 

 其实是必须一样,否则该接口不能正确调用方法,但是这未免重复了,可以把这个请求路径剥离成UserApi,UserClient继承UserApi,UserController实现UserApi,这样的缺点是UserClient和UserController通过UserApi耦合在一起了,一方出问题,另外一方也会出问题。

2、以抽离的方式优化

order-service1调用user-service需要写一个userclient接口,order-service2调用user-service也需要写一个userclient接口,这就导致同样的代码写很多遍,不仅麻烦,还很容易出错,所以一种思路就是把userclient、orderclient等等都抽离到一个公共的feign-Api模块里去,把所用到的实体类都放到feign-Api里去,然后在自己的maven依赖中导入feign-Api,通过调用Feign-Api里的userclient、orderclient直接返回user、order对象。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值