java声明式服务_spring cloud 入门系列五:使用Feign 实现声明式服务调用

一、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

先给出代码结构:

fb2b9408da1805732721ed082c0ad9aa.png

代码实现:

新建maven工程(feign-consumer)

修改pom文件,引入eureka和feign依赖

4.0.0

com.sam

feign-consumer

0.0.1-SNAPSHOT

org.springframework.boot

spring-boot-starter-parent

1.5.1.RELEASE

1.8

org.springframework.cloud

spring-cloud-dependencies

Camden.SR6

pom

import

org.springframework.cloud

spring-cloud-starter-eureka

org.springframework.cloud

spring-cloud-starter-feign

新建启动类

/*** 通过@EnableFeignClients来开启spring cloud feign的支持功能

**/@EnableFeignClients

@EnableDiscoveryClient

@SpringBootApplicationpublic classFeiApp {public static voidmain(String[] args) {

SpringApplication.run(FeiApp.class, args);

}

}

新建service接口

/*** 通过@FeignClient注解指定服务名来绑定服务,这里的服务名字不区分大小写

* 然后再通过@RequestMapping来绑定服务下的rest接口

**/@FeignClient(name="hello-service")public interface FeignConsumerService{

@RequestMapping("/hello")public voidhello();

}

新建controller

@RestControllerpublic classFeiConsumerController {

@Autowired

FeignConsumerService consumerService;

@RequestMapping("feign-consumer")publicString feignConsumer() {

consumerService.hello();return "feign consumer call finished!!!";

}

}

新建application.properties

server.port=9001spring.application.name=feign-consumer

eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka

测试,启动服务注册中心eureka、启动两个hello-service(端口号分别为9090和9091),启动feign-consumer

e36b35dcc340531f2566bb0d21bb53d7.png

访问http://localhost:9001/feign-consumer

19a15e577a562919e04d1eec684833d9.png

并且多次访问的话,会轮询调用两个hello-service服务。

三、参数绑定

在上面的例子中,我们实现的只是一个不带参数的rest服务绑定,然而现实的业务中不会这么简单,往往会有各种参数,

这个时候我们做如下事情:

如果服务提供方有对象参数(如User对象),那么feign-consumer工程中需要建一个路径和类名完全一样的类。

然后将服务提供方controller里面的所有方法声明进行copy(包括前面的@RequestMapping),粘贴到feign-consumer的service接口里面。

四、继承特性

根据上面参数绑定的做法,我们需要进行很多copy操作,这样比较麻烦,可以通过继承的方式进行简化。

这种实现步骤如下:

1.我们需要新建一个基础工程hello-service-api,

代码结构:

d50a048493141438ff4abffab70ef9ef.png

代码实现:

)新建maven项目hello-service-api

)修改pom文件

4.0.0

com.sam

hello-service-api

0.0.1-SNAPSHOT

org.springframework.boot

spring-boot-starter-parent

1.5.1.RELEASE

1.8

org.springframework.boot

spring-boot-starter-web

你会发现其实就是一个普通的spring boot项目。

)考虑到需要掩饰参数中有对象的情况,我们加个User类

packagecom.sam.entity;public classUser {privateString name;privateInteger age;publicUser(String name, Integer age) {super();this.name =name;this.age =age;

}publicUser() {super();

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}publicInteger getAge() {returnage;

}public voidsetAge(Integer age) {this.age =age;

}

}

User必须要有一个无参数的构造器。

)新建service接口

/*** 为了同前面那个hello 接口区分开了,我们加了refactor前缀

**/@RequestMapping("/refactor")public interfaceHelloService {

@RequestMapping("/hello2")publicString hello2();

@RequestMapping("/hello3")publicUser printUser(@RequestBody User user);

}

2.重构hello-sevice服务

)修改pom文件

com.sam

hello-service-api

0.0.1-SNAPSHOT

)HelloController implements HelloService,并实现interface中的接口

@RestControllerpublic class HelloController implementsHelloService{

Logger logger= LoggerFactory.getLogger(HelloController.class);

@Autowired

DiscoveryClient discoveryClient;

@RequestMapping("/hello")public String hello() throwsException {

ServiceInstance instance=discoveryClient.getLocalServiceInstance();//打印服务的服务id

logger.info("*********" +instance.getServiceId());return "hello,this is hello-service";

}

@OverridepublicString hello2() {return "hello,this is hello2-service";

}

@OverridepublicUser printUser(@RequestBody User user) {returnuser;

}

}

controller实现接口的方法时,不需要@RequestMapping注解,只需要类注解@RestController即可。

3.重构feign-consumer服务

)修改POM文件

com.sam

hello-service-api

0.0.1-SNAPSHOT

)让FeignConsumerService extends hello-service-api中的HelloService

/*** 通过@FeignClient注解指定服务名来绑定服务,这里的服务名字不区分大小写

* 然后再通过@RequestMapping来绑定服务下的rest接口

**/@FeignClient(name="hello-service")public interface FeignConsumerServiceextendsHelloService{

@RequestMapping("/hello")public voidhello();

}

只需要继承即可。

)修改controller,追加方法

@RestControllerpublic classFeiConsumerController {

@Autowired

FeignConsumerService consumerService;

@RequestMapping("feign-consumer")publicString feignConsumer() {

consumerService.hello();return "feign consumer call finished!!!";

}

@RequestMapping("feign-consumer-user")publicUser feignConsumer2(User user) {

consumerService.hello2();returnconsumerService.printUser(user);

}

}

4.测试

369e9c344aa20934f11e174b4a27de38.png

五、其他

由于Spring Cloud Feign是通过ribbon和hystrix实现具体功能的,因此可以直接通过配置这两个来实现功能

1.ribbon配置方式:

通过ribbon.=的方式进行全局配置,比如

ribbon.ConnectTimeout=500

ribbon.ReadTimeout=5000

通过.ribbon.=的方式进行指定服务配置,比如

#这里的为@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..xxx进行指定配置,这里的可以为方法名

如: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分析。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值