1.前提准备
本文是在使用nacos的基础上进行的简单讲解,如果nacos了解的不多的朋友可以先了解下nacos的基本用法,传送地址:【Nacos的介绍和使用】
2.关于服务端负载均衡
单体架构模式下,一个应用会用多个实例,通过nginx做反向代理,将请求过来的数据通过负载均衡算法确定好指定实例进行转发,而nginx是部署是在服务器端的,这种方式就叫做服务端的负载均衡
3.关于客户端负载均衡
内容中心通过discoveryClient获取到用户中心的所有实例,我们通过手写一个负载均衡的规则确定好请求哪个实例,通过RestTemplate进行请求这样就实现了手写的一个客户端负载均衡器。
4.启动服务
准备2个服务content-center和user-center,user-center准备2个实例,后面使用content-center选择user-center的实例进行调用。可参考:【Nacos的介绍和使用】
5 content-center 编码
5.1 ShareController.java
package com.ding.contentcenter.controller.content;
import com.ding.contentcenter.domain.dto.content.ShareDTO;
import com.ding.contentcenter.service.content.ShareService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/shares")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ShareController {
private final ShareService shareService;
@GetMapping("/{id}")
public ShareDTO findById(@PathVariable Integer id){
return this.shareService.findById(id);
}
}
5.2 ShareService.java
package com.ding.contentcenter.service.content;
import com.alibaba.nacos.client.naming.utils.ThreadLocalRandom;
import com.ding.contentcenter.dao.share.ShareMapper;
import com.ding.contentcenter.domain.dto.content.ShareDTO;
import com.ding.contentcenter.domain.dto.user.UserDTO;
import com.ding.contentcenter.domain.entity.share.Share;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ShareService {
private final ShareMapper shareMapper;
private final RestTemplate restTemplate;
private final DiscoveryClient discoveryClient;
public ShareDTO findById(Integer id){
Share share = this.shareMapper.selectByPrimaryKey(id);
Integer userId = share.getUserId();
List<ServiceInstance> instances = discoveryClient.getInstances("user-center");
List <String> targetURLS = instances.stream()
.map(instance -> instance.getUri().toString()+"/users/{id}")
.collect(Collectors.toList());
int i = ThreadLocalRandom.current().nextInt(targetURLS.size());
log.info("请求的目标地址:{}",targetURLS.get(i));
UserDTO userDTO = this.restTemplate.getForObject(
targetURLS.get(i),
UserDTO.class,userId
);
ShareDTO shareDTO = new ShareDTO();
BeanUtils.copyProperties(share,shareDTO);
shareDTO.setWxNickname(userDTO.getWxNickname());
return shareDTO;
}
}
5.3 多次调用地址
http://localhost:8082/shares/1
5.4 响应结果:
{
"id": 1,
"userId": 1,
"title": "xxx",
"createTime": "2022-04-17T16:28:34.000+00:00",
"updateTime": "2022-04-17T16:28:34.000+00:00",
"isOriginal": false,
"author": "earnest",
"cover": "xxx",
"summary": "",
"price": 0,
"downloadUrl": "",
"buyCount": 1,
"showFlag": false,
"auditStatus": "0",
"reason": "",
"wxNickname": "212aa"
}
5.6 查看随机请求实例:
总结:客户端content-center每次生成随机的user-center服务端请求地址进行请求实现了简单的客户端负载均衡。
提示:@LoadBalanced记得注释,这个注解是RestTemplate用来整合Ribbon,不注解以上请求会失效
(此文完)
|