SpringCloud微服務(wù)框架Ribbon負(fù)載均衡
Ribbon相關(guān)概念
它是基于實(shí)現(xiàn)一套客戶端的負(fù)載均衡工具
官方資料
Ribbon初步配置
在microservicecloud-consumer-dept-8080添加pom依賴
<!-- Ribbon相關(guān) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
修改config類 添加 @LoadBalanced注解
package com.yang.springcloud.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ConfigBean
{
@Bean
@LoadBalanced
public RestTemplate getRestTemplate()
{
return new RestTemplate();
}
}
在啟動(dòng)類添加 @EnableEurekaClient注解
package com.yang.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class DeptConsumer80_App
{
public static void main(String[] args)
{
SpringApplication.run(DeptConsumer80_App.class, args);
}
}
修改controller層,添加 private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";
package com.yang.springcloud.controller;
import com.yang.entity.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
public class DeptController_Consumer {
// private static final String REST_URL_PREFIX = "http://localhost:8001";
private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value="/consumer/dept/add")
public boolean add(Dept dept)
{
return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add", dept, Boolean.class);
}
@RequestMapping(value="/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id)
{
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id, Dept.class);
}
@SuppressWarnings("unchecked")
@RequestMapping(value="/consumer/dept/list")
public List<Dept> list()
{
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list", List.class);
}
}
Ribbon負(fù)載均衡
參考microservicecloud-provider-dept-8001,新建兩份,分別命名為8002,8003 數(shù)據(jù)庫腳本
DROP DATABASE IF EXISTS cloudDB02;
CREATE DATABASE cloudDB02 CHARACTER SET UTF8;
USE cloudDB02;
CREATE TABLE dept
(
deptno BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
dname VARCHAR(60),
db_source VARCHAR(60)
);
INSERT INTO dept(dname,db_source) VALUES('開發(fā)部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('人事部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('財(cái)務(wù)部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('市場(chǎng)部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('運(yùn)維部',DATABASE());
SELECT * FROM dept;
新建8002/8003數(shù)據(jù)庫,各自微服務(wù)分別連各自的數(shù)據(jù)庫
server:
port: 8002
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路徑
type-aliases-package: com.yang.entity # 所有Entity別名類所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射文件
spring:
application:
name: microservicecloud-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 當(dāng)前數(shù)據(jù)源操作類型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驅(qū)動(dòng)包
url: jdbc:mysql://localhost:3306/clouddb02 # 數(shù)據(jù)庫名稱
username: root
password: root
dbcp2:
min-idle: 5 # 數(shù)據(jù)庫連接池的最小維持連接數(shù)
initial-size: 5 # 初始化連接數(shù)
max-total: 5 # 最大連接數(shù)
max-wait-millis: 200 # 等待連接獲取的最大超時(shí)時(shí)間
eureka:
client: #客戶端注冊(cè)進(jìn)eureka服務(wù)列表內(nèi)
service-url:
# defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
instance:
instance-id: microservicecloud-dept8002
prefer-ip-address: true #訪問路徑可以顯示IP地址
info:
app.name: atguigu-microservicecloud
company.name: www.atguigu.com
build.artifactId: $project.artifactId$
build.version: $project.version$
自定義輪詢
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RoundRobinRule;
@Configuration
public class MySelfRule
{
@Bean
public IRule myRule()
{
//return new RandomRule();// Ribbon默認(rèn)是輪詢,我自定義為隨機(jī)
//return new RoundRobinRule();// Ribbon默認(rèn)是輪詢,我自定義為隨機(jī)
return new RandomRule_ZY();// 我自定義為每臺(tái)機(jī)器5次
}
}
自定義輪詢算法
import java.util.List;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
public class RandomRule_ZY extends AbstractLoadBalancerRule
{
// total = 0 // 當(dāng)total==5以后,我們指針才能往下走,
// index = 0 // 當(dāng)前對(duì)外提供服務(wù)的服務(wù)器地址,
// total需要重新置為零,但是已經(jīng)達(dá)到過一個(gè)5次,我們的index = 1
// 分析:我們5次,但是微服務(wù)只有8001 8002 8003 三臺(tái),OK?
//
private int total = 0; // 總共被調(diào)用的次數(shù),目前要求每臺(tái)被調(diào)用5次
private int currentIndex = 0; // 當(dāng)前提供服務(wù)的機(jī)器號(hào)
public Server choose(ILoadBalancer lb, Object key)
{
if (lb == null) {
return null;
}
Server server = null;
while (server == null) {
if (Thread.interrupted()) {
return null;
}
List<Server> upList = lb.getReachableServers();
List<Server> allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0) {
/*
* No servers. End regardless of pass, because subsequent passes only get more
* restrictive.
*/
return null;
}
// int index = rand.nextInt(serverCount);// java.util.Random().nextInt(3);
// server = upList.get(index);
// private int total = 0; // 總共被調(diào)用的次數(shù),目前要求每臺(tái)被調(diào)用5次
// private int currentIndex = 0; // 當(dāng)前提供服務(wù)的機(jī)器號(hào)
if(total < 5)
{
server = upList.get(currentIndex);
total++;
}else {
total = 0;
currentIndex++;
if(currentIndex >= upList.size())
{
currentIndex = 0;
}
}
if (server == null) {
/*
* The only time this should happen is if the server list were somehow trimmed.
* This is a transient condition. Retry after yielding.
*/
Thread.yield();
continue;
}
if (server.isAlive()) {
return (server);
}
// Shouldn't actually happen.. but must be transient or a bug.
server = null;
Thread.yield();
}
return server;
}
@Override
public Server choose(Object key)
{
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig)
{
// TODO Auto-generated method stub
}
}
完
如果你覺得這篇內(nèi)容對(duì)你挺有啟發(fā),我想邀請(qǐng)你幫我三個(gè)小忙:
點(diǎn)個(gè)【在看】,或者分享轉(zhuǎn)發(fā),讓更多的人也能看到這篇內(nèi)容
關(guān)注公眾號(hào)【園碼生活】,不定期分享原創(chuàng)&精品技術(shù)文章。
公眾號(hào)內(nèi)回復(fù):【 1 】。加我的微信。
覺得文章不錯(cuò)可以分享到朋友圈讓更多的小伙伴看到哦~
評(píng)論
圖片
表情
