转载

Spring Cloud实战系列(二) - 客户端调用Rest + Ribbon

上一篇文章我们介绍了 Eureka 服务注册中心 的搭建,这篇文章介绍一下如何使用 Eureka 服务注册中心 ,搭建一个简单的 服务端注册服务 ,由 客户端 通过 Ribbon 负载均衡 地去调用服务案例。

正文

1. 创建服务提供者

创建一个 service-hiModule ,创建完成后的 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 http://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.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>io.ostenant.github.springcloud</groupId>
    <artifactId>service-hi</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>service-hi</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Dalston.SR1</spring-cloud.version>
    </properties>

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

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</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>
复制代码

通过 注解 @EnableEurekaClient 表明自己是一个 Eureka Client

@SpringBootApplication
@EnableEurekaClient
@RestController
public class ServiceHiApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceHiApplication.class, args);
    }
}
复制代码

创建一个控制器 HelloController ,对外提供一个 /hiHTTP 的服务。在响应数据中返回当前 服务实例端口号

@RestController
public class HelloController {

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

    @RequestMapping("/hi")
    public String hi(@RequestParam String name) {
        return "Hi " + name + ", I am from port: "  + port;
    }
}
复制代码

配置文件 中注明的 服务注册中心 的地址, application.yml 配置文件如下:

spring:
  active:
    profiles: service-hi1 # service-hi2

---

spring:
  profiles: service-hi1
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8763
spring:
  application:
    name: service-hi

---

spring:
  profiles: service-hi2
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8764
spring:
  application:
    name: service-hi
复制代码

分别以 spring.profiles.active=hi1spring.profiles.active=hi2 作为 Spring Boot启动命令参数 ,在 端口号 87638764 启动 2服务提供者 实例。

2. 创建服务消费者

重新新建 service-ribbonModule ,在它的 pom.xml 文件分别引入 起步依赖 spring-cloud-starter-eurekaspring-cloud-starter-ribbonspring-boot-starter-web ,代码如下:

<?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 http://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.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>io.ostenant.github.springcloud</groupId>
    <artifactId>service-ribbon</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>service-ribbon</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Dalston.SR1</spring-cloud.version>
    </properties>

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

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</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>
复制代码

在项目的 配置文件 指定服务的 服务注册中心 的地址, 应用名称service-ribbon端口号8762 。完整配置文件 application.yml 如下:

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8762
spring:
  application:
    name: service-ribbon
复制代码

在应用 启动类 上,通过 @EnableDiscoveryClient服务中心 注册自身信息,向 Spring Boot 容器注册一个 RestTemplate 对象,并通过 @LoadBalanced 注解表明这个 RestRemplate 开启 客户端负载均衡 的功能。

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

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
复制代码

写一个 测试接口 ,注入上面的 RestTemplate 对象来消费 service-hi 服务的 /hi 接口。在 RestTemplateURL 中,我们将具体 服务生产者主机名称端口号 替换为它的 服务名称

@RestController
public class HelloController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping(value = "/hi")
    public String requestForHi(@RequestParam String name){
        return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
    }
}
复制代码

在浏览器上多次访问 http://localhost:8762/hi?name=ribbon ,浏览器交替显示:

Hi ribbon, I am from port: 8763
Hi ribbon, I am from port: 8764

在具体的调用过程中, Ribbon 提供的 @LoadBalanced 注解会从 Eureka Server 上查询 服务列表 ,根据 服务名称 找到 SERVICE-HI服务实例 。如果有多个 SERVICE-HI 实例, Ribbon 会根据 客户端负载均衡 算法筛选其中一台,并把 URL 中的 SERVICE-HI 替换为具体实例的 主机名称端口号

原文  https://juejin.im/post/5c4d7da96fb9a04a0a5f9087
正文到此结束
Loading...