spring cloud 入门系列五:使用Feign 实现声明式…
2018-06-18 01:23:55来源:未知 阅读 ()
一、Spring Cloud Feign概念引入
通过前面的随笔,我们了解如何通过Spring Cloud ribbon进行负责均衡,如何通过Spring Cloud Hystrix进行服务断路保护,
两者作为基础工具类框架应用在各种基础设施类微服务和业务类微服务中,并且成对存在,那么有没有更高层的封装,将两者的使用
进一步简化呢? 有! 他就是Spring Cloud Feign。它基于Netflix Feign实现,整合了Spring Cloud Ribbon和Spring Cloud Hystrix,
除了提供两者强大的功能外,还提供了一种声明式的Web服务客户端定义方式。
二、入门实例
我们还是继续使用前面随笔中的hello-service服务,这里通过Spring Cloud Feign提供的声明式服务绑定功能来实现对服务接口的调用。
我们需要新建一个feign-consumer来代替之前的hello-consumer
先给出代码结构:
代码实现:
- 新建maven工程(feign-consumer)
- 修改pom文件,引入eureka和feign依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.sam</groupId> <artifactId>feign-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <properties> <javaVersion>1.8</javaVersion> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR6</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- 引入eureka 客户端依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!-- 引入feign 依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> </dependencies> </project>
- 新建启动类
/** * 通过@EnableFeignClients来开启spring cloud feign的支持功能 * */ @EnableFeignClients @EnableDiscoveryClient @SpringBootApplication public class FeiApp { public static void main(String[] args) { SpringApplication.run(FeiApp.class, args); } }
- 新建service接口
/** * 通过@FeignClient注解指定服务名来绑定服务,这里的服务名字不区分大小写 * 然后再通过@RequestMapping来绑定服务下的rest接口 * */ @FeignClient(name="hello-service") public interface FeignConsumerService{ @RequestMapping("/hello") public void hello(); }
- 新建controller
@RestController public class FeiConsumerController { @Autowired FeignConsumerService consumerService; @RequestMapping("feign-consumer") public String feignConsumer() { consumerService.hello(); return "feign consumer call finished!!!"; } }
- 新建application.properties
server.port=9001 spring.application.name=feign-consumer eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka
- 测试,
- 启动服务注册中心eureka、启动两个hello-service(端口号分别为9090和9091),启动feign-consumer
- 访问http://localhost:9001/feign-consumer
- 启动服务注册中心eureka、启动两个hello-service(端口号分别为9090和9091),启动feign-consumer
并且多次访问的话,会轮询调用两个hello-service服务。
三、参数绑定
在上面的例子中,我们实现的只是一个不带参数的rest服务绑定,然而现实的业务中不会这么简单,往往会有各种参数,
这个时候我们做如下事情:
- 如果服务提供方有对象参数(如User对象),那么feign-consumer工程中需要建一个路径和类名完全一样的类。
- 然后将服务提供方controller里面的所有方法声明进行copy(包括前面的@RequestMapping),粘贴到feign-consumer的service接口里面。
四、继承特性
根据上面参数绑定的做法,我们需要进行很多copy操作,这样比较麻烦,可以通过继承的方式进行简化。
这种实现步骤如下:
1.我们需要新建一个基础工程hello-service-api,
代码结构:
代码实现:
- )新建maven项目hello-service-api
- )修改pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.sam</groupId> <artifactId>hello-service-api</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <properties> <javaVersion>1.8</javaVersion> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
你会发现其实就是一个普通的spring boot项目。
- )考虑到需要掩饰参数中有对象的情况,我们加个User类
package com.sam.entity; public class User { private String name; private Integer age; public User(String name, Integer age) { super(); this.name = name; this.age = age; } public User() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
User必须要有一个无参数的构造器。
- )新建service接口
/** * 为了同前面那个hello 接口区分开了,我们加了refactor前缀 * */ @RequestMapping("/refactor") public interface HelloService { @RequestMapping("/hello2") public String hello2(); @RequestMapping("/hello3") public User printUser(@RequestBody User user); }
2.重构hello-sevice服务
- )修改pom文件
<!-- 引入 hello-service-api的依赖,以继承其提供的接口 --> <dependency> <groupId>com.sam</groupId> <artifactId>hello-service-api</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
- )HelloController implements HelloService,并实现interface中的接口
@RestController public class HelloController implements HelloService{ Logger logger = LoggerFactory.getLogger(HelloController.class); @Autowired DiscoveryClient discoveryClient; @RequestMapping("/hello") public String hello() throws Exception { ServiceInstance instance = discoveryClient.getLocalServiceInstance(); //打印服务的服务id logger.info("*********" + instance.getServiceId()); return "hello,this is hello-service"; } @Override public String hello2() { return "hello,this is hello2-service"; } @Override public User printUser(@RequestBody User user) { return user; } }
controller实现接口的方法时,不需要@RequestMapping注解,只需要类注解@RestController即可。
3.重构feign-consumer服务
- )修改POM文件
<!-- 引入 hello-service-api的依赖,以继承其提供的接口 --> <dependency> <groupId>com.sam</groupId> <artifactId>hello-service-api</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
- )让FeignConsumerService extends hello-service-api中的HelloService
/** * 通过@FeignClient注解指定服务名来绑定服务,这里的服务名字不区分大小写 * 然后再通过@RequestMapping来绑定服务下的rest接口 * */ @FeignClient(name="hello-service") public interface FeignConsumerService extends HelloService{ @RequestMapping("/hello") public void hello(); }
只需要继承即可。
- )修改controller,追加方法
@RestController public class FeiConsumerController { @Autowired FeignConsumerService consumerService; @RequestMapping("feign-consumer") public String feignConsumer() { consumerService.hello(); return "feign consumer call finished!!!"; } @RequestMapping("feign-consumer-user") public User feignConsumer2(User user) { consumerService.hello2(); return consumerService.printUser(user); } }
4.测试
五、其他
由于Spring Cloud Feign是通过ribbon和hystrix实现具体功能的,因此可以直接通过配置这两个来实现功能
1.ribbon配置方式:
通过ribbon.<key>=<value>的方式进行全局配置,比如
ribbon.ConnectTimeout=500
ribbon.ReadTimeout=5000
通过<client>.ribbon.<key>=<value>的方式进行指定服务配置,比如
#这里的<client>为@FeignClient(value="hello-service")指定的服务名
hello-service.ribbon.ConnectTimeout=500
hello-service.ribbon.ReadTimeout=500
2.hystrix配置方式:
通过hystrix.command.default.xxx进行全局配置
如:hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
通过hystrix.command.<commandKey>.xxx进行指定配置,这里的<commandKey>可以为方法名
如:hystrix.command.hello.execution.isolation.thread.timeoutInMilliseconds=5000
3.请求压缩配置,支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。
feign.compression.request.enabled=true;
feigan.compression.response.enabled=true;
4.日志配置
Spring Cloud Feign在构建被@FeignClient注解修饰的服务客户端是,会为每一个客户端都创建一个feign.Logger实例,我们可以利用该日志对象进行Log分析。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Spring系列.ApplicationContext接口 2020-06-11
- springboot2配置JavaMelody与springMVC配置JavaMelody 2020-06-11
- 给你一份超详细 Spring Boot 知识清单 2020-06-11
- SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 2020-06-11
- 掌握SpringBoot-2.3的容器探针:实战篇 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash