Spring Cloud微服务实战教程系列(五)——通过Spring Cloud Ribbon实现客户端负载均衡

        Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,通过Spring Cloud的封装,可以让我们轻松的将面向服务的REST模板请求自动装换成客户端负载均衡的服务调用。它不需要像服务注册中心、配置中心、API网关那样独立部署,而是嵌入到每一个Spring Cloud构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等实际上都是通过Ribbon来实现的。

        通过Spring Cloud Ribbon的封装,我们在微服务架构中使用客户端负载均衡调用非常简单,只需要如下的两步:

        1)服务提供者需要启动多个服务实例并注册到一个服务中心或者多个关联的服务注册中心;
        2)服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用。

        RestTemplate可以针对GET请求、POST请求、PUT请求、DELETE请求实现服务的调用,其参数和调用方法十分类似,下面就以GET请求为例,开发一个最简单的客户端负载均衡的实例。

        (一)启动Eureka服务注册中心

java -jar eureka-server-1.0.0.jar

        (二)启动两个hello-service的实例,共同注册到注册中心

java -jar hello-service-1.0.0.jar --server.port=8081
java -jar hello-service-1.0.0.jar --server.port=8082

        (三)创建一个Spring Boot基础项目来实现服务消费者,命名为ribbon-consumer,相比之前的pom.xml,新增了Ribbon的依赖模块spring-cloud-starter-ribbon,代码如下:

<?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>

    <groupId>cn.badtom</groupId>
    <artifactId>ribbon-consumer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <dependencies>
        <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-eureka</artifactId>
        </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>

        (四)创建主类ConsumerController,通过@EnableDiscoveryClient注解让应用注册为Eureka客户端应用,以获得服务发现的能力;通过RestTemplate实例及@LoadBalanced注解开启客户端负载均衡功能;创建/ribbon-consumer接口,在该接口中,通过RestTemplate来实现对HELLO-SERVICE服务提供的/hello接口进行调用。这里访问的是服务名HELLO-SERVICE而不是一个具体的地址,在服务治理框架中,这是一个非常重要的特性。

package cn.badtom.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@EnableAutoConfiguration
@EnableDiscoveryClient
public class ConsumerController {

    @Autowired
    RestTemplate restTemplate;

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

    @RequestMapping(value = "/ribbon-consumer", method = RequestMethod.GET)
    public String helloConsumer() {
        return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody();
//        return "hello ribbon";
    }

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

        (五)在application.properties配置文件中配置Eureka服务注册中心的位置,同时设置该应用的端口为9000,避免冲突。

server.port=9000
spring.application.name=ribbon-consumer
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka
        启动ribbon-consumer应用之后,在Eureka信息面板中可以看到除了HELLO-SERVICE之外,还注册了RIBBON-CONSUMER服务。通过向http://localhost:9000/ribbon-consumer发起GET请求,可以看到控制台成功返回HELLO-SERVICE的输出信息。连续的发起GET请求,在去HELLO-SERVICE的两个实例的控制台查看,可以看到它们是交替的打印被访问信息的,证明Ribbon正在对该服务进行轮询访问。
使用Python来安装geopandas包时,由于geopandas依赖于几个其他的Python库(如GDAL, Fiona, Pyproj, Shapely等),因此安装过程可能需要一些额外的步骤。以下是一个基本的安装指南,适用于大多数用户: 使用pip安装 确保Python和pip已安装: 首先,确保你的计算机上已安装了Python和pip。pip是Python的包管理工具,用于安装和管理Python包。 安装依赖库: 由于geopandas依赖于GDAL, Fiona, Pyproj, Shapely等库,你可能需要先安装这些库。通常,你可以通过pip直接安装这些库,但有时候可能需要从其他源下载预编译的二进制包(wheel文件),特别是GDAL和Fiona,因为它们可能包含一些系统级的依赖。 bash pip install GDAL Fiona Pyproj Shapely 注意:在某些系统上,直接使用pip安装GDAL和Fiona可能会遇到问题,因为它们需要编译一些C/C++代码。如果遇到问题,你可以考虑使用conda(一个Python包、依赖和环境管理器)来安装这些库,或者从Unofficial Windows Binaries for Python Extension Packages这样的网站下载预编译的wheel文件。 安装geopandas: 在安装了所有依赖库之后,你可以使用pip来安装geopandas。 bash pip install geopandas 使用conda安装 如果你正在使用conda作为你的Python包管理器,那么安装geopandas和它的依赖可能会更简单一些。 创建一个新的conda环境(可选,但推荐): bash conda create -n geoenv python=3.x anaconda conda activate geoenv 其3.x是你希望使用的Python版本。 安装geopandas: 使用conda-forge频道来安装geopandas,因为它提供了许多地理空间相关的包。 bash conda install -c conda-forge geopandas 这条命令会自动安装geopandas及其所有依赖。 注意事项 如果你在安装过程遇到任何问题,比如编译错误或依赖问题,请检查你的Python版本和pip/conda的版本是否是最新的,或者尝试在不同的环境安装。 某些库(如GDAL)可能需要额外的系统级依赖,如地理空间库(如PROJ和GEOS)。这些依赖可能需要单独安装,具体取决于你的操作系统。 如果你在Windows上遇到问题,并且pip安装失败,尝试从Unofficial Windows Binaries for Python Extension Packages网站下载相应的wheel文件,并使用pip进行安装。 脚本示例 虽然你的问题主要是关于如何安装geopandas,但如果你想要一个Python脚本来重命名文件夹下的文件,在原始名字前面加上字符串"geopandas",以下是一个简单的示例: python import os # 指定文件夹路径 folder_path = 'path/to/your/folder' # 遍历文件夹的文件 for filename in os.listdir(folder_path): # 构造原始文件路径 old_file_path = os.path.join(folder_path, filename) # 构造新文件名 new_filename = 'geopandas_' + filename # 构造新文件路径 new_file_path = os.path.join(folder_path, new_filename) # 重命名文件 os.rename(old_file_path, new_file_path) print(f'Renamed "{filename}" to "{new_filename}"') 请确保将'path/to/your/folder'替换为你想要重命名文件的实际文件夹路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值