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

SpringCloudAlibaba技术栈-Higress

1、什么是Higress?

云原生网关,干啥的?用通俗易懂的话来说,微服务架构下Higress 就像是一个智能的“交通警察”,它站在你的网络世界里,负责指挥和调度所有进出的“车辆”(也就是数据流量)。它的主要工作包括:
        指挥交通:它告诉数据应该走哪条路,去哪个服务(就像告诉你去某个地方应该走哪条路)。
        保障安全:它检查进出的数据,防止坏人(比如黑客)进来搞破坏,保护你的网络世界安全。
        维护秩序:如果有太多数据同时涌进来(比如网站访问量突然暴增),它会采取措施,比如限制流量,确保系统不会因为太忙而崩溃。
        记录情况:它会记录所有车辆的行驶情况,如果出了问题,可以帮忙查找原因。
        适应各种路况:无论是云上的道路,还是自己家修的路(混合云环境),它都能管理得井井有条。
简而言之,Higress 就是帮助你的网络世界更加顺畅、安全、有序的一个工具。

2、Higress的安装

1、安装DockerCompose

序号软件版本
1Centos7.5
2Linux内核3.8之上

 卸载之前的docker

yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-selinux \docker-engine-selinux \docker-engine \docker-ce

防火墙关掉

systemctl stop firewalld

设置安装仓库

#安装yum的工具包
yum install -y yum-utils \device-mapper-persistent-data \lvm2 --skip-broken
# 设置docker镜像源
yum-config-manager \--add-repo \https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.reposed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
#将软件包信息提前在本地索引缓存,用来提高搜索安装软件的速度,建议执行这个命令可以提升yum安装的速度。
yum makecache fast

 安装docker引擎

sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

启动docker

systemctl start docker

设置docker自启动(我不喜欢)

systemctl enable docker

检查是不是启动成功

docker version

2、搭建Higress

#创建Higress工作目录
mkdir higress;  #进入Hogress文件夹
cd higress#创建higress-ai容器
docker run -d --name higress-ai -v ${PWD}:/data \-p 8001:8001 -p 80:8080 -p 8443:8443  \higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/all-in-one:latest

监听端口说明如下:

  • 80 端口:Higress UI 控制台入口
  • 8080 端口:网关 HTTP 协议入口
  • 8443 端口:网关 HTTPS 协议入口

访问Higress控制台

http://192.168.66.100:8001/

自己设置密码即可,进去后创建服务来源为nacos

之后项目启动的时候需要先打开docker服务,然后再开启Higress的容器。 

 3、Higress配置Nacos注册中心

为啥要配置Nacos呢?因为微服务都在nacos上注册着。

nacos的下载安装见博客:

SpringCloudAlibaba技术栈-Nacos-CSDN博客

安装完成之后访问浏览器输入网址192.168.66.100:8848/nacos即可。

3、项目案例

1、创建网关微服务模块

创建完父项目添加依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.zj</groupId><artifactId>testHigress</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><name>testHigress</name><url>http://maven.apache.org</url><modules><module>order-service</module><module>auth</module></modules><properties><dubbo.version>3.2.4</dubbo.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>17</java.version><spring-boot.version>3.0.2</spring-boot.version><spring-cloud.version>2022.0.0</spring-cloud.version><spring-cloud-alibaba.version>2022.0.0.0</spring-cloud-alibaba.version><lombok.version>1.8.28</lombok.version></properties><dependencyManagement><dependencies><!-- SpringCloud 微服务 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><!-- SpringCloud Alibaba 微服务 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency><!-- SpringBoot 依赖配置 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
</project>

创建子项目order-service并添加依赖。

        <!--   springboot依赖包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--   nacos依赖包  --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>

在resources文件夹下面创建application.yml文件。

spring:application:# 应用名字name: order-servicecloud:nacos:discovery:# Nacos注册中心的地址server-addr:  192.168.66.100:8848server:port: 8889

主要是为了将order-service服务注册到Nacos上。

 编写主启动类。

@SpringBootApplication
@EnableDiscoveryClient
public class OderServiceApplication
{public static void main( String[] args ){SpringApplication.run(OderServiceApplication.class, args);}
}

编写测试控制器。

package com.zj.controller;/*控制器*/
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/order")
public class indexController {@GetMapping("/index")public String index(){return "hello higress";}
}

启动项目,检查nacos客户端是不是存在该服务。

浏览器访问控制器,检查是不是创建成功。localhost:8888/order/index  出现hi gress表示成功。

2、Higress路由配置

它的作用是根据一定的规则,将访问者的请求正确地发送到对应的服务或者后端服务器上。

安装Switchhosts

Switchhosts:切换hosts与编辑hosts,实现域名和地址的映射。

会出现写数据没权限的情况看这篇文章:

switchHosts应用时,没有写入 Hosts 文件的权限_没有写入 hosts 文件的权限。-CSDN博客

在Higress中创建数据来源:

 在域名管理中创建域名:

配置访问order-service服务的路由:

 如果不存在一级路由的话还需要重写路由(这里存在一级路由):

 这样访问的时候由原来的localhost:8888/order/index  变为  www.zj.com/order/index  为啥呢?因为微服务在nacos上,higress会根据/order/index找到匹配的服务。 

浏览器访问地址:

 3、Higress策略配置-跨域配置

什么是跨域

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

当前页面url被请求页面url是否跨域原因
http://www.test.com/http://www.test.com/index.html同源(协议、域名、端口号相同)
http://www.test.com/https://www.test.com/index.html跨域协议不同(http/https)
http://www.test.com/百度一下,你就知道跨域主域名不同(test/baidu)
http://www.test.com/http://blog.test.com/跨域子域名不同(www/blog)
http://www.test.com:8080/http://www.test.com:7001/跨域端口号不同(8080/7001)

 常见的报错就是:Access-Control-Allow-Origin。 

Higress配置跨域访问order-service服务:

 4、HTTP认证

Higress HTTP认证是一种保护网页或服务的机制,需要用户输入用户名和密码才能访问。这就像给你的网站或服务加了一把锁,只有知道密码的人才能进入。

常见的验证方案包括

1、Basic Authentication(基本认证)

Basic认证是最常见的HTTP认证方式之一。在Basic认证中,客户端发送请求时,会在请求头中包含一个"Authorization"字段,该字段包含了经过Base64编码的用户名和密码。

2、Digest Authentication(摘要认证)

Digest认证是一种更安全的认证方式。在Digest认证中,服务器会向客户端发送一个随机数(称为"nonce"),客户端根据该随机数和用户密码计算一个摘要,并将其发送给服务器。服务器收到摘要后,会验证其有效性。Digest认证相对于Basic认证而言,更难以被中间人攻击截获密码。

3、Bearer Token Authentication(令牌认证)

Bearer认证是一种使用令牌(Token)进行身份验证的方式。在Bearer认证中,客户端在请求头中添加一个"Authorization"字段,该字段包含了一个令牌信息。服务器在接收到请求后,会验证令牌的有效性,并根据令牌来识别用户身份。

4、OAuth(开放授权)

OAuth认证是一种开放标准的身份验证协议,用于授权第三方应用程序访问用户资源。在OAuth认证中,用户可以通过授权服务器授权第三方应用程序访问自己的资源。这种方式可以避免用户将密码直接提供给第三方应用程序。

(1)Basic 认证

暂略。

(2)JWT认证

啥叫JWT认证?JWT认证是一种通过令牌(token)来验证用户身份的方法。用户登录后,服务器会发一个像密码一样的令牌给用户,用户每次访问网站时都带上这个令牌,服务器检查令牌来确定用户是谁。这种方法不需要服务器记住用户的登录状态,令牌里有用户信息,还能保证安全。

传统的session认证的缺点:

  • 安全性:CSRF攻击因为基于cookie来进行用户识别, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。
  • 扩展性:对于分布式应用,需要实现 session 数据共享
  • 性能:每一个用户经过后端应用认证之后,后端应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大,与REST风格不匹配。因为它在一个无状态协议里注入了状态。

JWT的认证方式:

业务流程:

  1. 客户端向API网关发起认证请求,请求中一般会携带终端用户的用户名和密码;
  2. 网关将请求直接转发给后端服务也就是auth服务模块;
  3. 后端服务读取请求中的验证信息(比如用户名、密码)进行验证,验证通过后使用私钥生成标准的token,返回给网关;
  4. 网关将携带token的应答返回给客户端,客户端需要将这个token缓存到本地;
  5. 客户端向API网关发送业务请求,请求中携带token;
  6. 网关使用用户设定的公钥对请求中的token进行验证,验证通过后,将请求透传给后端服务;
  7. 后端服务进行业务处理后应答;
  8. 网关将业务应答返回给客户端

JWT 结构

头部 / header

JSON对象,描述 JWT 的元数据。其中 alg 属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ 属性表示这个令牌(token)的类型(type),统一写为 JWT。

    {
       "alg": "HS256",
       "typ": "JWT"
    }
alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT然后将头部进行Base64编码构成了第一部分,Base64是一种用64个字符来表示任意二进制数据的方法,Base64是一种任意二进制到文本字符串的编码方法,常用于在URL、Cookie、网页中传输少量二进制数据。

载荷 / Payload

Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 指定七个默认字段供选择。除了默认字段之外,你完全可以添加自己想要的任何字段,一般用户登录成功后,就将用户信息存放在这里

iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT

{
 "iss": "xxxxxxx",
 "sub": "xxxxxxx",
 "aud": "xxxxxxx",
 "user": {
     'username': 'itbaizhan',
     'userId': 1
  } 
}

签名 / Signature

  • 签名部分是对上面的 头部、载荷 两部分数据进行的数据签名
  • 为了保证数据不被篡改,则需要指定一个密钥,而这个密钥一般只有你知道,并且存放在服务端

(3)Higress策略配置-创建认证中心微服务

添加依赖

    <dependencies><!--springboot--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--注册中心,当前的认证服务也需要将自己注册到注册中心才能被其他服务调用--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--JWT认证包--><dependency><groupId>org.bitbucket.b_c</groupId><artifactId>jose4j</artifactId><version>0.7.0</version></dependency><!--工具包--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.18</version></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>

在resources文件夹下面创建application.yml文件。

#微服务名称
spring:application:name: auth-service
#    注册中心地址cloud:nacos:discovery:server-addr: 192.168.66.100:8848
#端口
server:port: 8889#还能添加数据库的配置信息,从数据库获取用户的信息认证用户的身份

 创建主启动类

@SpringBootApplication
@EnableDiscoveryClient
public class authApplication
{public static void main( String[] args ){SpringApplication.run(authApplication.class, args);}
}

(4)编写JWT工具类生成JWT

在此之前一定要把Linux的时间设置成北京时间。

生成公钥和私钥,用户也可以在这个站点https://mkjwk.org 生成用于token生成与验证的私钥与公钥。

public static void main(String[] args) {RsaJsonWebKey rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);final String publicKeyString = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.PUBLIC_ONLY);final String privateKeyString = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);System.out.println(publicKeyString);System.out.println(privateKeyString);
}

 JWT工具类

package com.zj.utils;import org.jose4j.json.JsonUtil;
import org.jose4j.jwa.AlgorithmConstraints;
import org.jose4j.jwk.JsonWebKey;
import org.jose4j.jwk.RsaJsonWebKey;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.InvalidJwtException;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.lang.JoseException;import java.security.PrivateKey;
import java.security.PublicKey;// Jwt工具类,包含生成和验证JWT令牌的方法
public class JwtUtils {// 私钥字符串,用于签名JWT令牌,这里存储的是RSA私钥的JSON表示public final static String privatejson = "{\"kty\":\"RSA\",\"n\":\"...\",\"e\":\"...\",\"d\":\"...\",\"p\":\"...\",\"q\":\"...\",\"dp\":\"...\",\"dq\":\"...\",\"qi\":\"...\"}";// 公钥字符串,用于验证JWT令牌,这里存储的是RSA公钥的JSON表示public final static String publicjson = "{\"kty\":\"RSA\",\"n\":\"...\",\"e\":\"...\"}";/*** 生成JWT令牌* @param userId 用户ID,将作为JWT负载的一部分* @param username 用户名,将作为JWT负载的一部分* @return 返回生成的JWT令牌字符串*/public static String sign(Long userId, String username) throws JoseException {// 创建JWT的声明部分,JwtClaims对象包含JWT的有效负载JwtClaims claims = new JwtClaims();claims.setIssuer("abcd"); // 设置JWT的发行者,通常是创建JWT的应用的名称claims.setAudience("audience"); // 设置JWT的接收者,通常是接收JWT的应用的名称claims.setExpirationTimeMinutesInTheFuture(10000); // 设置JWT的过期时间,这里设置为10000分钟后过期claims.setGeneratedJwtId(); // 自动生成JWT的唯一标识符claims.setIssuedAtToNow(); // 设置JWT的发行时间,即当前时间claims.setNotBeforeMinutesInThePast(2); // 设置JWT生效时间,即2分钟前claims.setSubject("subject"); // 设置JWT的主题,通常是关于JWT的描述信息claims.setClaim("userId", userId); // 添加自定义声明,这里是用户IDclaims.setClaim("username", username); // 添加自定义声明,这里是用户名// 创建JWT签名对象,用于生成签名后的JWT令牌JsonWebSignature jws = new JsonWebSignature();jws.setPayload(claims.toJson()); // 设置JWT的有效负载,即上面的claims对象转换成JSON字符串// 使用私钥签名JWT,私钥用于加密签名,确保JWT的完整性和真实性PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privatejson)).getPrivateKey();jws.setKey(privateKey);// 设置密钥ID,可以用于区分不同的密钥对jws.setKeyIdHeaderValue("keyId");// 设置签名算法,这里使用RSA SHA-256算法jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);// 生成JWT令牌,即对有效负载进行签名并返回签名后的字符串String jwt = jws.getCompactSerialization();return jwt;}/*** 验证JWT令牌* @param token 要验证的JWT令牌字符串*/public static void checkJwt(String token) throws JoseException {// 使用公钥验证JWT,公钥用于解密签名,验证JWT的完整性和真实性PublicKey publicKey = new RsaJsonWebKey(JsonUtil.parseJson(publicjson)).getPublicKey();// 创建JWT消费者,用于验证和解码JWT令牌JwtConsumer jwtConsumer = new JwtConsumerBuilder().setRequireExpirationTime() // 要求JWT包含过期时间字段.setAllowedClockSkewInSeconds(30) // 允许时间偏移量,即服务器时间与JWT生成时间之间的差异.setRequireSubject() // 要求JWT包含主题字段.setExpectedIssuer("abcd") // 预期的发行者,必须与JWT中的发行者匹配.setExpectedAudience("audience") // 预期的接收者,必须与JWT中的接收者匹配.setVerificationKey(publicKey) // 设置用于验证签名的公钥.setJwsAlgorithmConstraints(new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST, AlgorithmIdentifiers.RSA_USING_SHA256))// 设置只允许使用RSA SHA-256算法的JWT.build();try {// 解析和验证JWT令牌JwtClaims jwtClaims = jwtConsumer.processToClaims(token);System.out.println("JWT验证成功!");// 输出JWT中的声明信息System.out.println("JWT内容: " + jwtClaims);} catch (InvalidJwtException e) {// 如果JWT验证失败,打印错误信息System.out.println("JWT验证失败: " + e);}}// 主函数,用于测试JWT的生成和验证public static void main(String[] args) throws JoseException {// 生成JWT令牌String token = sign(123L, "testUser");System.out.println("生成的JWT令牌: " + token);// 验证JWT令牌checkJwt(token);}}

(5)编写认证中心控制器和服务层

package com.zj.controller;import com.zj.domain.LoginBodyDTO;
import com.zj.domain.R;
import com.zj.service.LoginService;
import org.jose4j.lang.JoseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;/*** 用户层*/
@RestController
@RequestMapping("/auth")
public class LoginController {@Autowiredprivate LoginService loginService;/*** @RequestBody:将数据转换为java对象* @param loginBodyDTO* @return*/@PostMapping("/login")public R login(@RequestBody LoginBodyDTO loginBodyDTO) throws JoseException {System.out.println("啊哈哈哈哈");R login = loginService.login(loginBodyDTO);return login;}
}

编写统一结果返回集

package com.zj.domain;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;/*** 统一结果返回集*/
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class R {private Integer code;private String msg;public Object data;public static R fail( String msg) {R r = new R();r.setCode(500);r.setMsg(msg);return r;}public static R success( Object data) {R r = new R();r.setCode(200);r.setMsg("success");r.setData(data);return r;}
}

登录业务层

package com.zj.service;import com.zj.domain.LoginBodyDTO;
import com.zj.domain.R;
import com.zj.utils.JwtUtils;
import org.jose4j.lang.JoseException;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;@Service
public class LoginService {//登录public R login(LoginBodyDTO loginBodyDTO) throws JoseException {//1.用户名密码数据库校验if(StringUtils.isEmpty(loginBodyDTO.getUsername()) || StringUtils.isEmpty(loginBodyDTO.getPassword())){return R.fail("用户名或者密码为空");}//TODO 数据操作验证用户信息if(loginBodyDTO.getUsername().equals("admin") && loginBodyDTO.getPassword().equals("123456")){//颁发登录tokenString token = JwtUtils.sign(1001L,"admin");return R.success(token);}else{return R.fail("登录信息错误");}}}

创建Higess路由

 

启动项目验证授权服务是不是成功了

这就成功了。

(6)Higress策略配置-JWT配置

这个配置主要是针对微服务的这里主要是order-service,不是针对验证模块的,验证模块不需要添加,总不能让用户第一次登录就带着token吧。

因为在JWT认证流程中需要网关对用户的请求进行验证,也就是需要对用户的请求进行解密,解密成功才能访问微服务,否则直接不让访问。

因为访问每个微服务都需要进行身份的验证,因此需要全局配置JWT,在插件市场配置就是全局配置。

参数配置见文档:https://higress.cn/docs/latest/plugins/authentication/jwt-auth/?spm=36971b57.2ef5001f.0.0.2a932c1fXPZUk1

namestring必填-配置该consumer的名称,每个consumer相当于是一个策略。
jwksstring必填-https://www.rfc-editor.org/rfc/rfc7517 指定的json格式字符串,是由验证JWT中签名的公钥(或对称密钥)组成的Json Web Key Set,其实就是公钥。
issuerstring必填-JWT的签发者,需要和payload中的iss字段保持一致

 开启order-service微服务权限认证。

idea上开启auth服务和order-serice服务测试:

先直接访问order-service模块显然没验证成功:

 再登录一下获取token

再次请求order-service这次带上token

 要注意Authorization的参数: Bearer+token

这样最基础的认证就OK 啦!

(7) Higress策略配置-Key 认证

global_authbool选填(仅实例级别配置-只能在实例级别配置,若配置为true,则全局生效认证机制; 若配置为false,则只对做了配置的域名和路由生效认证机制,若不配置则仅当没有域名和路由配置时全局生效(兼容老用户使用习惯)。
consumersarray of object必填-配置服务的调用者,用于对请求进行认证
keysarray of string必填-API Key 的来源字段名称,可以是 URL 参数或者 HTTP 请求头名称
in_queryboolin_query 和 in_header 至少有一个为 truetrue配置 true 时,网关会尝试从 URL 参数中解析 API Key
in_headerboolin_query 和 in_header 至少有一个为 truetrue配置 true 时,网关会尝试从 HTTP 请求头中解析 API Key

在key认证的全局配置添加下面的配置:

credential: 2bda943c-ba2b-11ec-ba07-00163e1250b5  通过UUID生成的。keys就是在请求的时候要携带的参数,in_header就是放在请求的header中,in_query就是携带到请求的参数上。

在order-sevice服务上使用配置的key认证:

 在不携带apikey参数的时候请求登录是不行的。

带上参数就能访问了。

带上参数访问order-service。

 对于in_header式key认证是一样的。

相关文章:

SpringCloudAlibaba技术栈-Higress

1、什么是Higress? 云原生网关&#xff0c;干啥的&#xff1f;用通俗易懂的话来说&#xff0c;微服务架构下Higress 就像是一个智能的“交通警察”&#xff0c;它站在你的网络世界里&#xff0c;负责指挥和调度所有进出的“车辆”&#xff08;也就是数据流量&#xff09;。它的…...

《信息传播:人工智能助力驱散虚假信息阴霾》

在信息爆炸的时代&#xff0c;虚假信息和谣言如同脱缰野马&#xff0c;肆意传播&#xff0c;对社会秩序和公众生活造成了严重影响。人工智能作为一种强大的技术工具&#xff0c;正逐渐成为信息传播的有力助手&#xff0c;为防止虚假信息和谣言扩散提供了新的途径。 虚假信息和…...

玩客云v1.0 刷机时无法识别USB

v1.0刷机时公对公插头掉了&#xff0c;刷机失败&#xff0c;再次刷机&#xff0c;一直提示无法识别的USB设备&#xff0c;此时LED一直不亮&#xff0c;就像是刷成砖了一样&#xff0c;查了好多文章最后发现正面还有一个地方需要短接。 背面的短接点 【免费】玩客云刷机包s805-…...

STM32F103RCT6学习之五:ADC

1.ADC基础 ADC&#xff08;Analog-Digital Converter&#xff09;模拟-数字转换器ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量&#xff0c;建立模拟电路到数字电路的桥梁12位逐次逼近型ADC&#xff0c;1us转换时间 输入电压范围&#xff1a;0~3.3V&#xff…...

通过Cephadm工具搭建Ceph分布式存储以及通过文件系统形式进行挂载的步骤

1、什么是Ceph Ceph是一种开源、分布式存储系统&#xff0c;旨在提供卓越的性能、可靠性和可伸缩性。它是为了解决大规模数据存储问题而设计的&#xff0c;使得用户可以在无需特定硬件支持的前提下&#xff0c;通过普通的硬件设备来部署和管理存储解决方案。Ceph的灵活性和设计…...

flink+kafka实现流数据处理学习

在应用系统的建设过程中&#xff0c;通常都会遇到需要实时处理数据的场景&#xff0c;处理实时数据的框架有很多&#xff0c;本文将以一个示例来介绍flinkkafka在流数据处理中的应用。 1、概念介绍 flink&#xff1a;是一个分布式、高可用、高可靠的大数据处理引擎&#xff0c…...

SpringBoot使用外置的Servlet容器(详细步骤)

嵌入式Servlet容器&#xff1a;应用打成可执行的jar 优点&#xff1a;简单、便携&#xff1b; 缺点&#xff1a;默认不支持JSP、优化定制比较复杂.&#xff1b; 外置的Servlet容器&#xff1a;外面安装Tomcat---应用war包的方式打包&#xff1b; 操作步骤&#xff1a; 方式一&…...

C# 中的委托与事件:实现灵活的回调机制

C#中的委托&#xff08;Delegate&#xff09;和事件&#xff08;Event&#xff09;。委托和事件是C#中非常重要的特性&#xff0c;它们允许你实现回调机制和发布-订阅模式&#xff0c;从而提高代码的灵活性和解耦程度。通过使用委托和事件&#xff0c;你可以编写更加模块化和可…...

大模型辅助测试的正确打开方式?

测试的基本目的之一&#xff0c;是对被测对象进行质量评估。换言之&#xff0c;是要提供关于被测对象质量的“确定性”。因此&#xff0c;我们很忌讳在测试设计中引入“不确定性”&#xff0c;比如采用不可靠的测试工具、自动化测试代码逻辑复杂易错、测试选择假设过于主观等等…...

设计模式之代理模式

代理模式代码示例&#xff1a;https://blog.csdn.net/weixin_39865508/article/details/141924680 代理模式的左右&#xff0c;一定程度上不暴露被代课对象的内容&#xff0c;更安全&#xff0c;也减少系统的耦合性 静态代理 代理对象和被代理对象都继承同一个接口 在代理对象…...

win11中win加方向键失效的原因

1、可能是你把win键锁了&#xff1a; 解决办法&#xff1a;先按Fn键&#xff0c;再按win键 2、可能是可能是 贴靠窗口设置 中将贴靠窗口关闭了&#xff0c;只需要将其打开就好了...

Html——11. 页面跳转

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>页面跳转</title><meta http-equiv"refresh" content"5; urlhttps://www.51zxw.net"/><!--<meta http-equiv"refresh" co…...

要查询 `user` 表中 `we_chat_open_id` 列不为空的用户数量

要查询 user 表中 we_chat_open_id 列不为空的用户数量&#xff0c;你可以使用以下 SQL 查询语句&#xff1a; SELECT COUNT(*) FROM user WHERE we_chat_open_id IS NOT NULL AND we_chat_open_id ! ;解释&#xff1a; SELECT COUNT(*): 表示要计算符合条件的行数。FROM us…...

docker-compos mysql5.7主从配置

docker-compos mysql5.7主从配置 docker-compose目录结构 配置文件 master/my.cnf [client] port 3306 socket /var/run/mysqld/mysqld.sock[mysqld_safe] pid-file /var/run/mysqld/mysqld.pid socket /var/run/mysqld/mysqld.sock nice 0…...

关于无线AP信道调整的优化(锐捷)

目录 一、信道优化的基本原则二、2.4G频段信道优化三、5G频段信道优化四、信道优化代码具体示例五、其他优化措施 一、信道优化的基本原则 信道优化旨在减少信道间的干扰&#xff0c;提高网络覆盖范围和信号质量。基本原则包括&#xff1a; 1. 选择合适的信道&#xff1a;根据…...

Flask入门一(介绍、Flask安装、Flask运行方式及使用、虚拟环境、调试模式、配置文件、路由系统)

文章目录 一、Flask介绍二、Flask创建和运行 1.安装2.快速使用3.Flask小知识4.flask的运行方式 三、Werkzeug介绍四、Jinja2介绍五、Click CLI 介绍六、Flask安装 介绍watchdog使用python–dotenv使用&#xff08;操作环境变量&#xff09; 七、虚拟环境 介绍Mac/linux创建虚拟…...

解决Docker国内网络问题

6月后以来&#xff0c;大量Docker镜像网站停服&#xff0c;Docker无法下载安装 本仓库致力于解决国内网络原因无法使用Docker的问题。 特点&#xff1a; 使用Github Action将官网的安装脚本/安装包定时下载到本项目Release&#xff0c;供国内使用官方安装包&#xff0c;安全可…...

Anaconda 安装与虚拟环境创建完整指南

Anaconda 安装与虚拟环境创建完整指南 Anaconda 是目前最流行的 Python 和数据科学工具集之一&#xff0c;它不仅可以轻松管理 Python 包&#xff0c;还能提供强大的虚拟环境功能&#xff0c;避免项目之间的依赖冲突。如果你是机器学习、数据科学或计算机视觉的开发者&#xf…...

【Java数据结构】LinkedList与链表

认识LinkedList LinkedList就是一个链表&#xff0c;它也是实现List接口的一个类。LinkedList就是通过next引用将所有的结点链接起来&#xff0c;所以不需要数组。LinkedList也是以泛型的方法实现的&#xff0c;所以使用这个类都需要实例化对象。 链表分为很多种&#xff0c;比…...

Linux 搭建 nginx+keepalived 高可用 | Nginx反向代理

注意&#xff1a;本文为 “Linux 搭建 nginxkeepalived (主备双主模式) 高可用 | Nginx反向代理” 相关文章合辑。 KeepalivedNginx实现高可用&#xff08;HA&#xff09; xyang0917 于 2016-09-17 00:24:15 发布 keepalived 的 HA 分为抢占模式和非抢占模式&#xff0c;抢占…...

17_HTML5 Web 存储 --[HTML5 API 学习之旅]

HTML5 Web 存储&#xff08;Web Storage&#xff09;是 HTML5 引入的一种在用户浏览器中存储数据的机制。它提供了比传统的 cookies 更加方便和强大的功能&#xff0c;包括更大的存储空间、更好的性能以及更简单的 API。Web 存储主要分为两种类型&#xff1a;localStorage 和 s…...

uni-app(优医咨询)项目实战 - 第7天

学习目标&#xff1a; 能够基于 WebSocket 完成问诊全流程 能够使用 uniCloud 云存储上传文件 能够完成查看电子处方的功能 能够完成医生评价的功能 一、问诊室 以对话聊天的方式向医生介绍病情并获取诊断方案&#xff0c;聊天的内容支持文字和图片两种形式。 首先新建一…...

今日总结 2024-12-28

今天全身心投入到鸿蒙系统下 TCPSocket 的学习中。从最基础的 TCP 协议三次握手、四次挥手原理重新梳理&#xff0c;深刻理解其可靠连接建立与断开机制&#xff0c;这是后续运用 TCPSocket 无误通信的根基。在深入鸿蒙体系时&#xff0c;仔细研读了其为 TCPSocket 封装的 API&a…...

ip归属地怎么判定?如何查看自己ip属地

在当今数字化时代&#xff0c;IP地址作为互联网通信的基础&#xff0c;扮演着至关重要的角色。而IP归属地的判定与查看&#xff0c;不仅关乎网络安全、隐私保护&#xff0c;还直接影响到社交平台的信任机制与信息传播的真实性。本文将深入探讨IP归属地的判定原理以及如何查看自…...

4.采用锁操作并支持等待功能的线程安全队列

分析 书接上文 修改push()似乎并不困难:在函数末尾加上对data_cond.notify_one()的调用即可&#xff0c;与代码清单1(第一篇文章)一样。事情其实没那么简单&#xff0c;我们之所以采用精细粒度的锁&#xff0c;目的是尽可能提高并发操作的数量。如果在notify_one()调用期间&a…...

螺杆支撑座在运用中会出现哪些问题?

螺杆支撑座是一种用于支撑滚珠螺杆的零件&#xff0c;通常用于机床、数控机床、自动化生产线等高精度机械设备中。在运用中可能会出现多种问题&#xff0c;这些问题源于多个方面&#xff0c;以下是对可能出现的问题简单了解下&#xff1a; 1、安装不当&#xff1a;安装过程中没…...

OSI 七层模型 | TCP/IP 四层模型

注&#xff1a;本文为 “OSI 七层模型 | TCP/IP 四层模型” 相关文章合辑。 未整理去重。 OSI 参考模型&#xff08;七层模型&#xff09; BeretSEC 于 2020-04-02 15:54:37 发布 OSI 的概念 七层模型&#xff0c;亦称 OSI&#xff08;Open System Interconnection&#xf…...

秒鲨后端之MyBatis【2】默认的类型别名、MyBatis的增删改查、idea中设置文件的配置模板、MyBatis获取参数值的两种方式、特殊SQL的执行

别忘了请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01;! ! ! 下篇更新&#xff1a; 秒鲨后端之MyBatis【3】自定义映射resultMap、动态SQL、MyBatis的缓存、MyBatis的逆向工程、分页插件。 默认的类型别名 MyBatis的增删改查 添加 <!--int insertUs…...

快云服务器小助手getdetail存在任意文件文件读取漏洞

免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…...

尚硅谷Vue3入门到实战 —— 02 编写 App 组件

根目录下的 index.html 是项目的入口文件&#xff0c;默认的具体内容如下&#xff1a; src 文件夹分析 <!DOCTYPE html> <html lang""><head><meta charset"UTF-8"><link rel"icon" href"/favicon.ico"&…...

Java - 日志体系_Simple Logging Facade for Java (SLF4J)日志门面_SLF4J实现原理分析

文章目录 官网SLF4J 简单使用案例分析SLF4J 获取 Logger 的原理获取 ILoggerFactory 的过程获取 Logger 的过程SLF4J 与底层日志框架的集成 小结 官网 https://slf4j.org/ Simple Logging Facade for Java &#xff08;SLF4J&#xff09; 用作各种日志记录框架&#xff08;e.g…...

Flutter 调试环境下浏览器网络请求跨域问题解决方案

本篇文章主要讲解&#xff0c;Flutter调试环境情况下&#xff0c;浏览器调试报错跨域问题的解决方法&#xff0c;通过本篇文章你可以快速掌握Flutter调试环境情况下的跨域问题。 日期&#xff1a;2024年12月28日 作者&#xff1a;任聪聪 报错现象&#xff1a; 报文信息&#xf…...

python编译为可执行文件

1.用py2exe生成可执行文件 目前&#xff0c;在py2exe 0.9.2版本已经支持python3.x&#xff0c;它可以将python程序打包为windows下独立的可执行文件。 要使用py2exe&#xff0c;首先要编写一个编译程序(例如编写一个名为setup.py的程序)&#xff0c;然后在python中运行…...

【机器学习(九)】分类和回归任务-多层感知机(Multilayer Perceptron,MLP)算法-Sentosa_DSML社区版 (1)111

文章目录 一、算法概念111二、算法原理&#xff08;一&#xff09;感知机&#xff08;二&#xff09;多层感知机1、隐藏层2、激活函数sigma函数tanh函数ReLU函数 3、反向传播算法 三、算法优缺点&#xff08;一&#xff09;优点&#xff08;二&#xff09;缺点 四、MLP分类任务…...

spring cloud微服务-OpenFeign的使用

OpenFeign的使用 openFeign的作用是服务间的远程调用 &#xff0c;比如通过OpenFeign可以实现调用远程服务。 已经有了LoadBalancer为什么还要用openFeign? 在微服务架构中&#xff0c;LoadBalancer和OpenFeign虽然都提供了服务间调用的能力&#xff0c;但它们的设计目的和…...

欢迪迈手机商城设计与实现基于(代码+数据库+LW)

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本欢迪迈手机商城就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…...

GCP Cloud Architect exam - PASS

备考指南 推荐视频课程 https://www.udemy.com/course/google-cloud-architect-certifications/?couponCodeKEEPLEARNING 推荐题库 https://www.udemy.com/course/gcp-professional-cloud-architect-exam-practice-tests-2024​/?couponCodeKEEPLEARNING 错题集 http…...

通过 `@Configuration` 和 `WebMvcConfigurer` 配置 Spring MVC 中的静态资源映射

通过 Configuration 和 WebMvcConfigurer 配置 Spring MVC 中的静态资源映射 一、前言1. 了解静态资源的默认配置2. 使用 Configuration 和 WebMvcConfigurer 自定义资源映射示例&#xff1a;将 /upload/ 和 /img/ 映射到不同的文件系统目录解释&#xff1a;为什么使用 classpa…...

敏捷测试文化的转变

敏捷文化是敏捷测试转型的基础&#xff0c;只有具备敏捷文化的氛围&#xff0c;对组织架构、流程和相关测试实践的调整才能起作用。在前面的敏捷测试定义中&#xff0c;敏捷测试是遵从敏捷软件开发原则的一种测试实践&#xff0c;这意味着敏捷的价值观。 此外&#xff0c;从传…...

深度学习:从原理到搭建基础模型

引言: 深度学习为什么火? 深度学习在处理复杂的感知和模式识别任务方面展现出了前所未有的能力。以图像识别为例,深度学习模型(如卷积神经网络 CNN)能够识别图像中的各种物体、场景和特征,准确率远超传统的计算机视觉方法。 当然这之中也还因为 大数据时代的推动(随着…...

MySQL和HBase的对比

Mysql &#xff1a;关系型数据库&#xff0c;主要面向 OLTP &#xff0c;支持事务&#xff0c;支持二级索引&#xff0c;支持 sql &#xff0c;支持主从、 Group Replication 架构模型&#xff08;此处以 Innodb 为例&#xff0c;不涉及别的存储引擎&#xff09;。 HBase &am…...

Gateway Timeout504 网关超时的完美解决方法

引言 在Web开发中&#xff0c;遇到HTTP状态码504&#xff08;Gateway Timeout&#xff09;是相当常见的。这个状态码表示前端服务器&#xff08;如负载均衡器或代理服务器&#xff09;作为网关工作时&#xff0c;在尝试访问后端服务器处理请求时未能及时得到响应。本文将探讨导…...

【探花交友】day03—MongoDB基础

目录 课程介绍 1、通用设置 1.1 需求分析 1.2 查询通用设置 1.2 陌生人问题 1.3 通知设置 1.4 黑名单管理 2、MongoDB简介 1.1、MongoDB简介 1.2、MongoDB的特点 1.3 数据类型 3、MongoDB入门 2.1、数据库以及表的操作 2.2、新增数据 2.3、更新数据 2.4、删除数…...

总结-常见缓存替换算法

缓存替换算法 1. 总结 1. 总结 常见的缓存替换算法除了FIFO、LRU和LFU还有下面几种&#xff1a; 算法优点缺点适用场景FIFO简单实现可能移除重要数据嵌入式系统&#xff0c;简单场景LRU局部性原理良好维护成本高&#xff0c;占用更多存储空间内存管理&#xff0c;浏览器缓存L…...

宏集eX710物联网工控屏在石油开采机械中的应用与优势

案例概况 客户&#xff1a;天津某石油机械公司 应用产品&#xff1a;宏集eX710物联网工控屏 应用场景&#xff1a;钻井平台设备控制系统 一、应用背景 石油开采和生产过程复杂&#xff0c;涵盖钻井平台、采油设备、压缩机、分离器、管道输送系统等多种机械设备。这些设备通…...

【社区投稿】自动特征auto trait的扩散规则

自动特征auto trait的扩散规则 公式化地概括&#xff0c;auto trait marker trait derived trait。其中&#xff0c;等号右侧的marker与derived是在Rustonomicon书中的引入的概念&#xff0c;鲜见于Rust References。所以&#xff0c;若略感生僻&#xff0c;不奇怪。 marker …...

【MySQL】第一弹----库的操作及数据类型

笔上得来终觉浅,绝知此事要躬行 &#x1f525; 个人主页&#xff1a;星云爱编程 &#x1f525; 所属专栏&#xff1a;MySQL &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 一、SQL 语句分类 DDL:数据定…...

【服务器主板】定制化:基于Intel至强平台的全新解决方案

随着数据处理需求不断增长&#xff0c;服务器硬件的发展也在持续推进。在这一背景下&#xff0c;为用户定制了一款全新的基于Intel至强平台的服务器主板&#xff0c;旨在提供强大的计算能力、优异的内存支持以及高速存储扩展能力。适用于需要高性能计算、大规模数据处理和高可用…...

Flutter路由工具类RouteUtils,可二次开发,拿来即用

一、RouteUtils路由核心类 /*** 路由封装*/ class RouteUtils {RouteUtils._();static final navigatorKey GlobalKey<NavigatorState>();// App 根节点Contextstatic BuildContext get context > navigatorKey.currentContext!;static NavigatorState get navigato…...

报错:No module named ‘pygeohash‘

如果你遇到这个错误&#xff1a; platform... using builtin-java classes where applicableTraceback (most recent call last):File "/home/spark-shell/AppLogDWD02.py", line 4, in <module>from pygeohash import encodeModuleNotFoundError: No module …...