java学习微服务实践springcloud学习

spring cloud feign学习一:快速入门

2017-09-02  本文已影响401人  二月_春风

Feign是什么?官网的一段话。

Feign is a declarative(声明式) web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable(可插拔) annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates(集成) Ribbon and Eureka to provide a load balanced http client when using Feign.

通过对spring cloud ribbonspring cloud hystrix的介绍,我们已经掌握了开发微服务应用时的两个重磅武器,学会了如何在微服务架构中实现客户端负载均衡的服务调用以及如何通过断路器来保护我们的微服务应用。这二个组件都被广泛地应用在各个微服务实现中,不仅包括我们自身的业务类微服务,也包括一些基础设施类微服务(比如网关)。此外,在实践中,我们发现几乎对这二个框架的使用几乎都是同时出现的。既然如此,那么是否有更高层次的封装来整合这二个基础工具以简化开发呢?spring cloud feign就是一个这样的工具。它基于Netfix Feign实现,整合了spring cloud Ribbonspring cloud Hystrix,除了提供这二者的强大功能之外,它还提供了一种生命式的web服务客户端定义方式。

我们在使用spring cloud ribbon时,通常会利用它对rersttemplate的请求拦截来实现对依赖服务的接口调用,而RestTemplate已经实现了对http请求的封装处理,形成了一套模版花的调用方法。之前已经介绍了RestTemplate调用的实现,但是在实际开发中,由于对服务依赖的调用可能不止于一处,往往一个接口会被多处调用,所以我们通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。这个时候我们发现,由于RestTemplate的封装,几乎每一个调用都是简单的模版化内容。

综合上述所说,spring cloud feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在spring cloud feign的实现下,我们只需创建一个接口并调用注解的方式来配置它,即可完成对服务提供方的接口绑定,简化了使用spring cloud ribbon时自动封装服务调用客户端的开发量。spring cloud feign具备可插拔的注解支持,包括feign注解和JAX-RS注解。同时,为了适应Spring的广大用户,它在Netfix Feign的基础上扩展了spring mvc的注解支持,这对于习惯spring mvc的开发者来说,无疑是个好消息,因为这样可以大大减少学习使用它的成本。另外,对于feign自身的一些主要组件,比如说编码器和解码器等,它也以可插拔的方式提高,在有需要的时候我们可以方便地扩展和替换它们。

快速入门

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
    </dependencies>
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class PayApplication {

    public static void main(String[] args) {
        SpringApplication.run(PayApplication.class,args);
    }
}
@FeignClient("user-service")
public interface UserService {

    @RequestMapping(value = "/user/index",method = RequestMethod.GET)
    String index();

    @RequestMapping(value = "/user/hello",method = RequestMethod.GET)
    String hello();
}

这里,这里的服务名不区分大小写,所以user-serviceUSER_SERVICE都可以的。另外,在Camden.SR7版本中,原本的serviceId属性已经被废弃了,若要写属性名,可以使用namevalue

@RestController
@RequestMapping("/pay")
public class PayController {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    UserService userService;

    @RequestMapping("/index")
    public String index(){
        return userService.index();
    }

    @RequestMapping("/hello")
    public String hello(){
        return userService.hello();
    }
}
spring:
  application:
    name: pay-service
eureka:
  client:
    service-url:
     defaultZone: http://localhost:8761/eureka
  instance:
    instance-id:  ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
server:
  port: 7070
Eureka控制面板

发送多个请求http://192.168.5.3:7070/pay/index,发现二个user-service都能在控制台打印日志,我们看到了feign实现的消费者,依然是利用了Ribbon维护了user-service的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过feign我们只需要定义服务绑定接口,以声明式的方法,优雅而简单的实现了服务调用。

注意
我们知道为了适应Spring的广大用户,它在Netfix Feign的基础上扩展了spring mvc的注解支持,但是springmvc4.0出现的一系列注解比如@GetMapping,@PostMapping,@PutMapping等等是Feign是不支持的,比如在pay项目中定义的UserService接口,如果在

@FeignClient(value = "user-service")
public interface UserService {

//    @RequestMapping(value = "/user/index",method = RequestMethod.GET)
    @GetMapping("/user/index")
    String index();
...

在启动的时候就会抛出如下的异常


当然这些所谓的坑在开发阶段便会发现。

参考资料
Declarative REST Client: Feign

代码地址
代码地址

上一篇下一篇

猜你喜欢

热点阅读