在上面一篇介绍Nacos的文章最后,两个服务的相互调用是用的RestTemplate类完成的。但这种方式不是很推荐,更佳的方式是用OpenFeign组件去调用。OpenFeign是官方推出的服务调用和负载均衡组件,基于Ribbon和Hystrix,前身是第一代Spring Cloud的Feign,对Feign进行了扩展,支持了SpringMvc的相关注解。
OpenFeign是使用接口+注解实现的,因此了解它的常用注解是必要的,有以下几个:
@EnableFeignClients:在启动类上添加,用于开启OpenFeign功能。当项目启动时,会扫描带有@FeignClient的接口,生成代理类并注册到Spring容器中
@FeignClient:通知OpenFeign组件对该注解下的接口进行解析,通过动态代理的方式产生实现类,完成服务调用
@RequestMapping:SpringMvc中的注解,不过此时该注解表示发起Request请求(默认Get方式)
@GetMapping:SpringMvc中的注解,不过此时该注解表示发起Get请求
@PostMapping:SpringMvc中的注解,不过此时该注解表示发起Post请求
首先得把Nacos启动
服务提供方,
bootstrap.yml:
server: port: 8083 servlet: context-path: /nacosProvider spring: application: name: nacos-provider cloud: nacos: discovery: server-addr: 127.0.0.1:8848
server: port: 8083 servlet: context-path: /nacosProvider
spring: application: name: nacos-provider cloud: nacos: discovery: server-addr: 127.0.0.1:8848
引入依赖:
<dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery </artifactId> <version>2.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency></dependencies>
服务方法:
@Controller@RequestMapping("/provide")public class ProviderController { @RequestMapping("/distribute") @ResponseBody public String distribute() { return "吃鸡胸肉"; } @RequestMapping("/distribute1") @ResponseBody public String distribute1(String name, Integer age) { return "姓名:" + name + ",年龄:" + age; } @PostMapping("/distribute2") @ResponseBody public String distribute2(@RequestBody Person p) { return "身高:" + p.getHeight() + ",肤色:" + p.getSkin(); }}
import lombok.Data;@Datapublic class Person { private Integer height; private String skin;}
服务调用方,
bootstrap.yml
server: port: 8082 servlet: context-path: /nacosInvoke spring: application: name: nacos-invoke cloud: nacos: discovery: server-addr: 127.0.0.1:8848
server: port: 8082 servlet: context-path: /nacosInvoke
spring: application: name: nacos-invoke cloud: nacos: discovery: server-addr: 127.0.0.1:8848
<dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery </artifactId> <version>2.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency></dependencies>
启动类上添加注解:
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.openfeign.EnableFeignClients;//开启OpenFeign@EnableFeignClients@SpringBootApplicationpublic class NacosInvokeApplication { public static void main(String[] args) { SpringApplication.run(NacosConfigApplication.class, args); }}
创建@FeignClient修饰的接口:
import com.gs.nacos_invoke.dto.Person;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestParam;/** * value值是服务提供方的服务名称 */@FeignClient(value = "nacos-provider")public interface InvokeClient { @GetMapping("/nacosProvider/provide/distribute") String distribute(); @GetMapping("/nacosProvider/provide/distribute1") String distribute1(@RequestParam("name") String name, @RequestParam("age") Integer age); @PostMapping("/nacosProvider/provide/distribute2") String distribute2(@RequestBody Person p);}
Person类(服务调用方再创建一个,不是同一个):
编写控制器,使用接口请求提供方的服务:
import com.gs.nacos_invoke.dto.Person;import com.gs.nacos_config.feign.InvokeClient;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;@Controller@RequestMapping("/user")public class UserController { @Autowired private InvokeClient invokeClient; @GetMapping("/invoke") public void invoke(String name, Integer age) { String str = invokeClient.distribute(); System.out.println(str); } @GetMapping("/invoke1") public void invoke1() { String str = invokeClient.distribute1("coder", 20); System.out.println(str); } @GetMapping("/invoke2") public void invoke2() { Person p = new Person(); p.setHeight(183); p.setSkin("黄皮肤"); String s = invokeClient.distribute2(p); System.out.println(s); }}
OpenFeign是基于Ribbon的,所以它默认是负载均衡的。其次,它也是基于Hystrix的,有超时降级的处理:默认服务提供方的接口超时时间是1s,超过1s服务调用方会报错。1s是可以配置的,按照业务需要调整。@FeignClient注解有个fallback属性,当该属性有值时,服务提供方超时,会返回程序所指定的降级值。
服务调用方,bootstrap.yml添加(更规范的做法是引入spring-cloud-starter-alibaba-nacos-config依赖,nacos中新建配置,然后在这个配置中添加):
feign: hystrix: enabled: trueribbon: # 请求连接的超时时间 ConnectionTimeout: 3000 # 请求处理的超时时间 ReadTimeout: 3000 hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 3000
feign: hystrix: enabled: trueribbon: # 请求连接的超时时间 ConnectionTimeout: 3000 # 请求处理的超时时间 ReadTimeout: 3000
hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 3000
接口修改为:
import com.gs.nacos_invoke.dto.Person;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestParam;@FeignClient(value = "nacos-provider", fallback = InvokeClientFallback.class)public interface InvokeClient { @GetMapping("/nacosProvider/provide/distribute") String distribute(); @GetMapping("/nacosProvider/provide/distribute1") String distribute1(@RequestParam("name") String name, @RequestParam("age") Integer age); @PostMapping("/nacosProvider/provide/distribute2") String distribute2(@RequestBody Person p);}
fallback指定的类:
import com.gs.nacos_invoke.dto.Person;import org.springframework.stereotype.Component;@Componentpublic class InvokeClientFallback implements InvokeClient { @Override public String distribute() { return "超时3s"; } @Override public String distribute1(String name, Integer age) { return "超时3s"; } @Override public String distribute2(Person p) { return "超时3s"; }}
服务提供方ProviderController类的方法中,加入Thread.sleep(4000);或者throw new RuntimeException("抛异常");来触发降级(抛出未捕获的异常也能触发)。
到此这篇关于SpringCloud OpenFeign基本介绍与实现示例的文章就介绍到这了,更多相关SpringCloud OpenFeign内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!
本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728