目录
Ribbon-3.1 使用配置文件自定义Ribbon Client
-
Ribbon-0 文章内容
-
Ribbon-1.1 Ribbon 的基本使用
需要解决的问题:
- 怎样让CONSUMER-MOVIE电影微服务用到eureka server里面的PROVIDER-USER的注册信息?
- 假设PROVIDER-USER有多个节点,怎么样才能做到CONSUMER-MOVIE去请求PROVIDER-USER,怎么才能做到负载均衡?
负载均衡的方法:
- 1 服务器端的负载均衡
- 2 客户端的负载均衡
Ribbon是什么:
Ribbon是Netflix发布的云中间层服务开源项目,其主要功能是提供客户端侧负载均衡算法。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,Ribbon是一个客户端负载均衡器,我们可以在配置文件中列出Load Balancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。
下图展示了Eureka使用Ribbon时候的大致架构:
(拉取可用列表——>在服务消费者ribbobn内部实现负载均衡算法——>命中某一节点)
Ribbon工作时分为两步:第一步先选择 Eureka Server, 它优先选择在同一个Zone且负载较少的Server;第二步再根据用户指定的策略,在从Server取到的服务注册列表中选择一个地址。其中Ribbon提供了多种策略,例如轮询round robin、随机Random、根据响应时间加权等。
-
Ribbon-1.2 Ribbon 的项目搭建
- spring-cloud-starter-eureka和spring-cloud-starter-ribbon之间的关系
spring-cloud-starter-eureka包含了spring-cloud-starter-ribbon所以也可以不用导入spring-cloud-starter-ribbon.jar
-
@LoadBalanced
@SpringBootApplication public class QServiceRibbonApplication { @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(QServiceRibbonApplication.class, args); } }
让restTemplate具有负载均衡的能力
- MovieController.java
@RestController public class MovieController { @Autowired private RestTemplate restTemplate; @Value("${user.userServicePath}") private String userServicePath; @GetMapping("/movie/{id}") public User findById(@PathVariable Long id) { return this.restTemplate.getForObject("http://provider-user/simple/" + id, User.class); //error-- return this.restTemplate.getForObject("http://provider-user:7900/simple/" + id, User.class); // return this.restTemplate.getForObject(userServicePath+ id, User.class); } }
现在先硬编码一下,provider-user:7900是直接从Instances currently registered with Eureka的Status直接粘贴过来
- application.yml
server: port: 8010 user: userServicePath: http://localhost:7900/simple/ eureka: client: serviceUrl: defaultZone: http://user:123@localhost:8761/eureka instance: prefer-ip-address: true instance-id: ${spring.application.name}:${spring.application.instance-id:${server.port}} spring: application: name: service-ribbon
不发生变动即可。
- 再启动一个PROVIDER-USER节点【端口不同,但是spring.application.name都为provider-user相同】,再次访问发现日志有时候是PROVIDER-USER A有时候是PROVIDER-USER B就成功了。
如图所示:
-
Ribbon-2.1 通过代码自定义配置 Ribbon
- 文档地址:【ctrl+f ribbon client】http://projects.spring.io/spring-cloud/spring-cloud.html#_service_discovery_eureka_clients
- 按照文档新建TestConfiguration.java
@Configuration @RibbonClient(name = "${spring.application.name}", configuration = TestConfiguration.class) public class TestConfiguration { }
为了避免扫描,需要和Application同级,同时将@RibbonClient注解内容转移到applicaiton.java里面
- 自定义Test.java
@Configuration public class TestConfiguration { @Autowired IClientConfig config; @Bean public IRule ribbonRubble(IClientConfig config){ return new RandomRule(); } }
表明 name 为 " service-ribbon "使用指定的 RibbonClient 名叫做” TestConfiguration.class “
-
Ribbon-2.2 Ribbon实现指定轮洵
前言:在Ribbon-1.2 操作中,我们已经让RestTemplate获得ribbon的负载均衡,可以是实现随机访问PROVIDER-USER A / PROVIDER-USER B,现在我们新增 PROVIDER-USER2 C / PROVIDER-USER2 D,那么如何实现对PROVIDER-USER2 C / PROVIDER-USER2 D指定轮洵操作呢?其实在Ribbon-2.1的操作基础上,其实已经实现了,我们现在直接测试看结果。
-
MovieController.java
//当前服务名称:为A:XXXX1,A:XXXX2 @RestController public class MovieController { @Autowired private RestTemplate restTemplate; @GetMapping("/movie/{id}") public User findById(@PathVariable Long id) { // http://localhost:7900/simple/ // VIP Virtual IP:虚拟IP,使用的是服务提供者的ServiceId,也就是application.name // HAProxy HeartBeat // microservice-provider-user:7900 return this.restTemplate.getForObject("http://--A---/simple/" + id, User.class); } @Autowired private LoadBalancerClient loadBalancerClient; @GetMapping("/test") public String test() { ServiceInstance serviceInstance = this.loadBalancerClient.choose("A:XXXX1"); System.out.println("111"+ ":" + serviceInstance.getServiceId() +":"+serviceInstance.getHost() + ":"+ serviceInstance.getPort() ); ServiceInstance serviceInstance2 = this.loadBalancerClient.choose("A:XXXX2"); System.out.println("222" + ":" + serviceInstance2.getServiceId()+":"+ serviceInstance2.getHost() + ":"+ serviceInstance2.getPort() ); return "1"; } }
在打印的日志中,我们已经看到PROVIDER-USER2 C / PROVIDER-USER2 D 端口交替出现,文档中也说到只要以下两个注解不重叠即可【这也是Ribbon-1.2 操作和Ribbon-2.1 操作的区别之处】:
-
end
-
Ribbon-3.1 使用配置文件自定义Ribbon Client
- 文档地址:【ctrl+f IRule】http://projects.spring.io/spring-cloud/spring-cloud.html#_service_discovery_eureka_clients
- 在eureka client的配置文件application.yml中添加配置信息
service-ribbon2: #服务id ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
- 工作内容图示
-
Ribbon-4.1 Ribbon 脱离Eureka使用
前言:之前说的都是连用
eureka.client.region有默认值”us-east-1“
private String region = "us-east-1";
现在直接进入主题,如何单独使用ribbon而不去使用eureka。
- 文档地址:【ctrl+f How to Use Ribbon Without Eureka】http://projects.spring.io/spring-cloud/spring-cloud.html#_service_discovery_eureka_clients
- 根本没有引入eureka
- 如何禁用eureka
- 在引入了eureka的情况下
- 在SERVICE-RIBBON-STOP的application.yml中添加
ribbon: eureka: enabled: false provider-user: #指定微服务的服务名称 上面框红线的地方 ribbon: listOfServers: localhost:7900 #指定微服务的服务端口
- 启动访问http://192.168.4.160:8012/movie/1 永远是7901有打印信息
-
Feign 知识篇