手把手教你使用 Spring Boot 3 開發上線一個前後端分離的生產級系統(十) - ShardingSphere-JDBC 集成與配置

来源:https://www.cnblogs.com/xxyopen/archive/2022/06/09/16358081.html
-Advertisement-
Play Games

手把手教你使用 Spring Boot 3 開發上線一個前後端分離的生產級系統(一) - 介紹 手把手教你使用 Spring Boot 3 開發上線一個前後端分離的生產級系統(二) - 資料庫設計 手把手教你使用 Spring Boot 3 開發上線一個前後端分離的生產級系統(三) - 項目初始化 ...


手把手教你使用 Spring Boot 3 開發上線一個前後端分離的生產級系統(一) - 介紹
手把手教你使用 Spring Boot 3 開發上線一個前後端分離的生產級系統(二) - 資料庫設計
手把手教你使用 Spring Boot 3 開發上線一個前後端分離的生產級系統(三) - 項目初始化
手把手教你使用 Spring Boot 3 開發上線一個前後端分離的生產級系統(四) - 日誌 & 跨域配置
手把手教你使用 Spring Boot 3 開發上線一個前後端分離的生產級系統(五) - MyBatis-Plus & 代碼生成器集成與配置
手把手教你使用 Spring Boot 3 開發上線一個前後端分離的生產級系統(六) - 本地緩存 Caffeine 和 分散式緩存 Redis 集成與配置
手把手教你使用 Spring Boot 3 開發上線一個前後端分離的生產級系統(七) - Elasticsearch 8.2 集成與配置
手把手教你使用 Spring Boot 3 開發上線一個前後端分離的生產級系統(八) - XXL-JOB 集成與配置
手把手教你使用 Spring Boot 3 開發上線一個前後端分離的生產級系統(九) - Spring AMQP 集成與配置

背景

傳統的將數據集中存儲至單一節點的解決方案,在性能、可用性和運維成本這三方面已經難於滿足海量數據的場景。

從性能方面來說,由於關係型資料庫大多採用 B+ 樹類型的索引,在數據量超過閾值的情況下,索引深度的增加也將使得磁碟訪問的 IO 次數增加,進而導致查詢性能的下降; 同時,高併發訪問請求也使得集中式資料庫成為系統的最大瓶頸。

從可用性的方面來講,服務化的無狀態性,能夠達到較小成本的隨意擴容,這必然導致系統的最終壓力都落在資料庫之上。 而單一的數據節點,或者簡單的主從架構,已經越來越難以承擔。資料庫的可用性,已成為整個系統的關鍵。

從運維成本方面考慮,當一個資料庫實例中的數據達到閾值以上,對於 DBA 的運維壓力就會增大。 數據備份和恢復的時間成本都將隨著數據量的大小而愈發不可控。一般來講,單一資料庫實例的數據的閾值在 1TB 之內,是比較合理的範圍。

數據分片指按照某個維度將存放在單一資料庫中的數據分散地存放至多個資料庫或表中以達到提升性能瓶頸以及可用性的效果。通過分庫和分表進行數據的拆分來使得各個表的數據量保持在閾值以下,以及對流量進行疏導應對高訪問量,是應對高併發和海量數據系統的有效手段。分庫和分表均可以有效的避免由數據量超過可承受閾值而產生的查詢瓶頸。

小說數據有著內容多、增長速度快的特點,一本主流的完結小說一般所需存儲空間大概在 5MB 以上。一個主流的小說網站在發展中後期,數據量是遠遠超過單一資料庫實例的閾值的,所以我們對小說內容進行分庫分表存儲是非常有必要的。在發展初期,我們的數據量還不是很大,可以先將小說內容分表存儲以減輕資料庫單表壓力以及為後期的資料庫分庫做準備。等數據量即將超過閾值時,再遷移到不同的資料庫實例上。

註:數據分片分為按照業務將表進行歸類,分佈到不同的資料庫中的垂直分片和通過某個欄位(或某幾個欄位)按照某種規則將數據分散至多個庫或表中的水平分片。

Apache ShardingSphere 介紹

Apache ShardingSphere 產品定位為 Database Plus,它關註如何充分合理地利用資料庫的計算和存儲能力,而並非實現一個全新的資料庫。ShardingSphere 站在資料庫的上層視角,關註他們之間的協作多於資料庫自身,由 JDBC、Proxy 和 Sidecar(規劃中)這 3 款既能夠獨立部署,又支持混合部署配合使用的產品組成。 它們均提供標準化的基於資料庫作為存儲節點的增量功能,可適用於如 Java 同構、異構語言、雲原生等各種多樣化的應用場景。

ShardingSphere-JDBC 定位為輕量級 Java 框架,在 Java 的 JDBC 層提供額外服務。 它使用客戶端直連資料庫,以 jar 包形式提供服務,無需額外部署和依賴,可理解為增強版的 JDBC 驅動,完全相容 JDBC 和各種 ORM 框架。

ShardingSphere-Proxy 定位為透明化的資料庫代理端,提供封裝了資料庫二進位協議的服務端版本,用於完成對異構語言的支持。

ShardingSphere-Sidecar 定位為 Kubernetes 的雲原生資料庫代理,以 Sidecar 的形式代理所有對資料庫的訪問。 通過無中心、零侵入的方案提供與資料庫交互的嚙合層,即 Database Mesh,又可稱資料庫網格。

連接、增量 和 可插拔 是 Apache ShardingSphere 的核心概念:

  • 連接:通過對資料庫協議、SQL 方言以及資料庫存儲的靈活適配,快速的連接應用與多模式的異構資料庫;

  • 增量:獲取資料庫的訪問流量,並提供流量重定向(數據分片、讀寫分離、影子庫)、流量變形(數據加密、數據脫敏)、流量鑒權(安全、審計、許可權)、流量治理(熔斷、限流)以及流量分析(服務質量分析、可觀察性)等透明化增量功能;

  • 可插拔:項目採用微內核 + 三層可插拔模型,使內核、功能組件以及生態對接完全能夠靈活的方式進行插拔式擴展,開發者能夠像使用積木一樣定製屬於自己的獨特系統。

Apache ShardingSphere 的數據分片模塊透明化了分庫分表所帶來的影響,讓使用方儘量像使用一個資料庫一樣使用水平分片之後的資料庫集群。

集成步驟

  1. MySQL 執行以下的數據遷移腳本:
DROP PROCEDURE
IF
	EXISTS createBookChapterTable;
-- 創建小說章節表的存儲過程
CREATE PROCEDURE createBookChapterTable ( ) BEGIN
	-- 定義變數
	DECLARE
		i INT DEFAULT 0;
	DECLARE
		tableName CHAR ( 13 ) DEFAULT NULL;
	WHILE
			i < 10 DO
			
			SET tableName = concat( 'book_chapter', i );
		
			SET @stmt = concat( 'create table ', tableName, '(
				`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
				`book_id` bigint(20) unsigned NOT NULL COMMENT \'小說ID\',
				`chapter_num` smallint(5) unsigned NOT NULL COMMENT \'章節號\',
				`chapter_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT \'章節名\',
				`word_count` int(10) unsigned NOT NULL COMMENT \'章節字數\',
				`is_vip` tinyint(3) unsigned NOT NULL DEFAULT \'0\' COMMENT \'是否收費;1-收費 0-免費\',
				`create_time` datetime DEFAULT NULL,
				`update_time` datetime DEFAULT NULL,
				PRIMARY KEY (`id`) USING BTREE,
				UNIQUE KEY `uk_bookId_chapterNum` (`book_id`,`chapter_num`) USING BTREE,
				UNIQUE KEY `pk_id` (`id`) USING BTREE,
				KEY `idx_bookId` (`book_id`) USING BTREE
			) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT=\'小說章節\'' );
			PREPARE stmt 
			FROM
				@stmt;
			EXECUTE stmt;
			DEALLOCATE PREPARE stmt;
			
			SET i = i + 1;
		
	END WHILE;
END;
CALL createBookChapterTable ( );

DROP PROCEDURE
IF
	EXISTS createBookContentTable;
-- 創建小說內容表的存儲過程
CREATE PROCEDURE createBookContentTable ( ) BEGIN
	-- 定義變數
	DECLARE
		i INT DEFAULT 0;
	DECLARE
		tableName CHAR ( 13 ) DEFAULT NULL;
	WHILE
			i < 10 DO
			
			SET tableName = concat( 'book_content', i );
		
			SET @stmt = concat( 'create table ', tableName, '(
				`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT \'主鍵\',
				`chapter_id` bigint(20) unsigned NOT NULL COMMENT \'章節ID\',
				`content` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT \'小說章節內容\',
				`create_time` datetime DEFAULT NULL,
				`update_time` datetime DEFAULT NULL,
				PRIMARY KEY (`id`) USING BTREE,
				UNIQUE KEY `uk_chapterId` (`chapter_id`) USING BTREE,
				UNIQUE KEY `pk_id` (`id`) USING BTREE
			) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT=\'小說內容\'' );
			PREPARE stmt 
			FROM
				@stmt;
			EXECUTE stmt;
			DEALLOCATE PREPARE stmt;
			
			SET i = i + 1;
		
	END WHILE;
END;
CALL createBookContentTable ( );

DROP PROCEDURE
IF
	EXISTS copyBookChapterData;
-- 遷移小說章節數據的存儲過程
CREATE PROCEDURE copyBookChapterData ( ) BEGIN
	-- 定義變數
	DECLARE
		s INT DEFAULT 0;
	DECLARE
		chapterId BIGINT;
	DECLARE
		bookId BIGINT;
	DECLARE
		chapterNum SMALLINT;
	DECLARE
		chapterName VARCHAR ( 100 );
	DECLARE
		wordCount INT DEFAULT 0;
	DECLARE
		isVip TINYINT ( 64 ) DEFAULT 0;
	DECLARE
		createTime datetime DEFAULT NULL;
	DECLARE
		updateTime datetime DEFAULT NULL;
	DECLARE
		tableNumber INT DEFAULT 0;
	DECLARE
		tableName CHAR ( 13 ) DEFAULT NULL;
	-- 定義游標
	DECLARE
		report CURSOR FOR SELECT
		id,
		book_id,
		chapter_num,
		chapter_name,
		word_count,
		is_vip,
		create_time,
		update_time 
	FROM
		book_chapter;
	-- 聲明當游標遍歷完後將標誌變數置成某個值
	DECLARE
		CONTINUE HANDLER FOR NOT FOUND 
		SET s = 1;
	-- 打開游標
	OPEN report;
	-- 將游標中的值賦值給變數,註意:變數名不要和返回的列名同名,變數順序要和sql結果列的順序一致
	FETCH report INTO chapterId,
	bookId,
	chapterNum,
	chapterName,
	wordCount,
	isVip,
	createTime,
	updateTime;
	-- 迴圈遍歷
	WHILE
			s <> 1 DO
			-- 執行業務邏輯
			
			SET tableNumber = bookId % 10;
		
			SET tableName = concat( 'book_chapter', tableNumber );
			
			SET @stmt = concat(
				'insert into ',
				tableName,
				'(`id`, `book_id`, `chapter_num`, `chapter_name`, `word_count`, `is_vip`, `create_time`, `update_time`) VALUES (',
				chapterId,
				', ',
				bookId,
				', ',
				chapterNum,
				', \'',
				chapterName,
				'\', ',
				wordCount,
				', ',
				isVip,
				', \'',
				createTime,
				'\', \'',
				updateTime,
				'\')' 
			);
			PREPARE stmt 
			FROM
				@stmt;
			EXECUTE stmt;
			DEALLOCATE PREPARE stmt;
			FETCH report INTO chapterId,
			bookId,
			chapterNum,
			chapterName,
			wordCount,
			isVip,
			createTime,
			updateTime;
		
	END WHILE;
	-- 關閉游標
	CLOSE report;
END;
CALL copyBookChapterData ( );

DROP PROCEDURE
IF
	EXISTS copyBookContentData;
-- 遷移小說內容數據的存儲過程
CREATE PROCEDURE copyBookContentData ( ) BEGIN
	-- 定義變數
	DECLARE
		s INT DEFAULT 0;
	DECLARE
		contentId BIGINT;
	DECLARE
		chapterId BIGINT;
	DECLARE
		bookContent MEDIUMTEXT;
	DECLARE
		createTime datetime DEFAULT NULL;
	DECLARE
		updateTime datetime DEFAULT NULL;
	DECLARE
		tableNumber INT DEFAULT 0;
	DECLARE
		tableName CHAR ( 13 ) DEFAULT NULL;
	-- 定義游標
	DECLARE
		report CURSOR FOR SELECT
		id,
		chapter_id,
		content,
		create_time,
		update_time 
	FROM
		book_content;
	-- 聲明當游標遍歷完後將標誌變數置成某個值
	DECLARE
		CONTINUE HANDLER FOR NOT FOUND 
		SET s = 1;
	-- 打開游標
	OPEN report;
	-- 將游標中的值賦值給變數,註意:變數名不要和返回的列名同名,變數順序要和sql結果列的順序一致
	FETCH report INTO contentId,
	chapterId,
	bookContent,
	createTime,
	updateTime;
	-- 迴圈遍歷
	WHILE
			s <> 1 DO
			-- 執行業務邏輯
			
			SET tableNumber = chapterId % 10;
		
			SET tableName = concat( 'book_content', tableNumber );
			
			SET bookContent = REPLACE ( bookContent, '\'', "\\'" );
			
			SET @stmt = concat(
				'insert into ',
				tableName,
				'(`id`, `chapter_id`, `content`) VALUES (',
				contentId,
				', ',
				chapterId,
				',\'',
				bookContent,
				'\')' 
			);
			PREPARE stmt 
			FROM
				@stmt;
			EXECUTE stmt;
			DEALLOCATE PREPARE stmt;
			FETCH report INTO contentId,
			chapterId,
			bookContent,
			createTime,
			updateTime;
		
	END WHILE;
	-- 關閉游標
	CLOSE report;
END;
CALL copyBookContentData ( );
  1. 引入 ShardingSphere-JDBC 官方提供的 Spring Boot Starter 依賴:
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
    <version>5.1.1</version>
</dependency>
  1. application.yml 中添加 ShardingSphere-JDBC 的配置:
spring:
  shardingsphere:
    # 是否開啟 shardingsphere
    enabled: false
    props:
      # 是否在日誌中列印 SQL
      sql-show: true
    # 模式配置
    mode:
      # 單機模式
      type: Standalone
      repository:
        # 文件持久化
        type: File
        props:
          # 元數據存儲路徑
          path: .shardingsphere
      # 使用本地配置覆蓋持久化配置
      overwrite: true
    # 數據源配置
    datasource:
      names: ds_0
      ds_0:
        type: com.zaxxer.hikari.HikariDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        jdbcUrl: jdbc:mysql://localhost:3306/novel_test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
        username: root
        password: test123456
    # 規則配置
    rules:
      # 數據分片
      sharding:
        tables:
          # book_content 表
          book_content:
            # 數據節點
            actual-data-nodes: ds_$->{0}.book_content$->{0..9}
            # 分表策略
            table-strategy:
              standard:
                # 分片列名稱
                sharding-column: chapter_id
                # 分片演算法名稱
                sharding-algorithm-name: bookContentSharding
        sharding-algorithms:
          bookContentSharding:
            # 行表達式分片演算法,使用 Groovy 的表達式,提供對 SQL 語句中的 = 和 IN 的分片操作支持
            type: INLINE
            props:
              # 分片演算法的行表達式
              algorithm-expression: book_content$->{chapter_id % 10}

配置是 ShardingSphere-JDBC 中唯一與應用開發者交互的模塊,通過它可以快速清晰的理解 ShardingSphere-JDBC 所提供的功能。

  • 模式配置: Apache ShardingSphere 提供的 3 種運行模式分別是適用於集成測試的環境啟動,方便開發人員在整合功能測試中集成 Apache ShardingSphere 而無需清理運行痕跡記憶體模式、能夠將數據源和規則等元數據信息持久化,但無法將元數據同步至多個 Apache ShardingSphere 實例,無法在集群環境中相互感知的單機模式和提供了多個 Apache ShardingSphere 實例之間的元數據共用和分散式場景下狀態協調能力的集群模式

  • 數據源配置:包括使用本地數據源配置(本項目中)和使用 JNDI 數據源的配置。如果計劃使用 JNDI 配置資料庫,在應用容器(如 Tomcat)中使用 ShardingSphere-JDBC 時, 可使用 spring.shardingsphere.datasource.${datasourceName}.jndiName 來代替數據源的一系列配置。

  • 規則配置:規則是 Apache ShardingSphere 面向可插拔的一部分,包括數據分片、讀寫分離、高可用、數據加密、影子庫、SQL 解析、混合規則等。

以下是數據分片的配置項說明:

# 標準分片表配置
spring.shardingsphere.rules.sharding.tables.<table-name>.actual-data-nodes= # 由數據源名 + 表名組成,以小數點分隔。多個表以逗號分隔,支持 inline 表達式。預設表示使用已知數據源與邏輯表名稱生成數據節點,用於廣播表(即每個庫中都需要一個同樣的表用於關聯查詢,多為字典表)或只分庫不分表且所有庫的表結構完全一致的情況

# 分庫策略,預設表示使用預設分庫策略,以下的分片策略只能選其一

# 用於單分片鍵的標準分片場景
spring.shardingsphere.rules.sharding.tables.<table-name>.database-strategy.standard.sharding-column= # 分片列名稱
spring.shardingsphere.rules.sharding.tables.<table-name>.database-strategy.standard.sharding-algorithm-name= # 分片演算法名稱

# 用於多分片鍵的複合分片場景
spring.shardingsphere.rules.sharding.tables.<table-name>.database-strategy.complex.sharding-columns= # 分片列名稱,多個列以逗號分隔
spring.shardingsphere.rules.sharding.tables.<table-name>.database-strategy.complex.sharding-algorithm-name= # 分片演算法名稱

# 用於 Hint 的分片策略
spring.shardingsphere.rules.sharding.tables.<table-name>.database-strategy.hint.sharding-algorithm-name= # 分片演算法名稱

# 分表策略,同分庫策略
spring.shardingsphere.rules.sharding.tables.<table-name>.table-strategy.xxx= # 省略

# 自動分片表配置
spring.shardingsphere.rules.sharding.auto-tables.<auto-table-name>.actual-data-sources= # 數據源名

spring.shardingsphere.rules.sharding.auto-tables.<auto-table-name>.sharding-strategy.standard.sharding-column= # 分片列名稱
spring.shardingsphere.rules.sharding.auto-tables.<auto-table-name>.sharding-strategy.standard.sharding-algorithm-name= # 自動分片演算法名稱

# 分散式序列策略配置
spring.shardingsphere.rules.sharding.tables.<table-name>.key-generate-strategy.column= # 分散式序列列名稱
spring.shardingsphere.rules.sharding.tables.<table-name>.key-generate-strategy.key-generator-name= # 分散式序列演算法名稱

spring.shardingsphere.rules.sharding.binding-tables[0]= # 綁定表規則列表
spring.shardingsphere.rules.sharding.binding-tables[1]= # 綁定表規則列表
spring.shardingsphere.rules.sharding.binding-tables[x]= # 綁定表規則列表

spring.shardingsphere.rules.sharding.broadcast-tables[0]= # 廣播表規則列表
spring.shardingsphere.rules.sharding.broadcast-tables[1]= # 廣播表規則列表
spring.shardingsphere.rules.sharding.broadcast-tables[x]= # 廣播表規則列表

spring.shardingsphere.sharding.default-database-strategy.xxx= # 預設資料庫分片策略
spring.shardingsphere.sharding.default-table-strategy.xxx= # 預設表分片策略
spring.shardingsphere.sharding.default-key-generate-strategy.xxx= # 預設分散式序列策略
spring.shardingsphere.sharding.default-sharding-column= # 預設分片列名稱

# 分片演算法配置
spring.shardingsphere.rules.sharding.sharding-algorithms.<sharding-algorithm-name>.type= # 分片演算法類型
spring.shardingsphere.rules.sharding.sharding-algorithms.<sharding-algorithm-name>.props.xxx= # 分片演算法屬性配置

# 分散式序列演算法配置
spring.shardingsphere.rules.sharding.key-generators.<key-generate-algorithm-name>.type= # 分散式序列演算法類型
spring.shardingsphere.rules.sharding.key-generators.<key-generate-algorithm-name>.props.xxx= # 分散式序列演算法屬性配置

其中,分片演算法分為包含取模分片、哈希取模分片、基於分片容量的範圍分片、基於分片邊界的範圍分片、自動時間段分片在內的自動分片演算法和包含行表達式分片、時間範圍分片在內的標準分片演算法以及複合分片演算法Hint 分片演算法。我們還可以自定義類分片演算法,通過配置分片策略類型和演算法類名,實現自定義擴展。

分散式序列演算法包括雪花演算法和 UUID。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 時間的獲取及時間各格式間的轉換是比較常用的操作,但一是多種語言經常容易弄混,二是同一種語言同一個功能可能有不同的實現函數,導致每次處理時間經常要百度所以來記錄一下。 另外個人真不喜歡同樣功能有多種寫法的形式,從理想角度說多種實現方式讓不同的人都能以其喜歡的方式進行編寫;但實際上當你忘記的時候,你就總 ...
  • 沙包和打傘的故事 美國在1961年到1972年組織實施的一系列載人登月飛行任務。目的是實現載人登月飛行和人對月球的實地考察,為載人行星飛行和探測進行技術準備,它是世界航天史上具有劃時代意義的一項成就。阿波羅計劃始於1961年5月,至1972年12月第6次登月成功結束,歷時約11年,耗資255億美元。 ...
  • 一、分詞 - jieba 優秀的中文分詞庫,依靠中文詞庫,利用詞庫確定漢子之間關聯的概率,形成分詞結果 import jieba word = '偉大的中華人民共和國' jieba.cut(word) jieba.lcut(word) 二、詞雲庫 - wordcloud 對數據中出現頻率較高的 關鍵 ...
  • pom版本 <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.7</version> </dependency> 1.自定義合併單元格 在某些業務場景中可能會有合併單 ...
  • 主要內容 1·學習java日誌體系及日誌工具的演進 2·瞭解日誌採集、處理、分析等各階段的常用中間件 3·學會搭建完整的elk日誌平臺 4·學習日誌打點,切麵,日誌文件等輸出手段 5·項目實戰,完成一訪問日誌鏈路的跟蹤 1、Java日誌體系 1.1 體系概述 1.1.1 日誌介面 JCL:Apach ...
  • 前面我們詳細介紹了SSO、OAuth2的定義和實現原理,也舉例說明瞭如何在微服務框架中使用spring-security-oauth2實現單點登錄授權伺服器和單點登錄客戶端。目前很多平臺都提供了單點登錄授權伺服器功能,比如我們經常用到的QQ登錄、微信登錄、新浪微博登錄、支付寶登錄等等。 如果我們自己 ...
  • 一個工作了3年的粉絲,去一個互聯網公司面試,結果被面試官懟了。 面試官說:”這麼簡單的問題你都不知道? 沒法聊了,回去等通知吧“。 這個問題是: ”什麼是可重入鎖,以及它的作用是什麼?“ 對於這個問題,來看看普通人和高手的回答吧 普通人: 嗯。。。。。。。。。。。。。。。。。。 高手: 好的。 可重 ...
  • JDBC概述 JDBC(Java Data Base Connectivity,java資料庫連接)是一種用於執行SQL語句的Java API,可以為多種關係資料庫提供統一訪問,它由一組用Java語言編寫的類和介面組成。是Java訪問資料庫的標準規範。 JDBC提供了一種基準,據此可以構建更高級的工 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...