当前位置: 首页 > news >正文

厂字形网页布局网站网站建设核心技术创新点

厂字形网页布局网站,网站建设核心技术创新点,网站内容建设ppt模板,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 二。问题表现 当启动项目服务后,服务无法注册到 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 启动状态 启动成功并且可以正常访问且不存在网络问题
  • 环境配置检查
<!-- 依赖检查 无误 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>

配置检查

#配置也正常
spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.cloud.sentinel.transport.port=8719
  • 第三步源码追踪

接下来开始漫长源码分析步骤

然后点击 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, won't send heartbeat"return 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.List<Endpoint> 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 List<Endpoint> getConsoleServerList() {String config = SentinelConfig.getConfig(CONSOLE_SERVER);List<Endpoint> list = new ArrayList<Endpoint>();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.Entry<Object, 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.server=localhost:8080 -Dcsp.sentinel.app.name=gateway-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

http://www.yayakq.cn/news/463543/

相关文章:

  • 招远网站建设招聘廊坊百度快照优化哪家服务好
  • 可以做分销的网站做网站的如何增加电话量
  • 网站文章结构变更怎么做301注册公司网上申请入口网站
  • 安徽建设工程安全监督网站企业官网建站的流程
  • 组培实验室建设网站广州免费网站建设
  • 做网站销售好吗免费追漫软件app
  • 网站设计的提案西安网站托管专业公司
  • 网站建设过程中要细心如何仿做网站
  • 茂名本土网站建设公司安阳网站推广
  • 淘宝客个人网站怎么做泰安住房和城乡建设厅网站
  • 公司网站服务商上海企业网站建设方案
  • 做公司网站的服务费入什么费用国外免费个人网站空间
  • 东阳网站建设yw81网站建设报告内容
  • 宁波网站建设公司优选亿企邦中企动力官网登陆
  • 黔西南网站建设wordpress首页不显示最新文章
  • seo 网站地图优化东莞南城网站建设公司怎么样
  • 免费的制作手机网站平台wordpress首页密码访问
  • 怎么做一个企业网站做网站需不需要购买服务器
  • 网站建设华企湖北天健建设集团有限公司网站
  • 如何验证网站所有权电商网站开发报告
  • 网站的面包屑怎么做的网站结构形式有哪些
  • 自己给网站做优化怎么做如何创建网站步骤
  • 最新的高端网站建设设计素材网站特点
  • 大连智能模板建站网站设计公司排名
  • 湖南佳程建设有限公司网站wordpress如何设置4个侧边栏
  • 做搜索的网站办公室装修效果图图片大全
  • 建网站一条龙国内最新重大新闻
  • 新会住房建设局网站浏览器地址栏怎么打开
  • 邯郸网站建设服务报价wordpress空页面模板
  • 佛山专业做网站公司旅游网站建设策划方案书