邯郸建设网站wordpress ip地址只能访问首页
邯郸建设网站,wordpress ip地址只能访问首页,合肥建设工程质量监督局网站,备案期间网站能打开吗微服务化的负载均衡组件源码剖析与实战开发全流程 什么是负载均衡负载均衡的种类服务器端负载均衡#xff08;S-LB#xff09;客户端负载均衡#xff08;C-LB#xff09;注解LoadBalancedLoadBalancerAutoConfiguration类LoadBalancerClient类源码分析 ServiceInstanceChoo… 微服务化的负载均衡组件源码剖析与实战开发全流程 什么是负载均衡负载均衡的种类服务器端负载均衡S-LB客户端负载均衡C-LB注解LoadBalancedLoadBalancerAutoConfiguration类LoadBalancerClient类源码分析 ServiceInstanceChooser类 内置负载均衡策略的介绍IRuleIRule的源码IRule接口定义了3个方法主要方法是 IRule的实现类八种常见的负载均衡策略负载均衡的自定义通过代码实现 - 配置类 同时使用2种以上的不同策略算法移除Configuration 注解操作处理方式通过配置配置文件实现不同的算法 如何对负载均衡策略进行扩展继承 AbstractLoadBalancerRule 类通过配置文件 总结分析 什么是负载均衡
负载均衡是通过将请求流量分发到多个服务器来实现资源分配的一种策略。它可以确保各个服务器在处理请求方面的负载均衡并能够更高效地利用系统资源。负载均衡的主要目标是避免服务器过载并通过在不同的服务器之间分发负载提高系统的可伸缩性和可用性。
负载均衡的种类
通过负载均衡我们可以在服务器集群中有效地分配请求从而实现更快的响应时间和更好的用户体验。目前负载均衡的方式分类主要有两种服务器端负载均衡nginx和客户端负载均衡Ribbon
服务器端负载均衡S-LB
服务器端负载均衡如Nginx是一种将请求流量分发到多个服务器的方法以提高系统的性能和可靠性。通过将请求分发到不同的服务器负载均衡可以避免单个服务器的过载并能够更均衡地分配请求负载从而提高整体的响应能力。
客户端负载均衡C-LB
客户端负载均衡如Ribbon是在客户端层面上进行的负载均衡。当客户端发起请求时通过负载均衡算法Ribbon可以选择最合适的服务器来处理请求。这种方式使得客户端可以根据实际情况选择最佳的服务器提高了系统的可扩展性和容错性。
注解LoadBalanced 作用识别应用名称并进行负载均衡。 在Spring Cloud应用中使用RestTemplate进行服务间的通讯时我们可以添加LoadBalanced注解来开启负载均衡。
在一个微服务架构中通常一个服务会有多个实例并且这些实例部署在不同的服务器上。为了保证服务的高可用性我们需要在这些实例之间进行负载均衡。Spring Cloud提供了LoadBalanced注解它可以在RestTemplate中实现负载均衡
Configuration
public class RestTemplateConfiguration {LoadBalanced // 使用 LoadBalanced 注解实现负载均衡Beanpublic RestTemplate restTemplate() {return new RestTemplate();}}在RestTemplate添加了LoadBalanced注解之后我们就可以直接使用服务名来调用其他服务而不再需要关心具体的IP和端口号。
Autowired
private RestTemplate restTemplate;public String runTaskExecute() {return restTemplate.getForObject(http://serviceName/execute, String.class);
}当发起请求时Ribbon会自动从服务注册中心获取serviceName的所有实例然后根据负载均衡策略选择一个实例进行调用这样就实现了负载均衡。默认负载均衡策略是基于轮询算法平均分配请求给每个服务实例。
LoadBalancerAutoConfiguration类
Ribbon的负载均衡自动配置需满足两个条件
RestTemplate类必须在当前项目的环境中可用ConditionalOnClass(RestTemplate.class)Spring的Bean工厂中必须存在LoadBalancerClient的实现类的Bean实例。ConditionalOnBean(LoadBalancerClient.class)
下面是LoadBalancerAutoConfiguration的源码
/*** Auto configuration for Ribbon (client side load balancing).* author Spencer Gibb* author Dave Syer* author Will Tran*/
Configuration
ConditionalOnClass(RestTemplate.class)
ConditionalOnBean(LoadBalancerClient.class)
EnableConfigurationProperties(LoadBalancerRetryProperties.class)
public class LoadBalancerAutoConfiguration {LoadBalancedAutowired(required false)private ListRestTemplate restTemplates Collections.emptyList();Beanpublic SmartInitializingSingleton loadBalancedRestTemplateInitializer(final ListRestTemplateCustomizer customizers) {return new SmartInitializingSingleton() {Overridepublic void afterSingletonsInstantiated() {for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) {for (RestTemplateCustomizer customizer : customizers) {customizer.customize(restTemplate);}}}};}
}LoadBalancerClient类
LoadBalancerClient的接口的定义该接口在Spring Cloud中被用来实现客户端的负载均衡。它是一个Spring Cloud特有的接口扩展自ServiceInstanceChooser接口。这个接口定义了如何从服务注册中心获取服务实例并对其进行负载均衡。
import java.io.IOException;
import java.net.URI;/*** Represents a client side load balancer.* * author Spencer Gibb*/
public interface LoadBalancerClient extends ServiceInstanceChooser {/*** Execute request using a serviceInstance from the LoadBalancer for the specified service.** param serviceId the service id to look up the LoadBalancer* param request allows implementations to execute pre and post actions such as incrementing metrics* return the result of the LoadBalancerRequest callback on the selected ServiceInstance */T T execute(String serviceId, LoadBalancerRequestT request) throws IOException;/*** Execute request using a ServiceInstance from the LoadBalancer for the specified service.** param serviceId the service id to look up the LoadBalancer* param serviceInstance the service to execute the request to* param request allows implementations to execute pre and post actions such as incrementing metrics* return the result of the LoadBalancerRequest callback on the selected serviceInstance */T T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequestT request) throws IOException;/*** Create a proper URI with a real host and port for systems to utilize.* Some systems use a URI with the logical service name as the host, such as http://myservice/path/to/service.* This will replace the service name with the host:port from the serviceInstance.** param instance* param original a URI with the host as a logical service name* return a reconstructed URI*/URI reconstructURI(ServiceInstance instance, URI original);
}
源码分析
这些方法主要在客户端向服务端发起请求时使用以实现负载均衡的效果 execute(String serviceId, LoadBalancerRequestT request) throws IOException负载均衡器选择的服务实例执行请求。serviceId是要查找负载均衡器的服务的idrequest参数让实现类在服务调用前后执行一些操作如度量增量等。 execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequestT request) throws IOException增加了serviceInstance参数该参数表示要执行请求的服务是在已经选择了服务实例后执行请求。 reconstructURI(ServiceInstance instance, URI original)一些系统使用的是逻辑服务名作为主机的URI如http://myservice/path/to/service这种URI中的主机名不是真实的网络地址而是服务名。 在基于服务名进行路由的微服务系统为了获取实际的网络地址host:port就需要这个转换方法把逻辑服务名替换为从服务实例获取的真实主机名和端口。 ServiceInstanceChooser类
接口ServiceInstanceChooser该接口在Ribbon中被用作负载均衡策略的接口应用可以实现这个接口来自定义自己的负载均衡策略。在这个接口中定义了一个choose方法该方法用于从负载均衡器中为特定服务选择一个服务实例。
/*** Implemented by classes which use a load balancer to choose a server to* send a request to.** author Ryan Baxter*/
public interface ServiceInstanceChooser {/*** Choose a ServiceInstance from the LoadBalancer for the specified service.** param serviceId the service id to look up the LoadBalancer* return a ServiceInstance that matches the serviceId*/ServiceInstance choose(String serviceId);
}负载均衡器具备以下几个主要职能 能够根据特定的服务ID从负载均衡器中选取一个合适的服务实例。 能够利用选取的服务实例执行特定的任务或请求。 能够为系统生成一个有效的“主机名:端口号”格式的URI以便于系统的其他部分使用。 内置负载均衡策略的介绍
IRule
IRule是Ribbon客户端内置负载均衡策略的接口定义所有Ribbon内建策略或者自定义策略都需要实现这个接口。它主要的决定了服务选择的策略即根据什么样的规则从一组服务中选取一个有效的服务实例。
IRule的源码
package com.netflix.loadbalancer;/** The class that will be used by clients of Ribbon API to pick a server from* the already filtered list of servers. The responsibility of implementations* will be to spread the load of request traffic among the list of servers.*/
public interface IRule {/** set load balancer** param lb*/public void setLoadBalancer(ILoadBalancer lb);/** get load balancer** return*/public ILoadBalancer getLoadBalancer();/** Choose a server from load balancer.** param key An object that the load balancer may use to determine* which server to return. key is defined by client, and* can be anything. load balancer implementations may* choose to return a server based on key or not.** return server chosen*/public Server choose(Object key);
}IRule接口定义了3个方法
setLoadBalancer(ILoadBalancer lb): 用来设置负载均衡器。getLoadBalancer(): 用来获取负载均衡器。choose(Object key): 用来从已经过滤过的服务列表中选择合适的服务。key参数是由客户端定义的可以是任何对象。实现此接口的类可以选择根据key选择服务也可以忽略key。
主要方法是
public abstract Server choose(Object key);出参 Server这是Ribbon定义的一个类代表了一个可以达到的、执行某个服务的物理或者虚拟的实例。入参 choose(Object key)此方法根据传入的keykey的具体含义根据实现类的解读可能有所不同选择并返回一个Server。
IRule的实现类
当你实现IRule接口时你可以自己定义服务选择的规则比如你可以根据服务的实际情况如服务器负载、网络延迟等信息来选择最符合你需求的服务创建出定制化的负载均衡策略。
八种常见的负载均衡策略 八种常见的负载均衡策略BestAvailableRule、AvailabilityFilteringRule等都是IRule的实现类每种策略都有自己独特的服务选择规则。
策略名称描述BestAvailableRule该策略选择并发请求最少的server。若某个Server处于熔断状态将忽略该Server。AvailabilityFilteringRule过滤掉连续连接失败被标记为熔断的Server以及并发连接高的Server。ZoneAvoidanceRule复合判断Server所在区域的性能和Server的可用性来选择Server剔除不可用的区域的所有Server和连接数过多的Server。RandomRule随机策略会在所有可用的Server中进行随机选择。RetryRule为选定的负载均衡策略添加重试机制。在配置的时间段内若无法成功选择Server将会持续重试。RoundRobinRule轮询策略每次请求会轮询选择一个Server。此为默认策略。WeightedResponseTimeRule根据响应时间分配权重响应时间较长的Server权重越小被选中的可能性越低。ResponseTimeWeightedRule与WeightedResponseTimeRule一致是其旧版本名称。
负载均衡的自定义
通过代码实现 - 配置类
仅需两个简洁的配置即可确定轮询的策略。
Configuration
public class RandomRuleConfig {Beanpublic IRule randomRule() {return new RandomRule();}
}Configuration
RibbonClient(name client-balance-provider, configuration RandomRuleConfig.class)
public class ProviderConfiguration {
}注意如果在RandomRuleConfig类中添加了Configuration注解所有的负载均衡策略将被覆盖。这是因为如果RandomRuleConfig类被SpringContext扫描到这会导致所有的策略被RibbonClients共享从而实现覆盖。 同时使用2种以上的不同策略算法
移除Configuration 注解
以下是整理和优化后的代码
// Define the round robin rule configuration.
public class RoundRobinRuleConfig {Beanpublic IRule roundRobinRule() {return new RoundRobinRule();}
}RoundRobinRuleConfig类定义了roundRobinRule方法该方法生成了RoundRobinRule的实例表示采用轮询负载均衡策略。
// The configuration class for the Ribbon client.
Configuration
RibbonClient(name spring-cloud-provider2, configuration RoundRobinRuleConfig.class)
public class Provider2Configuration {}Provider2Configuration类则是spring-cloud-provider2服务的Ribbon配置类该类指定在调用spring-cloud-provider2服务时使用RoundRobinRuleConfig类中定义的轮询策略。
操作处理方式
需要新增RoundRobinRuleConfig类并移除其中的Configuration注解。同时也要移除RandomRuleConfig类中的Configuration注解。 可以通过指定ComponentScan的扫描路径实现默认情况下扫描路径为主类所在的所有文件夹。 将RoundRobinRuleConfig类移至主类之外防止主程序进行扫描一定要确保SpringContext无法扫描到这些类。
通过配置配置文件实现不同的算法
通过配置文件可以让应用来灵活的选择不同的负载均衡策略。设置格式为application-name.ribbon.NFLoadBalancerRuleClassNamefully-qualified-class-name。
这样就可以根据应用的实际需要选择最适合的负载均衡策略。
#设置策略
spring-cloud-provider.ribbon.NFLoadBalancerRuleClassNamecom.netflix.loadbalancer.RandomRule
#spring-cloud-provider2.ribbon.NFLoadBalancerRuleClassNamecom.netflix.loadbalancer.RandomRule如何对负载均衡策略进行扩展
当内置的负载均衡策略不满足业务需求的时候我们就需要自定义 Ribbon 的负载策略。
继承 AbstractLoadBalancerRule 类
扩展了AbstractLoadBalancerRule抽象类用于定义自定义的负载均衡规则。这个规则是从所有可用的服务实例(upList)中选择端口为7779的服务实例为提供服务的实例。如果没有找到或者选中的实例已经不可用则重新选择。如果因为线程中断导致获取服务实例错误直接返回null。
/*** Custom Ribbon load balancing strategy.*/
public class RoncooCustomRule extends AbstractLoadBalancerRule {private Server choose(ILoadBalancer lb, Object key) {if (lb null) {return null;}Server server null;while (server null) {if (Thread.interrupted()) {return null;}// Available service instancesListServer upList lb.getReachableServers();// Only fetch service instance with port: 7779for (Server s : upList) {if (s.getPort() 7779) {server s;break;}}if (server null) {Thread.yield();continue;}if (server.isAlive()) {return server;}server null;Thread.yield();}return server;}Overridepublic Server choose(Object key) {return choose(getLoadBalancer(), key);}Overridepublic void initWithNiwsConfig(IClientConfig clientConfig) {// No-Operation}
}通过配置文件
spring-cloud-provider.ribbon.NFLoadBalancerRuleClassNamecom.roncoo.education.configuration.RoncooCustomRule总结分析
Ribbon是Netflix开发的一款基于HTTP和TCP的客户端负载均衡器。它在Spring Cloud环境中广泛使用于执行HTTP请求的负载均衡其主要知识点和技术特性包括 客户端负载均衡Ribbon是一个客户端的负载均衡器这意味着它会在客户端运行并在发起请求时对一组服务实例进行选择。 灵活的负载均衡策略Ribbon内置了多种负载均衡策略如轮询、随机、响应时间加权等。用户也可以自定义策略以满足特殊要求。 故障转移在访问某个服务实例失败时Ribbon可以自动选择另一个实例进行访问以提高系统的可用性。 扩展性良好Ribbon的结构让它可以方便地扩展和定制以支持各种各样的需求。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/88328.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!