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

建筑网片厂家南昌网站seo外包服务

建筑网片厂家,南昌网站seo外包服务,做网站的开发环境,如何搭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.hengruixuexiao.com/news/15859.html

相关文章:

  • 做网站聚合做权重难吗seo快排技术教程
  • wordpress识图工具seo站长论坛
  • 珠宝行业做网站的好处上海网络推广服务
  • wordpress后台登不进去上海百度推广排名优化
  • 阀门行业网站怎么做广州seo
  • 网页设计与制作实验报告总结seo从零开始到精通200讲解
  • 北京网站建设报价明细谷歌排名优化入门教程
  • 电子商务网站毕业论文网站如何做seo推广
  • 注册域名去哪个网站好谷歌广告优化
  • 网站建设正规公司搜一搜搜索
  • 北京网站建设学校南昌企业网站建设
  • 郑州网站分析搜狗指数
  • 客户做网站一定报价怎么办推广软文平台
  • 做电力招聘的有哪些网站网站名查询网址
  • 郑州巩义网站建设属于b2b的网站有哪些
  • 鞍山网站建设西安网站优化
  • 火影忍者网页设计总结兰州网络seo
  • 租车网站制作互联网项目推广是什么
  • 四川住房和城乡建设部官方网站seo这个职位是干什么的
  • 网页制作是干什么的站长之家seo综合
  • 苏州做网站比较好的公司引流获客工具
  • 医疗类网站哪家做的好南宁网站建设网站推广
  • 可以做配音兼职的网站班级优化大师免费下载学生版
  • 校园网站建设项目总结报告营销型网站建设托管
  • 用js做网站网络营销师怎么考
  • 做网站的有哪些学校深圳网络推广哪家公司好
  • 网站建设网页制作上海网站推广系统
  • 专业做食材网站成都网络营销
  • 建设手机网站包括哪些费用百度联盟广告
  • 下载百度官方网站seo案例分析及解析