国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

SpringCloud網關Zuul底層實現原理詳解

開發(fā) 前端
Zuul實現是基于Servlet這種阻塞是IO這種機制是通過創(chuàng)建更多的線程來彌補其不足;而Cloud Gateway則是基于反應式非阻塞式的,使用少量的線程來做更多的事。

Zuul現在應用的已經非常少了,至少都在使用Spring Cloud Gateway。Zuul實現是基于Servlet這種阻塞是IO這種機制是通過創(chuàng)建更多的線程來彌補其不足;而Cloud Gateway則是基于反應式非阻塞式的,使用少量的線程來做更多的事。以下是官方對阻塞與非阻塞的對比圖:

圖片圖片

1 收集路由

public class ZuulServerAutoConfiguration {
   @Autowired
   protected ZuulProperties zuulProperties;
   @Autowired
   protected ServerProperties server;
   // 主
   @Bean
   @Primary
   public CompositeRouteLocator primaryRouteLocator(
       Collection<RouteLocator> routeLocators) {
     return new CompositeRouteLocator(routeLocators);
   }
 
   @Bean
   @ConditionalOnMissingBean(SimpleRouteLocator.class)
   public SimpleRouteLocator simpleRouteLocator() {
     return new SimpleRouteLocator(this.server.getServlet().getContextPath(), this.zuulProperties);
   }
 }

SimpleRouteLocator

public class SimpleRouteLocator implements RouteLocator, Ordered {
   private ZuulProperties properties;
   private String dispatcherServletPath = "/";
   private String zuulServletPath;
   private AtomicReference<Map<String, ZuulRoute>> routes = new AtomicReference<>();
   // servletPath = server.servlet.contextPath 配置屬性值
   public SimpleRouteLocator(String servletPath, ZuulProperties properties) {
     this.properties = properties;
     if (StringUtils.hasText(servletPath)) {
       this.dispatcherServletPath = servletPath;
     }
     // 默認為:/zuul
     this.zuulServletPath = properties.getServletPath();
   }
 
   // 該方法會在CompositeRouteLocator中調用,而本例的作用就是將ZuulRoute轉換為Route對象
   @Override
   public List<Route> getRoutes() {
     List<Route> values = new ArrayList<>();
     for (Entry<String, ZuulRoute> entry : getRoutesMap().entrySet()) {
       ZuulRoute route = entry.getValue();
       String path = route.getPath();
       try {
         // 將配置文件中配置的ZuulRoute路由轉換為Route對象
         values.add(getRoute(route, path));
       }
     }
     return values;
   }
   protected Map<String, ZuulRoute> getRoutesMap() {
     if (this.routes.get() == null) {
       this.routes.set(locateRoutes());
     }
     return this.routes.get();
   }
   protected Map<String, ZuulRoute> locateRoutes() {
     LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<>();
     // properties.getRouets獲取配置文件中配置的所有路由
     for (ZuulRoute route : this.properties.getRoutes().values()) {
       routesMap.put(route.getPath(), route);
     }
     return routesMap;
   }
   protected Route getRoute(ZuulRoute route, String path) {
     String targetPath = path;
     // 獲取配置文件的zuul.prefix屬性值
     String prefix = this.properties.getPrefix();
     if (prefix.endsWith("/")) {
       // 刪除 '/' 結尾的字符
       prefix = prefix.substring(0, prefix.length() - 1);
     }
     // 判斷配置的路由path屬性值的開始字符串是不是以 '/prefix/'開頭,如:/api/
     // 如果配置的path:/api/api-1/**則匹配第一個條件,再判斷zuul.strip-prefix屬性值是否為true
     if (path.startsWith(prefix + "/") && this.properties.isStripPrefix()) {
       // 成立則會截取字符串刪除'/prefix/'開頭的字符,則最終targetPath = /api-1/**
       targetPath = path.substring(prefix.length());
     }
     // 如果配置為true
     if (route.isStripPrefix()) {
       // 知道path中第一個'*'
       int index = route.getPath().indexOf("*") - 1;
       // 如果存在
       if (index > 0) {
         // 截取第一個'*'之前的字符串
         // 如上:最終routePrefix = /api-1
         String routePrefix = route.getPath().substring(0, index);
         // 結合上面:targetPath = /**
         targetPath = targetPath.replaceFirst(routePrefix, "");
         // 結合上面:prefix = /api + /api-1 = /api/api-1
         prefix = prefix + routePrefix;
       }
     }
     // 上面的路徑處理就是將配置的zuul.prefix + zuul.routes.xx.path
     Boolean retryable = this.properties.getRetryable();
     if (route.getRetryable() != null) {
       retryable = route.getRetryable();
     }
     // 構建Route對象
     return new Route(route.getId(), targetPath, route.getLocation(), prefix,
         retryable,
         route.isCustomSensitiveHeaders() ? route.getSensitiveHeaders() : null,
         route.isStripPrefix());
   }
 }

CompositeRouteLocator

public class CompositeRouteLocator implements RefreshableRouteLocator {
   private final Collection<? extends RouteLocator> routeLocators;
   private ArrayList<RouteLocator> rl;
   // 收集所有RouteLocator,如上面的SimpleRouteLocator
   public CompositeRouteLocator(Collection<? extends RouteLocator> routeLocators) {
     rl = new ArrayList<>(routeLocators);
     AnnotationAwareOrderComparator.sort(rl);
     this.routeLocators = rl;
   }
   public List<Route> getRoutes() {
     List<Route> route = new ArrayList<>();
     for (RouteLocator locator : routeLocators) {
       route.addAll(locator.getRoutes());
     }
     return route;
   }
 }

這里的RouteLocator有何用,下面會見到。

2 注冊HandlerMapping

Zuul會注冊自身特定的ZuulHandlerMapping對象。

public class ZuulServerAutoConfiguration {
   // Controller接口;一個controller接口可以通過實現Controller或AbstractController接口來實現
   @Bean
   public ZuulController zuulController() {
     return new ZuulController();
   }
 
   @Bean
   public ZuulHandlerMapping zuulHandlerMapping(RouteLocator routes,
       ZuulController zuulController) {
     // HandlerMapping中注入了RouteLocator,也就是上面的CompositeRouteLocator對象
     ZuulHandlerMapping mapping = new ZuulHandlerMapping(routes, zuulController);
     mapping.setErrorController(this.errorController);
     mapping.setCorsConfigurations(getCorsConfigurations());
     return mapping;
   }
 }

zuulController

public class ZuulController extends ServletWrappingController {
 
   public ZuulController() {
     // 調用父類的方法設置父類的成員變量servletClass 該Class是個Servlet
     // 在下面會看到如何使用ZuulServlet對象
     setServletClass(ZuulServlet.class);
     setServletName("zuul");
     // 支持任意的請求方法
     setSupportedMethods((String[]) null); // Allow all
   }
 
   // 該方法是Controller接口的核心方法
   @Override
   public ModelAndView handleRequest(HttpServletRequest request,
       HttpServletResponse response) throws Exception {
     try {
       return super.handleRequestInternal(request, response);
     }
   }
 }

ZuulHandlerMapping

HandlerMapping作用就是從通過請求的URI查找到合適的處理句柄,找到就之間返回,接下來就是由HandlerAdapter進行實際的處理了

public class ZuulHandlerMapping extends AbstractUrlHandlerMapping {
   private volatile boolean dirty = true;
   private final ZuulController zuul;
   public ZuulHandlerMapping(RouteLocator routeLocator, ZuulController zuul) {
     this.routeLocator = routeLocator;
     this.zuul = zuul;
     // 優(yōu)先級就很高了,值越小優(yōu)先級越高
     setOrder(-200);
   }
   protected Object lookupHandler(String urlPath, HttpServletRequest request)
       throws Exception {
     if (this.errorController != null && urlPath.equals(this.errorController.getErrorPath())) {
       return null;
     }
     if (isIgnoredPath(urlPath, this.routeLocator.getIgnoredPaths())) {
       return null;
     }
     RequestContext ctx = RequestContext.getCurrentContext();
     if (ctx.containsKey("forward.to")) {
       return null;
     }
     if (this.dirty) {
       synchronized (this) {
         if (this.dirty) {
           // 首次時dirty為true,這時候就會注冊處理句柄了
           registerHandlers();
           this.dirty = false;
         }
       }
     }
     // 調用父類的方法查找合適的請求處理器,從父類handlerMap屬性(Map)集合中查找
     return super.lookupHandler(urlPath, request);
   }
   private void registerHandlers() {
     // 這里就調用了上面CompositeRouteLocator#getRoutes,這樣就得到了所有的路由信息
     Collection<Route> routes = this.routeLocator.getRoutes();
     if (routes.isEmpty()) {
       this.logger.warn("No routes found from RouteLocator");
     } else {
       for (Route route : routes) {
         // 注意:所有的請求路徑都對應同一個Handler也就是上面的ZuulController對象
         // 到這就知道了所有的路由請求都會被ZuulController處理
         // 調用父類方法,將路由信息添加到父類handlerMap屬性中(Map)集合
         registerHandler(route.getFullPath(), this.zuul);
       }
     }
   }
 }

3 路由調用

一個請求過來時,通過上面的ZuulHandlerMapping對象找到了合適的處理句柄也就是ZuulController,接下來就是由合適的HandlerAdapter進行真正的調用了。

現在確定了handler對象是ZuulController,接下來就是查看那個HandlerAdatper能夠進行處理了。

ZuulController實現了Controller接口,能夠處理該類型的是:SimpleControllerHandlerAdaper。

public class SimpleControllerHandlerAdapter implements HandlerAdapter {
   public boolean supports(Object handler) {
     return (handler instanceof Controller);
   }
 
   @Override
   @Nullable
   public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
       throws Exception {
     // 調用ZuulController#handleRequest方法
     return ((Controller) handler).handleRequest(request, response);
   }
 }

回到ZuulController

public class ZuulController extends ServletWrappingController {
 
   public ZuulController() {
     // 記住這里我們給父類屬性servletClass 設置為ZuulServlet
     setServletClass(ZuulServlet.class);
     setServletName("zuul");
     // 支持任意方法
     setSupportedMethods((String[]) null); // Allow all
   }
 
   @Override
   public ModelAndView handleRequest(HttpServletRequest request,
       HttpServletResponse response) throws Exception {
     try {
       // 調用父類方法
       return super.handleRequestInternal(request, response);
     } finally {
       // @see com.netflix.zuul.context.ContextLifecycleFilter.doFilter
       RequestContext.getCurrentContext().unset();
     }
   }
 
 }
 public class ServletWrappingController extends AbstractController
     implements BeanNameAware, InitializingBean, DisposableBean {
   private Class<? extends Servlet> servletClass;
   public void setServletClass(Class<? extends Servlet> servletClass) {
     this.servletClass = servletClass;
   }
   protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
       throws Exception {
     // 調用ZuulServlet#service方法(具體的處理還是通過ZuulServlet處理)
     this.servletInstance.service(request, response);
     return null;
   }
   // 該Bean在初始化解決會通過serveltClass實例化ZuulServlet對象。
   public void afterPropertiesSet() throws Exception {
     if (this.servletClass == null) {
       throw new IllegalArgumentException("'servletClass' is required");
     }
     if (this.servletName == null) {
       this.servletName = this.beanName;
     }
     // 實例化
     this.servletInstance = ReflectionUtils.accessibleConstructor(this.servletClass).newInstance();
     // servlet初始化
     this.servletInstance.init(new DelegatingServletConfig());
   }
 }

ZuulServlet

public class ZuulServlet extends HttpServlet {
   public void init(ServletConfig config) throws ServletException {
     super.init(config);
     String bufferReqsStr = config.getInitParameter("buffer-requests");
     boolean bufferReqs = bufferReqsStr != null && bufferReqsStr.equals("true") ? true : false;
     zuulRunner = new ZuulRunner(bufferReqs);
   }
   // 任意階段發(fā)生了異常都會執(zhí)行error,post階段
   public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException {
     try {
       init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);
       RequestContext context = RequestContext.getCurrentContext();
       context.setZuulEngineRan();
 
       try {
         // pre節(jié)點的ZuulFilter執(zhí)行
         preRoute();
       } catch (ZuulException e) {
         // error階段
         error(e);
         postRoute();
         return;
       }
       try {
         // route階段的路由執(zhí)行
         // 這里其實就是通過網絡api調用目標服務的接口了
         // 我們可以實現自己的處理api接口的調用
         // 如果你真的自己實現了,那么請記得最后執(zhí)行這行代碼
         // context.setRouteHost(null); // prevent SimpleHostRoutingFilter from running
         // 這樣就阻止默認的執(zhí)行了
         // SimpleHostRoutingFilter 網絡請求處理使用的Apache Client
         // 在該節(jié)點得到數據后我們可以通過ProxyRequestHelper工具類將結果(InputStream)保存到
         // RequestContext中,一切順利在post階段就會由SendResponseFilter從RequestContext中獲取InputStream,然后寫到客戶端
         route();
       } catch (ZuulException e) {
         error(e);
         // 發(fā)生了異常也會執(zhí)行
         postRoute();
         return;
       }
       try {
         // post階段
         // 比如:系統(tǒng)提供的SendResponseFilter過濾器就是真正往客戶端開始寫數據了。
         postRoute();
       } catch (ZuulException e) {
         error(e);
         return;
       }
 
     } catch (Throwable e) {
       error(new ZuulException(e, 500, "UNHANDLED_EXCEPTION_" + e.getClass().getName()));
     } finally {
       RequestContext.getCurrentContext().unset();
     }
   }
   void init(HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
     // 將request,response都進行了Wrapper(HttpServletRequestWrapper, HttpServletResponseWrapper)
     zuulRunner.init(servletRequest, servletResponse);
   }
 }

在上面就看到了各個階段的Filter的執(zhí)行。這里需要注意一點,在每個階段執(zhí)行的時候都會通過FilterLoader來獲取對應階段的ZuulFilter。

這個FilterLoader對象并不是一個被容器管理的對象,下面來看這個FilterLoader是如何收集所有ZuulFilter。

public class ZuulServerAutoConfiguration {
   @Configuration(proxyBeanMethods = false)
   protected static class ZuulFilterConfiguration {
 
     // 獲取容器中所有的ZuulFilter
     @Autowired
     private Map<String, ZuulFilter> filters;
 
     // 該Bean中有通過注解@PostConstruct標注的Bean在初始化階段執(zhí)行的方法。
     @Bean
     public ZuulFilterInitializer zuulFilterInitializer(CounterFactory counterFactory,
         TracerFactory tracerFactory) {
       FilterLoader filterLoader = FilterLoader.getInstance();
       FilterRegistry filterRegistry = FilterRegistry.instance();
       return new ZuulFilterInitializer(this.filters, counterFactory, tracerFactory,
           filterLoader, filterRegistry);
     }
 
   }
 }
 public class ZuulFilterInitializer {
   private final Map<String, ZuulFilter> filters;
   private final FilterLoader filterLoader;
   private final FilterRegistry filterRegistry;
   public ZuulFilterInitializer(Map<String, ZuulFilter> filters,
       CounterFactory counterFactory, TracerFactory tracerFactory,
       FilterLoader filterLoader, FilterRegistry filterRegistry) {
     this.filters = filters;
     this.counterFactory = counterFactory;
     this.tracerFactory = tracerFactory;
     this.filterLoader = filterLoader;
     this.filterRegistry = filterRegistry;
   }
 
   // 該方法作用就是將所有的ZuulFilter添加到FilterRegistry中
   @PostConstruct
   public void contextInitialized() {
     for (Map.Entry<String, ZuulFilter> entry : this.filters.entrySet()) {
       // 將所有的ZuulFilter注冊到FilterRegistry中
       filterRegistry.put(entry.getKey(), entry.getValue());
     }
   }
 }

FilterLoader

public class FilterLoader {
   public Object runFilters(String sType) throws Throwable {
     boolean bResult = false;
     // 獲取對應階段的ZuulFilter
     List<ZuulFilter> list = FilterLoader.getInstance().getFiltersByType(sType);
     if (list != null) {
       for (int i = 0; i < list.size(); i++) {
         ZuulFilter zuulFilter = list.get(i);
         Object result = processZuulFilter(zuulFilter);
         if (result != null && result instanceof Boolean) {
           bResult |= ((Boolean) result);
         }
       }
     }
     return bResult;
   }
   public List<ZuulFilter> getFiltersByType(String filterType) {
     List<ZuulFilter> list = hashFiltersByType.get(filterType);
     if (list != null) return list;
 
     list = new ArrayList<ZuulFilter>();
 
     // 從FilterRegistry中獲取所有的ZuulFilter;在上面看到了所有的ZuulFilter都被添加到了FilterRegistry中
     Collection<ZuulFilter> filters = filterRegistry.getAllFilters();
     for (Iterator<ZuulFilter> iterator = filters.iterator(); iterator.hasNext(); ) {
       ZuulFilter filter = iterator.next();
       if (filter.filterType().equals(filterType)) {
         list.add(filter);
       }
     }
     Collections.sort(list); // sort by priority
 
     hashFiltersByType.putIfAbsent(filterType, list);
     return list;
   }
 }

以上就是Zuul網關的底層實現原理。

責任編輯:武曉燕 來源: 實戰(zhàn)案例錦集
相關推薦

2020-11-18 11:26:45

SpringCloudZuulJava

2022-05-13 08:23:07

Zuul微服務Zuul過濾器

2022-12-19 08:00:00

SpringBootWeb開發(fā)

2023-07-20 10:04:37

底層路由配置

2023-07-11 08:00:00

2024-01-05 09:00:00

SpringMVC軟件

2021-08-29 07:41:48

數據HashMap底層

2023-01-04 07:54:03

HashMap底層JDK

2021-04-20 10:15:34

Spring ClouZuul架構

2021-08-31 07:36:22

LinkedListAndroid數據結構

2022-05-20 12:14:50

ZuulSpringClou

2021-01-08 08:34:09

Synchronize線程開發(fā)技術

2024-03-07 07:47:04

代碼塊Monitor

2017-10-18 16:00:14

SpringCloudZuul路徑

2021-02-20 08:40:19

HiveExplain底層

2017-10-23 10:13:18

IO底層虛擬

2022-12-26 09:27:48

Java底層monitor

2021-02-07 09:36:20

LongAdderJDK8開發(fā)

2022-05-12 08:21:13

項目網關模塊

2024-08-29 16:30:27

點贊
收藏

51CTO技術棧公眾號

亚洲iv一区二区三区| 国产精品9999久久久久仙踪林| 羞羞的视频免费| 欧美三级网页| 日韩在线观看网站| 精品视频在线一区二区| 中文字幕亚洲欧美在线不卡| 亚洲五月六月| 9191国语精品高清在线| 久久久久久成人| 一个人www视频在线免费观看| 欧美午夜性色大片在线观看| 成年人在线观看视频免费| 国产综合色产在线精品| 国产高清在线精品一区二区三区| 丁香婷婷成人| 最近2019年手机中文字幕| 天堂8中文在线| 色婷婷精品大在线视频| ckplayer中文字幕| 2024最新电影在线免费观看| 国产在线播放观看| 91亚洲国产高清| 欧美激情按摩在线| 国产综合色在线观看| 日韩欧美视频在线| 国产精品秘入口| 五月激情丁香一区二区三区| 免费黄色特级片| 成人精品一区二区三区四区| av动漫免费观看| 日本伊人精品一区二区三区观看方式 | 亚洲人成7777| 美女一区二区三区视频| 99久久国产综合精品麻豆| 麻豆md0077饥渴少妇| 美女精品自拍一二三四| 欧美日韩在线精品一区二区三区| 国产亚洲激情| 婷婷久久伊人| 日本在线不卡一区| 在线看无码的免费网站| 国产最新精品精品你懂的| 亚洲精美视频| 免费成人在线网站| 欧美日韩国产综合在线| 亚洲一区二区毛片| 亚洲电影一二三区| 国产一区不卡视频| 99精品人妻少妇一区二区| 国产欧美日韩在线看| 成人在色线视频在线观看免费大全| 国产喷白浆一区二区三区| 久久婷五月综合| 亚洲免费观看高清| 中文字幕中文字幕在线中文字幕三区 | 99精品国产福利在线观看免费| 91亚洲一区精品| 狠狠入ady亚洲精品经典电影| 99久久精品免费看国产一区二区三区| 黄色亚洲在线| 亚洲资源在线网| 99久免费精品视频在线观看| jizz欧美激情18| 亚洲无线码一区二区三区| 国产色在线 com| 亚洲精品mp4| 综合中文字幕| 超碰97在线资源| 国产在线视频精品一区| 91国产精品视频在线观看| 天天综合日日夜夜精品| 欧美四级在线| 久久婷婷国产麻豆91天堂| 国产精品亚洲片在线播放| 精品一区二区三区国产| 丰满放荡岳乱妇91ww| 成人在线看片网站| 56国语精品自产拍在线观看| 韩日精品一区二区| 日本在线精品视频| 亚洲第一毛片| 欧美日韩性生活片| 精品国产91久久久久久| 国精产品一区| 欧美乱大交做爰xxxⅹ性3| 国产精品国产一区| 精品国产一区二区三区在线| 一区二区三区欧美久久| 7777kkk亚洲综合欧美网站| 欧美亚洲国产日韩2020| 亚洲精品欧美| 日韩av一二三四| 欧美精选一区二区| 97人人澡人人爽91综合色| 91系列在线播放| 风间由美一区二区三区在线观看| 一级免费视频| 亚洲欧美日韩天堂| 日本久久一二三四| 激情六月天婷婷| 欧美视频一二三| 精品成人18| 日韩福利一区二区三区| 亚洲欧洲日韩综合一区二区| 超碰在线公开| 91欧美精品成人综合在线观看| 国产69精品久久久久777| 都市激情一区| 欧美一二三视频| 岛国精品在线观看| 欧美69xxxx| 青青久久av北条麻妃黑人| 精品一区二区免费视频| 欧美扣逼视频| 欧美性一区二区三区| 成人精品在线视频观看| √天堂8在线网| 91香蕉亚洲精品| 国产精品美女久久福利网站| 国产自产自拍视频在线观看| av在线不卡一区| 夜夜嗨av一区二区三区| 亚洲日本免费电影| 中文字幕日韩精品一区二区| 欧洲精品在线观看| 不卡中文一二三区| 中文字幕国产传媒| 中文字幕在线国产精品| 免费观看日韩电影| 婷婷免费在线视频| 91牛牛免费视频| 亚洲综合色区另类av| 日韩精品一区二区三区免费视频| 亚洲一区二区三区乱码| 欧美视频在线一区二区三区 | 性欧美大战久久久久久久| 欧美人体做爰大胆视频| 日韩在线综合| 午夜丝袜av电影| 午夜精品视频在线| 久久一日本道色综合| 先锋欧美三级| 欧美 亚洲 视频| 日韩av中文字幕在线| 日日夜夜免费精品视频| 欧美精品videos另类| 国产精品18毛片一区二区| 精品国产福利在线| 欧美电影免费播放| 在线看的你懂得| 国产欧美 在线欧美| 亚洲电影一级黄| 四季av一区二区三区免费观看| 夜色福利刺激| 国产美女直播视频一区| 精品国产91久久久久久| 99久久久久国产精品| 欧美5-7sexvideos处| 国产有码一区二区| 色综合天天做天天爱| 韩日精品在线| 国产1区在线| 伊人久久大香线蕉成人综合网| 日韩欧美一级二级三级久久久| 奇米在线7777在线精品| 69久成人做爰电影| 日韩激情免费视频| 欧美精品999| 午夜精彩视频在线观看不卡| 国产综合婷婷| 国产精品蜜芽在线观看| 成年人网站免费视频| 国模gogo一区二区大胆私拍 | 欧美一级免费大片| 久久综合色婷婷| 亚洲男男av| 国产精品va在线观看视色| 欧美黄网站在线观看| 精品国产91亚洲一区二区三区婷婷 | 另类少妇人与禽zozz0性伦| 嫩草影院中文字幕| 中文字幕精品视频| 国产婷婷精品av在线| 久久精品色播| 亚洲成人影院在线观看| 国产一区二区三区av在线| 日韩手机在线导航| 成人在线一区二区三区| 成人短视频软件网站大全app| 亚洲欧美激情网| 国产色视频一区| 日韩一区二区三区免费看 | 国产电影一区| 日本女优北野望在线电影| 国产精品二区在线| 中文字幕av一区二区| 亚洲成av人片在线观看无码| 丝袜亚洲精品中文字幕一区| 日韩影片在线观看|