一:SpringCloud之Ribbon简介
- 什么是Ribbon?
二:Ribbon的初步配置
- 注意:这个Ribbon是客户端负载均衡的工具,所以我们应该配置在消费者微服务部门模块
- 修改microservicecloud-consumer-dept-80模块的pom.xml文件,添加Ribbon相关的依赖
- 修改application.yml文件,追加eureka的服务注册地址
server: port: 80 eureka: client: register-with-eureka: false #false表示我们消费者服务不需要注册中心注册自己 service-url: #下面的这个defaultZone,因为万平米把注册中心做成了集群,需要3个服务都引入 defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
- 修改消费者的ConfigBean.java类,添加负载均衡的注解
- 修改消费者的DeptConsumer80_App.java启动类,因为我们使用Ribbon,需要和Eureka整合,所以
需要添加eureka的注解
- 修改消费者的DeptController_Consumer.java客户端访问类
- 我们需要将所有的微服务按顺序启动,7001,7002,7003,8001,80这个顺序启动起来,并且通过消费者部门试试能否
正常访问8001这个提供者部门微服务
- 小结
三:Ribbon的负载均衡
- 架构说明
因为我们现在只有一个微服务的提供者,所以我们在使用Ribbon去做负载均衡是没法做的,因为我们的消费者微服务
只能去访问这一个8001的微服务提供者。所以我们再参照8001建立两个微服务提供者8002,8003,这样我们就有3个微
服务提供着了,这样我们就可以做负载均衡了。 - 新建8002和8003
注意:因为我们这里是做负载均衡,所以3个服务端基本一样不一样的就是启动类各自定义名称
DeptProvider8002_App.java, DeptProvider8003_App.java,pom.xml这三个服务引入的依赖都一样,还有就是
application.yml的区别,将各自的端口修改为8002,8003,以及我们三个提供者微服务都链接不同的数据库,
8002链接clouddb02,8003链接clouddb03数据库,表和数据我们保持一致。
- 测试效果
a:我们先启动3个Eureka的注册中心集群
b:再依次启动8001,8002,8003,并且自测一下这三个微服务是否正常访问,可以发现我们下面是ok的。
c:启动最后的消费者80微服务
a:第一次访问
b:第二次访问
c:第三次访问
d:看一下注册中心,可以发现一个微服务下面挂着三个实例
- 总结
可以发现我们上面做了3个提供者微服务的负载均衡,最后让一个80的微服务消费者去调用我们的提供者
微服务,发现3次访问的提供者微服务都不一样,因为Ribbon默认的负载均衡方式是轮循方式,一个微服
务访问一次。
四:Ribbon的核心组件IRule
- 简介
- IRule对应的7种算法
- 我们现在将Ribbon默认的轮循算法换成IRule中的随机算法,如下,直接在80消费者部门微服务添加即可。
- 效果(通过下面的访问我们可以发现,现在访问的规律并没有安装之前的1,2,3进行了,效果是随机的。)
a:第一次访问
b:第二次访问
c:第三次访问
五:Ribbon自定义(也就是说我们不想使用Ribbon自定义的算法)
- 简介
当我们不想使用 Ribbon本身包含的负载均衡算法时,我们就需要自定义Ribbon的算法,按照我们的需求自定义自己
的算法,然后将自定义的算法加载到Ribbon中。 - 在消费者部门微服务自定义Ribbon算法
a:在消费者部门微服务的DeptConsumer80_App.java启动类添加@RibbonClient注解
注意:在MICROSERVICECLOUD-DEPT微服务中加载我们自定义的Ribbon自定义算法配置类,从而使配置生效,
并且这个算法我们定义在MySelfRule中,通过configuration去加载它。
b:创建MySelfRule算法类
注意:这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,否则我们我们自定义的这个
配置类就会被所有的Ribbon客户端所共享,也就是说我们就达不到特殊化定制的目的了。并且我们的启动类
DeptConsumer80_App.java,里面存在一个@SpringBootApplication注解,这个注解内部也是存在并且镶嵌
着@ComponentScan注解的,所以我们也不能放在和启动类同包或子包下,我们从新创建一个
com.topcheer.myrule包,将MySelRule.java配置类放在下面。 - 上面简单的自定义随机算法是OK的,我们就不截图了,下面开始真正自定义算法。
- 我们现在新的需求是:依旧是轮循策略,但是我们要求是每个服务器调用5次,也就是说以前是
每台服务器调用一次,现在调用5次。
a:我们查看随机算法的源码,然后新建一个类,基于RandomRule算计算法代码进行改造,创建算法类
b:算法类的内容
package com.topcheer.myrule; 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; /** * 自定义的算法类 * @author john * */ public class MyRule extends AbstractLoadBalancerRule{ //下面两个定义我们自己算法所需要的变量 private int total = 0;//总共被调用的次数,目前要求每台被调用5次 private int currentIndex = 0;//当前提供服务器的机器号 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) { return null; } /**BEGIN==中间这部分是我们主要的算法部门,帮助我们选择相应的服务器,开头以及结尾是一些基础判断保留即可==*/ if(total<5) { server = upList.get(currentIndex); total++; }else { total=0; currentIndex++; if(currentIndex>=upList.size()) { currentIndex=0; } } /**BEGIN==中间这部分是我们主要的算法部门,帮助我们选择相应的服务器,开头以及结尾是一些基础判断保留即可==*/ if (server == null) { Thread.yield(); continue; } if (server.isAlive()) { return (server); } server = null; Thread.yield(); } return server; } /** * 这个方法就是调用上面的真正的choose方法 */ @Override public Server choose(Object key) { return choose(getLoadBalancer(), key); } /** * 这个初始化的方法,根据自己需求,是否需要在里面添加内容 */ @Override public void initWithNiwsConfig(IClientConfig clientConfig) { } }
c:在配置类中引入我们的算法类
六:Feign负载均衡
- 简介
- Feign的使用步骤
⑴参照microservicecloud-consumer-dept-80创建microservicecloud-consumer-dept-feign微服务
a:ConfigBean类
b:DeptController_Consumer类
c:DeptConsumer80_Feign_App启动类
d:pom.xml文件<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"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.topcheer</groupId> <artifactId>microservicecloud</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>microservicecloud-consumer-dept-feign</artifactId> <dependencies> <!--引入feign相关的依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <!--这里我们引入自己自定义的api通用包,就可以使用Dept部门实体 --> <dependency> <groupId>com.topcheer</groupId> <artifactId>microservicecloud-api</artifactId> <version>${project.version}</version> </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> <!--Ribbon相关的依赖 ,ribbon需要和eureka整合,所以需要这个eureka依赖 --> <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> </dependencies> </project>
e:修改microservicecloud-api微服务类,在pom..xml文件中引入依赖
f:在microservicecloud-api微服务类中创建一个feign接口类,这个公共类,可以让所有的消费者调用
其它提供者微服务对应的接口(在这个公共微服务中创建方法中需要mvn clean,和install一下)
-
测试,我们将几个微服务都启动起来
效果1:feign和Eureka负载均衡依旧存在
效果2:接口依旧可以正常调用,如下: