成都都网站建设,口碑营销论文,黄山小程序开发,青岛网页制作设计营销最近整理一下微服务的文章#xff0c;先拿一直用的OpenFeign开刀
思考#xff1a;微服务之间如何方便优雅的实现服务间的远程调用
一、说说openFeign是什么吧#xff1f;
说到这个#xff0c;那不得不先说说RPC
1.什么是RPC
RPC 全称是 Remote Procedure Call #x…最近整理一下微服务的文章先拿一直用的OpenFeign开刀
思考微服务之间如何方便优雅的实现服务间的远程调用
一、说说openFeign是什么吧
说到这个那不得不先说说RPC
1.什么是RPC
RPC 全称是 Remote Procedure Call 即远程过程调用其对应的是我们的本地调用。RPC 的目的是让我们调用远程方法像调用本地方法一样。
//本地调用
R result orderService.findOrderByUserId(id);
//RPC远程调用 orderService为代理对象
R result orderService.findOrderByUserId(id); RPC框架设计架构
2. 什么是Feign
Feign是Netflix开发的声明式、模板化的HTTP客户端Feign可帮助我们更加便捷、优雅地调用HTTP API。
Feign可以做到使用 HTTP 请求远程服务时就像调用本地方法一样的体验开发者完全感知不到这是远程方法更感知不到这是个 HTTP 请求。它像 Dubbo 一样consumer 直接调用接口方法调用 provider而不需要通过常规的 Http Client 构造请求再解析返回数据。它解决了让开发者调用远程接口就跟调用本地方法一样无需关注与远程的交互细节更无需关注分布式环境开发。
Spring Cloud openfeign对Feign进行了增强使其支持Spring MVC注解另外还整合了Ribbon和Eureka从而使得Feign的使用更加方便。
2.1 OpenFeign和Feign的区别
Feign Feign是SpringCloud组件中的一个轻量级RESTful的Http服务客户端Feign内置了Ribbon用来做客户端负载均衡去调用服务注册中心的服务。Feign的使用方式是使用Feign的注解定义接口调用这个接口就可以调用服务注册中心的服务。 OpenFeign OpenFeign是SpringCloud在Feign的基础上支持了SpringMVC的注解如RequestMapping等。OpenFeign的FeignClient可以解析SpringMVC的RequestMapping注解下的接口并通过动态代理的方式产生实现类实现类中做负载均衡并调用其他服务。 2.2 RibbonFeign对比
RibbonRestTemplate进行微服务调用
Bean
LoadBalanced
public RestTemplate restTemplate() {return new RestTemplate();
}//调用方式
String url http://mall-order/order/findOrderByUserId/id;
R result restTemplate.getForObject(url,R.class);
Feign进行微服务调用
FeignClient(value mall-order,path /order)
public interface OrderFeignService {RequestMapping(/findOrderByUserId/{userId})public R findOrderByUserId(PathVariable(userId) Integer userId);
}//调用
Autowired
OrderFeignService orderFeignService;
//feign调用
R result orderFeignService.findOrderByUserId(id);
2.3 Feign的设计架构 二、Spring Cloud Alibaba快速整合Feign
下面是Springboot集成OpenFeign Demo完全照着来妥妥的没问题
服务提供者我就不写了这就是正常的controller主要是调用者这块接下来写的也是这个
1.在pom.xml文件中添加以下依赖
dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId
/dependency
2.调用端添加启动注解 EnableFeignClients
EnableAsync
SpringBootApplication(exclude { DataSourceAutoConfiguration.class, DruidDataSourceAutoConfigure.class })
EnableDiscoveryClient
EnableFeignClients //扫描和注册feign客户端的beanDefinition
MapperScan(com.**.**.**.**.mapper)
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
3.编写调用接口FeignClient注解
创建一个FeignClient接口用于定义要调用的远程服务的方法
FeignClient(value base-application, path /base)
RequestMapping(/api/testDemo)
public interface OpenFeignBaseDemo {PostMapping(/queryList)String queryList(RequestBody JSONObject jsonObject);
}
在上面的代码中我们使用FeignClient注解指定了要调用的远程服务的名称。然后我们定义了一个名为queryList的方法并使用PostMapping注解指定了要调用的远程服务的API路径。
4.发起调用像调用本地方式一样调用远程服务
在其他类中使用OpenFeignBaseDemo 来调用远程服务的方法
RestController
RequestMapping(/openFeignDemo)
public class OpenFeignControllerDemo {Autowiredprivate OpenFeignBaseDemo openFeignBase;PostMapping(value /test, produces { application/json;charsetutf-8 })public ResponseEntity test(RequestBody JSONObject jsonObject) {//feign调用String res openFeignBase.queryList(jsonObject);return new ResponseEntity(res, HttpStatus.OK);}}
5.结果预览
启动两个工程postmain调用 请求url localhost:8088/server/openFeignDemo/test。 6.这里我必须强调一下第3步这个参数设置的含义
public interface FeignClient {AliasFor(name)String value() default ;String contextId() default ;AliasFor(value)String name() default ;String qualifier() default ;String url() default ;boolean decode404() default false;Class?[] configuration() default {};Class? fallback() default void.class;Class? fallbackFactory() default void.class;String path() default ;boolean primary() default true;
}
下面就对各个属性进行分析
value、name value和name的作用一样如果没有配置url那么配置的值将作为服务名称用于服务发现。反之只是一个名称。
contextId 我们不想将所有的调用接口都定义在一个类中有一种解决方案就是为每个Client手动指定不同的contextId这样就不会冲突了。
url url用于配置指定服务的地址相当于直接请求这个服务不经过Ribbon的服务选择。像调试等场景可以使用。
decode404 当调用请求发生404错误时decode404的值为true那么会执行decoder解码否则抛出异常。
configuration configuration是配置Feign配置类在配置类中可以自定义Feign的Encoder、Decoder、LogLevel、Contract等。
fallback 定义容错的处理类也就是回退逻辑fallback的类必须实现Feign Client的接口无法知道熔断的异常信息。
fallbackFactory 也是容错的处理可以知道熔断的异常信息。
path path定义当前FeignClient访问接口时的统一前缀比如接口地址是/user/get, 如果你定义了前缀是user, 那么具体方法上的路径就只需要写/get 即可。
primary primary对应的是Primary注解默认为true官方这样设置也是有原因的。当我们的Feign实现了fallback后也就意味着Feign Client有多个相同的Bean在Spring容器中当我们在使用Autowired进行注入的时候不知道注入哪个所以我们需要设置一个优先级高的Primary注解就是干这件事情的。
qualifier qualifier对应的是Qualifier注解使用场景跟上面的primary关系很淡一般场景直接Autowired直接注入就可以了。
7.报错解决
如果遇到这样的错误feign.RetryableException: Read timed out executing POST
可以做如下处理yaml配置
feign:client:config:default:connectTimeout: 1000readTimeout: 6000
或者propertis配置
feign.client.config.default.connect-timeout20000
feign.client.config.default.read-timeout20000
https://cloud.spring.io/spring-cloud-openfeign/reference/html/