SpringCloud-远程调用

一、远程调用是什么?

是指在微服务架构中,不同的微服务之间通过网络进行通信和调用。可以帮助实现微服务之间的协作和交互,使得系统更加灵活和可扩展。

二、什么是Feign?

Feign是Netflix公司提供服务调用组件,单独使用Feign比较麻烦。SpringCloud对Feign做了集成封装,提供了声明式服务调用组件Open-Feign。

Open-Feign支持SpringMVC注解。是Spring Cloud提供的一个声明式的伪Http客户端,它使得调用远程服务就像调用本地服务一样简单,只需要创建一个接口并添加一个注解即可。

Feign默认集成了Ribbon,所以使用Feign默认就具备负载均衡的效果。

三、Feign入门

1. 使用步骤

Feign要在调用者一方配置

  1. 导入openfeign的起步依赖
  2. 创建Feign的Client接口
  • 编写feign接口是一定要提前明确
    1. 期望feign帮我们发送什么请求
    2. 期望feign帮我们把响应结果转化成什么对象
  1. 在引导类上添加@EnableFeignClients("Client接口所在的包名")
  2. 使用Client进行远程调用

2. 示例

添加依赖

xml 复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

创建Feign客户端

创建一个UserClient接口,用于配置Feign调用user-service的功能

要求:

  • 在接口上添加注解@FeignClient("要调用的服务名")
  • 接口里要有方法
  • 每个方法对应一个请求接口
  • 在方法上添加注解,设置方法的路径
java 复制代码
@FeignClient("user-service")
public interface UserClient {
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}

在引导类上添加@EnableFeignClients

java 复制代码
@EnableDiscoveryClient
@SpringBootApplication
@MapperScan("com.sdf.order.mapper")
@EnableFeignClients("com.sdf.order.client")//启用Feign支持
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

使用UserClient调用用户服务

java 复制代码
@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserClient userClient;
    public Order findById(Long id){
        Order order = orderMapper.selectById(id);
        //使用UserClient调用用户服务
        User user = userClient.findById(order.getUserId());
        order.setUser(user);
        return order;
    }
}

四、Feign原理

Feign帮我们生成的接口代理对象(注入进来的代理对象),在代理对象里边Feign帮我们做了两件事:

  1. 构造HTTP请求并发出去

    请求方式:创建Client接口方法上的请求方式

    请求路径:http://目标服务名/资源路径

  2. 获取HTTP响应并转换返回给调用者

    得到HTTP响应,根据Client接口方法的返回值类型,将响应结果转换成返回值类型,在返回给调用

图示:

五、Feign配置Ribbon

Feign已经集成了Ribbon,用法参考负载均衡

不做任何配置:也有负载均衡效果。默认的负载均衡策略是:轮询

如果要修改负载均衡策略:

  • 方式1:修改消费者的配置文件,设置负载均衡策略
  • 方式2:使用@Bean把负载均衡策略对象放到IoC容器里

如果要实现饥饿加载:修改配置文件,开启饥饿加载,并设置哪些服务需要饥饿加载

六、Feign配置日志

1. 使用步骤

  1. 修改配置文件,设置整体文件的日志级别

  2. 创建Feign配置类,注册Logger.Level用于设置Feign的日志级别

支持四种日志级别

  1. NONE:不输出任何日志,是默认值
  2. BASIC:仅输出请求的方式、URL以及响应状态码、执行时间
  3. HEADERS:在BASIC基础上,额外输出请求头和响应头信息
  4. FULL:输出所有请求和响应的明细,包括头信息、请求体、元数据

2. 示例

设置整体的日志级别

yaml 复制代码
logging:
  level:
    com.sdf: debug

配置Feign的日志文件级别

方式一:@Bean方式(不推荐)

单独为Feign配置一个日志类,设置日志级别

java 复制代码
@Configuration
public class FeignConfig {
    @Bean
    public Logger.Level feignLog(){
        return Logger.Level.FULL;
    }
}

方式二、配置文件方式(推荐)

修改配置文件application.yaml,添加如下配置:

yaml 复制代码
feign:
  client:
    config:
      default:
        loggerLevel: FULL

七、Feign使用优化

Feign底层发起http请求,依赖于其它的框架。其底层客户端实现包括:

  • URLConnection:默认实现,不支持连接池,性能低(每次请求都需要建立连接,得到响应在断开连接)

  • Apache HttpClient :支持连接池

  • OKHttp:支持连接池

因此提高Feign的性能主要手段就是使用连接池代替默认的URLConnection。

1. 使用步骤

使用Apache HttpClient 的步骤:

  1. 添加httpclient的依赖坐标
  2. 配置httpclient连接池

2. 示例

添加httpclient的依赖坐标

xml 复制代码
<!--httpClient的依赖 -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

配置httpclient连接池

yml 复制代码
feign:
  httpclient:
    enabled: true # 开启feign对HttpClient的支持,默认是true
    max-connections: 200 # 最大的连接数,默认200
    max-connections-per-route: 50 # 每个路径的最大连接数,默认50

测试效果

在FeignClientFactoryBean中的loadBalance方法中打断点:

Debug方式重启服务,可以看到这里的client,底层就是Apache HttpClient:

相关推荐
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ6 分钟前
MyBatis执行完sql后,返回的数值代表的意思
java·开发语言
CodeClimb37 分钟前
【华为OD-E卷-寻找密码 100分(python、java、c++、js、c)】
java·python·华为od
爱上语文40 分钟前
宠物管理系统:Service层
java·开发语言·宠物
解梦者1 小时前
Spring(七)Spring Cloud----Feign、Zuul和Apollo
spring·spring cloud·feign·apollo·zuul
水w1 小时前
【项目实践】SpringBoot Nacos配置管理 map数据
java·服务器·开发语言·spring boot·nacos
@菜鸟进阶记@1 小时前
SpringBoot核心:自动配置
java·spring boot·后端
瓜牛_gn1 小时前
苍穹外卖项目Day02代码结构深度解析
java·spring
汤姆yu1 小时前
基于springboot的健身俱乐部网站系统
java·spring boot·后端·健身房·俱乐部
喵手1 小时前
Java 实现日志文件大小限制及管理——以 Python Logging 为启示
java·开发语言·python
huapiaoy1 小时前
JavaSE---String(含一些源码)
java·linux·前端