springcloud整合nacos实现相同版本实例相互调用

ops/2024/10/21 10:12:37/

springcloud整合nacos实现相同版本实例相互调用

注: 本文为自己学习研究总结,仅供参考,若有侵权,请及时联系本人

业务场景

有时候一些新的业务或者修改后的功能只开放给部分人访问,那么可以新老版本都部署,对于大多数人访问老版本,部分人访问新版本。部分人请求的时候,http请求header添加特定的version值,结合nacos的服务元数据进行塞选服务实例,从而实现不同人访问相同的功能,对应不同的版本。

基础理论

(1)基于feign进行远程方法调用,首先FeignBlockingLoadBalancerClient会根据url中的serviceId,交给LoadBalancerClient#choose()方法拉取服务列表并且基于负载均衡算法选择一个服务实例,最后重构Uri发起请求
(2)RoundRobinLoadbalancer(轮询,springcloudloadbalance默认负载均衡实现,还有一个是随机负载均衡)为例,ServiceInstanceListSupplier#get()用于拉取服务实例,getInstanceResponse()用于负载均衡选择某个实例

coding

demo如下:

import com.google.common.collect.Lists;
import com.test.server.util.GreyThreadLocalUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.DelegatingServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import reactor.core.publisher.Flux;import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Slf4j
public class SameVersionServiceInstanceListSupplier extends DelegatingServiceInstanceListSupplier {private final String VERSION = "version";public SameVersionServiceInstanceListSupplier(ServiceInstanceListSupplier delegate) {super(delegate);}@Overridepublic Flux<List<ServiceInstance>> get() {ServiceInstanceListSupplier delegate1 = getDelegate();Flux<List<ServiceInstance>> listFlux = delegate1.get();Flux<List<ServiceInstance>> map = listFlux.map(this::filteredByVersion);return map;}/*** 根据version进行过滤* @param serviceInstances* @return*/private List<ServiceInstance> filteredByVersion(List<ServiceInstance> serviceInstances) {List<ServiceInstance> filteredInstances = new ArrayList<>();for (ServiceInstance serviceInstance : serviceInstances) {String instanceVersion = getVersion(serviceInstance);if (GreyThreadLocalUtils.getVersion().equalsIgnoreCase(instanceVersion)) {filteredInstances.add(serviceInstance);}}if (filteredInstances.size() > 0) {return filteredInstances;}return Lists.newArrayList();}/*** 从元数据获取version值* @param serviceInstance* @return*/private String getVersion(ServiceInstance serviceInstance) {Map<String, String> metadata = serviceInstance.getMetadata();if (metadata != null) {return metadata.get(VERSION);}return null;}
}
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.cloud.loadbalancer.support.SimpleObjectProvider;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;@Component
@Configuration(proxyBeanMethods = false)
public class LoadBalanceConfig {/*** 支持的服务实例* @param context* @return*/@Beanpublic ServiceInstanceListSupplier serviceInstanceListSupplier(ConfigurableApplicationContext context) {ServiceInstanceListSupplier supplier = ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withCaching().build(context);return new SameVersionServiceInstanceListSupplier(supplier);}/*** 负载均衡方式* @param environment* @param serviceInstanceListSupplier* @return*/@Beanpublic ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment, ServiceInstanceListSupplier serviceInstanceListSupplier) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RoundRobinLoadBalancer(new SimpleObjectProvider<>(serviceInstanceListSupplier), name);}
}
/*** 注入了spring容器*/
@Configuration(proxyBeanMethods = false)
@LoadBalancerClients(defaultConfiguration = LoadBalanceConfig.class)
@AutoConfigureBefore({ ReactorLoadBalancerClientAutoConfiguration.class,LoadBalancerBeanPostProcessorAutoConfiguration.class })
public class LoadBalanceAutoConfiguration {
}

参考资料

(1) https://mp.weixin.qq.com/s/rsRGMRiRb0atKclPl2K1zg
(2) 黑马程序员 java黑马商城项目微服务实战开发视频讲解


http://www.ppmy.cn/ops/36372.html

相关文章

苹果CEO对未来一代人工智能投资持乐观态度

尽管在动荡的第二季度&#xff0c;苹果的收入和iPhone销量有所下降&#xff0c;但其新兴的人工智能技术可能会带来急需的提振。 在5月2日的电话财报会议上&#xff0c;苹果公布季度收入为908亿美元&#xff0c;比去年下降4%。iPhone的收入也下降了10%&#xff0c;至460亿美元。…

pytorch_lightning 训练教程

步骤1&#xff1a;引入必要的库 首先&#xff0c;确保你已经安装了 pytorch_lightning。pip 安装&#xff1a; pip install pytorch_lightning 然后在你的代码中导入必要的库&#xff1a; import pytorch_lightning as pl from pytorch_lightning.callbacks import ModelC…

与Apolo共创生态: Apollo X企业自动驾驶解决方案的亮点

文章目录 前言技术革新的里程碑Apollo X企业自动驾驶解决方案的亮点Application X企业预制套件的多场景覆盖Studio X企业协同工具链的全周期支持第一阶段&#xff1a;上机系统构建第二阶段&#xff1a;POC搭建第三阶段&#xff1a;规模运营小结 共创生态&#xff0c;共享未来共…

学习R语言第五天

文章目录 语法学习创建数据的方式绘制图形的方式图形添加颜色如何操作数据的方式数据进行验算的判断加付值的方式修改变量名称的方式判断是否存在缺失值在计算的方式忽略缺失值通过函数的方式忽略缺失值日期处理的方式字符串转化成日期的方式格式化数据框中数据返回当前的日期的…

2-5 任务:打印九九表

本次实战的目标是通过编写程序实现打印九九乘法表、字符矩形、字符平行四边形和字符菱形等图形&#xff0c;以及解决百钱买百鸡问题和输出素数等实际问题。在实战过程中&#xff0c;我们将学习并掌握以下知识点。 双重循环的使用&#xff1a;通过双重循环实现九九乘法表的打印&…

libcity笔记:libcity/utils/utils.py

1 get_logger 2 set_random_seed def set_random_seed(seed):"""重置随机数种子Args:seed(int): 种子数"""random.seed(seed)#设置 Python 内置的随机数生成器的种子np.random.seed(seed)#设置 NumPy 的随机数生成器的种torch.manual_seed(see…

Vue的省份联动

Vue的省份联动 一、安装依赖库 npm install element-china-area-data -Snpm install element-ui --save全局使用elemntui组件库 import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css;Vue.use(ElementUI);二 、代码如下 <template><div…

linux查看ip和端口

1. ip addr ip addr 或者 ip addr show 输出包含了网络接口的名称、状态、MTU&#xff08;Maximum Transmission Unit&#xff09;、链路层地址&#xff08;如MAC地址&#xff09;、IPv4和IPv6地址等信息。 2. 只需要 ip地址 ipV4 ip addr | grep inet ipV6 3.查看端口 s…