asp网站小迪网站建设
- 作者: 多梦笔记
- 时间: 2026年02月16日 03:38
当前位置: 首页 > news >正文
asp网站,小迪网站建设,汕头网,wordpress主题请勿删除版权信息一。技术背景
由于升级jdk17的需要 我们将项目中的 spring cloud spring cloud alibaba 以及springboot进行了升级 各版本如下 spring cloud 2021.0.5 spring cloud alibaba 2021.0.5.0 spring boot 2.6.13
二。问题表现
当启动项目服务后#xff0c;服务无法注册到 sentin…一。技术背景
由于升级jdk17的需要 我们将项目中的 spring cloud spring cloud alibaba 以及springboot进行了升级 各版本如下 spring cloud 2021.0.5 spring cloud alibaba 2021.0.5.0 spring boot 2.6.13
二。问题表现
当启动项目服务后服务无法注册到 sentinel-dashboard
三。错误排查
首先检查sentinel-dashboard 启动状态 启动成功并且可以正常访问且不存在网络问题环境配置检查
!– 依赖检查 无误 –
dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-gateway/artifactId
/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactId
/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-alibaba-sentinel-gateway/artifactId
/dependency配置检查
#配置也正常
spring.cloud.sentinel.transport.dashboardlocalhost:8080
spring.cloud.sentinel.transport.port8719第三步源码追踪
接下来开始漫长源码分析步骤
然后点击 spring.cloud.sentinel.transport.dashboard 这条配置 跳转 com.alibaba.cloud.sentinel.SentinelProperties.Transport#setDashboard
然后点击 getDashboard() 方法查看在哪里调用 最后来到了 com.alibaba.cloud.sentinel.custom.SentinelAutoConfiguration#init
在如下代码中
Configuration(proxyBeanMethods false)
ConditionalOnProperty(name spring.cloud.sentinel.enabled, matchIfMissing true)
EnableConfigurationProperties(SentinelProperties.class)
public class SentinelAutoConfiguration {PostConstructprivate void init() {///省略部分逻辑 if (StringUtils.isEmpty(System.getProperty(TransportConfig.SERVER_PORT)) StringUtils.isNotBlank(properties.getTransport().getPort())) {System.setProperty(TransportConfig.SERVER_PORT,properties.getTransport().getPort());}if (StringUtils.isEmpty(System.getProperty(TransportConfig.CONSOLE_SERVER)) StringUtils.isNotBlank(properties.getTransport().getDashboard())) {System.setProperty(TransportConfig.CONSOLE_SERVER,properties.getTransport().getDashboard());}}
}断点时 发现配置成功被设置到 系统的属性配置中 接下来再来看 心跳发送具体类 HeartbeatSenderInitFunc com.alibaba.csp.sentinel.transport.init.HeartbeatSenderInitFunc#init
Override
public void init() {HeartbeatSender sender HeartbeatSenderProvider.getHeartbeatSender();if (sender null) {RecordLog.warn([HeartbeatSenderInitFunc] WARN: No HeartbeatSender loaded);return;}initSchedulerIfNeeded();long interval retrieveInterval(sender);setIntervalIfNotExists(interval);//定时调度发送心跳scheduleHeartbeatTask(sender, interval);
}具体得调度逻辑 每5秒发送一次心跳
private void scheduleHeartbeatTask(/NonNull/ final HeartbeatSender sender, /Valid/ long interval) {pool.scheduleAtFixedRate(new Runnable() {Overridepublic void run() {try {sender.sendHeartbeat();} catch (Throwable e) {RecordLog.warn([HeartbeatSender] Send heartbeat error, e);}}}, 5000, interval, TimeUnit.MILLISECONDS);RecordLog.info([HeartbeatSenderInit] HeartbeatSender started: sender.getClass().getCanonicalName());
}我们再来看下具体的实现 sender.sendHeartbeat(); 实现类只有一个 SimpleHttpHeartbeatSender
com.alibaba.csp.sentinel.transport.heartbeat.SimpleHttpHeartbeatSender#sendHeartbeat
Override
public boolean sendHeartbeat() throws Exception { if (TransportConfig.getRuntimePort() 0) { RecordLog.info([SimpleHttpHeartbeatSender] Command server port not initialized, wont send heartbeatreturn false; } Endpoint addrInfo getAvailableAddress(); if (addrInfo null) { return false; } SimpleHttpRequest request new SimpleHttpRequest(addrInfo, TransportConfig.getHeartbeatApiPath()); request.setParams(heartBeat.generateCurrentMessage()); try { SimpleHttpResponse response httpClient.post(request); if (response.getStatusCode() OK_STATUS) { return true; } else if (clientErrorCode(response.getStatusCode()) || serverErrorCode(response.getStatusCode())) { RecordLog.warn([SimpleHttpHeartbeatSender] Failed to send heartbeat to addrInfo , http status code: response.getStatusCode()); } } catch (Exception e) { RecordLog.warn([SimpleHttpHeartbeatSender] Failed to send heartbeat to addrInfo, e); } return false;
}
以上就是发送心跳的逻辑 核心逻辑
获取有效的链接创建连接发送心跳请求响应以及异常处理
但是在断点过程中 有效的链接列表居然是空的 这就是导致代码无法继续向下 然后我们继续围绕这个点进行排查
获取有效的地址列表方法如下
private Endpoint getAvailableAddress() {if (addressList null || addressList.isEmpty()) {return null;}if (currentAddressIdx 0) {currentAddressIdx 0;}int index currentAddressIdx % addressList.size();return addressList.get(index);
}发现使用的成员变量 addressList 我们再来找下这个值的赋值操作
赋值操作只有一个地方 在SimpleHttpHeartbeatSender的构造方法中
public SimpleHttpHeartbeatSender() {// Retrieve the list of default addresses.ListEndpoint newAddrs TransportConfig.getConsoleServerList();if (newAddrs.isEmpty()) {RecordLog.warn([SimpleHttpHeartbeatSender] Dashboard server address not configured or not available);} else {RecordLog.info([SimpleHttpHeartbeatSender] Default console address list retrieved: {}, newAddrs);}this.addressList newAddrs;
}com.alibaba.csp.sentinel.transport.config.TransportConfig#getConsoleServerList
public static ListEndpoint getConsoleServerList() {String config SentinelConfig.getConfig(CONSOLE_SERVER);ListEndpoint list new ArrayListEndpoint();if (StringUtil.isBlank(config)) {return list;}//。。。。。省略部分return list;
}com.alibaba.csp.sentinel.config.SentinelConfig#getConfig(java.lang.String)
public static String getConfig(String key) {AssertUtil.notNull(key, key cannot be null);return props.get(key);
}我们再来看下 props的初始化
在SentinelConfig的静态构造中
static {try {initialize();//加载配置loadProps();resolveAppName();resolveAppType();RecordLog.info([SentinelConfig] Application type resolved: {}, appType);} catch (Throwable ex) {RecordLog.warn([SentinelConfig] Failed to initialize, ex);ex.printStackTrace();}
}com.alibaba.csp.sentinel.config.SentinelConfig#loadProps
private static void loadProps() {///从配置加载中获取配置Properties properties SentinelConfigLoader.getProperties();for (Object key : properties.keySet()) {setConfig((String) key, (String) properties.get(key));}
}从SentinelConfigLoader 获取到配置
public static Properties getProperties() {return properties;
}而这个properties的初始化是在SentinelConfigLoader 静态构造方法中
static {try {load();} catch (Throwable t) {RecordLog.warn([SentinelConfigLoader] Failed to initialize configuration items, t);}
}private static void load() {// Order: system property - system env - default file (classpath:sentinel.properties) - legacy pathString fileName System.getProperty(SENTINEL_CONFIG_PROPERTY_KEY);if (StringUtil.isBlank(fileName)) {fileName System.getenv(SENTINEL_CONFIG_ENV_KEY);if (StringUtil.isBlank(fileName)) {fileName DEFAULT_SENTINEL_CONFIG_FILE;}}Properties p ConfigUtil.loadProperties(fileName);if (p ! null !p.isEmpty()) {RecordLog.info([SentinelConfigLoader] Loading Sentinel config from {}, fileName);properties.putAll(p);}for (Map.EntryObject, Object entry : new CopyOnWriteArraySet(System.getProperties().entrySet())) {String configKey entry.getKey().toString();String newConfigValue entry.getValue().toString();String oldConfigValue properties.getProperty(configKey);properties.put(configKey, newConfigValue);if (oldConfigValue ! null) {RecordLog.info([SentinelConfigLoader] JVM parameter overrides {}: {} - {},configKey, oldConfigValue, newConfigValue);}}
}看到这里就大概明白了因为这是静态代码话 肯定优先初始化而我们的地址在项目启动bean加载中才会设置到System的Properties里
所以获取的 地址一直是空的。 也无法注册到sentinel-dashboard上
四。解决办法
idea 启动类 增加参数 指定dashboard server地址 以及应用名称
-Dcsp.sentinel.dashboard.serverlocalhost:8080 -Dcsp.sentinel.app.namegateway-service启动类设置系统变量
SpringBootApplication
EnableDiscoveryClient
public class GatewayServiceApplication {public static void main(String[] args) {System.setProperty(csp.sentinel.dashboard.server,localhost:8080);System.setProperty(csp.sentinel.app.name,gateway-service);SpringApplication.run(GatewayServiceApplication.class, args);}}五。后续分析旧的版本的依赖对应的实现方式
旧的依赖版本为 springboot 2.3.12.RELEASE spring cloud Hoxton.SR12 spring cloud alibaba 2.2.9.RELEASE
- 上一篇: asp网站如何搭建关键词seo优化排名
- 下一篇: asp网站新闻置顶成都网站建设电话咨询
相关文章
-
asp网站如何搭建关键词seo优化排名
asp网站如何搭建关键词seo优化排名
- 站长
- 2026年02月16日
-
asp网站没有数据库外贸原单是什么意思
asp网站没有数据库外贸原单是什么意思
- 站长
- 2026年02月16日
-
asp网站路径学校网站建设开发项目计划报告
asp网站路径学校网站建设开发项目计划报告
- 站长
- 2026年02月16日
-
asp网站新闻置顶成都网站建设电话咨询
asp网站新闻置顶成都网站建设电话咨询
- 站长
- 2026年02月16日
-
asp网站压缩建一个网站大约多少钱
asp网站压缩建一个网站大约多少钱
- 站长
- 2026年02月16日
-
asp网站优化访问速度点石关键词排名优化软件
asp网站优化访问速度点石关键词排名优化软件
- 站长
- 2026年02月16日
