开发经验gateway网关开发调试优先选择本地服务
Posted 叁滴水
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开发经验gateway网关开发调试优先选择本地服务相关的知识,希望对你有一定的参考价值。
背景
在微服务开发时,本地要启动太多的服务,比如基本服务,注册中心、网关、鉴权等等。还要启动当前代码所在的服务。这样,本地环境会特别卡,影响开发效率。
:
如下图所示:
在局域网内搭建一套开发环境,在开发时,这个开发环境启动的服务用来做“备胎”。
1.客户端访问的时候,携带自己想要优先访问的ip。
2.网关在转发时,发现客户端有想要优先访问的ip,则优先转发。
在整个微服务转发过程中,设计到进入网关时转发
和RPC调用时转发
;此只介绍网关转发时锁定远程ip。
如果是dubbo调用时想锁定远程ip可参考文章dubbo多服务本地开发调试
代码思路
网关层面在进行服务选择时,肯定会加载所有的服务,然后根据随机、轮训、权重等规则进行分发。只要自定义自己的路由规则即可。新建远程锁定ip负载均衡类LockRemoteIpLoadBalancer.java
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.*;
import org.springframework.cloud.loadbalancer.core.*;
import org.springframework.http.HttpHeaders;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public class LockRemoteIpLoadBalancer implements ReactorServiceInstanceLoadBalancer
private static final Log log = LogFactory.getLog(LockRemoteIpLoadBalancer.class);
private static final String LockIp="lock-remote—ip";
ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
final String serviceId;
public LockRemoteIpLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId)
this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
this.serviceId = serviceId;
@Override
public Mono<Response<ServiceInstance>> choose(Request request)
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
.getIfAvailable(NoopServiceInstanceListSupplier::new);
return supplier.get(request).next()
.map(serviceInstances -> processInstanceResponse(supplier, serviceInstances, request));
private Response<ServiceInstance> processInstanceResponse(ServiceInstanceListSupplier supplier,
List<ServiceInstance> serviceInstances,
Request request)
Response<ServiceInstance> serviceInstanceResponse = getInstanceResponse(serviceInstances, request);
if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer())
((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstanceResponse.getServer());
return serviceInstanceResponse;
private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances, Request request)
if (instances.isEmpty())
if (log.isWarnEnabled())
log.warn("No servers available for service: " + serviceId);
return new EmptyResponse();
int index = ThreadLocalRandom.current().nextInt(instances.size());
ServiceInstance instance = instances.get(index);
//锁定远程ip逻辑
//在请求头添加想要访问的ip
if (request instanceof DefaultRequest)
DefaultRequest defaultRequest = (DefaultRequest) request;
if (defaultRequest.getContext() instanceof RequestDataContext)
RequestDataContext requestDataContext = (RequestDataContext) defaultRequest.getContext();
HttpHeaders headers = requestDataContext.getClientRequest().getHeaders();
if (headers.containsKey(LockIp))
ServiceInstance lockIpInstance = this.chooseLockIpInstance(instances,headers.get(LockIp));
instance = lockIpInstance!=null?lockIpInstance:instance;
return new DefaultResponse(instance);
private ServiceInstance chooseLockIpInstance(List<ServiceInstance> instances, List<String> strings)
//获取想要访问的ip
String ip = strings.get(0);
// 循环所有服务器,查看是否有符合规则的服务
for(ServiceInstance instance:instances)
if(ip.equals(instance.getHost()))
return instance;
return null;
添加配置类,选用自己的负责均衡规则
@Configuration
@LoadBalancerClients(
//远程服务名称,比如订单服务、商品服务。如果哪个服务想要使用此规则,在这边添加即可
@LoadBalancerClient(name = "order-application", configuration = GatewayConfig.class)
)
public class GatewayConfig
@Bean
public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory)
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new LockRemoteIpLoadBalancer(
loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
然后在请求头添加如下:
lock-remote—ip:192.168.1.50
即可优先访问这个ip。
以上是关于开发经验gateway网关开发调试优先选择本地服务的主要内容,如果未能解决你的问题,请参考以下文章
开发经验为什么gateWay网关要用webFlux代替WebMvc
开发经验为什么gateWay网关要用webFlux代替WebMvc
Solon2 接口开发: 分布式 Api Gateway 开发预览
#yyds干货盘点#SpringCloud技术专题「Gateway网关系列」微服务网关服务的Gateway全流程开发实践指南(2.2.X)