SpringCloud实战之Feign声明式服务调用

网友投稿 212 2023-02-04


SpringCloud实战之Feign声明式服务调用

在前面的文章中可以发现当我们通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还可以忍受,一旦有多个参数的话,这时拼接请求字符串就会效率低下,并且显得好傻。

那么有没有更好的解决方案呢?答案是确定的有,Netflix已经为我们提供了一个框架:Feign。

Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。

而Feign则会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了Ribbon和Hystrix(关于Hystrix我们后面再讲),可以让我们不再需要显式地使用这两个组件。

总起来说,Feign具有如下特性:

可插拔的注解支持,包括Feign注解和JAX-RS注解;

支持可插拔的HTTP编码器和解码器;

支持Hystrix和它的Fallback;

支持Ribbon的负载均衡;

支持HTTP请求和响应的压缩。

这看起来有点像我们springmvc模式的Controller层的RequestMapping映射。这种模式是我们非常喜欢的。Feign是用@FeignClient来映射服务的。

首先第一步,在原来的基础上新建一个Feign模块,接着引入相关依赖,引入Feign依赖,会自动引入Hystrix依赖的,如下:

org.springframework.cloud

spring-cloud-starter-eureka

1.3.5.RELEASE

org.springframework.clohttp://ud

spring-cloud-starter-feign

1.4.0.RELEASE

application.yml配置如下:

server:

port: 8083

spring:

application:

name: feign-consumer

eureka:

client:

service-url:

defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/

接着在前面文章中的的的两个provider1和provider2两个模块的服务新增几个方法,如下代码所示:

/**

* Created by cong on 2018/5/8.

*/

@RestController

public class HelloController {

@RequestMapping("/hello")

public String hello(){

System.out.println("访问来1了......");

return "hello1";

}

@RequestMapping("/hjcs")

public List laowangs(String ids){

List list = new ArrayList<>();

list.add("laowang1");

list.add("laowang2");

list.add("laowang3");

return list;

}

//新增的方法

@RequestMapping(value = "/hellol", method= RequestMethod.GET)

public String hello(@RequestParam String name) {

return "Hello " + name;

}

@RequestMapping(value = "/hello2", method= RequestMethod.GET)

public User hello(@RequestHeader String name, @RequestHeader Integer age) {

return new User(name, age);

}

@RequestMapping(value = "/hello3", method = RequestMethod.POST)

public String hello (@RequestBody User user) {

return "Hello "+ user. getName () + ", " + user. getAge ();

}

}

接着是上面代码所需用到的User类,代码如下:

/**

* Created by cong 2017/12/2.

*/

public class User {

private String name;

private Integer age;

//序列化传输的时候必须要有空构造方法,不然会出错

public User() {

}

public User(String name, Integer age) {

this.name = name;

this.age = age;

}

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;

}

}

接下来用Feign的@FeignClient(“服务名称”)映射服务调用。代码如下:

package hjc;

import org.springframework.cloud.netflix.feign.FeignClient;

import org.springframework.web.bind.annotation.*;

/**

* Created by cong on 2018/5/17.

*/

//configuration = xxx.class 这个类配置Hystrix的一些精确属性

//value=“你用到的服务名称”

@FeignClient(value = "hello-service",fallback = FeignFallBack.class)

public interface FeignService {

  //服务中方法的映射路径

@RequestMapping("/hello")

String hello();

@RequestMapping(value = "/hellol", method= RequestMethod.GET)

String hello(@RequestParam("name") String name) ;

@RequestMapping(value = "/hello2", method= RequestMethod.GET)

User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age);

@RequestMapping(value = "/hello3", method= RequestMethod.POST)

String hello(@RequestBody User user);

}

接着在Controller层注入FeiService这个接口,进行远程服务调用,代码如下:

/**

* Created by cong on 2018/5/17.

*/

@RestController

public class ConsumerController {

@Autowired

FeignService feignService;

@RequestMapping("/consumer")

public String helloConsumer(){

return feignService.hello();

}

@RequestMapping("/consumer2")

public String helloConsumer2(){

String r1 = feignService.hello("hjc");

String r2 = feignService.hello("hjc", 23).toString();

String r3 = feignService.hello(new User("hjc", 23));

return r1 + "-----" + r2 + "----" + r3;

}

}

接着在Feign模块的启动类哪里打上Eureka客户端的注解@EnableDiscoveryClient  Feign客户端的注解

ADRFL

@EnableFeignClients,代码如下:

@SpringBootApplication

@EnableDiscoveryClient

@EnableFeignClients

public class FeignApplication {

pADRFLublic static void main(String[] args) {

SpringApplication.run(FeignApplication.class, args);

}

}

接着启动启动类,浏览器上输入localhost:8083/consumer  运行结果如下:

可以看到负载均衡轮询出现hello1,hello2。

接着继续在浏览器上输入localhost:8083/consumer2,运行结果如下:

接下来我们进行Feign声明式调用服务下的,服务降级的使用,那么我们就必须新建一个FeignFallBack类来继承FeiService,代码如下:

package hjc;

import org.springframework.stereotype.Component;

/**

* Created by cong on 2018/5/17.

*/

@Component

public class FeignFallBack implements FeignService{

  //实现的方法是服务调用的降级方法

@Override

public String hello() {

return "error";

}

@Override

public String hello(String name) {

return "error";

}

@Override

public User hello(String name, Integer age) {

return new User();

}

@Override

public String hello(User user) {

return "error";

}

}

接着我们再把那两个服务提供模块provider1,provider2模块进行停止,运行结果如下所示:

可以看到我们这几个调用,都进行了服务降级了。

那么如果我们想精确的控制一下Hystrix的参数也是可以的,比方说跟Hystrix结合的参数,那么可以在FeignClient注解里面配置一个Configuration=XXX类.class属性,在哪个类里面精确的指定一下属性。

或者在application.yml里面配置,如下:

hystrix:

command:

default:

execution:

isolation:

thread:

timeoutinMilliseconds: 5000

ribbon:

connectTimeout: 500

#如果想对单独的某个服务进行详细配置,如下

hello-service:

ribbon:

connectTimeout: 500

这里满足了我们大部分场景的调用,但是有写精细场景,还是要用原生的Hystrix,跟我们之前的Hystrix用法一下,不要走Feign客户端调用就行了,如下:

/**

* Created by cong on 2018/5/17.

*/

public class HjcCommand extends HystrixCommand {

protected HjcCommand(HystrixCommandGroupKey group) {

super(group);

}

@Override

protected Object run() throws Exception {

return null;

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java线程状态(java线程状态机)
下一篇:SpringBoot 动态定时器的使用方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~