精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

聊聊 SaaS 多租戶系統數據隔離實現方案

云計算 SaaS
不同角色只能看到不同數據,部門經理只能看到自己部門的數據,小組長只能看到自己小組的數據,這些實現邏輯套路都可以模仿多租戶插件的方式進行優雅實現,這也是我后面有時間想研究的,后續會再出一篇數據權限的實現方案總結。

開發過SaaS系統平臺的小伙伴一定對多租戶這個概念不陌生,簡單來說一個租戶就是一個公司客戶,多個租戶共用同一個SaaS系統,一旦SaaS系統不可用,那么所有的租戶都不可用。你可以這么理解SaaS系統就像一棟大樓,而租戶就是大樓里面租辦公樓層的公司,平時每家公司做著自己的業務,互不干擾,但是一旦大樓的電梯壞了,那么影響到的就是所有的公司。

多租戶問題,其是一種架構設計方式,就是在一臺或者一組服務器上運行的SaaS系統,可以為多個租戶(客戶)提供服務,目的是為了讓多個租戶在互聯網環境下使用同一套程序,且保證租戶間的數據隔離。從這種架構設計的模式上,不難看出來,多租戶架構的重點就是同一套程序下多個租戶數據的隔離。由于租戶數據是集中存儲的,所以要實現數據的安全性,就是看能否實現對租戶數據的隔離,防止租戶數據不經意或被他人惡意地獲取和篡改。在講多租戶數據隔離實現之前,先來看看什么是SaaS系統。

什么是SaaS系統?

SaaS平臺是運營saas軟件的平臺。SaaS提供商為企業搭建信息化所需要的所有網絡基礎設施及軟件、硬件運作平臺,并負責所有前期的實施、后期的維護等一系列服務,租戶(企業)無需購買軟硬件、建設機房、招聘IT人員,即可通過互聯網使用信息系統。SaaS 是一種軟件布局模型,其應用專為網絡交付而設計,便于用戶通過互聯網托管、部署及接入。

簡單來說就是租戶給SaaS平臺付租金就能使用平臺提供的功能服務,當下比較典型就是各種云平臺、云服務廠商。

多租戶數據隔離架構設計

目前saas多租戶系統的數據隔離有三種架構設計,即為每個租戶提供獨立的數據庫、獨立的表空間、按字段區分租戶,每種方案都有其各自的適用情況。

一個租戶獨立一個數據庫

一個租戶獨立使用一個數據庫,那就意味著我們的SaaS系統需要連接多個數據庫,這種實現方案其實就和分庫分表架構設計是一樣的,好處就是數據隔離級別高、安全性好,畢竟一個租戶單用一個數據庫,但是物理硬件成本,維護成本也變高了。

獨立的表空間

這種方案的實現方式,就是所有租戶共用一個數據庫系統,但是每個租戶在數據庫系統中擁有一個獨立的表空間。

按租戶id字段隔離租戶

這種方案是多租戶方案中最簡單的數據隔離方法,即在每張表中都添加一個用于區分租戶的字段(如tenant_id或org_id啥的)來標識每條數據屬于哪個租戶,當進行查詢的時候每條語句都要添加該字段作為過濾條件,其特點是所有租戶的數據全都存放在同一個表中,數據的隔離性是最低的,完全是通過字段來區分的,很容易把數據搞串或者誤操作。

三種數據隔離架構設計的對比如下:

隔離方案

成本

支持租戶數量

優點

缺點

獨立數據庫系統

數據隔離級別高,安全性,可以針對單個租戶開發個性化需求

數據庫獨立安裝,物理成本和維護成本都比較高

獨立的表空間

較多

提供了一定程度的邏輯數據隔離,一個數據庫系統可支持多個租戶

數據庫管理比較困難,表繁多,同時數據修復稍復雜

按租戶id字段區分

維護和購置成本最低,每個數據庫能夠支持的租戶數量最多

隔離級別最低,安全性也最低

大部分公司都是采用第三種:按租戶id字段隔離租戶架構設計實現多租戶數據隔離的。接下來我們就來看看代碼層面怎么實現多租戶數據隔離的。關注公眾號:碼猿技術專欄,回復關鍵詞:1111 獲取阿里內部Java性能調優手冊!

mybatis-plus優雅實現多租戶數據權限隔離

上面我們說過按租戶id字段隔離租戶這種方式就是在獲取數據的時候對每一條SQL語句添加租戶id作為過濾條件來隔離租戶數據的。但是這樣意味著每個查詢SQL都必須加上租戶id這個過濾條件,如果漏加就意味著會查詢出不同租戶的數據,這是絕對不允許的,同時每個查詢接口都需要手動設置過濾條件,重復勞動,一點都不夠優雅。這時候就不得不說說mybatis-plus的多租戶插件了,看看它如何優雅實現多租戶隔離的?再講述之前,我們先思考一下如何優雅實現數據隔離?首先我們要求每一條SQL都加上租戶id這個過濾條件,這意味著我們需要解析原始SQL在合適的地方加上租戶id過濾條件,我們知道mybatis提供擴展點就是攔截器,可以對SQL語句處理前后進行增強邏輯,分頁插件就是這么做的,所以我們這里要增強SQL自然也是這樣,接下來我們就來看看mybatis-plus多租戶插件是怎么實現多租戶數據隔離的,插件官網介紹地址:https://www.baomidou.com/pages/aef2f2/#tenantlineinnerinterceptor,該攔截器部分源碼如下:

public class TenantLineInnerInterceptor extends JsqlParserSupport implements InnerInterceptor {
    // 多租戶處理器
    private TenantLineHandler tenantLineHandler;

    // 改SQL,添加多租戶id條件
    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
        if (!InterceptorIgnoreHelper.willIgnoreTenantLine(ms.getId())) {
            MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
            mpBs.sql(this.parserSingle(mpBs.sql(), (Object)null));
        }
    }

    public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {
        MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh);
        MappedStatement ms = mpSh.mappedStatement();
        SqlCommandType sct = ms.getSqlCommandType();
        if (sct == SqlCommandType.INSERT || sct == SqlCommandType.UPDATE || sct == SqlCommandType.DELETE) {
            if (InterceptorIgnoreHelper.willIgnoreTenantLine(ms.getId())) {
                return;
            }

            MPBoundSql mpBs = mpSh.mPBoundSql();
            mpBs.sql(this.parserMulti(mpBs.sql(), (Object)null));
        }

    }
  
  // 礙于篇幅問題,下面省略的代碼就是繼承抽象類JsqlParserSupport解析SQL然后添加多租戶id條件的,可以自行查看源碼
  ......
}

接著我們來看看處理器TenantLineHandler,這是一個接口,需要我們提供自定義實現,指定多租戶相關配置:

public class TenantDatabaseHandler implements TenantLineHandler {
    private final Set<String> ignoreTables = new HashSet<>();

    public TenantDatabaseHandler(TenantProperties properties) {
        // 將配置文件配置的忽略表名同步大小寫,適配不同寫法
        properties.getIgnoreTables().forEach(table -> {
            ignoreTables.add(table.toLowerCase());
            ignoreTables.add(table.toUpperCase());
        });
    }

    /**
     * 獲取租戶字段名
     * <p>
     * 默認字段名叫: tenant_id,我這里使用org_id
     *
     * @return 租戶字段名
     */
    @Override
     public String getTenantIdColumn() {
        return "org_id";
    }


    @Override
    public Expression getTenantId() {
        // 這里通過登錄信息上下文返回租戶id給多租戶攔截器增強SQL使用
        return new LongValue(RequestUserHolder.getCurrentUser().getOrgId());
    }

    @Override
    public boolean ignoreTable(String tableName) {
        // 忽略多租戶的表
        return CollUtil.contains(ignoreTables, tableName);
    }
}

配置屬性如下:

@ConfigurationProperties(prefix = "ptc.tenant")
@Data
public class TenantProperties {


    /**
     * 全局控制是否開啟多租戶功能
     */
    private Boolean enable = Boolean.TRUE;

    /**
     * 需要忽略多租戶的表
     *
     * 即默認所有表都開啟多租戶的功能,所以記得添加對應的 tenant_id 字段喲
     */
    private Set<String> ignoreTables = Collections.emptySet();
}

接下來注入攔截器插件即可:

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(TenantProperties properties) {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 必須保證多租戶插件在分頁插件之前,這個是 MyBatis-plus 的規定
        if (properties.getEnable()) {
            mybatisPlusInterceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantDatabaseHandler(properties)));
        }
        // 分頁插件
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }

使用示例如下:這里提供了一個常見的案例:用戶和角色關聯查詢的SQL:getUserList()

<select id="getUserList" resultType="com.plasticene.textile.entity.User">
        select u.* from user u
        left join user_role r on u.id = r.user_id
        <where>
            <if test="query.status != null">
                and u.status = #{query.status}
            </if>
            <if test="query.roleId != null">
                and r.role_id = #{query.roleId}
            </if>
            <if test="query.keyword != null">
                and ((u.name like concat('%',#{query.keyword},'%')) or (u.mobile like concat(#{query.keyword},'%')))
            </if>
            <if test="query.startEntryTime != null">
                and u.entry_time >= #{query.startEntryTime}
            </if>
            <if test="query.endEntryTime != null">
                <![CDATA[ and u.entry_time <= #{query.endEntryTime}]]>
            </if>

        </where>
        group by u.id
        order by u.id desc
    </select>

啟動項目,先登錄之后使用token掉接口執行下面代碼邏輯:

public PageResult<UserDTO> getList(UserQuery query) {
        Page<UserDTO> page = new Page<>(query.getPageNo(), query.getPageSize());
        List<User> userList = userDAO.getUserList(page, query);
        List<UserDTO> userDTOS = toUserDTOList(userList);
        return new PageResult<>(userDTOS, page.getTotal(), page.getPages());
    }

查看控制臺發現:

[1658720355293990912] [DEBUG] [2023-05-17 14:25:25.504] [http-nio-16688-exec-1@23652]  com.plasticene.textile.dao.UserDAO.getUserList debug : ==>  Preparing: SELECT u.* FROM user u LEFT JOIN user_role r ON u.id = r.user_id AND r.org_id = 3 WHERE u.org_id = 3 GROUP BY u.id ORDER BY u.id DESC LIMIT ?
[1658720355293990912] [DEBUG] [2023-05-17 14:25:25.505] [http-nio-16688-exec-1@23652]  com.plasticene.textile.dao.UserDAO.getUserList debug : ==> Parameters: 20(Long)

user表u加上u.org_id=3這個多租戶過濾條件,user_role也同樣加上了,說明多租戶插件起作用了。

當然如果想忽略掉表user,我們只需要在配置文件如下配置即可:

ptc:
  tenant:
    ignore-tables: user

這樣user表u就不會再加上u.org_id=3這個多租戶過濾條件,但是這里有一個細節需要注意,由于user在MySQL中是關鍵字,所以我有時候為了規范書寫SQL,會按照如下編寫:

select u.* from `user` u
        left join user_role r on u.id = r.user_id

這時候你會發現上面配置的忽略表user不起作用,還是會加上u.org_id=3這個多租戶過濾條件,跟源碼才發現我們上面自定義的多租戶處理器TenantLineHandler只對表名進行了大小寫適配,然而這里SQL解析出來的表名是: **user**,所以匹配不到配置不起作用。

當然我們有可能需要針對單一SQL語句不加多租戶過濾條件,可以使用@InterceptorIgnore注解:

public interface UserDAO extends BaseMapperX<User> {

    @InterceptorIgnore(tenantLine = "true")
    List<User> getUserList(IPage<UserDTO> userPage, @Param("query") UserQuery query);
}

這樣調用getUserList()不再會加多租戶過濾條件了。

通過上面我們知道了這個多租戶插件其實就是通過解析SQL,然后進行拼接多租戶id過濾條件來實現SQL增強從而做到數據隔離,解析SQL的框架叫:JSqlParser,官方文檔:https://github.com/JSQLParser/JSqlParser/wiki,之前我總結過一篇關于 Druid解析動態SQL。Druid也可以解析SQL,我們都知道SQL語句會生成語法樹,兩者對SQL解析的孰強孰弱(特別是復雜SQL)不得而知,可以自行驗證對比,我這里給出一個JSqlParser解析出錯的情況,把上面的SQL語句user_role r 改為 user_role ur

select u.* from user u
        left join user_role ur on u.id = ur.user_id

按照上面一樣調用執行getUserList(), 會報解析錯誤:

Caused by: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Failed to process, Error SQL: select u.* from user u
left join user_role ur on u.id = ur.user_id
group by u.id
order by u.id desc
at com.baomidou.mybatisplus.core.toolkit.ExceptionUtils.mpe(ExceptionUtils.java:39)
at com.baomidou.mybatisplus.extension.parser.JsqlParserSupport.parserSingle(JsqlParserSupport.java:52)
at com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor.beforeQuery(TenantLineInnerInterceptor.java:65)
at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:78)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:62)
at com.sun.proxy.$Proxy178.query(Unknown Source)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:151)
... 101 common frames omitted
Caused by: net.sf.jsqlparser.parser.ParseException: Encountered unexpected token: "ur" <K_ISOLATION>
at line 2, column 29.

我在mybatis-plus的官方提了一個issue:https://github.com/baomidou/mybatis-plus/issues/5086,也得到官方維護者的迅速回應說是JSqlParser解析的問題,不是mybatis-plus的問題~~~,給出的建議就是把別名ur改成別的,或者升級到JSqlParser的最新版本。

4.總結

至此,我們對多租戶系統數據隔離實現方案,架構設計,以及如何優雅實現全局操作數據隔離都講完了,同時也對mybati-plus的多租戶插件實現原理和源碼流程套路進行了淺析,也對實際應用案例中進行了舉證并闡述了相關細節點。當然數據權限不止停留在租戶(公司)層面上面,大多數系統的數據權限會按照業務組織架構角色來控制,數據權限其套路和根據角色判斷菜單權限一回事。由于數據權限通常與公司業務相關,比較個性化,每家公司業務組織架構不盡相同,所以實際開發項目的數據權限隔離還需要大家按實際需求進行修改,但總的來說我們可以模仿多租戶隔離實現方式,比如說一個業務系統組織架構有公司(org_id),公司下有多個部門(dept_id),部門下有多個團隊分組(team_id),團隊下有多個人員(user_id)。不同角色只能看到不同數據,部門經理只能看到自己部門的數據,小組長只能看到自己小組的數據,這些實現邏輯套路都可以模仿多租戶插件的方式進行優雅實現,這也是我后面有時間想研究的,后續會再出一篇數據權限的實現方案總結。

責任編輯:武曉燕 來源: 碼猿技術專欄
相關推薦

2025-05-14 03:00:00

2015-08-12 15:46:02

SaaS多租戶數據存儲

2023-12-14 12:26:16

SaaS數據庫方案

2020-05-14 18:04:20

Spring BootSaaS平臺

2024-03-28 09:46:50

2025-08-28 07:36:48

2023-11-06 08:26:11

Spring微服務架構

2020-09-15 07:00:00

SaaS架構架構

2015-04-02 11:04:27

云應用SaaSOFBIZ

2025-01-09 14:39:40

2024-05-28 08:17:54

2019-03-22 14:38:03

容器安全隔離

2023-12-15 07:34:56

分布式數據庫數據庫租戶軟件架構

2025-02-18 16:27:01

2023-11-29 08:35:28

群多租戶ES運維

2025-09-29 02:00:00

2015-11-12 09:58:45

多租戶SaaS軟件架構設計

2021-05-17 11:47:41

多租戶系統私有化

2020-10-16 08:57:51

云平臺之多租戶的實踐

2023-10-11 08:09:53

事務隔離級別
點贊
收藏

51CTO技術棧公眾號

中文字幕 自拍| 在线成人免费网站| 在线天堂中文资源最新版| 国产又大又长又粗又黄| 午夜欧美视频在线观看| 成人美女黄网站| 久久精品一二三四| 亚洲免费精彩视频| 欧美日韩一区二区高清| 久久伊人成人网| 不卡av电影院| 日本vs亚洲vs韩国一区三区二区 | 亚洲国产精品电影在线观看| 欧美一级精品片在线看| 天天综合天天做| 欧美在线影院在线视频| 久久国产精品色婷婷| 嫩草在线播放| 五月天激情图片| 91精品国产日韩91久久久久久| 深爱激情综合| 成人午夜视频在线播放| 91久久久久久久久久久久久| 久久久久久久久久久久久女国产乱| 日韩在线免费播放| 一本久道久久综合| 欧美撒尿777hd撒尿| 欧美限制电影| 日韩人妻精品中文字幕 | 五月婷婷欧美激情| 国产精品成人观看视频国产奇米| 91视频在线观看免费| h片精品在线观看| 天天干天天色天天干| 亚洲精品久久久久中文字幕二区| 一区二区三区导航| 日韩在线无毛| 日本人视频jizz页码69| 久久精品国产一区二区三区 | 亚洲第一页av| 欧美最近摘花xxxx摘花| 成人高清av在线| 校园春色亚洲| 91精品少妇一区二区三区蜜桃臀| 97超碰资源| 亚洲成av人片一区二区梦乃 | 中国一级大黄大黄大色毛片| 精品国产一区二区三区四区四 | 美女精品视频在线| 男女啊啊啊视频| 蜜桃视频在线观看91| 91精品国产色综合久久不卡电影| 日韩亚洲国产欧美| 国产区高清在线| 亚洲黄色片免费| 青青草一区二区| 一区二区三区产品免费精品久久75| 亚洲一二av| 国产一级生活片| 免费99视频| 亚洲成人久久网| 国产精品一区二区在线观看网站| 美脚恋feet久草欧美| 性生交大片免费全黄| 欧美日韩一区二区三| 欧美不卡在线视频| 日本亚洲天堂网| 搞黄网站在线看| 国产午夜精品久久久久久久久| 国产精品嫩草在线观看| 欧美日韩免费不卡视频一区二区三区| 99在线|亚洲一区二区| 在线观看wwwxxxx| 男人晚上看的视频| 日韩欧美99| 亚洲美女av黄| 成人在线视频一区| 久久男人av| 一级黄色片在线播放| 麻豆传传媒久久久爱| 91色中文字幕| 精品国产精品网麻豆系列| 99精品久久免费看蜜臀剧情介绍| 日韩黄色网络| av黄色在线观看| 久久午夜无码鲁丝片| 热99这里只有精品| 久久福利视频一区二区| 日韩福利影视| 色窝窝无码一区二区三区成人网站| 国产性猛交96| 亚洲一区二区免费视频软件合集| 久久躁日日躁aaaaxxxx| 午夜影视日本亚洲欧洲精品| 白嫩亚洲一区二区三区| 青青草视频免费在线观看| 东方伊人免费在线观看| 久久久久久久中文| 国产有码在线一区二区视频| 亚洲黄色有码视频| 亚洲精品久久嫩草网站秘色| 麻豆九一精品爱看视频在线观看免费| 成人精品电影在线| 精品人妻aV中文字幕乱码色欲| 美女被到爽高潮视频| 日本一级黄视频| 成人免费视频在线观看超级碰| 日韩成人在线视频| 亚洲一级二级三级| 麻豆国产欧美日韩综合精品二区 | 人妻一区二区三区四区| 午夜精品一区二区三级视频| 成年人网站免费看| 亚洲综合欧美综合| 欧美一级欧美一级| 精品国产综合久久| 国产v综合ⅴ日韩v欧美大片| 亚洲成人黄色影院| 99成人在线| 久久gogo国模啪啪裸体| va婷婷在线免费观看| av不卡中文字幕| 2022国产精品| 高清不卡日本v二区在线| 免费久久一级欧美特大黄| 97av中文字幕| 中文字幕日韩精品无码内射| 国产精品自产拍在线观看中文 | 中文字幕乱伦视频| 国产乱码精品一区二区三区五月婷| 国模精品一区二区三区| free性欧美hd另类精品| 欧美日韩亚洲网| 国内外成人免费在线视频| 中国av一区| 欧美精品videos另类日本| 特级西西444www高清大视频| 91女人视频在线观看| 丰满的少妇愉情hd高清果冻传媒| 色综合视频一区二区三区日韩| 亚洲美女av黄| 久久国产视频精品| av中文字幕不卡| www.av蜜桃| 99精品国产高清一区二区麻豆| 欧美久久精品午夜青青大伊人| 国产精品午夜一区二区| 久久精品一级爱片| 青青草原av在线播放| 久久大胆人体视频| 97在线视频一区| 婷婷开心激情网| 午夜激情一区二区三区| 日韩高清在线一区二区| 综合激情网站| 成人免费高清完整版在线观看| 欧美天天影院| 337p亚洲精品色噜噜| www.av欧美| 亚洲美洲欧洲综合国产一区| 精品不卡在线| 韩日毛片在线观看| 亚洲欧美国产另类| 国模私拍一区二区| 国产精品久久久久影院老司| 亚洲美女性囗交| 一区二区电影| 99在线观看| heyzo高清国产精品| 亚洲精品久久久一区二区三区| 国产成人亚洲欧洲在线| 久久综合狠狠综合| 欧美在线一区视频| 亚洲+变态+欧美+另类+精品| 国产成人午夜视频网址| 日本激情视频在线观看| 欧美久久一二三四区| 欧美人妻精品一区二区三区 | 福利一区福利二区微拍刺激| 视频免费在线观看| 日日夜夜精品免费视频| 日韩精品无码一区二区三区| 自拍偷拍亚洲| 欧美精品亚州精品| 亚洲色图 校园春色| 日韩欧美在线播放| 91麻豆免费视频网站| 久久电影网电视剧免费观看| 男人的天堂avav| 美腿丝袜亚洲图片| 国产精品欧美久久久| 四虎av在线| 国产亚洲精品久久久| 国产99对白在线播放| 日韩欧美国产免费播放| 免费成年人视频在线观看| 97精品国产露脸对白| 六月丁香婷婷在线| 一精品久久久| 日韩免费一区二区三区| 凹凸av导航大全精品| 国产精品成人观看视频国产奇米| 免费电影网站在线视频观看福利| 亚洲社区在线观看| 俄罗斯嫩小性bbwbbw| 欧美午夜www高清视频| 精品一区在线观看视频| 国产午夜亚洲精品理论片色戒| 免费高清视频在线观看| 久久精品动漫| 亚洲国产精品无码观看久久| 欧美3p在线观看| 久久久久久亚洲精品不卡4k岛国 | 久久99精品久久久久久野外| 日韩欧美国产午夜精品| 国产美女www爽爽爽| 亚洲激情网站免费观看| 精品久久久久一区二区| 久久精品99久久久| 国产精品乱码久久久久| 亚洲天堂成人| 美国av在线播放| 国产精品亚洲二区| 97超级在线观看免费高清完整版电视剧| 88xx成人永久免费观看| 97在线观看视频| 色婷婷av在线| 欧美成人激情图片网| wwwww在线观看免费视频| 精品视频—区二区三区免费| 99久久国产免费| 91国在线观看| 中文字幕69页| 午夜精品在线视频一区| 麻豆亚洲av成人无码久久精品| 中文字幕亚洲在| 国产18无套直看片| 国产日韩欧美亚洲| 在线不卡av电影| 久久综合色天天久久综合图片| 亚洲自拍偷拍精品| 成人午夜视频网站| 亚洲av无一区二区三区久久| 久久99这里只有精品| 日韩一级理论片| 日韩电影网1区2区| caopor在线视频| 日韩av在线播放中文字幕| 99久久激情视频| 久久激情一区| 熟女少妇精品一区二区| 日韩在线一区二区| 婷婷激情四射五月天| 视频一区二区三区在线| av动漫在线观看| 久久综合亚州| xxxx一级片| 免费xxxx性欧美18vr| 污污网站免费看| 麻豆精品一区二区| 日韩在线不卡一区| 国内成人免费视频| 91在线第一页| 成人av在线播放网址| 国产精品手机在线观看| 91麻豆123| 成人片黄网站色大片免费毛片| 国产免费成人在线视频| 青花影视在线观看免费高清| 伊人夜夜躁av伊人久久| 精品无码人妻一区二区三区品| 五月婷婷久久丁香| 黄色片视频免费| 欧美熟乱第一页| av中文字幕免费在线观看| 精品国产乱码久久| 国产香蕉在线| 久久精品国产亚洲精品| av软件在线观看| 97热在线精品视频在线观看| 高清av一区二区三区| 亚洲free嫩bbb| 久久悠悠精品综合网| 日韩欧美视频一区二区三区四区| 欧美1级片网站| 国产精品无码av在线播放| 亚洲欧美不卡| 日韩精品视频网址| 97久久久精品综合88久久| 亚洲国产精品一区二区久久hs| 亚洲综合色网站| 青青草成人av| 欧美精品vⅰdeose4hd| 蜜臀av中文字幕| 亚洲精品大尺度| 免费在线观看av网站| 亚洲97在线观看| **国产精品| 精品伦理一区二区三区| 欧美一区二区麻豆红桃视频| 亚洲人一区二区| 亚洲精品在线二区| 那种视频在线观看| 成人综合婷婷国产精品久久 | 美女撒尿一区二区三区| 伊人久久视频| 99久久一区三区四区免费| 香蕉成人app| 一本一生久久a久久精品综合蜜| 欧美网站在线| 亚洲va在线va天堂va偷拍| 99热国产精品| 老熟妇高潮一区二区三区| 欧美激情中文不卡| 影音先锋亚洲天堂| 欧美一区二区三级| jizz在线观看中文| 97香蕉久久超级碰碰高清版| 国产在线不卡一区二区三区| 欧美xxxx黑人又粗又长密月| 国产在线成人| 视频区 图片区 小说区| 中文字幕av一区二区三区高| 久草视频中文在线| 色婷婷av一区二区三区之一色屋| 国产黄色一级大片| 最近2019中文免费高清视频观看www99| 黄毛片在线观看| 国产欧美日韩在线播放| 欧美网站在线| 少妇高潮一69aⅹ| 国产精品乱码一区二三区小蝌蚪| 欧美a视频在线观看| 日韩成人av网| 好吊日av在线| 亚洲一区二区久久久久久| 欧美成人自拍| 国产二区视频在线播放| 99这里只有精品| 最新一区二区三区| 欧美一区二区三区免费观看视频| 天堂аⅴ在线地址8| 国产精品精品久久久久久| 国产欧美一区| 日日碰狠狠添天天爽超碰97| av电影天堂一区二区在线 | 欧美色视频日本高清在线观看| 黄色www视频| 久久91精品国产91久久跳| 日韩黄色av| 国产黄色激情视频| 成人黄色网址在线观看| 特级片在线观看| 日韩欧美中文字幕精品| 欧美hdxxxxx| 国产免费高清一区| 99精品久久久| 偷拍夫妻性生活| 精品视频色一区| 午夜在线免费观看视频| 91亚洲国产精品| 国产精品麻豆久久| 日本 片 成人 在线| 综合久久久久久| 国产免费叼嘿网站免费| 久久精品国产一区二区三区| 精品一区二区三区中文字幕视频| 黄色三级中文字幕| 国产福利一区二区三区视频| www.天天色| 亚洲日本中文字幕| 欧洲亚洲精品久久久久| 成人短视频在线观看免费| 成人小视频在线观看| 黄色一级视频免费看| 日韩在线观看视频免费| 136国产福利精品导航网址应用| av高清在线免费观看| 日本一区二区视频在线| 91麻豆视频在线观看| 久久激情视频免费观看| 日韩激情综合| 国产a级一级片| 中文字幕一区二区三区在线观看 | 亚洲美女www午夜| 成人福利av| 在线观看三级网站| 26uuu精品一区二区| 97成人在线观看| 97视频免费在线看| 日韩精品中文字幕第1页| 岛国精品一区二区三区| 色综合久久天天| 国产激情在线| 蜜桃视频日韩| 日本v片在线高清不卡在线观看| 久草资源在线视频| 亚洲天堂影视av| aiai久久| 色婷婷综合网站|