網(wǎng)絡(luò)推廣銷售怎么做seo文章生成器
LoadBalancer
- 概念
- 常見的負(fù)載均衡策略
- 使用隨機(jī)選擇的負(fù)載均衡策略
- 創(chuàng)建隨機(jī)選擇負(fù)載均衡器
- 配置
- Nacos 權(quán)重負(fù)載均衡器
- 創(chuàng)建 Nacos 負(fù)載均衡器
- 配置
- 自定義負(fù)載均衡器(根據(jù)IP哈希策略選擇)
- 創(chuàng)建自定義負(fù)載均衡器
- 封裝自定義負(fù)載均衡器
- 配置
- 緩存
概念
LoadBalancer(負(fù)載均衡器)是一種網(wǎng)絡(luò)設(shè)備或軟件機(jī)制, 用于分發(fā)傳入的網(wǎng)絡(luò)流量負(fù)載(請(qǐng)求)到多個(gè)后端目標(biāo)服務(wù)器上, 從而實(shí)現(xiàn)系統(tǒng)資源的均衡利用和提高系統(tǒng)的可用性和性能
負(fù)載均衡分為服務(wù)器端負(fù)載均衡和客戶端負(fù)載均衡
- 服務(wù)器端負(fù)載均衡是指放在服務(wù)器端的負(fù)載均衡器(反向代理), 如: Nginx, HAProxy, F5等
- 客戶端負(fù)載均衡器是指嵌套在客戶端的負(fù)載均衡器(正向代理), 如: Ribbon, Spring Cloud LoadBalancer等
服務(wù)器端負(fù)載均衡器所有請(qǐng)求都會(huì)發(fā)送到服務(wù)器端, 就會(huì)造成服務(wù)器端壓力大的情況
常見的負(fù)載均衡策略
- 輪詢(默認(rèn)): 按照順序?qū)⒄?qǐng)求發(fā)送到服務(wù)器
- 隨機(jī)選擇: 隨機(jī)選擇一個(gè)服務(wù)器處理請(qǐng)求
- 最少連接: 選擇連接數(shù)最少的一個(gè)服務(wù)器
- IP 哈希: 使用客戶端IP地址計(jì)算哈希值然后發(fā)送到與之對(duì)應(yīng)的服務(wù)器
- 加權(quán)輪詢: 按照權(quán)重值的比例發(fā)送請(qǐng)求
- 加權(quán)隨機(jī)選擇: 按照權(quán)重值隨機(jī)選擇后端服務(wù)器
- 最短響應(yīng)時(shí)間: 將請(qǐng)求發(fā)送到響應(yīng)時(shí)間最短的服務(wù)器
Spring Cloud LoadBalancer 默認(rèn)只支持輪詢和隨機(jī)選擇, 但是可以自定義負(fù)載均衡策略
使用隨機(jī)選擇的負(fù)載均衡策略
創(chuàng)建隨機(jī)選擇負(fù)載均衡器
public class MyRandomLoadBalancer {@Beanpublic ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);}
}
配置
注意: 配置局部負(fù)載均衡器有可能不起作用, 可以配置全局負(fù)載均衡器
Nacos 權(quán)重負(fù)載均衡器
Nacos 中支持兩種負(fù)載均衡器, 一種是權(quán)重負(fù)載均衡器, 另一種是第三方的CMDB(地域就近訪問)標(biāo)簽負(fù)載均衡器, 我們可以將Spring Cloud LoadBalancer 直接配置為 Nacos 的負(fù)載均衡器
創(chuàng)建 Nacos 負(fù)載均衡器
@LoadBalancerClients(defaultConfiguration = MyNacosLoadBalancer.class)
public class MyNacosLoadBalancer {@Resourceprivate NacosDiscoveryProperties nacosDiscoveryProperties;@Beanpublic ReactorLoadBalancer<ServiceInstance> nacosLoadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new NacosLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name, nacosDiscoveryProperties);}
}
配置
自定義負(fù)載均衡器(根據(jù)IP哈希策略選擇)
創(chuàng)建自定義負(fù)載均衡器
public class CustomLoadBalancer implements ReactorServiceInstanceLoadBalancer {private static final Log log = LogFactory.getLog(RandomLoadBalancer.class);private final String serviceId;private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;public CustomLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId) {this.serviceId = serviceId;this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;}public Mono<Response<ServiceInstance>> choose(Request request) {ServiceInstanceListSupplier supplier = (ServiceInstanceListSupplier)this.serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);return supplier.get(request).next().map((serviceInstances) -> {return this.processInstanceResponse(supplier, serviceInstances);});}private Response<ServiceInstance> processInstanceResponse(ServiceInstanceListSupplier supplier, List<ServiceInstance> serviceInstances) {Response<ServiceInstance> serviceInstanceResponse = this.getInstanceResponse(serviceInstances);if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {((SelectedInstanceCallback)supplier).selectedServiceInstance((ServiceInstance)serviceInstanceResponse.getServer());}return serviceInstanceResponse;}private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {if (instances.isEmpty()) {if (log.isWarnEnabled()) {log.warn("No servers available for service: " + this.serviceId);}return new EmptyResponse();} else {ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();String ipAddress = request.getRemoteAddr();System.out.println("ip地址:" + ipAddress);int hash = instances.hashCode();int index = hash % instances.size();ServiceInstance instance = (ServiceInstance) instances.get(index);return new DefaultResponse(instance);}}
}
由于自定義負(fù)載均衡器和內(nèi)置的負(fù)載均衡器只是在服務(wù)器選擇的時(shí)候有所不同, 所以我們可以直接復(fù)制 RandomLoadBalancer 然后 在 getInstanceResponse()方法中進(jìn)行改動(dòng)即可
封裝自定義負(fù)載均衡器
配置
緩存
Spring Cloud LoadBalancer 在獲取實(shí)例時(shí)有兩種選擇:
- 及時(shí)獲取: 每次都從注冊(cè)中心獲取到最新的實(shí)例, 效果好但是開銷大
- 緩存服務(wù)列表: 每次得到服務(wù)列表后, 緩存一段時(shí)間,
spring Cloud LoadBalancer 默認(rèn)緩存過期時(shí)間為 35s, 保存?zhèn)€數(shù)為 256個(gè)
我們也可以通過配置來改變這兩個(gè)值
spring:cloud:loadbalancer:cache:ttl: 10capacity: 1000
# enabled: false 關(guān)閉緩存
生產(chǎn)環(huán)境下不要關(guān)閉緩存否則會(huì)降低性能