使用 Spring Cloud Alibaba 搭建
微服务
,业务实例默认使用内网 IP 注册到 Nacos 服务端,这样在跨
局域网
时会无法请求成功。那如何解决呢?
答:指定
外网
IP 注册到 Nacos 上。

下述方法来自网络,版权归原著作人,本人只是搬运工+实践者!
在 Nacos 客户端指定IP,启动成功后即可以在 Nacos 服务端上看到对应的IP。
在 bootstrap.yml 配置文件中写入:
|
1 2 |
spring.cloud.nacos.discovery.ip = xx spring.cloud.nacos.discovery.port = xxx |
或指定网卡注册:
|
1 |
spring.cloud.nacos.discovery.networkInterface = xx |
也可以使用spring cloud 的 InetUtils工具,配置项为,具体说明可以自行检索
|
1 2 3 4 5 6 |
spring.cloud.inetutils.default-hostname spring.cloud.inetutils.default-ip-address spring.cloud.inetutils.ignored-interfaces spring.cloud.inetutils.preferred-networks spring.cloud.inetutils.timeout-seconds spring.cloud.inetutils.use-only-site-local-interfaces |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
package com.zhongyi.doctor.config; import cn.hutool.http.Header; import cn.hutool.http.HttpRequest; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; import com.alibaba.cloud.nacos.NacosServiceManager; import com.alibaba.cloud.nacos.discovery.NacosServiceDiscovery; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; /** * @author SymbolWong * @description * @date 2023/2/6 16:25 */ @Configuration @Slf4j public class NacosDiscoveryConfig { /** * nacosConfigServerAaddr yml中配置的nacos配置中心地址 */ @Value("${spring.cloud.nacos.config.server-addr}") String nacosConfigServerAaddr; /** * nacosConfignamespace yml中配置的nacos配置中心命名空间 */ @Value("${spring.cloud.nacos.config.namespace}") String nacosConfignamespace; /** * getServerInternetIP 通过Nginx获取本机外网IP,需要Nginx配合配置 * @author IPMan * @date 2022/7/10 * * @return java.lang.String 返回本机外网IP */ private String getServerInternetIPByNginx(){ //通过配置中心地址构造查询IP请求地址 String url="http://"+nacosConfigServerAaddr.split(":")[0]+"/getIp"; //调试输出,这里不推荐err的方式输出,这样仅为测试使用,推荐采用日志实现或者不输出 // System.err.println(url); log.warn("Nacos server addr is {}",url); //外网IP String internetIP="127.0.0.1"; //这里一步完成了,构造一个RestTemplate对象,通过对指定URL执行GET请求来获取响应实体 ResponseEntity<String> response = new RestTemplate() .getForEntity(url, String.class); // //从响应实体对象中获取内容 internetIP = response.getBody(); // //调试输出,这里不推荐err的方式输出,这样仅为测试使用,推荐采用日志实现或者不输出 // System.err.println(internetIP); log.warn("Internet ip is {}",url); return internetIP; } /** * nacosProperties Nacos 服务发现配置类,代替yml中spring.cloud.nacos.discovery:配置 * @author IPMan * @date 2022/7/10 * * @return com.alibaba.cloud.nacos.NacosDiscoveryProperties */ @Bean public NacosDiscoveryProperties nacosProperties() { //new一个nacos服务发现配置对象 NacosDiscoveryProperties properties = new NacosDiscoveryProperties(); //设置发现注册的IP,即注册中心详情中的IP,这里很关键,默认是Inet4Address.getLocalHost(),即如果包含子网,则获取的是子网IP properties.setIp(getServerInternetIP()); //设置注册中心地址 properties.setServerAddr(nacosConfigServerAaddr); //设置注册中心命名空间 properties.setNamespace(nacosConfignamespace); return properties; } private String getServerInternetIP() { String internetip = ""; String url = "https://ip.3322.org"; internetip = HttpRequest.get(url) .header(Header.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36") .execute().body(); log.warn("Internet ip is {}",internetip); return internetip; } /** * nacosServiceDiscovery nacos 服务发现对象,这个对象构造完成后是无法设置配置的 * @author IPMan * @date 2022/7/10 * * @param discoveryProperties com.alibaba.cloud.nacos.NacosDiscoveryProperties * @param nacosServiceManager com.alibaba.cloud.nacos.NacosServiceManager * @return com.alibaba.cloud.nacos.discovery.NacosServiceDiscovery */ @Bean public NacosServiceDiscovery nacosServiceDiscovery( NacosDiscoveryProperties discoveryProperties, NacosServiceManager nacosServiceManager) { return new NacosServiceDiscovery(discoveryProperties, nacosServiceManager); } } |
PS:本人使用该方法虽然能注册成功,但是请求是失败的,报错:Illegal character in authority at index 7,本来以为是得到的公网IP前后有空格之类的,用了trim方法依然还是报错,有待继续研究。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
package com.zhongyi.doctor.config; import cn.hutool.http.Header; import cn.hutool.http.HttpRequest; import org.springframework.boot.context.config.ConfigFileApplicationListener; import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; import org.springframework.boot.context.event.ApplicationPreparedEvent; import org.springframework.context.ApplicationEvent; import org.springframework.context.event.SmartApplicationListener; import org.springframework.core.Ordered; /** * @author SymbolWong * @description * @date 2023/2/18 9:13 */ public class AfterConfigListener implements SmartApplicationListener, Ordered { @Override public boolean supportsEventType(Class<? extends ApplicationEvent> aClass) { return (ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(aClass) || ApplicationPreparedEvent.class.isAssignableFrom(aClass)); } @Override public int getOrder() { return (ConfigFileApplicationListener.DEFAULT_ORDER + 1); } @Override public void onApplicationEvent(ApplicationEvent applicationEvent) { String currentIp = getServerInternetIP(); if (applicationEvent instanceof ApplicationEnvironmentPreparedEvent) { System.setProperty("spring.cloud.nacos.discovery.ip", currentIp); } } private String getServerInternetIP() { String internetip = ""; String url = "https://ip.3322.org"; internetip = HttpRequest.get(url) .header(Header.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36") .execute().body(); return internetip.trim(); } } |
2、启动入口处注入该监听类
|
1 2 3 |
SpringApplication springApplication = new SpringApplication(DoctorApplication.class); springApplication.addListeners(new AfterConfigListener()); springApplication.run(args); |
PS:使用此方法完美解决,可以愉快的跨服务器请求了!
参考文章:[Nacos] 业务实例如何指定IP注入Nacos_nacos指定ip-CSDN博客
from:https://blog.csdn.net/yyongsheng/article/details/134137316