前言
前面我们学习了 SpringCloud整合Consul,在此基础上我们手写本地客户端实现类似Ribbon负载均衡的效果。
注:order
模块调用者 记得关闭 @LoadBalanced
注解。我们这里只演示 注册中心 consul,至于 zookeeper 也是一模一样。
生产者
member模块
member
服务需要集群,所以我们copy application-consul.yml
文件命名为 application-consul2.yml
服务别名一致,只需要修改端口号即可。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 包路径 shift + 右键
启动 PowerShell 窗口,运行命令:
java -jar E:\ideaworkspaceback\springcloud-zookeeper\springcloud-zookeeper-member\target\springcloud-zookeeper-member-1.0-SNAPSHOT.jar --spring.profiles.active=consul2
启动 8503
端口
打开 http://localhost:8500/ui/dc1/services 可以发现上面 注册了 member
集群服务:
消费者
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
注解即可:
由于我们是在 springcloud集成zookeeper
项目上改造的,所以order 模块
yml 配置也做相应的调整,注册中心修改为consul,并且在该模块中引入 consul 的 maven依赖
<!--springcloud 整合consul-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
启动 AppOrder.java
,并刷新 http://localhost:8500/ui/dc1/services 可以发现上面 注册了 order
服务:
这里有一个巨坑,导致 order
模块调用不到 member
模块,我们需要在yml 配置文件中注释掉:
参考博客: https://blog.csdn.net/apdkapskdad/article/details/93927860
## consul ip地址
##hostname: 192.168.3.91
消费者调用生产者:访问http://localhost:8508/getRibbonOrder
OK!我们便达到了负载均衡!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。