Spring Cloud Ribbon是基FNetflix Ribbon实现的一套客户端 负载均衡的工具。
简单的说,Ribbon是Netflx发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时, 重试等。简单的说,就是在配置文件中列出Load Balancer (简称LB)后面所有的机器, Ribbon会自动的帮助你基 于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。
Ribbon在工作时分成两步
第一步先选择EurekaServer ,它优先选择在同一个区域内负载较少的server
第二步再根据用户指定的策略,在从server取到的服务注册列表中选择一个地址。其中Ribbon提供了多种策略:比如轮询、随机和根据响应时间加权。
ribbon是一个负载均衡客户端,可以很好的控制htt和tcp的一些行为。Feign默认集成了ribbon。7种方式。
架构:搭建两个eureka服务端(7001,7003),还有两个服务提供者(8001,8002),一个服务消费者(80)
首先微服务7001与7003进行Eureka集群搭建。配置文件是通过两个Eureka Server互相注册,配置的时候要表示自己就是注册中心,不注册自己。在启动类加上@EnableEurekaServer表示该服务是服务端启动类,接受其它微服务注册进来。
C:\Windows\System32\drivers\etc\hosts目录下配置域名
#127.0.0.1 activate.navicat.com 127.0.0.1 localhost 127.0.0.1 eureka7001 127.0.0.1 eureka7003 127.0.0.1 eureka7005 127.0.0.1 myzuul.com
7001yml配置
server: port: 7001 eureka: instance: hostname: eureka7001 #eureka服务端的实例名称 #hostname: localhost prefer-ip-address: true #访问路径可以显示IP地址 client: register-with-eureka: false #false表示不向注册中心注册自己。 fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 service-url: #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址 defaultZone: http://eureka7003:7003/eureka/ #将自己注册到其它的eureka服务器
7003yml配置
server: port: 7003 eureka: instance: hostname: eureka7003 #eureka服务端的实例名称 prefer-ip-address: true #访问路径可以显示IP地址 #hostname: localhost client: register-with-eureka: false #false表示不向注册中心注册自己。 fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 service-url: #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址(单机)。 defaultZone: http://eureka7001:7001/eureka/ #将自己注册到其它的eureka服务器
把8001与8002注册进eureka服务注册中心,8001与8002可以拥有自己独立的数据库本案例是连接了两个数据库,配置时需要注意的地方
pom文件两个大致相同
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>microservicecloud</artifactId> <groupId>com.smxy.lq</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>microservicecloud-provider-dept-8001</artifactId> <dependencies> <!-- 引入自己定义的api通用包,可以使用Dept部门Entity --> <dependency> <groupId>com.smxy.lq</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> </dependencies> </project>
yum配置,把8001注册进两个Eureka服务中心,8002同理,需要注意的是
1.eureka.client.serviceUrl.defaultZone 中defaultZone不等于default-zone使用default-zone eureka客户端会识别不了。
2.使用IP进行配置eurake 但是没有eureka.instance.prefer-ip-address=true时,集群erueka注册信息混乱。
3.两个服务的spring.application.name需要一致
server: port: 8001 mybatis: config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径 type-aliases-package: com.smxy.lq.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://localhost:3306/cloudDB01 # 数据库名称 username: root password: 671354 dbcp2: min-idle: 5 # 数据库连接池的最小维持连接数 initial-size: 5 # 初始化连接数 max-total: 5 # 最大连接数 max-wait-millis: 200 # 等待连接获取的最大超时时间 eureka: client: #客户端注册进eureka服务列表内 service-url: #defaultZone: http://localhost:7001/eureka defaultZone: http://eureka7001:7001/eureka/,http://eureka7003:7003/eureka/ instance: instance-id: microservicecloud-dept8001 #服务名称 prefer-ip-address: true #访问路径可以显示IP地址 info: app.name: microservicecloud company.name: www.baidu.com build.artifactId: $project.artifactId$ build.version: $project.version$
在启动类上面添加@EnableEurekaClient即可,本服务启动后会自动注入进eureka服务中
/** * @author BushRo * @Description: TOTO * @date 2018-12-29 */ @SpringBootApplication @EnableEurekaClient//本服务启动后会自动注入进eureka服务中 public class DeptProvider8002_App { public static void main(String[] args) { SpringApplication.run(DeptProvider8002_App.class, args); } }
新建一个80端口的服务消费者,利用Ribbon轮训访问两个服务提供者,实现负载均衡的效果
pom配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>microservicecloud</artifactId> <groupId>com.smxy.lq</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>microservicecloud-consumer-dept-80</artifactId> <description>部门微服务消费者</description> <dependencies> <dependency><!-- 自己定义的api --> <groupId>com.smxy.lq</groupId> <artifactId>microservicecloud-api</artifactId> <version>${project.version}</version> </dependency> <!-- Ribbon相关 --> <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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 修改后立即生效,热部署 --> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> </dependencies> </project>
yml配置
server: port: 80 eureka: client: register-with-eureka: false service-url: defaultZone: http://eureka7001:7001/eureka/,http://eureka7003:7003/eureka/
启动类
@SpringBootApplication @EnableEurekaClient public class DeptConsumer80_App { public static void main(String[] args) { SpringApplication.run(DeptConsumer80_App.class, args); } }
springboot微服务之间的调用可以使用RestTemplate
RestTemplate提供了多种便捷访问远程Http服务的方法,
是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客戸端模板工具集。在使用负载均衡的时候只要添加上@LoadBalanced注解就好了。默认是轮询的方式调用。
1.首先把这个类加载到spring容器中
/** * @author BushRo * @Description: TOTO * @date 2018-12-25 */ @Configuration public class ConfigBean { @Bean @LoadBalanced//Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具。 public RestTemplate getRestTemplate() { return new RestTemplate(); } }
2.在Controller中调用,使用 使用restTemplate访问restful接口非常的简单粗暴无脑。 (url, requestMap,ResponseBean.class)这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT"; @Autowired private RestTemplate restTemplate; @RequestMapping(value = "/consumer/dept/test") public String test() { return restTemplate.getForObject(REST_URL_PREFIX + "/dept/test", String.class); }
远程调用的地址前缀为8001与8002配置的spring.application.name中的名称大写,所以前面配置yml是名称需要一致
8001与8002服务提供方需要提供的接口
@RequestMapping(value = "/dept/test") public String test() { return "8001"; } @RequestMapping(value = "/dept/test") public String test() { return "8002"; }
依次启动7001,7003,8001,8002,80访问80的接口出现如下结果,出现不同的结果说明负载均衡配置成功。
自定义负载均衡的方式
@Configuration public class ConfigBean { @Bean @LoadBalanced//Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具。 public RestTemplate getRestTemplate() { return new RestTemplate(); } @Bean public IRule myRule(){ return new RandomRule(); } }