做网站销售会问哪些问题,沈阳做网站的公司,asp 网站图标,莆田网站建设制作一、背景介绍
二、正文
OpenFeign是什么#xff1f;
OpenFeign#xff08;简称Feign#xff09;是一个声明式的Web服务客户端#xff0c;用于简化服务之间的HTTP通信。与Nacos和Ribbon等组件协同#xff0c;以支持在微服务体系结构中方便地进行服务间的通信#xff1b…一、背景介绍
二、正文
OpenFeign是什么
OpenFeign简称Feign是一个声明式的Web服务客户端用于简化服务之间的HTTP通信。与Nacos和Ribbon等组件协同以支持在微服务体系结构中方便地进行服务间的通信 OpenFeign在默认情况下集成了Hystrix提供了服务容错和服务降级的功能。
OpenFeign的作用是什么
按照单一职责也为了满足可复用、可扩展的核心我们可以对整体业务拆分成不同的服务这样涉及到的一个问题就是某一个服务的逻辑实现需要依托另一个服务的信息这样服务和服务之间需要通信来进行消息传递但是服务和服务之间如果直接通信的话耦合关系变强无法达到高复用的作用。使用了OpenFeign技术来解决这个问题如果其中一个类需要调用另一个类的某一个方法的话直接通过OpenFeign这个第三方转发这个调用减少直接通信带来的耦合关系 通过使用FeignClien注解标识UserApiService这个客户端对【internetbar-provider-user】这个服务远程调用。OpenFeign会根据接口自动创建一个实现类发起HTTP请求去用Get的方式访问远程服务的【/userManage/getUserInfoById/{userId}】这个接口
Feign和OpenFeign的关系
OpenFeign是对Feign的增强对mvc注解的增强那如何理解这句话呢 共同点Feign和OpenFeign都是用于简化服务之间HTTP通信的Web服务客户端 不同点 所属不同Feign是Netflix开发HTTP客户端OpenFeign是SpringCloud对Feign的重新实现和增强OpenFeign引入了SpringMVC的注解例如GetMapping等注解可以类似于SpringMVC的一些效果 Hystrix集成OpenFeign默认集成Hystrix提供服务容错和服务降级的功能Feign中需要显式地添加Hystrix的依赖并配置 Java还有哪些服务调用方式
Okhttp、HttpURLConnection、RestTemplate 使用OpenFeign和不使用的区别对比
我们先从代码形式上来看一下两者如何使用 基于RestTemplate使用HTTP请求调用服务 基于OpenFeign调用 Feign可以根据接口的定义生成客户端所需要的代码这部分代码被Feign封装到底层并且底层同步的实现了负载均衡和服务发现、服务容错等功能不需要我们像使用RestTemplate一样额外的手动去配置一个简单的API接口就可以帮助我们做了很多事情。 实战
引入依赖 dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId
/dependency在启动类添加EnableFeignClients注解
EnableFeignClients(defaultConfiguration FeignAutoConfiguration.class)添加FeignClient接口
package cn.itcast.order.clients;import cn.itcast.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;/*** BelongsProject: cloud-demo* BelongsPackage: cn.itcast.order.clients* CreateTime: 2023-03-17 12:29* Description: TODO* Version: 1.0*/
FeignClient(userservice)
public interface UserClient {GetMapping(/user/{id})User findById(PathVariable(id) Long id);
}修改逻辑代码
使用RestTemplate**
package cn.itcast.order.service;import cn.itcast.order.clients.UserClient;
import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import cn.itcast.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;Service
public class OrderService {Autowiredprivate OrderMapper orderMapper;Autowiredprivate RestTemplate template;public Order queryOrderById(Long orderId){//1、根据用户id查询用户的订单信息Order order orderMapper.findById(orderId);//2、利用RestTemplate发起http请求查询用户信息String urlhttp://userservice/user/order.getUserId();User forObject template.getForObject(url, User.class);//3、将user信息封装到Order中order.setUser(forObject);// 返回return order;}
}使用Feign接口
package cn.itcast.order.service;import cn.itcast.order.clients.UserClient;
import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import cn.itcast.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;Service
public class OrderService {Autowiredprivate OrderMapper orderMapper;Autowiredprivate UserClient userClient;public Order queryOrderById(Long orderId) {//1、查询订单Order order orderMapper.findById(orderId);//2、用Feign远程调用User user userClient.findById(order.getUserId());//3、封装user到Orderorder.setUser(user);//4、返回return order;}
} 自定义配置
配置日志以debug级别输出
当我们进行服务调用的过程中有可能出现接口调用失败的问题或者我们想要输出请求或响应的详细信息我们可以配置日志
日志级别有哪些 NONE不记录任何日志默认值 BASIC记录请求方法、URL、响应状态代码及执行时间 HEADERS记录BASIC级别的基础上记录请求和响应的header FULL记录请求和响应的header、body和元数据 方式一配置文件
全局所有服务生效
feign:client:config:default:loggerLevel: FULL#某服务生效
feign:client:config:userservice:loggerLevel: FULL方式二配置类
添加配置类
package cn.itcast.order.config;import feign.Logger;
import org.springframework.context.annotation.Bean;/*** BelongsProject: cloud-demo* BelongsPackage: cn.itcast.order.config* CreateTime: 2023-03-17 13:05* Description: TODO* Version: 1.0*/
public class DefaultFeignConfiguration {Beanpublic Logger.Level feignLogLevel() {return Logger.Level.BASIC;}
}方式三在启动类上添加注解EnableFeignClients
全局配置对所有生效 EnableFeignClients(defaultConfiguration FeignAutoConfiguration.class) 局部配置只对userservice服务生效 EnableFeignClients(value “userservice”, defaultConfiguration FeignAutoConfiguration.class) 性能优化
底层的客户端实现 URLConnection默认实现不支持连接池 Apache HttpClient支持连接池 OKHttp支持连接池 优化包括 使用连接池代替默认的URLConnection 日志级别最好用basic或none 实操——Feign工程化
引入feign-httpClient依赖 dependencygroupIdio.github.openfeign/groupIdartifactIdfeign-httpclient/artifactId
/dependency配置文件开启httpClient功能设置连接池参数
feign:client:config:default: #default全局的配置loggerLevel: BASIC #日志级别基本的请求和响应信息httpclient:enabled: true #开启feign对HttpClient的支持max-connections: 200 #最大的连接数max-connections-per-route: 50 #每个路径的最大连接数目的将公共的配置抽取出来
新建一个Maven项目服务名叫——feign-api
引入依赖
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdcloud-demo/artifactIdgroupIdcn.itcast.demo/groupIdversion1.0/version/parentmodelVersion4.0.0/modelVersionartifactIdfeign-api/artifactIdpropertiesmaven.compiler.source8/maven.compiler.sourcemaven.compiler.target8/maven.compiler.target/propertiesdependenciesdependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependency/dependencies/project
第一步、公有接口——工程化核心
在项目中创建一个Feign客户端接口通过使用FeignClient注解来声明要调用的服务和服务接口
package cn.itcast.feign.clients;import cn.itcast.feign.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;/*** BelongsProject: cloud-demo* BelongsPackage: cn.itcast.order.clients* CreateTime: 2023-03-17 12:29* Description: TODO* Version: 1.0*/
FeignClient(userservice)
public interface UserClient {GetMapping(/user/{id})User findById(PathVariable(id) Long id);
}第二步、配置类—用于配置Feign客户端的一些属性如日志级别等
package cn.itcast.feign.config;import feign.Logger;
import org.springframework.context.annotation.Bean;/*** BelongsProject: cloud-demo* BelongsPackage: cn.itcast.order.config* CreateTime: 2023-03-17 13:05* Description: TODO* Version: 1.0*/
public class DefaultFeignConfiguration {Beanpublic Logger.Level feignLogLevel() {return Logger.Level.BASIC;}
}实体类
package cn.itcast.feign.pojo;import lombok.Data;Data
public class User {private Long id;private String username;private String address;
} orderservice服务
第三步、启动类—启用Feign客户端
在Spring Boot应用程序中通过使用EnableFeignClients注解启用Feign客户端并指定要扫描的Feign客户端接口所在的包。
package cn.itcast.order;import cn.itcast.feign.clients.UserClient;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;MapperScan(cn.itcast.order.mapper)
SpringBootApplication
EnableFeignClients(clients UserClient.class,defaultConfiguration FeignAutoConfiguration.class)public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}/*** Description: 将RestTemplate注册到容器中* Date: 2023/3/13 11:28* return: org.springframework.web.client.RestTemplate**/BeanLoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}/*** Description: 修改负载均衡策略方式* Date: 2023/3/13 19:56* return: com.netflix.loadbalancer.IRule**/Beanpublic IRule randomRule() {return new RandomRule();}
}
实体类
package cn.itcast.order.pojo;import cn.itcast.feign.pojo.User;
import lombok.Data;Data
public class Order {private Long id;private Long price;private String name;private Integer num;private Long userId;private User user;
}Mapper类
package cn.itcast.order.mapper;import cn.itcast.order.pojo.Order;
import org.apache.ibatis.annotations.Select;public interface OrderMapper {Select(select * from tb_order where id #{id})Order findById(Long id);
}Controller类
package cn.itcast.order.web;import cn.itcast.order.pojo.Order;
import cn.itcast.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
RequestMapping(/order)
public class OrderController {Autowiredprivate OrderService orderService;GetMapping(/{orderId})public Order queryOrderByUserId(PathVariable(orderId) Long orderId) {// 根据id查询订单并返回return orderService.queryOrderById(orderId);}
}第四步、使用Feign客户端—service类
在需要调用远程服务的地方注入Feign客户端并使用
package cn.itcast.order.service;import cn.itcast.feign.clients.UserClient;
import cn.itcast.feign.pojo.User;
import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;Service
public class OrderService {Autowiredprivate OrderMapper orderMapper;Autowiredprivate UserClient userClient;public Order queryOrderById(Long orderId) {//1、查询订单Order order orderMapper.findById(orderId);//2、用Feign远程调用User user userClient.findById(order.getUserId());//3、封装user到Orderorder.setUser(user);//4、返回return order;}
}通过上述的四个步骤公有接口、配置类、启动类—启用Feign客户端、使用Feign客户端—service类我们就实现了Feign的工程化以声明式的方式定义了服务调用接口配置了Feign客户端
基于工程化的思想所有的服务调用被抽成公共的API单独放在一个包中我们只需要调用公共接口不需要写太多重复代码哪个服务需要调用引用对应的包就可以了避免冗余代码这也是设计模式思想可复用的体现。 集成Hystrix
我们需要先了解雪崩效应通过OpenFeign进行多服务之间调用如果服务提供者出现了故障将会导致服务消费者不可用。比方说login服务需要调用user服务获取登录用户的基本信息此时user服务可能服务挂掉或者被攻击了此时login服务可能将会处于等待过程我们可以使用Hystrix进行熔断当远程服务调用失败或超时时熔断器会出发并执行降级逻辑。 关于OpenFeign和Hystrix的集成使用请等待我之后关于Hystrix的博客详解哦~~~ 源码解析
1、Spring启动时初始化-生成代理类
在服务启动时Spring会加载配置并且初始化Spring容器、扫描并加载项目当中用到的组件此时OpenFeign的配置也会被程序加载包括自定义Feign配置类、负载均衡配置、熔断器配置等扫描带有FeignClient注解的接口Feign会使用动态代理生成代理类并注册到Spring容器中
2、服务发现和负载均衡
Nacos注册中心如果项目中用到了Nacos注册中心Feign会与Nacos集成通过服务名进行服务发现 Ribbon负载均衡如果项目中使用了Ribbon可以实现对服务实例的负载均衡 大家可以看下面这张图片我们点进OpenFeign的依赖会发现里面自动集成了Ribbon 那Feign和Ribbon、RestTemplate三者之间的关系是什么样的呢
3、请求处理
场景服务A调用服务B 当服务A通过OpenFeign的方式调用服务B时实际上是通过代理类最终调用LoadBalancerFeignClient的execute方法execute方法内部整合了Ribbon去实现负载均衡最终会找到真实要请求的服务地址从而发送RibbonRequest请求返回响应内容给服务A 这也是Feign的核心代码 为什么Feign第一次调用耗时很长 这个问题是我在网上看到的一个问题大家也可以参考参考图中说到的原因 三、总结 OpenFeign帮助我们简化了服务之间的通信同时继承了负载均衡、熔断器等功能帮助我们更好的实现服务调用。之后我将会针对OpenFeign中集成的Hystrix做分享大家敬请期待 如果有想要交流的内容欢迎在评论区进行留言如果这篇文档受到了您的喜欢那就留下你点赞收藏评论脚印支持一下博主~