Spring Cloud系列-微服务篇(六) 服务消费者 Feign
1.准备
在spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端。我们可以使用JDK原生的URLConnection、Apache的Http Client、Netty的异步HTTP Client, Spring的RestTemplate。但是,用起来最方便、最优雅的还是要属Feign了。
Feign是一个声明式的Web Service客户端,它使得编写Web Serivce客户端变得更加简单。我们只需要使用Feign来创建一个接口并用注解来配置它既可完成。它具备可插拔的注解支持,包括Feign注解和JAX-RS注解。
Feign也支持可插拔的编码器和解码器。Spring Cloud为Feign增加了对Spring
MVC注解的支持,还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。
2.使用Feign实现客户端负载均衡的消费者
1.通过 http://start.spring.io/ 使用SPRING INITIALIZR 创建一个基础的Spring Boot工程,
- Dependencies :Eureka Discovery + Feign
- Group : com.alanzh.platform
- Artifact : wish.feign.server
- Spring boot 版本: 1.5.4
<?xml version="1.0" encoding="UTF-8"?>
<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.alanzh.platform</groupId>
<artifactId>wish.feign.server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>wish.feign.server</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Dalston.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@EnableFeignClients注解开启Feign功能
@EnableDiscoveryClient注解来添加发现服务能力。
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
定义wish.user.service服务的接口,具体如下:
@FeignClient(name="wish.user.service")
public interface UserFeignService {
@RequestMapping(value="/user/{userEntryID}", method=RequestMethod.GET)
String getUserEntry(@PathVariable("userEntryID") Long userEntryID);
}
@FeignClient用于通知Feign组件对该接口进行代理(不需要编写接口实现),使用者可直接通过@Autowired注入。
value="/user/{userEntryID}"用来接收参数并传递参数到URI.
@PathVariable("userEntryID") Long userEntryID 请不要忽略这里的@PathVariable("userEntryID")
@FeignClient(name="wish.user.service")
注解来绑定该接口对应wish.user.service服务
创建Controller层调用wish.user.service服务的接口来消费wish.user.service服务.
@RestController
public class UserFeignAction {
@Autowired
UserFeignService userFeignService;
@RequestMapping(value="/user/{userEntryID}", method=RequestMethod.GET)
public String getUserEntry(@PathVariable Long userEntryID) {
// 通过HTTP调用远程服务
return userFeignService.getUserEntry(userEntryID);
}
}
application.properties中配置eureka服务注册中心
server.port=4000
spring.application.name=@project.name@
eureka.client.serviceUrl.defaultZone=http://localhost:1000/eureka/
启动应用,访问:http://localhost:4000/user/1
wish.user.service的两个服务提供方,分别输出了类似下面的日志内容:
2017-04-28 02:02:12.664 INFO 12912 --- [nio-2000-exec-4] c.a.p.controller.HelloWorldController : /hello, host:ALAN-HOME, service_id:ms-hello-world-service,Hello name
到这里,我们已经通过Feign在客户端已经实现了对服务调用的均衡负载。
Spring Cloud应用在启动时,Feign会扫描标有@FeignClient注解的接口,生成代理,并注册到Spring容器中。生成代理时Feign会为每个接口方法创建一个RequetTemplate对象,该对象封装了HTTP请求需要的全部信息,请求参数名、请求方法等信息都是在这个过程中确定的,Feign的模板化就体现在这里。
期待更新