spring sharding JDBC 动态调整数据库连接
spring sharding JDBC 动态调整数据库连接
通过重写ShardingSphereDataSource类来实现
代码
package org.apache.shardingsphere.driver.jdbc.core.datasource;import com.alibaba.druid.pool.DruidDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.driver.jdbc.adapter.AbstractDataSourceAdapter;
import org.apache.shardingsphere.driver.jdbc.context.CachedDatabaseMetaData;
import org.apache.shardingsphere.driver.jdbc.context.JDBCContext;
import org.apache.shardingsphere.driver.state.DriverStateContext;
import org.apache.shardingsphere.infra.config.RuleConfiguration;
import org.apache.shardingsphere.infra.config.checker.RuleConfigurationCheckerFactory;
import org.apache.shardingsphere.infra.config.database.DatabaseConfiguration;
import org.apache.shardingsphere.infra.config.database.impl.DataSourceProvidedDatabaseConfiguration;
import org.apache.shardingsphere.infra.config.mode.ModeConfiguration;
import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
import org.apache.shardingsphere.infra.config.scope.GlobalRuleConfiguration;
import org.apache.shardingsphere.infra.datasource.props.DataSourceProperties;
import org.apache.shardingsphere.infra.datasource.props.DataSourcePropertiesCreator;
import org.apache.shardingsphere.infra.instance.definition.InstanceDefinition;
import org.apache.shardingsphere.infra.instance.definition.InstanceType;
import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
import org.apache.shardingsphere.infra.rule.builder.schema.DatabaseRulesBuilder;
import org.apache.shardingsphere.mode.manager.ContextManager;
import org.apache.shardingsphere.mode.manager.ContextManagerBuilderFactory;
import org.apache.shardingsphere.mode.manager.ContextManagerBuilderParameter;
import org.apache.shardingsphere.mode.metadata.persist.MetaDataPersistService;
import org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration;
import org.apache.shardingsphere.sharding.api.config.rule.ShardingTableRuleConfiguration;
import org.apache.shardingsphere.spring.boot.ShardingSphereAutoConfiguration;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;/*** @author qyc* @version 1.0*/
@Slf4j
public final class ShardingSphereDataSource extends AbstractDataSourceAdapter implements AutoCloseable {private final String databaseName;private final ContextManager contextManager;private final JDBCContext jdbcContext;private ContextManagerBuilderParameter contextManagerBuilderParameter;private ModeConfiguration modeConfiguration;private Collection<RuleConfiguration> ruleConfigs;private Properties properties;public ShardingSphereDataSource(final String databaseName, final ModeConfiguration modeConfig) throws SQLException {this.databaseName = databaseName;this.modeConfiguration = modeConfig;this.properties = new Properties();this.ruleConfigs = new LinkedList<>();contextManager = createContextManager(databaseName, modeConfig, new HashMap<>(), this.ruleConfigs, this.properties);jdbcContext = new JDBCContext(contextManager.getDataSourceMap(databaseName));}/*** {@link ShardingSphereAutoConfiguration#shardingSphereDataSource(org.springframework.beans.factory.ObjectProvider, org.springframework.beans.factory.ObjectProvider)}** @param databaseName* @param modeConfig* @param dataSourceMap* @param ruleConfigs* @param props* @throws SQLException*/public ShardingSphereDataSource(final String databaseName, final ModeConfiguration modeConfig, final Map<String, DataSource> dataSourceMap,final Collection<RuleConfiguration> ruleConfigs, final Properties props) throws SQLException {checkRuleConfiguration(databaseName, ruleConfigs);this.modeConfiguration = modeConfig;this.databaseName = databaseName;contextManager = createContextManager(databaseName, modeConfig, dataSourceMap, ruleConfigs, null == props ? new Properties() : props);this.ruleConfigs = ruleConfigs;this.properties = props;jdbcContext = new JDBCContext(contextManager.getDataSourceMap(databaseName));}/*** 更新现有的数据库配置** @param addDataSourcePropertiesMap 添加的配置* @param dropDataSourceNames 移除的配置* @param updateSources 修改的配置* @param newDataNodes 新的节点使用配置* @throws Exception */public void updateContextMetaData(final Map<String, DataSourceProperties> addDataSourcePropertiesMap, final Collection<String> dropDataSourceNames, Map<String, DataSourceProperties> updateSources, String newDataNodes) throws Exception {if (CollectionUtils.isEmpty(addDataSourcePropertiesMap) && CollectionUtils.isEmpty(dropDataSourceNames) && CollectionUtils.isEmpty(updateSources)) {if (!StringUtils.isEmpty(newDataNodes)) {this.rebuildShardingSphereRule(newDataNodes);}return;}Map<String, DataSourceProperties> refreshProperties = new HashMap<>();Map<String, DataSource> oldDataSources = new HashMap<>(this.contextManager.getDataSourceMap(databaseName));Map<String, DataSource> closeDataSources = new HashMap<>();if (!CollectionUtils.isEmpty(addDataSourcePropertiesMap)) {log.info("添加新的db:{}", addDataSourcePropertiesMap.keySet());this.contextManager.addResource(this.databaseName, addDataSourcePropertiesMap);refreshProperties.putAll(addDataSourcePropertiesMap);}if (!CollectionUtils.isEmpty(dropDataSourceNames)) {log.info("移除旧的db:{}", dropDataSourceNames);this.contextManager.dropResource(this.databaseName, dropDataSourceNames);dropDataSourceNames.forEach(s -> {closeDataSources.put(s, oldDataSources.get(s));});}if (!CollectionUtils.isEmpty(updateSources)) {log.info("更新db:{}", updateSources.keySet());this.contextManager.dropResource(this.databaseName, updateSources.keySet());this.contextManager.addResource(this.databaseName, updateSources);refreshProperties.putAll(updateSources);}log.info("重新加载shardingRule");this.rebuildShardingSphereRule(newDataNodes);log.info("重新构建managerBuildParameter");Map<String, DataSource> dataSourceMap = this.contextManager.getDataSourceMap(databaseName);this.contextManagerBuilderParameter = this.builderParameter(this.databaseName, this.modeConfiguration, dataSourceMap, this.ruleConfigs, this.properties);closeDataSources.forEach((k, closeDataSource) -> {try {log.info("关闭原dataSources:{}", k);if (closeDataSource instanceof DruidDataSource) {((DruidDataSource) closeDataSource).close();}} catch (Exception e) {log.warn("db:{}close时出现异常,异常为:{}", k, e.getMessage(), e);}});}private Map<String, DataSourceProperties> getDataSourcePropertiesMap(final Map<String, DataSource> dataSourceMap) {Map<String, DataSourceProperties> result = new LinkedHashMap<>(dataSourceMap.size(), 1);for (Map.Entry<String, DataSource> each : dataSourceMap.entrySet()) {result.put(each.getKey(), DataSourcePropertiesCreator.create(each.getValue()));}return result;}@SuppressWarnings("unchecked")private void checkRuleConfiguration(final String databaseName, final Collection<RuleConfiguration> ruleConfigs) {ruleConfigs.forEach(each -> RuleConfigurationCheckerFactory.findInstance(each).ifPresent(optional -> optional.check(databaseName, each)));}private ContextManager createContextManager(final String databaseName, final ModeConfiguration modeConfig, final Map<String, DataSource> dataSourceMap,final Collection<RuleConfiguration> ruleConfigs, final Properties props) throws SQLException {ContextManagerBuilderParameter parameter = this.builderParameter(databaseName, modeConfig, dataSourceMap, ruleConfigs, props);this.contextManagerBuilderParameter = parameter;return ContextManagerBuilderFactory.getInstance(modeConfig).build(parameter);}private ContextManagerBuilderParameter builderParameter(final String databaseName, final ModeConfiguration modeConfig, final Map<String, DataSource> dataSourceMap,final Collection<RuleConfiguration> ruleConfigs, final Properties props) {ContextManagerBuilderParameter parameter = ContextManagerBuilderParameter.builder().modeConfig(modeConfig).databaseConfigs(Collections.singletonMap(databaseName, new DataSourceProvidedDatabaseConfiguration(dataSourceMap, ruleConfigs))).globalRuleConfigs(ruleConfigs.stream().filter(each -> each instanceof GlobalRuleConfiguration).collect(Collectors.toList())).props(props).instanceDefinition(new InstanceDefinition(InstanceType.JDBC)).build();return parameter;}private Optional<CachedDatabaseMetaData> createCachedDatabaseMetaData(final Map<String, DataSource> dataSources) throws SQLException {if (dataSources.isEmpty()) {return Optional.empty();}try (Connection connection = dataSources.values().iterator().next().getConnection()) {return Optional.of(new CachedDatabaseMetaData(connection.getMetaData()));}}@Overridepublic Connection getConnection() throws SQLException {return DriverStateContext.getConnection(databaseName, contextManager, jdbcContext);}@Overridepublic Connection getConnection(final String username, final String password) throws SQLException {return getConnection();}/*** Close data sources.** @param dataSourceNames data source names to be closed* @throws Exception exception*/public void close(final Collection<String> dataSourceNames) throws Exception {Map<String, DataSource> dataSourceMap = contextManager.getDataSourceMap(databaseName);for (String each : dataSourceNames) {close(dataSourceMap.get(each));}contextManager.close();}private void close(final DataSource dataSource) throws Exception {if (dataSource instanceof AutoCloseable) {((AutoCloseable) dataSource).close();}}@Overridepublic void close() throws Exception {close(contextManager.getDataSourceMap(databaseName).keySet());}@Overridepublic int getLoginTimeout() throws SQLException {Map<String, DataSource> dataSourceMap = contextManager.getDataSourceMap(databaseName);return dataSourceMap.isEmpty() ? 0 : dataSourceMap.values().iterator().next().getLoginTimeout();}@Overridepublic void setLoginTimeout(final int seconds) throws SQLException {for (DataSource each : contextManager.getDataSourceMap(databaseName).values()) {each.setLoginTimeout(seconds);}}public Set<String> getDataBaseNames() {return this.contextManager.getDataSourceMap(databaseName).keySet();}private void rebuildShardingSphereRule(String newDataNodes) {if (StringUtils.isEmpty(newDataNodes)) {return;}log.info("重新加载db映射:{}", newDataNodes);MetaDataPersistService metaDataPersistService = this.contextManager.getMetaDataContexts().getPersistService().get();Map<String, DatabaseConfiguration> databaseConfigurationMap = getDatabaseConfigMap(Stream.of(this.databaseName).collect(Collectors.toList()), metaDataPersistService, this.contextManagerBuilderParameter);databaseConfigurationMap.get(this.databaseName).getRuleConfigurations().forEach(rule -> {if (rule instanceof ShardingRuleConfiguration) {Collection<ShardingTableRuleConfiguration> tables = ((ShardingRuleConfiguration) rule).getTables();List<ShardingTableRuleConfiguration> newShardingTableRuleConfigurations = tables.stream().map(table -> {String newActualDataNodes = newDataNodes + "." + table.getLogicTable();ShardingTableRuleConfiguration shardingTableRuleConfiguration = new ShardingTableRuleConfiguration(table.getLogicTable(), newActualDataNodes);shardingTableRuleConfiguration.setDatabaseShardingStrategy(table.getDatabaseShardingStrategy());shardingTableRuleConfiguration.setTableShardingStrategy(table.getTableShardingStrategy());shardingTableRuleConfiguration.setReplaceTablePrefix(table.getReplaceTablePrefix());shardingTableRuleConfiguration.setKeyGenerateStrategy(table.getKeyGenerateStrategy());return shardingTableRuleConfiguration;}).collect(Collectors.toList());((ShardingRuleConfiguration) rule).setTables(newShardingTableRuleConfigurations);}});ConfigurationProperties props = new ConfigurationProperties(metaDataPersistService.getPropsService().load());Collection<ShardingSphereRule> build = DatabaseRulesBuilder.build(databaseName, databaseConfigurationMap.get(this.databaseName), props);List<ShardingSphereRule> oldRules = (List<ShardingSphereRule>) this.contextManager.getMetaDataContexts().getMetaData().getDatabases().get(databaseName).getRuleMetaData().getRules();oldRules.clear();oldRules.addAll(build);}private Map<String, DatabaseConfiguration> getDatabaseConfigMap(final Collection<String> databaseNames, final MetaDataPersistService metaDataPersistService,final ContextManagerBuilderParameter parameter) {Map<String, DatabaseConfiguration> result = new HashMap<>(databaseNames.size(), 1);databaseNames.forEach(each -> result.put(each, createDatabaseConfiguration(each, metaDataPersistService, parameter)));return result;}private DatabaseConfiguration createDatabaseConfiguration(final String databaseName, final MetaDataPersistService metaDataPersistService,final ContextManagerBuilderParameter parameter) {Map<String, DataSource> dataSources = this.contextManager.getDataSourceMap(databaseName);Collection<RuleConfiguration> databaseRuleConfigs = metaDataPersistService.getDatabaseRulePersistService().load(databaseName);return new DataSourceProvidedDatabaseConfiguration(dataSources, databaseRuleConfigs);}
}
通过调用重写的DataSource的updateContextMetaData方法来重新加载连接配置
* @param addDataSourcePropertiesMap 添加的配置* @param dropDataSourceNames 移除的配置 * @param updateSources 修改的配置* @param newDataNodes 新的节点使用配置
spring:shardingsphere:datasource:names: ${SHARDING_DATA_SOURCE_NAMES:db-0,db-1}db-0:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.jdbc.Driverurl: jdbc:mysql://${mysql.message0.host}/${mysql.message0.database}?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=falseusername: ${mysql.message0.username}password: ${mysql.message0.password}initialSize: 5 # 初始化大小minIdle: 5 # 最小maxActive: 20 # 最大maxWait: 60000 # 获取连接等待超时的时间...db-1:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.jdbc.Driver...
参数说明
参数名 | 说明 |
---|---|
addDataSourcePropertiesMap | 添加的db连接,key->连接id,例如配置中的db-0,db-1,value->根据普通db连接配置构建成的DataSourceProperties |
dropDataSourceNames | 移除的db连接,key->连接id,例如配置中的db-0,db-1 |
updateSources | 修改的db连接,key->连接id,例如配置中的db-0,db-1,value->根据普通db连接配置构建成的DataSourceProperties |
newDataNodes | 新的节点使用配置,将配置项中使用的的spring.shardingsphere.datasource.names值更换为该值 |
DataSourceProperties构建类
getDataSource(),传入的值为普通的db连接配置,例如
type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.jdbc.Driverurl: jdbc:mysql://db3Ip/db3DB?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=falseusername: db3Userpassword: db3PwdinitialSize: 5 # 初始化大小minIdle: 5 # 最小maxActive: 20 # 最大maxWait: 60000 # 获取连接等待超时的时间timeBetweenEvictionRunsMillis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒(3600000:为1小时)minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最小生存的时间,单位是毫秒validationQuery: select current_timestamp() #SELECT 1 FROM DUAL #用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。testWhileIdle: true #申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。建议配置为true,不影响性能,并且保证安全性。testOnBorrow: false #申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。缺省值:truetestOnReturn: false #归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。缺省值:falsepoolPreparedStatements: true #打开PSCache,并且指定每个连接上PSCache的大小#是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql5.5以下的版本中没有PSCache功能,建议关闭掉。5.5及以上版本有PSCache,建议开启。缺省值:falsemaxPoolPreparedStatementPerConnectionSize: 20 # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100。
package com.kittlen.provider.config.sharding;import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import org.apache.shardingsphere.infra.datasource.pool.creator.DataSourcePoolCreator;
import org.apache.shardingsphere.infra.datasource.props.DataSourceProperties;
import org.apache.shardingsphere.infra.datasource.props.DataSourcePropertiesCreator;
import org.apache.shardingsphere.infra.exception.ShardingSphereException;
import org.apache.shardingsphere.infra.expr.InlineExpressionParser;
import org.apache.shardingsphere.spring.boot.datasource.AopProxyUtils;
import org.apache.shardingsphere.spring.boot.util.PropertyUtil;
import org.springframework.core.env.Environment;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.jndi.JndiObjectFactoryBean;
import org.springframework.stereotype.Component;import javax.naming.NamingException;
import javax.sql.DataSource;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;/*** @author kittlen* @version 1.0*/
public class MyShardingDataSource {private static final String PREFIX = "spring.shardingsphere.datasource.";private static final String DATA_SOURCE_NAME = "name";private static final String DATA_SOURCE_NAMES = "names";private static final String DATA_SOURCE_TYPE = "type";private static final String JNDI_NAME = "jndi-name";/*** Get data source map.** @param environment spring boot environment* @return data source map*/public static Map<String, DataSource> getDataSourceMap(final Environment environment) {Map<String, DataSource> result = new LinkedHashMap<>();for (String each : getDataSourceNames(environment)) {try {result.put(each, getDataSource(environment, each));} catch (final NamingException ex) {throw new ShardingSphereException("Can't find JNDI data source.", ex);}}return result;}/*** Get data source map.** @param environment spring boot environment* @return data source map*/public static Map<String, DataSourceProperties> getDataSourcePropertiesMap(final Environment environment) {Map<String, DataSourceProperties> result = new LinkedHashMap<>();for (String each : getDataSourceNames(environment)) {try {result.put(each, getDataSourceProperties(environment, each));} catch (final NamingException ex) {throw new ShardingSphereException("Can't find JNDI data source.", ex);}}return result;}private static List<String> getDataSourceNames(final Environment environment) {StandardEnvironment standardEnv = (StandardEnvironment) environment;standardEnv.setIgnoreUnresolvableNestedPlaceholders(true);String dataSourceNames = standardEnv.getProperty(PREFIX + DATA_SOURCE_NAME);if (Strings.isNullOrEmpty(dataSourceNames)) {dataSourceNames = standardEnv.getProperty(PREFIX + DATA_SOURCE_NAMES);}return new InlineExpressionParser(dataSourceNames).splitAndEvaluate();}private static DataSource getDataSource(final Environment environment, final String dataSourceName) throws NamingException {Map<String, Object> dataSourceProps = PropertyUtil.handle(environment, String.join("", PREFIX, dataSourceName), Map.class);Preconditions.checkState(!dataSourceProps.isEmpty(), "Wrong datasource [%s] properties.", dataSourceName);if (dataSourceProps.containsKey(JNDI_NAME)) {return getJNDIDataSource(dataSourceProps.get(JNDI_NAME).toString());}return DataSourcePoolCreator.create(new DataSourceProperties(dataSourceProps.get(DATA_SOURCE_TYPE).toString(), PropertyUtil.getCamelCaseKeys(dataSourceProps)));}private static DataSourceProperties getDataSourceProperties(final Environment environment, final String dataSourceName) throws NamingException {Map<String, Object> dataSourceProps = PropertyUtil.handle(environment, String.join("", PREFIX, dataSourceName), Map.class);Preconditions.checkState(!dataSourceProps.isEmpty(), "Wrong datasource [%s] properties.", dataSourceName);if (dataSourceProps.containsKey(JNDI_NAME)) {return DataSourcePropertiesCreator.create(getJNDIDataSource(dataSourceProps.get(JNDI_NAME).toString()));}return new DataSourceProperties(dataSourceProps.get(DATA_SOURCE_TYPE).toString(), PropertyUtil.getCamelCaseKeys(dataSourceProps));}public static DataSourceProperties getDataSourceProperties(Map<String, Object> dataSourceProps) throws NamingException {if (dataSourceProps.containsKey(JNDI_NAME)) {return DataSourcePropertiesCreator.create(getJNDIDataSource(dataSourceProps.get(JNDI_NAME).toString()));}return new DataSourceProperties(dataSourceProps.get(DATA_SOURCE_TYPE).toString(), PropertyUtil.getCamelCaseKeys(dataSourceProps));}public static DataSource getDataSource(Map<String, Object> dataSourceProps) throws NamingException {if (dataSourceProps.containsKey(JNDI_NAME)) {return getJNDIDataSource(dataSourceProps.get(JNDI_NAME).toString());}return DataSourcePoolCreator.create(new DataSourceProperties(dataSourceProps.get(DATA_SOURCE_TYPE).toString(), PropertyUtil.getCamelCaseKeys(dataSourceProps)));}private static DataSource getJNDIDataSource(final String jndiName) throws NamingException {JndiObjectFactoryBean bean = new JndiObjectFactoryBean();bean.setResourceRef(true);bean.setJndiName(jndiName);bean.setProxyInterface(DataSource.class);bean.afterPropertiesSet();return (DataSource) AopProxyUtils.getTarget(bean.getObject());}
}
相关文章:
spring sharding JDBC 动态调整数据库连接
spring sharding JDBC 动态调整数据库连接 通过重写ShardingSphereDataSource类来实现 代码 package org.apache.shardingsphere.driver.jdbc.core.datasource;import com.alibaba.druid.pool.DruidDataSource; import lombok.extern.slf4j.Slf4j; import org.apache.shardi…...

解决CondaHTTPError HTTP 000 CONNECTION FAILED for url解决方法
解决CondaHTTPError: HTTP 000 CONNECTION FAILED for url解决方法 问题:使用conda install命令安装包提示CondaHTTPError: HTTP 000 CONNECTION FAILED for url 分析:网络连接问题,大概率是网速不行或者源没有换 解决方案:修改国…...

10 创建型模式-原型模式
引言: 创建对象的五种方式: 通过new关键字通过Class类的newInstance()方法通过Constructor类的newInstance()方法利用Clone方法反序列化 Clone方法: 其实现方式正是通过调用 Object 类的 clone() 方法来完成。 protected native Object cl…...

MSQL系列(七) Mysql实战-SQL语句Join,exists,in的区别
Mysql实战-SQL语句Join,exists,in的区别 前面我们讲解了索引的存储结构,BTree的索引结构,以及索引最左侧匹配原则及讲解一下常用的SQL语句的优化建议,今天我们来详细讲解一下 我们经常使用的 join, exist&…...

最新壁纸自动采集系统网站PHP源码/360壁纸官方数据接口采集/ZHEYI采集源码
源码介绍: 最新壁纸自动采集系统网站PHP源码,它是ZHEYI自动采集源码,能够在360壁纸官方数据接口采集。很好用的壁纸网站源码分享,仅供学习,请勿商用。 ZHEYI自动采集壁纸PHP源码,能全自动采集高清壁纸网源…...

Redis在分布式场景下的应用
分布式缓存 缓存的基本作用是在高并发场景下对应服务的保护缓冲 – 基于Redis集群解决单机Redis存在的问题 单机的Redis存在四大问题: redis由于高强度性能采用内存 但是意味着丢失的风险单结点redis并发能力有限分布式服务中数据过多 依赖内存的redis 明显单机不…...

2316. 统计无向图中无法互相到达点对数
2316. 统计无向图中无法互相到达点对数 难度: 中等 来源: 每日一题 2023.10.21 给你一个整数 n ,表示一张 无向图 中有 n 个节点,编号为 0 到 n - 1 。同时给你一个二维整数数组 edges ,其中 edges[i] [ai, bi] 表示节点 ai 和 bi 之间…...
Selenium定向爬取海量精美图片及搜索引擎杂谈
我自认为这是自己写过博客中一篇比较优秀的文章,同时也是在深夜凌晨2点满怀着激情和愉悦之心完成的。首先通过这篇文章,你能学到以下几点: 1.可以了解Python简单爬取图片的一些思路和方法 2.学习Selenium自动、测试分析动态网页和正则表达式的区别和共同点 …...

面试题—JAVA基础①
文章目录 1.Java面向对象有哪些特征?2.ArrayList和LinkedList有什么区别?3.Java接口和抽象类有哪些区别?4.hashcode和equals如何使用?5.try-catch6.局部变量和实例变量7.String、StringBuffer、StringBuilder 的区别?8…...
naive-ui的n-data-table标签奇特bug记录
具体参考之前的博文:vueday02——使用naive-ui做一个ACM看榜-CSDN博客 具体代码在这里面 原因:在本地运行的时候,datatable里面使用列表渲染成字符串前端设置样式进行转换,但是在正式部署的时候,这个组件没有将其自动…...

微信小程序OA会议系统个人中心授权登入
在我们的完成微信登入授权之前,首先我们要完成我们前面所写的代码,如果有不会的大家可以去看以下我发的前面几个文章链接我发下面了,各位加油! 微信小程序OA会议系统数据交互-CSDN博客 微信小程序会议OA系统其他页面-CSDN博客 …...

Git(一)Windows下安装及使用Git Bash
目录 一、简介1.1 什么是Git?1.2 Git 的主要特点1.3 什么是 Git Bash? 二、下载三、安装3.1 同意协议3.2 选择安装位置3.3 其他配置(【Next】 即可)3.4 安装完毕3.5 打开 Git Bash 官网地址: https://www.git-scm.com/…...

[AUTOSAR][诊断管理][ECU][$19] 读取ECU的DTC故障信息
一、简介 在车载诊断中常用的诊断协议有ISO 14229等,在协议中主要定义了诊断请求、诊断响应的报文格式及ECU该如何处理诊断请求的应用。其中ISO 14229系列标准协议定义了用于行业内诊断通信的需求规范,也就是UDS。UDS主要应用于OSI七层模型的第七层——…...
前端精度问题 (id 返回的和传给后端的不一致问题)
eg: 后端返回 id 10976458979374929 前端获取到的: 10976458979374928 原因: js 中 Number类型范围-2^53 1 到 2^53 - 1 Number.isSafeInteger()用来判断一个整数是否落在这个范围之内。 java中 Long 类型的取值范围是-2^63 1 到 2^63 - 1, 比JavaScript中大很多࿰…...

WPF Material Design UI框架
前言 Material Design in xaml 是开源免费的ui框架,工控软件主打的就是简单界面。 以下简称MD 相关资源 MaterialDesignInXamlToolkit Github 地址 MD 快速启动 MD 案例压缩包 MD 框架使用 启动环境配置 安装Nuget包 App.xaml 配置 <Application x:Class&qu…...

C语言求 3*3 矩阵对角线之和
完整代码: // 求 3*3 矩阵对角线之和 #include<stdio.h>int main() {int n3;int arr[3][3];// 输入矩阵printf("请输入矩阵的元素:\n");for (int i 0; i < n; i){for (int j 0; j < n; j){scanf("%d", &arr[i][j]);}}int su…...

缓存分片中的哈希算法与一致性哈希算法
什么是缓存分片 在高并发场景下,缓存往往成为了瓶颈。这时候,我们可以通过缓存数据分片的方式来解决问题。所谓缓存数据分片,就是将缓存数据按照一定的规则分成多个片段,每个片段由不同的缓存节点负责。这样做有两个好处…...

线框图软件:Balsamiq Wireframes mac中文介绍
Balsamiq Wireframes mac是一款用于创建线框图的软件工具。它旨在帮助用户快速制作出清晰、简洁的界面原型,以便在设计和开发过程中进行协作和沟通。 Balsamiq Wireframes具有简单直观的用户界面,使用户能够快速添加和编辑各种用户界面元素,如…...

【wxWidgets实现透明wxPanel_核心实现_原创思想】
描述 wxWidgets 根本就没有实现过透明wxPanel容器,你设置wxTRANSPARENT_WINDOW,结果sorry 黑色,哈哈哈哈, 就是和你作对.想想当下那么漂亮的桌面, 背景, 透明, 特效.哎 悲哀啊,实现不了,就那死板的界面特性. 网上找了好久,也是乱七八糟,改底层代码还是算了吧,升级特要命.都是只…...

重大技术问题,iPhone 15 Pro Max面临“烧屏门”风波 | 百能云芯
近期,社交媒体平台上陆续涌现大量用户和数码博主就iPhone 15 Pro Max出现烧屏问题的投诉与评论。 烧屏问题是OLED屏幕常见的一个缺陷,这是由OLED屏幕发光机制引发的,OLED屏幕可视为由无数微小的灯泡-像素点构成,这些像素点可以独立…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...