日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Boot集成Hazelcast实现集群与分布式内存缓存

發(fā)布時間:2025/6/17 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Boot集成Hazelcast实现集群与分布式内存缓存 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標準>>>

Hazelcast是Hazelcast公司開源的一款分布式內(nèi)存數(shù)據(jù)庫產(chǎn)品,提供彈性可擴展、高性能的分布式內(nèi)存計算。并通過提供諸如Map,Queue,ExecutorService,Lock和JCache等Java的許多開發(fā)人員友好的分布式實現(xiàn)。

了解Hazelcast

Hazelcast特性

  • 簡單易用 Hazelcast是用Java編寫的,沒有其他依賴關(guān)系。只需簡單的把jar包引入項目的classpath即可創(chuàng)建集群。
  • 無主從模式 與許多NoSQL解決方案不同,Hazelcast節(jié)點是點對點的。沒有主從關(guān)系; 所有成員都存儲相同數(shù)量的數(shù)據(jù),并進行相等的處理,避免了單點故障。
  • 彈性可擴展 Hazelcast旨在擴展成千上萬的成員。新成員啟動,將自動發(fā)現(xiàn)群集,并線性增加存儲和處理能力。成員之間通過TCP保持連接和通訊。
  • 讀寫快速高效 Hazelcast所有數(shù)據(jù)都存儲在內(nèi)存中,提供基于內(nèi)存快速高效的讀寫能力。

Hazelcast部署拓撲 在Hazelcast官方提供兩種方式部署集群(圖片均來自官方文檔):

如需聚焦異步或高性能大批量任務(wù)的緩存服務(wù),嵌入式方式是相對有優(yōu)勢的,最明顯嵌入式方式訪問數(shù)據(jù)延遲性低。

獨立創(chuàng)建Hazelcast集群,統(tǒng)一管理,所有的應(yīng)用程序如果需要訪問緩存,可通過Hazelcast客戶端(有java .NET C++的實現(xiàn))或Memcache客戶端或簡單的REST客戶端訪問。后續(xù)demo示例以嵌入式為例。

Hazelcast數(shù)據(jù)分區(qū) 在Hazelcast分布式環(huán)境中,默認情況下,Hazelcast有271個分區(qū)。 當啟動第一個成員的時候,成員1在集群中的分區(qū)如下圖:

當在集群中新添加一個節(jié)點2時,分區(qū)圖如下:

在圖示中,黑色分區(qū)是主分區(qū),藍色分區(qū)是副本分區(qū)(備份)。第一個成員具有135個主分區(qū)(黑色),并且每個分區(qū)都備份在第二個成員(藍色)中。同時,第一個成員還具有第二個成員的主分區(qū)的副本分區(qū)。

隨著成員的增多,Hazelcast將一些主要和副本分區(qū)逐個移動到新成員,使所有成員相等和冗余。只有最小量的分區(qū)將被移動到擴展Hazelcast。以下是具有四個成員的Hazelcast集群中的分區(qū)圖示如下:

Hazelcast在群集成員之間平均分配分區(qū)。Hazelcast創(chuàng)建分區(qū)的備份,并將其分配給成員之間進行冗余。

上述插圖中的分區(qū)是為了方便描述。通常,Hazelcast分區(qū)不會按照順序分配(如這些圖所示),而是隨機分布。Hazelcast在成員間平均分配了分區(qū)和備份。

Hazelcast優(yōu)勢

  • Hazelcast提供開源版本。
  • Hazelcast無需安裝,只是個極小jar包。
  • Hazelcast提供開箱即用的分布式數(shù)據(jù)結(jié)構(gòu),如Map,Queue,MultiMap,Topic,Lock和Executor。
  • Hazelcast集群非傳統(tǒng)主從關(guān)系,避免了單點故障;集群中所有成員共同分擔集群功能。
  • Hazelcast集群提供彈性擴展,新成員在內(nèi)存不足或負載過高時能動態(tài)加入集群。
  • Hazelcast集群中成員分擔數(shù)據(jù)緩存的同時互相冗余備份其他成員數(shù)據(jù),防止某成員離線后數(shù)據(jù)丟失。
  • Hazelcast提供SPI接口支持用戶自定義分布式數(shù)據(jù)結(jié)構(gòu)。

Hazelcast適用場景

  • 頻繁讀寫數(shù)據(jù)
  • 需要高可用分布式緩存
  • 內(nèi)存行NoSql存儲
  • 分布式環(huán)境中彈性擴展

下面我們來使用Spring Boot集成Hazelcast實現(xiàn)分布式集群服務(wù)看看

Spring Boot集成Hazelcast實現(xiàn)分布式集群服務(wù)

首先新建一個Spring Boot的gradle項目,引入Hazelcast相關(guān)jar包:

dependencies {compile 'com.hazelcast:hazelcast'compile 'org.springframework.boot:spring-boot-starter-web' }

當Hazelcast包在classpath上,Spring Boot將通過下面兩種方式之一為我們創(chuàng)建一個HazelcastInstance實例:

方式一,通過配置屬性指定的Hazelcast.xml文件創(chuàng)建: spring.hazelcast.config = classpath:hazelcast.xml 該方式需要編寫一個hazelcast.xml文件,通過xml文件描述Hazelcast集群

方式二,通過提供一個com.hazelcast.config.Config javabean到Spring容器中(下面所有demo是基于java config方式)

@Beanpublic Config hazelCastConfig() {//如果有集群管理中心,可以配置ManagementCenterConfig centerConfig = new ManagementCenterConfig();centerConfig.setUrl("http://127.0.0.1:8200/mancenter");centerConfig.setEnabled(true);return new Config().setInstanceName("hazelcast-instance").setManagementCenterConfig(centerConfig).addMapConfig(new MapConfig().setName("instruments").setMaxSizeConfig(new MaxSizeConfig(200, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE)).setEvictionPolicy(EvictionPolicy.LRU).setTimeToLiveSeconds(20000));}

上面代碼通過提供Config的bean時候,主要做了如下幾個事:

  • 創(chuàng)建一個默認名為hazelcast-instance的HazelcastInstance實例;
  • 使用默認的組播發(fā)現(xiàn)模式,組播傳播地址默認為:224.2.2.3,如果想修改信息或修改為TCP模式可通過setNetworkConfig()接口設(shè)置相關(guān)信息;
  • 創(chuàng)建一個名為dev,訪問密碼為dev-pass的group保障節(jié)點加入,如果想修改組,可通過setGroupConfig()接口設(shè)置相關(guān)信息;
  • 創(chuàng)建了一個名為instruments的分布式map數(shù)據(jù)結(jié)構(gòu),并設(shè)置了該map的最大容量200/逐出策略LRU/有效期20000ms等信息,當集群啟動后,我們可以在任一成員節(jié)點上通過HazelcastInstance讀寫該map。

完整代碼:

@SpringBootApplication public class StartUp {private Logger LOGGER = LoggerFactory.getLogger(StartUp.class);public static void main(String[] args) {SpringApplication.run(StartUp.class, args);}@Beanpublic Config hazelCastConfig() {//如果有集群管理中心,可以配置ManagementCenterConfig centerConfig = new ManagementCenterConfig();centerConfig.setUrl("http://127.0.0.1:8200/mancenter");centerConfig.setEnabled(true);return new Config().setInstanceName("hazelcast-instance").setManagementCenterConfig(centerConfig).addMapConfig(new MapConfig().setName("instruments").setMaxSizeConfig(new MaxSizeConfig(200, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE)).setEvictionPolicy(EvictionPolicy.LRU).setTimeToLiveSeconds(20000));} }

下面我們通過修改server.port分別啟動端口為8080和8081的成員服務(wù) 當啟動完8080成員的時候,可以在8080控制臺看到如下日志:

Members [1] {Member [172.17.42.1]:5701 - 0d39dd66-d4fb-4af4-8ddb-e9f4c7bbe5a1 this }

因我們使用的是組播傳播模式,5701為節(jié)點在組播網(wǎng)絡(luò)中分配的端口 當啟動完8081成員的時候,可以在8081控制臺看到如下日志:

Members [2] {Member [172.17.42.1]:5701 - 0d39dd66-d4fb-4af4-8ddb-e9f4c7bbe5a1Member [172.17.42.1]:5702 - a46ceeb4-e079-43a5-9c9d-c74265211bf7 this }

回到8080控制臺,發(fā)現(xiàn)多了一行日志:

Members [2] {Member [172.17.42.1]:5701 - 0d39dd66-d4fb-4af4-8ddb-e9f4c7bbe5a1 thisMember [172.17.42.1]:5702 - a46ceeb4-e079-43a5-9c9d-c74265211bf7 }

發(fā)現(xiàn)8081成員也加入進來了。兩個控制臺都能看到成員列表。集群就已經(jīng)搭建成功。

為了驗證結(jié)果,上面我們在集群中已經(jīng)創(chuàng)建了一個名為instruments的分布式map數(shù)據(jù)結(jié)構(gòu),現(xiàn)在我們通過寫個接口證明:

@GetMapping("/greet")public Object greet() {Object value = Hazelcast.getHazelcastInstanceByName("hazelcast-instance").getMap("instruments").get("hello");if (Objects.isNull(value)) {Hazelcast.getHazelcastInstanceByName("hazelcast-instance").getMap("instruments").put("hello", "world!");} LOGGER.info("從分布式緩存獲取到 key=hello,value={}", value);return value;}

首先通過訪問8080服務(wù)的/greet,第一次訪問instruments中是沒有key為hello的鍵值對,會往里面塞入{"helo":"world!"},然后訪問8081服務(wù)的/greet,這個時候應(yīng)該是能取得改鍵值對的。

完整代碼:

@RestController @SpringBootApplication public class StartUp {private Logger LOGGER = LoggerFactory.getLogger(StartUp.class);public static void main(String[] args) {SpringApplication.run(StartUp.class, args);}@Beanpublic Config hazelCastConfig() {//如果有集群管理中心,可以配置ManagementCenterConfig centerConfig = new ManagementCenterConfig();centerConfig.setUrl("http://127.0.0.1:8200/mancenter");centerConfig.setEnabled(true);return new Config().setInstanceName("hazelcast-instance").setManagementCenterConfig(centerConfig).addMapConfig(new MapConfig().setName("instruments").setMaxSizeConfig(new MaxSizeConfig(200, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE)).setEvictionPolicy(EvictionPolicy.LRU).setTimeToLiveSeconds(20000));}@GetMapping("/greet")public Object greet() {Object value = Hazelcast.getHazelcastInstanceByName("hazelcast-instance").getMap("instruments").get("hello");if (Objects.isNull(value)) {Hazelcast.getHazelcastInstanceByName("hazelcast-instance").getMap("instruments").put("hello", "world!");} LOGGER.info("從分布式緩存獲取到 key=hello,value={}", value);return value;} }

重啟8080和8081服務(wù) 通過瀏覽器請求http://localhost:8080/greet 查看8080控制臺日志: 2017-10-23 13:52:27.865 INFO 13848 --- [nio-8080-exec-1] com.hazelcast.StartUp: 從分布式緩存獲取到 key=hello,value=nul

通過瀏覽器請求http://localhost:8081/greet 查看8081控制臺日志: 2017-10-23 13:52:40.116 INFO 13860 --- [nio-8081-exec-2] com.hazelcast.StartUp: 從分布式緩存獲取到 key=hello,value=world

Spring Boot為Hazelcast提供了明確的緩存支持。如果啟用緩存, HazelcastInstance則會自動包含在CacheManager實現(xiàn)中。所以完全可以支持Spring Cache。

以往我們用Spring Cache都是基于Redis做存儲后端,現(xiàn)在我們使用Hazelcast來嘗試一下 首先在啟動類上開啟緩存 @EnableCaching

建立個service類,demo為了方便,寫在一起 完整代碼:

@EnableCaching @RestController @SpringBootApplication public class StartUp {private Logger LOGGER = LoggerFactory.getLogger(StartUp.class);public static void main(String[] args) {SpringApplication.run(StartUp.class, args);}@Beanpublic Config hazelCastConfig() {//如果有集群管理中心,可以配置ManagementCenterConfig centerConfig = new ManagementCenterConfig();centerConfig.setUrl("http://127.0.0.1:8200/mancenter");centerConfig.setEnabled(true);return new Config().setInstanceName("hazelcast-instance").setManagementCenterConfig(centerConfig).addMapConfig(new MapConfig().setName("instruments").setMaxSizeConfig(new MaxSizeConfig(200, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE)).setEvictionPolicy(EvictionPolicy.LRU).setTimeToLiveSeconds(20000));}@GetMapping("/greet")public Object greet() {Object value = Hazelcast.getHazelcastInstanceByName("hazelcast-instance").getMap("instruments").get("hello");if (Objects.isNull(value)) {Hazelcast.getHazelcastInstanceByName("hazelcast-instance").getMap("instruments").put("hello", "world!");} LOGGER.info("從分布式緩存獲取到 key=hello,value={}", value);return value;}@Autowiredprivate DemoService demoService;@GetMapping("/cache")public Object cache() {String value = demoService.greet("hello"); LOGGER.info("從分布式緩存獲取到 key=hello,value={}", value);return value;}}@Service @CacheConfig(cacheNames = "instruments") class DemoService {private Logger LOGGER = LoggerFactory.getLogger(DemoService.class);@Cacheable(key = "#key")public String greet(String key) { LOGGER.info("緩存內(nèi)沒有取到key={}", key);return "world!";}}

連續(xù)訪問兩次8080服務(wù)的/cache接口 第一次控制臺輸出日志:

2017-10-23 14:10:02.201 INFO 13069 --- [nio-8081-exec-1] com.hazelcast.DemoService: 緩存內(nèi)沒有取到key=hello 2017-10-23 14:10:02.202 INFO 13069 --- [nio-8081-exec-1] com.hazelcast.StartUp: 從分布式緩存獲取到 key=hello,value=world!

第二次控制臺輸出日志: 2017-10-23 14:11:51.966 INFO 13069 --- [nio-8081-exec-3] com.hazelcast.StartUp: 從分布式緩存獲取到 key=hello,value=world!

第二次比第一次相比少了執(zhí)行service方法體內(nèi)容,證明第二次是通過了緩存獲取。

  • 在Hazelcast官網(wǎng)上,有使用Hazelcast集群和Redis集群做緩存的對比
  • 單只性能上來說,寫入速度Hazelcast比Redis快44%,讀取速度Hazelcast比Redis快56%
  • 詳情移步底下參考資料中鏈接
  • 下面,我們再來一個嘗試,既然有分布式緩存了,我們可以把我們的8080和8081服務(wù)做成一個web集群,web服務(wù)集群主要標志是前端負載均衡和session共享,我們來實現(xiàn)8080和8081的session共享。

Spring Session已經(jīng)支持使用Hazelcast作為會話緩存后端,首先引入Spring Session jar包

dependencies {compile 'com.hazelcast:hazelcast'compile 'org.springframework.boot:spring-boot-starter-web'compile 'org.springframework.session:spring-session' }

要啟用Hazelcast作為集群會話緩存后端,有兩種方式 第一種Spring Boot配置文件里面配置spring.session.*屬性: spring.session.store-type=hazelcast

第二種使用java注解開啟: @EnableHazelcastHttpSession

這里選擇第二種方式,要證明集群會話共享,我們定一個簡單接口打印一下sessionId,通過同一瀏覽器訪問8080和8081服務(wù)的該接口,看看不同服務(wù)請求的時候sessionId是否一致,完整代碼如下:

@EnableCaching @RestController @EnableHazelcastHttpSession @SpringBootApplication public class StartUp {private Logger LOGGER = LoggerFactory.getLogger(StartUp.class);public static void main(String[] args) {SpringApplication.run(StartUp.class, args);}@Beanpublic Config hazelCastConfig() {//如果有集群管理中心,可以配置ManagementCenterConfig centerConfig = new ManagementCenterConfig();centerConfig.setUrl("http://127.0.0.1:8200/mancenter");centerConfig.setEnabled(true);return new Config().setInstanceName("hazelcast-instance").setManagementCenterConfig(centerConfig).addMapConfig(new MapConfig().setName("instruments").setMaxSizeConfig(new MaxSizeConfig(200, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE)).setEvictionPolicy(EvictionPolicy.LRU).setTimeToLiveSeconds(20000));}@GetMapping("/greet")public Object greet() {Object value = Hazelcast.getHazelcastInstanceByName("hazelcast-instance").getMap("instruments").get("hello");if (Objects.isNull(value)) {Hazelcast.getHazelcastInstanceByName("hazelcast-instance").getMap("instruments").put("hello", "world!");} LOGGER.info("從分布式緩存獲取到 key=hello,value={}", value);return value;}@Autowiredprivate DemoService demoService;@GetMapping("/cache")public Object cache() {String value = demoService.greet("hello"); LOGGER.info("從分布式緩存獲取到 key=hello,value={}", value);return value;}@GetMapping("/session")public Object session(HttpSession session) {String sessionId = session.getId(); LOGGER.info("當前請求的sessionId={}", sessionId);return sessionId;} }@Service @CacheConfig(cacheNames = "instruments") class DemoService {private Logger LOGGER = LoggerFactory.getLogger(DemoService.class);@Cacheable(key = "#key")public String greet(String key) { LOGGER.info("緩存內(nèi)沒有取到key={}", key);return "world!";}}

訪問8080服務(wù)/session接口,控制臺日志如下: 2017-10-23 14:28:41.991 INFO 14140 --- [nio-8080-exec-2] com.hazelcast.StartUp: 當前請求的sessionId=e75ffc53-90bc-41cd-8de9-e9ddb9c2a5ee

訪問8081服務(wù)/session接口,控制臺日志如下: 2017-10-23 14:28:45.615 INFO 14152 --- [nio-8081-exec-1] com.hazelcast.StartUp: 當前請求的sessionId=e75ffc53-90bc-41cd-8de9-e9ddb9c2a5ee 集群會話共享生效。

集群管理界面

在上面的demo中,在創(chuàng)建Config的時候,設(shè)置了一個ManagementCenterConfig配置,該配置是指向一個Hazelcast集群管理平臺,比如demo中表示在本地啟動了一個管理平臺服務(wù)。該功能也是相對其他NoSql服務(wù)的一個優(yōu)勢。

要部署ManagementCenter管理平臺有多種方式 比如通過https://download.hazelcast.com/management-center/management-center-3.8.3.zip地址下載,解壓后啟動; sh ./startManCenter.sh 8200 /mancenter

如果有docker環(huán)境,直接可以docker部署: docker run -ti -p 8200:8080 hazelcast/management-center:latest

部署成功后,訪問http://ip:8200/mancenter,首次訪問會讓你配置個用戶名密碼,進入后 :

在左側(cè)菜單欄,能看到現(xiàn)有支持的分布式數(shù)據(jù)格式,比如Maps下面名為instruments的是我們前面demo自己創(chuàng)建的,名為spring:session:sessions是我們用了Hazelcast做集群會話同步的時候Spring為我們創(chuàng)建的。

中間區(qū)域能看到所有節(jié)點成員的系統(tǒng)相關(guān)實時使用率,隨便點擊一個節(jié)點進去,能看到當前節(jié)點的系統(tǒng)實時使用率:

紅圈里面的即是上面提到的節(jié)點數(shù)據(jù)分區(qū)數(shù),通過左側(cè)菜單欄的數(shù)據(jù)結(jié)構(gòu)進去,能看到當前對應(yīng)的數(shù)據(jù)結(jié)構(gòu)的詳細信息和實時吞吐量:

更多內(nèi)容請參考下方參考資料。 示例代碼可以通過https://github.com/zggg/hazelcast-in-spring-boot下載。

參考資料

  • 為什么選Hazelcast:https://hazelcast.com/why-hazelcast/imdg/
  • Hazelcast官方文檔:http://docs.hazelcast.org/docs/3.8.6/manual/html-single/index.html
  • Redis對比:https://hazelcast.com/use-cases/nosql/redis-replacement/
  • Redis 3.2.8 vs Hazelcast 3.8 集群基準測試對比:https://hazelcast.com/resources/benchmark-redis-vs-hazelcast/

——————————————————分割線——————————————————

我是黑少,直男一枚,微服務(wù)硬核玩家,喜歡分享、愛交友人、崇尚“實踐出真知”的理念,以折騰鼓搗代碼為樂

我的微信:weiweiweiblack (備注:開源中國)

微信公號:黑少微服務(wù),專注微服務(wù)技術(shù)分享,非技術(shù)不八卦!

轉(zhuǎn)載于:https://my.oschina.net/u/4009457/blog/2875381

總結(jié)

以上是生活随笔為你收集整理的Spring Boot集成Hazelcast实现集群与分布式内存缓存的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成人免费在线视频网站 | 精品嫩模一区二区三区 | 亚洲 美腿 欧美 偷拍 | 欧美性啪啪 | 国产精品无码在线播放 | 国产精品8 | 黄色aaaa| 男插女青青影院 | 亚洲乱码少妇 | 免费看黄色片子 | 日本一区二区三区免费电影 | videos另类灌满极品另类 | 国产精品久久久久久人妻精品动漫 | 色88久久久久高潮综合影院 | 国产精品无码av无码 | 欧美激情视频在线播放 | 在线观看免费视频一区二区 | av视觉盛宴| 色呦呦在线免费观看 | 免费福利av | 波多野结衣一二区 | 操一操视频 | 亚洲精品欧美精品 | 超能一家人电影免费喜剧在线观看 | 午夜影院性 | 国产午夜精品久久久久 | 亚日韩 | 日本一区二区免费电影 | 影音先锋中文字幕一区 | 精品人妻一区二区免费视频 | 日本学生初尝黑人巨免费视频 | 亚洲午夜伦理 | 激情文学欧美 | 久久亚洲AV无码专区成人国产 | ass精品国模裸体pics | 深夜福利国产 | 亚洲色图第一页 | 日韩久久电影 | 麻豆三级在线观看 | 久久人妻少妇嫩草av无码专区 | a级黄色小说 | 亚洲美女中文字幕 | 国内精品视频一区二区三区 | 3d动漫啪啪精品一区二区中文字幕 | 亚色91| 亚洲视频 欧美视频 | www性| 亚洲精品中文字幕在线观看 | 久久五月婷| 在线视频观看一区 | 亚洲97视频 | 免费av影视 | 日本xxxx色| 国产美女三级无套内谢 | 欧美激情一区二区 | 污污网站在线看 | 国产精品久久婷婷 | 国产精品无码粉嫩小泬 | 亚洲成人午夜在线 | 爽爽影院在线 | 自拍视频第一页 | 三级全黄做爰龚玥菲在线 | 国产亚洲性欧美日韩在线观看软件 | 成人激情视频网 | 黄色大片在线播放 | 日韩中文字幕视频在线 | 9久9久9久女女女九九九一九 | 国产后入又长又硬 | 超碰夜夜 | 国产一二三精品 | 久久五月天婷婷 | 国产一区二区三区精品愉拍 | 麻豆极品 | 夜夜看av| 伊人久久久久噜噜噜亚洲熟女综合 | 日韩国产电影 | 台湾色综合 | 老女人人体欣赏a√s | av资源一区 | 香蕉久久精品 | 妖精视频在线观看免费 | 国产精品怡红院 | 日韩精品色呦呦 | 激情五月婷婷在线 | 美国av大片 | 91国产免费看| 越南毛茸茸的少妇 | 中文字幕在线免费观看 | 婷婷一区二区三区四区 | 免费精品无码AV片在线观看黄 | 少妇太爽了太深了太硬了 | 精品一二三四区 | 高清乱码毛片 | 日韩精品在线视频 | 日韩毛片一区二区三区 | 亚洲第一视频网站 | 欧美日韩国产三级 | 精品黄色一级片 | 黄网站免费入口 |