天天看点

SpringCloud之Ribbon ,Feign简单实现

微服务调用方式Ribbon

使用Ribbon来实现远程调用

1. 启动类中添加RestTemplate的bean
2.使用RestTemplate.getObject获取远程接口的信息
----------------------------------------------------------
  @Bean
    public RestTemplate template(){
        return new RestTemplate();
    }
---------------------------------------------------------
   @Autowired
    private RestTemplate template;
    public static final String PRODUCT_URL = "http://localhost:8080";

    @Override
    public Order save(Long userId, Long productId) {
        Product product = template.getForObject(PRODUCT_URL + "/products/get/" + productId, Product.class);//远程获取
           

使用Ribbon实现负载均衡

1. 修改启动类OrderMain8090 ,在@Bean上贴 @LoadBalanced //负载均衡
2. 修改订单服务OrderServiceImpl 此时url可以通过name从注册中心获取
3. 修改ProductController 
4. 负载均衡策略调整 默认轮询策略
---------------------------------------------------------------
在RestTemplate的bean上贴上@LoadBalanced注解

@SpringBootApplication
@EnableEurekaClient
public class OrderMain8090 {
    @Bean
    @LoadBalanced //负载均衡
    public RestTemplate template(){
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(OrderMain8090.class, args);
    }
}
----------------------------------------------------------------
    private RestTemplate template;
    public static final String PRODUCT_URL = "http://PRODUCT-SERVER";

    @Override
    public Order save(Long userId, Long productId) {
        Product product = template.getForObject(PRODUCT_URL + "/products/get/" + productId, Product.class);//远程获取
-------------------------------------------------------------------   
    //测试
    1:先启动ProductMain8080 

2:修改application.yml里面端口8081
    再启动ProductMain8080 , 模拟启动了2个Product-server服务
--------------------------------------------------------------------
    PRODUCT-SERVER:   #必须是provide的服务名
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
           

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VYuwia1E-1598758873295)(C:\Users\白米白9999\AppData\Roaming\Typora\typora-user-images\1598663642707.png)]

[外链图片转存失

SpringCloud之Ribbon ,Feign简单实现
SpringCloud之Ribbon ,Feign简单实现

微服务调用方式Feign

以上Ribbon实现的弊端

1:硬编码
2:参数不可控

有点类似当初没使用Mapper接口前的mybatis操作
解决方案类似Mapper接口,此次使用定义Feign接口,使用接口方式解决上述问题
           

改造项目使用Feign方式实现远程调用

01.修改cloud-product-api项目依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
</dependencies>
           

02.在cloud-product-api项目中添加ProductFeignApi接口

@FeignClient(name = "PRODUCT-SERVER")
public interface IProductFeignApi {
    @GetMapping("/products/get/{id}")
    Product get(@PathVariable("id") Long id);
}
           

03.修改cloud-consumer-order8090项目中的启动类

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients  //添加 注释掉Ribbon的调用方法 ,Feigion底层实现了Ribbon
public class OrderMain8090 {

  //注释掉ribbon调用方式
   /* @Bean
    @LoadBalanced //负载均衡
    public RestTemplate template(){
        return new RestTemplate();
    }*/
    public static void main(String[] args) {
        SpringApplication.run(OrderMain8090.class, args);
    }
}

           

04.修改cloud-consumer-order8090项目中OrderServiceImpl

@Autowired
    private IProductFeignApi productFeignApi;

    @Override
    public Order save(Long userId, Long productId) {
        System.out.println("执行保存订单操作-----begin....");
        //Product product = template.getForObject(PRODUCT_URL + "/products/get/" + productId, Product.class);//远程获取
        Product product = productFeignApi.get(productId);
           

05.在cloud-provider-product8080建新类ProductFeignClient(更换controller类)

springcloud推崇的不适用controller进行对外提供接口服务,使用feign客户端方式

其实本质还是controller,换一种写法而已。

@RestController
public class ProductFeignClient implements IProductFeignApi {

    @Autowired
    private IProductService productService;

    @Value("${server.port}")
    private String port;

    @Override
    public Product get(Long id) {
        System.out.println("ProductFeignClient..get...");

        Product product = productService.get(id);
        //想让order-server服务调用product集群时,知道调用哪一个服务(8080?8081?)
        //product.setName(product.getName() + "-" + port);

        //防止端口重复拼接
        Product pp = new Product();
        BeanUtils.copyProperties(product,pp);
        pp.setName(product.getName() + "-" + port);
        return pp;
    }
}
           

Feign超时时间设置

在cloud-consumer-order8090的application.yml中配置

feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000
           

Feign超时重试次数设置

在cloud-consumer-order8090的application.yml中配置

PRODUCT-SERVER:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    MaxAutoRetries: 0
    MaxAutoRetriesNextServer: 1
           

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mCbsfThO-1598758873299)(C:\Users\白米白9999\AppData\Roaming\Typora\typora-user-images\1598605276324.png)]

[外链图片转存失败,源站可能有

SpringCloud之Ribbon ,Feign简单实现

防盗链机制,建议将图片保存下来直接上传(img-bSOz4CZ8-1598758873301)(C:\Users\白米白9999\AppData\Roaming\Typora\typora-user-images\1598600640294.png)

SpringCloud之Ribbon ,Feign简单实现