Spring Cloud Ribbon 是基於 Netflix Ribbon 實現的一套客戶端負載均衡的工具;html
Ribbon主要功能是提供客戶端的軟件負載均衡算法,將Netflix的中間服務鏈接在一塊兒,Ribbon客戶端組件提供一系列完善的配置項,如鏈接超時,重試等。就是在配置文件中列出Loade Balancer(簡稱LB)後面的全部機器,Ribbon會自動的幫助基於某種規則(輪詢,隨機等)去鏈接這些機器。也可使用 Ribbon 實現自定義的負載均衡算法。java
LB,即負載均衡,在微服務或分佈式集羣中常常用的一種應用;負載均衡簡單的說就是將用戶的請求平攤到多個服務上,從而達到系統的高可用;常見的負載均衡有:nginx、LVS、硬件F5 等;mysql
相應的中間件,例如:dubbo 和 Spring cloud中均給咱們提供了負載均衡,SpringCloud的負載均衡算法能夠自定義。nginx
microservicecloud-provider-dept-8001web
microservicecloud-provider-dept-8002算法
microservicecloud-provider-dept-8003spring
(1)它們的pom.xml文件配置都同樣,配置pom.xml文件sql
<!-- 引入本身定義的api通用包,可使用Dept部門Entity --> <dependency> <groupId>com.yufeng.springcloud</groupId> <artifactId>microservicecloud-api</artifactId> <version>${project.version}</version> </dependency> <!-- actuator監控信息完善 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- 將微服務provider側註冊進eureka --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <!-- 修改後當即生效,熱部署 --> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency>
(2)application.yml文件的配置數據庫
3個服務提供者分別鏈接了3個數據庫,而且都註冊到了eureka集羣中;api
microservicecloud-provider-dept-8001工程: 端口爲8001,數據庫鏈接到 cloudDB01 數據庫;
microservicecloud-provider-dept-8002工程: 端口爲8002,數據庫鏈接到 cloudDB02 數據庫;
microservicecloud-provider-dept-8003工程: 端口爲8003,數據庫鏈接到 cloudDB03 數據庫;
注意:3個生產者服務的 spring.application.name 配置的必需要同樣。
此處3個生產者服務的 eureka.instance.instance-id 配置的不同,每一個服務配置了惟一的instance-id;
server: port: 8001 mybatis: config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路徑 type-aliases-package: com.yufeng.springcloud.entities # 全部Entity別名類所在包 mapper-locations: - classpath:mybatis/mapper/**/*.xml # mapper映射文件 spring: application: name: microservicecloud-dept datasource: type: com.alibaba.druid.pool.DruidDataSource # 當前數據源操做類型 driver-class-name: org.gjt.mm.mysql.Driver # mysql驅動包 url: jdbc:mysql://192.168.172.20:3306/cloudDB01 # 數據庫名稱
username: root password: root dbcp2: min-idle: 5 # 數據庫鏈接池的最小維持鏈接數 initial-size: 5 # 初始化鏈接數 max-total: 5 # 最大鏈接數 max-wait-millis: 200 # 等待鏈接獲取的最大超時時間 eureka: client: # 客戶端註冊進eureka內 service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
instance: instance-id: microservicecloud-provider-dept-8001 prefer-ip-address: true # 訪問路徑能夠顯示IP info: app.name: yufeng-microservicecloud company.name: www.yufeng.com build.artifactId: $project.artifactId$ build.version: $project.version$
(3)啓動類中增長 @EnableEurekaClient 註解
@SpringBootApplication @EnableEurekaClient //本服務啓動後自動註冊到eureka中
public class DeptProvider8001_App { public static void main(String[] args) { SpringApplication.run(DeptProvider8001_App.class, args); } }
注意:在這裏省略了鏈接數據庫從數據庫中查詢數據的代碼,這個比較基礎你們均可以完成;
(1)pom.xml增長以下依賴:
<!-- Ribbon相關 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId> <!-- Eureka 客戶端 -->
</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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
(2)修改application.yml,增長eureka的服務註冊地址
server:
port: 80
# eureka 客戶端配置
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
(3)對 ConfigBean 進行註解 @LoadBalanced, 得到Rest時加入Ribbon的配置
@Configuration public class ConfigBean { @Bean @LoadBalanced //Ribbon 是客戶端負載均衡的工具;
public RestTemplate getRestTemplate() { return new RestTemplate(); } }
(4)啓動類添加 @EnableEurekaClient
@SpringBootApplication @EnableEurekaClient public class DeptConsumer80_App { public static void main(String[] args) { SpringApplication.run(DeptConsumer80_App.class, args); } }
(5)修改客戶端訪問類
不用關心服務提供方的端口,只須要使用服務提供方的服務名調用;
@RestController public class DeptController_Consumer { //private static final String RETURN_URL_PREFIX = "http://localhost:8001";
private static final String RETURN_URL_PREFIX = "http://microservicecloud-dept"; //服務提供方的spring.application.name的配置
@Autowired private RestTemplate restTemplate; @RequestMapping(value = "/consumer/dept/get/list", method = RequestMethod.GET) public List<Dept> list() { return restTemplate.getForObject(RETURN_URL_PREFIX + "/dept/get/list", List.class); } }
(1)啓動eureka集羣的3個工程;
(2)啓動3個生產者的工程;
隨便打開一個eureka地址,看到註冊了3個生產者服務,它們的Application都是同樣的:
(3)啓動消費者工程,由於消費者工程配置的eureka.client.register-with-eureka爲false,因此它不會註冊到eureka中;
接着,使用瀏覽器訪問 http://localhost/consumer/dept/get/list 3次,分別看到以下信息:
(注意:數據庫cloudDB0一、cloudDB0二、cloudDB02的 dept 表中的db_source字段爲數據庫名)
第1次:
第2次:
第3次:
從以上結果能夠看到,實現了客戶端的負載均衡;消費者在輪詢的調用3個生產者服務;
結論:Ribbon和Eureka整合以後,消費者能夠直接調用生產者的服務名而不用關心生產者的地址和端口號;