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整合以后,消费者能够直接调用生产者的服务名而不用关心生产者的地址和端口号;