总结之SpringCloud之服务发现与调用——Ribbon与Feign(使用及比较)

Ribbion简介

Ribbon 带有负载均衡功能
Fegin实现基于Ribbon

代码实现步骤

pom.xml中引入eureka-server和netfix-ribbon依赖
application.yml中指定配置项,端口、application name、eureka-server地址
SpringBoot 启动类添加注解@EnableEurekaClient @EnableDiscoveryClient
使用@Bean @LoadBalanced向Spring容器注入org.springframework.web.client.RestTemplate 实例
在使用之处使用@Autowired public RestTemplate restTemplate; 获取实例,调用服务提供方提供的方法

关键代码
@EnableEurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaServiceRibbonApplication {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(EurekaServiceRibbonApplication.class, args);
    }
}

也可以configApplication使用

@Configuration
public class RestTemplateConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return  new RestTemplate();
    }
}

service
其中http://eureka-service//print为其他服务接口 如果这个eureka-service有多个不同端口实例,就会自动负载均衡,还可以加上ip,指定实例

package org.oscar.scd.eureka.service.ribbon.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class HelloRibbonService {

    @Autowired
    public RestTemplate restTemplate;

    public String hiService(String name) {
        return restTemplate.getForObject("http://eureka-service//print?name=" + name, String.class);
    }

}

Controller

import org.oscar.scd.eureka.service.ribbon.service.HelloRibbonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/ribbon")
public class HelloRibbonController {

    @Autowired
    public HelloRibbonService service;

    @GetMapping("/print")
    public String print(@RequestParam String name) {
        return this.service.hiService(name);
    }

这里在Controller中补充介绍三种数据传输方式

第三种便是上面介绍的,常用方式。

  //第二种方式
    @Autowired
    private LoadBalancerClient loadBalancerClient;

    //第三种方式
    @Autowired
    private RestTemplate restTemplate;

    /**
     * 第一种方式 通过url
     * @return
     */
    @RequestMapping("/one")
    public String one(){
        RestTemplate restTemplate =new RestTemplate();
        String response = restTemplate.getForObject("http://localhost:8773/one",String.class);
        System.out.println(response);
        return response;
    }

    @RequestMapping("/two")
    public String two(){
        ServiceInstance serviceInstance  =loadBalancerClient.choose("one");//为null
        serviceInstance.getHost();
        String url = String.format("http://%s:%s",serviceInstance.getHost(),serviceInstance.getPort()+"/msg");
        String response = restTemplate.getForObject(url,String.class);
        return response;
    }

    @RequestMapping("/three")
    public String three(){
              String response = restTemplate.getForObject("http://one/one",String.class);

        return response;
    }
    //对象测试
    @RequestMapping("four")
    public Goods four(){
        Goods goods =restTemplate.getForObject("http://one/two",Goods.class);//对象服务两边都要有
        System.out.println(goods);
        return goods;
    }

Feign介绍

Feign 是一个声明式调用HTTP协议服务的客户端
支持注解形式发现与调用服务
支持编码与解码
与Ribbon、Eureka结合使用可实现负载均衡功能

代码实现步骤

pom.xml中引入spring-cloud-starter-netflix-eureka-server和spring-cloud-starter-openfeign依赖
application.yml中指定配置项,端口、application.name、eureka-server地址
SpringBoot 启动类添加启用Fegin的注解@EnableFeignClients
在当前项目Service接口类名上使用FeignClient注解指定服务提供者的服务名@FeignClient(“eureka-service”)
在需要调用服务提供者的接口方法之上使用注解指定调用服务提供者提供的方法@RequestMapping("/print")
在需要使用服务提供者提供的方法之处,使用第4步与第5步实例化好的服务提供者的方法

关键代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableFeignClients
@EnableEurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaServiceFeignApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServiceFeignApplication.class, args);
    }
}

service(注意与上面的不同)

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient("eureka-service")
public interface FeignHelloService {

    @RequestMapping("/print")
    String printPort(@RequestParam("name") String name);
}

controller

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/feign")
public class FeignHelloController {

    @Autowired
    private FeignHelloService service;

    @RequestMapping("/print")
    public String print(@RequestParam("name") String name) {
        return this.service.printPort(name);
    }
}

feign开启熔断器

注意feign里面开启熔断器处理时,需要有以下配置:

spring:
  application:
    name: service-feign
  hystrix:
    enabled: true
    client:
      service-url:
       defaultZone: 

熔断器的配置就拿一个订单的熔断器来说,需要继承相应的订单feign接口,并且在注解里面的@feignclient里面申明到fallback会调用到订单的熔断器类。

@FeignClient(name = "total-service",fallback = OrderHystrics.class)
public interface OrderFeignClient {
    public static final String version="/v0/order/";
 
  @RequestMapping(value =version+"sending/order/batch")
  @ApiOperation(value = "获取用户所有的发货中订单内容",notes = "获取用户所有订单内容")
  @ApiImplicitParams({
    @ApiImplicitParam(name = "sessionKey", value = "sessionKey", dataType = "String",paramType = "query"),
    @ApiImplicitParam(name = "page",value = "pageNum",dataType = "int",paramType = "query") })
  public List<Object> sendingOrder(@RequestParam(name = "sessionKey") String sessionKey,
        @RequestParam(name = "page") int page);
 }
 
熔断器部分代码:
 
@Component
 
@Slf4j
 
public class OrderHystrics implements OrderFeignClient {
    public List<Object> sendingOrder(String sessionKey, int page) {
        Date date=new Date();
        log.warn(date.toString()+"sendingOrder出现异常!请管理员尽快处理");
        return null;
    }
 
}

写到最后

根据上述内容可以了解负载均衡之feign与ribbon比较,选择feign
理由:1. feign本身里面就包含有了ribbon
2. feign自身是一个声明式的伪http客户端,写起来更加思路清晰和方便
3. fegin是一个采用基于接口的注解的编程方式,更加简便

注意:一般在feign调用相应的service接口时候,第一次调用会因为超时而导致调用失败,所以需要设置超时时长。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值