声明式服务调用 Spring Cloud Feign 搭建
Spring Cloud Feign 整合了Ribbon和Hystrix,提供了一种声明式的web服务客户端定义方式,我们只需创建一个接口并用注解的方式配置它们,就可以完成对服务提供方的接口的绑定,简化了使用Ribbon时自行封装服务调用客户端的开发量。
一 1 创建一个spring boot工程是服务调用的客户端, 取名为feign-consumer,pom文件如下
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2 创建应用主类FeignConsumerApplication,@EnableFeignClients注解开启spring cloud Feign的支持功能
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class FeignConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(FeignConsumerApplication.class, args);
}
}
3 定义接口和User类,通过@FeignClient注解注定服务名称来绑定服务,再使用spring mvc的注解来绑定该服务提供的Rest接口,注意Feign中绑定参数必须通过value属性指明具体的参数名称,这点跟spring mvc不一样。
@FeignClient(name="hello-service")
public interface HelloService {
@RequestMapping("/hello")
String hello();
@RequestMapping("/hello3")
public String hello3(@RequestParam("name") String name ) ;
@RequestMapping("/hello5")
public User hello5(@RequestHeader("name") String name,@RequestHeader("age") int age ) ;
@RequestMapping("/hello6")
public String hello6(@RequestBody User user ) ;
@RequestMapping("/hello7/{name}/{age}")
public User hello7(@PathVariable("name") String name,@PathVariable("age") int age) ;
}
public class User {
private String name;
private int age;
public User(String name, int 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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
4 创建一个Controller实现对Feign客户端的调用,
@RestController
public class ConsumerController {
@Autowired
private HelloService helloService;
@Autowired
private RefactorSayService refactorSayService;
@RequestMapping("/feign-consumer")
public String helloConsumer( ) {
System.out.println("feign-consumer---before");
String ss= helloService.hello();
System.out.println("ss="+ss);
System.out.println("feign-consumer---after");
return ss;
}
@RequestMapping("/feign-consumer3")
public String helloConsumer3( ) {
System.out.println("feign-consumer3---before");
String ss= helloService.hello3("erica");
System.out.println("ss="+ss);
System.out.println("feign-consumer3---after");
return ss;
}
@RequestMapping("/feign-consumer5")
public String helloConsumer5( ) {
System.out.println("feign-consumer5---before");
User user= helloService.hello5("erica",23);
System.out.println("ss="+user.getName()+","+user.getAge());
System.out.println("feign-consumer5---after");
return "ss="+user.getName()+","+user.getAge();
}
@RequestMapping("/feign-consumer6")
public String helloConsumer6( ) {
System.out.println("feign-consumer6---before");
String s= helloService.hello6(new User("wangli",22));
System.out.println("ss="+s);
System.out.println("feign-consumer6---after");
return s;
}
@RequestMapping("/feign-consumer7")
public String helloConsumer7( ) {
System.out.println("feign-consumer7---before");
User user= helloService.hello7("terry",27);
System.out.println("ss="+user.getName()+","+user.getAge());
System.out.println("feign-consumer7---after");
return "ss="+user.getName()+","+user.getAge();
}
}
5 application.yml的配置
server:
port: 9001
eureka:
client:
serviceUrl: #注册中心的注册地址
defaultZone: http://peer1:8761/eureka/,http://peer2:8771/eureka/
spring:
application:
name: feign-consumer
启动feign-consumer项目,如下图:
二 创建服务端项目,创建一个spring boot项目,取名为hello,controller类如下,
@RestController
public class HelloController {
private String name;
private String desc;
@RequestMapping("/hello")
public String index( ) {
return "Hello ="+name+",desc="+desc;
}
@RequestMapping("/hello2")
public String index2( ) {
return "Hello2";
}
@RequestMapping("/hello3")
public String hello3(@RequestParam String name ) {
return "Hello "+name;
}
@RequestMapping("/hello5")
public User hello5(@RequestHeader String name,@RequestHeader int age ) {
return new User(name,age);
}
@RequestMapping("/hello6")
public String hello6(@RequestBody User user) {
return user.getName()+","+user.getAge();
}
}
服务端配置如下:
server:
port: 8083
eureka:
client:
serviceUrl: #注册中心的注册地址
defaultZone: http://peer1:8761/eureka/,http://peer2:8771/eureka/
spring:
application:
name: hello-service
启动服务端,分别端口是8083,8088
三 访问客户端的地址,结果如下,多次访问,会发现2个服务实例轮训被调用,实现了负载均衡功能。
http://127.0.0.1:9001/feign-consumer