spring-cloud-alibaba2.2.x 远程调用负载均衡ribbon搭建使用
文章目录
本地项目的基础环境
环境 | 版本 |
---|---|
jdk | 1.8.0_201 |
maven | 3.6.0 |
Spring-boot | 2.2.4.RELEASE |
Spring-cloud-alibaba | 2.2.1.RELEASE |
构建本项目之前,请详细参看如下步骤,如果已经搭建好,略过即可;
项目地址的码云的git地址https://gitee.com/liqi01/badger-spring-cloud-alibaba.git
《spring-cloud-alibaba.2.2.x 服务注册与发现nacos简介以及环境搭建》
1、badger-spring-cloud-alibaba-provider,普通的服务提供者项目搭建
1.1、maven的pom文件如下,就是一个普通的web的springboot项目,加入了nacos的nacos-discovery
的包
<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>2.2.4.RELEASE</version>
</parent>
<groupId>com.badger</groupId>
<artifactId>badger-spring-cloud-alibaba-provider</artifactId>
<name>badger-spring-cloud-alibaba-provider</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.1.RELEASE</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>
<finalName>badger-spring-cloud-alibaba-provider</finalName>
</build>
<description>服务提供者</description>
</project>
1.2、yaml的配置文件
server:
port: 7000
spring:
application:
name: badger-spring-cloud-alibaba-provider
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
management:
endpoints:
web:
exposure:
include: '*'
1.3、springboot的主启动类以及业务演示代码
/**
* @EnableDiscoveryClient 开启服务注册和发现
*/
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(ProviderApplication.class, args);
}
@RestController
public class DemoController {
@Value("${server.port}")
String port;
@Value("${spring.cloud.client.ip-address}")
String address;
@GetMapping("/demo")
public String demo() {
return "我的地址是-->" + address + ":" + port;
}
}
}
1.4、演示的代码详细参考github上的官方文档,或者spring的英文文档
2、badger-spring-cloud-alibaba-consumer-ribbon。服务的消费者ribbon的项目搭建
2.1、maven的pom文件如下,就是一个普通的web的springboot项目,加入了nacos的nacos-discovery
的包
<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>2.2.4.RELEASE</version>
</parent>
<groupId>com.badger</groupId>
<artifactId>badger-spring-cloud-alibaba-consumer-ribbon</artifactId>
<name>badger-spring-cloud-alibaba-consumer-ribbon</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.1.RELEASE</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>
<finalName>badger-spring-cloud-alibaba-consumer-ribbon</finalName>
</build>
<description>服务消费者</description>
</project>
2.2、yaml配置文件如下,基础配置
server:
port: 8000
spring:
application:
name: badger-spring-cloud-alibaba-consumer-ribbon
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
management:
endpoints:
web:
exposure:
include: '*'
2.3、主启动类、配置类、以及业务类
这个写法,是取自官网的演示,使用LoadBalancerClient(负载均衡的客户端)获取服务的列表,然后调用,是编程式
的调用形式;
/**
* @EnableDiscoveryClient 开启服务注册和发现
*/
@SpringBootApplication
@EnableDiscoveryClient
public class RibbonConsumerApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(RibbonConsumerApplication.class, args);
}
// 实例化 RestTemplate 实例
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@RestController
public class DemoController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate restTemplate;
private static final String SERVER_NAME = "badger-spring-cloud-alibaba-provider";
@GetMapping("/ribbon/demo")
public String demo() {
// 使用 LoadBalanceClient 和 RestTemplate 结合的方式来访问
ServiceInstance serviceInstance = loadBalancerClient.choose(SERVER_NAME);
String url = String.format("http://%s:%s/%s", serviceInstance.getHost(), serviceInstance.getPort(), "demo");
System.out.println("request url:" + url);
return restTemplate.getForObject(url, String.class);
}
}
}
对RestTemplate声明式
的调用,代码如下,大家二选一,就可以了
/**
* @EnableDiscoveryClient 开启服务注册和发现
*/
@SpringBootApplication
@EnableDiscoveryClient
public class RibbonConsumerApplication2 {
public static void main(String[] args) throws Exception {
SpringApplication.run(RibbonConsumerApplication2.class, args);
}
@Bean
@LoadBalanced // Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具。
public RestTemplate restTemplate() {
return new RestTemplate();
}
@RestController
public class DemoController {
@Autowired
private RestTemplate restTemplate;
private static final String REST_URL_PREFIX = "http://badger-spring-cloud-alibaba-provider";
@GetMapping("/ribbon/demo")
public String getAddress() {
return restTemplate.getForObject(REST_URL_PREFIX + "/demo", String.class);
}
}
}
ribbon使用过程中,是获取注册中心,服务提供者的地址,然后使用RestTemplate类来远程调用的;
@LoadBalanced
注解,Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具。也就说,加了这个注解的RestTemplate,可以使用ribbon默认的负载均衡算法
,来调用服务器提供者的服务;关于ribbon的部分源码解析,可以参考《spring boot 2.x spring cloud Greenwich.SR1 负载均衡ribbon自动装配,负载均衡部分源码解析》
3、项目启动,测试使用
启动步骤如下:
- 启动nacos的服务,端口8848;
- 修改yaml的配置文件,启动端口为7000,启动服务的提供者badger-spring-cloud-alibaba-provider;
- 修改yaml的配置文件,启动端口为7001,启动服务的提供者badger-spring-cloud-alibaba-provider;
- 启动服务的消费者badger-spring-cloud-alibaba-consumer-ribbon,端口为7100;
这里为了测试负载均衡,我们使用不同的端口(7000,7001)启动了两份badger-spring-cloud-alibaba-provider应用;通过nacos的页面,也可以看到具体的服务
调用ribbon的服务 http://localhost:7100/ribbon/demo;
持续调用,会发现业务上的端口,有顺序的改变;这个也是默认的负载均衡算法生效了;以及远程调用badger-spring-cloud-alibaba-provider成功了。
我的地址是-->172.16.2.54:7000
我的地址是-->172.16.2.54:7001
4、更多关于 Nacos Discovery Starter 的配置项信息
更多关于 Nacos Discovery Starter 的配置项如下所示:
配置项 | Key | 说明 |
---|---|---|
服务端地址 | spring.cloud.nacos.discovery.server-addr | Nacos Server 启动监听的ip地址和端口 |
服务名 | spring.cloud.nacos.discovery.service | 注册的服务名,默认${spring.application.name} |
权重 | spring.cloud.nacos.discovery.weight | 取值范围 1 到 100,数值越大,权重越大;默认1 |
网卡名 | spring.cloud.nacos.discovery.network-interface | 当IP未配置时,注册的IP为此网卡所对应的IP地址,如果此项也未配置,则默认取第一块网卡的地址 |
注册的IP地址 | spring.cloud.nacos.discovery.ip | 优先级最高 |
注册的端口 | spring.cloud.nacos.discovery.port | 默认情况下不用配置,会自动探测;默认-1 |
命名空间 | spring.cloud.nacos.discovery.namespace | 常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 |
AccessKey | spring.cloud.nacos.discovery.access-key | 当要上阿里云时,阿里云上面的一个云账号名 |
SecretKey | spring.cloud.nacos.discovery.secret-key | 当要上阿里云时,阿里云上面的一个云账号密码 |
Metadata | spring.cloud.nacos.discovery.metadata | 使用Map格式配置,用户可以根据自己的需要自定义一些和服务相关的元数据信息 |
日志文件名 | spring.cloud.nacos.discovery.log-name | |
集群 | spring.cloud.nacos.discovery.cluster-name | Nacos集群名称;默认DEFAULT |
接入点 | spring.cloud.nacos.discovery.endpoint | 地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址 |
是否集成Ribbon | ribbon.nacos.enabled | 一般都设置成true即可 |
是否开启Nacos Watch | spring.cloud.nacos.discovery.watch.enabled | 可以设置成false来关闭 watch;默认true |
5、ribbon其他负载均衡算法说明,和算法切换
5.1、ribbon负载均衡算法的种类
ribbon的负载均衡算法,主要是实现这个com.netflix.loadbalancer.IRule.class
这个接口;具体算法如下:
BestAvailableRule:表示请求数最少策略;
PredicateBaseRule:表示过滤掉一些一直连接失败的服务,或者并发高的服务;先过滤再轮询的策略
RandomRule:表示随机策略;
RetryRule:当前请求超时,那么就再次轮询调用下一个请求,直到成功;
RoundRobinRule:轮询策略;轮询策略下有个加权策略:WeightedResponseTimeRule;另外一个(ResponseTimeWeightedRule)不建议使用了,名字跟WeightedResponseTimeRule差不多,只是单次排列不一样;
5.2、ribbon切换默认的负载均衡算法
@Configuration
public class RestConfig {
@Bean
@LoadBalanced // Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具。
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
@Bean
public IRule myRule() {
// return new RoundRobinRule();
return new RandomRule();// 达到的目的,用我们重新选择的随机算法替代默认的轮询。
// return new RetryRule();
}
}
向spring容器中,注入一个IRule的实例就可以了;