吉林省軟環(huán)境建設(shè)辦公室網(wǎng)站百度快速排名點擊器
目錄
1.負載均衡介紹
1.1問題描述
1.2什么是負載均衡
1.3負載均衡的一些實現(xiàn)
服務(wù)端負載均衡
客戶端負載均衡
2.Spring Cloud LoadBalancer
2.1快速上手實現(xiàn)負載均衡
2.2負載均衡策略
自定義負載均衡策略
3.服務(wù)部署(Linux)
3.1服務(wù)構(gòu)建打包
3.2啟動服務(wù)
承接上文服務(wù)注冊/服務(wù)發(fā)現(xiàn)-Eureka
1.負載均衡介紹
1.1問題描述
觀察上個章節(jié)遠程調(diào)用的代碼
List<ServiceInstance> instances = discoveryClient.getInstances("product-service");//服務(wù)可能有多個, 獲取第?個EurekaServiceInstance instance = (EurekaServiceInstance) instances.get(0);
1.根據(jù)應(yīng)用名稱獲取了服務(wù)實例列表
2.從列表中選擇了一個服務(wù)實例
思考:如果一個服務(wù)對應(yīng)多個實例呢?流量是否可以合理的分配到多個實例
現(xiàn)象觀察:
我們再啟動2個product-service實例
選中要啟動的服務(wù),右鍵選擇Copy Configuration
在彈出的框中選擇 Configuration -> VM options
?添加VM options: -Dserver.port=9091
9091為服務(wù)啟動的端口號,根據(jù)自己的情況進行修改
11:46:05.684+08:00 INFO 23128 --- [nio-8080-exec-1]
com.bite.order.service.OrderService : LUCF:product-service:909011:46:06.435+08:00 INFO 23128 --- [nio-8080-exec-2]
com.bite.order.service.OrderService : LUCF:product-service:909011:46:07.081+08:00 INFO 23128 --- [nio-8080-exec-3]
com.bite.order.service.OrderService : LUCF:product-service:9090
先啟動Eureka后啟動所有實例
觀察Eureka,可以看到product-service下有三個實例
訪問:http://127.0.0.1:8080/order/1
訪問結(jié)果:
11:46:05.684+08:00 INFO 23128 --- [nio-8080-exec-1]
com.bite.order.service.OrderService : LUCF:product-service:909011:46:06.435+08:00 INFO 23128 --- [nio-8080-exec-2]
com.bite.order.service.OrderService : LUCF:product-service:909011:46:07.081+08:00 INFO 23128 --- [nio-8080-exec-3]
com.bite.order.service.OrderService : LUCF:product-service:9090
通過日志可以觀察到,請求多次訪問,都是同一臺機器。
這肯定不是我們想要的結(jié)果,啟動多個實例,是希望可以分擔其他機器的負荷,那么如何實現(xiàn)呢?
解決方案:
我們可以對上述代碼進行簡單修改:
import com.example.orderservice.mapper.OrderMapper;
import com.example.orderservice.model.OrderInfo;
import com.example.orderservice.model.ProductInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;@Slf4j
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;private static AtomicInteger atomicInteger = new AtomicInteger(1);public OrderInfo selectOrderById(Integer orderId){OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
// String url = "http://127.0.0.1:9090/product/"+orderInfo.getProductId();//從Eureka中獲取服務(wù)列表List<ServiceInstance> instances = discoveryClient.getInstances("product-service");String uri = instances.get(atomicInteger.getAndIncrement() % instances.size()).getUri().toString();String url = uri+"/product/"+orderInfo.getProductId();log.info("遠程調(diào)用url:{}", url);ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}
}
觀察日志:
12:02:13.245+08:00 INFO 1800 --- [nio-8080-exec-1]
com.bite.order.service.OrderService : LUCF:product-service:909112:02:15.723+08:00 INFO 1800 --- [nio-8080-exec-2]
com.bite.order.service.OrderService : LUCF:product-service:909012:02:16.534+08:00 INFO 1800 --- [nio-8080-exec-3]
com.bite.order.service.OrderService : LUCF:product-service:909212:02:16.864+08:00 INFO 1800 --- [nio-8080-exec-4]
com.bite.order.service.OrderService : LUCF:product-service:909112:02:17.078+08:00 INFO 1800 --- [nio-8080-exec-5]
com.bite.order.service.OrderService : LUCF:product-service:909012:02:17.260+08:00 INFO 1800 --- [nio-8080-exec-6]
com.bite.order.service.OrderService : LUCF:product-service:909212:02:17.431+08:00 INFO 1800 --- [nio-8080-exec-7]
com.bite.order.service.OrderService : LUCF:product-service:9091
通過日志可以看到,請求被均衡的分配在不同的實例上,這就是負載均衡
1.2什么是負載均衡
負載均衡(Load Balance,簡稱LB),是高并發(fā),高可用系統(tǒng)必不可少的關(guān)鍵組件.
當服務(wù)流量增大時,通常會采用增加機器的方式進行擴容,負載均衡就是用來在多個機器或者其他資源中,按照一定的規(guī)則合理分配負載.
?一個團隊最開始只有一個人,后來隨著工作量的增加,公司又招聘了幾個人.負載均衡就是:如何把工作量均衡的分配到這幾個人身上,以提高整個團隊的效率
1.3負載均衡的一些實現(xiàn)
上面的例子中,我們只是簡單的對實例進行了輪詢,但真實的業(yè)務(wù)場景會更加復(fù)雜.比如根據(jù)機器的配置進行負載分配,配置高的分配的流量高,配置低的分配流量低等. 類似企業(yè)員工:能力強的員工可以多承擔一些工作。
服務(wù)多機部署時,開發(fā)人員都需要考慮負載均衡的實現(xiàn),所以也出現(xiàn)了一些負載均衡器,來幫助我們實現(xiàn)負載均衡.
負載均衡分為服務(wù)端負載均衡和客戶端負載均衡.
服務(wù)端負載均衡
在服務(wù)端進行負載均衡的算法分配
比較有名的服務(wù)端負載均衡器是Nginx.
請求先到達Nginx負載均衡器,然后通過負載均衡算法,在多個服務(wù)器之間選擇一個進行訪問.
客戶端負載均衡
在客戶端進行負載均衡的算法分配.
把負載均衡的功能以庫的方式集成到客戶端,而不再是由一臺指定的負載均衡設(shè)備集中提供.
?

2.Spring Cloud LoadBalancer
2.1快速上手實現(xiàn)負載均衡
1.給RestTemplate這個Bean添加@LoadBalanced注解
@Configuration
public class BeanConfig {@LoadBalanced@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}
}
2.修改IP端口號為服務(wù)名稱
public OrderInfo selectOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectOrderById(orderId);//String url = "http://127.0.0.1:9090/product/"+ orderInfo.getProductId();String url = "http://product-service/product/" + orderInfo.getProductId();ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}
?3.啟動多個product-service實例

2.2負載均衡策略
?負載均衡策略是一種思想,無論是哪種負載均衡器,它們的負載均衡策略都是相似的.
Spring Cloud LoadBalancer僅支持兩種負載均衡策略:輪詢策略和隨機策略
- 輪詢(Round Robin):輪詢策略是指服務(wù)器輪流處理用戶的請求.這是一種實現(xiàn)最簡單,也最常用的 策略.生活中也有類似的場景,比如學(xué)校輪流值日,或者輪流打掃衛(wèi)生.
- 隨機選擇(Random):隨機選擇策略是指隨機選擇一個后端服務(wù)器來處理新的請求.
?
自定義負載均衡策略
Spring Cloud LoadBalancer默認負載均衡策略是輪詢策略,實現(xiàn)是RoundRobinLoadBalancer,如果服務(wù)的消費者如果想采用隨機的負載均衡策略,也非常簡單.
參考官網(wǎng):Spring Cloud LoadBalancer :: Spring Cloud Commons
此處使?Spring Cloud LoadBalancer提供的 RandomLoadBalancer
public class CustomLoadBalancerConfiguration {@BeanReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);}}
注意:該類需要滿足
- 不用@Configuration注釋
- 在組件掃描范圍內(nèi)
?
@LoadBalancerClient(name = "product-service",configuration = CustomLoadBalancerConfiguration.class)
@Configuration
public class BeanConfig {@LoadBalanced@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}
}
@LoadBalancerClient注解說明:
- name:該負載均衡策略對哪個服務(wù)生效(服務(wù)提供方)
- configuration:該負載均衡策略用哪個負載均衡策略實現(xiàn).
?
3.服務(wù)部署(Linux)
3.1服務(wù)構(gòu)建打包
?采用Maven打包,需要對3個服務(wù)分別打包:
?eureka-server,order-service,product-service
?1.打包方式和SpringBoot項目一致,依次對三個項目打包即可.
3.2啟動服務(wù)
#后臺啟動eureka-server, 并設(shè)置輸出?志到logs/eureka.lognohup java -jar eureka-server.jar >logs/eureka.log &#后臺啟動order-service, 并設(shè)置輸出?志到logs/order.lognohup java -jar order-service.jar >logs/order.log &#后臺啟動product-service, 并設(shè)置輸出?志到logs/order.lognohup java -jar product-service.jar >logs/product-9090.log &
#啟動實例, 指定端?號為9091nohup java -jar product-service.jar --server.port=9091 >logs/product-9091.log &#啟動實例, 指定端?號為9092nohup java -jar product-service.jar --server.port=9092 >logs/product-9092.log &