SpringCloud-Feign(老版本)
1, 两种服务调用方式
1,Feign
2,restTemplate
1,1 RestTemplate
1, application.yml
server:
port: 8084
spring:
application:
name: feign-customer-example
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
2,在启动类中配置一个 bean
@Bean
@LoadBalanced//在注册中心里进行查找微服务,负载均衡
public RestTemplate restTemplate(){
RestTemplate restTemplate=new RestTemplate();
return restTemplate;
}
3,使用 restTemplate 调用服务
package com.zgjt.controller;
import com.netflix.discovery.converters.Auto;
import com.zgjt.feign.FeignDemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class EurakeTest {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("testRestTemplate")
public void test(){
restTemplate.getForEntity("http://EUREKA-CLIENT/eurakeTest",String.class);
}
}
注意:高版本的时候,貌似 loadBalance 需要导包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
<version>3.1.1</version>
</dependency>
2, Feign
Feign 在 restTemplate 基础上做一次封装,定义和注册中心同样的接口,就可以调用注册中心的服务
这是 openFeign,区别于 Feign,继承了 SpringMvc 的注解
1,pom
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId> com.alibaba.cloud</groupId>
<artifactId> spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
</dependencies>
2,application.yml
server:
port: 8084
spring:
application:
name: feign-customer-example
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
##不需要注册服务
register-enabled: false
3,定义 feign 接口
//注册到 nacos 的服务名
@FeignClient("nacos-provider-example")
@Component
public interface NacosProviderDemo {
//方法签名要相同
@PostMapping("/test")
String helloNacos();
}
4,新建 controller 调用 feign
package com.zgjt.controller;
import com.zgjt.feign.NacosProviderDemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FeignTest {
@Autowired
private NacosProviderDemo feignDemo;
@RequestMapping("/feignTest")
public String test(){
return feignDemo.helloNacos() ;
}
}
5,启动类添加 @EnableFeignClients
package com.zgjt;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class FeignCustomerApplication {
public static void main(String[] args){
SpringApplication.run(FeignCustomerApplication.class,args);
}
}
2, 负载均衡 Ribbon
ribbon 负载均衡策略,默认策略是轮询
内置负载均衡规则类 | 规则描述 |
---|---|
RoundRobinRule | 简单轮询服务列表来选择服务器。它是Ribbon默认的负载均衡规则。 |
AvailabilityFilteringRule | 对以下两种服务器进行忽略: (1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。 (2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的..ActiveConnectionsLimit属性进行配置。 |
WeightedResponseTimeRule | 为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。 |
ZoneAvoidanceRule | 以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询。 |
BestAvailableRule | 忽略那些短路的服务器,并选择并发数较低的服务器。 |
RandomRule | 随机选择一个可用的服务器。 |
RetryRule | 重试机制的选择逻辑 |
2.1 restTemplate
添加负载均衡策略 @LoadBalanced
修改负载均衡策略,启动类中自定义一个 bean
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ApplicationContentConfig {
@Bean
@LoadBalanced //开启ribbon自带负载均衡
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
//修改轮询策略为随机
@Bean
public IRule myRule(){
return new RandomRule();
}
}
2.2, Feign
feign 已经集成了 ribbon,修改 feign 轮询策略, application.properties 中添加
EUREKA-CLIENT.ribbon.NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
EUREKA-CLIENT 是提供者服务名
或者在启动类中添加, 其中 WeightedResponseTimeRule 权重方式,需要在 nacos 中配置权重
//修改轮询策略为随机
@Bean
public IRule myRule(){
return new RandomRule();
}
2.3 Ribbon 重试机制
当调用服务,超时未响应的时候,会根据配置重新调用服务
主要配置
ribbon:
ReadTimeout: 1000
ConnectTimeout: 1000
MaxAutoRetries: 1 #同一台实例最大重试次数,不包括首次调用
MaxAutoRetriesNextServer: 1 #重试负载均衡其他的实例最大重试次数,不包括首次调用
OkToRetryOnAllOperations: false #是否所有操作都重试
根据上面的参数计算重试的次数, 即重试3次 则一共产生4次调用
MaxAutoRetries + MaxAutoRetriesNextServer + ( MaxAutoRetries * MaxAutoRetriesNextServer )
另外, ribbon 默认重试一次, 读取数据时间为 1s
3. hystrix 熔断器
如果在 Ribbon 重试期间,时间超过了hystrix的超时时间,便会立即执行熔断,fallback。所以要根据上面配置的参数计算hystrix的超时时间,使得在重试期间不能达到hystrix的超时时间,不然重试机制就会没有意义
hystrix超时时间的计算:
(1 + MaxAutoRetries + MaxAutoRetriesNextServer) * ReadTimeout
hystrix 熔断机制使用(这个 pom 和 ribbon 的 pom 都已经集成再 feign 中,可以不用引入)
1,Pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2,application.yml
#启动 hystrix
feign:
hystrix:
enabled: true
##请求进行重试
hystrix:
command:
Feign#test():
execution:
isolation:
thread:
timeoutInMilliseconds: 4000
3,实现 feign 接口,做降级处理
package com.zgjt.hystrix;
import com.zgjt.feign.FeignDemo;
import org.springframework.stereotype.Component;
@Component
public class HystrixDemo implements FeignDemo {
@Override
public String test() {
System.out.println("hello hystrix");
return "1";
}
}
4,feign 接口声明调用失败使用的实现类,添加 fallback 参数
@FeignClient(name ="service-vod",fallback = HystrixDemo.class)
@Component
public interface VodClient {
@PostMapping("/vod/videos/dropVideos")
ResultApi dropVideos(@RequestBody String videoId);
}