1. Feign介绍
Feign是一个rest客户端框架,能够访问远程web service,在之前的列子中,我们在invoke-service中调用provide-service时,使用了spring自带的resttemplate来访问服务。而Feign会使我们的访问更加简单,使用它的注解我们将会很方便的访问web service。下面就让我们开始学习吧。
2.改造provide-service1,使它变成多个实例注册到Eureka。
修改provideServer醒目的application.yml文件,使用profiles来配置两份配置参数:
spring:
profiles: p1
application:
name: provider-server1
server:
port: 8091
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
---
spring:
profiles: p2
application:
name: provider-server2
server:
port: 8092
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
修改启动类:
package com.demo;
import java.util.Scanner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class App {
public static void main(String[] args) {
//控制台输入p1,p2
Scanner scan = new Scanner(System.in);
String profiles = scan.nextLine();
new SpringApplicationBuilder(App.class).profiles(profiles).run(args);
}
}
运行启动类在ide控制台输入p1启动provider-server1,然后再次运行启动类,输入p2启动provider-server2。
然后访问之前的Eureka,访问http://localhost:8761/,发现已经有两个服务provider-server1,provider-server2。
3.改造invokerService,使用Feign来调用上面的两个服务。
添加Feign的依赖:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</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-ribbon</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
修改启动端口,应为之前的8092已经被上面的服务占用了,你也可以使用其他端口:
spring:
application:
name: invoker-server1
server:
port: 8093
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
新建Feign客户端调用接口CallClient:
package com.demo;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient("provider-server1") //申明调用服务
public interface CallClient {
@GetMapping("/api/hello")
String hello();
}
修改启动类,添加注解@EnableFeignClients
package com.demo;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class App {
public static void main(String[] args) {
new SpringApplicationBuilder(App.class).run(args);
}
}
修改CallService:
package com.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Configuration
public class CallService {
@Autowired
private CallClient ccl;
@GetMapping("/call")
public String call(){
return ccl.hello();
}
}
启动应用,访问http://localhost:8761/,发现3个服务都启动,然后访问http://localhost:8093/call,正常显示:hello world。刚才我们只是访问了provider-server1,现在我们要改造一下,让Feign实现负载均衡。
在provideServer,application.yml中将两个服务的名称都改为:provider-server。
修改RestApi:
package com.demo;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@RestController
public class RestApi {
@GetMapping("/api/hello")
public String Hello(){
ServletRequestAttributes requestAttr = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttr.getRequest();
System.out.println("请求了:"+request.getRequestURL());
return "hello world";
}
}
然后重新启动服务提供者:provideServer。
修改invokerService,CallClient,让其调用provider-server:
package com.demo;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient("provider-server") //申明调用服务
public interface CallClient {
@GetMapping("/api/hello")
String hello();
}
重新启动应用,然后访问http://localhost:8093/call,控制台会轮流显示:
请求了:http://localhost:8091/api/hello
请求了:http://localhost:8092/api/hello
这样feign就帮我们做好了负载均衡,美滋滋。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。