日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

深入理解 RocketMQ 廣播消費(fèi)

來(lái)源: 責(zé)編: 時(shí)間:2023-09-28 10:09:12 431觀看
導(dǎo)讀這篇文章我們聊聊廣播消費(fèi),因?yàn)閺V播消費(fèi)在某些場(chǎng)景下真的有奇效。筆者會(huì)從基礎(chǔ)概念、實(shí)現(xiàn)機(jī)制、實(shí)戰(zhàn)案例三個(gè)方面一一展開(kāi),希望能幫助到大家。1 基礎(chǔ)概念RocketMQ 支持兩種消息模式:集群消費(fèi)( Clustering )和廣播消費(fèi)( Broa

這篇文章我們聊聊廣播消費(fèi),因?yàn)閺V播消費(fèi)在某些場(chǎng)景下真的有奇效。筆者會(huì)從基礎(chǔ)概念、實(shí)現(xiàn)機(jī)制、實(shí)戰(zhàn)案例三個(gè)方面一一展開(kāi),希望能幫助到大家。Aaa28資訊網(wǎng)——每日最新資訊28at.com

1 基礎(chǔ)概念

RocketMQ 支持兩種消息模式:集群消費(fèi)( Clustering )和廣播消費(fèi)( Broadcasting )。Aaa28資訊網(wǎng)——每日最新資訊28at.com

集群消費(fèi):Aaa28資訊網(wǎng)——每日最新資訊28at.com

同一 Topic 下的一條消息只會(huì)被同一消費(fèi)組中的一個(gè)消費(fèi)者消費(fèi)。也就是說(shuō),消息被負(fù)載均衡到了同一個(gè)消費(fèi)組的多個(gè)消費(fèi)者實(shí)例上。Aaa28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Aaa28資訊網(wǎng)——每日最新資訊28at.com

廣播消費(fèi):Aaa28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)使用廣播消費(fèi)模式時(shí),每條消息推送給集群內(nèi)所有的消費(fèi)者,保證消息至少被每個(gè)消費(fèi)者消費(fèi)一次。Aaa28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Aaa28資訊網(wǎng)——每日最新資訊28at.com

2 源碼解析

首先下圖展示了廣播消費(fèi)的代碼示例。Aaa28資訊網(wǎng)——每日最新資訊28at.com

public class PushConsumer {    public static final String CONSUMER_GROUP = "myconsumerGroup";    public static final String DEFAULT_NAMESRVADDR = "localhost:9876";    public static final String TOPIC = "mytest";    public static final String SUB_EXPRESSION = "TagA || TagC || TagD";    public static void main(String[] args) throws InterruptedException, MQClientException {        // 定義 DefaultPushConsumer         DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(CONSUMER_GROUP);        // 定義名字服務(wù)地址        consumer.setNamesrvAddr(DEFAULT_NAMESRVADDR);        // 定義消費(fèi)讀取位點(diǎn)        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);        // 定義消費(fèi)模式        consumer.setMessageModel(MessageModel.BROADCASTING);        // 訂閱主題信息        consumer.subscribe(TOPIC, SUB_EXPRESSION);        // 訂閱消息監(jiān)聽(tīng)器        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {            try {                for (MessageExt messageExt : msgs) {                    System.out.println(new String(messageExt.getBody()));                }            }catch (Exception e) {                e.printStackTrace();            }            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;        });        consumer.start();        System.out.printf("Broadcast Consumer Started.%n");    }}

和集群消費(fèi)不同的點(diǎn)在于下面的代碼:Aaa28資訊網(wǎng)——每日最新資訊28at.com

consumer.setMessageModel(MessageModel.BROADCASTING);

接下來(lái),我們從源碼角度來(lái)看看廣播消費(fèi)和集群消費(fèi)有哪些差異點(diǎn) ?Aaa28資訊網(wǎng)——每日最新資訊28at.com

首先進(jìn)入 DefaultMQPushConsumerImpl 類的 start 方法 , 分析啟動(dòng)流程中他們兩者的差異點(diǎn):Aaa28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Aaa28資訊網(wǎng)——每日最新資訊28at.com

▍ 差異點(diǎn)1:拷貝訂閱關(guān)系Aaa28資訊網(wǎng)——每日最新資訊28at.com

private void copySubscription() throws MQClientException {    try {       Map<String, String> sub = this.defaultMQPushConsumer.getSubscription();       if (sub != null) {          for (final Map.Entry<String, String> entry : sub.entrySet()) {              final String topic = entry.getKey();              final String subString = entry.getValue();              SubscriptionData subscriptionData = FilterAPI.buildSubscriptionData(topic, subString);                this.rebalanceImpl.getSubscriptionInner().put(topic, subscriptionData);            }        }       if (null == this.messageListenerInner) {          this.messageListenerInner = this.defaultMQPushConsumer.getMessageListener();       }       // 注意下面的代碼 , 集群模式下自動(dòng)訂閱重試主題        switch (this.defaultMQPushConsumer.getMessageModel()) {           case BROADCASTING:               break;           case CLUSTERING:                final String retryTopic = MixAll.getRetryTopic(this.defaultMQPushConsumer.getConsumerGroup());                SubscriptionData subscriptionData = FilterAPI.buildSubscriptionData(retryTopic, SubscriptionData.SUB_ALL);                this.rebalanceImpl.getSubscriptionInner().put(retryTopic, subscriptionData);                break;            default:                break;        }    } catch (Exception e) {        throw new MQClientException("subscription exception", e);    }}

在集群模式下,會(huì)自動(dòng)訂閱重試隊(duì)列,而廣播模式下,并沒(méi)有這段代碼。也就是說(shuō)廣播模式下,不支持消息重試。Aaa28資訊網(wǎng)——每日最新資訊28at.com

▍ 差異點(diǎn)2:本地進(jìn)度存儲(chǔ)Aaa28資訊網(wǎng)——每日最新資訊28at.com

switch (this.defaultMQPushConsumer.getMessageModel()) {    case BROADCASTING:        this.offsetStore = new LocalFileOffsetStore(this.mQClientFactory, this.defaultMQPushConsumer.getConsumerGroup());        break;    case CLUSTERING:        this.offsetStore = new RemoteBrokerOffsetStore(this.mQClientFactory, this.defaultMQPushConsumer.getConsumerGroup());        break;    default:        break;}this.defaultMQPushConsumer.setOffsetStore(this.offsetStore);

我們可以看到消費(fèi)進(jìn)度存儲(chǔ)的對(duì)象是:LocalFileOffsetStore , 進(jìn)度文件存儲(chǔ)在如下的主目錄 /{用戶主目錄}/.rocketmq_offsets。Aaa28資訊網(wǎng)——每日最新資訊28at.com

public final static String LOCAL_OFFSET_STORE_DIR = System.getProperty(    "rocketmq.client.localOffsetStoreDir",    System.getProperty("user.home") + File.separator + ".rocketmq_offsets");

進(jìn)度文件是 /mqClientId/{consumerGroupName}/offsets.json 。Aaa28資訊網(wǎng)——每日最新資訊28at.com

this.storePath = LOCAL_OFFSET_STORE_DIR + File.separator + this.mQClientFactory.getClientId() + File.separator + this.groupName + File.separator + "offsets.json";

筆者創(chuàng)建了一個(gè)主題 mytest , 包含4個(gè)隊(duì)列,進(jìn)度文件內(nèi)容如下:Aaa28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Aaa28資訊網(wǎng)——每日最新資訊28at.com

消費(fèi)者啟動(dòng)后,我們可以將整個(gè)流程簡(jiǎn)化如下圖,并繼續(xù)整理差異點(diǎn):Aaa28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Aaa28資訊網(wǎng)——每日最新資訊28at.com

▍ 差異點(diǎn)3:負(fù)載均衡消費(fèi)該主題的所有 MessageQueueAaa28資訊網(wǎng)——每日最新資訊28at.com

進(jìn)入負(fù)載均衡抽象類 RebalanceImpl 的rebalanceByTopic方法 。Aaa28資訊網(wǎng)——每日最新資訊28at.com

private void rebalanceByTopic(final String topic, final boolean isOrder) {    switch (messageModel) {        case BROADCASTING: {            Set<MessageQueue> mqSet = this.topicSubscribeInfoTable.get(topic);            if (mqSet != null) {                boolean changed = this.updateProcessQueueTableInRebalance(topic, mqSet, isOrder);                // 省略代碼            } else {                log.warn("doRebalance, {}, but the topic[{}] not exist.", consumerGroup, topic);            }            break;        }        case CLUSTERING: {            Set<MessageQueue> mqSet = this.topicSubscribeInfoTable.get(topic);            List<String> cidAll = this.mQClientFactory.findConsumerIdList(topic, consumerGroup);            // 省略代碼            if (mqSet != null && cidAll != null) {                List<MessageQueue> mqAll = new ArrayList<MessageQueue>();                mqAll.addAll(mqSet);                Collections.sort(mqAll);                Collections.sort(cidAll);                AllocateMessageQueueStrategy strategy = this.allocateMessageQueueStrategy;                List<MessageQueue> allocateResult = null;                try {                     allocateResult = strategy.allocate(                            this.consumerGroup,                            this.mQClientFactory.getClientId(),                            mqAll,                            cidAll);                    } catch (Throwable e) {                        // 省略日志打印代碼                        return;                    }                Set<MessageQueue> allocateResultSet = new HashSet<MessageQueue>();                if (allocateResult != null) {                    allocateResultSet.addAll(allocateResult);                }                boolean changed = this.updateProcessQueueTableInRebalance(topic, allocateResultSet, isOrder);                //省略代碼            }            break;        }        default:            break;    }}

從上面代碼我們可以看到消息模式為廣播消費(fèi)模式時(shí),消費(fèi)者會(huì)消費(fèi)該主題下所有的隊(duì)列,這一點(diǎn)也可以從本地的進(jìn)度文件 offsets.json 得到印證。Aaa28資訊網(wǎng)——每日最新資訊28at.com

▍ 差異點(diǎn)4:不支持順序消息Aaa28資訊網(wǎng)——每日最新資訊28at.com

我們知道消費(fèi)消息順序服務(wù)會(huì)向 Borker 申請(qǐng)鎖 。消費(fèi)者根據(jù)分配的隊(duì)列 messageQueue ,向 Borker 申請(qǐng)鎖 ,如果申請(qǐng)成功,則會(huì)拉取消息,如果失敗,則定時(shí)任務(wù)每隔 20 秒會(huì)重新嘗試。Aaa28資訊網(wǎng)——每日最新資訊28at.com

if (MessageModel.CLUSTERING.equals(ConsumeMessageOrderlyService.this.defaultMQPushConsumerImpl.messageModel())) {    this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {        @Override        public void run() {            try {                ConsumeMessageOrderlyService.this.lockMQPeriodically();            } catch (Throwable e) {                log.error("scheduleAtFixedRate lockMQPeriodically exception", e);            }        }    }, 1000 * 1, ProcessQueue.REBALANCE_LOCK_INTERVAL, TimeUnit.MILLISECONDS);}

但是從上面的代碼,我們發(fā)現(xiàn)只有在集群消費(fèi)的時(shí)候才會(huì)定時(shí)申請(qǐng)鎖,這樣就會(huì)導(dǎo)致廣播消費(fèi)時(shí),無(wú)法為負(fù)載均衡的隊(duì)列申請(qǐng)鎖,導(dǎo)致拉取消息服務(wù)一直無(wú)法獲取消息數(shù)據(jù)。Aaa28資訊網(wǎng)——每日最新資訊28at.com

筆者修改消費(fèi)例子,在消息模式為廣播模式的場(chǎng)景下,將消費(fèi)模式從并發(fā)消費(fèi)修改為順序消費(fèi)。Aaa28資訊網(wǎng)——每日最新資訊28at.com

consumer.registerMessageListener((MessageListenerOrderly) (msgs, context) -> {    try {        for (MessageExt messageExt : msgs) {            System.out.println(new String(messageExt.getBody()));        }    }catch (Exception e) {        e.printStackTrace();    }    return ConsumeOrderlyStatus.SUCCESS;});

圖片圖片Aaa28資訊網(wǎng)——每日最新資訊28at.com

推送服務(wù)是一個(gè) TCP 服務(wù)(自定義協(xié)議),同時(shí)也是一個(gè)消費(fèi)者服務(wù),消息模式是廣播消費(fèi)。Aaa28資訊網(wǎng)——每日最新資訊28at.com

司機(jī)打開(kāi)司機(jī)端 APP 后,APP 會(huì)通過(guò)負(fù)載均衡和推送服務(wù)創(chuàng)建長(zhǎng)連接,推送服務(wù)會(huì)保存 TCP 連接引用 (比如司機(jī)編號(hào)和 TCP channel 的引用)。Aaa28資訊網(wǎng)——每日最新資訊28at.com

派單服務(wù)是生產(chǎn)者,將派單數(shù)據(jù)發(fā)送到 MetaQ ,  每個(gè)推送服務(wù)都會(huì)消費(fèi)到該消息,推送服務(wù)判斷本地內(nèi)存中是否存在該司機(jī)的 TCP channel , 若存在,則通過(guò) TCP 連接將數(shù)據(jù)推送給司機(jī)端。Aaa28資訊網(wǎng)——每日最新資訊28at.com

肯定有同學(xué)會(huì)問(wèn):假如網(wǎng)絡(luò)原因,推送失敗怎么處理 ?有兩個(gè)要點(diǎn):Aaa28資訊網(wǎng)——每日最新資訊28at.com

  1. 司機(jī)端 APP 定時(shí)主動(dòng)拉取派單信息;
  2. 當(dāng)推送服務(wù)沒(méi)有收到司機(jī)端的 ACK 時(shí) ,也會(huì)一定時(shí)限內(nèi)再次推送,達(dá)到閾值后,不再推送。

3.2 緩存同步

高并發(fā)場(chǎng)景下,很多應(yīng)用使用本地緩存,提升系統(tǒng)性能 。Aaa28資訊網(wǎng)——每日最新資訊28at.com

本地緩存可以是 HashMap 、ConcurrentHashMap ,也可以是緩存框架 Guava Cache 或者 Caffeine cache 。Aaa28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Aaa28資訊網(wǎng)——每日最新資訊28at.com

如上圖,應(yīng)用A啟動(dòng)后,作為一個(gè) RocketMQ 消費(fèi)者,消息模式設(shè)置為廣播消費(fèi)。為了提升接口性能,每個(gè)應(yīng)用節(jié)點(diǎn)都會(huì)將字典表加載到本地緩存里。Aaa28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)字典表數(shù)據(jù)變更時(shí),可以通過(guò)業(yè)務(wù)系統(tǒng)發(fā)送一條消息到 RocketMQ ,每個(gè)應(yīng)用節(jié)點(diǎn)都會(huì)消費(fèi)消息,刷新本地緩存。Aaa28資訊網(wǎng)——每日最新資訊28at.com

4 總結(jié)

集群消費(fèi)和廣播消費(fèi)模式下,各功能的支持情況如下:Aaa28資訊網(wǎng)——每日最新資訊28at.com

功能Aaa28資訊網(wǎng)——每日最新資訊28at.com

集群消費(fèi)Aaa28資訊網(wǎng)——每日最新資訊28at.com

廣播消費(fèi)Aaa28資訊網(wǎng)——每日最新資訊28at.com

順序消息Aaa28資訊網(wǎng)——每日最新資訊28at.com

支持Aaa28資訊網(wǎng)——每日最新資訊28at.com

不支持Aaa28資訊網(wǎng)——每日最新資訊28at.com

重置消費(fèi)位點(diǎn)Aaa28資訊網(wǎng)——每日最新資訊28at.com

支持Aaa28資訊網(wǎng)——每日最新資訊28at.com

不支持Aaa28資訊網(wǎng)——每日最新資訊28at.com

消息重試Aaa28資訊網(wǎng)——每日最新資訊28at.com

支持Aaa28資訊網(wǎng)——每日最新資訊28at.com

不支持Aaa28資訊網(wǎng)——每日最新資訊28at.com

消費(fèi)進(jìn)度Aaa28資訊網(wǎng)——每日最新資訊28at.com

服務(wù)端維護(hù)Aaa28資訊網(wǎng)——每日最新資訊28at.com

客戶端維護(hù)Aaa28資訊網(wǎng)——每日最新資訊28at.com

廣播消費(fèi)主要用于兩種場(chǎng)景:消息推送和緩存同步。Aaa28資訊網(wǎng)——每日最新資訊28at.com

參考資料 :Aaa28資訊網(wǎng)——每日最新資訊28at.com

https://www.51cto.com/article/714277.htmlAaa28資訊網(wǎng)——每日最新資訊28at.com

https://ost.51cto.com/posts/21100Aaa28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-11888-0.html深入理解 RocketMQ 廣播消費(fèi)

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 消息隊(duì)列技術(shù)選型:這七種消息場(chǎng)景一定要考慮!

下一篇: 從零開(kāi)發(fā)可視化大屏制作平臺(tái)

標(biāo)簽:
  • 熱門(mén)焦點(diǎn)
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
欧美日韩国产小视频在线观看| 9国产精品视频| 国产精品亚洲不卡a| 国产精品日本欧美一区二区三区| 国产亚洲人成网站在线观看| 韩日成人av| 亚洲免费观看高清完整版在线观看熊| 亚洲一区二区三| 久久嫩草精品久久久精品一| 欧美精品一区二| 国产精品国产三级欧美二区| 狠狠色综合色区| 亚洲精品午夜精品| 亚洲欧美99| 久久久久久久成人| 欧美日韩亚洲一区二区三区在线| 国产日产欧产精品推荐色| 亚洲福利视频一区| 亚洲一区二区三区在线观看视频 | 国产精品一香蕉国产线看观看 | 久久网站热最新地址| 欧美日韩高清在线一区| 国产视频一区在线观看| 亚洲美女精品成人在线视频| 欧美一区二区免费视频| 欧美大片免费观看| 国产精品一区久久久| 亚洲欧洲在线免费| 小处雏高清一区二区三区| 欧美凹凸一区二区三区视频| 国产伦精品一区二区三区视频黑人| 尤妮丝一区二区裸体视频| 99视频一区二区三区| 久久久久久电影| 国产精品爱啪在线线免费观看| 亚洲成人在线免费| 欧美一区二区三区精品| 欧美性久久久| 亚洲人午夜精品| 久久久久久网| 国产精品有限公司| 一区二区动漫| 你懂的成人av| 国模大胆一区二区三区| 亚洲性视频网址| 欧美精品一区二区视频| 精品av久久久久电影| 午夜精品婷婷| 欧美性理论片在线观看片免费| 激情欧美日韩一区| 欧美一区1区三区3区公司| 欧美三级视频| 亚洲精品欧美在线| 老司机免费视频一区二区三区| 国产美女一区二区| 亚洲午夜性刺激影院| 欧美日韩高清不卡| 91久久夜色精品国产网站| 久久九九国产精品| 国产精品中文在线| 亚洲主播在线| 欧美性淫爽ww久久久久无| 日韩视频专区| 欧美精品日韩精品| 亚洲国产日韩一区| 免费日韩一区二区| 亚洲盗摄视频| 免费在线观看一区二区| 激情婷婷欧美| 久久久午夜电影| 国内成+人亚洲| 欧美在线观看视频一区二区| 国产精品一区二区三区观看| 亚洲综合好骚| 国产精品女同互慰在线看| 亚洲视频精品在线| 欧美日韩一区二区在线视频| 99国产精品视频免费观看一公开| 欧美刺激午夜性久久久久久久| 在线免费观看日本一区| 美女久久一区| 亚洲精品乱码久久久久| 欧美人与性动交cc0o| 99视频在线观看一区三区| 欧美视频第二页| 亚洲在线日韩| 国产区在线观看成人精品| 欧美亚洲一区二区在线观看| 国产欧美综合一区二区三区| 午夜精品福利电影| 国产一区二区三区四区hd| 久久九九精品| 在线成人av网站| 欧美大片免费观看| 日韩视频免费观看高清完整版| 欧美日韩免费在线观看| 亚洲午夜激情| 国产欧美一区视频| 久久视频在线视频| 亚洲日本免费| 国产精品盗摄久久久| 午夜视频久久久久久| 国产一区二区无遮挡| 久久综合中文| 亚洲美女av黄| 国产精品―色哟哟| 久久久久在线观看| 另类激情亚洲| 亚洲蜜桃精久久久久久久| 国产精品超碰97尤物18| 亚洲影院污污.| 国产亚洲永久域名| 男人的天堂亚洲| 一区二区欧美激情| 国产区日韩欧美| 久久这里有精品15一区二区三区| 亚洲黄色片网站| 国产精品国产a级| 久久人人爽爽爽人久久久| 亚洲精品免费电影| 国产精品男人爽免费视频1| 久久久999精品| 亚洲美女免费精品视频在线观看| 国产精品久久国产精麻豆99网站| 久久不见久久见免费视频1| 亚洲国产精品t66y| 国产精品国产三级欧美二区| 久久久久一区二区| 日韩一本二本av| 国产亚洲欧美色| 欧美精品一区二区三区蜜臀| 新狼窝色av性久久久久久| 亚洲国产精品成人久久综合一区| 欧美日韩精品免费观看视一区二区 | 亚洲日本无吗高清不卡| 国产精品久线观看视频| 久久久久久久久综合| av成人手机在线| 黑人中文字幕一区二区三区| 欧美区亚洲区| 久久精品国亚洲| 99视频在线观看一区三区| 黄色成人91| 欧美亚一区二区| 免费国产一区二区| 亚洲女人小视频在线观看| 亚洲国产精品女人久久久| 国产精品色在线| 欧美精品三级日韩久久| 欧美在线观看网址综合| 日韩视频永久免费观看| 韩国精品久久久999| 欧美午夜三级| 欧美.www| 久久国产日韩| 亚洲一区二区三区四区在线观看| 亚洲福利国产精品| 国产日韩在线亚洲字幕中文| 欧美色大人视频| 欧美成人精品一区二区三区| 欧美中文字幕久久| 中文久久乱码一区二区| 亚洲福利在线看| 狠狠色丁香婷婷综合影院| 国产精品乱码久久久久久| 99伊人成综合| 136国产福利精品导航网址| 国产精品资源在线观看| 欧美精品久久久久久久免费观看| 欧美自拍偷拍午夜视频| 亚洲午夜视频在线观看| 日韩亚洲欧美综合| 亚洲精品1区2区| 极品中文字幕一区| 国产区亚洲区欧美区| 国产精品s色| 欧美日韩国产区| 欧美激情免费观看| 蜜臀av性久久久久蜜臀aⅴ四虎| 欧美一区中文字幕| 午夜精品久久久久久久| 亚洲一级免费视频| 中文欧美在线视频| 亚洲深夜激情| 亚洲婷婷国产精品电影人久久| 亚洲久久一区| 亚洲欧洲另类| 亚洲欧洲一级| 亚洲国产视频一区| 亚洲国产另类久久久精品极度| 极品日韩av| 一区在线视频| 国产一区二区日韩精品欧美精品 | 国产日本精品| 国产精品永久免费在线| 国产精品理论片| 国产精品入口夜色视频大尺度| 国产精品成人免费视频| 欧美性猛交xxxx免费看久久久 | 亚洲午夜在线| 一本色道久久88精品综合| 日韩一区二区电影网| 中文av一区特黄| 亚洲一区二区精品视频|