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

客户端负载均衡Ribbon

文章目录

      • Ribbon
        • 1)、Ribbon模块
        • 2)、RestTemplate结合Ribbon使用
          • I、使用RestTemplate
          • II、整合Ribbon
        • 3)、负载均衡策略介绍
        • 4)、自定义负载策略
        • 5)、配置详情
          • I、常用配置
          • II、代码配置Ribbon
          • III、配置文件方式配置Ribbon
        • 6)、重试机制
          • I、RetryRule重试
          • II、Spring Retry重试

Ribbon

目前主流的负载均衡分为两种,一种是集中式负载均衡, 在消费者和服务提供方中间使用的代理方式进行负载,有硬件(比如F5),也有软件的(比如Nginx)。另一种则是客户端自己做负载均衡,根据自己的请求情况做负载,Ribbon就属于客户端自己做负载。 如果用一句话介绍,那就是Ribbon是Netflix开源的一款用于客户端负载均衡的工具软件。

GitHub地址:https://github.com/Netflix/ribbon

什么是负载均衡?

负载均衡,是一种计算机技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最优化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。或者这么说:负载均衡就是将负载(工作任务,访问请求)进行平衡、分摊到多个操作单元(服务器,组件)上进行执行。是解决高性能,单点故障(高可用),扩展性(水平伸缩)的终极解决方案。

ribbon能干嘛?
LB,即负载均衡(Load Balance),在微服务或分布式集群中经常用的一种应用。

负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用)。

常见的负载均衡软件有Nginx,Lvs等等

dubbo、SpringCloud中均给我们提供了负载均衡,SpringCloud的负载均衡算法可以自定义

负载均衡简单分类:
集中式LB:

即在服务的消费方和提供方之间使用独立的LB设施,如Nginx:反向代理服务器!由该设施负责把访问请求通过某种策略转发至服务的提供方!

进程式LB:

将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选出一个合适的服务器。
Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址!

1)、Ribbon模块

Ribbon模块如下:

ribbon-loadbalancer负载均衡模块,可独立使用,也可以和别的模块一起使用。Ribbon内置的负载均衡算法都实现在其中。

ribbon-eureka:基于Eureka封装的模块,能够快速、方便地集成Eureka。

ribbon-transport:基于Netty实现多协议的支持,比如HTTP、Tcp、Udp等。

ribbon-httpclient:基于Apache HttpClient封装的REST客户端,集成了负载均衡模块,可以直接在项目中使用来调用接口。

ribbon-example:Ribbon使用代码示例。

ribbon-core:一些比较核心且具有通用性的代码,客户端API的一些配置和其他API的定义。

Ribbon使用
接下来我们使用Ribbon来实现一个最简单的负载均衡调用功能,接口就用在Eureka注册中心文章中的服务提供者的接口/user/hello,需要启动两个服务,一个是8081的端口,一个是8083的端口。然后我们创建一个新的Maven项目ribbon-native-demo,在项目中集成Ribbon,在pom.xml中添加依赖:

<dependency><groupId>com.netflix.ribbon</groupId><artifactId>ribbon</artifactId><version>2.2.2</version></dependency><dependency><groupId>com.netflix.ribbon</groupId><artifactId>ribbon-core</artifactId><version>2.2.2</version></dependency><dependency><groupId>com.netflix.ribbon</groupId><artifactId>ribbon-loadbalancer</artifactId><version>2.2.2</version></dependency><dependency><groupId>io.reactivex</groupId><artifactId>rxjava</artifactId><version>1.0.10</version>
</dependency>

然后编写一个普通的接口:

public class Main {public static void main(String[] args) {//服务列表List<Server> serverList = Arrays.asList(new Server("localhost", 8081),new Server("localhost", 8083));//构建负载实例ILoadBalancer loadBalancer = LoadBalancerBuilder.newBuilder().buildFixedServerListLoadBalancer(serverList);//调用5次来测试效果for (int i = 0; i < 5; i++) {String result = LoadBalancerCommand.<String>builder().withLoadBalancer(loadBalancer).build().submit(new ServerOperation<String>() {@Overridepublic Observable<String> call(Server server) {try {String addr = "http://" + server.getHost() + ":" +server.getPort() + "/user/hello";System.out.println("调用地址:" + addr);URL url = new URL(addr);HttpURLConnection conn = (HttpURLConnection)url.openConnection();conn.setRequestMethod("GET");conn.connect();InputStream in = conn.getInputStream();byte[] data = new byte[in.available()];in.read(data);return Observable.just(new String(data));} catch (Exception e) {return Observable.error(e);}}}).toBlocking().first();System.out.println("调用结果:" + result);}}
}

这个例子主要演示了Ribbon如何去做负载操作,调用接口用的最底层的HttpURLConnection。启动服务提供者的接口/user/hello的服务,分别使用不同端口,怕有小伙伴不会同一服务启动两次,来!上教程:
首先要勾起这个:
在这里插入图片描述
然后启动一次服务,挂着,再然后去application.properties里更换端口:
在这里插入图片描述
在点击启动,这样便可以同时启动8081和8083服务,启动服务提供者的这两个服务前,记得要先启动服务中心:
在这里插入图片描述
运行一下这个程序可以在控制台看到:
在这里插入图片描述
从输出的结果中可以看到,负载起作用了。

2)、RestTemplate结合Ribbon使用

刚才我们便简单的使用了Ribbon进行了负载的一个调用,这意味着Ribbon是可以单独使用的。
那我们应该如何使用RestTemplate与整合Ribbon呢?

I、使用RestTemplate

首先我们得先会使用RestTemplate,在Eureka的学习中就使用过RestTemplate,项目便讲解具体的使用方法:
配置好依赖pom.xml:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
</dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Finchley.SR2</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>

首先来看看GET请求的使用方式:创建一个新项目spring-rest-template,配置好RestTemplate:
config/BeanConfiguration.java:

@Configuration
public class BeanConfiguration {@Beanpublic RestTemplate getRestTemplate() {return new RestTemplate();}
}

实体类:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class HouseInfo {private Long id;private String city;private String region;private String name;
}

新建一个HouseController,并增加两个接口,一个通过@RequestParam来传递参数,返回一个对象信息;另一个通过@PathVariable来传递参数,返回一个字符串。
消费接口定义:

@RestController
public class HouseController {@GetMapping("/house/data")public HouseInfo getData(@RequestParam("name") String name) {return new HouseInfo(1L, "广东", "广州", "增城区");}@GetMapping("/house/data/{name}")public String getData2(@PathVariable("name") String name) {return name;}
}

新建一个HouseClientController用于测试,使用RestTemplate来调用我们刚刚定义的两个接口:
调用接口:

public class HouseClientController {@Autowiredprivate RestTemplate restTemplate;@GetMapping("/call/data")public HouseInfo getData(@RequestParam("name") String name) {return restTemplate.getForObject("http://localhost:8081/house/data?name=" +name, HouseInfo.class);}@GetMapping("/call/data/{name}")public String getData2(@PathVariable("name") String name) {return restTemplate.getForObject("http://localhost:8081/house/data/{name}",String.class, name);}
}

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

获取数据结果可通过RestTemplate的getForObject方法来实现,此方法有三个重载的实现:

url: 请求的API地址,有两种方式,其中一种是字符串,另一种是URL形式。
responseType: 返回值的类型。
uriVariables: PathVariable参数,有两种方式,其中一种是可变参数,另外一种是Map形式。

可以看看getForObject方法的源码:
在这里插入图片描述
除了getForObject,我们还可以使用getEntity来获取数据;
getForEntity使用:
HouseClientController.java:

@GetMapping("/call/dataEntity")
public HouseInfo getData1(@RequestParam("name") String name) {ResponseEntity<HouseInfo> responseEntity = restTemplate.getForEntity("http://localhost:8081/house/data?name=" + name, HouseInfo.class);if (responseEntity.getStatusCodeValue() == 200) {return responseEntity.getBody();}return null;
}

getForEntity中可以获取返回的状态码、请求头等信息,通过getBody获取响应的内容。其余的和getForObject一样,也是有3个重载的实现,可以看看源码:
在这里插入图片描述
那么接下来就看看怎么使用POST方法调用接口。在HouseController中增加一个save方法用来接收HouseInfo数据:
POST接口定义:
HouseController.java:

@PostMapping("/house/save")
public Long addData(@RequestBody HouseInfo houseInfo) {System.out.println(houseInfo.getName());return 1001L;
}

接着写调用代码,用postForObject来调用:
HouseClientController.java:

@GetMapping("/call/save")
public Long add() {HouseInfo houseInfo = new HouseInfo();houseInfo.setCity("广东");houseInfo.setRegion("广州");houseInfo.setName("XXX");Long id = restTemplate.postForObject("http://localhost:8081/house/save", houseInfo, Long.class);return id;
}

postForObject同样有3个重载的实现。除了postForObject还可以使用postForEntity方法,用法都一样,来看源码:
在这里插入图片描述
除了get和post对应的方法之外,RestTemplate还提供put、delete等操作,还有一个比较实用就是exchange方法。exchange可以执行get、post、put、delete这4种请求方式。

II、整合Ribbon

在Spring Cloud项目中集成Ribbon只需要在pom.xml中加入下面的依赖即可,其实也可以不用配置,因为Eureka中已经引用了Ribbon。
Ribbon Maven配置:

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

RestTemplate负载均衡示例:
前面我们调用接口都是通过具体的接口地址来进行调用,RestTemplate可以结合Eureka来动态发现服务并进行负载均衡的调用。
修改RestTemplate的配置,增加能够让RestTemplate具备负载均衡能力的注解@LoadBalanced。

RestTemplate负载配置:

@Configuration
public class BeanConfiguration {@Bean@LoadBalancedpublic RestTemplate getRestTemplate() {return new RestTemplate();}
}

修改接口调用的代码,将IP+PORT改成服务名称,也就是注册到Eureka中的名称。
服务名称方式调用:

@GetMapping("/call/data")
public HouseInfo getData(@RequestParam("name") String name) {return restTemplate.getForObject("http://ribbon-eureka-demo/house/data?name=" + name, HouseInfo.class);
}

接口调用的时候,框架内部会将服务名称替换成具体的服务IP信息,然后进行调用。

相信在配置类中大家都看见了 @LoadBalanced,那这个注解的原理是什么呢?

相信大家一定有一个疑问:为什么在RestTemplate上加了一个@LoadBalanced之后,RestTemplate就能够跟Eureka结合了,不但可以使用服务名称去调用接口,还可以负载均衡?
应该归功于Spring Cloud给我们做了大量的底层工作,因为它将这些都封装好了,我们用起来才会那么简单。框架就是为了简化代码,提高效率而产生的。
这里主要的逻辑就是给RestTemplate 增加拦截器,在请求之前对请求的地址进行替换,或者根据具体的负载策略选择服务地址,然后再去调用,这就是@LoadBalanced的原理。

接下来我们便看看 @LoadBalanced的工作原理源码是一个怎样的一个逻辑:
首先看配置类,如何为RestTemplate设置拦截器,代码在spring-cloud-commons.jar中的org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration类里面通过查看LoadBalancerAutoConfiguration的源码,可以看到这里也是维护一个@LoadBalanced的RestTemplate列表:
LoadBalanced拦截注入源码(一)
在这里插入图片描述
通过查看拦截器的配置可以知道,拦截器用的是LoadBalancerInterceptor,RestTemplateCustomizer用来添加拦截器
LoadBalanced拦截注入源码:
在这里插入图片描述
拦截器的代码在org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor中
LoadBalanced拦截注入源码:
在这里插入图片描述
主要的逻辑在intercept中,执行交给了LoadBalancerClient来处理,通过LoadBalancerRequestFactory来构建一个LoadBalancerRequest对象
LoadBalancerRequest拦截注入源码:
在这里插入图片描述
createRequest中通过ServiceRequestWrapper来执行替换URI的逻辑,ServiceRequestWrapper中将URI的获取交给了org.springframework.cloud.client.loadbalancer.LoadBalancerClient#reconstructURI方法。
以上就是整个RestTemplate结合@LoadBalanced的执行流程。

Ribbon API使用:
当我们有一些特殊需求,想通过Ribbon获取对应的服务信息时,可以使用Load-Balancer Client来获取,比如想获取一个ribbon-eureka-demo服务的服务地址,可以通过LoadBalancerClient的choose方法来选择一个:
Ribbon Client使用:

@Autowired
private LoadBalancerClient loadBalancerClient;@GetMapping("/choose")
public Object choose() {ServiceInstance instance = loadBalancerClient.choose("ribbon-eureka-demo");return instance;
}

访问接口,可以看到返回的信息。

Ribbon饥饿加载
在进行服务调用的时候,如果网络情况不好,第一次调用会超时?有很多大神对此提出了解决方案,比如把超时时间改长一点、禁止超时等。而Spring Cloud随着版本的更新,提供了最优的解决方案。Ribbon的客户端是在第一次请求的时候初始化的,如果超时时间比较短的话,初始化Client的时间再加上请求接口的时间,就会导致第一次请求超时。
而下面将介绍Finchley.SR2版本提供的一种针对上述问题的解决方法,那就是eager-load方式。通过配置eager-load来提前初始化客户端就解决这个问题。

ribbon.eager-load.enabled=true
ribbon.eager-load.clients=ribbon-eureka-demo

ribbon.eager-load.enabled:开启Ribbon的饥饿加载模式。
ribbon.eager-load.clients:指定需要饥饿加载的服务名,也就是你需要调用的服务,若有多个则用逗号隔开。

怎么进行验证呢?网络情况确实不太好的模拟,不过通过调试源码的方式即可验证,在org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration中找到对应的代码:
Ribbon饥饿加载配置源码:
在这里插入图片描述
在return这行设置一个断点,然后以调试的模式启动服务,如果能进入到这个断点的代码这里,就证明配置生效了。

3)、负载均衡策略介绍

Ribbon作为一款客户端负载均衡框架,默认的负载策略是轮询,同时也提供了很多其他的策略,能够让用户根据自身的业务需求进行选择。
整体策略代码实现类:
在这里插入图片描述
图中:

BestAvailableRule:选择一个最小的并发请求的Server,逐个考察Server,如果Server被标记为错误,则跳过,然后再选择ActiveRequestCount中最小的Server。

AvibliliteringRul:过滤掉那些一直连接失败的且被标记为circuit tripped的后端Server,并过滤掉那些高并发的后端Server或者使用一个AvailabilityPredicate来包含过滤Server的逻辑。其实就是检查Status里记录的各个Server的运行状态。

ZoneAvoidanceRule:使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个Server,前一个判断判定个Zone 的运行性能是否可用, 剔除不可用的 Zone (的所有Server),AvailabilityPredicate 用于过滤掉连接数过多的Server。

RandomRule:随机选择一个Server。

RoundRobinRule::轮询选择,轮询index,选择index对应位置的Server。

RetryRule:对选定的负载均衡策略机上重试机制,也就是说当选定了某个策略进行请求负载时在一个配置时间段内若选择Server不成功,则一直尝试使用subRule的方式选择一个可用的Server。

ResponseTimeWeightedRule:作用同WeightedResponseTimeRule,ResponseTimeWeightedRule后来改名为WeightedResponseTimeRule。

WeightedResponseTimeRule:根据响应时间分配一个Weight (权重),响应时间越长,Weight越小,被选中的可能性越低。

4)、自定义负载策略

通过实现IRule接口可以自定义负载策略,主要的选择服务逻辑在choose方法中。
自定义负载策略:

public class MyRule implements IRule {private ILoadBalancer lb;@Overridepublic Server choose(Object key) {List<Server> servers = lb.getAllServers();for (Server server : servers) {System.out.println(server.getHostPort());}return servers.get(0);}@Overridepublic void setLoadBalancer(ILoadBalancer lb) {this.lb = lb;}@Overridepublic ILoadBalancer getLoadBalancer() {return lb;}
}

在Spring Cloud中,可通过配置的方式使用自定义的负载策略,ribbon-config-demo是调用的服务名称。

ribbon-config-demo.ribbon.NFLoadBalancerRuleClassName=com.springresttemplate.ribbon_eureka_demo.rule.MyRule

重启服务,访问调用了其他服务的接口,可以看到控制台的输出信息中已经有了我们自定义策略中输出的服务信息,并且每次都是调用第一次服务。这跟我们的逻辑是相匹配的。

5)、配置详情

I、常用配置

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中提供了很多的策略,这个在后面会进行讲解。我们通过配置可以指定服务使用哪种策略来进行负载操作。

#配置负载均衡策略
ribbon-config-demo.ribbon.NFLoadBalancerRuleClassName=com. netflix. loadbalancer.RandomRule

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

II、代码配置Ribbon

配置Ribbon最简单的方式就是通过配置文件实现。当然我们也可以通过代码的方式来配置。
通过代码方式来配置之前自定义的负载策略,首先需要创建一个配置类,初始化自定义的策略:
自定义负载策略配置:

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

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

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

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

III、配置文件方式配置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(服务列表的过滤)

6)、重试机制

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

由于Eureka是基于AP原则构建的,牺牲了数据的一致性,每个Eureka服务都会保存注册的服务信息,当注册的客户端与Eureka的心跳无法保持时,有可能是网络原因,也有可能是服务挂掉了。在这种情况下,Eureka中还会在一段时间内保存注册信息。这个时候客户端就有可能拿到已经挂掉了的服务信息,故Ribbon就有可能拿到已经失效了的服务信息,这样就会导致发生失败的请求。

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

I、RetryRule重试

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

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

II、Spring Retry重试

除了使用Ribbon自带的重试策略,我们还可以通过集成Spring Retry来进行重试操作。在pom.xml中添加Spring Retry的依赖:
Spring Retry Maven配置:

<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

至此关于Ribbon的学习就到这里,相信大家看完后明白Ribbon是一款非常优秀的客户端负载均衡组件,在Spring Cloud中集成Ribbon可以让我们的服务调用具备负载均衡的能力。

在Spring Cloud中结合RestTemplate使用Ribbon。用RestTemplate调用接口还是比较麻烦的,所以下一篇文章将学习如何通过Feign去优雅地调用服务中的接口(~ ̄▽ ̄)~

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

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

Mysql异常之Communications link failure

前天线上出现数据数据抖动&#xff0c;收到大量异常告警&#xff0c;都要疯了&#xff0c;数据库出现大量异常&#xff0c;肯定第一件事就是看下数据库监控数据&#xff0c;发现有一个从分片执行时间有一个50多秒的操作&#xff0c;这里肯定有问题了&#xff0c;第一时间找了db…...

储备未完待续

储备 如何精准熬一人份的粥 如何快速晾凉一碗粥 3M手套和钢铁侠 洗手盆三件套 三种门锁、两个门锁 制作书签的一种方法 摩托车和汽车的排气筒 变形金刚和巴巴爸爸 横向冲击和纵向冲击 我和图书馆 影响我的三本书 曲黎敏、亨利我们会追上你的、穷理查历书...

git知识点查阅

若自己在自己的电脑上修改了某一代码&#xff0c;而此时远程分支上对应的代码别人也做了修改&#xff0c;现在需要把远程分支的代码和自己本地的代码合并到本地电脑&#xff0c;操作&#xff1a; git stash git pull git stash pop...

如何成为一个成功的 Java 开发人员?

【此文章转自乐字节】 如果你是一名成功的Java程序员&#xff0c;那么在任何公司中的Java开发人员中&#xff0c;你都有机会获取一席之地。 前言 在当今时代&#xff0c;有很多编程语言可能会塑造我们的未来。然而&#xff0c;当我们开始学习编程时&#xff0c;我们总是从C语…...

代理和负载均衡的详细说明是什么

对客户端提供的代理服务&#xff0c;在客户端无法直接访问服务端的情况下&#xff0c;星池StarPool通过配置代理服务器的方式访问服务端。在整个过程中&#xff0c;客户端请求首先发送到代理服务器&#xff0c;代理服务器再将请求发送到服务端后将结果返回给客户端。从服务端角…...

使用DNSObserver检测DNS安全漏洞

关于DNSObserver DNSObserver是个功能强大的DNS服务&#xff0c;该工具使用Go语言开发&#xff0c;可以帮助广大研究人员轻松检测各种类型的盲注漏洞。它可以监控渗透测试人员所搭建服务器的带外DNS交互信息&#xff0c;并通过Slack发送查询通知。DNSObserver可以帮助我们寻找的…...

Zookeeper源码查看: 七. 客户端启动源码

客户端启动源码 查看启动脚本 查看 zkCli.sh, 在 zkCli.sh 启动 Zookeeper 时, 会调用 ZooKeeperMain.java 创建 ZookeeperAdmin 查看启动类 ZookeeperMain 查看 ZookeeperMain 构造方法 查看 connectToZK() 方法 初始化监听器 查看 ZookeeperAdmin 类 解析连接地址…...

整理了 34 个 Python 自动化办公库

本次内容涵盖了Excel、Word、PPT、ODF、PDF、邮件、微信、文件处理等所有能在办公场景实现自动化的库,希望能够对大家有所帮助。 Python Excel自动化库 // 1.xlwings 库 官网: https://www.xlwings.org/ 特点:xlwings 是开源且免费的,预装了 Anaconda 和 WinPython,可…...

【Jenkins插件】之Multiple SCMs

在Jenkins配置中&#xff0c;有的时候我们需要依次拉取多个代码仓库&#xff0c;有时候还会需要既拉取svn代码库&#xff0c;又拉取git代码库&#xff0c;但Jenkins默认的配置是不支持这样操作的。因此&#xff0c;我们需要使用到Jenkins的Multiple SCMs插件。 Multiple SCMs这…...

为什么自己干了这么多活,最后功劳都是别人的?

【本文只针对IT行业技术岗】 一、粉丝留言 自己每天加班到10点&#xff0c;有时候都到凌晨&#xff0c;周6基本全勤&#xff0c;公司项目忙的时候周日还去加班&#xff0c; 做过的项目无数&#xff0c;很多项目都给公司带来了丰厚的利润。 年底年终奖比别人少了一个月&…...

pytest(10)-参数化详解

先看如下情况&#xff0c;即为了测试一个函数&#xff0c;列举了三个测试用例&#xff0c;每个用例其实就是参数不同而已 在test_example.py 文件中编写如下代码&#xff1a; def add(a,b):return (ab)def test_1():assert add(3,5)8def test_2():assert add(2,4)7def test_3(…...

防(反)浏览器指纹技术之指纹浏览器揭秘

什么是指纹浏览器? 首先&#xff0c;这个指纹并不是上班打卡的指纹&#xff0c;也不是你家指纹锁的指纹&#xff01; 这里指的浏览器指纹是指通过浏览器的各种信息&#xff0c;如系统字体、屏幕分辨率、浏览器语言、时区等等&#xff0c;无需 cookie 等技术&#xff0c;就能…...

2021全球暑期量子学习日程汇总,谷歌量子夏季研讨会正在报名中

今日小暑&#xff0c;虽酷热&#xff0c;但学习热忱不减&#xff0c;尤其是在各个科技巨头和高等院校接连发布了量子暑期班的招募通告后&#xff0c;大家可以妥善安排&#xff0c;“错峰出行”。 近日&#xff0c;谷歌也发布了暑期会议相关通告&#xff0c;其量子夏季研讨会 (…...

STM32使用STM32CubeMX配置引脚中断

前言 嵌入式系统中&#xff0c;外部中断&#xff0c;是一个比较常见的功能。中断的灵活使用&#xff0c;大大增强了系统的实时性。使用STM32 最新的HAL库&#xff0c;如何配置一个引脚中断呢&#xff1f; 配置中断 可以借助STM32提供的可视化软件&#xff1a;STM32CubeMX&#…...

命令提示符

CMD 打开CMD方式 开始&#xff0c;Windows 系统&#xff0c;命令提示符&#xff08;以管理员身份运行&#xff09;WIndowsR&#xff0c;cmd文件夹下&#xff0c;Shift鼠标右键&#xff0c;在此处打开Powershell窗口资源管理器地址栏&#xff0c;cmd 常用DOS命令 切换盘符&a…...

最新出炉,头条三面技术四面HR,看我如何一步一步攻克面试官?

最开始面的头条游戏中台&#xff0c;当时是第一次面试&#xff0c;没有经验&#xff0c;导致算法题虽然有思路&#xff0c;但是没有写出最优解&#xff0c;直接挂了。后来又被捞起来&#xff0c;因为此时已有阿里的offer&#xff0c;所以胆子也大起来了&#xff0c;收拾心情开始…...

Linux基本命令

文章目录第一章Linux基础一、基本命令1.ls命令2.cd命令3.文件操作二、用户解读1.用户权限三、linux的基本操作1.软件介绍2.用户操作3.组3.1权限控制4.文件权限控制4.1权限设置5.vim的使用——一开始是命令模式6.寄存器7.find命令格式8.管道符—— |xargs9.grep命令第一章Linux基…...

python数据类型的性能分析

python数据类型的性能分析 本文主要对Python两种内置数据类型list 和 dict上各种操作的大O数量级进行分析 list与dict的比较 list类型各种操作&#xff08;interface&#xff09;的实现方 法有很多&#xff0c;如何选择具体哪种实现方法&#xff1f; 总的方案就是&#xff0…...

docker+k8s 报错

dockerk8s报错 问题点&#xff1a;docker容器中或者k8s的pod中执行systemctl相关后台服务 报错信息&#xff1a;Failed to get D-Bus connection: Operation not permitted解决办法 docker&#xff1a;运行容器添加参数–privilegedtrue /sbin/init docker run -tid --name…...

Redis集群的搭建和Redis的使用

Redis集群的搭建和Redis的使用 一.Redis的简介和用途 简介 Redis是一个高性能的key-value数据库。 Redis 与其他 key - value 缓存产品有以下三个特点&#xff1a; Redis支持数据的持久化&#xff0c;可以将内存中的数据保存在磁盘中&#xff0c;重启的时候可以再次加载进行…...

用Python搭建股票舆情分析系统

写在前面 下面的这篇文章将手把手教大家搭建一个简单的股票舆情分析系统&#xff0c;其中将先通过金融界网站爬取指定股票在一段时间的新闻&#xff0c;然后通过百度情感分析接口&#xff0c;用于评估指定股票的正面和反面新闻的占比&#xff0c;以此确定该股票是处于利好还是…...

python学习之路(第八天)---re模块正则表达式

python学习之路&#xff08;第八天&#xff09;—re模块正则表达式 python学习之路&#xff08;第八天&#xff09;---re模块正则表达式在线正则匹配正则匹配语法re.compile方法re.match方法re.search方法re.finditer方法转义匹配findall()正则表达式的实例正则表达式&#xff…...

win10开启局域网远程桌面连接

要求&#xff1a;两台电脑&#xff0c;同时连接在同一局域网。假设是电脑A开启允许局域网远程桌面&#xff0c;然后电脑B连接。这两台电脑需要按照下面的步骤来做。 一、电脑A 1.点击此电脑图标&#xff0c;右键&#xff0c;属性。 2.点击远程设置 3.开启允许被远程连接 4.打开…...

740_CTEX安装

全部学习汇总&#xff1a; https://github.com/GreyZhang/g_Tex 最终还是走上了这条路&#xff0c;没有抵制住这个神秘的诱惑。其实&#xff0c;TEX对我来说似乎并不是一个必须要接触的东西&#xff0c;接触的最大原因也是因为高德纳创造了他&#xff0c;我想看看这一套工具背后…...

Python Day9函数

一函数使用步骤 &#xff08;1&#xff09;定义函数 &#xff08;2&#xff09;调用函数 如&#xff1a; 若不调用函数&#xff0c;函数内部的代码不会执行 二函数的参数的作用 三函数的返回值的作用 在函数中&#xff0c;如果需要返回结果给用户需要使用函数返…...

《零基础安装 Oracle 数据库》RAC集群系列 ❸ 简单两步快速安装 Oracle 18C RAC 数据库

前言 很多朋友吐槽我的脚本不会用&#xff0c;看不懂&#xff0c;哎&#xff0c;一言难尽&#xff01;于是&#xff0c;我将 [vagrant virtualbox shell脚本] 组合起来&#xff0c;实现了零基础也可安装 Oracle 数据库的方式&#xff0c;我称之为 新手纯享版本&#xff0c;真…...

java16语言新特性

新语言特性 JEP 394&#xff0c;适用于 instanceof 的模式匹配模式匹配&#xff08;Pattern Matching&#xff09;最早在 Java 14 中作为预览特性引入&#xff0c;在 Java 15 中还是预览特性。模式匹配通过对 instacneof 运算符进行模式匹配来增强 Java 编程语言。模式匹配使程…...

入门图形学:屏幕波爆特效

最近bilibili看了黑神话悟空的UE5演示视频&#xff0c;感觉是真牛逼&#xff0c;地址&#xff1a;黑神花悟空UE5实机演示视频 遥想我也算是国内第一批用ue4的开发者了&#xff0c;15年开始用ue4.7源码版&#xff0c;做了一年多就又用回u3d了&#xff0c;哈哈&#xff0c;主要因…...

清新简约教育培训汇报总结PPT-朴尔PPT

清新简约教育培训汇报总结PPT模板。一套,总结报告,工作汇报,幻灯片模板&#xff0c;内含黄色,红色多种配色&#xff0c;简约,小清新,卡通风风格设计&#xff0c;动态播放效果&#xff0c;精美实用。 希望下面这份精美的PPT模板能帮助到你 基本信息 用途&#xff1a;,总结报告…...

【详细教程】-Python绘图模块Matplotlib

文章目录1 简介2 绘图标记2.1 fmt参数2.2 标记大小与颜色3 绘图线3.1 线的类型3.2 线的颜色3.3 线的宽度3.4 多条线4 轴标签和标题4.1 标题4.2 图形中文显示4.3 标题与标签的定位5 网格线6 绘制多个图6.1 subplot6.2 subplots7 散点图8 柱形图9 饼图1 简介 下面的代码通过两个…...

dbc2000 注册机|dbc2000 注册码注册机下载

点击下载来源&#xff1a;dbc2000 注册机 dbc2000 注册机是同名源程序软件的注册机软件&#xff0c;该源程序软件是一款应用于数据库搭建以及数据写入的数据库架设工具&#xff0c;它拥有强大的数据写入功能&#xff0c;在作为应用程序使用时&#xff0c;它不仅可以充当数据属性…...

秋招面经第八弹:网易二面-数据开发工程师

秋招第八弹&#xff1a;网易二面-数据开发工程师 写在最前&#xff1a;秋招以来一直在冲&#xff0c;因为事情比较多&#xff0c;对于笔试面试一直没有复盘&#xff0c;现在靠仅存的记忆把面试的一些问题记录下来&#xff0c;尽可能记录出能回忆到的问题&#xff0c;但可能记的…...

安卓课程格子APP

https://download.csdn.net/download/weixin_57836618/73810452 功能演示&#xff1a; 查看所有课程 点击主页面空白处即可添加课程 添加课程之后查看课程 查看双周课程 查看单周课程 6.查看课程详情...

强化学习——格子世界

强化学习——格子世界 项目源码地址&#xff1a;https://gitee.com/infiniteStars/machine-learning-experiment 1. 实验内容 2. 实验代码 import numpy as np import matplotlib.pyplot as plt from matplotlib.table import Table from xml.dom.minidom import Document #手…...

华为机试 - 跳格子游戏

目录 题目描述 输入描述 输出描述 用例 题目解析 算法源码 题目描述 地上共有N个格子&#xff0c;你需要跳完地上所有的格子&#xff0c;但是格子间是有强依赖关系的&#xff0c;跳完前一个格子后&#xff0c;后续的格子才会被开启&#xff0c;格子间的依赖关系由多组st…...

php 爬课程表信息,Ruby爬取教务系统生成课程表

我为什么要虐自己最近觉得课程格子广告越来越多&#xff0c;乱七八糟的东西越来越多&#xff0c;完全失去了一开始的存在价值&#xff0c;并且没有电脑端app&#xff0c;想查看课程必须拿出手机&#xff0c;而我使用电脑频率要比手机高&#xff0c;所以才有了折腾的动力。于是我…...

android 课程表 ui,UICollectionViewLayout实现课程表布局

因为项目中有课程表的相关模块&#xff0c;第一时间想到用UICollectionView。然而后期的需求越来越复杂&#xff0c;每个格子需要展示的内容越来越多&#xff0c;所以不得不寻找合适的解决方案。最后发现自定义UICollectionViewLayout可以实现我的需求。先放效果图&#xff1a;…...

Android自定义View课程表,Android 自定义View课程表表格

自己闲下来时间写的一个课表控件使用的自定义LinearLayout 里面View都是用代码实现的 最终效果如下图 写的可能有问题希望多多指点创建一个自定义LinearLayout 控件用来装载课程的信息和课程的周数 和节数大概的布局三这样的根据上面的看来觉得总体布局我分了两个 上面的星期是…...

java课程设计设计_java课程设计

1. 团队课程设计博客链接https://www.cnblogs.com/choco1ate/p/12172223.html2.本组课题及本人任务本组课题&#xff1a;泡泡堂(炸弹人)游戏本人任务&#xff1a;Box类(游戏地图中的每个方格)Bomb类(游戏过程中的)游戏玩家输赢信息的文件储存3.需求分析Box类&#xff1a;该类为…...

《课程格子》的一个笔试题目

题目如下&#xff0c;感觉很适合喜欢琢磨的程序员&#xff0c;也是考验你编码风格的时候。 Lets make a tower defense game&#xff08;塔防游戏):1. You have 1 tower, with H health and D dps(damage per second).2. There are n attackers, each with h_i health and d_i …...

Android仿照超级课程表 or 课程格子 一键提取课表功能(方正系统)

参考文章http://blog.csdn.net/sbsujjbcy ,本文仿照‘ 安卓弟 提供的android 项目实战——打造超级课程表一键提取课表功能文章&#xff0c;对他的代码进行了修改和补充&#xff0c;为什么要修改呢&#xff1f;原因是安卓弟的那个源码版本过于老旧&#xff0c;很多方法已经过…...

查看linux网速的命令,Ubuntu中查看网速的命令

在这里我们要使用Linux系统中的查看网速的命令&#xff0c;指的是查看网卡此时是工作在哪种速度的模式下。因为通常现在的网卡都支持10M/100M/1000M的网速&#xff0c;但是具体的网卡速度工作模式&#xff0c;要根据计算机所处的网络环境而定。在Windows下&#xff0c;查看方式…...

linux下网速测试

linux下网速测试 speedtest 是一个知名的网速测试工具&#xff0c;它是用 Python 写成的&#xff0c;可以使用 apt 或 pip 命令来安装。 安装 sudo apt install speedtest-cli 或者 pip3 install speedtest-cli 使用 使用的时候&#xff0c;可以直接运行 speedtest 命令即可…...

网速测试网站链接

1、测速网 - 专业网速测试, 宽带提速, 游戏测速, 直播测速, 5G测速, 物联网监测 - SpeedTest.cn 2、中国科学技术大学测速网站 (ustc.edu.cn) 3、测试链接&#xff1a;ed2k://|file|cn_office_professional_plus_2016_x86_x64_dvd_6969182.iso|2588266496|27EEA4FE4BB13CD0EC…...

linux服务器 网速测试

speedtest apt install speedtest-clispeedtest-cli --simple --secure --bytes参考 网络测速神器&#xff1a;SpeedTest深度指南Linux下3种常用的网络测速工具github speedtest-cli...

网络带宽 (网速) 在线测试

网络带宽 (网速) 在线测试 https://www.speedtest.net/ https://www.speedtest.cn/ 1. 测速 2. 获取到下载和上传带宽 3. bits (比特) Kilobit per second (Kbit/s, Kb/s or Kbps) 千比特每秒 Megabit per second (Mbit/s, Mb/s or Mbps) 兆比特每秒 Gigabit per second (G…...

在线光纤网速测试软件,光纤网速测试,宽带测试

大家在家使用电脑的时候&#xff0c;通常都会测试自己家网速的稳定性&#xff0c;看看自己的网速是否能够达到应用商所提供的服务&#xff0c;那么网速的稳定性如何去检测呢?接下来小编就网速稳定性的检测方法做一个简单的介绍&#xff0c;供大家在实际生活的时候参考使用。一…...

linux网速测试

linux网速测试 2019年03月04日 系统版本&#xff1a;CentOS Linux release 7.5.1804 参考文档 https://jingyan.baidu.com/article/f006222814b0eefbd2f0c873.html linux命令行界面用 speedtest 测网速&#xff0c;linux版本是基于python&#xff0c;网站是 speedtest.net 因为…...

java 网速测试_简易的网速测试 - 梦想游戏 - OSCHINA - 中文开源技术交流社区

基本原理是访问稳定的网页来测试速度&#xff0c;或者利用稳定的下载地址来测速&#xff0c;比如QQ.EXE网页粒度小 测试没有 下载地址 稳定准确界面MFC完成&#xff0c;网络API使用CURLHttpClient.cpp#include "stdafx.h"#include"HttpClient.h"#include &…...

什么软件测试出来的网速准确,百度应用的网速测试工具最不准确

现在的网速测试工具越来越多&#xff0c;有的是在网站上直接进行&#xff0c;有的是需要安装软件或插件后进行&#xff0c;但是工具多了&#xff0c;数据就各式各样&#xff0c;千差百错&#xff0c;我们到底相信哪个为准呢&#xff1f;为此&#xff0c;小编今天专门研究了一番…...