Spring Cloud进阶之路 | 三:服务消费者(rest+ribbon)

转载请注明作者及出处:

作者:银河架构师

原文链接:https://www.cnblogs.com/luas/p/12097219.html

ribbon简介

官网说明

Ribbon is a client side load balancer which gives you a lot of control over the behaviour of HTTP and TCP clients. Feign already uses Ribbon, so if you are using @FeignClient then this section also applies.

大概意思是Ribbon是一个客户端负载均衡器,它可以有效的控制HTTP和TCP客户端的访问。Feign默认集成了Ribbon,也可以使用@FeignClient。

其中有个很关键的词”“客户端负载均衡器”,我们常用的负载均衡模式就是服务端负载均衡,如nginx反向代理,这种模式并不知道服务究竟请求的具体是那台机器。 而客户端负载均衡是在发起请求时已确定明确的目标,请求将精确指向集群中的某台机器。

Ribbon的负载均衡默认是依靠服务注册中心来实现的,Ribbon通过注册客户端定期拉取注册服务,通过客户端的轮训、随机等算法来实现负载均衡。

创建服务提供者

使用前一篇文章的商品工程xmall-product作为服务提供者,启动双实例,供负载均衡使用。如何启动双实例,请参见另外一篇文章:Spring Boot工程如何在IDEA中启动多实例

先启动8080端口的xmall-product工程,修改端口号为8081,并启动第二个实例。查看nacos,已有2个实例注册:

创建服务消费者

创建服务消费者工程xmall-product-clients-ribbon,作为服务消费者,调用商品服务。

pom

其父工程正是上一篇文章中创建的父工程java-boot-parent-2.1

<?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>com.luas.cloud</groupId>
        <artifactId>java-boot-parent-2.1</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../../java-boot-parent-2.1</relativePath>
    </parent>

    <groupId>com.luas.xmall</groupId>
    <artifactId>xmall-product-clients-ribbon</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <name>xmall-product-clients-ribbon</name>
    <description>product service clients by ribbon</description>

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- nacos cloud -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</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>

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

yml

依然注册到nacos,端口为8082。

server:
  port: 8082

spring:
  application:
    name: xmall-product-clients-ribbon
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

注册RestTemplate

在启动类中注册RestTemplate,并添加@LoadBalanced注解,开启负载均衡。

在启动类中注册RestTemplate,也是懒省事,正常项目时要在配置类中注册,如SystemConfiguration。

至于为何不添加@EnableDiscoveryClient注解,前面已有说明,不在赘述。

@SpringBootApplication
public class XmallProductClientsRibbonApplication {

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

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

}

创建客户端

创建SkuService,注入RestTemplate,访问xmall-product服务的“/sku/{skuId}”接口,在这里,因为服务都注册到了nacos,所以我们采用服务名来代替冗长的url地址。

package com.luas.xmall.product.clients.clients;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Component
public class SkuService {

    @Autowired
    private RestTemplate restTemplate;

    public Object info(String skuId) {
        return this.restTemplate.getForObject("http://xmall-product/sku/{skuId}", Object.class, skuId);
    }

}

创建测试入口

创建SkuController,注入上一步创建的SkuService客户端,来测试是否生效。

package com.luas.xmall.product.clients.controller;

import com.luas.xmall.product.clients.clients.SkuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/sku")
public class SkuController {

    @Autowired
    private SkuService skuService;

    @RequestMapping("/{skuId}")
    public Object info(@PathVariable String skuId) {
        return this.skuService.info(skuId);
    }

}

浏览器访问http://localhost:8082/sku/1122,多次刷新页面,可发现负载均衡生效,商品信息来自于不同端口的实例。

 

源码

github

https://github.com/liuminglei/SpringCloudLearning/tree/master/03/

gitee

https://gitee.com/xbd521/SpringCloudLearning/tree/master/03/

 正文完!

微信搜索【银河架构师】,发现更多精彩内容。

image.png

猜你喜欢

转载自www.cnblogs.com/luas/p/12097219.html