当前位置: 首页 > news >正文

重庆手机网站推广资料python基础教程第三版

重庆手机网站推广资料,python基础教程第三版,贺岁币在建设银行那个网站预约,今天最新生猪价格SpringCloud Gateway默认不支持将请求路由到一个服务的多个端口 本文将结合Gateway的处理流程#xff0c;提供一些解决思路 需求背景 公司有一个IM项目#xff0c;对外暴露了两个端口8081和8082#xff0c;8081是springboot启动使用的端口#xff0c;对外提供一些http接口… SpringCloud Gateway默认不支持将请求路由到一个服务的多个端口 本文将结合Gateway的处理流程提供一些解决思路 需求背景 公司有一个IM项目对外暴露了两个端口8081和80828081是springboot启动使用的端口对外提供一些http接口如获取聊天群组成员列表等相关配置如下 spring: application: name: im server:port: 8081servlet:context-path: /im8082是内部启动了一个netty服务器处理websocket请求实现即时通讯 ...... ...... pipeline.addLast(new WebSocketServerProtocolHandler(/ws)); ...... ...... bootstrap.bind(8082).sync();以本地环境为例直连IM项目的请求地址如下 http://localhost:8081/im/*** 请求http接口 ws://localhost:8082/ws进行websocket协议升级 项目组希望客户端能统一走网关实现对这两种接口的调用 问题描述 网关使用springcloud gateway监听端口8080注册中心使用nacos 正常情况下gateway根据服务名转发配置如下 - id: im_routeuri: lb://impredicates:- Path/im/**访问网关http://localhost:8080/im/**即可将请求转发到IM服务 同理我们希望访问网关ws://localhost:8080/ws也能转发到IM的netty服务器 一般情况下如果要通过gateway转发websocket请求我们需要做如下配置 - id: im_ws_routeuri: lb:ws://impredicates:- Path/ws/**但实际上lb这个schema告诉gateway要走负载gateway转发的时候会到nacos拉取im的服务清单将其替换为 ip 端口而nacos上注册的是springboot项目的端口也就是8081所以想转发到IM的8082上默认是没办法利用gateway的服务发现机制的只能直接配置服务的ip地址如下 - id: im_ws_routeuri: ws://localhost:8082predicates:- Path/ws不过这样也就失去使用网关的意义了 寻找思路 先观察下gateway转发的流程找到DispatcherHandler的handle方法 Overridepublic MonoVoid handle(ServerWebExchange exchange) {if (this.handlerMappings null) {return createNotFoundError();}if (CorsUtils.isPreFlightRequest(exchange.getRequest())) {return handlePreFlight(exchange);}return Flux.fromIterable(this.handlerMappings).concatMap(mapping - mapping.getHandler(exchange)).next().switchIfEmpty(createNotFoundError()).onErrorResume(ex - handleDispatchError(exchange, ex)).flatMap(handler - handleRequestWith(exchange, handler));}首先遍历内部的HandlerMapping依次调用其getHandler方法寻找能处理当前请求的Handler HandlerMapping共有四个一般来说我们配置了上述的路由会在第三个RoutePredicateHandlerMapping返回一个Handler Handler类型为FilteringWebHandler其中包含了一组Filter 找到Handler后在DispatcherHandler # handle方法的最后一行调了handleRequestWith方法 private MonoVoid handleRequestWith(ServerWebExchange exchange, Object handler) {if (ObjectUtils.nullSafeEquals(exchange.getResponse().getStatusCode(), HttpStatus.FORBIDDEN)) {return Mono.empty(); // CORS rejection}if (this.handlerAdapters ! null) {for (HandlerAdapter adapter : this.handlerAdapters) {if (adapter.supports(handler)) {return adapter.handle(exchange, handler).flatMap(result - handleResult(exchange, result));}}}return Mono.error(new IllegalStateException(No HandlerAdapter: handler));}然后遍历了HandlerAdapter一共有四个 这里起作用的是最后一个SimpleHandlerAdapter进入其handle方法 Overridepublic MonoHandlerResult handle(ServerWebExchange exchange, Object handler) {WebHandler webHandler (WebHandler) handler;MonoVoid mono webHandler.handle(exchange);return mono.then(Mono.empty());}调用了上面找到Handler的handle方法 Overridepublic MonoVoid handle(ServerWebExchange exchange) {Route route exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);ListGatewayFilter gatewayFilters route.getFilters();ListGatewayFilter combined new ArrayList(this.globalFilters);combined.addAll(gatewayFilters);// TODO: needed or cached?AnnotationAwareOrderComparator.sort(combined);if (logger.isDebugEnabled()) {logger.debug(Sorted gatewayFilterFactories: combined);}return new DefaultGatewayFilterChain(combined).filter(exchange);}最后filter方法依次执行了其中的Filter Overridepublic MonoVoid filter(ServerWebExchange exchange) {return Mono.defer(() - {if (this.index filters.size()) {GatewayFilter filter filters.get(this.index);DefaultGatewayFilterChain chain new DefaultGatewayFilterChain(this, this.index 1);return filter.filter(exchange, chain);}else {return Mono.empty(); // complete}});}}在这些Filter中有一个ReactiveLoadBalancerClientFilter会完成从nacos拉取服务清单替换请求地址的任务 看下它的filter方法 Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {URI url exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);String schemePrefix exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);if (url null || (!lb.equals(url.getScheme()) !lb.equals(schemePrefix))) {return chain.filter(exchange);}// preserve the original urladdOriginalRequestUrl(exchange, url);if (log.isTraceEnabled()) {log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName() url before: url);}URI requestUri exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);String serviceId requestUri.getHost();SetLoadBalancerLifecycle supportedLifecycleProcessors LoadBalancerLifecycleValidator.getSupportedLifecycleProcessors(clientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),RequestDataContext.class, ResponseData.class, ServiceInstance.class);DefaultRequestRequestDataContext lbRequest new DefaultRequest(new RequestDataContext(new RequestData(exchange.getRequest()), getHint(serviceId)));return choose(lbRequest, serviceId, supportedLifecycleProcessors).doOnNext(response - {if (!response.hasServer()) {supportedLifecycleProcessors.forEach(lifecycle - lifecycle.onComplete(new CompletionContext(CompletionContext.Status.DISCARD, lbRequest, response)));throw NotFoundException.create(properties.isUse404(), Unable to find instance for url.getHost());}ServiceInstance retrievedInstance response.getServer();URI uri exchange.getRequest().getURI();// if the lb:scheme mechanism was used, use scheme as the default,// if the loadbalancer doesnt provide one.String overrideScheme retrievedInstance.isSecure() ? https : http;if (schemePrefix ! null) {overrideScheme url.getScheme();}DelegatingServiceInstance serviceInstance new DelegatingServiceInstance(retrievedInstance,overrideScheme);URI requestUrl reconstructURI(serviceInstance, uri);if (log.isTraceEnabled()) {log.trace(LoadBalancerClientFilter url chosen: requestUrl);}exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);exchange.getAttributes().put(GATEWAY_LOADBALANCER_RESPONSE_ATTR, response);supportedLifecycleProcessors.forEach(lifecycle - lifecycle.onStartRequest(lbRequest, response));}).then(chain.filter(exchange)).doOnError(throwable - supportedLifecycleProcessors.forEach(lifecycle - lifecycle.onComplete(new CompletionContextResponseData, ServiceInstance, RequestDataContext(CompletionContext.Status.FAILED, throwable, lbRequest,exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR))))).doOnSuccess(aVoid - supportedLifecycleProcessors.forEach(lifecycle - lifecycle.onComplete(new CompletionContextResponseData, ServiceInstance, RequestDataContext(CompletionContext.Status.SUCCESS, lbRequest,exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR),new ResponseData(exchange.getResponse(), new RequestData(exchange.getRequest()))))));}首先判断uri配置了lb需要根据服务名做负载转发 在这个filter前已经根据请求路径/ws和router配置将请求地址转换成了 服务名:请求路径的形式也就是将ws://localhost:8080/ws转化成了ws://im/ws 然后根据服务名im到nacos获取到服务的实际地址 ServiceInstance retrievedInstance response.getServer();其中包含了ip和端口 最后替换出实际要转发的地址 所以我们只要在这一步根据需要将端口8081改成8082就能实现我们要的效果了 最终解决方案 最初是想自定义一个HandlerMapping完成转发的但看下来后直接改源码更便捷一些所以直接在项目中新建一个同路径的类将源码copy进来覆盖掉这个Filter 然后在获取到nacos实例后修改掉端口号就能改变最终的目标地址 在获取服务实例ServiceInstance retrievedInstance response.getServer()这行后面加一段代码 if (url.toString().equals(ws://im/ws)) {try {Field field retrievedInstance.getClass().getDeclaredField(port);field.setAccessible(true);field.set(retrievedInstance, 8082);} catch (Exception e) {e.printStackTrace();} }im相关的路由配置 - id: im_routeuri: lb://impredicates:- Path/im/**- id: im_ws_routeuri: lb:ws://impredicates:- Path/ws/**
http://www.hkea.cn/news/14415552/

相关文章:

  • 织梦教育培训网站源码怎么用PS做网站广告图
  • 青岛网站建设公司在哪国外男女直接做的视频网站
  • 营业执照注册网站包装设计接单网站
  • 做的好的网站着陆页wpautop wordpress
  • 网站没备案可以上线吗做个网站需要多少钱?有没有旧装修要拆
  • 网站用户群网站结构优化怎么做
  • 百度站长绵阳做最好优化网站的
  • 咸宁响应式网站建设价格更改wordpress管理地址
  • 做网站还得买域名吗如何安装wordpress博客
  • 更合网站设计定制平台
  • 公司网站文章wordpress换模板
  • 会展类网站模板企业网站有哪些类型
  • 深圳网站建设力荐上榜网络手机什么app做网站
  • 高大上公司网站minty wordpress
  • 网站建设自助搭配系统wordpress前台编辑
  • 2016市网站建设总结为什么辽宁省城乡建设厅网站打不开
  • 网网站建设设计公司淘宝购物返利网站建设app
  • 制作简历的免费网站深圳seo优化seo关键词
  • 个人网站电商怎么做中英文双语网站怎么做
  • 一站式做网站哪家专业网站平均停留时间
  • 本地邵阳网站建设北京中高端网站建设公司
  • 中小企业官方网站昆山企业做网站
  • 网站开发 链接指向文件夹网站后台管理默认密码
  • 赣州网站建设效果wordpress在线计算程序
  • 北京恒伟网站建设机房建设网站模板
  • 做网站广告词淘客网站后台怎么做
  • asp网站浏览器兼容多语言社交网站开发
  • 怎么上传网站到ftp泰安创意网络公司
  • 贵阳网站建设培训学校要学做网站
  • 做数学题网站在线图片处理工具