Go gRPC 和微服務架構的基礎與設計與實戰
微服務架構是一種將單體應用分解成一組獨立的小服務的架構模式,服務之間通過輕量級協議(如 HTTP 或 RPC)進行通信。相比傳統的單體架構,微服務架構具有高靈活性和擴展性,使團隊可以在開發、測試和部署上實現高度的自治。要深度理解微服務架構的基礎和設計。
一. 微服務基礎
1. 微服務架構的核心基礎
-
服務劃分(Service Partitioning) 微服務的核心是將應用程序分解爲一組相對獨立的小服務。通常每個服務專注於特定的業務功能(如用戶服務、訂單服務、支付服務等),這些服務獨立部署和擴展。
-
領域驅動設計(DDD):使用領域驅動設計中的 “限界上下文” 來劃分服務,確保服務具有明確的職責,減少依賴性。
-
單一職責原則:每個微服務應該只專注於一種業務功能,並具有清晰的邊界。
-
輕量級通信機制 微服務之間通過輕量級協議通信,常見協議有 HTTP(RESTful)、gRPC(基於 Protocol Buffers 的高性能 RPC 框架)和消息隊列(如 Kafka 或 RabbitMQ)。選擇通信方式時需考慮延遲、數據一致性和可靠性要求。
-
RESTful API:適合請求響應式通信,簡單而靈活。
-
gRPC:適合高性能、低延遲的通信場景,特別是對實時性有要求的服務。
-
消息隊列:適合事件驅動架構和異步任務處理,能夠提升系統的解耦和容錯性。
-
數據管理與隔離 每個微服務應擁有自己的數據存儲,避免直接共享數據庫,確保服務的獨立性和自治性。這種 “數據庫去中心化” 使得微服務可以獨立選擇最適合的存儲方案(關係型數據庫、NoSQL、圖數據庫等)。
-
事件驅動架構:通過事件總線(如 Kafka)來同步服務之間的狀態變化。
-
CQRS(命令查詢責任分離):使用不同的數據模型來分別處理讀取和寫入請求,適合高併發場景。
-
服務發現與註冊 在分佈式系統中,服務實例數量和位置是動態變化的。服務發現機制使客戶端能夠通過服務名稱找到服務地址,實現動態擴展和負載均衡。常見的服務發現工具包括 Consul、etcd 和 Eureka。
-
客戶端負載均衡:客戶端通過服務發現獲取服務列表,隨機或按負載均衡策略選擇實例。
-
服務註冊中心:服務啓動時將自身註冊到註冊中心,便於其他服務查找。
-
容錯機制與服務治理 微服務架構中需要實現服務的高可用性和容錯機制,確保系統在部分服務異常時依然能夠提供基本功能。常見的容錯機制包括:
-
斷路器(Circuit Breaker):在服務故障時自動切換到備用服務或返回默認響應,防止系統過載。
-
重試與限流:重試機制確保服務在短期失敗後能恢復;限流機制控制請求速率,防止系統超載。
-
熔斷器:在服務故障過多時短暫熔斷,恢復後再開啓請求通道。
-
API 網關 API 網關是客戶端與微服務之間的唯一入口,負責請求路由、認證、負載均衡、緩存和聚合等功能。API 網關不僅優化了前後端通信,還能在請求到達微服務之前進行預處理,提供統一的安全和治理能力。
-
請求路由:將客戶端請求路由到對應的服務。
-
聚合:整合多個服務的響應,減少客戶端的請求數量。
-
安全驗證:統一處理認證和授權,提高服務的安全性。
2. 微服務架構的設計原則
-
單一職責原則 每個微服務都應該只負責一個業務功能,實現業務與代碼的高度一致性。單一職責保證了服務的清晰性和穩定性,降低了複雜度。
-
高內聚、低耦合 微服務架構中服務之間的耦合度越低越好,使得某個服務的變更不會影響到其他服務。同時服務內部的功能應具備高度內聚,保證業務邏輯的完整性和一致性。
-
獨立部署 每個服務應獨立開發、測試、部署和擴展,且彼此不受干擾。獨立部署支持快速迭代,提高了開發效率。
-
去中心化數據管理 微服務架構通常採用去中心化的數據存儲,每個服務有獨立的數據存儲,從而避免服務間的數據耦合。此外,這種方式允許服務根據需求選擇最佳的數據存儲技術。
-
自動化部署與運維 微服務架構中服務數量衆多,手動運維幾乎不可行。使用 CI/CD 工具(如 Github Action、Github CI/CD)來實現自動化構建、測試和部署。同時使用容器化工具(如 Docker)和編排系統(如 Kubernetes)管理服務的部署和伸縮。
-
可觀測性與監控 微服務架構複雜且分佈式,必須具有完善的可觀測性,便於追蹤請求和定位問題。可觀測性通常包含以下三個部分:
-
日誌:記錄每個服務的請求、響應和異常信息。
-
指標監控:監控服務的性能和資源使用情況,如請求響應時間、內存、CPU 使用率等。
-
分佈式追蹤:跟蹤請求在服務間的調用鏈路,常用的工具有 Jaeger 和 Zipkin。
-
容錯與自愈 微服務架構中服務可能頻繁出現故障,設計時需考慮容錯性。除了斷路器和熔斷器,還可以使用自愈機制,如在服務故障後自動重新啓動服務實例。
3. 微服務架構的常見模式
-
聚合器模式 通過 API 網關將多個微服務聚合爲一個響應,適合需要同時訪問多個服務的場景。
-
代理模式 使用代理服務替代具體服務提供的功能,適合跨越多個子系統的調用需求,有助於隱藏複雜的內部實現。
-
事件驅動模式 基於事件總線實現服務間異步通信,常用於高併發系統中,通過事件來實現松耦合。
-
共享庫模式 公用邏輯或工具庫抽取爲共享庫,減少重複開發,適合包含複雜業務邏輯的系統。
4. 微服務架構的挑戰
-
分佈式系統複雜性 服務間的網絡調用較本地調用更爲複雜,需處理延遲、丟包、重試等問題,且數據一致性難以保證。
-
數據一致性 數據分散在多個服務中,跨服務的數據一致性(如分佈式事務)成爲難點。常用的解決方案包括兩階段提交和最終一致性。
-
監控與日誌聚合 微服務的分佈式特性使得監控和日誌管理更具挑戰,需要整合分散的服務日誌以獲得全局視角。
-
安全性管理 服務間需要統一的安全策略,防止未經授權的訪問。API 網關通常負責身份認證,但也需防範服務間的安全問題,如使用 TLS、身份驗證和權限控制。
5. 總結
微服務架構通過解耦應用中的不同功能模塊來提升靈活性和擴展性,允許開發團隊更快地響應業務需求。然而,微服務架構也增加了系統複雜性,需要依賴分佈式系統的設計原則和服務治理機制來確保系統的可靠性和可維護性。在設計和實現微服務架構時,需綜合考慮業務需求、技術能力和團隊規模,並靈活應用各類架構模式和工具。
二. DappLink 一鍵發錢包服務架構設計
1. 系統架構設計
-
wallet-chain-utxo: utxo 鏈的錢包 RPC 接口統一封裝
-
wallet-chain-account: account 鏈的 RPC 接口的統一封裝
-
chain-data-api: 對接第三方平臺的統一錢包 API,主要是給 HD 錢包使用的
-
key-locker: 鏈上密鑰管理工具,目前對接 Ethereum, IFPS, Ar 等鏈
-
skeye: 統一行情服務,對接了 CEX 和 DEX
-
trade: 支持中心化錢包的閃兌,槓槓,期貨和期權保險的項目,後面對接的是交易所
-
hailstone: 統一 API 和業務中臺
-
tss 網絡: MPC 網絡
-
wallet-sdk:多鏈離線地址和離線簽名的 SDK
-
wallet-sign-center: java, go, node
-
統一掃鏈服務:支持多租戶,中心化錢包業務組件
-
API:支持第三方調度錢包業務的 API
-
Dapp 容器:支持各種 Dapp 和錢包進行交互
-
去中心化閃兌:調度 Aggregator API
2. 功能模塊設計
2.1 統一 RPC Service 項目
2.1.1 現在的版本
2.1.2 本次開發版本
-
UTXO: 對接 UTXO 鏈的統一 RPC 服務
-
Account:對接 Account 模型的統一 RPC 服務
2.2 統一簽名機服務
2.3 統一錢包業務平臺 (含掃鏈功能)
2.3.1 業務配置流程
2.3.2 批量地址生成
2.3.3 充值業務
2.3.4 提現業務流程
3. Account 數據庫設計
3.1 業務表
CREATE TABLE IF NOT EXISTS business
(
guid VARCHAR PRIMARY KEY,
business_uid VARCHAR NOT NULL,
deposit_notify VARCHAR NOT NULL,
withdraw_notify VARCHAR NOT NULL,
tx_flow_notify VARCHAR NOT NULL,
timestamp INTEGER NOT NULL CHECK (timestamp > 0)
);
CREATE INDEX IF NOT EXISTS tokens_timestamp ON business (timestamp);
CREATE INDEX IF NOT EXISTS business_uid ON business (business_uid);
3.2 區塊表
CREATE TABLE IF NOT EXISTS blocks (
hash VARCHAR PRIMARY KEY,
parent_hash VARCHAR NOT NULL UNIQUE,
number UINT256 NOT NULL UNIQUE CHECK(number>0),
timestamp INTEGER NOT NULL CHECK(timestamp>0)
);
CREATE INDEX IF NOT EXISTS blocks_number ON blocks(number);
CREATE INDEX IF NOT EXISTS blocks_timestamp ON blocks(timestamp);
3.3 Token 配置表
CREATE TABLE IF NOT EXISTS tokens
(
guid VARCHAR PRIMARY KEY,
token_address VARCHAR NOT NULL,
decimals SMALLINT NOT NULL DEFAULT 18,
token_name VARCHAR NOT NULL,
collect_amount UINT256 NOT NULL,
cold_amount UINT256 NOT NULL,
timestamp INTEGER NOT NULL CHECK (timestamp > 0)
);
CREATE INDEX IF NOT EXISTS tokens_timestamp ON tokens (timestamp);
CREATE INDEX IF NOT EXISTS tokens_token_address ON tokens (token_address);
3.4 地址表
CREATE TABLE IF NOT EXISTS addresses (
guid VARCHAR PRIMARY KEY,
address VARCHAR UNIQUE NOT NULL,
address_type SMALLINT NOT NULL DEFAULT 0,
public_key VARCHAR NOT NULL,
timestamp INTEGER NOT NULL CHECK(timestamp>0)
);
CREATE INDEX IF NOT EXISTS addresses_address ON addresses(address);
CREATE INDEX IF NOT EXISTS addresses_timestamp ON addresses(timestamp);
3.5 賬戶表
CREATE TABLE IF NOT EXISTS balances (
guid VARCHAR PRIMARY KEY,
address VARCHAR NOT NULL,
token_address VARCHAR NOT NULL,
balance UINT256 NOT NULL CHECK(balance>=0),
lock_balance UINT256 NOT NULL,
timestamp INTEGER NOT NULL CHECK(timestamp>0)
);
CREATE INDEX IF NOT EXISTS balances_address_uuid ON balances(address_uuid);
CREATE INDEX IF NOT EXISTS balances_timestamp ON balances(timestamp);
3.6 充值表
CREATE TABLE IF NOT EXISTS deposits (
guid VARCHAR PRIMARY KEY,
block_hash VARCHAR NOT NULL,
block_number UINT256 NOT NULL CHECK(block_number>0),
hash VARCHAR NOT NULL,
from_address VARCHAR NOT NULL,
to_address VARCHAR NOT NULL,
token_address VARCHAR NOT NULL,
token_id VARCHAR NOT NULL,
token_meta VARCHAR NOT NULL,
fee UINT256 NOT NULL,
amount UINT256 NOT NULL,
status SMALLINT NOT NULL DEFAULT 0,
timestamp INTEGER NOT NULL CHECK(timestamp>0)
);
CREATE INDEX IF NOT EXISTS deposits_hash ON deposits(hash);
CREATE INDEX IF NOT EXISTS deposits_timestamp ON deposits(timestamp);
3.7 提現表
CREATE TABLE IF NOT EXISTS withdraws (
guid VARCHAR PRIMARY KEY,
block_hash VARCHAR NOT NULL,
block_number UINT256 NOT NULL CHECK(block_number>0),
hash VARCHAR NOT NULL,
from_address VARCHAR NOT NULL,
to_address VARCHAR NOT NULL,
token_address VARCHAR NOT NULL,
token_id VARCHAR NOT NULL,
token_meta VARCHAR NOT NULL,
fee UINT256 NOT NULL,
amount UINT256 NOT NULL,
status SMALLINT NOT NULL DEFAULT 0,
transaction_index UINT256 NOT NULL,
timestamp INTEGER NOT NULL CHECK(timestamp>0),
tx_sign_hex VARCHAR NOT NULL
);
CREATE INDEX IF NOT EXISTS withdraws_hash ON withdraws(hash);
CREATE INDEX IF NOT EXISTS withdraws_timestamp ON withdraws(timestamp);
3.8 交易流水錶
CREATE TABLE IF NOT EXISTS transactions (
guid VARCHAR PRIMARY KEY,
block_hash VARCHAR NOT NULL,
block_number UINT256 NOT NULL CHECK(block_number>0),
hash VARCHAR NOT NULL,
from_address VARCHAR NOT NULL,
to_address VARCHAR NOT NULL,
token_address VARCHAR NOT NULL,
token_id VARCHAR NOT NULL,
token_meta VARCHAR NOT NULL,
fee UINT256 NOT NULL,
amount UINT256 NOT NULL,
status SMALLINT NOT NULL DEFAULT 0,
tx_type SMALLINT NOT NULL DEFAULT 0,
timestamp INTEGER NOT NULL CHECK(timestamp>0)
);
CREATE INDEX IF NOT EXISTS transactions_hash ON transactions(hash);
CREATE INDEX IF NOT EXISTS transactions_timestamp ON transactions(timestamp);
- 每一個業務一套數據庫
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/joSeoC0rZSU1lz0mV7WGdA