问题
如果服务端如果配置了
server:
port: 8081
servlet:
context-path: xxxxx
对于nacos服务进行注册后,有可能因为 context-path 的问题导致
spring cloude gateway、
@LoadBalanced、
openFeign
三种负载均衡的方式 无法找到对应路径而出错
方案一:
采用nacos 服务注册带metadata参数方式
discovery:
#server-addr: 192.168.100.254:8848
group: CHRIS-GROUP
weight: 1
metadata:
context-path: '${server.servlet.context-path}'
scheme: "http"
但是只能手动读取拼凑,代码如下
private String GetUrl(String ServiceName)
{
//---方案1 loadBalancerClient---------
//serviceId要在nacos的服务列表中
ServiceInstance choose = loadBalancerClient.choose(ServiceName);
String ip = choose.getHost();
int port = choose.getPort();
String scheme="http";
String context_path="";
if (choose.getMetadata().containsKey("scheme"))
scheme=choose.getMetadata().get("scheme");
if (choose.getMetadata().containsKey("context-path"))
context_path=choose.getMetadata().get("context-path");
String url = String.format("%s://%s:%s%s", scheme,ip,port,context_path);
return url;
}
有一定局限性,只合适纯手动自定义 获取服务发现模式,无法[自动]适配 gateway、@LoadBalanced、openFeign
方案二
在【方案一】基础上
openFeign解决方案
@FeignClient(name = "${var.dataid}" ,path = "${var.context-path}")//,contextId = "remoteProviderService"
@Service
public interface OpenfeignService {
@GetMapping("/nacos/{id}")
String nacos(@PathVariable("id") Integer id);
}
gateway解决方案
routes: #手工定义路由
-
id: chris_route
uri: lb://${var.dataid}
predicates:
- Path=/${context-path}/**
#filters:
# - StripPrefix=1 #过滤第一级path
@LoadBalanced解决方案
restTemplate.getForObject("http://"+appName+context_path+"/" + id, String.class);
appName,context_path 从配置文件取
方案三(推荐)
采用约定大于配置原则,全局约定
dataid = context-path
在【方案二】基础上
openFeign解决方案
@FeignClient(name = "${var.dataid}" ,path = "${var.dataid}")//,contextId = "remoteProviderService"
@Service
public interface OpenfeignService {
@GetMapping("/nacos/{id}")
String nacos(@PathVariable("id") Integer id);
}
gateway解决方案
routes: #手工定义路由
-
id: chris_route
uri: lb://${var.dataid}
predicates:
- Path=/${var.dataid}/**
#filters:
# - StripPrefix=1 #过滤第一级path
@LoadBalanced解决方案
restTemplate.getForObject("http://"+dataid+"/"+dataid+"/" + id, String.class);
dataid从配置文件取