08 SpringCloud 微服务网关Gateway组件
网关简介
大家都都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?
如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去用。
这样的架构,会存在着诸多的问题:
- 每个业务都会需要鉴权、限流、权限校验、跨域等逻辑,如果每个业务都各自为战,自己造轮子实现一遍,会很蛋疼,完全可以抽出来,放到一个统一的地方去做。
- 如果业务量比较简单的话,这种方式前期不会有什么问题,但随着业务越来越复杂,比如淘宝、亚马逊打开一个页面可能会涉及到数百个微服务协同工作,如果每一个微服务都分配一个域名的话,一方面客户端代码会很难维护,涉及到数百个域名,另一方面是连接数的瓶颈,想象一下你打开一个APP,通过抓包发现涉及到了数百个远程调用,这在移动端下会显得非常低效。
- 后期如果需要对微服务进行重构的话,也会变的非常麻烦,需要客户端配合你一起进行改造,比如商品服务,随着业务变的越来越复杂,后期需要进行拆分成多个微服务,这个时候对外提供的服务也需要拆分成多个,同时需要客户端配合你进行改造,非常蛋疼。
上面的这些问题可以借助API网关来解决。
所谓的API网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、路由转发等等。
添加上API网关之后,系统的架构图变成了如下所示:
我们也可以观察下,我们现在的整体架构图:
1、什么是Spring Cloud Gateway
网关作为流量的入口,常用的功能包括路由转发,权限校验,限流等。
Spring Cloud Gateway 是Spring Cloud官方推出的第二代网关框架,定位于取代 Netflix Zuul1.0。相比 Zuul 来说,Spring Cloud Gateway 提供更优秀的性能,更强大的有功能。
Spring Cloud Gateway 是由 WebFlux + Netty + Reactor 实现的响应式的 API 网关。它不能在传统的 servlet 容器中工作,也不能构建成 war 包。
Spring Cloud Gateway 旨在为微服务架构提供一种简单且有效的 API 路由的管理方式,并基于 Filter 的方式提供网关的基本功能,例如说安全认证、监控、限流等等。
官网文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories
Spring Cloud Gateway 功能特征
- 基于Spring Framework 5, Project Reactor 和 Spring Boot 2.0 进行构建;
- 动态路由:能够匹配任何请求属性;
- 支持路径重写;
- 集成 Spring Cloud 服务发现功能(Nacos、Eruka);
- 可集成流控降级功能(Sentinel、Hystrix);
- 可以对路由指定易于编写的 Predicate(断言)和 Filter(过滤器);
1.1 核心概念
-
路由(route)
路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成。如果断言为真,则说明请求的URL和配置的路由匹配。 -
断言(predicates)
Java8中的断言函数,SpringCloud Gateway中的断言函数类型是Spring5.0框架中的ServerWebExchange。断言函数允许开发者去定义匹配Http request中的任何信息,比如请求头和参数等。 -
过滤器(Filter)
SpringCloud Gateway中的filter分为Gateway FilIer和Global Filter。Filter可以对请求和响应进行处理。
1.2 工作原理
执行流程大体如下:
1、Gateway Client向Gateway Server发送请求
2、请求首先会被HttpWebHandlerAdapter进行提取组装成网关上下文
3、然后网关的上下文会传递到DispatcherHandler,它负责将请求分发给RoutePredicateHandlerMapping
4、RoutePredicateHandlerMapping负责路由查找,并根据路由断言判断路由是否可用
5、如果过断言成功,由FilteringWebHandler创建过滤器链并调用
6、请求会一次经过PreFilter–微服务–PostFilter的方法,最终返回响应
2、Spring Cloud Gateway快速开始
2.1 环境搭建
1. 引入依赖
<!-- gateway网关 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
注意:会和spring-webmvc的依赖冲突,需要排除spring-webmvc
2.编写yml配置文件
server:port: 8888
spring:application:name: api-gatewaycloud:gateway:routes: # 路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]- id: product_route # 当前路由的标识, 要求唯一 uri: http://localhost:8081 # 请求要转发到的地址order: 1 # 路由的优先级,数字越小级别越高predicates: # 断言(就是路由转发要满足的条件)- Path=/product-serv/** # 当请求路径满足Path指定的规则时,才进行路由转发filters: # 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改- StripPrefix=1 # 转发之前去掉1层路径.
集成Nacos
现在在配置文件中写死了转发路径的地址, 前面我们已经分析过地址写死带来的问题, 接下来我们从注册中心获取此地址。
1. 引入依赖
<!-- nacos服务注册与发现 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2、 编写yml配置文件
server:port: 8888spring:application:name: api-gatewaycloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:routes:- id: product_routeuri: lb://service-product # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略predicates:- Path=/product-serve/**filters:- StripPrefix=1
简写: 去掉关于路由的配置,自动寻找服务
server:port: 8888spring:application:name: api-gatewaycloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:discovery:locator:enabled: true
测试:
这时候,就发现只要按照网关地址/微服务/接口的格式去访问,就可以得到成功响应。
2.2 路由断言工厂(Route Predicate Factories)配置
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories
作用: 当请求gateway的时候, 使用断言对请求进行匹配, 如果匹配成功就路由转发, 如果匹配失败就返回404
类型:内置,自定义
SpringCloud Gateway包括许多内置的断言工厂,所有这些断言都与HTTP请求的不同属性匹配。具体如下:
-基于Datetime类型的断言工厂
此类型的断言根据时间做判断,主要有三个:
AfterRoutePredicateFactory: 接收一个日期参数,判断请求日期是否晚于指定日期
BeforeRoutePredicateFactory: 接收一个日期参数,判断请求日期是否早于指定日期
BetweenRoutePredicateFactory: 接收两个日期参数,判断请求日期是否在指定时间段内
ZonedDateTime.now()
- After=2019-12-31T23:59:59.789+08:00[Asia/Shanghai]
- 基于远程地址的断言工厂
RemoteAddrRoutePredicateFactory:接收一个IP地址段,判断请求主机地址是否在地址段中
- RemoteAddr=192.168.1.1/24
- 基于Cookie的断言工厂
CookieRoutePredicateFactory:接收两个参数,cookie 名字和一个正则表达式。 判断请求
cookie是否具有给定名称且值与正则表达式匹配。
-Cookie=chocolate, ch.
-基于Header的断言工厂
HeaderRoutePredicateFactory:接收两个参数,标题名称和正则表达式。 判断请求Header是否具有给定名称且值与正则表达式匹配。
-Header=X-Request-Id, \d+
- 基于Host的断言工厂
HostRoutePredicateFactory:接收一个参数,主机名模式。判断请求的Host是否满足匹配规则。
-Host=**.testhost.org
- 基于Method请求方法的断言工厂
MethodRoutePredicateFactory:接收一个参数,判断请求类型是否跟指定的类型匹配。
-Method=GET
-基于Path请求路径的断言工厂
PathRoutePredicateFactory:接收一个参数,判断请求的URI部分是否满足路径规则。
-Path=/foo/{segment}
- 基于Query请求参数的断言工厂
QueryRoutePredicateFactory :接收两个参数,请求param和正则表达式, 判断请求参数是否具有给定名称且值与正则表达式匹配。
-Query=baz, ba.
- 基于路由权重的断言工厂
WeightRoutePredicateFactory:接收一个[组名,权重], 然后对于同一个组内的路由按照权重转发
routes:-id: weight_route1 uri: host1 predicates:-Path=/product/**-Weight=group3, 1-id: weight_route2 uri: host2 predicates:-Path=/product/**-Weight= group3, 9
自定义路由断言工厂
自定义路由断言工厂需要继承 AbstractRoutePredicateFactory
类,重写 apply 方法的逻辑。在 apply 方法中可以通过 exchange.getRequest()
拿到 ServerHttpRequest
对象,从而可以获取到请求的参数、请求方式、请求头等信息。
1、必须spring组件 bean
2. 类必须加上RoutePredicateFactory作为结尾
3. 必须继承AbstractRoutePredicateFactory
4. 必须声明静态内部类 声明属性来接收 配置文件中对应的断言的信息
5. 需要结合shortcutFieldOrder进行绑定
6.通过apply进行逻辑判断 true就是匹配成功 false匹配失败
注意: 命名需要以 RoutePredicateFactory 结尾
@Component
@Slf4j
public class CheckAuthRoutePredicateFactory extends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactory.Config> {public CheckAuthRoutePredicateFactory() {super(Config.class);}@Overridepublic Predicate<ServerWebExchange> apply(Config config) {return new GatewayPredicate() {@Overridepublic boolean test(ServerWebExchange serverWebExchange) {log.info("调用CheckAuthRoutePredicateFactory" + config.getName());if(config.getName().equals("xushu")){return true;}return false;}};}/*** 快捷配置* @return*/@Overridepublic List<String> shortcutFieldOrder() {return Collections.singletonList("name");}public static class Config {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}}
}
yml配置
spring:cloud:gateway:#设置路由:路由id、路由到微服务的uri、断言routes:- id: order_route #路由ID,全局唯一uri: http://localhost:8020 #目标微服务的请求地址和端口predicates:# 测试:http://localhost:8888/order/findOrderByUserId/1- Path=/order/** #Path路径匹配#自定义CheckAuth断言工厂 - CheckAuth=heiyu
2.3 过滤工厂(GatewayFilter Factories)配置
Gateway 内置了很多的过滤器工厂,我们通过一些过滤器工厂可以进行一些业务逻辑处理器,比如添加剔除响应头,添加去除参数等。
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories
2.3.1 添加请求头
spring:cloud:gateway:#设置路由:路由id、路由到微服务的uri、断言routes:- id: order_route #路由ID,全局唯一uri: http://localhost:8020 #目标微服务的请求地址和端口#配置过滤器工厂filters:- AddRequestHeader=X-Request-color, red #添加请求头
测试http://localhost:8888/order/testgateway
@GetMapping("/testgateway")
public String testGateway(HttpServletRequest request) throws Exception {log.info("gateWay获取请求头X-Request-color:"+request.getHeader("X-Request-color"));return "success";
}
@GetMapping("/testgateway2")
public String testGateway(@RequestHeader("X-Request-color") String color) throws Exception {log.info("gateWay获取请求头X-Request-color:"+color);return "success";
}
2.3.2 添加请求参数
spring:cloud:gateway:#设置路由:路由id、路由到微服务的uri、断言routes:- id: order_route #路由ID,全局唯一uri: http://localhost:8020 #目标微服务的请求地址和端口#配置过滤器工厂filters:- AddRequestParameter=color, blue # 添加请求参数
测试http://localhost:8888/order/testgateway3
@GetMapping("/testgateway3")
public String testGateway3(@RequestParam("color") String color) throws Exception {log.info("gateWay获取请求参数color:"+color);return "success";
}
2.3.3 为匹配的路由统一添加前缀
spring:cloud:gateway:#设置路由:路由id、路由到微服务的uri、断言routes:- id: order_route #路由ID,全局唯一uri: http://localhost:8020 #目标微服务的请求地址和端口#配置过滤器工厂filters:- PrefixPath=/mall-order # 添加前缀 对应微服务需要配置context-path
mall-order中需要配置
server:servlet:context-path: /mall-order
测试:http://localhost:8888/order/findOrderByUserId/1 ====》 http://localhost:8020/mall-order/order/findOrderByUserId/1
2.3.4 重定向操作
spring:cloud:gateway:#设置路由:路由id、路由到微服务的uri、断言routes:- id: order_route #路由ID,全局唯一uri: http://localhost:8020 #目标微服务的请求地址和端口#配置过滤器工厂filters:- RedirectTo=302, https://www.baidu.com/ #重定向到百度
测试:http://localhost:8888/order/findOrderByUserId/1
2.3.5 自定义过滤器工厂
继承AbstractNameValueGatewayFilterFactory
且我们的自定义名称必须要以GatewayFilterFactory结尾并交给spring管理。
@Component
@Slf4j
public class CheckAuthGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {@Overridepublic GatewayFilter apply(NameValueConfig config) {return (exchange, chain) -> {log.info("调用CheckAuthGatewayFilterFactory==="+ config.getName() + ":" + config.getValue());return chain.filter(exchange);};}
}
配置自定义的过滤器工厂
spring:cloud:gateway:#设置路由:路由id、路由到微服务的uri、断言routes:- id: order_route #路由ID,全局唯一uri: http://localhost:8020 #目标微服务的请求地址和端口#配置过滤器工厂filters:- CheckAuth=heiyu,男
2.4 全局过滤器(Global Filters)
局部过滤器和全局过滤器区别:
局部:局部针对某个路由, 需要在路由中进行配置
全局:针对所有路由请求, 一旦定义就会投入使用
GlobalFilter 接口和 GatewayFilter 有一样的接口定义,只不过, GlobalFilter 会作用于所有路由。
2.4.1 LoadBalancerClientFilter
LoadBalancerClientFilter
会查看exchange
的属性 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
的值(一个URI),如果该值的scheme是 lb,比如:lb://myservice
,它将会使用Spring Cloud的LoadBalancerClient 来将 myservice 解析成实际的host和port,并替换掉 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
的内容。
其实就是用来整合负载均衡器Ribbon的
spring:cloud:gateway:routes:- id: order_routeuri: lb://mall-orderpredicates:- Path=/order/**
2.4.2 自定义全局过滤器
@Component
public class LogFilter implements GlobalFilter {Logger log= LoggerFactory.getLogger(this.getClass());@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info(exchange.getRequest().getPath().value());return chain.filter(exchange);}
}
2.5 Gateway跨域配置(CORS Configuration)
通过yml配置的方式
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#cors-configuration
spring:cloud:gateway:globalcors:cors-configurations:'[/**]':allowedOrigins: "*"allowedMethods:- GET- POST- DELETE- PUT- OPTION
通过java配置的方式
@Configuration
public class CorsConfig {@Beanpublic CorsWebFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.addAllowedMethod("*");config.addAllowedOrigin("*");config.addAllowedHeader("*");UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());source.registerCorsConfiguration("/**", config);return new CorsWebFilter(source);}
}
2.6 Gateway整合sentinel流控降级
网关作为内部系统外的一层屏障, 对内起到一定的保护作用, 限流便是其中之一. 网关层的限流可以简单地针对不同路由进行限流, 也可针对业务的接口进行限流,或者根据接口的特征分组限流。
https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81
1、添加依赖
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2、添加配置
sentinel:transport:# 添加sentinel的控制台地址dashboard: 127.0.0.1:8080
2.6.1 控制台实现方式:
Sentinel 1.6.3 引入了网关流控控制台的支持,用户可以直接在 Sentinel 控制台上查看 API Gateway 实时的 route 和自定义 API 分组监控,管理网关规则和 API 分组配置。
从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:
- route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId
- 自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组
自定义异常方式:
1.通过yml
spring:cloud.sentinel.scg.fallback.mode = response
spring.cloud.sentinel.scg.fallback.response-body = '{"code":403,"mes":"限流了"}'
2.通过GatewayCallbackManager
@Configuration
public class GatewayConfig {@PostConstructpublic void init(){BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {@Overridepublic Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable throwable) {return ServerResponse.status(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue("降级了!"));}};GatewayCallbackManager.setBlockHandler(blockRequestHandler);}
}
2.7 网关高可用
为了保证 Gateway 的高可用性,可以同时启动多个 Gateway 实例进行负载,在 Gateway 的上游使用 Nginx 或者 F5 进行负载转发以达到高可用。
相关文章:
08 SpringCloud 微服务网关Gateway组件
网关简介 大家都都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢? 如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去用。 这样的架构,会存…...
极验3代 加密分析
目标链接 aHR0cHM6Ly93d3cuZ2VldGVzdC5jb20vZGVtby9zbGlkZS1mbG9hdC5odG1s接口分析 极验参数重要信息 gt和challenge;gt是固定的,但是challenge每次请求会产生不同的,这里的请求的并没有什么加密参数。 下一个请求 gettype.php,…...
python 数据分析可视化实战 超全 附完整代码数据
代码数据:https://download.csdn.net/download/qq_38735017/873799141.1 数据预处理1.1.1 异常值检测①将支付时间转为标准时间的过程中发生错误,经排查错误数据为‘2017/2/29’,后将其修改为‘2017/2/27’。②经检测发现部分订单应付金额与实付金额都为…...
有趣的HTML实例(十三) 咖啡选择(css+js)
一个人追求目标的路途是孤单的,一个人独品辛酸的时候是寂寥的,一个人马不停蹄的追赶着,狂奔着,相信前方是一片光明,我从不放弃希望,就像我对生活的信念,没有人可以动摇。 ——《北京青年》 目录…...
【力扣-LeetCode】1139. 最大的以 1 为边界的正方形 C++题解
1139. 最大的以 1 为边界的正方形难度中等137收藏分享切换为英文接收动态反馈给你一个由若干 0 和 1 组成的二维网格 grid,请你找出边界全部由 1 组成的最大 正方形 子网格,并返回该子网格中的元素数量。如果不存在,则返回 0。示例 1…...
【JavaGuide面试总结】Redis篇·下
【JavaGuide面试总结】Redis篇下1.如何使用 Redis 事务?2.如何解决 Redis 事务的缺陷?3.说说Redis bigkey吧4.大量 key 集中过期问题怎么解决的5.如何保证缓存和数据库数据的一致性?6.缓存穿透有哪些解决办法?7.缓存击穿有哪些解决…...
ForkJoinPool原理
1、概述 Fork/Join框架是Java7提供了的一个用于并行执行任务的框架。ForkJoinPool是Java中提供了一个线程池,特点是用来执行分治任务。主题思想是将大任务分解为小任务,然后继续将小任务分解,直至能够直接解决为止,然后再依次将任…...
02 python基本语法和数据类型
基本语法 python脚本可以在python交互式shell或者代码编辑器中编写与运行。python文件的扩展名一般为.py python使用缩进来区分不同的代码块,此特性有利于提高代码可读性。 下面是一个简单的python条件语句代码: 小明=矮穷错 小红=白富美 小华=高富帅 小李=程序员某人 = &quo…...
【办公类-16-09】“2022下学期 大班运动场地分配表-跳过节日循环排序”(python 排班表系列)
样例展示:跳过节日的运动场地循环排序表(8个班级8组内容 下学期一共20周)背景需求:上学期做过一次大班运动场地安排,跳过节日。2023.2下学期运动场地排班(跳过节日)又来了。一、场地器械微调二、…...
全网多种方法分析解决HTTP Status 404资源未找到的错误,TCP的3次握手,dns域名解析,发起http请求以及cookie和session的区别
文章目录1. 文章引言2. 简述URL3. http完整请求3.1 DNS域名解析3.2 TCP的3次握手3.3 发起http请求3.4 浏览器解析html代码3.5 浏览器对页面进行渲染呈现给用户4. 解决404错误的方法5. 补充知识点5.1 cookie和session的区别5.2 ChatGPT的介绍1. 文章引言 正赶上最近ChatGPT很火…...
Django图书商场购物系统python毕业设计项目推荐
mysql数据库进行开发,实现了首页、个人中心、用户管理、卖家管理、图书类型管理、图书信息管理、订单管理、系统管理等内容进行管理,本系统具有良好的兼容性和适应性,为用户提供更多的网上图书商城信息,也提供了良好的平台&#x…...
基于模型预测控制(MPC)的悬架系统仿真分析
目录 前言 1.悬架系统 2.基于MPC的悬架系统仿真分析 2.1 simulink模型 2.2仿真结果 2.3 结论 3 总结 前言 模型预测控制是无人驾驶中较为热门的控制算法,但是对于悬架等这类系统的控制同样适用。 我们知道模型预测控制主要可以划分为三个部分: …...
Word处理控件Aspose.Words功能演示:使用 Java 拆分 MS Word 文档
Aspose.Words 是一种高级Word文档处理API,用于执行各种文档管理和操作任务。API支持生成,修改,转换,呈现和打印文档,而无需在跨平台应用程序中直接使用Microsoft Word。此外,API支持所有流行的Word处理文件…...
图扑数字孪生智慧机场,助推民航“四型机场“建设
前言 民航局印发的《智慧民航建设路线图》文件中,明确提出智慧机场是智慧民航的四个核心抓手之一。并从机场全域协同运行、作业与服务智能化、智慧建造与运维方面,为智慧机场的发展绘制了清晰的蓝图。 效果展示 图扑软件应用自主研发核心产品 HT for …...
内网安装管家婆软件如何实现外网访问?内网穿透的几种方案教程
管家婆软件从网络架构上分两种版本:web(浏览器http端口)访问的版本和客户端(211固定端口sqlserver数据库)访问的版本。公司库管经常用仓库登录管家婆,一旦需要在公司外部登陆访问管家婆客户端,就…...
CCNP350-401学习笔记(1-50题)
1、Which function does a fabric edge node perform in an SD-Access deployment?A. Connects endpoints to the fabric and forwards their traffic. B. Encapsulates end-user data traffic into LISP. C. Connects the SD-Access fabric to another fabric or external La…...
基于微信小程序的新冠肺炎服务预约小程序
文末联系获取源码 开发语言:Java 框架:ssm JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏览器…...
网站项目部署在k8s案例与Jenkins自动化发布项目(CI/CD)
在K8s平台部署项目流程 在K8s平台部署Java网站项目 制作镜像流程 第一步:制作镜像 使用镜像仓库(私有仓库、公共仓库): 1、配置可信任(如果仓库是HTTPS访问不用配置) # vi /etc/docker/daemon.json { "…...
网络原理 (1)
网络原理 文章目录1. 前言: 2. 应用层2.1 XML2.2 json2.3 protobuffer3. 传输层3.1 UDP3.1 TCP4. TCP 内部的工作机制 (重点)1. 确认应答 2.超时重传3. 连接管理3.1 建立联系 :三次握手3.2 断开连接 : 四次挥手4. 滑动窗口5. 流量…...
LeetCode-1139. 最大的以 1 为边界的正方形【前缀和,矩阵】
LeetCode-1139. 最大的以 1 为边界的正方形【前缀和,矩阵】题目描述:解题思路一:前缀和。前缀和来记录边长。解题思路二:0解题思路三:0题目描述: 给你一个由若干 0 和 1 组成的二维网格 grid,请…...
windows10/11,傻瓜式安装pytorch(gpu),在虚拟环境anaconda
安装anaconda地址 :Anaconda | The Worlds Most Popular Data Science Platform安装选项全默认点击next就行。查看支持cuda版本cmd命令行输入nvidia-smi。下图右上角显示11.6为支持的cuda版本。要是显示没有nvidia-smi命令。得安装nvidia驱动,一般情况都…...
Revit导出PDF格式图纸流程及“批量导出图纸”
一、Revit导出PDF格式图纸流程 1、点击左上方“应用程序菜单”即“R”图标,进择“打印”选项。 2、在弹出的对话框中,需要设置图纸“打印范围”,选择“所选的视图/图纸选项”,点击“选择”,按钮,选择我们需…...
【自学Linux】 Linux文件目录结构
Linux文件目录结构 Linux文件目录结构教程 在 Linux 中,有一个很经典的说法,叫做一切皆文件,因此,我们在系统学习 Linux 之前,首先要了解 Linux 的文件目录结构。Linux 主要的目录有三大类,即根目录(/)&a…...
如何让APP在Google Play中成为特色
Google Play覆盖了 190 多个地区,数十亿的用户,所以开发者都会希望APP在应用商店中获得推荐位。 Google Play 上的精选热门应用类型:热门游戏或应用,畅销应用,安装量增长的应用,产生最多收入的应用。 那么…...
【C++】cin的处理过程
使用cin进行输入时,程序将输入视为一系列的字节,其中每个字节都被解释为字符编码。不管目标数据 类型是什么,输入一开始都是字符数据——文本数据。然后,cin对象负责将文本转换为其他类型。 为说明这是如何完成的,来看…...
读取Sentinel和Landsat 压缩包数据,直接进行波段重组、影像裁剪或者匀色镶嵌处理
波段重组在软件中查找:菜单栏-》影像基本处理-》波段处理-》波段重组,弹出如下对话框:根据对话框中的提示,输入需要处理的数据。注意:1、输入数据添加之后,需要点击其中任意一条数据,获取数据波…...
Yakit Web Fuzzer 终极能力强化:热加载 Fuzz
Background 在 HTB:BountyHunter 中,我们发现 Web Fuzzer 在使用中可以 “更强”,我们需要编写 Yak 脚本的事情,如果可以经过某些 Web Fuzzer 的优化,可以达到同样的效果。 在一个标签中,我们实现{{base6…...
Qt新手入门指南 - 如何创建模型/视图(三)
每个UI开发人员都应该了解ModelView编程,本教程的目标是为大家提供一个简单易懂的介绍。Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今ÿ…...
【Spring】手动实现简易AOP和IOC
前言 XML:通过Dom4j对XML进行解析和验证。 IOC:通过获取要创建对象的Class类型、构造函数后,通过反射来实现。 AOP:通过使用JDK动态代理和Cglib动态代理实现。 一、解析XML 1.1、解析bean标签 /*** 解析bean标签* param xmlBean…...
EasyExcel的使用
这里写目录标题先导入依赖最简单的写最简单的读項目开发中的一些操作xml一定要默認放先导入依赖 <dependencies><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.7</version><…...
大庆建设局网站/如何做宣传推广效果最好
搜索热词用file_get_contents()抓取了 这个网址上的内容http://simonfenci.sinaapp.com/index.PHP?keysimon&wd1314abc看似好像反回的是数组。。但是我不管怎么用foreach循环都报错。。我只想把数组中的word里面的值 取出来。方法如下:正解(其他的字段一样&…...
常州做网站的公司/免费引流推广的方法
首先:为什么需要动态定义数组呢? 这是因为,很多情况下,在预编译过程阶段,数组的长度是不能预先知道的,必须在程序运行时动态的给出 但是问题是,c要求定义数组时,必须明确给定数组的…...
申请个人营业执照需要什么资料/深圳搜狗seo
自MySQL5.1.0起,增加了一个非常有特色的功能–事件调度器(Event Scheduler),可以用做定时执行某些特定任务(例如:删除记录、对数据进行汇总等等),来取代原先只能由操作系统的计划任务来执行的工作。更值得一…...
灵犀科技网站建设/外链工具
1. 加载数据库驱动 通常来说,JDBC 使用 Class 类的 forName() 静态方法来加载驱动,需要输入数据库驱动代表的字符串。 例如: 加载 MySQL 驱动: Class.forName("com.mysql.jdbc.Driver"); 加载 Oracle 驱动: …...
毕设做网站什么能过/苏州seo关键词优化报价
精心挑选的12款优秀 jQuery Ajax 分页插件和教程转载于:https://www.cnblogs.com/zhujiabin/p/4565971.html...
洛阳网站开发/seo技术培训教程视频
xpath 省略中间路径在我的职业生涯的大部分时间里,我一直在从事软件开发工作,因此,即使我不止一次涉足解决方案工程,我还是把自己视为软件开发人员(或软件架构师)。 这肯定会对我如何看待架构景观产生影响&…...