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

《微服务实战》 第三十一章 ShardingSphere - ShardingSphere-JDBC

前言

Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。

Apache ShardingSphere 设计哲学为 Database Plus,旨在构建异构数据库上层的标准和生态。 它关注如何充分合理地利用数据库的计算和存储能力,而并非实现一个全新的数据库。 它站在数据库的上层视角,关注它们之间的协作多于数据库自身。

1、ShardingSphere-JDBC

ShardingSphere-JDBC 定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。

1.1、应用场景

Apache ShardingSphere-JDBC 可以通过Java 和 YAML 这 2 种方式进行配置,开发者可根据场景选择适合的配置方式。

  • 数据库读写分离
  • 数据库分表分库

1.2、原理

  • Sharding-JDBC中的路由结果是通过分片字段和分片方法来确定的,如果查询条件中有 id 字段的情况还好,查询将会落到某个具体的分片
  • 如果查询没有分片的字段,会向所有的db或者是表都会查询一遍,让后封装结果集给客户端。
    在这里插入图片描述

1.3、spring boot整合

1.3.1、添加依赖

<!-- 分表分库依赖 -->
<dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.1</version>
</dependency>

1.3.2、添加配置

spring:main:# 一个实体类对应多张表,覆盖allow-bean-definition-overriding: trueshardingsphere:datasource:ds0:#配置数据源具体内容,包含连接池,驱动,地址,用户名和密码driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://127.0.0.1:3306/account?autoReconnect=true&allowMultiQueries=truepassword: roottype: com.zaxxer.hikari.HikariDataSourceusername: rootds1:driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://127.0.0.1:3306/account?autoReconnect=true&allowMultiQueries=truepassword: roottype: com.zaxxer.hikari.HikariDataSourceusername: root# 配置数据源,给数据源起名称names: ds0,ds1props:sql:show: truesharding:tables:user_info:#指定 user_info 表分布情况,配置表在哪个数据库里面,表名称都是什么actual-data-nodes: ds0.user_info_${0..9}database-strategy:standard:preciseAlgorithmClassName: com.xxxx.store.account.config.PreciseDBShardingAlgorithmrangeAlgorithmClassName: com.xxxx.store.account.config.RangeDBShardingAlgorithmsharding-column: idtable-strategy:standard:preciseAlgorithmClassName: com.xxxx.store.account.config.PreciseTablesShardingAlgorithmrangeAlgorithmClassName: com.xxxx.store.account.config.RangeTablesShardingAlgorithmsharding-column: id

1.3.3、制定分片算法

1.3.3.1、精确分库算法

/*** 精确分库算法*/
public class PreciseDBShardingAlgorithm implements PreciseShardingAlgorithm<Long> {/**** @param availableTargetNames 配置所有的列表* @param preciseShardingValue 分片值* @return*/@Overridepublic String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> preciseShardingValue) {Long value = preciseShardingValue.getValue();//后缀 0,1String postfix = String.valueOf(value % 2);for (String availableTargetName : availableTargetNames) {if(availableTargetName.endsWith(postfix)){return availableTargetName;}}throw new UnsupportedOperationException();}}

1.3.3.2、范围分库算法

/*** 范围分库算法*/
public class RangeDBShardingAlgorithm implements RangeShardingAlgorithm<Long> {@Overridepublic Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Long> rangeShardingValue) {return collection;}
}

1.3.3.3、精确分表算法

/*** 精确分表算法*/
public class PreciseTablesShardingAlgorithm implements PreciseShardingAlgorithm<Long> {/**** @param availableTargetNames 配置所有的列表* @param preciseShardingValue 分片值* @return*/@Overridepublic String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> preciseShardingValue) {Long value = preciseShardingValue.getValue();//后缀String postfix = String.valueOf(value % 10);for (String availableTargetName : availableTargetNames) {if(availableTargetName.endsWith(postfix)){return availableTargetName;}}throw new UnsupportedOperationException();}}

1.3.3.4、范围分表算法

/*** 范围分表算法*/
public class RangeTablesShardingAlgorithm implements RangeShardingAlgorithm<Long> {@Overridepublic Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Long> rangeShardingValue) {Collection<String> result = new ArrayList<>();Range<Long> valueRange = rangeShardingValue.getValueRange();Long start = valueRange.lowerEndpoint();Long end = valueRange.upperEndpoint();Long min = start % 10;Long max = end % 10;for (Long i = min; i < max +1; i++) {Long finalI = i;collection.forEach(e -> {if(e.endsWith(String.valueOf(finalI))){result.add(e);}});}return result;}}

1.3.4、数据库建表

DROP TABLE IF EXISTS `user_info_0`;
CREATE TABLE `user_info_0` (`id` bigint(20) NOT NULL,`account` varchar(255) DEFAULT NULL,`user_name` varchar(255) DEFAULT NULL,`pwd` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

1.3.5、业务应用

1.3.5.1、定义实体类

@Data
@TableName(value = "user_info")
public class UserInfo {/*** 主键*/private Long id;/*** 账号*/private String account;/*** 用户名*/private String userName;/*** 密码*/private String pwd;}

1.3.5.2、定义接口

public interface UserInfoService{/*** 保存* @param userInfo* @return*/public UserInfo saveUserInfo(UserInfo userInfo);public UserInfo getUserInfoById(Long id);public List<UserInfo> listUserInfo();
}

1.3.5.3、实现类

@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {@Override@Transactionalpublic UserInfo saveUserInfo(UserInfo userInfo) {userInfo.setId(IdUtils.getId());this.save(userInfo);return userInfo;}@Overridepublic UserInfo getUserInfoById(Long id) {return this.getById(id);}@Overridepublic List<UserInfo> listUserInfo() {QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<>();userInfoQueryWrapper.between("id",1623695688380448768L,1623695688380448769L);return this.list(userInfoQueryWrapper);}
}

1.3.6、生成ID - 雪花算法

package com.xxxx.tore.common.utils;import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;/*** 生成各种组件ID*/
public class IdUtils {/*** 雪花算法* @return*/public static long getId(){Snowflake snowflake = IdUtil.getSnowflake(0, 0);long id = snowflake.nextId();return id;}
}

1.4、seata与sharding-jdbc整合

https://github.com/seata/seata-samples/tree/master/springcloud-seata-sharding-jdbc-mybatis-plus-samples

1.4.1、common中添加依赖

<!--seata依赖-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId><version>2021.0.4.0</version>
</dependency>
<!-- sharding-jdbc整合seata分布式事务-->
<dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-transaction-base-seata-at</artifactId><version>4.1.1</version>
</dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>2021.0.4.0</version><exclusions><exclusion><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId><version>1.4.2</version>
</dependency>

1.4.2、改造account-service服务

@Service
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> implements AccountService {@Autowiredprivate OrderService orderService;@Autowiredprivate StorageService storageService;/*** 存放商品编码及其对应的价钱*/private static Map<String,Integer> map = new HashMap<>();static {map.put("c001",3);map.put("c002",5);map.put("c003",10);map.put("c004",6);}@Override@Transactional@ShardingTransactionType(TransactionType.BASE)public void debit(OrderDTO orderDTO) {//扣减账户余额int calculate = this.calculate(orderDTO.getCommodityCode(), orderDTO.getCount());AccountDTO accountDTO = new AccountDTO(orderDTO.getUserId(), calculate);QueryWrapper<Account> objectQueryWrapper = new QueryWrapper<>();objectQueryWrapper.eq("id",1);objectQueryWrapper.eq(accountDTO.getUserId() != null,"user_id",accountDTO.getUserId());Account account = this.getOne(objectQueryWrapper);account.setMoney(account.getMoney() - accountDTO.getMoney());this.saveOrUpdate(account);//扣减库存this.storageService.deduct(new StorageDTO(null,orderDTO.getCommodityCode(),orderDTO.getCount()));//生成订单this.orderService.create(orderDTO);      }/*** 计算购买商品的总价钱* @param commodityCode* @param orderCount* @return*/private int calculate(String commodityCode, int orderCount){//商品价钱Integer price = map.get(commodityCode) == null ? 0 : map.get(commodityCode);return price * orderCount;}
}

注意:调单生成调用的逻辑修改,减余额->减库存->生成订单。调用入口方法注解加上:@ShardingTransactionType(TransactionType.BASE)

1.4.3、修改business-service服务

@Service
public class BusinessServiceImpl implements BusinessService {@Autowiredprivate OrderService orderService;@Autowiredprivate StorageService storageService;@Autowiredprivate AccountService accountService;@Overridepublic void purchase(OrderDTO orderDTO) {//扣减账号中的钱accountService.debit(orderDTO);        }
}

1.4.4、修改order-service服务

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper,Order> implements OrderService {/*** 存放商品编码及其对应的价钱*/private static Map<String,Integer> map = new HashMap<>();static {map.put("c001",3);map.put("c002",5);map.put("c003",10);map.put("c004",6);}@Override@Transactional@ShardingTransactionType(TransactionType.BASE)public Order create(String userId, String commodityCode, int orderCount) {int orderMoney = calculate(commodityCode, orderCount);Order order = new Order();order.setUserId(userId);order.setCommodityCode(commodityCode);order.setCount(orderCount);order.setMoney(orderMoney);//保存订单this.save(order);try {TimeUnit.SECONDS.sleep(30);} catch (InterruptedException e) {e.printStackTrace();}if(true){throw new RuntimeException("回滚测试");}return order;}/*** 计算购买商品的总价钱* @param commodityCode* @param orderCount* @return*/private int calculate(String commodityCode, int orderCount){//商品价钱Integer price = map.get(commodityCode) == null ? 0 : map.get(commodityCode);return price * orderCount;}
}

1.4.5、配置文件参考

server:port: 8090spring:main:# 一个实体类对应多张表,覆盖allow-bean-definition-overriding: trueshardingsphere:datasource:ds0:#配置数据源具体内容,包含连接池,驱动,地址,用户名和密码driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://127.0.0.1:3306/account?autoReconnect=true&allowMultiQueries=truepassword: roottype: com.zaxxer.hikari.HikariDataSourceusername: rootds1:driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://127.0.0.1:3306/account?autoReconnect=true&allowMultiQueries=truepassword: roottype: com.zaxxer.hikari.HikariDataSourceusername: root# 配置数据源,给数据源起名称names: ds0,ds1props:sql:show: truesharding:tables:account_tbl:actual-data-nodes: ds0.account_tbl_${0..1}database-strategy:standard:preciseAlgorithmClassName: com.xxxx.store.account.config.PreciseDBExtShardingAlgorithm#rangeAlgorithmClassName: com.xxxx.store.account.config.RangeDBShardingAlgorithmsharding-column: idtable-strategy:standard:preciseAlgorithmClassName: com.xxxx.store.account.config.PreciseTablesExtShardingAlgorithm#rangeAlgorithmClassName: com.xxxx.store.account.config.RangeTablesShardingAlgorithmsharding-column: iduser_info:#指定 user_info 表分布情况,配置表在哪个数据库里面,表名称都是什么actual-data-nodes: ds0.user_info_${0..9}database-strategy:standard:preciseAlgorithmClassName: com.xxxx.store.account.config.PreciseDBShardingAlgorithmrangeAlgorithmClassName: com.xxxx.store.account.config.RangeDBShardingAlgorithmsharding-column: idtable-strategy:standard:preciseAlgorithmClassName: com.xxxx.store.account.config.PreciseTablesShardingAlgorithmrangeAlgorithmClassName: com.xxxx.store.account.config.RangeTablesShardingAlgorithmsharding-column: id#以上是sharding-jdbc配置cloud:nacos:discovery:server-addr: localhost:8848namespace: 1ff3782d-b62d-402f-8bc4-ebcf40254d0aapplication:name: account-service  #微服务名称
#  datasource:
#    username: root
#    password: root
#    url: jdbc:mysql://127.0.0.1:3306/account
#    driver-class-name: com.mysql.cj.jdbc.Driverseata:enabled: trueenable-auto-data-source-proxy: falseapplication-id: account-servicetx-service-group: default_tx_groupservice:vgroup-mapping:default_tx_group: defaultdisable-global-transaction: falseregistry:type: nacosnacos:application: seata-serverserver-addr: 127.0.0.1:8848namespace: 1ff3782d-b62d-402f-8bc4-ebcf40254d0agroup: SEATA_GROUPusername: nacospassword: nacosconfig:nacos:server-addr: 127.0.0.1:8848namespace: 1ff3782d-b62d-402f-8bc4-ebcf40254d0agroup: SEATA_GROUPusername: nacospassword: nacos

相关文章:

《微服务实战》 第三十一章 ShardingSphere - ShardingSphere-JDBC

前言 Apache ShardingSphere 是一款分布式的数据库生态系统&#xff0c; 可以将任意数据库转换为分布式数据库&#xff0c;并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。 Apache ShardingSphere 设计哲学为 Database Plus&#xff0c;旨在构建异构数据库上层的…...

【论文阅读】Twin neural network regression is a semi- supervised regression algorithm

论文下载 GitHub bib: ARTICLE{,title {Twin neural network regression is a semi- supervised regression algorithm},author {Sebastian J Wetzel and Roger G Melko and Isaac Tamblyn},journal {Machine Learning: Science and Technology},year {2022},volum…...

java之反射机制和注解(更新中......)

Reflect在文档中的位置&#xff1a; 文档链接&#xff1a;https://docs.oracle.com/javase/8/docs/api/index.html 用于获取类或对象的反射信息。 常用的反射机制重要的类&#xff1a; java.lang.Class&#xff1a;整个字节码&#xff0c;代表一个类型。包含了以下三块内容&a…...

【Unity入门】25.入门结课Demo--神鸟大战怪兽

【Unity入门】入门结课Demo--神鸟大战怪兽 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity入门系列博客&#xff0c;所学知识来自B站阿发老师~感谢 (一) 前言 经过了两个月的学习&#xff0c;我们也顺利的完成了入门课程&#xff0c;最后就用一个Demo作为我们的结课句号吧&am…...

HTTP协议基本格式

HTTP即HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09;&#xff0c;HTTP基于TCP/IP协议传输数据。 目录 Chrome抓包Fiddler代理抓包HTTP协议格式HTTP请求首行URL方法Get方法Post方法Get与Post的区别 请求报头中的属性Cookie和SessionCookie与Session的区别…...

在 ubuntu 22.04 上配置界面服务器 xrdp

文章目录 图形界面解决方案VNCXRDP XRDP 实例安装和配置使用 XRDP 使用原理谁更快 : X11转发 > XRDP > VNC 图形界面解决方案 1. VNC 2. XRDP 3. X11 ssh : // https://blog.csdn.net/u011011827/article/details/131065690VNC 外部开放端口 用的 是 5901-5910 桌面用…...

53、基于51单片机蓄电池充电器过充过放保护LCD液晶屏显示系统设计(程序+原理图+PCB源文件+参考论文+参考PPT+元器件清单等)

方案选择 单片机的选择 方案一&#xff1a;AT89C52是美国ATMEL公司生产的低电压&#xff0c;高性能CMOS型8位单片机&#xff0c;器件采用ATMEL公司的高密度、非易失性存储技术生产&#xff0c;兼容标准MCS-51指令系统&#xff0c;片内置通用8位中央处理器(CPU)和Flash存储单元&…...

【C/C++】详解 函数重载和应用

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…...

WPF开发txt阅读器4:字体控件绑定

文章目录 控件折叠字体尺寸绑定选择字体字体的中文名称 txt阅读器系列&#xff1a; 需求分析和文件读写目录提取类&#x1f48e;列表控件与目录 控件折叠 作为一个txt阅读器&#xff0c;至少能够设置文字字体、尺寸&#xff0c;段落行间距等&#xff0c;还得有护眼模式等一系…...

CoreDX DDS应用开发指南(8)开发订阅应用程序

11 应用数据类型Application Data Types 11.1 概述 每个DDS主题都包含一个且仅包含一个数据类型,这是在主题上进行通信时使用的用户定义的数据类型。在大多数情况下,应用程序开发人员以数据定义语言(DDL)格式定义这些DDS数据类型。编译器用于将这些DDL类型定义转换为适当的…...

基于Python的接口自动化-读写配置文件

目录 引言 configparser模块功能介绍 引言 在编写接口自动化测试脚本时&#xff0c;有时我们需要在代码中定义变量并给变量固定的赋值。为了统一管理和操作这些固定的变量&#xff0c;咱们一般会将这些固定的变量以一定规则配置到指定的配置文件中&#xff0c;后续需要用到这…...

useEffect的基础知识和底层机制

useEffect 是 React 中一个重要的 Hook&#xff0c;用来处理组件的副作用操作。它的基础知识包括两个方面&#xff1a;执行时机和参数。 执行时机&#xff1a; useEff ect 的执行时机包括两种情况&#xff1a; 组件挂载时&#xff0c;即第一次渲染之后。组件更新时&#xff…...

chatgpt赋能python:Python中如何加空格

Python中如何加空格 Python是一门广泛应用于科学计算、数据分析、人工智能、Web开发等领域的高级编程语言。在Python编程过程中&#xff0c;经常需要使用到空格&#xff0c;以实现程序的格式化和美观&#xff0c;同时也有助于提高代码的可读性和可维护性。本文主要介绍Python中…...

软件测试之路已不再是坦途

去年下半年才跳了槽&#xff0c;过程非常顺利&#xff0c;没有经历大家所说的工作荒的境地&#xff0c;所以一直没有直观地感受到软件测试就业形势到底有多严峻。 近来看到一些机构频频发出某某测试员在糟糕的就业形势下逆袭拿下XXW的某厂offer&#xff0c;然后推荐测试进阶课…...

扫雷——C语言实现

扫雷 文章目录 扫雷实现代码什么是扫雷基本功能实现显示选择菜单定义几个二维数组&#xff1f;确定数组大小初始化数组布置地雷打印展示数组排查地雷记录指定区域周围地雷的个数判断排雷成功排查地雷实现代码 基本功能的实现代码和效果展示 拓展功能简化游戏界面改变字体颜色实…...

CSS基础学习--6 CSS Text(文本)

一、文本颜色 color:red; 颜色属性被用来设置文字的颜色。 颜色是通过CSS最经常的指定&#xff1a; 十六进制值 - 如: &#xff03;FF0000一个RGB值 - 如: RGB(255,0,0)颜色的名称 - 如: red body {color:red;} h1 {color:#00ff00;} h2 {color:rgb(255,0,0);} 二、文本的…...

高精度电压源的应用场合有哪些

高精度电压源是一种能够提供恒定、稳定电压输出的设备&#xff0c;被广泛应用于各种领域。高精度电压源是现代电力、通信、控制等领域中重要的测试仪器之一&#xff0c;其主要功能是提供稳定可靠的直流或交流电源&#xff0c;并具有高精度和高分辨率的特点。在实际应用中&#…...

Android约束布局

一、嵌套布局效率可能很低。 在 Android 开发中,我们常常需要使用嵌套布局来实现某些较复杂的界面效果。但是嵌套层级太深会带来一些问题,主要包括: 视图层级过深,导致内存占用过高和性能下降。Android 需要为每个 View 对象分配内存,嵌套层级过深会创建很多 View 对象,占用较…...

selenium基础语法

文章目录 selenium基础语法1.定位页面元素2.元素的操作1) 模拟键盘输入(send_keys)2) 点击操作(click)3) 清除去对象输入的文本内容(clear)4) 获取文本(gettext) 3. 等待4. 信息打印5. 窗口6. 导航7. 弹窗8. 鼠标和弹窗9.选择框10.文件上传11.屏幕截图 selenium基础语法 1.定位…...

运行后端SpringBoot项目

目录 一、注册微信开发者账号 1. 注册开发者账号 2. 获取appid和密钥 二、开通腾讯云TRTC服务 1. TRTC业务介绍 2. 为什么不使用阿里云的实时音视频服务&#xff0c;偏要选用腾讯云TRTC服务&#xff1f; 3. 开通TRTC服务 4. 领取TRTC的AppID和密钥 三、导入 emos-api …...

终极指南:如何用3步清理Windows右键菜单,让电脑操作效率翻倍

终极指南&#xff1a;如何用3步清理Windows右键菜单&#xff0c;让电脑操作效率翻倍 【免费下载链接】ContextMenuManager &#x1f5b1;️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager 你是否曾被Windows右键菜单的…...

repo2txt:Git仓库转纯文本工具,为AI分析、代码归档与审查提供完整上下文

1. 项目概述&#xff1a;从代码仓库到纯文本的自动化提取最近在整理个人技术笔记和项目文档时&#xff0c;我遇到了一个挺普遍但有点烦人的问题&#xff1a;如何把一个完整的Git代码仓库&#xff0c;包括它的目录结构、所有源代码文件以及提交历史&#xff0c;以一种清晰、可读…...

免费好用的去水印工具推荐:哪个效果最好?免费去水印工具对比 2026 实测

免费好用的去水印工具推荐&#xff1a;哪个效果最好&#xff1f;免费去水印工具对比 2026 实测 去水印这件事&#xff0c;真的是越来越高频了。自媒体剪素材、收藏喜欢的短视频、整理图片资料……一旦碰到带水印的内容&#xff0c;找个顺手的工具就成了刚需。网上工具多&#x…...

Llama.cpp Docker镜像部署指南:快速搭建本地大模型运行环境

1. 项目概述&#xff1a;为什么需要为Llama.cpp准备Docker镜像&#xff1f; 在本地部署和运行大型语言模型&#xff08;LLM&#xff09;这件事上&#xff0c;Llama.cpp 几乎成了开源社区的“标准答案”。它用纯C/C编写&#xff0c;通过高效的量化技术&#xff0c;让我们能在消费…...

VS2019集成libigl实战:从零到一的图形学开发环境搭建

1. 环境准备&#xff1a;从零搭建开发基础 第一次接触libigl和VS2019的组合时&#xff0c;我完全能理解那种手足无措的感觉。记得当时为了赶图形学课程作业&#xff0c;我和室友熬了三个通宵才把环境跑通。现在回头看&#xff0c;其实只要掌握几个关键步骤&#xff0c;整个过程…...

Marko导入导出完全指南:掌握模块化组件的终极导入导出机制

Marko导入导出完全指南&#xff1a;掌握模块化组件的终极导入导出机制 【免费下载链接】marko A declarative, HTML-based language that makes building web apps fun 项目地址: https://gitcode.com/gh_mirrors/ma/marko Marko是一款声明式、基于HTML的语言&#xff0…...

终极指南:3分钟解决Windows安装iPhone网络共享驱动难题

终极指南&#xff1a;3分钟解决Windows安装iPhone网络共享驱动难题 【免费下载链接】Apple-Mobile-Drivers-Installer Powershell script to easily install Apple USB and Mobile Device Ethernet (USB Tethering) drivers on Windows! 项目地址: https://gitcode.com/gh_mi…...

常见404 500错误解析

一、常见404 500错误解析浏览器&#xff1a;用户发起请求的入口&#xff0c;地址栏输入 URL、AJAX 请求都从这里发。服务器&#xff1a;本质就是一台电脑&#xff0c;Tomcat 在这里负责接收请求、分发处理。前端层&#xff1a;存放静态页面&#xff0c;处理页面渲染、用户交互…...

5分钟掌握视频号批量下载:res-downloader高效操作指南

5分钟掌握视频号批量下载&#xff1a;res-downloader高效操作指南 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader 在数字内容…...

智慧港口高风险作业AI实时监督技术实操解析

在智慧港口建设中&#xff0c;集装箱堆场、高风险作业的安全管控是核心重点&#xff0c;其中皮带运输、高风险作业&#xff08;吊装、动火、高处、有限空间等&#xff09;的安全保障&#xff0c;是港口运维的关键。当前&#xff0c;港口高风险作业普遍面临痛点&#xff1a;人工…...