共计 3171 个字符,预计需要花费 8 分钟才能阅读完成。
前言
后面咱们学习了 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! 咱们便达到了负载平衡!