微服务 – Spring Cloud – Rabbion

作者: 太阳上的雨天 分类: Java 发布时间: 2023-06-22 00:42

[TOC]

Ribbon 简介

Ribbon是Netflix发布的开源项目,主要目的是为客户端提供负载均衡算法和服务调用。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单地说,就是在配置文件中列出Load Balancer(简称LB)后面所有机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法。

负载均衡 + RestTemplate 示例

一、Ribbon默认的负载规则 – 轮询

1、启动eureka 集群

localhost:7001

localhost:7002

pom依赖

 <!-- eureka server依赖包 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

配置文件 application.yaml

-- 7001
server:
  port: 7001

eureka:
  instance:
    # eureka 服务端的实例名称
    hostname: eureka7001.com
  client:
    # 表示是否将自己注册到Eureka Server,默认为true。
    register-with-eureka: false
    # 表示是否从Eureka Server获取注册信息,默认为true。
    fetch-registry: false
    service-url:
      # 设置与Eureka Server交互的地址
      defaultZone: http://eureka7002.com:7002/eureka/
  server:
    enable-self-preservation: false # 禁用自我保护机制
    eviction-interval-timer-in-ms: 2000 # 2秒钟

-- 7002
server:
  port: 7002

eureka:
  instance:
    # eureka 服务端的实例名称
    hostname: eureka7002.com
  client:
    # 表示是否将自己注册到Eureka Server,默认为true。
    register-with-eureka: false
    # 表示是否从Eureka Server获取注册信息,默认为true。
    fetch-registry: false
    service-url:
      # 设置与Eureka Server交互的地址
      defaultZone: http://eureka7001.com:7001/eureka/

  server:
    enable-self-preservation: false # 禁用自我保护机制
    eviction-interval-timer-in-ms: 2000 # 2秒钟

主启动类 7001 、7002

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication7001 {

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

}

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication7002 {

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

}

2、两个服务提供者 payment 8001 和 payment 8002。并注册到eureka注册中心

启动类 8001 和 8002

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

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class PaymentMain8002 {

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

}

提供者业务类 8001 和 8002 部分代码

@RestController
@Slf4j
public class PaymentController {

    @Autowired
    private PaymentService paymentService;

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

    @GetMapping(value = "/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
        Payment res = paymentService.getPaymentById(id);
        log.info("************************** 查询结果: " + res);
        if (res != null) {
            return new CommonResult(200, "查询成功, serverPort: " + serverPort, res);
        }
        return new CommonResult(444, "查询失败",null);
    }

}

3、消费者服务 order 以轮询的方式 通过 eureka 调用 payment8001payment8002

启动类

@SpringBootApplication
@EnableEurekaClient
public class OrderMain80 {

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

}

消费者服务部分代码

@RestController
public class OrderController {

    private static final String PROVIDER_URL = "http://CLOUD-PAYMENT-SERVICE";

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
        return restTemplate.getForObject(PROVIDER_URL + "/payment/get/"+id, CommonResult.class);
    }

}

访问localhost/consumner/payment/get/6

第一次访问结果: 调用的 8002

{
  "code": 200,
  "message": "查询成功, serverPort: 8002",
  "data": {
  "id": 4,
  "serial": "jeffcail00004"
  }
}

第二次访问结果: 调用的 8001

{
  "code": 200,
  "message": "查询成功, serverPort: 8001",
  "data": {
  "id": 4,
  "serial": "jeffcail00004"
  }
}

第三次访问结果: 调用的 8002

{
  "code": 200,
  "message": "查询成功, serverPort: 8002",
  "data": {
  "id": 4,
  "serial": "jeffcail00004"
  }
}

第四次访问结果: 调用的 8001

{
  "code": 200,
  "message": "查询成功, serverPort: 8001",
  "data": {
  "id": 4,
  "serial": "jeffcail00004"
  }
}

因为Rabbion 默认的负载均衡机制为 轮询

二、Ribbon负载规则 – 随机

在主主启动类所在的package的同级目录下,新建ribbonrule package。 新建MyselfRule.java 类

在这里插入图片描述

MyselfRule.java类

@Configuration
public class MyselfRule {

    @Bean
    public IRule myRule() {
        return new RandomRule(); // 定义为随机规则
    }

}

在主启动类上添加 @RibbonClient 注解

@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE", configuration = MyselfRule.class)
public class OrderMain80 {

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

}

重启 order服务 ,然后访问 localhost/consumner/payment/get/4

第一次结果:

{
  "code": 200,
  "message": "查询成功, serverPort: 8001",
  "data": {
  "id": 4,
  "serial": "jeffcail00004"
  }
}

第二次结果:

{
  "code": 200,
  "message": "查询成功, serverPort: 8001",
  "data": {
  "id": 4,
  "serial": "jeffcail00004"
  }
}

第三次结果:

{
"code": 200,
"message": "查询成功, serverPort: 8002",
"data": {
"id": 4,
"serial": "jeffcail00004"
}
}

第四次结果:

{
  "code": 200,
  "message": "查询成功, serverPort: 8002",
  "data": {
  "id": 4,
  "serial": "jeffcail00004"
  }
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注