【Java】SpringCloud手写Ribbon实现负载均衡

SpringCloud手写Ribbon实现负载均衡

isWulongbo发布于 32 分钟前

前言

前面我们学习了 SpringCloud整合Consul,在此基础上我们手写本地客户端实现类似Ribbon负载均衡的效果。
注:order 模块调用者 记得关闭 @LoadBalanced注解。
我们这里只演示 注册中心 consul,至于 zookeeper 也是一模一样。

生产者

member模块

member 服务需要集群,所以我们copy application-consul.yml 文件命名为 application-consul2.yml
【Java】SpringCloud手写Ribbon实现负载均衡
【Java】SpringCloud手写Ribbon实现负载均衡
服务别名一致,只需要修改端口号即可。
application-consul2.yml 配置文件:

##服务端口号

server:

port: 8503

spring:

application:

##服务别名--服务注册到consul名称

name: consul-member

##注册中心consul地址

cloud:

consul:

host: localhost

port: 8500

discovery:

## consul ip地址

hostname: 192.168.3.91

启动 member 集群服务:
idea 运行 AppMember.java 启动 8501 端口
再打开 jar 包路径
【Java】SpringCloud手写Ribbon实现负载均衡
shift + 右键 启动 PowerShell 窗口,运行命令:

java -jar E:\ideaworkspaceback\springcloud-zookeeper\springcloud-zookeeper-member\target\springcloud-zookeeper-member-1.0-SNAPSHOT.jar --spring.profiles.active=consul2

启动 8503 端口
【Java】SpringCloud手写Ribbon实现负载均衡

打开 http://localhost:8500/ui/dc1/services 可以发现上面 注册了 member 集群服务:
【Java】SpringCloud手写Ribbon实现负载均衡

消费者

order模块

OrderApiController.java控制页面使用原子类来 AtomicInteger 保证操作的原子性。

package com.baba.wlb.controller;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.cloud.client.ServiceInstance;

import org.springframework.cloud.client.discovery.DiscoveryClient;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.client.RestTemplate;

import java.util.List;

import java.util.concurrent.atomic.AtomicInteger;

/**

* @Author wulongbo

* @Date 2021/1/9 15:32

* @Version 1.0

*/@RestController

public class OrderApiController {

@Autowired

private RestTemplate restTemplate;

@Autowired

private DiscoveryClient discoveryClient;

//使用原子类AtomicInteger

private AtomicInteger atomicInteger = new AtomicInteger(1);

public int add() {

return atomicInteger.getAndIncrement(); //先获取再自增,对应a++

//若使用++a 则对应方法是a.incrementAndGet(); 先自增再获取 , //多说一句 a-- 就是 a.getAndDecrement(); //若a = a + 10;————对应API a.getAndAdd(10);

}

/**

* springCloud中,两种方式调用(rest/feign)

*

* @return

*/

// 订单服务调用会员服务

@RequestMapping("/getOrder")

public String getOrder() {

// 有两种调用方式,一种是采用服务别名方式调用,另一种是使用别名去注册中心上获取对应服务调用地址

// 第一种方式

String url = "http://dy-202006281547:8000/getMember";

// 第二种方式

url = "http://zk-member/getMember";

String result = restTemplate.getForObject(url, String.class);

return "订单服务调用会员服务:" + result;

}

/**

* springCloud中,两种方式调用(rest/feign)

*

* @return

*/

// 订单服务调用会员服务

@RequestMapping("/getRibbonOrder")

public String getRibbonOrder() {

// 第一种方式

String url = getUri() + "/getMember";

String result = restTemplate.getForObject(url, String.class);

return "纯手写Ribbon本地负载均衡:" + result;

}

public String getUri() {

List<ServiceInstance> serviceInstances = discoveryClient.getInstances("consul-member");

if (serviceInstances == null || serviceInstances.isEmpty()) {

return null;

}

int serverSize = serviceInstances.size();

int count = add();

int indexServer = count % serverSize;

return serviceInstances.get(indexServer).getUri().toString();

}

}

AppOrder.java 启动类,关闭 @LoadBalanced 注解即可:
【Java】SpringCloud手写Ribbon实现负载均衡

由于我们是在 springcloud集成zookeeper 项目上改造的,所以order 模块 yml 配置也做相应的调整,注册中心修改为consul,并且在该模块中引入 consul 的 maven依赖

<!--springcloud 整合consul-->

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-consul-discovery</artifactId>

</dependency>

【Java】SpringCloud手写Ribbon实现负载均衡

启动 AppOrder.java,并刷新 http://localhost:8500/ui/dc1/services 可以发现上面 注册了 order 服务:
【Java】SpringCloud手写Ribbon实现负载均衡

这里有一个巨坑,导致 order 模块调用不到 member 模块,我们需要在yml 配置文件中注释掉:
参考博客: https://blog.csdn.net/apdkapskdad/article/details/93927860

## consul ip地址

##hostname: 192.168.3.91

消费者调用生产者:访问http://localhost:8508/getRibbonOrder
【Java】SpringCloud手写Ribbon实现负载均衡
【Java】SpringCloud手写Ribbon实现负载均衡
OK!我们便达到了负载均衡!

javaspringboot

阅读 16更新于 31 分钟前

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议


wulongbo

我的专栏

avatar

isWulongbo

在人生的头三十年,你培养习惯,后三十年,习惯铸就你

178 声望

8 粉丝

0 条评论

得票时间

avatar

isWulongbo

在人生的头三十年,你培养习惯,后三十年,习惯铸就你

178 声望

8 粉丝

宣传栏

前言

前面我们学习了 SpringCloud整合Consul,在此基础上我们手写本地客户端实现类似Ribbon负载均衡的效果。
注:order 模块调用者 记得关闭 @LoadBalanced注解。
我们这里只演示 注册中心 consul,至于 zookeeper 也是一模一样。

生产者

member模块

member 服务需要集群,所以我们copy application-consul.yml 文件命名为 application-consul2.yml
【Java】SpringCloud手写Ribbon实现负载均衡
【Java】SpringCloud手写Ribbon实现负载均衡
服务别名一致,只需要修改端口号即可。
application-consul2.yml 配置文件:

##服务端口号

server:

port: 8503

spring:

application:

##服务别名--服务注册到consul名称

name: consul-member

##注册中心consul地址

cloud:

consul:

host: localhost

port: 8500

discovery:

## consul ip地址

hostname: 192.168.3.91

启动 member 集群服务:
idea 运行 AppMember.java 启动 8501 端口
再打开 jar 包路径
【Java】SpringCloud手写Ribbon实现负载均衡
shift + 右键 启动 PowerShell 窗口,运行命令:

java -jar E:\ideaworkspaceback\springcloud-zookeeper\springcloud-zookeeper-member\target\springcloud-zookeeper-member-1.0-SNAPSHOT.jar --spring.profiles.active=consul2

启动 8503 端口
【Java】SpringCloud手写Ribbon实现负载均衡

打开 http://localhost:8500/ui/dc1/services 可以发现上面 注册了 member 集群服务:
【Java】SpringCloud手写Ribbon实现负载均衡

消费者

order模块

OrderApiController.java控制页面使用原子类来 AtomicInteger 保证操作的原子性。

package com.baba.wlb.controller;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.cloud.client.ServiceInstance;

import org.springframework.cloud.client.discovery.DiscoveryClient;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.client.RestTemplate;

import java.util.List;

import java.util.concurrent.atomic.AtomicInteger;

/**

* @Author wulongbo

* @Date 2021/1/9 15:32

* @Version 1.0

*/@RestController

public class OrderApiController {

@Autowired

private RestTemplate restTemplate;

@Autowired

private DiscoveryClient discoveryClient;

//使用原子类AtomicInteger

private AtomicInteger atomicInteger = new AtomicInteger(1);

public int add() {

return atomicInteger.getAndIncrement(); //先获取再自增,对应a++

//若使用++a 则对应方法是a.incrementAndGet(); 先自增再获取 , //多说一句 a-- 就是 a.getAndDecrement(); //若a = a + 10;————对应API a.getAndAdd(10);

}

/**

* springCloud中,两种方式调用(rest/feign)

*

* @return

*/

// 订单服务调用会员服务

@RequestMapping("/getOrder")

public String getOrder() {

// 有两种调用方式,一种是采用服务别名方式调用,另一种是使用别名去注册中心上获取对应服务调用地址

// 第一种方式

String url = "http://dy-202006281547:8000/getMember";

// 第二种方式

url = "http://zk-member/getMember";

String result = restTemplate.getForObject(url, String.class);

return "订单服务调用会员服务:" + result;

}

/**

* springCloud中,两种方式调用(rest/feign)

*

* @return

*/

// 订单服务调用会员服务

@RequestMapping("/getRibbonOrder")

public String getRibbonOrder() {

// 第一种方式

String url = getUri() + "/getMember";

String result = restTemplate.getForObject(url, String.class);

return "纯手写Ribbon本地负载均衡:" + result;

}

public String getUri() {

List<ServiceInstance> serviceInstances = discoveryClient.getInstances("consul-member");

if (serviceInstances == null || serviceInstances.isEmpty()) {

return null;

}

int serverSize = serviceInstances.size();

int count = add();

int indexServer = count % serverSize;

return serviceInstances.get(indexServer).getUri().toString();

}

}

AppOrder.java 启动类,关闭 @LoadBalanced 注解即可:
【Java】SpringCloud手写Ribbon实现负载均衡

由于我们是在 springcloud集成zookeeper 项目上改造的,所以order 模块 yml 配置也做相应的调整,注册中心修改为consul,并且在该模块中引入 consul 的 maven依赖

<!--springcloud 整合consul-->

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-consul-discovery</artifactId>

</dependency>

【Java】SpringCloud手写Ribbon实现负载均衡

启动 AppOrder.java,并刷新 http://localhost:8500/ui/dc1/services 可以发现上面 注册了 order 服务:
【Java】SpringCloud手写Ribbon实现负载均衡

这里有一个巨坑,导致 order 模块调用不到 member 模块,我们需要在yml 配置文件中注释掉:
参考博客: https://blog.csdn.net/apdkapskdad/article/details/93927860

## consul ip地址

##hostname: 192.168.3.91

消费者调用生产者:访问http://localhost:8508/getRibbonOrder
【Java】SpringCloud手写Ribbon实现负载均衡
【Java】SpringCloud手写Ribbon实现负载均衡
OK!我们便达到了负载均衡!

以上是 【Java】SpringCloud手写Ribbon实现负载均衡 的全部内容, 来源链接: utcz.com/a/105639.html

回到顶部