【微服务】2、网关
Spring Cloud微服务网关技术介绍
- 单体项目拆分微服务后的问题
- 服务地址问题:单体项目端口固定(如黑马商城为8080),拆分微服务后端口各异(如购物车808、商品8081、支付8086等)且可能变化,前端难以确定请求的服务地址及应对变化。
- 登录校验问题:单体项目登录校验后所有功能可获取用户信息,拆分后若各微服务都做登录校验,代码重复度高,且分发密钥风险大。
- 网关解决方案及作用
- 网关功能概述:网关负责请求路由转发和身份校验,类似小区看门大爷,住户类比微服务。前端只需知网关地址(设为8080),所有请求发往网关后,网关根据请求路由至相应微服务(如查商品路由到商品微服务,查用户路由到用户微服务),并在路由前校验用户身份,登录则解析获取用户信息并向后传递,避免微服务重复校验,同时保护微服务,使前端开发体验与单体架构一致,成为微服务开发必备组件。
- 路由转发与微服务地址获取:网关通过注册中心获取微服务地址,微服务启动时注册信息到注册中心,网关启动后拉取,地址变更时注册中心推送。微服务多实例部署时,网关利用负载均衡算法挑选实例转发请求。
- Spring Cloud网关组件
- 网关路由转发功能介绍与入门案例规划
- 核心功能阐述:网关主要有两个核心功能,一是对前端请求进行路由转发,二是对用户身份进行校验,本节课主要学习路由转发功能。
- 路由转发流程分析:由于微服务拆分,前端难以知晓请求对象,网关作为微服务群入口,可从注册中心获取服务地址,前端请求网关后,网关判断应由哪个微服务处理(路由),再从注册中心拉取实例列表并负载均衡挑选实例发送请求(转发)。
- 入门案例步骤规划:创建网关服务实现路由转发分为四步,重点是路由规则配置,包括创建新项目模块、引入网关相关依赖、编写启动类、配置路由规则,其中前三步是创建网关微服务,依赖坐标可复制,本节课重点学习路由规则配置。
Spring Cloud网关路由特殊配置
网关路由特殊配置引入
- 背景:上节课学习了网关路由规则基本配置,能满足多数开发需求,但特殊复杂需求需特殊路由配置。
- 路由配置类:网关路由配置由
RouteDefinition
类读写,常见四个属性,ID
是路由唯一标识,URI
是目标服务地址,配置方式与上节课基本一致;重点关注路由断言predicates
和路由过滤器filters
属性。
路由断言
- 作用:判断请求是否符合规则,符合则路由到对应目标地址。
- 断言方式
- Spring内部提供12种,如按请求路径匹配的
Path
、按时间判断的After
和Before
(与After
相反)、按请求头、cookie、请求方式等匹配。 - 语法与上节课类似,路径规则中
{}
为占位符,一般按/
开头后接*
的方式配置。
- Spring内部提供12种,如按请求路径匹配的
- 配置方式:可参考官网
spring cloud gateway
中的Route Predicate Factory
部分,路由断言由工厂类处理,工厂名以RoutePredicateFactory
为后缀,以路由规则名字为前缀,官网有详细示例。
路由过滤器
- 作用:对进入网关的前端请求和微服务响应结果进行加工处理。
- 过滤器种类及示例
- Spring提供30多种,如
AddRequestHeader
(添加请求头)、RemoveRequestHeader
(移除请求头)、AddResponseHeader
(添加响应头)、RemoveResponseHeader
(移除响应头)、RewritePath
(重写请求路径)、StripPrefix
(去除请求路径中的N段前缀)等。 - 以
StripPrefix
为例,可解决前端请求路径与微服务路径不一致问题,如前端请求路径含/API
前缀,微服务路径无此前缀,可通过StripPrefix
去除前缀使路由正确。
- Spring提供30多种,如
- 配置语法:与路由断言类似,如
AddRequestHeader
过滤器,等号左边为过滤器名字,右边为以逗号隔开的键值形式参数(请求头的key
和value
)。 - 演示示例:以添加请求头过滤器
AddRequestHeader
为例,在idea
中操作,在商品微服务路由下添加filters
,具体配置可参考源码或直接复制粘贴,如添加名为truth
的请求头,值为anyone Long press like button will be rich
;在商品微服务controller
中利用@RequestHeader
注解获取请求头并打印(设置required = false
),测试时先重启网关和商品服务,访问网关后查看idea
中是否成功打印出添加的请求头内容,以此验证过滤器生效。
默认过滤器配置
- 配置方法:若希望过滤器对所有路由生效,可配置在
defaultFilter
下,与路由同级,无需在每个路由中单独配置。 - 验证测试:测试时仅需重启网关,再次访问网关查看是否能获取到请求头,以此验证默认过滤器对所有路由生效。
- 网关实现登录校验功能的分析与思路
- 登录授权功能部署:采用JWT登录,登录授权功能置于user service(用户微服务),登录后颁发JWT token,可从token解析用户信息。
- 多微服务对用户信息的需求及校验问题:多个微服务(如购物车服务、交易服务)需知晓登录用户信息,若在各微服务分别进行JWT校验,会导致代码重复且增加密钥泄露风险,因此考虑在网关进行校验并向后传递用户信息。
- 校验时机的重要性:JWT校验必须在网关将请求转发到微服务之前完成,否则校验失去意义。
-
网关底层处理流程剖析
- 路由规则判断:网关底层基于路由规则判断前端请求应由哪个微服务处理,此过程由handler mapping接口(默认实现为root predicted handler mapping)基于路由断言完成路由规则匹配,找到符合请求的路由后存入上下文并转交给web handler接口。
- 过滤器链的形成与作用:web handler接口(默认实现为filtering web handler)找到当前请求对应路由生效的过滤器,排序形成过滤器链,依次调用。过滤器链中的netty routine filter默认对所有路由生效且在最后执行,负责将请求转发到微服务,微服务执行完返回结果后它进行封装并存入上下文,再依次返回给其他过滤器和用户。
- 过滤器的PRE和POST逻辑:过滤器内部有PRE和POST两部分逻辑,请求进入先执行PRE逻辑,若失败则结束,成功才继续调用下一个过滤器的PRE逻辑;执行到netty routine filter的PRE逻辑时将请求转发到微服务,微服务执行完进入POST阶段,结果经netty routine filter封装存入上下文后依次返回给上一个过滤器,PRE阶段按顺序执行,POST阶段倒序执行。
-
网关转发前校验方案及用户信息传递问题
- 自定义过滤器实现校验:需在网关内自定义过滤器,保证其执行顺序在netty routine filter之前,在PRE逻辑里实现JWT校验,从而确保转发前完成校验。
- 网关与微服务间用户信息传递方式:网关校验得到用户信息后,将用户信息放入请求头传递给微服务。
- 微服务之间用户信息传递问题及差异:复杂业务中微服务间相互调用(如交易服务调用购物车服务)时也需传递用户信息,虽同样基于HTTP请求,但实现方式与网关到微服务传递有所不同,因为微服务间的HTTP请求基于open feign发起,而网关到微服务是网关内置的请求方式。
网关过滤器自定义及登录校验逻辑实现
网关过滤器种类
- gateway filter
- 之前在学习网关路由时见过,在路由配置属性中有filters,其可指定过滤器及参数。
- 过滤器约30多种,默认不生效,可配置到特定路由或default filter下,针对指定路由或所有路由生效,灵活性高,能任意指定作用范围。
- global filter(全局过滤器)
- 作用范围是所有路由,进入网关的请求都会被处理,无需指定或选择,声明后自动生效,使用更简单。
- 两种过滤器的filter方法在返回值、方法名和方法参数上完全一样,该方法是编写过滤逻辑的核心,编写登录校验逻辑时方法差别不大,以global filter为例解读方法信息。
过滤器方法参数及返回值(以global filter为例)
- 方法参数
- server web exchange:网关内部上下文对象,用于保存网关内部共享数据,如request、response、session等,过滤器链中所有过滤器可从中读取和存入数据。
- gateway filter chain:过滤器链,自定义过滤器业务逻辑处理完后,调用它来调用下一个过滤器,使整个链条串联。
- 返回值
- 返回值为mono,网关过滤器内部分为PRE和post两部分逻辑,实现filter方法后写的业务属于PRE部分。PRE执行完调用chain调用下一个过滤器,所有过滤器PRE执行完后将请求转发到微服务,微服务返回结果才执行post部分。
定义global filter示例
- 定义一个类实现global filter接口,加上component注解注册为spring bean,实现filter方法编写PRE逻辑(如模拟登录校验逻辑,先获取请求头,这里仅打印请求头,实际登录校验时再从请求头获取登录凭证)。
- 校验逻辑完成后利用chain放行(调用filter方法并传入exchange,使下一个过滤器可使用上下文)。
控制过滤器执行顺序
- 过滤器定义后要保证在netty routing filter之前执行,因为其作用是做转发,希望在转发前做登录校验,所以优先级要更高。
- 通过查看nt routing filter源码发现它实现了order接口来排序,order接口要求实现get order方法返回int值,值越小优先级越高,netty routing filter默认优先级为integer最大值(最低优先级)。
- 自定义过滤器实现order接口并设置较小优先级值(如0)即可在其之前执行
总结
- 自定义global filter方式:写类实现接口,实现filter方法利用
ServerWebExchange exchange
获取请求信息做登录校验,校验完成利用过滤器链放行。 - 控制过滤器执行顺序靠order接口,实现get order方法返回int值,值越小优先级越高,NTROUTFILTER默认优先级最低,自定义过滤器值比其小即可。掌握这些后,登录校验可行。
自定义gateway filter概述
- gateway filter特点:使用时可自由指定作用范围,能配置自定义参数,比global filter更灵活,但自定义较麻烦,日常开发多选用global filter,做登录校验功能时也常用global filter。
- 自定义方式:需继承abstract gateway filter factory,其作用是读取配置创建定制化过滤器对象,采用工厂模式,定义的是过滤器工厂。过滤器工厂内有apply方法,基于配置创建过滤器对象,采用匿名内部类实现filter方法编写逻辑。
- 过滤器工厂命名要求:名字必须以gateway filter factory为后缀,类名前缀将作为过滤器名字在配置文件中使用。
- 无参gateway filter的定义与实现
- 定义无参过滤器工厂类:如print any gateway filter工厂类,继承Abstract gateway filter factory,泛型为object,实现apply方法。
- 注册工厂类:给工厂类加@Component注解注册为bean。
- 构造过滤器:在apply方法中用匿名内部类构造gateway filter,实现filter方法,可编写PRE或post逻辑,此处仅打印执行信息。
- 过滤器执行顺序问题:全局过滤器和自定义过滤器执行顺序需控制,匿名内部类无法实现order接口指定顺序,解决办法一是单独写类实现gateway filter和order接口,二是使用装饰模式。
- 装饰模式实现:定义
OrderGatewayFilter
类,接受gateway filter和order参数,实现GTFILTER和order接口,构造函数记录参数,filter方法调用委托对象的filter方法,返回记录的order,使用该装饰模式为自定义过滤器添加顺序。 - 配置生效与测试:在yml文件中配置过滤器,可定义在某一路由下或default下(作用于所有),配置print any过滤器。重启服务,清空日志,浏览器访问后查看日志,验证global filter先执行(顺序为1),print any gateway filter后执行(顺序为0,值越大优先级越低)。
- 带参gateway filter的定义方式
- 定义属性类:自定义带参gateway filter更复杂,需定义专门属性类匹配参数,一般定义在过滤器工厂内部为内部类,变量数量与参数数量对应。
网关登录校验功能实现
- 准备工作及工具介绍
- 网关过滤器类型:网关过滤器有gateway filter和global filter两种,日常开发多用global filter,本节课用它实现登录校验功能。
- 黑马商城登录方式:基于JWT实现,相关密钥和工具类在单体架构项目hm service中,需拷贝到网关项目。包括保存JWT密钥的加密文件hmall.jks、加载属性的
JwtProperties类
、生成密钥并注册到spring容器的SecurityConfig类
、配置不需要登录校验路径的exclude paths、读取路径属性AuthProperties
类,以及生成和解析token的工具类JwtTool
。
- 工具拷贝与配置
- 拷贝属性类:将jw properties、OLI等属性类拷贝到网关项目新建的CONFIG包中,标记为component使其生效。
- 拷贝工具类:拷贝工具类GDP t two到网关项目,解决报错问题。
- 拷贝密钥文件和配置文件:将密钥文件HMGK和相关配置文件拷贝到网关项目。
- 定义全局过滤器:定义名为OsGlobalFilter的全局过滤器,实现global filter和order接口,设置order值为0,在filter方法中编写登录校验逻辑,包括获取request对象,判断请求路径是否在放行路径中,若在则放行,不在则获取token并校验解析,校验失败用401状态码拦截,校验通过则传递用户信息(本节课先打印用户id,后续再实现传递)。
- 校验token与拦截逻辑
- 获取token:从request获取header,通过指定请求头名字authorization获取token,判断header不为空且不为null时取出token。
- 校验token:利用拷贝过来的工具类jp t two校验解析token,校验失败时try catch捕获异常,用401状态码拦截并设置response状态码为Unauthorized,终止请求。
- 传递用户信息:校验通过则传递用户信息(本节课先打印用户id)。
- 路径校验与整体回顾
- 路径校验方法:定义判断请求路径是否需要被拦截的方法,通过注入all properties类获取放行路径,利用spring提供的ant pass match匹配器判断请求路径与放行路径是否匹配,循环遍历所有放行路径,若匹配则返回true,否则返回false。
- 测试与回顾:完成过滤器逻辑后,配置购物车服务路由路径cars,重启网关服务进行测试。未登录访问购物车路径返回401,登录后可成功查询,说明登录拦截生效。回顾网关登录校验逻辑,主要包括获取请求和token、校验token、根据校验结果拦截或放行,拦截时通过response设置状态码401并结束请求,路径判断通过ant pass match匹配器判断配置路径与当前路径是否匹配。掌握这些API可实现整套登录拦截逻辑。
从网关到微服务的用户传递实现方法
- 实现思路
- 请求流程与用户信息传递方式:请求先到网关,网关过滤器中已实现登录校验并获取用户信息。网关到微服务是新的请求,将用户信息保存到请求头是传递信息的最佳方案,微服务可从请求头获取用户信息。
- 微服务获取用户信息的优化:微服务业务接口基于Spring MVC,为避免在每个业务接口获取登录用户信息,可在所有业务接口执行前,通过Spring MVC拦截器获取请求头中的用户信息并保存到ThreadLocal,后续业务可随时取用。
- 网关过滤器保存用户信息到请求头
- 利用API修改请求头:网关提供了ServerWebExchange上下文对象,其mutate方法可对下游请求进行改变和处理,通过该方法返回的RequestBuilder可修改请求头信息。
- 约定请求头名称与设置值:请求头名称可自定义,但需与微服务开发者约定好,本案例约定为user info,其值为用户ID(long型转字符串)。
- 完成请求头修改与传递:修改完请求头后,需调用build方法构建新的ServerWebExchange,并将其传递到下一个过滤器,以确保修改生效。
- 测试用户信息传递:在购物车服务的Controller中获取并打印请求头中的user info,重启网关后,通过查询购物车操作测试用户信息是否传递成功。
- 微服务编写拦截器获取用户信息
- 拦截器编写与功能实现
- 创建拦截器类:在common模块的interceptor包下新建UserInfoInterceptor拦截器,实现HandlerInterceptor接口,只需实现preHandle和afterCompletion方法。
- 获取并保存用户信息:在preHandle方法中,从Spring MVC的request对象获取请求头中的用户信息(与网关约定的user info一致),使用工具类判断不为空后,通过common中的UserContext将用户信息(字符串转long型)存入ThreadLocal。
- 清理用户信息:在afterCompletion方法中,调用UserContext的removeUser清理用户信息。
- 拦截器配置与生效问题解决
- 配置拦截器:定义Spring MVC配置类MvcConfig,实现WebMvcConfigure接口并加Configuration注解,在addInterceptor方法中将UserInfoInterceptor添加到拦截器注册器,默认拦截所有路径。
- 解决配置类扫描问题:由于配置类所在包与微服务包不同,需在resource目录下的meta - info下的spring.factories文件中记录配置类名字,使配置类生效。
- 避免网关引用报错:因网关引用了common且无Spring MVC,会导致配置类在网关报错。通过给配置类加@ConditionalOnClass注解,以判断是否存在Spring MVC的核心API DispatcherServlet为条件,使配置类仅在微服务生效。
- 测试拦截器生效:重启网关和微服务(如购物车服务),测试拦截器是否生效,如查询购物车时,日志显示能从ThreadLocal获取到正确的用户ID,而非写死的值。
- 拦截器编写与功能实现
- 总结回顾
- 网关传递用户信息:网关通过过滤器获取用户信息,利用exchange的API修改请求头,将用户信息添加到请求头中传递给微服务。
- 微服务获取用户信息:微服务通过在common模块定义拦截器,在所有业务接口执行前获取请求头中的用户信息并保存到ThreadLocal,方便后续业务使用。
- 问题解决与技术应用:解决了拦截器配置生效问题,包括配置类扫描和网关引用报错问题,运用了Spring Boot自动装配原理。通过在spring.factories文件中记录配置类名字实现自动装配,利用@ConditionalOnClass注解根据项目中是否存在Spring MVC的核心API来控制配置类生效范围。这表明Spring Boot自动装配原理在实际开发中可解决诸多问题,如本案例中的拦截器配置问题,同时也为后续在微服务之间传递登录用户信息等操作奠定了基础。
- 微服务间用户信息传递问题引出
- 背景:实现从网关到微服务的用户信息传递后,复杂业务场景中微服务间相互调用时的用户信息传递面临挑战。
- 场景示例:以用户下单场景为例,涉及交易服务、商品服务和购物车服务。前端请求先进入交易服务,交易服务保存订单时需向商品服务扣减库存、向购物车服务清理购物车。
- 用户信息传递流程及问题分析
- 正常流程
- 前端带JWT token请求到网关,网关过滤器校验token,有效则解析用户信息存于请求头并转发给微服务。
- 微服务通过通用拦截器从请求头获取用户信息,如交易服务可拿到登录用户信息创建订单。
- 现有问题
- 交易服务调用购物车服务时未传用户id,仅传商品id。
- 购物车服务从user context获取用户id,但因请求头无用户信息导致获取失败。
- 原因是交易服务调用购物车服务未处理请求头,而购物车服务获取用户方式依赖user context,其前提是拦截器能从请求头取用户信息并存入user context,当前交易服务调用购物车服务时请求头无用户信息。
- 正常流程
- OpenFeign拦截器解决方案
- 拦截器原理与作用:OpenFeign的request interceptor接口,其apply方法在每次请求时调用,可利用request template修改请求头,如添加请求头信息。
- 拦截器定义与配置
- 定义位置:因所有微服务调用其他服务时都需传递用户信息,故定义在公共的HM-api模块最合适,这样引用该模块的微服务在发起远程调用时拦截器自动生效。
- 定义方式:采用匿名内部类声明,实现apply方法,在方法内从user context获取用户信息(需添加common依赖以使用user context),判断用户id不为空后添加到请求头。
- 生效条件:配置类需加在Feign启动类上。
- 测试效果:重启交易服务后下单测试,查看购物车服务日志,发现其执行业务时成功拿到user context中的用户信息,购物车成功删除,证明用户信息传递成功。
- 总结回顾微服务用户信息传递方案
- 过滤器和拦截器总结
- 网关的global filter过滤器:进行JWT登录校验,获取用户信息后保存到请求头转发给微服务。
- 微服务的handler interceptor拦截器:从请求头获取用户信息后保存到thread local,方便微服务内部业务使用。
- OpenFeign的request interceptor拦截器:在微服务间基于OpenFeign调用时,将用户信息保存到请求头,确保下游微服务能获取用户信息。
- 方案价值:此方案是解决微服务体系登录功能的整体思路,公司实现思路与之类似,对实际开发具有重要参考价值。
- 过滤器和拦截器总结
相关文章:
【微服务】2、网关
Spring Cloud微服务网关技术介绍 单体项目拆分微服务后的问题 服务地址问题:单体项目端口固定(如黑马商城为8080),拆分微服务后端口各异(如购物车808、商品8081、支付8086等)且可能变化,前端难…...
计算机网络--路由表的更新
一、方法 【计算机网络习题-RIP路由表更新-哔哩哔哩】 二、举个例子 例1 例2...
网络安全抓包
#知识点: 1、抓包技术应用意义 //有些应用或者目标是看不到的,这时候就要进行抓包 2、抓包技术应用对象 //app,小程序 3、抓包技术应用协议 //http,socket 4、抓包技术应用支持 5、封包技术应用意义 总结点:学会不同对象采用…...
字玩FontPlayer开发笔记8 Tauri2文件系统
字玩FontPlayer开发笔记8 Tauri2文件系统 字玩FontPlayer是笔者开源的一款字体设计工具,使用Vue3 ElementUI开发,源代码: github: https://github.com/HiToysMaker/fontplayer gitee: https://gitee.com/toysmaker/fontplayer 笔记 字玩目…...
http源码分析
一、HttpURLConnection http连接池源码分析 二、HttpClient 连接池,每个路由最大连接数 三、OkHttp okhttp的连接池与socket连接...
【vim】vim常用操作总结
vim常用操作总结 一,简介二,操作介绍2.1 命令模式2.1.1 删除(剪切)光标所在行2.1.2 复制2.1.3 粘贴2.1.4 跳到行末2.1.5 跳到行首2.1.6 撤销操作 2.2 视图模式2.3 命令模式2.4 编辑模式 三,总结 一,简介 在…...
【学Rust开发CAD】1 环境搭建
文章目录 一、搭建C/C编译环境二、安装Rust三、配置 PATH 环境变量四、验证安装结果五、安装编辑工具 一、搭建C/C编译环境 Rust 的编译工具依赖 C 语言的编译工具,这意味着你的电脑上至少已经存在一个 C 语言的编译环境。如果你使用的是 Linux 系统,往…...
RK3588开发笔记-spi接口调试
目录 前言 一、SPI接口简介 二、原理图连接 三、设备树配置 四、spi调试 五、spi应用软件接口 总结 前言 在嵌入式系统开发中,SPI(Serial Peripheral Interface)接口作为一种同步、全双工、多设备、多主机的通信协议,广泛应用于连接各种外围设备,如ADC、DAC、数据存…...
AlphaPi相关硬件驱动提取
初涉硬件编程,在咸鱼上搞了几块AlphaPi和microbit的板鼓捣了一下,alphapi生态不完善,网上又无任何文档,搞封闭,可玩性实在有限,但貌似相关扩展板是可以插microbit的,于是想把这些扩展版用microb…...
【Unity3D】Text文本文字掉落效果
相关技术:Text、TextMesh、Rigidbody(刚体)、BoxCollider(碰撞体)、TextGenerator、文本网格、文字网格 原理:使用UGUI Text获取其文字的每个字符网格坐标,转世界坐标生成对应的3D文本(TextMesh…...
MySQL内置函数详解
MySQL内置函数详解 1. 字符串函数 1.1 基本字符串处理 -- 字符串长度 SELECT LENGTH(Hello MySQL); -- 返回11-- 字符串大小写转换 SELECT LOWER(HELLO), UPPER(hello); -- 返回 hello, HELLO-- 字符串截取 SELECT SUBSTRING(MySQL Database, 1, 5); -- 返回 MySQL SELEC…...
【网络安全设备系列】9、WAF(Web应用防火墙)
0x00 定义: Web应用防火墙是通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提供保护的一种设备。 WAF需要部署在Web服务器的前面,串行接入,不仅在硬件性能上要求高,而且不能影响Web服务,所以HA功能、Bypass功能都是必…...
Express 加 sqlite3 写一个简单博客
例图: 搭建 命令: 前提已装好node.js 开始创建项目结构 npm init -y package.json:{"name": "ex01","version": "1.0.0","main": "index.js","scripts": {"test": &q…...
【C++数据结构——图】图的邻接矩阵和邻接表的存储(头歌实践教学平台习题)【合集】
目录😋 任务描述 相关知识 1. 带权有向图 2. 图的邻接矩阵 3. 图的邻接表 测试说明 通关代码 测试结果 任务描述 本关任务:编写一个程序实现图的邻接矩阵和邻接表的存储。 相关知识 为了完成本关任务,你需要掌握: 带权有向图…...
基于单片机的直流稳压电源的设计(论文+源码)
1.系统方案设计 在本次直流稳压电源的设计中,其关键指标如下: 系统输入电压220V交流系统输出直流0到12V可调,步进可以达到0.1V电流最大输出可以到2A具有短路保护功能可以通过液晶或者数码管等显示设备显示当前输出电压 2. 电路图...
Golang开发-案例整理汇总
前言 CSDN的文章缺少一个索引所有文章分类的地方,所以手动创建这么一个文章汇总的地方,方便查找。Golang开发经典案例汇总 GoangWeb开发 GolangWeb开发- net/http模块 GolangWeb开发-好用的HTTP客户端httplib(beego) GolangWeb开发- Gin不使用Nginx部署Vue项目 Golang并发开…...
从入门到精通:Ansible Shell 模块的应用与最佳实践
Ansible是一款强大的自动化运维工具,通过其模块化的设计,可以方便地管理和配置远程主机。作为Ansible的一个常用模块,shell 模块使得我们可以在目标主机上执行复杂的命令或脚本。无论是单一的命令,还是复杂的Shell脚本,…...
【Javascript Day1】javascript基础
javascript编程规则 弹窗(举例) alert("内容"),直接写在控制区生效 三种写法 1、行内js语法 :需要注意引号的问题 <input type"button" value"提示窗" οnclick alert("消息") &…...
dbeaver导入导出数据库(sql文件形式)
目录 前言dbeaver导出数据库dbeaver导入数据库 前言 有时候我们需要复制一份数据库,可以使用dbeaver简单操作! dbeaver导出数据库 选中数据库右键->工具->转储数据库 dbeaver导入数据库 选中数据库右键->工具->执行脚本 mysql 默…...
字玩FontPlayer开发笔记6 Tauri2设置菜单
字玩FontPlayer开发笔记6 Tauri2设置菜单 字玩FontPlayer是笔者开源的一款字体设计工具,使用Vue3 ElementUI开发,源代码: github: https://github.com/HiToysMaker/fontplayer gitee: https://gitee.com/toysmaker/fontplayer 笔记 字玩目…...
大学生HTML5期末作业 Web前端网页制作 html5+css3+js html+css+js网页设计 美食 美食3个页面(带js)
大学生HTML5期末作业 Web前端网页制作 html5css3js htmlcssjs网页设计 美食 美食3个页面(带js) 网页作品代码简单,可使用任意HTML辑软件(如:Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行…...
创龙3588——debian根文件系统制作
文章目录 build.sh debian 执行流程build.sh源码流程 30-rootfs.sh源码流程 mk-rootfs-bullseys.sh源码流程 mk-sysroot.sh源码流程 mk-image.sh源码流程 post-build.sh 大致流程系统制作步骤 build.sh debian 执行流程 build.sh 源码 run_hooks() {DIR"$1"shiftf…...
element组件el-select、el-tree-select有值,不渲染lable
大致情况是这个样子的............ 之前vue页面和script脚本是放在一个页面的,今天把页面和脚本拆开了。这一拆不打紧,完犊子!它奶奶的el-select、el-tree-select这俩组件不正常显示了!!! 我这个是vite-vue…...
【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】
目录😋 任务描述 相关知识 一、线性表的基本概念 二、初始化线性表 三、销毁线性表 四、判定是否为空表 五、求线性表的长度 六、输出线性表 七、求线性表中某个数据元素值 八、按元素值查找 九、插入数据元素 十、删除数据元素 测试说明 通关代码 测…...
2025第1周 | JavaScript中的正则表达式
目录 1. 正则表达式是个什么东东?1.1 怎么定义正则1.2 对象字面量方式1.3 类创建方式 2. 怎么使用2.1 实例方法2.1.1 exec方法2.1.2 test方法 2.2 字符串中的方法2.2.1 match/matchAll2.2.2 replace/replaceAll2.2.3 split2.2.4 search 3. 规则3.1 修饰符3.2 字符类…...
模型 九屏幕分析法
系列文章 分享 模型,了解更多👉 模型_思维模型目录。九屏幕法:全方位分析问题的系统工具。 1 九屏幕分析法的应用 1.1 新产品研发的市场分析 一家科技公司计划开发一款新型智能手机,为了全面评估市场潜力和风险,他们…...
快速排序(霍尔法),冒泡排序 【C语言】
冒泡排序 效率低,但是稳定性高 代码 // 冒泡排序 void maopao(int a[]);int main() {int a1[10] {34,78,29,46,12,85,63,92,57,31};printf("\n排序前:\n");print(a1);maopao(a2);printf("冒泡排序后:");print(a2); }//冒泡排序 void maopao(…...
国产编辑器EverEdit - 两种删除空白行的方法
1 使用技巧:删除空白行 1.1 应用场景 用户在编辑文档时,可能会遇到很多空白行需要删除的情况,比如从网页上拷贝文字,可能就会存在大量的空白行要删除。 1.2 使用方法 1.2.1 方法1: 使用编辑主菜单 选择主菜单编辑 …...
20241230 AI智能体-用例学习(LlamaIndex/Ollama)
AI小白一枚,入门实验。 1. Pg-Hydra 颠覆数据库体验:Hydra —— 开源的列式存储 PostgreSQL-CSDN博客 git clone https://github.com/hydradatabase/hydra && cd hydra cp .env.example .env docker compose up psql postgres://postgres:hydra@127.0.0.1:5432 do…...
2024年终总结及计划
24年收获不少,早就想总结下,但是有的问题不想去思考,也不想去面对,就晚了几天,趁着加班总结反思下。 一、计划完成情况 1、生活 ①运动:继续坚持每周慢跑15公里,这是必须要做的。另外&#x…...
基于深度学习算法的AI图像视觉检测
基于人工智能和深度学习方法的现代计算机视觉技术在过去10年里取得了显著进展。如今,它被广泛用于图像分类、人脸识别、图像中物体的识别等。那么什么是深度学习?深度学习是如何应用在视觉检测上的呢? 什么是深度学习? 深度学习是…...
分布式环境下定时任务扫描时间段模板创建可预订时间段
🎯 本文详细介绍了场馆预定系统中时间段生成的实现方案。通过设计场馆表、时间段模板表和时间段表,系统能够根据场馆的提前预定天数生成未来可预定的时间段。为了确保任务执行的唯一性和高效性,系统采用分布式锁机制和定时任务,避…...
谷粒商城-高级篇完结-Sleuth+Zipkin 服务链路追踪
1、基本概念和整合 1.1、为什么用 微服务架构是一个分布式架构,它按业务划分服务单元,一个分布式系统往往有很多个服务单元。由于服务单元数量众多,业务的复杂性,如果出现了错误和异常,很难去定位 。主要体现在&#…...
GraphRAG:LLM之Graphrag接入milvus
前言 微软目前的graphrag更像个demo,数据量大的时候不是很友好的啊,所以将milvus接入了graphrag,看完这篇文章,其他数据库接入应该也没问题 注:这篇文章只是在search的时候接入进来,index过程或者说整个流…...
flink cdc oceanbase(binlog模式)
接上文:一文说清flink从编码到部署上线 环境:①操作系统:阿里龙蜥 7.9(平替CentOS7.9);②CPU:x86;③用户:root。 预研初衷:现在很多项目有国产化的要求&#…...
【算法】算法初步
要学好数据结构和算法的设计与分析,请务必先打好C语言基础,因为C语言中的数据存储、内存映射、指针等等概念最接近计算机的底层原理,数据结构是数据在内存空间当中的组织形式,而算法则是提供了解决某个问题的一种思路,…...
Eureka原理
my: 服务注册与发现 心跳 自我保护 故障转移 Eureka 原理 Eureka 是一个由 Netflix 开源的服务注册与发现框架,广泛用于微服务架构中,尤其是 Spring Cloud 中的服务注册与发现。Eureka 的主要作用是管理和协调分布式系统中的服务实例,使…...
关于linux的ld.so.conf.d
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...
Linux Shell 脚本编程基础知识篇—awk的条件判断(3)
ℹ️大家好,我是练小杰,今天周五了,又是一周过去了😆 本文是有关Linux shell脚本编程的awk命令的条件语句,后续我会不断增加相关内容 ~~ 回顾:【awk字符串函数和内置变量】 更多Linux 相关内容请点击👉【Li…...
安装Cockpit服务,使用Web页面管理你的Linux服务器
说起管理 Linux 服务器,大家首先想到的使用 SecureCRT、Xshell、MobaXterm 等工具远程到服务器,然后使用命令行管理服务器。今天给大家介绍一个好玩的工具,名字叫Cockpit, Cockpit 是一个免费开源的基于 web 的 Linux 服务器管理…...
基于微信小程序的面部动作检测
目录 引言系统架构概述前端实现细节后端实现细节防止欺骗与误导的措施前后端数据交互详细细节关键技术选型关键技术框架与算法详细说明优化与注意事项总结 引言 微信小程序的面部动作检测的核心功能包括检测用户的左右转头、眨眼和张嘴动作,并根据检测结果逐步引导…...
使用npm 插件[mmdc]将.mmd时序图转换为图片
使用npm 插件[mmdc]将.mmd时序图转换为图片 1. 安装 mmdc2. 转换为图片 可以使用 mmdc (Mermaid CLI)这个工具来将 .mmd 时序图(Mermaid语法描述的时序图)转换为图片,以下是使用步骤: 1. 安装 mmdc 确保…...
服务端错误的处理和web安全检测
文章目录 I 服务端错误的处理业务返回码处理前端处理业务返回码nginx处理http状态码II web安全检测区分服务器类型主机扫漏III 使用 micro_httpd 搭建一个PHP站点步骤下载micro_httpd 并安装它配置micro_httpd 来服务PHP文件I 服务端错误的处理 服务端发生错误时,返回给前端的…...
周记-Repeater中的children和item区别
Repeater中的children和item 在开发qml的界面时,用到了Repeater,表头需要根据Repeater是否存在显示的项,来进行显示。 repeater.children[i] repeater.itemAt(i)如果判断有没有存在显示的项,可以用下面的代码 function is_exis…...
JVM实战—8.如何分析jstat统计来定位GC
大纲 1.使用jstat了解线上系统的JVM运行状况 2.使用jmap和jhat了解线上系统的对象分布 3.如何分析JVM运行状况并合理优化 4.使用jstat分析模拟的BI系统JVM运行情况 5.使用jstat分析模拟的计算系统JVM运行情况 6.问题汇总 1.使用jstat了解线上系统的JVM运行状况 (1)JVM的…...
halcon三维点云数据处理(五)创建代表工具和机器人底座的3D模型
目录 一、gen_robot_tool_and_base_object_model_3d 函数调用二、gen_arrow_object_model_3d 函数调用 首先说明一下这部分代码在find_box_3d这个例程中,非常好用的一个坐标系生成函数。 一、gen_robot_tool_and_base_object_model_3d 函数调用 RobotToolSize : 0.…...
React Router 向路由组件传state参数浏览器回退历史页面显示效果问题
昨天在看尚硅谷张天禹老师讲的 React教程p90,老师讲到 React路由的 replace模式和push模式,老师的演示效果与自己本地操作不太一样。 老师的效果:点击查看消息1,消息2,消息3 再点回退,可以依次查看到 消息…...
LabVIEW四旋翼飞行器姿态监测系统
四旋翼飞行器姿态监测系统是一个集成了高度、速度、俯仰角与滚转角数据采集与分析的系统,提高飞行器在复杂环境中的操作精确度与安全性。系统利用LabVIEW平台与硬件传感器相结合,实现实时数据处理与显示,有效地提升了四旋翼飞行器的监测与控制…...
HTML——66.单选框
<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>单选框</title></head><body><!--input元素的type属性:(必须要有)--> <!--单选框:(如所住省会,性别选择&…...
av1学习笔记(二):sequence_header_obu
av1学习笔记(二):sequence_header_obu 目录 av1学习笔记(二):sequence_header_obu1,图片的编解码方式1.1 seq_profile:1.2 still_picture1.3 reduced_still_picture_header1.4 编解码图像的宽高…...