微服务之负载均衡器

1、负载均衡介绍

负载均衡就是将负载(工作任务,访问请求)进行分摊到多个操作单元(服务器,组件)上 进行执行。

根据负载均衡发生位置的不同, 一般分为服务端负载均衡和客户端负载均衡。

服务端负载均衡指的是发生在服务提供者一方,例如Nginx,通过Nginx进行负载均衡,先发送请求,然后通过负载均衡算法,在多个服务 器之间选择一个进行访问;即在服务器端再进行负载均衡算法分配。

客户端负载均衡指的是发生在服务请求的一方,也就是在发送请求之前已经选好了由哪个实例处理请 求。例如spring cloud中的ribbon,客户端会有一个服务器地址列表,在发送请求前通过负载 均衡算法选择一个服务器,然后进行访问,这是客户端负载均衡;即在客户端就进行负载均 衡算法分配。

常见的负载均衡算法

自定义公共接口

package com.example.consumer.loadbalance;import org.springframework.cloud.client.ServiceInstance;import java.util.List;/*** @author* @ClassName LoadBalance* @addres www.boyatop.com*/
public interface LoadBalance {/*** 负载均衡算法 给我多个地址 负载均衡 取出一个地址返回使用*/ServiceInstance getInstances(String serviceId);
}

1)轮询算法

轮询算法实现思路:

例如在集合中 多个接口地址

[192.168.110.1:8080,192.168.110.2:8081]

0              1

第一次访问:1%2=1

第二次访问:2%2=0

第三次访问:3%2=1

第四次访问:4%2=0

[192.168.110.1:8080,192.168.110.2:8081,192.168.110.2:8082]

  0                 1               3

第一次访问:1%3=1

第二次访问:2%3=2

第三次访问:3%3=0

第四次访问:4%3=1

第五次访问:5%3=2第六次访问:6%3=0

package com.example.consumer.loadbalance;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;/*** 轮询算法** @author* @ClassName RoundLoadBalance* @addres www.boyatop.com*/
@Component
public class RoundLoadBalance implements LoadBalance {@Autowiredprivate DiscoveryClient discoveryClient;//记录第几次访问private AtomicInteger atomicCount = new AtomicInteger(0);@Overridepublic ServiceInstance getInstances(String serviceId) {//1.根据服务的名称 获取 该服务集群地址列表List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);//2.判断是否nullif (instances == null || instances.size() == 0) {return null;}//3.使用负载均衡算法int index = atomicCount.incrementAndGet() % instances.size();// 0+1return instances.get(index);}
}

2)随机算法

package com.example.consumer.loadbalance;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Random;/*** 随机算法** @author* @ClassName RandomLoadBalance* @addres www.boyatop.com*/
@Component
public class RandomLoadBalance implements LoadBalance {@Autowiredprivate DiscoveryClient discoveryClient;@Overridepublic ServiceInstance getInstances(String serviceId) {//1.根据服务的名称 获取 该服务集群地址列表List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);//2.判断是否nullif (instances == null || instances.size() == 0) {return null;}// 生成随机 范围Random random = new Random();//3  0 1 2int index = random.nextInt(instances.size());return instances.get(index);}
}

3)故障转移算法

 @RequestMapping("/orderToMember3")public String orderToMember3() {/***模拟其中的服务器宕机*/
//    ServiceInstance serviceInstance = randomLoadBalance.getInstances("producer");List<ServiceInstance> instances = discoveryClient.getInstances("producer");//ServiceInstance serviceInstance = instances.get(0);for (int i = 0; i <instances.size(); i++) {ServiceInstance serviceInstance = instances.get(i);// 会员服务的ip和端口String memberUrl = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/" + "getMember";//调用的过程当中可能会出现服务宕机的情况  此刻应该实现故障转移机制try {//将获取请求服务的结果换成获取服务访问成功的对象  目的:验证服务是否宕机ResponseEntity<String> response = restTemplate.getForEntity(memberUrl, String.class);if (response == null) {continue;}return "订单服务调用会员服务:" + response.getBody();}catch (Exception e){log.error("<e:{}>", e);}}return "fail";}

4)权重算法

[192.168.110.1:8080,192.168.110.1:8081]

Index=0=192.168.110.1:8080

Index=1=192.168.110.1:8081

权重算法如何 比例:

1:1

第一次访问 192.168.110.1:8080

第二次访问 192.168.110.1:8081

轮询机制 默认权重1:1

2:1

[192.168.110.1:8080,192.168.110.1:8081]

权重比例 2:1

Index=0 192.168.110.1:8080 权重=2

Index=1 192.168.110.1:8081 权重=1

2(index=0):1(index=1)

第一次访问 192.168.110.1:8080

第二次访问 192.168.110.1:8080

第三次访问 192.168.110.1:8081

第四次访问 192.168.110.1:8080

第五次访问 192.168.110.1:8080

第六次访问 192.168.110.1:8081

Index=0 192.168.110.1:8080 权重=2

Index=1 192.168.110.1:8081 权重=1

2(index=0):1(index=1)

权重的底层实现逻辑

【192.168.110.1:8080,192.168.110.1:8080

192.168.110.1:8081】

第一次访问1%3=1  ===192.168.110.1:8080

第二次访问2%3=2  ===192.168.110.1:8081

第三次访问3%3=0  ===192.168.110.1:8080

第四次访问4%3=1  ===192.168.110.1:8080

第五次访问5%3=2  ===192.168.110.1:8081

第六次访问6%3=0  ===192.168.110.1:8080

第七次访问7%3=1  ===192.168.110.1:8080

第八次访问8%3=1  ===192.168.110.1:8081

package com.example.consumer.loadbalance;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;/*** @author* @ClassName WeightLoadBalance* @addres www.boyatop.com*/
@Component
public class WeightLoadBalance implements LoadBalance {@Autowiredprivate DiscoveryClient discoveryClient;private AtomicInteger countAtomicInteger = new AtomicInteger(0);@Overridepublic ServiceInstance getInstances(String serviceId) {// 1.根据服务的id名称 获取该接口多个实例List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);if (instances == null) {return null;}/*** 192.168.75.1:8080 权重比例 2* 192.168.75.1:8081  权重比例 1* [192.168.75.1:8080,192.168.75.1:8080,192.168.75.1:8081]*/ArrayList<ServiceInstance> newInstances = new ArrayList<>();// 循环遍历该服务名称 对应的多个实例instances.forEach((service) -> {// 获取该服务实例对应的权重比例Double weight = Double.parseDouble(service.getMetadata().get("nacos.weight"));for (int i = 0; i < weight; i++) {newInstances.add(service);}});// 线程安全性 i++return newInstances.get(countAtomicInteger.incrementAndGet() % newInstances.size());}
}
@Autowired
private WeightLoadBalance weightLoadBalance;
@RequestMapping("/orderToMember4")
public String orderToMember4() {/***使用权重的方式*///1.根据服务的名称 获取 该服务集群地址列表//List<ServiceInstance> instances = discoveryClient.getInstances("producer");// 如何服务实例的获取权重比例呢?ServiceInstance serviceInstance = weightLoadBalance.getInstances("producer");// 会员服务的ip和端口String memberUrl = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/" + "getMember";return "订单服务调用会员服务:" + restTemplate.getForObject(memberUrl, String.class);
}

2、Ribbon(第一代)

1)Ribbon负载均衡介绍及实现

Spring Cloud Ribbon是基于Netflix Ribbon 实现的一套客户端的负载均衡工具,Ribbon 客户端组件提供一系列的完善的配置,如超时,重试等。通过Load Balancer获取到服务提 供的所有机器实例,Ribbon会自动基于某种规则(轮询,随机)去调用这些服务。Ribbon也可以实现我们自己的负载均衡算法

RestTemplate 添加@LoadBalanced注解

让RestTemplate在请求时拥有客户端负载均衡的能力

@Configuration
public class RestConfig {@Bean@LoadBalanced //开启负载均衡public RestTemplate restTemplate() {return new RestTemplate();}
}

调用实现

//springcloud中Ribbon负载均衡的使用@Autowiredprivate LoadBalancerClient loadBalancerClient;@RequestMapping("/orderToMember6")public String orderToMember6() {ServiceInstance serviceInstance = loadBalancerClient.choose("producer");//默认采用轮询机制String memberUrl = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/" + "getMember";return "订单服务调用会员服务:" + restTemplate.getForObject(memberUrl, String.class);
//        return "订单服务调用会员服务:" + restTemplate.getForObject("http://producer/getMember", String.class);}

2)Ribbon底层实现原理

SpringCloudRibbon的底层采用了一个拦截器,拦截了RestTemplate发出的请求

基本流程如下:

拦截我们的RestTemplate请求http://userservice/user/1

RibbonLoadBalancerClient会从请求url中获取服务名称,也就是user-service

DynamicServerListLoadBalancer根据user-service到eureka拉取服务列表

eureka返回列表,localhost:8081、localhost:8082

IRule利用内置负载均衡规则,从列表中选择一个,例如localhost:8081

RibbonLoadBalancerClient修改请求地址,用localhost:8081替代userservice,得到http://localhost:8081/user/1,发起真实请求

3)Ribbon负载均衡策略

Ribbon内置了七种负载均衡规则,每种规则都有其特定的应用场景和策略。以下是这些规则的详细介绍:

RoundRobinRule(轮询策略)

    • 策略描述:这是Ribbon的默认负载均衡策略。通过简单的轮询服务列表来选择服务器。在没有可用服务的情况下,RoundRobinRule最多会轮询10轮,若最终没有找到可访问的服务,则返回NULL。
    • 特点:每个服务器依次被调用,确保每个服务器都能得到相等的负载。
    • 实现说明:轮询index,选择index对应位置的server

AvailabilityFilteringRule(可用性筛选策略)

    • 策略描述:先过滤掉非健康的服务实例,比如连接失败的服务,以及并发数过高的服务,然后再从剩余的服务中选择连接数较小的服务实例。
    • 特点:忽略无法连接的服务器,以及并发数过高的服务器,确保选择的服务都是可用的且负载较低的。
    • 参数配置:
      • 可以通过niws.loadbalancer..connectionFailureCountThreshold属性配置连接失败的次数。
      • 可以通过.ribbon.ActiveConnectionsLimit属性设定最高并发数。
    • 实现说明:使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的 运行状态

WeightedResponseTimeRule(权重策略)

    • 策略描述:为每个服务器赋予一个权重值,服务器的响应时间越长,该权重值就越少。这个规则会随机选择服务器,但权重值会影响服务器的选择。
    • 特点:响应快的服务器权重更高,被选中的概率也更大。
    • 实现说明:一个后台线程定期的从status里面 读取评价响应时间,为每个server 计算一weight。Weight的计算也 比较简单responsetime减去每个server自己平均的responsetime是  server的权重。当刚开始运行,没  有形成statas时,使用roubine策略 选择server

ZoneAvoidanceRule(区域回避策略)

    • 策略描述:根据服务所在区域(zone)的性能和服务的可用性来选择服务实例。如果在一个区域内有多台服务实例,并且区域内服务可用,那么只会在区域内进行选择;如果区域内服务不可用,才会选择其他区域的服务。
    • 特点:优先选择同区域的服务实例,以提高访问速度和可用性。
    • 实现说明:使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选 择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server), Availability Predicate用于过滤掉连 接数过多的Server。

BestAvailableRule(最佳可用策略)

    • 策略描述:忽略那些处于“短路”状态的服务器,并选择并发数较低的服务器。
    • 特点:确保选择的服务都是可用的,并且并发数较低,以提供最佳的服务性能。
    • 实现说明:逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server

RandomRule(随机策略)

    • 策略描述:随机选择一个可用的服务器。
    • 特点:随机性较强,适用于对服务器性能要求不高的场景。
    • 实现说明:在index上随机,选择index对应位 置的server

RetryRule(重试策略)

    • 策略描述:在一个配置的时间段内,如果选择的服务器不可用,则一直尝试选择一个可用的服务器。
    • 特点:具有重试机制,确保在服务器不可用时能够继续提供服务。
    • 实现说明:在一个配置时间段内当选择server 不成功,则一直尝试使用subRule 的方式选择一个可用的server

4)自定义负载均衡策略

通过定义IRule实现可以修改负载均衡规则,有两种方式:

① 代码方式:在order-service中的OrderApplication类中,定义一个新的IRule:

@Bean
public IRule randomRule(){return new RandomRule();
}

② 配置文件方式:在order-service的application.yml文件中,添加新的配置也可以修改规则:

userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则 

5)饥饿加载

Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。

而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:

ribbon:eager-load:enabled: trueclients: userservice

3、Loadbalancer(第二代)

Spring Cloud LoadBalancer是由SpringCloud官方提供的一个开源的、简单易用的客户端负载均衡器,它包含在SpringCloud-commons中用它来替换了以前的Ribbon组件。相比较于Ribbon,SpringCloud LoadBalancer不仅能够支持RestTemplate,还支持WebClient(WeClient是Spring Web Flux中提供的功能,可以实现响应式异步请求)

导入依赖

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

Loadbalancer提供的的负载均衡策略

  • RandomLoadBalancer - 随机策略
  • RoundRobinLoadBalancer - 轮询策略(默认)

算法切换

@Configuration // 标记为配置类
@LoadBalancerClient(value = "producer", configuration = RestTemplateConfig.class) // 使用负载均衡器客户端注解,指定服务名称和配置类
public class RestTemplateConfig {@Bean // 定义一个Bean@LoadBalanced // 使用@LoadBalanced注解赋予RestTemplate负载均衡的能力public RestTemplate restTemplate() {return new RestTemplate(); // 返回一个新的RestTemplate实例}@Bean // 定义一个BeanReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, // 注入环境变量LoadBalancerClientFactory loadBalancerClientFactory) { // 注入负载均衡器客户端工厂String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); // 获取负载均衡器的名称// 创建并返回一个随机负载均衡器实例return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);}
}

4、Ribbon和Loadbalancer的比较

Ribbon

1. 定义和用途

  • Ribbon是一个客户端负载均衡器,它是一个Java库,可以在客户端应用程序中使用。
  • 通过在客户端应用程序中维护服务实例列表,并使用负载均衡算法来选择要请求的服务实例,从而实现负载均衡。

2. 特点和优势

  • 适用于客户端负载均衡,将负载均衡逻辑集成到消费方进程中。
  • 消费者通过Ribbon来获取到服务提供方的地址。
  • Ribbon提供了多种负载均衡算法,如轮询、随机、加权轮询等。
  • 它还可以进行故障检查,检测服务器的健康状态,并自动从故障服务器中移除。

3. 与微服务的关系

  • 在微服务架构中,Ribbon常被用于Spring Cloud等Java微服务框架中,以提供客户端负载均衡和高可用支持。

LoadBalancer

1. 定义和用途

  • LoadBalancer是一个服务器端负载均衡器,它是一个独立的服务,可以在服务器集群中运行。
  • 通过接收客户端请求,并使用负载均衡算法来选择要处理请求的服务器实例,从而实现负载均衡。

2. 特点和优势

  • 适用于服务器端负载均衡,如常见的负载均衡工具有nginx、LVS,硬件上F5等集中式负载均衡设施。
  • 能够处理大量的并发请求,并根据服务器的负载情况动态分配请求。
  • 可以实现故障处理、实例健康检查、SSL转换、跨区域负载均衡等高级功能。

3. 与微服务的关系

  • 在微服务架构中,LoadBalancer通常被部署在服务提供者之前,作为客户端和服务提供者之间的代理。
  • 它可以根据配置的策略将请求分发到不同的服务实例上,从而确保服务的高可用性和可扩展性。

总结

  • Ribbon和LoadBalancer在微服务架构中都扮演着重要的角色,但它们的应用场景和实现方式有所不同。
  • Ribbon更侧重于客户端负载均衡,通过在客户端应用程序中集成负载均衡逻辑来实现;而LoadBalancer则更侧重于服务器端负载均衡,作为一个独立的服务来处理客户端请求。

5、loadbalancer本地负载均衡客户端 VS Nginx服务端负载均衡区别

Nginx是服务器负载均衡,客户端所有请求都会交给nginx,然后由nginx实现转发请求,即负载均衡是由服务端实现的。

loadbalancer本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术。

应用场景的:

Nginx属于服务器负载均衡,应用于Tomcat/Jetty服务器等,而我们的本地负载均衡器,应用于在微服务架构中rpc框架中:openfeign、dubbo等。

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

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

相关文章

Visual Studio 使用第三方库管理工具 vcpkg

一、介绍 Windows下开发C/C程序&#xff0c;少不了用开源的第三方库。比如线性代数和矩阵分析的库eigen&#xff0c;或者图像处理的OpenCV库。虽然这些库都是开源的&#xff0c;但是由于要编译debug和release版本的&#xff0c;32位以及64位的&#xff0c;如果像FFmpeg…

基于springboot实现校园组团平台系统项目【项目源码】计算机毕业设计

基于springboot实现校园组团平台系统的设计演示 SSM框架介绍 本课题程序开发使用到的框架技术&#xff0c;英文名称缩写是SSM&#xff0c;在JavaWeb开发中使用的流行框架有SSH、SSM、SpringMVC等&#xff0c;作为一个课题程序采用SSH框架也可以&#xff0c;SSM框架也可以&…

FullCalendar日历组件集成实战(14)

背景 有一些应用系统或应用功能&#xff0c;如日程管理、任务管理需要使用到日历组件。虽然Element Plus也提供了日历组件&#xff0c;但功能比较简单&#xff0c;用来做数据展现勉强可用。但如果需要进行复杂的数据展示&#xff0c;以及互动操作如通过点击添加事件&#xff0…

每日一题——Python实现PAT乙级1028 人口普查 Keyboard(举一反三+思想解读+逐步优化)六千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 题目链接​编辑我的写法 专业点评 时间复杂度分析 空间复杂度分析 总结 我要更强…

Python基础教程(十八):MySQL - mysql-connector 驱动

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

碳化硅陶瓷膜良好的性能

碳化硅陶瓷膜是一种高性能的陶瓷材料&#xff0c;以其独特的物理和化学特性&#xff0c;在众多领域展现出了广泛的应用前景。以下是对碳化硅陶瓷膜的详细介绍&#xff1a; 一、基本特性 高强度与高温稳定性&#xff1a;碳化硅陶瓷膜是一种非晶态陶瓷材料&#xff0c;具有极高的…

从GAN到WGAN(02/2)

文章目录 一、说明二、GAN中的问题2.1 难以实现纳什均衡(Nash equilibrium)2.2 低维度支撑2.3 梯度消失2.4 模式坍缩2.5 缺乏适当的评估指标 三、改进的GAN训练四、瓦瑟斯坦&#xff08;Wasserstein&#xff09;WGAN4.1 什么是 Wasserstein 距离&#xff1f;4.2 为什么 Wassers…

53.Python-web框架-Django开始第一个应用的多语言

针对上一篇的功能&#xff0c;本次仅对页面做了多语言&#xff0c;大家可以看看效果。 51.Python-web框架-Django开始第一个应用的增删改查-CSDN博客 目录 部门列表 新增部门 编辑部门 部门列表 源码 <!DOCTYPE html> {% load static %} {% load i18n %} <html …

JAVA开发 使用Apache PDFBox库生成PDF文件,绘制表格

1. 表格位置定点 2.执行效果展示&#xff08;截取PDF文件图片&#xff09; 3.执行代码 当我们使用Apache PDFBox库在PDF文件中创建带有表格的内容&#xff0c;需要遵循几个步骤。PDFBox本身并没有直接的API来创建表格&#xff0c;但我们可以通过定位文本、绘制线条和单元格矩形…

shell编程基础(第16篇:命令是什么?有哪些注意事项)

前言 前面我们已经使用过各种各样的命令&#xff0c;那么命令到底是什么呢&#xff1f;我们又该怎么理解该术语&#xff1f; 什么是命令&#xff1f; 命令是command的中文翻译&#xff0c;能在命令行中执行的是命令。因为早期的计算机只有文字界面&#xff0c;命令是程序&#…

高速公路智能管理系统:构建安全畅通的数字大动脉

随着城市化进程的加速和交通需求的增长&#xff0c;高速公路系统作为城市交通的重要组成部分&#xff0c;正承担着越来越多的交通运输任务。为了提升高速公路的安全性、便捷性和智能化管理水平&#xff0c;高速公路智能管理系统应运而生。本文将深入探讨高速公路智能管理系统的…

Leetcode 剑指 Offer II 082.组合总和 II

题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer&#xff08;专项突击版&#xff09;系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 给定一个可能有重复数字的整数数组 candidates 和一个目标数 tar…

能耗监控与管理平台

在当今社会&#xff0c;随着工业化、城市化的快速发展&#xff0c;能源消耗问题日益凸显&#xff0c;节能减排已成为全社会共同关注的焦点。在这个背景下&#xff0c;一款高效、智能的能耗监控与管理平台显得尤为重要。 一、HiWoo Cloud平台的概念 HiWoo Cloud是一款集数据采…

六大维度全面焕新升级!麒麟信安服务器操作系统V3.6.1引领未来计算

昨日&#xff0c;openEuler 24.03 LTS 正式发布&#xff0c;麒麟信安作为openEuler社区重要贡献者和参与者&#xff0c;充分发挥自身在国产操作系统领域的技术优势&#xff0c;在打造安全可靠、极致体验的操作系统上与社区共同努力&#xff0c;同步推出服务器操作系统V3.6.1&am…

OpenGL3.3_C++_Windows(7)

演示 最终演示效果 ​​​​ 冯氏光照 光照原理&#xff1a;对于向量相乘默认为点乘&#xff0c;如果*lightColor(1.0f, 1.0f, 1.0f);白光&#xff0c;值不变物体的颜色显示原理&#xff1a;不被物体吸收的光反射&#xff0c;也就是由白光分解后的一部分&#xff0c;因此&…

Cask ‘oraclexxx‘ is unavailable: No Cask with this name exists.

brew search oracle-jdk或brew search --cask oracle-jdk 原因&#xff1a;Homebrew官方仓库不再维护多个旧版本的OracleJDK 不推荐使用Homebrew环境安装JDK //指定版本安装 brew install --cask temurin17 //设置 JAVA_HOME 环境变量 //找到安装的JDK 版本的路径 /usr/lib…

探索测试分享

1. “器” 项目中的实践——我们是怎么做的 本章将带你身历其境的感受到思想和方法是如何具体使用在项目里的 1.如何挖掘探索性测试的探索点&#xff0c;在任何阶段都可以利用探索测试策略找到可探索的点&#xff0c;发现产品中的bug&#xff0c;或明显或隐含。 “器”的应用…

利用74HC165实现8路并行输入口的扩展

代码&#xff1a; #include <mega16.h>// Declare your global variables here #define hc165_clk PORTB.0 #define hc165_lp PORTB.1 #define hc165_out PINB.2unsigned char read_hc165(void) {unsigned char data0,i,temp0x80;hc165_lp0;hc165_lp1; for(i0;i<7;i)…

汇编:内联汇编和混合编程

C/C内联汇编 C/C 内联汇编&#xff08;Inline Assembly&#xff09;是一种在C或C代码中嵌入汇编语言指令的方法&#xff0c;以便在不离开C/C环境的情况下利用汇编语言的优势进行性能优化或执行特定的硬件操作。以下是一些详细的说明和示例&#xff0c;展示如何在C和C代码中使用…

zookeeper介绍 和 编译踩坑

zookeeper 分布式协调服务 ZooKeeper原理及介绍 - 鹿泉 - 博客园 Zookeeper是在分布式环境中应用非常广泛&#xff0c;它的优秀功能很多&#xff0c;比如分布式环境中全局命名服务&#xff0c;服务注册中心&#xff0c;全局分布式锁等等。 本项目使用其分布式服务配置中心&am…