成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

基于 DDD 的互聯網“贊&踩”系統

開發 架構
贊/踩服務是一種用戶反饋機制。隨著社交媒體的普及和發展,人們越來越喜歡在一種平臺上分享自己的觀點和生活,這時就需要一種形式化的反饋機制來快速評價這些信息的好壞。贊/踩服務的目標是為了提高用戶互動性,增加內容的社會影響力,從而增加活躍用戶數量。

該文是系統的用戶手冊,主要體現系統功能和所支持的高級特性,關于系統的核心設計正在整理中,請稍安勿躁

1. 背景

隨著社交媒體的普及,用戶生成的內容數量急劇增加。為了幫助用戶更好地發現和分享內容,許多社交媒體平臺都提供了贊/踩服務。

2. 目標

贊/踩服務是一種用戶反饋機制。隨著社交媒體的普及和發展,人們越來越喜歡在一種平臺上分享自己的觀點和生活,這時就需要一種形式化的反饋機制來快速評價這些信息的好壞。贊/踩服務的目標是為了提高用戶互動性,增加內容的社會影響力,從而增加活躍用戶數量。

3. 快速入門

系統所涉及的功能包括:

功能

描述

贊/踩

用戶可以點擊對應的贊或踩按鈕,以表達自己的喜好或不喜好

取消贊/踩

用戶可以取消之前的贊/踩,以更正自己的想法

計數器

贊和踩的數量都需要計數器,用于顯示文章或評論的受歡迎程度和社交影響力等

贊/踩歷史

用戶可以查看自己贊/踩的歷史記錄,以查看自己對文章或評論的態度

3.1. 開發環境

基于 Spring Boot 框架進行開發,以 DDD 作為業務邏輯承載模型。

框架

版本

依賴說明

JDK

1.8+

運行環境

Spring Boot

2.3.12.RELEASE


Spring Data

2.3.9.RELEASE

基于 JPA 實現持久化;基于 Redis 完成緩存加速(可選)

Lego

0.1.22

DDD 模型落地

springfox

3.0.0

文檔管理

RocketMQ

2.2.1

領域事件,異步處理(可選)

Sharding Sphere

4.4.1

分庫分表(可選)

3.2. 模塊介紹

該項目使用標準的 “六邊形架構”,對業務和技術進行分離,所以模塊較多,但層次更為清晰。

模塊

作用

domain

核心邏輯層,DDD 中核心組件,包括實體、值對象、聚合根、領域服務等

app

應用服務層,DDD 中的應用服務,主要負責流程編排

infrastructure

基礎設施層,主要負責與 DB 或其他服務進行通訊

api

RPC 服務中的接口定義,被 FeignClient 和 FeignService 依賴

FeignService

api 中接口的實際實現者,完成接口的適配

FeignClient

api 中Proxy實現者,方便使用方直接調用

bootstrap

應用啟動入口,包括 Spring Boot 入口和所有配置

3.3. 啟動項目

3.3.1. 建庫建表

建表語句在infrastructure/src/main/resources/sql 目標下,包括單庫和分庫分表配置。單庫建表語句如下:

create table dislike_action
(
    id          bigint auto_increment primary key,
    create_time datetime    not null,
    delete_time datetime    null,
    update_time datetime    null,
    vsn         int         not null,
    status      char(16)    not null,
    target_id   bigint      not null,
    target_type varchar(16) not null,
    user_id     bigint      not null,
    constraint unq_user_target
        unique (user_id, target_type, target_id)
);
create table dislike_target_count
(
    id          bigint auto_increment primary key,
    create_time datetime    not null,
    delete_time datetime    null,
    update_time datetime    null,
    vsn         int         not null,
    count       bigint      not null,
    target_id   bigint      not null,
    target_type varchar(16) not null,
    constraint unq_target
        unique (target_id, target_type)
);
create table like_action
(
    id          bigint auto_increment primary key,
    create_time datetime    not null,
    delete_time datetime    null,
    update_time datetime    null,
    vsn         int         not null,
    status      char(16)    not null,
    target_id   bigint      not null,
    target_type varchar(16) not null,
    user_id     bigint      not null,
    constraint unq_user_target
        unique (user_id, target_type, target_id)
);
create table like_target_count
(
    id          bigint auto_increment primary key,
    create_time datetime    not null,
    delete_time datetime    null,
    update_time datetime    null,
    vsn         int         not null,
    count       bigint      not null,
    target_id   bigint      not null,
    target_type varchar(16) not null,
    constraint unq_target
        unique (target_id, target_type)
);

3.3.2. 修改數據庫配置

修改bootstrap/src/main/resource/application.yml 增加數據配置,具體如下:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/like
    username: root
    password: root

3.3.3. 啟動應用程序

直接運行 bootstrap 模塊下的 LikeApplication 類,輸入地址:http://127.0.0.1:8080/swagger-ui/

當看到如下界面證明程序啟動成功:

3.3. 核心 API

核心接口如下:

功能

請求地址

參數類型

參數說明

返回結果

cur Demo

點贊

POST /feignService/action/command/like

RequestBody

{"userId": 用戶id, "targetType": 目標對象類型,"targetId": 目標對象 id}

curl -X POST "http://127.0.0.1:8080/feignService/action/command/like" -H "accept: /" -H "Content-Type: application/json" -d "{"targetId":1,"targetType":"TEST","userId":2}"

取消點贊

POST /feignService/action/command/unlike

RequestBody

{"userId": 用戶id, "targetType": 目標對象類型,"targetId": 目標對象 id}

curl -X POST "http://127.0.0.1:8080/feignService/action/command/unlike" -H "accept: /" -H "Content-Type: application/json" -d "{"targetId":1,"targetType":"test","userId":2}"

獲取點贊數量

GET /feignService/targetCount/query/getLikeCountByTarget

RequestParam

type:目標類型;ids:目標id集合

[{"targetType":目標對象類型,“targetId":目標對象id,"count":點贊數量}]

curl -X GET "http://127.0.0.1:8080/feignService/targetCount/query/getLikeCountByTarget?type=test&ids=1" -H "accept: /"

獲取點贊記錄

GET /feignService/action/query/getLikeByUserAndType

RequestParam

type:目標類型;userId:userId

[{"targetType":目標對象類型,“targetId":目標對象id,"userId":用戶id,"valid":是否有效}]

curl -X GET "http://127.0.0.1:8080/feignService/action/query/getLikeByUserAndType?userId=2&type=test" -H "accept: /"

POST /feignService/action/command/dislike

RequestBody

{"userId": 用戶id, "targetType": 目標對象類型,"targetId": 目標對象 id}

curl -X POST "http://127.0.0.1:8080/feignService/action/command/dislike" -H "accept: /" -H "Content-Type: application/json" -d "{"targetId":1,"targetType":"test","userId":2}"

取消踩

POST /feignService/action/command/unDislike

RequestBody

{"userId": 用戶id, "targetType": 目標對象類型,"targetId": 目標對象 id}

curl -X POST "http://127.0.0.1:8080/feignService/action/command/unDislike" -H "accept: /" -H "Content-Type: application/json" -d "{"targetId":1,"targetType":"test","userId":2}"

獲取踩數量

GET /feignService/targetCount/query/getDislikeCountByType

RequestParam

type:目標類型;ids:目標id集合

[{"targetType":目標對象類型,“targetId":目標對象id,"count":點贊數量}]

curl -X GET "http://127.0.0.1:8080/feignService/targetCount/query/getDislikeCountByType?type=test&ids=1" -H "accept: /"

獲取點贊記錄

GET /feignService/action/query/getDislikeByUserAndType

RequestParam

type:目標類型;userId:userId

[{"targetType":目標對象類型,“targetId":目標對象id,"userId":用戶id,"valid":是否有效}]

curl -X GET "http://127.0.0.1:8080/feignService/action/query/getDislikeByUserAndType?userId=2&type=test" -H "accept: /"

核心API直接在 Swagger UI 上進行測試即可?。?!

4. 高級特性

4.1. 自定義業務驗證

流程中涉及兩個重要的概念:

  • ActionUser: 操作 贊或踩 的用戶;
  • ActionTarget: 贊或踩 的目的對象;

在實際業務場景,需要對這兩個對象的有效性進行驗證,比如:

  • ActionUser

用戶是否存在?

用戶狀態是否有效?

是否是黑名單用戶?

  • ActionTarget
  • 目標對象是否存在?
  • 目標對象是否已經下線/禁用?

這些功能擴展直接實現對應的 Loader 即可。

4.1.1. ActionUser 擴展

ActionUser 定義如下:

public class ActionUser {
    @Column(name = "user_id", updatable = false)
    private Long userId;
    @Transient
    private boolean valid;
}

如果用戶狀態存在問題,直接將 valid 置為 false 即可。

ActionUserLoader 定義如下:

public interface ActionUserLoader {
    ActionUser loadByUserId(Long userId);
}

只需實現 ActionUserLoader 并注冊為 Spring 托管 Bean 即可,具體如下:

@Component(value = LoadActionUserByUserId.BEAN_NAME)
public class TestActionUserLoader implements ActionUserLoader {
    @Override
    public ActionUser loadByUserId(Long userId) {
        if (userId == null || userId.longValue() < 0){
            return ActionUser.apply(userId, false);
        }else {
            return ActionUser.apply(userId);
        }
    }
}

當 userId 為 null 或者 小于 0 時,表明為無效用戶,將 valid 設置為 false。

【備注】Bean 必須注冊為LoadActionUserByUserId.BEAN_NAME(actionUserLoader),否則框架將無法識別。

4.1.2. ActionTarget 擴展

ActionTarget 定義如下:

public class ActionTarget {
    @Column(name = "target_type", updatable = false)
    private String type;
    @Column(name = "target_id", updatable = false)
    private Long id;
    @Transient
    private boolean valid;
}

如果目標對象狀態存在問題,直接將 valid 置為 false 即可。

由于系統中可以存在多種目標對象,為每個類型提供單獨的 Loader,接口如下:

public interface SingleActionTargetLoader {
    /**
     * 是否支持 type 類型的 Target
     * @param type
     * @return
     */
    boolean support(String type);
    /**
     * 加載 Target 對象
     * @param type
     * @param id
     * @return
     */
    ActionTarget load(String type, Long id);
}

按需要實現接口,樣例如下:

@Component
@Order(0)
public class TestActionTargetLoader
        extends AbstractSingleActionTargetLoader
        implements SingleActionTargetLoader {
    public TestActionTargetLoader() {
        super("Test");
    }
    @Override
    protected ActionTarget doLoadById(String type, Long id) {
        if (id == null || id.longValue() < 0){
            return ActionTarget.apply(type, id, false);
        }else {
            return ActionTarget.apply(type, id);
        }
    }
}

該實現對 type 為 Test 的 Target 進行加載。

4.2. 發布領域事件

領域事件是 DDD 中的重要概念,當系統發生狀態變化后,將變化結果對外進行廣播,從而實現系統間的集成。

4.2.1. 添加 RocketMQ

外部領域事件通過 RocketMQ 向外廣播,需要搭建 RocketMQ 集群并在項目中增加 RocketMQ 的支持。

在 bootstrap 模塊的 pom 中增加 rocketmq starter,具體如下:

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
</dependency>

在 application.yml 增加 rocketmq 的配置,具體如下:

rocketmq:
  name-server: http://127.0.0.1:9876
  producer:
    group: like-service

至此,便完成了與 rocketmq 的集成。

4.2.2. 打開領域事件開關

在 application.yml 添加如下配置:

like:
  event:
    #開啟領域事件
    enable: true
    #指定領域事件發送的 topic
    topic: like-event-topic

開啟領域事件,并指定事件發送的 topic

4.2.3. 測試領域事件

重新啟動項目,當控制臺輸出以下表明配置成功:

Use RocketMQ to Publish Like Event

使用 swagger 運行 dislike 操作,從日志中可知消息發送成功:

4.2.4. 支持領域事件

系統支持的領域事件包括:

領域事件類型

觸發機制

tag

消息體

LikeMarkedEvent

點贊成功

LikeMarkedEvent

見 LikeMarkedEvent 類

LikeCancelledEvent

取消點贊成功

LikeCancelledEvent

見 LikeCancelledEvent 類

DislikeMarkedEvent

踩成功

DislikeMarkedEvent

見 DislikeMarkedEvent 類

DislikeCancelledEvent

取消踩成功

DislikeCancelledEvent

見 DislikeCancelledEvent 類

4.3. 緩存加速

在系統中,獲取目標對象的 贊/踩 數量接口調用量最大,會成為系統的第一個性能卡點,針對這個問題,可以通過引入 redis 緩存進行性能加速。

4.3.1. 添加 redis 依賴

首先需要引入 redis 相關依賴,在 bootstrap 的 pom 中增加如下配置:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

然后在 application.yml 中增加 redis 相關配置:

spring:
  redis:
    host: 127.0.0.1
    port: 6379

4.3.2. 開啟緩存

完成redis配置后,需要在 application.yml 開啟對應的緩存,具體如下:

target:
  count:
    dislike:
      cache:
        # 是否開啟緩存
        enable: true
    like:
      cache:
        # 是否開啟緩存
        enable: true

4.3.3. 緩存效果

未開啟緩存前,每次查詢數量都會執行一條 sql,具體如下:curl 命令如下:

curl -X GET "http://127.0.0.1:8080/feignService/targetCount/query/getDislikeCountByType?type=test&ids=1" -H "accept: */*"

輸出 sql 如下:

Hibernate: select disliketar0_.id as id1_1_, disliketar0_.create_time as create_t2_1_, disliketar0_.delete_time as delete_t3_1_, disliketar0_.update_time as update_t4_1_, disliketar0_.vsn as vsn5_1_, disliketar0_.count as count6_1_, disliketar0_.target_id as target_i7_1_, disliketar0_.target_type as target_t8_1_ from dislike_target_count disliketar0_ where disliketar0_.target_type=? and (disliketar0_.target_id in (?))

開啟緩存后,再次執行以上 curl,控制臺不會輸出sql,而是會輸出一行日志:

c.g.l.i.s.RedisBasedTargetCountCache     : load All Data From Cache for test and [1]

說明緩存已經生效。

所有的 action 操作都會與同步的對緩存進行更新。

4.4. 異步存儲

當目標對象出現熱點時,會產生高并發請求,對于 action 來說,主要以數據插入和數據的分散更新為主。但對于 count,就會產生熱點更新,從而成為系統的瓶頸。在這個場景,最適合的解決方案便是引入 MQ 對流量進行削峰填谷。

4.4.1. 增加 rocketmq

與 4.2.1. 添加 RocketMQ 內容一致,在此不再重復。

4.4.2. 開啟異步化

在 application.yml 中增加如下配置:

target:
  count:
    dislike:
      async:
        # 是否開啟異步更新
        enable: true
        # 異步更新所使用的 topic
        topic: dislike-target-count-async-topic
        # 異步更新使用的消費者組
        consumerGroup: dislike-target-count-async-group
    like:
      async:
        # 是否開啟異步更新
        enable: true
        # 異步更新所使用的 topic
        topic: like-target-count-async-topic
        # 異步更新使用的消費者組
        consumerGroup: like-target-count-async-group

4.4.3. 異步效果

重啟應用程序,在 swagger 中執行 點贊 操作,從控制臺可以看到如下日志:

[nio-8080-exec-7] c.g.l.c.a.order.OrderedAsyncInterceptor  : success to send orderly async Task to RocketMQ, args is [ActionTarget(type=test, id=18, valid=true), 1], shardingKey is 18, msg is GenericMessage [payload={"0":"{\"type\":\"test\",\"id\":18,\"valid\":true}","1":"1"}, headers={id=c84e6be5-acec-27c2-3f44-6250003a56c7, timestamp=1685275901638}], result is SendResult [sendStatus=SEND_OK, msgId=7F0000014F505C8DA9628F610AC60007, offsetMsgId=C0A8032300002A9F00000000001A0AFD, messageQueue=MessageQueue [topic=dislike-target-count-async-topic, brokerName=MacdeMacBook-Pro-171.local, queueId=3], queueOffset=8]
[MessageThread_4] g.l.i.d.DislikeTargetCountRepositoryImpl : begin to incr for db target ActionTarget(type=test, id=18, valid=true), count 1
[nio-8080-exec-7] com.geekhalo.like.app.RocketMQPublisher  : success to send msg GenericMessage [payload={"targetId":18,"targetType":"test","userId":1}, headers={id=4e8e13f9-b3cd-7b90-059f-f506f09d9948, timestamp=1685275901640}] to like-event-topic:DislikeMarkedEvent, msgId is 7F0000014F505C8DA9628F610AC80008
[nio-8080-exec-7] c.g.l.c.c.s.AbstractCommandService       : success to sync AbstractCommandService.Syncer.Data(id=106, action=UPDATE, a=DislikeAction(super=AbstractAction(super=AbstractAggRoot(super=AbstractEntity(vsn=0, createAt=Sun May 28 20:11:41 CST 2023, updateAt=Sun May 28 20:11:41 CST 2023, deleteAt=null), events=[]), id=106, user=ActionUser(userId=1, valid=true), target=ActionTarget(type=test, id=18, valid=true), status=VALID)))
[MessageThread_4] g.l.i.d.DislikeTargetCountRepositoryImpl : success to incr for db target ActionTarget(type=test, id=18, valid=true), count 1
[MessageThread_4] .s.AbstractSingleMethodConsumerContainer : consume message 7F0000014F505C8DA9628F610AC60007, cost: 27 ms

從日志上看,可以得出:

  • nio 線程向 MQ 發送消息
  • MessageThread 線程從 MQ 中獲取數據并執行 incr 操作

4.5. 分庫分表

隨著系統的運行,數據量會逐漸增大,最終超出單個 DB 的容量上限。這種情況下,最佳實踐便是對數據庫進行分庫分表。

4.5.1. 構建數據庫和表

在 infrastructure 模塊的 sql 目錄下存在兩個 sql 文件:

  • create_table_sharding_action.sql : 贊/踩 操作分庫分表
  • create_table_sharding_count.sql : 贊/踩 計數分庫分表

示例中總共分16張表,存放在兩個數據庫中:

  • db1 存放 0-7 表
  • db2 存放 8-15 表

如圖所示:

4.5.2. 添加 ShardingSphere 支持

在 bootstrap 的pom 文件增加 ShardingSphere 的依賴,具體如下:

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
</dependency>

其次,增加分庫分表配置文件,為了方便新建 application.properties 存放分庫分表配置:

# 數據源配置
# 總共4個數據源
spring.shardingsphere.datasource.names=action-ds0, action-ds1, count-ds0, count-ds1 
# action-ds0 數據源配置
spring.shardingsphere.datasource.action-ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.action-ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.action-ds0.jdbc-url=jdbc:mysql://127.0.0.1:3306/like_action_0?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC
spring.shardingsphere.datasource.action-ds0.username=root
spring.shardingsphere.datasource.action-ds0.password=root
# action-ds1 數據源配置
spring.shardingsphere.datasource.action-ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.action-ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.action-ds1.jdbc-url=jdbc:mysql://127.0.0.1:3306/like_action_1?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC
spring.shardingsphere.datasource.action-ds1.username=root
spring.shardingsphere.datasource.action-ds1.password=root
# count-ds0 數據源配置
spring.shardingsphere.datasource.count-ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.count-ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.count-ds0.jdbc-url=jdbc:mysql://127.0.0.1:3306/like_count_0?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC
spring.shardingsphere.datasource.count-ds0.username=root
spring.shardingsphere.datasource.count-ds0.password=root
# count-ds1 數據源配置
spring.shardingsphere.datasource.count-ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.count-ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.count-ds1.jdbc-url=jdbc:mysql://127.0.0.1:3306/like_count_1?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC
spring.shardingsphere.datasource.count-ds1.username=root
spring.shardingsphere.datasource.count-ds1.password=root
# 分庫分表規則配置
# 使用雪花算法生成分布式主鍵id的值
spring.shardingsphere.sharding.default-key-generator.column=id
spring.shardingsphere.sharding.default-key-generator.column-type=BIGINT
spring.shardingsphere.sharding.default-key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.default-key-generator.algorithm-expression=SNOWFLAKE_HASH(id, 12)
spring.shardingsphere.sharding.default-key-generator.matrix-handling-type=SHARDING_DEFAULT
# 踩行為表配置
spring.shardingsphere.sharding.tables.dislike_action.actual-data-nodes=action-ds0.dislike_action_$->{0..7},action-ds1.dislike_action_$->{8..15}
# user_id 為分表分片鍵
spring.shardingsphere.sharding.tables.dislike_action.table-strategy.inline.sharding-column=user_id
# 根據 user_id 以 16 取模,進行分表
spring.shardingsphere.sharding.tables.dislike_action.table-strategy.inline.algorithm-expression=dislike_action_$->{Math.abs(user_id.hashCode())  % 16}
# user_id 為分庫分片鍵
spring.shardingsphere.sharding.tables.dislike_action.database-strategy.inline.sharding-column=user_id
# 根據 user_id 以 16 取模后除8 ,進行分庫
spring.shardingsphere.sharding.tables.dislike_action.database-strategy.inline.algorithm-expression=action-ds$->{Math.floorDiv((Math.abs(user_id.hashCode())  % 16) , 8)}
spring.shardingsphere.sharding.tables.like_action.actual-data-nodes=action-ds0.like_action_$->{0..7},action-ds1.like_action_$->{8..15}
spring.shardingsphere.sharding.tables.like_action.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.like_action.table-strategy.inline.algorithm-expression=like_action_$->{Math.abs(user_id.hashCode())  % 16}
spring.shardingsphere.sharding.tables.like_action.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.like_action.database-strategy.inline.algorithm-expression=action-ds$->{Math.floorDiv((Math.abs(user_id.hashCode())  % 16) , 8)}
# 計數表配置
spring.shardingsphere.sharding.tables.dislike_target_count.actual-data-nodes=count-ds0.dislike_target_count_$->{0..7},count-ds1.dislike_target_count_$->{8..15}
# target_id 為分表分片鍵
spring.shardingsphere.sharding.tables.dislike_target_count.table-strategy.inline.sharding-column=target_id
# 根據 target_id 以 16 取模,進行分表
spring.shardingsphere.sharding.tables.dislike_target_count.table-strategy.inline.algorithm-expression=dislike_target_count_$->{Math.abs(target_id.hashCode())  % 16}
# target_id 為分庫分片鍵
spring.shardingsphere.sharding.tables.dislike_target_count.database-strategy.inline.sharding-column=target_id
# 根據 target_id 以 16 取模后除8 ,進行分庫
spring.shardingsphere.sharding.tables.dislike_target_count.database-strategy.inline.algorithm-expression=count-ds$->{Math.floorDiv((Math.abs(target_id.hashCode()) % 16), 8)}
spring.shardingsphere.sharding.tables.like_target_count.actual-data-nodes=count-ds0.like_target_count_$->{0..7},count-ds1.like_target_count_$->{8..15}
spring.shardingsphere.sharding.tables.like_target_count.table-strategy.inline.sharding-column=target_id
spring.shardingsphere.sharding.tables.like_target_count.table-strategy.inline.algorithm-expression=like_target_count_$->{Math.abs(target_id.hashCode()) % 16}
spring.shardingsphere.sharding.tables.like_target_count.database-strategy.inline.sharding-column=target_id
spring.shardingsphere.sharding.tables.like_target_count.database-strategy.inline.algorithm-expression=count-ds$->{Math.floorDiv((Math.abs(target_id.hashCode()) % 16), 8)}
# 打印 SQL 配置(可選)
spring.shardingsphere.props.sql.show=true

在雪花算法情況下,尾數會變的極度不均勻,所以在進行計算之前,通常先執行 hashCode 在進行取模操作。

4.5.3. 分庫分表效果

啟動應用程序,控制臺輸出 sharding 相關配置,具體如下:

defaultKeyGenerator:
  column: id
  type: SNOWFLAKE
tables:
  dislike_action:
    actualDataNodes: action-ds0.dislike_action_$->{0..7},action-ds1.dislike_action_$->{8..15}
    databaseStrategy:
      inline:
        algorithmExpression: action-ds$->{Math.floorDiv((Math.abs(user_id.hashCode())  % 16) , 8)}
        shardingColumn: user_id
    logicTable: dislike_action
    tableStrategy:
      inline:
        algorithmExpression: dislike_action_$->{Math.abs(user_id.hashCode()) % 16}
        shardingColumn: user_id
  like_action:
    actualDataNodes: action-ds0.like_action_$->{0..7},action-ds1.like_action_$->{8..15}
    databaseStrategy:
      inline:
        algorithmExpression: action-ds$->{Math.floorDiv((Math.abs(user_id.hashCode())  % 16) , 8)}
        shardingColumn: user_id
    logicTable: like_action
    tableStrategy:
      inline:
        algorithmExpression: like_action_$->{Math.abs(user_id.hashCode())  % 16}
        shardingColumn: user_id
  dislike_target_count:
    actualDataNodes: count-ds0.dislike_target_count_$->{0..7},count-ds1.dislike_target_count_$->{8..15}
    databaseStrategy:
      inline:
        algorithmExpression: count-ds$->{Math.floorDiv((Math.abs(target_id.hashCode()) % 16), 8)}
        shardingColumn: target_id
    logicTable: dislike_target_count
    tableStrategy:
      inline:
        algorithmExpression: dislike_target_count_$->{Math.abs(target_id.hashCode())  % 16}
        shardingColumn: target_id
  like_target_count:
    actualDataNodes: count-ds0.like_target_count_$->{0..7},count-ds1.like_target_count_$->{8..15}
    databaseStrategy:
      inline:
        algorithmExpression: count-ds$->{Math.floorDiv((Math.abs(target_id.hashCode()) % 16), 8)}
        shardingColumn: target_id
    logicTable: like_target_count
    tableStrategy:
      inline:
        algorithmExpression: like_target_count_$->{Math.abs(target_id.hashCode()) % 16}
        shardingColumn: target_id

在 Swagger UI 中操作點贊,控制臺輸出如下:

Logic SQL: select dislikeact0_.id as id1_0_, dislikeact0_.create_time as create_t2_0_, dislikeact0_.delete_time as delete_t3_0_, dislikeact0_.update_time as update_t4_0_, dislikeact0_.vsn as vsn5_0_, dislikeact0_.status as status6_0_, dislikeact0_.target_id as target_i7_0_, dislikeact0_.target_type as target_t8_0_, dislikeact0_.user_id as user_id9_0_ from dislike_action dislikeact0_ where dislikeact0_.user_id=? and dislikeact0_.target_type=?
Actual SQL: action-ds0 ::: select dislikeact0_.id as id1_0_, dislikeact0_.create_time as create_t2_0_, dislikeact0_.delete_time as delete_t3_0_, dislikeact0_.update_time as update_t4_0_, dislikeact0_.vsn as vsn5_0_, dislikeact0_.status as status6_0_, dislikeact0_.target_id as target_i7_0_, dislikeact0_.target_type as target_t8_0_, dislikeact0_.user_id as user_id9_0_ from dislike_action_0 dislikeact0_ where dislikeact0_.user_id=? and dislikeact0_.target_type=? ::: [2707692781417059328, Test]

其中:

  • Logic SQL:邏輯 SQL 中的表為 dislike_action
  • Actual SQL:實際執行的 SQL 表為 dislike_action_0,數據庫為 action-ds0

5. 項目信息

項目地址見:https://gitee.com/litao851025/lego/tree/master/services/like

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2015-06-24 15:35:54

2015-05-28 16:11:07

互聯網+

2022-06-09 08:01:43

秒殺系統互聯網架構

2018-08-15 09:02:59

產業互聯網工業互聯網物聯網

2014-01-15 14:35:35

云計算

2017-08-03 16:37:35

互聯網法院司法

2015-10-08 15:20:34

互聯網物聯網

2012-06-26 13:18:23

互聯網公社

2011-08-19 11:33:32

2015-09-22 09:17:33

互聯網發展史

2015-10-30 17:50:18

互聯網金融

2014-08-12 14:01:19

SDNICNCDN

2020-04-17 14:37:09

大數據工業互聯網技術

2019-04-04 15:01:03

2009-02-20 09:02:42

谷歌互聯網溫頓·瑟夫

2014-03-19 16:11:04

移動互聯網的顛覆和延伸

2015-03-25 18:31:20

互聯網+

2015-12-08 09:04:00

2013-03-08 09:41:06

宜搜移動互聯網洗腦

2023-07-13 15:26:27

無人機互聯網
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久国产精品一区 | 日韩网站免费观看 | 永久av| 欧洲成人 | 精品国产区 | 亚洲天堂999 | 亚洲精品一区二区久 | 免费国产视频在线观看 | 精品三区| 欧美无乱码久久久免费午夜一区 | 亚洲精品456 | 成人亚洲精品 | 国产婷婷在线视频 | 亚洲欧美在线视频 | 欧美性猛交一区二区三区精品 | 成人1区 | 国产在线永久免费 | 天天躁日日躁狠狠躁白人 | 欧美成人精品二区三区99精品 | 欧美日本免费 | 国产精品久久久久久久久免费相片 | 色网站入口 | 中文字幕成人在线 | 成人a免费 | 天天插天天操 | 欧美一二区 | 国产情品 | 国产精品区二区三区日本 | 天天草天天爱 | 国产成人午夜高潮毛片 | 成在线人视频免费视频 | 二区国产| 99视频免费在线观看 | 少妇性l交大片免费一 | 日一区二区 | 免费在线看黄视频 | 91在线视频免费观看 | 日韩欧美精品一区 | 国产精品视频久久久久久 | 久久久福利 | 欧美在线视频网 |