背景

微服务架构的分布式特性可以带来很多好处,但是单个微服务并不能独立对外提供服务,一个微服务群组需要作为一个整体对外提供完整的服务体验,而如何实现支撑整体的通用功能就需要好好考虑一番了。

就我司的需求来说,我们需要实现的通用功能包括路由(Routing)、认证(Authorization)、鉴权(Authentication),以及后端API的组合(API Composition)。我们计划在同一个地方即API Gateway,部署这一组功能,而不是在每个微服务都重复部署。

ℹ️ 在[微服务/API时代的前端开发] BFF入门--5个实用的BFF使用案例一文中,介绍了5个典型的BFF应用场景,API Gateway就是其中一个。

OIDC是一个适合微服务的认证方式,由于我们的服务主要构筑在AWS上,所以计划采用AWS Cognito作为ID Provider(或称为Authorization Server)。

关于OAuth和OIDC

OAuth和OIDC有什么区别呢?简单的说,OAuth是个框架(Framework),而Open ID Connect是一个协议。在OAuth2.0框架中,定义了认证过程中的各种角色以及5种认证流程。

角色包括:

  • 资源所有者(Resource Owner),能够授予对受保护资源的访问权限的实体。当资源所有者是一个人时,它被称为最终用户。
  • 资源服务器(Resource Server),托管受保护资源的服务器,能够通过访问令牌,对受保护资源的请求做出响应。
  • 客户端(Client),代表资源所有者并经其授权向受保护资源发出请求的应用程序。 术语“客户端”并不意味着任何特定的实现特征(例如,应用程序是否在服务器、桌面或其他设备上执行)。为了方便区分,也经常被称为OAuth客户端。
  • 认证服务器(Authorization Server),该服务器在成功验证资源所有者并获得授权后向客户端颁发访问令牌。
  • 用户代理(User Agent), 资源所有者的用户代理是客户端与资源所有者交互的中介 (通常是 Web 浏览器)。

5种认证流程分别是:

  1. 授权码模式(Authorization Code Grant)
  2. 简单模式(Implicit Grant)
  3. 密码模式(Resource Owner Password Credentials Grant)
  4. 客户端模式(Client Credentials Grant)
  5. 扩展模式(Extension Grants)

以最常见的授权码模式为例,具体认证流程如下:

     +----------+| Resource ||   Owner  ||          |+----------+^|(B)+----|-----+          Client Identifier      +---------------+|         -+----(A)-- & Redirection URI ---->|               ||  User-   |                                 | Authorization ||  Agent  -+----(B)-- User authenticates --->|     Server    ||          |                                 |               ||         -+----(C)-- Authorization Code ---<|               |+-|----|---+                                 +---------------+|    |                                         ^      v(A)  (C)                                        |      ||    |                                         |      |^    v                                         |      |+---------+                                      |      ||         |>---(D)-- Authorization Code ---------'      ||  Client |          & Redirection URI                  ||         |                                             ||         |<---(E)----- Access Token -------------------'+---------+       (w/ Optional Refresh Token)

OAuth 2.0 的设计仅用于认证,用于将数据和功能从一个应用程序授予另一个应用程序的访问权限。 OpenID Connect (OIDC) 位于 OAuth 2.0 之上,它添加了用户登录(Login)和个人资料信息(Profile)。当认证服务器支持 OIDC 时,它有时被称为身份提供者(ID Provider),因为它向客户端提供有关资源所有者的信息。

OpenID Connect 支持可以跨多个应用程序使用一次登录的场景,也称为单点登录 (SSO)。 例如,应用程序可以通过社交网络服务(如 Facebook 或 Twitter)支持 SSO,以便用户可以选择使用他们既有的登录信息。

OpenID Connect 流程看起来与 OAuth 相同。 唯一的区别是,在初始请求中,使用了特定的SCOPE:openid,并且在最终交换时,客户端同时收到一个 访问令牌(Access Token) 和一个 ID 令牌(ID Token)

关于Cognito

AWS Cognito可以为 Web 和移动应用程序添加用户注册、登录和访问控制功能。可以将用户规模扩展到数百万,并支持通过 SAML 2.0 和 OpenID Connect,使用社交身份提供商(如 Apple、Facebook、Google 和 Amazon)以及企业身份提供商进行登录。简单的说Cognito就是AWS提供的ID Provider,它可以很方便的和ALB、AWS API Gateway、CloudFront进行集成。

AWS Cognito的文档中,对OAuth授权码模式的支持如下图所示:

方案

如前所述,我们采用AWS Cognito作为认证服务器,至于OAuth客户端(即API Gateway)的实现,我们采用的是Spring Cloud Gateway和Spring Security的组合。

认证流程

上图中的微服务将扮演资源服务器的角色,用来展示如何使用 Spring Security 5.2+ 来确保服务的安全。调用它的任何用户(机器)负责提供有效的 访问令牌(Access Token),在我们的例子中使用的是 JWT 格式的不记名令牌。除了典型的 访问令牌JWT 还允许传输与 AuthN/AuthZ 相关的声明,例如用户名或角色/权限。这样微服务就无需为此类信息不断向原始身份提供者发出请求。

API 网关将使用基于会话(Session)的登录,用于展示 OAuth 2 的授权码模式。另外,这里会展示如何根据资源服务器的要求使用适当的 OAuth 令牌来控制 HTTP 访问请求。关键是从 Cognito 获取的访问/刷新令牌永远不会暴露给浏览器。Spring Cloud Gateway支持 WebFlux 模式和传统的MVC模式,由于所有的后端请求都需要经过API网关,对高吞吐量和低延迟有较高的要求,所以我们选择了非阻塞式的WebFlux模式。

相关时序图如下所示:

鉴权

我们计划在后端的一个账户服务中管理用户,用户所属的角色,以及角色对应的URL权限。Spring Security虽然支持如下所示的鉴权方式,但是只能硬编码,不能满足我们的需求。

http.authorizeExchange().pathMatchers(HttpMethod.GET, "/api/account/**").hasRole("account.access");

我们需要考虑如何让API网关从账户服务中获取实时的权限配置,实现动态鉴权。我们将实现一个自定义的ReactiveAuthorizationManager,作为鉴权过滤器,并通过如下方式添加到配置中。在自定义的过滤器中,定时从后端账户服务获取最新的权限配置,并刷新到API网关。

http.authorizeExchange().pathMatchers("/api/**").access(authorizationManager);

对于用户的角色,我们计划使用Cognito的群组(Group)功能,以群组作为角色进行权限控制。原因是我们可以很方便的利用Cognito维护用户和群组的关系,同时在令牌中也很容易获取用户所在群组的信息。关键是我们需要手动将Cognito群组信息转换为Spring Security能够识别的角色/权限。我们需要自定义一个ReactiveOAuth2UserService的Bean,实现群组到角色的转换。之后就可以使用GrantedAuthority来校验用户的权限了。

API组合

我们希望在API网关实现API组合的功能,将后端多个微服务的API组合成一个在功能上相对完整的API,对外提供服务。例如“显示页面时,从日记列表API获取日记的列表信息,同时从评论列表API获取多个评论”。在这种情况下,需要同时请求多个后端API。而在本文的代码示例中,我将把订单API和库存API组合在一起,返回给前端。

很遗憾,Spring Cloud Gateway官方并没有提供这个功能,虽然在社区的讨论中有很多这样的呼声(参考 Have Routes Support Multiple URIs?)。不过社区成员 spencergibb 建议使用Spring Cloud Gateway提供的 ProxyExchange 对象来实现这种功能。我们的示例中也采用了同样的实现方式。

 @PostMapping("/proxy")public Mono<ResponseEntity<Foo>> proxy(ProxyExchange<Foo> proxy) throws Exception {return proxy.uri("http://localhost:9000/foos/") //.post(response -> ResponseEntity.status(response.getStatusCode()) //.headers(response.getHeaders()) //.header("X-Custom", "MyCustomHeader") //.body(response.getBody()) //);}

实现

AWS Cognito

  • 创建AWS实例

首先使用Terraform构筑AWS Cognito实例。

cd ./aws-cognito
terraform init
terraform apply

Client ID, user pool ID 会被打印在窗口中,后续会使用到。

  • 获取 client secret

出于安全方面的考虑,Terrafrom不允许将client secret 打印在窗口中,所以需要用以下命令获取。

aws cognito-idp describe-user-pool-client --user-pool-id <your-user-pool-id> \
--client-id <your-client-id>
  • 注册用户并确认

注册用户admin@example.com。

aws cognito-idp sign-up --region <your-aws-region> \
--client-id <your-client-id> --username admin@example.com \
--password password123aws cognito-idp admin-confirm-sign-up --region <your-aws-region> \
--user-pool-id <your-user-pool-id> \
--username admin@example.com
  • 加入群组

将测试用户加入account.access群组。

aws cognito-idp admin-add-user-to-group --user-pool-id <your-user-pool-id> \
--username admin@example.com \
--group-name account.access

API网关

  • 依赖

在build.gradle中添加如下依赖:

    implementation  "org.springframework.boot:spring-boot-starter-webflux"implementation  "org.springframework.boot:spring-boot-starter-oauth2-client"implementation  "org.springframework.security:spring-security-oauth2-jose"implementation  "org.springframework.security:spring-security-config"implementation  "org.springframework.cloud:spring-cloud-starter-gateway"implementation  "org.springframework.cloud:spring-cloud-gateway-webflux"
  • 配置

在application.yaml中添加OAuth2的配置。这里需要将上一步中获得的Cognito的client-id, client-secret等信息配置到该文件中。

spring:security:oauth2:client:provider:cognito:issuerUri: https://cognito-idp.<region-id>.amazonaws.com/<region-id>_<user-pool-id>user-name-attribute: usernameregistration:cognito:client-id: <client-id>client-secret: <client-secret>client-name: scg-cognito-sample-user-poolprovider: cognitoscope: openidredirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'authorization-grant-type: authorization_code

另外,还需要添加路由相关的配置,这里是用来TokenRelayFilter,用于通过Http Header将Token传递给后端微服务。

spring:cloud:gateway:default-filters:- TokenRelayroutes:- id: account_service_routeuri: http://localhost:8082predicates:- Path=/api/account/**- id: order_service_routeuri: http://localhost:8083predicates:- Path=/api/order/**- id: storage_service_routeuri: http://localhost:8084predicates:- Path=/api/storage/**
  • 代码

在SecurityWebFilterChain中设置自定义的鉴权过滤器MyAuthorizationManager。

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http,ReactiveClientRegistrationRepository clientRegistrationRepository,MyAuthorizationManager authorizationManager) {// Authenticate through configured OpenID Providerhttp.oauth2Login(withDefaults());// Also logout at the OpenID Connect providerhttp.logout(logout -> logout.logoutSuccessHandler(new OidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository)));// add authorization filtershttp.authorizeExchange().pathMatchers("/api/**").access(authorizationManager);// Require authentication for all requestshttp.authorizeExchange().anyExchange().authenticated();// Disable CSRF in the gateway to prevent conflicts with proxied service CSRFhttp.csrf().disable();return http.build();
}

使用ReactiveOAuth2UserService,将Cognito群组信息转换为Spring Security能够识别的角色/权限。

@Bean
public ReactiveOAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() {final OidcReactiveOAuth2UserService delegate = new OidcReactiveOAuth2UserService();return (userRequest) -> {// Delegate to the default implementation for loading a userreturn delegate.loadUser(userRequest).map(user -> {Set<GrantedAuthority> mappedAuthorities = new HashSet<>();user.getAuthorities().forEach(authority -> {if (authority instanceof OidcUserAuthority) {OidcUserAuthority oidcUserAuthority = (OidcUserAuthority) authority;// get cognito groups from tokenJSONArray groups = oidcUserAuthority.getIdToken().getClaim("cognito:groups");if (Objects.nonNull(groups)) {groups.stream()// map group to role.map(roleName -> "ROLE_" + roleName).map(SimpleGrantedAuthority::new).forEach(mappedAuthorities::add);}}});return new DefaultOidcUser(mappedAuthorities, user.getIdToken(), user.getUserInfo());});};
}

自定义的鉴权过滤器MyAuthorizationManager代码如下:

@Component
public class MyAuthorizationManager implements ReactiveAuthorizationManager<AuthorizationContext> {// ...@Overridepublic Mono<AuthorizationDecision> check(Mono<Authentication> authenticationMono,AuthorizationContext authorizationContext) {ServerHttpRequest request = authorizationContext.getExchange().getRequest();// pass OPTIONS request of CORSif (request.getMethod() == HttpMethod.OPTIONS) {return Mono.just(new AuthorizationDecision(true));}// authenticateString url = request.getURI().getPath();return authenticationMono.map(auth -> new AuthorizationDecision(urlAuthorityChecker.check(auth.getAuthorities(), url))).defaultIfEmpty(new AuthorizationDecision(false));}}

具体的权限校验逻辑在UrlAuthorityChecker中实现。

@Component
@EnableScheduling
public class UrlAuthorityChecker {// .../*** map for permission and url*/private Map<String, String> permissionUrlMap;/*** check granted authorities of user*/public boolean check(Collection<? extends GrantedAuthority> authorities, String requestedUrl) {// loop all the authorities of user to find out if the url is authenticatedfor (GrantedAuthority authority : authorities) {String authorizationUrl = permissionUrlMap.get(authority.getAuthority());if (authorizationUrl != null && antPathMatcher.match(authorizationUrl, requestedUrl)) {return true;}}return false;}/*** create newPermissionUrlMap and replace the old one.* add scheduled task to refresh the map every certain ms.*/@Scheduled(initialDelay = 0, fixedDelay = REFRESH_DELAY)private void updatePermissionNameAuthorizationUrlMap() {Map<String, String> permissions = permissionManager.getPermissions();Map<String, String> newPermissionUrlMap = new ConcurrentHashMap<>();permissions.forEach((k,v) -> newPermissionUrlMap.put("ROLE_" + k, v));permissionUrlMap = newPermissionUrlMap;}
}

关于API组合功能,我们使用ProxyExchange实现了订单API和库存API的整合。

@GetMapping("/composition/{id}")
public Mono<? extends ResponseEntity<?>> proxy(@PathVariable Integer id, ProxyExchange<?> proxy) throws Exception {return proxy.uri("http://localhost:8083/api/order/get/" + id).get(resp -> ResponseEntity.status(resp.getStatusCode()).body(resp.getBody())).flatMap(re1 -> proxy.uri("http://localhost:8084/api/storage/get/" + id).get(resp -> ResponseEntity.status(resp.getStatusCode()).body(Map.of("order",re1.getBody(),"storage",resp.getBody()))));
}

资管服务器(微服务)

  • 依赖

在build.gradle中添加如下依赖:

    implementation 'org.springframework.boot:spring-boot-starter-web'implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
  • 配置

在application.yaml中,增加OAuth2的资源服务器配置。

spring:security:oauth2:resourceserver:jwt:issuer-uri: https://cognito-idp.<region-id>.amazonaws.com/<region-id>_<user-pool-id>
  • 代码

在SecurityConfig中配置资源服务器,启用 JWT令牌 校验,并采取API网关相同的措施,将令牌中的Cognito群组信息装换为角色/权限。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {// Validate tokens through configured OpenID Providerhttp.oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthenticationConverter());// Permit request for permissionshttp.authorizeRequests().antMatchers(HttpMethod.GET, "/api/account/permissions").permitAll();// Require authentication for the other requestshttp.authorizeRequests().anyRequest().authenticated();}private JwtAuthenticationConverter jwtAuthenticationConverter() {JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();// Convert realm_access.roles claims to granted authorities, for use in access decisionsjwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwt -> {Object groups = jwt.getClaims().get("cognito:groups");if (Objects.nonNull(groups)) {return ((List<?>) groups).stream().map(roleName -> "ROLE_" + roleName).map(SimpleGrantedAuthority::new).collect(Collectors.toList());} else {return new ArrayList<>();}});return jwtAuthenticationConverter;}
}

完整的示例代码可以从我的Github上下载。

其他方案

除了采用OAuth的授权码模式,还可以选择简单模式,将登录以及令牌的获取交给前端,API Gateway只作为资源服务器,而后端的微服务则只对API Gateway开放访问。前端是本地应用(Native Application)的情况下,这样做是十分可取的。本地应用是指安装在设备上的客户端软件,区别于基于浏览器的SPA,因为基于浏览器的应用代码是公开的,令牌容易泄露,所以不适用简单模式。

相关文章

  • [微服务/API时代的前端开发] BFF超入门--Netflix、Twitter、Recruit选择BFF的理由
  • [微服务/API时代的前端开发] BFF入门--5个实用的BFF使用案例
  • [微服务/API时代的前端开发] BFF进阶--实践中常见的3种反模式

参考链接

  • OAuth2.0
  • Spring Cloud Gateway with OpenID Connect and Token Relay
  • Understanding Amazon Cognito user pool OAuth 2.0 grants
  • Have Routes Support Multiple URIs?
  • Spring cloud samples: sample-gateway-oauth2login
  • JavaDoc: org.springframework.cloud.gateway.webflux.ProxyExchange

如果你觉得本文有点意思,不妨点个赞吧。

关注我的微信公众号【清朝程序猿】除了技术我还会聊点日常,有些话只能悄悄说~

 

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. DockerKubernetes ❀ Docker镜像与容器相关操作基础命令详解

    文章目录1、Docker信息查询1.1 版本信息1.2 详细信息1.3 帮助命令2、镜像命令2.1 本地镜像查看2.2 镜像搜索2.3 镜像拉取2.4 镜像删除3、容器命令3.1 新建并启动容器3.2 列出所有运行的容器3.3 退出容器3.4 启动/重启/停止/杀死/删除/重新登录 容器1、Docker信息查询 1.1 版本信…...

    2024/4/5 3:03:58
  2. 基于晏殊几何学涡旋激波模型仿真的光效和模型解析原理一

    ...

    2024/4/13 16:38:27
  3. LeetCode - Easy - 28 - 实现strStr()

    原题链接 : 实现strStr() 哎呀这题呀… 给我看到怀疑人生… 开门见山哈, 这题有三种解法, 如果作为简单题来看, 这题的思路就比较简单粗暴 简单题的思路 : 题目的意思是要在原串里找到目标串,并返回原串的首下标, 最简单的思路就是将原串长度为目标串的子串都依次和目标串比较…...

    2024/4/13 16:38:37
  4. Pytorch预测

    本次测试输入 dog.png # Coding by ajupyter from PIL import Image from torch import nn import torch import torchvisionclass Model(nn.Module):def __init__(self):super(Model, self).__init__()self.model nn.Sequential(nn.Conv2d(in_channels3, out_channels32, k…...

    2024/4/13 16:38:22
  5. MXY---数据库

    数据库 数据库&#xff1a;数据库就是管理数据的仓库 数据库分类&#xff1a; 1&#xff09;关系型数据库&#xff1a;Orcale、MYSQL 2&#xff09;非关系型数据库&#xff1a;Redis 关系、非关系型数据库&#xff1a; 1&#xff09;关系型数据库&#xff0c;建立在紧密关系基…...

    2024/4/5 3:03:53
  6. JVM GC

    文章目录如何判断对象可以被回收&#xff1f;1.引用计数2. 可达性分析&#xff08;Reachability Analysis&#xff09;GC算法和GC收集器Serial&#xff08;串行&#xff09;收集器ParNew&#xff08;Parallel New Generation&#xff09;收集器Parallel Scavenge收集器Serial O…...

    2024/4/17 23:20:46
  7. 动态规划简单 NC245 杨辉三角(一)

    NC245 杨辉三角(一) 描述 给定一个非负整数 num &#xff0c;生成杨辉三角的前 num 行。 杨辉三角中&#xff0c;每个数是左上方和右上方的数之和。 数据范围&#xff1a; 1 \le num \le 30 \1≤num≤30 例如当输入为4时&#xff0c;对应的返回值为[[1],[1,1],[1,2,1],[1,3,3…...

    2024/4/15 3:12:09
  8. 计算机科学类专升本复习之“C语言指针变量的定义和使用”详解(初稿)

    C语言指针变量的定义和使用&#xff08;精华&#xff09; "数据"在内存中的"地址"也成为"指针"&#xff0c;如果一个变量存储了一份数据的"指针"&#xff0c;我们就称它为"指针变量"。 在C语言中&#xff0c;允许用一个 变…...

    2024/4/14 4:55:59
  9. 你发年终奖了吗?

    年终奖是很多人的快乐&#xff0c;也是很多人的痛。 当然快乐与你有没有缘&#xff0c;就要看快乐与你有没有缘了&#xff0c;这是个玄学。 在一些公司是如果一个人有年终奖其他人就会都有&#xff0c;在一些公司是根据你整年的表现来的。 比如有这么一家公司&#xff1a; …...

    2024/4/7 20:39:06
  10. 计算机网络:王道考研

    前言 计算机考研课程408包括计组、计网、操作系统、数据结构与算法&#xff0c;计组在21年就补完了——计算机组成原理&#xff1a;最详细笔记&#xff01;&#xff0c;数据结构与算法、操作系统都看了&#xff0c;就差计网这个八股文,系统的听了一遍考研课程《王道-计算机网络…...

    2024/4/13 16:39:13
  11. 计算机网络面试题总结

    计算机网络面试题总结网络分层结构TCP/IP五层模型三次握手两次握手可以吗&#xff1f;四次挥手第四次挥手为什么要等待2MSL&#xff1f;为什么是四次挥手&#xff1f;TCP有哪些特点&#xff1f;TCP和UDP的区别&#xff1f;HTTP协议的特点&#xff1f;HTTP报文格式HTTP状态码有哪…...

    2024/4/16 21:41:34
  12. 【LeetCode-SQL每日一练】—— 595. 大的国家

    &#x1f388;写在前面 &#x1f64b;‍♂️大家好呀&#xff0c;我是超梦。大家可以叫我小梦~ 小伙伴们都知道&#xff0c;不管是在学习中还是日常工作中&#xff0c;几乎天天是要跟数据库打交道的&#xff0c;为了更好的操作数据库&#xff0c;我们的SQL知识储备是必不可少的…...

    2024/4/13 16:39:33
  13. 9,重载,继承抽象类的喂猫狗的案例

    1 public static void main(String[] args) {Dog dog new Dog();Cat cat new Cat();Person person1 new Person();Person person2 new Person();Scanner sc new Scanner(System.in);OUT:while (true) {System.out.println("请作出选择&#xff1a;1&#xff0c;照顾猫…...

    2024/4/13 16:39:38
  14. 专转本-大数据主要应用领域-笔记

    大数据在农业领域的典型应用 大数据理论和技术在农业上的应用和实践,是指运用大数据理念、技术和方法,解决农业或涉农领域数据的采集、存储、分析与应用等一系列问题,然后以此来指导农业生产经营。这里所讲的农业大数据就是指以大数据分析为基础去解决一系列问题。典型的一些…...

    2024/4/18 1:51:07
  15. 推力圆锥滚子轴承的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告

    本文研究全球与中国市场推力圆锥滚子轴承的发展现状及未来发展趋势&#xff0c;分别从生产和消费的角度分析推力圆锥滚子轴承的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国…...

    2024/4/13 16:41:10
  16. 在线SVG在线编辑器

    在线SVG在线编辑器 在线SVG在线编辑器 SVG在线编辑器,在线编辑SVG,SV辑器,在线编辑SVG,SVG在线编辑器,在线编辑SVG https://tooltt.com/svg/...

    2024/4/19 14:31:34
  17. 1017 Queueing at Bank (25 分) (模拟 23/25

    添加链接描述 /* 每个客户最多被服务1小时 给的小时 分钟 秒 超过17.00.01不被服务 提前来要等待 保留一位小数 */ #include<bits/stdc.h> using namespace std; const int N1e49; struct node {int st,nex; }t[N]; bool cmp(node a,node b){return a.st<b.st; } pr…...

    2024/4/13 16:39:23
  18. 人脸识别外部接口调用

    本文代码及数据集来自《Python大数据分析与机器学习商业案例实战》 要在Python中调用百度人脸识别接口&#xff0c;得先安装baidu-aip库。可以在Windows命令行窗口中输入并执行“pip install baidu-aip”命令&#xff0c;或者在JupyterNotebook中输入并运行“!pip install baid…...

    2024/4/18 14:09:33
  19. redis夺命连环问6--主库故障了从库该怎么办,数据还能保持一致吗,Redis 还能正常提供服务吗?

    目录主库故障了从库该怎么办&#xff0c;数据还能保持一致吗&#xff0c;Redis 还能正常提供服务吗&#xff1f;先谈哨兵机制哨兵咋监控的呢&#xff1f;如何选定新主库呢&#xff1f;哨兵集群是怎么建立的&#xff1f;哨兵集群由哪个实例来执行主从切换呢&#xff1f;主库故障…...

    2024/4/13 16:39:03
  20. 基于百度AL平台人体检测实现人体关键点检测代码

    本文通过OpenCV模块调用摄像头&#xff0c;利用百度开放的人体关键点检测API&#xff0c;实现了实时对人体的关键点检测。 一、百度API获取 使用百度的API&#xff0c;首先要在百度AI的官网上注册帐号&#xff0c;然后在人体关键点识别功能下创建一个应用&#xff0c;即可得到…...

    2024/4/13 16:39:13

最新文章

  1. ansible------inventory 主机清单

    目录 inventory 中的变量 2&#xff09;组变量[webservers:vars] #表示为 webservers 组内所有主机定义变量&#xff0c;所有组内成 员都有效 ansible_userrootansible_passwordabc1234 3&#xff09; [all:vars…...

    2024/5/8 12:05:46
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/7 10:36:02
  3. 设计模式:组合模式

    定义 组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使得客户端可以统一对待单个对象和组合对象。 应用场景 组合模式适用于以下场景: 表达对象的部分-整体层次结构:当你想要表示对象的部分-整…...

    2024/5/7 11:56:24
  4. FastAPI Web框架教程 第1章 快速上手

    1.1 fastapi介绍 简介&#xff1a; FastAPI 是一个高性能&#xff0c;易于学习&#xff0c;高效编码&#xff0c;生产可用的Python Web异步框架 FastAPI 适合来写API&#xff0c;使用 Python 3.6 并基于标准的 Python 类型提示 核心特性&#xff1a; 速度快&#xff1a;可…...

    2024/5/5 8:27:14
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/8 6:01:22
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/7 9:45:25
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/7 14:25:14
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/7 11:36:39
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/6 1:40:42
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/4 23:55:17
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/7 9:26:26
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/4 23:55:06
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/4 23:55:16
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/6 21:42:42
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57