springcloud Ribbon的详解

1、Ribbon是什么

Ribbon是Netflix发布的开源项目,Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的框架。

2、Ribbon能干什么

LB负载均衡(Load Balance)是什么?简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用)。常见的负载均衡有软件Nginx,硬件 F5等。

3.负载均衡使用场景

现在Java非常流行微服务,也就是所谓的面向服务开发,将一个项目拆分成了多个项目,其优点有很多,其中一个优点就是:将服务拆分成一个一个微服务后,我们很容易的来针对性的进行集群部署。例如订单模块用的人比较多,我就可以将这个模块多部署几台机器,来分担单个服务器的压力。

这时候有个问题来了,前端页面请求的时候到底请求集群当中的哪一台?既然是降低单个服务器的压力,所以肯定全部机器都要利用起来,而不是说一台用着,其他空余着。这时候就需要用负载均衡了,像这种前端页面调用后端请求的,要做负载均衡的话,常用的就是Nginx。

4.Ribbon和Nginx负载均衡区别

  • 当后端服务是集群的情况下,前端页面调用后端请求,要做负载均衡的话,常用的就是Nginx。
    Ribbon主要是在服务端内做负载均衡,举例:订单后端服务 要调用 支付后端服务,这属于后端之间的服务调用,压根根本不经过页面,而支付后端服务是集群,这时候订单服务就需要做负载均衡来调用支付服务,记住是订单服务做负载均衡 来调用 支付服务。

5.负载均衡分类

  • 集中式LB:即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx),由该设施负责把访问请求通过某种策略转发至服务的提供方;
  • 进程内LB:将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。
    Ribbon负载均衡

Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程。

举例:微服务经常会涉及到A服务调用B服务的接口,这时候就需要用HTTP远程调用框架,常见的有Feign、RestTemplate、HttpClient,假如B服务只有一个节点,这时候我们可以在调用的时候写固定ip来进行调用,假如B服务的节点存在多个(也就是集群),那A服务究竟调用B服务的哪个节点呢,这时候可以通过负载均衡框架来计算出调用哪个,比如轮询调用B服务的多个节点,总不可能一直调用人家的一个服务,这样B服务的集群有什么意义呢?或者也可以随机调用任意节点,总之负载均衡的作用就是避免一直调用一个节点。

大概的流程:RestTemplate或者Feign可以通过注册中心拿到服务提供方的IP+端口,假如提供者有多个,那他就会拿到多个地址,有了这些地址就差访问的时候访问哪个地址的服务了,而Ribbon可以很好的和RestTemplate或者Feign进行集成,来决定调用哪个服务,具体是负载均衡还是随机Ribbon都可以设置。

项目处于维护状态 ,已经一年多没有更新过了。

在这里插入图片描述

6.Ribbion架构说明

在这里插入图片描述
在这里插入图片描述

首先通过上图一定要明白一点:ribbon一定是用在消费方,而不是服务的提供方!

Ribbon在工作时分成两步(这里以Eureka为例,consul和zk同样道理):

第一步先选择 EurekaServer ,它优先选择在同一个区域内负载较少的server.
第二步再根据用户指定的策略,在从server取到的服务注册列表中选择一个地址。

之前写样例时候没有引入spring-cloud-starter-ribbon也可以使用ribbon,这是为什么?

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

猜测spring-cloud-starter-netflix-eureka-client自带了spring-cloud-starter-ribbon引用,证明如下: 可以看到spring-cloud-starter-netflix-eureka-client 确实引入了Ribbon(zk和consul注册中心同样是如此

在这里插入图片描述

7 .Ribbon负载均衡策略

Ribbon负载均衡策略是 IRule接口定义的,每一个子接口都是一种策略。下面是常见负载均衡算法

1.负载均衡种类

负载均衡类规则
RoundRobinRule轮询选择服务器。Ribbon默认负载均衡算法。
AvailabilitvFilteringRule(1) 默认情况,服务器连接3次失败,服务器设置为短路状态。短路状态持续30秒,如果再连接失败,短路状态持续时间就会几何级增长。 (2)并发数高的服务器。可配置该规则会忽略并发数高的服务器。并发数上限可以配置。
WeightedResponseTimeRule给服务器赋予权重。响应时间越长,权重越小。权重影响服务器的选择。
ZoneAvoidanceRule使用Zone对服务器进行分类。Zone可以是一个机房、一个机架等。然后对Zone内的服务进行轮询。例如:配置Zone是曹县机房,然后服务提供者会优先选择曹县机房的服务器。
BestAvailableRule忽略短路的服务器并选择并发数低的服务器。
RandomRule随机选择一个可用服务器。
RetryRule重试机制的选择逻辑。

8.置负载均衡

8.1.RestTemplate远程调用配置负载均衡

	@Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 根据订单id查询订单
        Order order = orderMapper.findById(orderId);
        // 利用RestTemplate发起http请求,根据用户id查询用户
        // 把localhost改为服务名称
 这里这里  String url = "http://userservice/user/" + order.getUserId();
        //String url = "http://localhost:8081/user/" + order.getUserId();
        // 发送http请求,实现远程调用,现在是get请求类型
        User user = restTemplate.getForObject(url, User.class);
        // 封装user到Order
        order.setUser(user);
        // 返回值
        return order;
    }


注意: Feign集成了Ribbon,不用去特别配置负载均衡。
2.RestTemplate配置类加上注解

	 /**
     * 创建RestTemplate并注入Spring容器
     */
    @Bean
    @LoadBalanced //负载均衡注解
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

8.2 配置负载均衡

(1) 代码类型

注意:这种配置是全局的,订单服务不光调用用户服务是随机的,调用其他的服务也是随机的
//注入新的负载均衡算法 在启动类内注入也可以自定义配置类
@Bean
public IRule randomRule() {
	//随机选取一个可用服务器
    return new RandomRule();
}

(2) yml中配置

注意:这种局部配置,只针对用户服务去选择负载均衡的算法

userservice:  # 服务名称
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.RandomRule  # 负载均衡规则

(3) Ribbon的饥饿加载配置

Ribbon默认是懒加载: 第一次加载才会创建 LoadBalancerClient ,请求时间会很长。
饥饿加载: 在项目启动时创建,降低第一次访问的耗时。

在Spring Cloud中,Ribbon的饥饿加载是指在启动时就加载并初始化相关的服务调用客户端配置,而不是等到第一次请求时再进行加载。这样做可以提高系统的响应速度,因为它避免了第一次请求的延迟。要配置Ribbon的饥饿加载,你需要在你的应用程序中设置spring.cloud.load-balancer.ribbon.enabled为true,默认情况下它是开启的。如果你需要关闭它,可以设置为false

(1) 单个服务配置饥饿加载(在yml文件配置)

spring:
  cloud:
    load-balancer:
      ribbon:
        eager-load:
          enabled: true # 开启Ribbon的饥饿加载
          clients: # 指定需要进行饥饿加载的服务列表
            - service-id-1
            - service-id-2

(1) 多个服务配置饥饿加载(在yml文件配置)

spring:
  cloud:
    load-balancer:
		ribbon:
		  eager-load:
		    enabled: true # 开启饥饿加载
		    clients: # 指定饥饿加载的服务名称
		      - userservice   # 用户服务
		      - cangkuservice # 仓库服务
		      - zhifuservice  # 支付服务

在这个配置中,service-id-1和service-id-2是你希望在启动时就加载并初始化的服务的ID。
注意:开启Ribbon的饥饿加载可能会稍微增加启动时间,因为它会预先初始化与服务相关的客户端。但是,这对于提高系统的整体响应速度是有益的。

九 Ribbon实现负载均衡的原理

Ctrl + N 快速查找类:原理是 LoadBalancerInterceptor 实现了 ClientHttpRequestInterceptor 接口。

客户端http请求拦截器

@FunctionalInterface
public interface ClientHttpRequestInterceptor {
    ClientHttpResponse intercept(HttpRequest var1, byte[] var2, ClientHttpRequestExecution var3) throws IOException;
}
 
public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {

	重写ClientHttpRequestInterceptor接口的方法
	@Override
	public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,final ClientHttpRequestExecution execution) throws IOException {
		// 1.获取http的请求地址
		final URI originalUri = request.getURI();
		
		// 2.获取服务的名称
		String serviceName = originalUri.getHost();
		
		Assert.state(serviceName != null,"Request URI does not contain a valid hostname: " + originalUri);
		
		//3.我们进去execute方法:就是为了从Eureka-Server拉取信息
		return this.loadBalancer.execute(serviceName,this.requestFactory.createRequest(request, body, execution));
	}
}
public class RibbonLoadBalancerClient implements LoadBalancerClient {
	//4.进入此方法
	public <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException {
		//调用下面的execute方法
        return this.execute(serviceId, (LoadBalancerRequest)request, (Object)null);
    }

	public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint) throws IOException {
		
		//5.根据服务名称获取对应的服务列表,loadBalancer里面有List存有服务的地址
        ILoadBalancer loadBalancer = this.getLoadBalancer(serviceId);
       
        //6.根据算法选择要使用的服务,会进入IRule接口里面,默认是轮询算法
        Server server = this.getServer(loadBalancer, hint);
       
        if (server == null) {
            throw new IllegalStateException("No instances available for " + serviceId);
        } else {
            RibbonLoadBalancerClient.RibbonServer ribbonServer = new RibbonLoadBalancerClient.RibbonServer(serviceId, server, this.isSecure(server, serviceId), this.serverIntrospector(serviceId).getMetadata(server));
            return this.execute(serviceId, (ServiceInstance)ribbonServer, (LoadBalancerRequest)request);
        }
    }
}

在这里插入图片描述

十 Ribbon单独使用,配置自动重试,实现负载均衡和高可用

JDK 1.8,SpringCloud Greenwich.SR2,SpringBoot 2.1.3.RELEASE

本文示例,CONSUMER-SERVICE服务调用PRODUCER-SERVICE服务。在进行以下步骤前,请先启动两个普通的SpringBoot服务PRODUCER-SERVICE。

2.1 pom依赖

因为这里独立使用Ribbon,所以CONSUMER-SERVICE只需要spring-cloud-starter-netflix-ribbon,启动主类也无需更多的注解,如

@EnableEurekaClient、@EnableDiscoveryClient、@EnableCircuitBreaker等,只需保留@SpringBootApplication即可。

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
</dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.SR2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2.2 RestTemplate配置

Ribbon是对RestTemplate的加强,需要为RestTemplate添加注解@LoadBalanced,使之具有负载均衡能力。如下:

@Bean
@LoadBalanced
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
    RestTemplate restTemplate = new RestTemplate(factory);
    restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
    return restTemplate;
}

2.3 Ribbon配置

注意:网上和书上很多教程都没有提到ribbon.restclient.enabled这一配置,导致再怎么尝试都无法成功自动重试。

spring.application.name=CONSUMER-SERVICE
server.port=8801
 
ribbon.restclient.enabled=true
#开启重试机制
spring.cloud.loadbalancer.retry.enabled=true
#请求连接的超时时间
PRODUCER-SERVICE.ribbon.ConnectTimeout=250
#请求处理的超时时间
PRODUCER-SERVICE.ribbon.ReadTimeout=1000
#对所有操作请求都进行重试,默认false,只有GET请求会重试;这是防止POST等对数据有影响的请求在重试后因为接口未做幂等性导致数据异常,影响较大
PRODUCER-SERVICE.ribbon.OkToRetryOnAllOperations=true
#指定请求重试开关,经调试源码该属性未被使用,疑似bug,导致不论怎么设置,都是只有服务提供者的Get请求可以被自动重试
#PRODUCER-SERVICE.ribbon.RequestSpecificRetryOn=true
#切换实例的重试次数
PRODUCER-SERVICE.ribbon.MaxAutoRetriesNextServer=2
#对当前实例的重试次数
PRODUCER-SERVICE.ribbon.MaxAutoRetries=1
 
#服务PRODUCER-SERVICE的地址
PRODUCER-SERVICE.ribbon.listOfServers=localhost:8080,localhost:8083

2.4 Ribbon调用服务

在Controller中,注入RestTemplate,使用服务名(即spring.application.name)的方式,调用PRODUCER-SERVICE服务的GET接口,如下:

@Controller
@RequestMapping("consumer/api")
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;
 
    @GetMapping("/test")
    @ResponseBody
    public String test() {
        ResponseEntity<String> entity = restTemplate
                .getForEntity("http://PRODUCER-SERVICE/outer/data?res=3&msgKey=token123", String.class);
        return entity.getBody();
    }
}

三、测试运行

3.1 负载均衡测试
启动一个消费者服务CONSUMER-SERVICE,多次访问/consumer/api/test,可以通过给PRODECER-SERVICE服务的/outer/data接口添加调试日志的打印,来确认默认使用了轮询的负载均衡策略。

3.2 高可用测试
停止其中一个PRODECER-SERVICE服务实例,确认轮询到已停止的服务时,可以成功地在未停止的服务上自动重试请求。

四、无法成功自动重试的几种情况
本人在单独使用Ribbon的过程中,碰到以下几种无法自动重试其他服务节点的情况:

4.1 ribbon.restclient.enabled
遇到Ribbon的问题,网上一搜,千篇一律,也不知道作者们是否亲自实践证明可用,就随意发篇文章。言归正传,若不设置ribbon.restclient.enabled=true,在本人的实验环境中是无法自动重试的。

4.2 Maven打包有警告
在SpringCloud生态的开发中,各组件往往自动依赖了很多其他的jar包,如果向Maven本地仓库下载的过程中,网络不好,就会下载到一份不完整的jar包或pom文件,最终可能会导致打包出错。下面是在使用Maven打包项目时,比较常见下面的警告:

[WARNING] The POM for com.sun.jersey:jersey-core:jar:1.19.1 is
invalid, transitive dependencies (if any) will not be available
[WARNING] The POM for com.sun.jersey:jersey-client:jar:1.19.1 is
invalid, transitive dependencies (if any) will not be available

可以看出来,提示我们传递依赖将失效,所以有可能整个打包过程是SUCCESS的,但是最后启动jar包时,却可能报NoClassDef等缺少jar包的错误。因此,我们需要在打包时加上参数 -X 以查看具体原因:

[WARNING] The POM for com.sun.jersey:jersey-core:jar:1.19.1 is
invalid, transitive dependencies (if any) will not be available: 1
problem was encountered while building the effective model for
com.sun.jersey:jersey-core:[unknown-version] [FATAL] Non-parseable POM
E:\maven\repository\com\sun\jersey\jersey-project\1.19.1\jersey-project-1.19.1.pom:
processing instruction can not have PITarget with reserved xml name
(position: END_TAG seen …\n\n\n<?xml …
@627:7) @
E:\maven\repository\com\sun\jersey\jersey-project\1.19.1\jersey-project-1.19.1.pom,
line 627, column 7 [WARNING] The POM for
com.sun.jersey:jersey-client:jar:1.19.1 is invalid, transitive
dependencies (if any) will not be available: 1 problem was encountered
while building the effective model for
com.sun.jersey:jersey-client:[unknown-version] [FATAL] Non-parseable
POM
E:\maven\repository\com\sun\jersey\jersey-project\1.19.1\jersey-project-1.19.1.pom:
processing instruction can not have PITarget with reserved xml name
(position: END_TAG seen …\n\n\n<?xml …
@627:7) @
E:\maven\repository\com\sun\jersey\jersey-project\1.19.1\jersey-project-1.19.1.pom,
line 627, column 7 [WARNING] The POM for
com.sun.jersey.contribs:jersey-apache-client4:jar:1.19.1 is invalid,
transitive dependencies (if any) will not be available: 1 problem was
encountered while building the effective model for
com.sun.jersey.contribs:jersey-apache-client4:[unknown-version]
[FATAL] Non-parseable POM
E:\maven\repository\com\sun\jersey\jersey-project\1.19.1\jersey-project-1.19.1.pom:
processing instruction can not have PITarget with reserved xml name
(position: END_TAG seen …\n\n\n<?xml …
@627:7) @
E:\maven\repository\com\sun\jersey\jersey-project\1.19.1\jersey-project-1.19.1.pom,
line 627, column 7

特别注意FATAL这个最严重的日志级别的信息, 日志提醒我们本地仓库的pom文件E:\maven\repository\com\sun\jersey\jersey-project\1.19.1\jersey-project-1.19.1.pom解析出错,然后我们去此目录下,可以发现这个文件未被下载完整。最后的解决方式是删除此文件的父目录,重新打包,则会自动下载一份完整的pom文件,警告消失,打包成功。

4.3 OkToRetryOnAllOperations和RequestSpecificRetryOn失效
在上文的例子中,消费者服务调用的生产者服务接口是GET类型,自动重试没有任何问题。接着,本人尝试让消费者调用生产者服务的POST接口,同时仍然设置了ribbon.OkToRetryOnAllOperations=true,结果无法成功重试,然后去调试ribbon源码,查看自动重试机制,经查,OkToRetryOnAllOperations和RequestSpecificRetryOn属性可以成功获取到,但RequestSpecificRetryOn并未被获取出来使用,疑似Ribbon的bug。这里记录一下调试的重要部分,

(1)Ribbon配置属性类com.netflix.client.config.CommonClientConfigKey;

(2)Ribbon判断是否重试:

所以,单独使用Ribbon需谨慎!

十一、Spring Cloud Ribbon配置详解

常用配置

1. 禁用 Eureka

当我们在 RestTemplate 上添加 @LoadBalanced 注解后,就可以用服务名称来调用接口了,当有多个服务的时候,还能做负载均衡。

这是因为 Eureka 中的服务信息已经被拉取到了客户端本地,如果我们不想和 Eureka 集成,可以通过下面的配置方法将其禁用。

# 禁用 Eureka
ribbon.eureka.enabled=false

当我们禁用了 Eureka 之后,就不能使用服务名称去调用接口了,必须指定服务地址。

2. 配置接口地址列表

上面我们讲了可以禁用 Eureka,禁用之后就需要手动配置调用的服务地址了,配置如下:

# 禁用 Eureka 后手动配置服务地址
ribbon-config-demo.ribbon.listOfServers=localhost:8081,localhost:8083

这个配置是针对具体服务的,前缀就是服务名称,配置完之后就可以和之前一样使用服务名称来调用接口了。

3. 配置负载均衡策略

Ribbon 默认的策略是轮询,从我们前面讲解的例子输出的结果就可以看出来,Ribbon 中提供了很多的策略,这个在后面会进行讲解。我们通过配置可以指定服务使用哪种策略来进行负载操作。

4. 超时时间

Ribbon 中有两种和时间相关的设置,分别是请求连接的超时时间和请求处理的超时时间,设置规则如下:

# 请求连接的超时时间
ribbon.ConnectTimeout=2000
# 请求处理的超时时间
ribbon.ReadTimeout=5000
也可以为每个Ribbon客户端设置不同的超时时间, 通过服务名称进行指定:
ribbon-config-demo.ribbon.ConnectTimeout=2000
ribbon-config-demo.ribbon.ReadTimeout=5000

5. 并发参数

# 最大连接数
ribbon.MaxTotalConnections=500
# 每个host最大连接数
ribbon.MaxConnectionsPerHost=500

代码配置 Ribbon

配置 Ribbon 最简单的方式就是通过配置文件实现。当然我们也可以通过代码的方式来配置。

通过代码方式来配置之前自定义的负载策略,首先需要创建一个配置类,初始化自定义的策略,代码如下所示。

@Configuration
public class BeanConfiguration {
@Bean
public MyRule rule() {
return new MyRule();
}
}

创建一个 Ribbon 客户端的配置类,关联 BeanConfiguration,用 name 来指定调用的服务名称,代码如下所示。

@RibbonClient(name = "ribbon-config-demo", configuration = BeanConfiguration.class)
public class RibbonClientConfig {
}

可以去掉之前配置文件中的策略配置,然后重启服务,访问接口即可看到和之前一样的效果。

配置文件方式配置 Ribbon

除了使用代码进行 Ribbon 的配置,我们还可以通过配置文件的方式来为 Ribbon 指定对应的配置:

<clientName>.ribbon.NFLoadBalancerClassName: Should implement ILoadBalancer(负载均衡器操作接口)
<clientName>.ribbon.NFLoadBalancerRuleClassName: Should implement IRule(负载均衡算法)
<clientName>.ribbon.NFLoadBalancerPingClassName: Should implement IPing(服务可用性检查)
<clientName>.ribbon.NIWSServerListClassName: Should implement ServerList(服务列表获取)
<clientName>.ribbon.NIWSServerListFilterClassName: Should implement ServerList­Filter(服务列表的过滤)

重试机制

在集群环境中,用多个节点来提供服务,难免会有某个节点出现故障。用 Nginx 做负载均衡的时候,如果你的应用是无状态的、可以滚动发布的,也就是需要一台台去重启应用,这样对用户的影响其实是比较小的,因为 Nginx 在转发请求失败后会重新将该请求转发到别的实例上去。

由于 Eureka 是基于 AP 原则构建的,牺牲了数据的一致性,每个 Eureka 服务都会保存注册的服务信息,当注册的客户端与 Eureka 的心跳无法保持时,有可能是网络原因,也有可能是服务挂掉了。

在这种情况下,Eureka 中还会在一段时间内保存注册信息。这个时候客户端就有可能拿到已经挂掉了的服务信息,故 Ribbon 就有可能拿到已经失效了的服务信息,这样就会导致发生失败的请求。

这种问题我们可以利用重试机制来避免。重试机制就是当 Ribbon 发现请求的服务不可到达时,重新请求另外的服务。

1. RetryRule 重试

解决上述问题,最简单的方法就是利用 Ribbon 自带的重试策略进行重试,此时只需要指定某个服务的负载策略为重试策略即可:

ribbon-config-demo.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RetryRule

2. Spring Retry 重试

除了使用 Ribbon 自带的重试策略,我们还可以通过集成 Spring Retry 来进行重试操作。

在 pom.xml 中添加 Spring Retry 的依赖,代码如下所示。

<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>

配置重试次数等信息:

# 对当前实例的重试次数
ribbon.maxAutoRetries=1
# 切换实例的重试次数
ribbon.maxAutoRetriesNextServer=3
# 对所有操作请求都进行重试
ribbon.okToRetryOnAllOperations=true
# 对Http响应码进行重试
ribbon.retryableStatusCodes=500,404,502

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/568656.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI视频改字个性化祝福豪车装X系统uniapp前端开源源码下载

装X系统源码简介 创意无限&#xff01;AI视频改字祝福&#xff0c;豪车装X系统源码开源&#xff0c;打造个性化祝福视频不再难&#xff01; 想要为你的朋友或家人送上一份特别的祝福&#xff0c;让他们感受到你的真诚与关怀吗&#xff1f;现在&#xff0c; 通过开源的AI视频…

从0到1—POC编写基础篇(二)

接着上一篇 POC常用基础模块 urllib 模块 Python urllib 库用于操作网页 URL&#xff0c;并对网页的内容进行抓取处理。 urllib 包 包含以下几个模块&#xff1a; ●urllib.request - 打开和读取 URL。 ●urllib.error - 包含 urllib.request 抛出的异常。 ●urllib.parse - …

新技术前沿-2024-大型语言模型LLM的本地化部署

参考快速入门LLM 参考究竟什么是神经网络 1 深度学习 1.1 神经网络和深度学习 神经网络是一种模拟人脑神经元工作方式的机器学习算法,也是深度学习算法的基本构成块。神经网络由多个相互连接的节点(也称为神经元或人工神经元)组成,这些节点被组织成层次结构。通过训练,…

【网络安全】在网络中如何对报文和发送实体进行鉴别?

目录 1、报文鉴别 &#xff08;1&#xff09;使用数字签名进行鉴别 &#xff08;2&#xff09;密码散列函数 &#xff08;3&#xff09;报文鉴别码 2、实体鉴别 鉴别(authentication) 是网络安全中一个很重要的问题。 一是要鉴别发信者&#xff0c;即验证通信的对方的确是…

小扎宣布开放 Meta Horizo​​n OS

日前&#xff0c;Meta以“混合现实的新时代”为题的博文宣布向第三方制造商开放Meta Horizon OS&#xff0c;包括华硕、联想和微软Xbox等等&#xff1a; Meta正在朝着为元宇宙建立一个更开放的计算平台的愿景迈出下一步。Meta正在向第三方硬件制造商开放赋能Meta Quest设备的操…

使用 IPAM 解决方案简化分布式网络管理

随着组织在数字领域的全球扩张&#xff0c;分布式网络是不可避免的&#xff0c;这意味着&#xff0c;随着 IT 基础设施的发展&#xff0c;组织需要适应&#xff0c;这包括在不断增长的系统需求、应用程序堆栈、各种协议和安全防御中监控、现代化和简化流程和资源。在有效管理现…

AJAX——案例

1.商品分类 需求&#xff1a;尽可能同时展示所有商品分类到页面上 步骤&#xff1a; 获取所有的一级分类数据遍历id&#xff0c;创建获取二级分类请求合并所有二级分类Promise对象等待同时成功后&#xff0c;渲染页面 index.html代码 <!DOCTYPE html> <html lang&qu…

Pycharm代码规范与代码格式化插件安装

给大家分享两个PyCharm编辑器的插件&#xff0c;分别是pylint与autopep8&#xff0c;主要用来提高我们在使用python进行自动化测试编写以及性能测试脚本编写过程中的代码质量、可读性与美观性。 pylint&#xff1a; ● 代码检查工具&#xff1a;它可以帮助检查代码中的错误、…

pnpm 安装后 node_modules 是什么结构?为什么 webpack 不识别 pnpm 安装的包?

本篇研究&#xff1a;使用 pnpm 安装依赖时&#xff0c;node_modules 下是什么结构 回顾 npm3 之前&#xff1a;依赖树 缺点&#xff1a; frequently packages were creating too deep dependency trees, which caused long directory paths issue on Windowspackages were c…

明日方舟游戏助手:一键完成日常任务 | 开源日报 No.233

MaaAssistantArknights/MaaAssistantArknights Stars: 11.6k License: AGPL-3.0 MaaAssistantArknights 是一款《明日方舟》游戏的小助手&#xff0c;基于图像识别技术&#xff0c;支持一键完成全部日常任务。 刷理智、掉落识别及上传企鹅物流智能基建换班、自动计算干员效率…

《ElementPlus 与 ElementUI 差异集合》el-select 差异点,如:高、宽、body插入等

宽度 Element UI 父元素不限制宽度时&#xff0c;默认有个宽度 207px&#xff1b; 父元素有固定宽度时&#xff0c;以父元素宽度为准&#xff1b; Element Plus 父元素不限制宽度时&#xff0c;默认100%&#xff1b; 父元素有固定宽度时&#xff0c;以父元素宽度为准&#x…

哪些因素影响了PCB电路板切割精度?

PCB电路板切割是电子制造过程中一个至关重要的环节&#xff0c;其精度对后续工序的质量和效率具有决定性影响。因此&#xff0c;了解影响PCB电路板切割精度的原因&#xff0c;对于提高电子产品的质量和生产效率具有重要意义。 1. PCB分板机稳定性 PCB分板机的性能直接影响到切…

李沐62_序列到序列学习seq2seq——自学笔记

"英&#xff0d;法”数据集来训练这个机器翻译模型。 !pip install --upgrade d2l0.17.5 #d2l需要更新import collections import math import torch from torch import nn from d2l import torch as d2l循环神经网络编码器。 我们使用了嵌入层&#xff08;embedding l…

广东理工学院携手泰迪智能科技成功部署人工智能实验室

广东理工学院是经国家教育部批准设立的全日制普通本科院校&#xff0c;入选全国应用型人才培养工程培养基地、国家级众创空间试点单位、广东省高校电子商务人才孵化基地。开设34个本科专业&#xff0c;涵盖工学、经济学、管理学、文学、艺术学、教育学等6大学科门类&#xff0c…

【docker】拉取人大金仓KingbaseES数据库镜像速度很慢问题

作为一种新兴的虚拟化方式&#xff0c;Docker 跟传统的虚拟化方式相比具有众多的优势。 对于学习新技术、快速搭建实验环境等是很不错的选择。优势大致总结如下&#xff1a; 1.镜像拉取速度对比 速度前后对比&#xff0c;提升10倍不止&#xff0c;很快将镜像文件下载至本地。 …

Java常见面试题总结

文章目录 1. 什么是线程和进程?2. 请简要描述线程与进程的关系,区别及优缺点&#xff1f;3. 什么是堆和方法区&#xff1f;4. 并发与并行的区别5. 同步和异步的区别6.为什么要使用多线程? 优点&#xff1f;&#xff08;重要&#xff09;7. 使用多线程可能带来什么问题?8. 如…

python爬虫 - 爬取html中的script数据(zum.com新闻信息 )

文章目录 1. 分析页面内容数据格式2. 使用re.findall方法&#xff0c;编写爬虫代码3. 使用re.search 方法&#xff0c;编写爬虫代码 1. 分析页面内容数据格式 &#xff08;1&#xff09;打开 https://zum.com/ &#xff08;2&#xff09;按F12&#xff08;或 在网页上右键 --…

SpringCloud Alibaba--nacos简介和配置管理和登录

目录 一.理论基础 二.nacos 2.1 简介 2.2 安装 三.父项目 三.生产者 3.1 配置依赖 3.2 配置文件 3.3 启动类 3.4 控制类 四.消费者 4.1 配置依赖 4.2 配置文件 4.3 启动类 4.4 feign的接口 五.效果 六.负载均衡--权重算法 6.1重启nacos 6.2 设置权重 6.3 设…

SSH Key生成

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

「React Native」为什么要选择 React Native 作为的跨端方案

文章目录 前言一、常见因素二、举个栗子2.1 项目背景2.2 为什么选择 React Native2.3 项目实施2.4 成果总结 前言 没有完美的跨端技术&#xff0c;只有适合的场景。脱离适用场景去谈跨端技术没有什么意义。 一、常见因素 共享代码库&#xff1a; React Native 允许开发者编写…