springCloud—服务请求(Ribbon负载均衡和Feign请求)

一、springCloud微服务请求:

上篇博客说到,如何注册服务到注册中心,并且实现erueka集群,那么把服务注册到注册中心后,如何来调用这些服务呢?
(1)、最傻的方式就是直接拼接ip地址加端口号:

   /**
   * get请求(rest风格)
   * @return
   */
   @GetMapping("/getPathVariableConsumer")
   public String getPathVariableConsumer(){

       RestTemplate restTemplate=new RestTemplate();
       Map<String,String> paramMap = new HashMap();
       paramMap.put("start","1");
       paramMap.put("page","5");
       return restTemplate.getForObject("http://localhost:8001/getDcPathVariable/{start}/{page}",String.class,paramMap);
   }

说明:

   如果这样请求,那我们还用cloud干嘛呢?还不如自己写个常量类维护好这些ip地址。这样直接请求ip地址,
   第一维护麻烦,还要知道其他微服务的ip地址才行
   第二不能实现负载均衡,比如这个请求的目标服务部署了多个实例,那就不能均衡的访问者多个实例。

(2)、不傻但是麻烦的方式就是通过LoadBalancerClient对象的choose方法,选中当前请求服务的实例(支持负载均衡),然后通过这个实例来拼接ip地址:

/**
 * post请求(loadBalancerClient)
 * @return
 */
@GetMapping("/postBalancerConsumer")
public String postBalancerConsumer(){
    RestTemplate restTemplate=new RestTemplate();
    Map<String,String> paramMap = new HashMap();
    paramMap.put("start", "1");
    paramMap.put("page", "5");
    //选中服务实例
    ServiceInstance serviceInstance =loadBalancerClient.choose("eureka-client");
    System.out.println(serviceInstance.getServiceId()+":"+serviceInstance.getPort());
    String url="http://"+serviceInstance.getHost()+ ":" + serviceInstance.getPort() + "/postDcRequestBody";;

    return restTemplate.postForObject(url,paramMap,String.class);
}

(3)、比较通用的方法,利用@LoadBalanced注解改造RestTemplate,使它有负载均衡的功能:

新建个配置类RestTemplateConfig ,构造一个restTemplateRibbon到spring容器:

@Configuration
public class RestTemplateConfig {

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

在调用方法里面注入restTemplateRibbon,并调用请求方法:

  @Autowired
  @Qualifier("restTemplateRibbon")
  public RestTemplate restTemplateRibbon;

@GetMapping("/postRestTemplateRibbonConsumer")
public String postRestTemplateRibbonConsumer(){
    Map<String,String> paramMap = new HashMap();
    paramMap.put("start", "1");
    paramMap.put("page", "5");
    return this.restTemplateRibbon.postForObject("http://eureka-client/"+"/postDcRequestBody",paramMap,String.class);
}

说明:这里也需要拼接地址,但是拼接的不是ip地址,而是eureka-client:微服务在注册中心的名字,因为标注了@LoadBalanced,就实现了Ribbon的负载均衡功能,所以这里会根据一定的算法(默认是轮询),来找到合适的实例地址(eureka-client有多个实例,ip地址或者端口不同)进行请求。

(4)、上面的那种方式已经很方便了,还有更加方便的方式,通过Feign接口来实现,我们连地址拼接都不需要了:

先实现一个Feign接口:

@FeignClient(value ="eureka-client",fallback = FeignFallBack.class)
public interface FeignInterface {

   @PostMapping("/postDcRequestBody")
   public String postDcRequestBody(@RequestBody Map<String,String> paramMap);

   @PostMapping("/postFeignClientConsumerHystrix")
   public String postFeignClientConsumerHystrix();
}

说明:@FeignClient(value =“eureka-client”,fallback = FeignFallBack.class),value指向要请求的微服务名称(在注册中心的名称),fallback指向发送错误时的处理类(这个下篇讲熔断的时候再说,先不管)

然后注入这个接口,并调用接口方法:

 @Autowired
 public FeignInterface feignInterface;

 @GetMapping("/postFeignClientConsumer")
 public String postFeignClientConsumer(){
       Map<String,String> paramMap = new HashMap();
       paramMap.put("start", "1");
       paramMap.put("page", "5");
       return this.feignInterface.postDcRequestBody(paramMap);
  }

Feign默认是实现了负载均衡的,所以这里调用接口方法的时候,也会根据接口里面的@FeignClient(value =“eureka-client”)选中最合适的实例去请求。

二、理解:

其实微服务相互请求,就是先把这些服务注册到同一个注册中心,这些服务都会从注册中心拉取一份微服务名单。
然后通过集成Ribbon,在消费端请求提供者端的服务(通过服务名来请求),实现负载均衡。
好处就是负载均衡分散了每个服务实例的访问压力,不需要关注每个服务的每个具体实例(ip和端口是多少),
通过服务名就可以请求到。

三、其它配置:

(1)、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.base</groupId>
    <artifactId>eureka-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-consumer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</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-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

(2)、yml配置:

spring:
  application:
    name: eureka-consumer
server:
  port: 9001
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:1001/eureka/
  instance:
    instance-id: ${spring.cloud.client.ipAddress}:${server.port}  #设置服务在注册中心的实例id
    prefer-ip-address: true

说明:将这个消费者服务也要注册到erueka服务中心(服务提供者也在这个中心).

(3)、启动类:

@EnableFeignClients :引入FeignClient
@EnableDiscoveryClient: 标注为服务客户端,便于从erueka获取服务列表。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值