pom依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</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-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
spring-cloud-starter-openfeign这个类主要为feign的依赖,其他类都是为了后续的turbine做的准备,这里小小解释一下
spring-cloud-starter-netflix-hystrix 断路器,官网上面这里名字拼错了,导致我一直找不到依赖,后面去了maven仓库捞了一下,发现名字对不上,不仔细看还发现不了,坑
spring-cloud-netflix-hystrix-stream和spring-cloud-starter-stream-rabbit 为流量收集,官网上的demo是以http长连接作为案例,但是感觉http收集流量的形式不够优雅,改用了消息队列来收集。
spring-boot-starter-actuator 健康信息(内存啊,磁盘啊,网络之类的监控)暂时未用到,后续探索
关于流量收集,这个内容比较多,会在turbine的章节重点解释,这里不再展开了,我们还是回归主题。
启动类加入注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableHystrix
@EnableCircuitBreaker
public class ExampleFeignApplication {
public static void main(String[] args) {
SpringApplication.run(ExampleFeignApplication.class, args);
}
}
使用
zuul会将流量转入到这个接口,可以看上一章的zuul配置文件配置,这个控制器引入了一个ExampleClient的服务,这个服务就是为了连接到我们的客户端的。(feign通常作为两个服务集群之间互通的桥梁,这里作为演示,把它直接塞在了zuul和client之间,实际场景一般是 zuul连接client,client与client之间的通信用feign)
@RestController
public class FeignController {
@Autowired
ExampleClient example;
@RequestMapping(value = "/hello",method = RequestMethod.GET)
public String hello(){
return example.helloCloud();
}
}
ExampleClinet 服务的内容,是一个接口,同时通过feign进行负载均衡(feign底层也是通过ribbon),我们看到这个服务会将请求转发到cilent的hello接口,是一个get请求(还记得第二章的cilent吗),同时我们看到@FeignClient有两个参数
value = “example-client” 指的客户端client,注册到eureka的实例名称,
fallbackFactory 当客户端不可访问的时候,会执行这个回退,当我们客户端挂掉或者繁忙的时候,我们可以返回一些有用的信息回去而不是抛出异常。
fallbackFactory和fallback 不能同时使用,这里简单介绍一下fallbck这个参数,这个参数和fallbackFactory基本上是没有多大区别,要表达的内容也是一致的,就是回退的时候带回有用的信息或执行一个什么样的逻辑, 不同的点在实现的方法上不一样,附上官方原话,这里采用了factory的实现方式。(采用另一种也完全没问题,性能上没有区别,全看个人喜好)
@FeignClient(value = "example-client",fallbackFactory = HystrixClientFallbackFactory.class)
public interface ExampleClient {
@RequestMapping(method = RequestMethod.GET,value = "/hello")
String helloCloud();
}
@Component
public class HystrixClientFallbackFactory implements FallbackFactory<ExampleClient> {
@Override
public ExampleClient create(Throwable throwable) {
return new ExampleClient() {
@Override
public String helloCloud() {
// 可以做复杂的业务
return "连接超时: " + throwable.getMessage();
}
};
}
}
feign配置文件
server:
port: 8752
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka
feign:
hystrix:
enabled: true
spring:
rabbitmq:
host: 172.16.10.2
username: test
password: test
port: 5672
virtual-host: turbine
feign.hystrix.enabled 表示是否打开断路,这个选项的作用很多,可以百度一下了解更多。
rabbitmq的配置是为了后续流量收集设置的,这里我在内网装了一个rabbitmq,同时创建了一个test的用户,该配置根据实际进行修改。
最后
feign通常作为两个client之间调用的组件①,可以将feign组件直接嵌入到client端,这样两个client端就可以通过feign互相调用对方的接口,同时在服务不可能用的时候,可以降级得到一个相对平滑的返回而不是调用超时或者抛出异常。
①解释: Feign本身还是HTTP调用,HTTP本身是基于应用层的协议,相比基于传输层协议的RPC效率还是要低一些。
总结:
- 速度来看,RPC要比http更快,http协议的信息往往比较臃肿。
- 难度来看,RPC实现较为复杂,http相对比较简单。
- 灵活性来看,http更好,因为它不关心实现细节,跨平台、跨语言。