环境
- spring-boot --> 2.3.7
- spring-cloud --> Hoxton.SR9
- spring-cloud-alibaba --> 2.2.2.RELEASE
过程
- 起因:本地开发时候,启动gateway与业务服务,当业务服务发生修改需要重启,gateway必须重启或等待服务定时刷新
- 操作:刷ribbon 与nacos服务列表更新源码,发现入口是写死的,无法重写,无法直接调用
- 风险:建议不要线上暴露,保留定时刷新原则,灰度发布也继续使用定时刷新,仅建议开发环境使用
代码
依赖:
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.cloud.nacos.NacosServiceManager;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.client.naming.core.HostReactor;
import com.netflix.loadbalancer.ServerListUpdater;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.named.NamedContextFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
方法:
public void refreshServerInfo() {
NamingService namingService = SpringUtil.getBean(NacosServiceManager.class).getNamingService(SpringUtil.getBean(Properties.class));
HostReactor hostReactor = (HostReactor) ReflectUtil.getFieldValue(namingService, "hostReactor");
Map<String, ServiceInfo> serviceInfoMap = (Map<String, ServiceInfo>) ReflectUtil.getFieldValue(hostReactor, "serviceInfoMap");
Set<String> set = serviceInfoMap.keySet();
for (String serviceName : set) {
ReflectUtil.invoke(hostReactor, ReflectUtil.getMethod(HostReactor.class, "updateServiceNow", String.class, String.class), serviceName, "");
ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) SpringUtil.getBean(NamedContextFactory.class).getInstance(serviceName.repl