Java之SpringCloud Alibaba【七】【Spring Cloud微服务网关Gateway组件】
一、网关简介
大家都都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去用。
这样的架构,会存在着诸多的问题:
- 每个业务都会需要鉴权、限流、权限校验、跨域等逻辑,如果每个业务都各自为战。自己造轮子实现一遍,会很蛋疼,完全可以抽出来,放到一个统一的地方去做。
- 如果业务量比较简单的话,这种方式前期不会有什么问题,但随着业务越来越复杂,比如淘宝、亚马逊打开一个页面可能会涉及到数百个微服务协同工作,如果每一个微辰务都分配一个域名的话,一方面客户端代码会很难维护,涉及到数百个域名,另一方面是连接数的瓶颈想象一下你打开一个APP,通过抓包发现涉及到了数百个远程调用,这在移动端下会显得非常低效。
- 后期如果需要对微服务进行重构的话,也会变的非常麻烦,需要客户端配合你一起进行改造,比如商品服务,随着业务变的越来越复杂,后期需要进行拆分成多个微服务这个时候对外提供的服务也需要拆分成多个,同时需要客户端配合你进行改造,非常蛋疼。
上面的这些问题可以借助API网关来解决。
所谓的API网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户说提供统一服务,一些与业务本身功能天关的公共逻辑可以在这里实现。诸如认证、鉴权、监控、路由转发等等,添加上API网关之后,系统的架构图变成了如下所示:
1、什么是Spring Cloud Gateway
网关作为流量的入口,常用的功能包括路由转发,权限校验,限流等。
Sping Cloud cGateway是Sping Clou官方推出的第二代网关框架,定位于取代NeificZul。
相比Zul来说,Spring Cloud Gateway提供更优秀的性能,更强大的有功能。
Spring Cloud Gateway是由WebFlux + Netty + Reactor实现的响应式的API网关。它不能在传统的servlet容器中工作,也不能构建成war包。
Sping Cloud Gateway旨在为微服务架构提供一种简单且有效的API路由的管理方式,并基于Fiter的方式提供网关的基本功能,例如说安全认证、监控、限流等等。
官网文档: 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 (过滤器);
2、核心概念
-
路由(route)
路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成。如果断言为真,则说明请求的URL和配置的路由匹配。 -
断言(predicates)
Java3中的断言函数,SpringCloud Gateway中的断言函数类型是Sping5.0框架中的SeverieExctange。断言函数允许开发者去定义匹酷t request中的任何信息,比加如请求头和参数等。 -
过滤器(Filter)
SpringCloud Gateway中的filter分为Gateway Filler和Global Filter。Filter可以对请求和响应进行处理
3、工作原理
Spring Cloud Gateway的工作原理跟Zuul的差不多,最大的区别就是Gateway的Filter只有pre和post 两种。
客户端向Spring Cloud Gateway发出请求,如果请求与网关程序定义的路由匹配,则该请求就会被发送到网关Web处理程序,此时处理程序运行特定的请求过滤器链。过滤器之间用虚线分开的原因是过滤器可能会在发送代理请求的前后执行逻辑。所有pre过滤器逻辑先执行,然后执行代理请求;代理请求完成后,执行post过滤器逻辑。
二、Spring Cloud Gateway快速开始
1、环境搭建【基本环境搭建-实现路由】
注意:会和spring-webmvc的依赖冲突,需要排除spring-webmvc
<dependencies><!--gateway的依赖 springcloud 开发--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency></dependencies>
设置配置文件
server:port: 8088
spring:application:name: api-gateway
# gateway的配置cloud:gateway:routes:- id: order_route #路由的唯一标识,路由到orderuri: http://localhost:8020 #需要转发的地址#断言规则 用于路由规则的匹配predicates:- Path=//# http://localhost:8088/order-serve/order/add 路由到↓# http://localhost:8020/order-serve/order/addfilters:- StripPrefix=1 # 转发之前,去掉第一次的路径# http://localhost:8020/order/add#- id: stock_route
访问:http://localhost:8088/order-serve/order/add
2、集成Nacos
<!-- nacos服务注册与发现 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>
server:port: 8088
spring:application:name: api-gateway
# gateway的配置cloud:gateway:routes:- id: order_route #路由的唯一标识,路由到orderuri: lb://order-service # 需要转发的地址 lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略 order-service服务名#断言规则 用于路由规则的匹配predicates:- Path=/order-serve/**# http://localhost:8088/order-serve/order/add 路由到↓# http://localhost:8020/order-serve/order/addfilters:- StripPrefix=1 # 转发之前,去掉第一次的路径# http://localhost:8020/order/add#- id: stock_route# 配置Nacosnacos:discovery:server-addr: 127.0.0.1:8848username: nacospassword: nacos
重新运行并访问:
http://localhost:8088/order-service/order/add
设置约定集成nacos
server:port: 8088
spring:application:name: api-gatewaycloud:# gateway的配置gateway:discovery:locator:enabled: true #是否启动自动识别nacos服务#配置Nacosnacos:discovery:server-addr: 127.0.0.1:8848username: nacospassword: nacos
重新启动项目
访问服务名对应的地址:http://localhost:8088/order-service/order/add
重新启动项目
访问:http://localhost:8088/order/add
调整时间
重新运行项目
http://localhost:8088/order/add
3、路由断言工厂(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:接收两个日期参数,判断请求日期是否在指定时间段内
- After=2023-10-19T09:07:00.660+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+
重新启动项目
利用API工具发送请求
把Headers当中的请求参数取消重新发起请求,会报错
- 基于Host的断言工厂
HostRoutePredicateFactory:接收一个参数, 主机名模式。判断请求的Host是否满足匹配规则。
-Host=**.testhost.org
- 基于Method请求方法的断言工厂
MethodRoutePredicateFactory:接收一个参数, 判断请求类型是否跟指定的类型匹配。
重新启动测试
通过GET发送请求
通过POST发起请求
- 基于Query请求参数的断言工厂
设置必须传递参数为name的参数
- Query=name
重新启动发起请求,没有设置name参数报错
设置name参数
设置指定参数
- Query=name,xushu|zhuge
设置name的参数只能是xushu或者zhuge否则断言失败
发送请求报错
将参数改为xushu请求成功,改为zhuge也请求成功
- 基于路由权重的断言工厂
WeightRoutePredicateFactory:接收-个[组名 权重],然后对于同-一个组内的路由按照权重转发
routes:-id: weight_ route1uri: host1predicates:-Path=/ product/**-Weight=group3,1-id: weight_ route2uri: host2predicates:- Path=/ product/**-Weight= group3, 9
4、自定义路由断言工厂
自定义路由断言工厂需要继承AbstractRoutePredicateFactory类,重写apply方法的逻辑。
在apply方法中可以通过exchange. getRequest()倒ServerHttpRequest对象,从而可以获取到请求的参数、请求方式、请求头等信息。
1、必须是Spring组件bean
2、类必须加上RoutePredicateFactory作为结尾
3、必须继承AbstractRoutePredicateFactory
4、必须声明静态的内部类 声明属性来接受配置文件当中配置的断言信息
5、需要结合shortcutFieldOrder进行绑定
6、通过apply方法进行逻辑判断 true 就是匹配成功 false就是匹配失败
注意:命名需要以RoutePredicateFactory结尾
@Component
public class CheckAuthRoutePredicateFactoryextends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactory.Config> {public CheckAuthRoutePredicateFactory() {super(CheckAuthRoutePredicateFactory.Config.class);}@Overridepublic List<String> shortcutFieldOrder() {return Arrays.asList("name");}@Overridepublic Predicate<ServerWebExchange> apply(CheckAuthRoutePredicateFactory.Config config) {return new GatewayPredicate() {@Overridepublic boolean test(ServerWebExchange exchange) {if(config.getName().equals("xushu")){return true;}return false;}};}// 用于接收配置文件中 断言的信息@Validatedpublic static class Config {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}}}
重新启动项目
访问:http://localhost:8088/order/add
修改对应的断言名称
查询启动
http://localhost:8088/order/add
5、过滤器工厂( GatewayFilter Factories)配置
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayilter-factories
5.1、添加请求头参数
filters:- AddRequestHeader=X-Request-color,red
@RequestMapping("/header")public String header(@RequestHeader("X-Request-color") String color){return color;}
重新启动两个项目
http://localhost:8088/order/header
5.2、添加请求参数
- AddRequestParameter=color,blue
@RequestMapping("/parameter")public String parameter(@RequestParam("color") String color){return color;}
http://localhost:8088/order/parameter
5.3、为匹配的路由统一添加前缀
servlet:context-path: /mall-order
- PrefixPath=/mall-order #添加前缀对应微服务需要配置context-path
重新启动两个项目
访问:http://localhost:8088/order/add
现在访问:http://localhost:8020/mall-order/order/add
然而访问8082必须携带前缀
http://localhost:8020/mall-order/order/add
5.4、配置重定向
- RedirectTo=302, https://www.baidu.com
访问:http://localhost:8088/order/add
重定向到了百度
5.5、自定义状态码
- SetStatus= 404
访问:http://localhost:8088/order/add
虽然访问成功了,但是返回的状态码为404
6、自定义过滤器工厂
继承AbstractNameValueGatewayFilterFactory且我们的自定义名称必须要以GatewayFilterFactory结尾并交给spring管理。
创建CheckAuthGatewayFilterFactory
/****/
@Component
public class CheckAuthGatewayFilterFactoryextends AbstractGatewayFilterFactory<CheckAuthGatewayFilterFactory.Config> {public CheckAuthGatewayFilterFactory() {super(Config.class);}@Overridepublic List<String> shortcutFieldOrder() {return Arrays.asList("value");}@Overridepublic GatewayFilter apply(Config config) {return new GatewayFilter() {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String name=exchange.getRequest().getQueryParams().getFirst("name");if(StringUtils.isNotBlank(name)){if(config.getValue().equals(name)){return chain.filter(exchange);}else {// 返回404exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);return exchange.getResponse().setComplete();}}// 正常请求return chain.filter(exchange);}};}public static class Config {private String value;public String getValue() {return value;}public void setValue(String value) {this.value = value;}}}
- CheckAuth=xushu
7、全局过滤器(Global Filters)
局部过滤器和全局过滤器的区别
局部:针对某个路由,需要在路由中进行配置
全局:针对所有路由请求,一旦定义就会投入使用
GlobalFilter接口和GatewayFilter有一样的接口定义, 只不过,GlobalFilter 会作用于所有路由。
@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);}
}
重新启动:http://localhost:8088/order/add?name=xushu
8、Reactor Netty访问日志
要启用Reactor Netty访问日志,请设置
-Dreactor.netty.http.server.accessLogEnabled=true
它必须是Java系统属性,而不是Spring Boot属性。
您可以将日志记录系统配置为具有单独的访问日志文件。以下示例创建一个Logback配置:
<appender name=" accessLog" class="ch.qos.logback.core.FileAppender"><file>access_log.log</file><encoder><pattern>%msg%n</pattern></encoder>
</appender><appender name=" async" class="ch.qos.logback.classic.AsyncAppender"><appender-ref ref="accessLog" />
</appender><logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false"><appender-ref ref=" async"/>
</logger>
8.1、Gateway跨域配置(CORS Configuration)
通过ym|配置的方式
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#cors-configuration
globalcors:cors-configurations:'[/**]': # 允许跨域访问的资源allowedOrigins: "*" #跨域允许的来源 例如:www.smsm.comallowedMethods:- GET- POST- PUT
模拟跨域请求,设置发起请求的页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body><div ><table border="1"><thead><tr><th>id</th><th>username</th><th>age</th></tr></thead><tbody id="userlist"></tbody></table></div><input type="button" value="用户列表" onclick="getData()"><script>function getData() {$.get('http://localhost:8088/order/add',function(data){alert(data)});}</script>
</body>
</html>
访问网页
allowedOrigins: "localhost:8088" #跨域允许的来源 例如:www.smsm.com
再次访问访问网页(抛出跨域异常)
设置*运行所有的来源访问
Spring自带的跨域方式
@Configuration
public class CorsConfig {@Beanpublic CorsWebFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.addAllowedMethod("*"); //允许运行methodconfig.addAllowedOrigin("*"); //允许的来源config.addAllowedHeader("*"); //允许的请求头参数// 允许访问的资源UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());source.registerCorsConfiguration("/**",config);return new CorsWebFilter(source);}
}
相关文章:

Java之SpringCloud Alibaba【七】【Spring Cloud微服务网关Gateway组件】
一、网关简介 大家都都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去用。 这样的架构,会存在着诸多…...

探讨jdk源码中的二分查找算法返回值巧妙之处
文章目录 1.什么是二分查找算法1.1 简介1.2 实现思路 2.二分查找的示例3.jdk 中的 Arrays.binarySearch()4.jdk 中核心二分查找方法解析4.1 为什么 low 是插入点4.2 为什么要进行取反:-(low 1)4.3 为什么不直接返回 插入点 low 的相反数&…...

深度学习实战:基于TensorFlow与OpenCV的手语识别系统
文章目录 写在前面基于TensorFlow与OpenCV的手语识别系统安装环境一、导入工具库二、导入数据集三、数据预处理四、训练模型基于CNN基于LeNet5基于ResNet50 五、模型预测基于OpenCV 写在后面 写在前面 本期内容:基于TensorFlow与OpenCV的手语识别系统 实验环境&…...
学习整理nginx常用屏蔽规则,让网站更安全
学习整理nginx常用屏蔽规则,让网站更安全 注意一、防止文件被下载二、屏蔽非常见蜘蛛(爬虫)三、禁止某个目录执行脚本四、屏蔽某个IP或IP段 注意 在开始之前,希望您已经熟悉的Nginx常用命令(如停止,重启等…...

四十一、【进阶】索引使用SQL提示
1、SQL提示使用情景 在使用MySQL时,当一个字段参在于多个索引中时,默认情况下,MySQL会自动选择一个索引,但我们可以指定索引吗?可以忽略某一种索引吗? 答案是可以的。 前提:profession字段已经…...

AI智能分析网关高空抛物算法如何实时检测高楼外立面剥落?
高楼外立面剥落是一种十分危险的行为,会造成严重的人身伤害和财产损失。TSINGSEE青犀智能分析网关利用高楼外立面剥落的信息,结合高空抛物算法来进行处理就可很好解决此问题。 1. 数据收集 首先,需要收集关于高楼外立面剥落的数据。这可以通…...

微信小程序 - 页面继承(非完美解决方案)
微信小程序 - 面页继承(非完美解决方案) 废话思路首页 indexindex.jsindex.jsonindex.wxml 父页面 page-basepage-base.jspage-base.wxml 子页面 page-apage-a.jspage-a.wxml 子页面 page-bpage-b.jspage-b.wxml 其它app.jsapp.jsonapp.wxss 参考资料 废…...

智能配件管理系统有什么用?企业如何实现管理数字化转型?
在当今高度信息化的时代,企业运营的各个环节都离不开准确及时的数据支持。特别是在制造业中,生产数据的记录和管理对于提高生产效率、降低成本、优化资源配置等方面具有至关重要的作用。然而,许多企业仍在采用纸质流转卡来记录生产数据&#…...
@SuppressWarnings注解使用说明
在Java编程中,我们常常会遇到一些警告(warnings),这些警告通常是对某些潜在问题的提示,虽然这些问题可能不会立即影响程序的运行,但可能会在将来引发问题。为了消除这些警告,我们可以使用Suppre…...
算法从入门到入土cpp版
1. 排序 1. 快速排序 # include<iostream> using namespace std;const int N 100010;int q[N];void quick_sort(int q[], int l, int r) {if(l>r) return;int il-1,jr1,tempq[l];while(i<j){do i;while(q[i]<temp);do j--;while(q[j]>temp);if(i<j)swa…...

没有PDF密码,如何解密文件?
PDF文件有两种密码,一个打开密码、一个限制编辑密码,因为PDF文件设置了密码,那么打开、编辑PDF文件就会受到限制。想要解密,我们需要输入正确的密码,但是有时候我们可能会出现忘记密码的情况,或者网上下载P…...

Sqlyog 无法连接 8 版本的mysql caching_sha2_password could not be loaded
Sqlyog 无法连接 8 版本的mysql caching_sha2_password could not be loaded 1.问题背景 近期系统对Mysql 版本进行了升级,由原来的 5.7升至 8版本,在现场使用Sqlyog 作为数据库连接软件时,发现连接失败。 2.问题现象 使用Sqlyog配置完连…...

学习笔记三十三:准入控制
ResourceQuota准入控制器 ResourceQuota准入控制器限制cpu、内存、pod、deployment数量限制存储空间大小 LimitRanger准入控制器在limit名称空间创建pod,不指定资源,看看是否会被limitrange规则自动附加其资源限制创建pod,指定cpu请求是100m&…...
Unix/Linux C语言 获取控制台窗口尺寸
在Unix/Linux控制台编程,为了能输出好看一些,需要知道窗口宽度,当然使用支持很宽的窗口的终端也是个办法,但是实在没有很宽的终端怎么办呢,还是要从程序上想办法的。 判断控制台窗口宽度需要两个函数: isa…...

界面控件DevExpress WinForms Gauge组件 - 实现更高级别数据可视化
DevExpress WinForms控件包含了超过150个随时可用的仪表盘预设,包括圆形,数字,线性和状态指示器等,来帮助用户实现更高级的数据可视化。 DevExpress WinForms有180组件和UI库,能为Windows Forms平台创建具有影响力的业…...

vivo 自研蓝河操作系统 BlueOS 发布:支持大模型、BlueXlink 协议实现万物互联
大家好,我是 Lorin , 2023 年 11 月 1 日,在今天的 2023 年 vivo 开发者大会上,vivo 自主研发的蓝河操作系统(BlueOS)正式亮相。这款操作系统被宣传为一款面向未来的智能操作系统,具备出色的支持能力&#…...

opencv复习(很乱)
2-高斯与中值滤波_哔哩哔哩_bilibili 1、均值滤波 2、高斯滤波 3、中值滤波 4、腐蚀操作 卷积核不都是255就腐蚀掉 5、膨胀操作 6、开运算 先腐蚀再膨胀 7、闭运算 先膨胀再腐蚀 8、礼帽 原始数据-开运算结果 9、黑帽 闭运算结果-原始数据 10、Sobel算子 左-右&#x…...

于璠访谈录 | AI 框架应该和而不同?
点击以下链接收听本期 “大咖访谈” 播客,与大咖面对面: 大咖访谈链接:于璠 | AI 框架应该和而不同? 刘天栋:访谈主持,开源雨林社区顾问、开源社联合创始人、ASF member 于璠:访谈嘉宾…...

基于Springboot+MYSQL+Maven实现的宠物医院管理系统(源码+数据库+运行指导文档+项目运行指导视频)
一、项目简介 本项目是一套基于springboot框架实现的宠物医院管理系统 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse或者idea 确保可以运行! 该系统功能完善、界面美观、操作简单…...
【数据结构二叉树】先序层序建立、递归非递归遍历层序遍历、树高、镜面、对称、子树、合并、目标路径、带权路径和等等
二叉树 文章目录 二叉树1. 二叉树的建立(递归创建,结构体指针形式)1.1. 先序建立1.2. 层序建立 2. 递归遍历(结构体指针)2.1. 先序遍历2.2. 中序遍历2.3. 后序遍历 3. 非递归遍历(结构体指针)3.1. 层次遍历3.2. 后序遍历(非递归) 4. 求树的高…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...

GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...