4、Spring Cloud-负载均衡 Ribbon
4.1、RestTemplate 简介
RestTemplate是Spring Resources中一个访问RESTful API 接口的网络请求框架。
RestTemplate 的设计 则和其他 Spring Template (例如 JdbcTemplate JmsTemplate )类似,都
是为执行复杂任务提供了一个具有默认行为的简单方法。
RestTemplate 是用来消费 REST 服务的,所以 RestTemplate 主要方法都与REST的HTTp
协议的一些方法紧密相连,例如 HEAD 、GET 、POST 、PUT、DELETE和OPTIONS 等方法
这些方法在 RestTemplate 类对应的方法为 headForHeaders()、getForObject()、
postForObject()、put()和 delete () 等。
RestTemplate 支持常见的 Http 协议的请求方法,例如 Post、 Put、 Delete ,所以用
RestTemplate 很容易构建 RESTful API 。
4.2、Ribbon 简介
负载均衡是指将负载分摊到多个执行单元上,常见的负载均衡有两种方式。
1.独立进程单元,通过负载均衡策略,将请求转发到不同的执行单元上,例如 Ngnix 。
2.将负载均衡逻辑以代码的形式封装到服务消费者的客户端上,服务消费者客户端维护了一份服务提
供者的信息列 ,有了信息列表,通过负载均衡策略将请求分摊给多个服务提供者,从而达到负
载均衡的目的。
Ribbon是Netflix 公司开源的一个负载均衡的组件,它属于上述的第2种方式
是将负载均衡逻辑封装在客户端中,并且运行在客户端的进程里
Ribbon是一个经过了云端测试的 IPC库,可以很好地控制 HTTP和TCP 客户端的负载均衡行为。
Spring Cloud 构建的微服务系统中, Ribbon 作为服务消费者的负载均衡器
两种使用方式:
1、 和RestTemplate 相结合
2、是和 Feign 相结合。(Feign 已经默认集成了 Ribbon)
Ribbon 有很多子模块,但很多模块没有用于生产环境,目前 Netflix 公司用于生产环境的 Ribbon
子模块如下:
4.3、使用RestTemplate和Ribbon来消费
之前的案例中已经有了注册中心此时不在进行注册中心的代码实现
(之前关于Eureka的高可用中有两个端口的Eureka)
服务提供者的开发如下:
eureka-client地址:https://www.cnblogs.com/Mrchengs/p/10645860.html
是之前的工程进行改变的
ProviderService.java
package com.cr.eurekaclient.service; import org.springframework.stereotype.Service; @Service public class ProviderService { public String port(){ return "8080"; } }
PortController.java
package com.cr.eurekaclient.controller; import com.cr.eurekaclient.service.ProviderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class PortController { @Autowired ProviderService providerService; @GetMapping("/port") public String getPort(){ return providerService.port(); } }
配置文件:
server.port=8089 spring.application.name=CLINET #应用起名字spring.application.name=provider #注册服务时使用服务的ip地址 eureka.instance.prefer-ip-address=true #服务中心地址 eureka.client.service-url.defaultZone=http://localhost:8762/eureka/
访问:
去注册中心可以看到此时的服务已经在注册中心注册:
这里的Application将会是消费者中引用的地址!!!
服务的消费者:
RibbonConfig.java
@Configuration public class RibbonConfig { @Bean @LoadBalanced RestTemplate restTemplate(){ return new RestTemplate(); } }
RibbonController.java
@RestController public class RibbonController { @Autowired RibbonService ribbonService; @GetMapping("/port") public String port(){ return ribbonService.port(); } }
RibbonService.java
@Service public class RibbonService { @Autowired RestTemplate restTemplate; public String port(){ return restTemplate.getForObject("http://CLINET/port",String.class); } }
http://CLINET/port中的CLIENT为注册中心中的Application中的值
EurekaRibbonClientApplication.java
@EnableEurekaClient @SpringBootApplication public class EurekaRibbonClientApplication { public static void main(String[] args) { SpringApplication.run(EurekaRibbonClientApplication.class, args); } }
配置文件:
spring.application.name=eureka-ribbon-client server.port=8088 eureka.client.service-url.defaultZone=http://localhost:8762/eureka/
访问:localhost:8080之后、
看注册中心:
@LoadBalanced开启负载均衡功能
测试实现:
同时也将8090换成8089,使用maven进行打包
在cmd中运行两个项目:
此时8089、8090端口都可以进行访问
http://localhost:8088/port页面进行刷新请求
此似乎可以看到两个端口的服务都可以访问到!!
负载均衡器会轮流地请求CLIENT的两个实例中的“/port”请求
4.4、loadBalancerClient 简介
负载均衡器的核 类为 LoadBalancerClient
LoadBalancerCiient 可以获取负载均衡的服务提供者的实例信息
在工程中进行测试:
RibbonController.java
package com.cr.eurekaribbonclient.controller; import com.cr.eurekaribbonclient.service.RibbonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class RibbonController { @Autowired RibbonService ribbonService; @GetMapping("/port") public String port(){ return ribbonService.port(); } @Autowired private LoadBalancerClient loadBalancerClient; @GetMapping("/testRibbon") public String testRibbon(){ ServiceInstance instance = loadBalancerClient.choose("CLINET"); return instance.getHost()+ ":" + instance.getPort(); } }
继续运行项目:
LoadBalancerClient的choose("CLINET")方法可以轮流得到 eureka-client 的两个服务实例的信息
负载均衡LoadBalancerClient是从Eureka Client 获取服务注册列表信息的,并且将注册信息缓存一份
LoadBalancerCJient 调用 choose()方法时,根据负载均衡策略选择一个服务实例的信息,
从而进行了负载均衡
LoadBalancerClient 也可以不从 Eureka Client 获取注册列表信息,
这时需要自己维护 份服务注册列 信息
有两个不同 Uri 地址 (例如 example.com,google.com )的服务实例 ,通
stores.ribbon.listOfServers 来配 这些服务实例的 Uri
spring.application.name=eureka-ribbon-client server.port=8088 eureka.client.service-url.defaultZone=http://localhost:8762/eureka/ stores.ribbon.listOfServers:example.com,google.com ribbon.eureka.enabled=false
package com.cr.eurekaribbonclient.controller; import com.cr.eurekaribbonclient.service.RibbonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class RibbonController { @Autowired RibbonService ribbonService; @GetMapping("/port") public String port(){ return ribbonService.port(); } @Autowired private LoadBalancerClient loadBalancerClient; @GetMapping("/testRibbon") public String testRibbon(){ ServiceInstance instance = loadBalancerClient.choose("CLINET"); return instance.getHost()+ ":" + instance.getPort(); } //进一步说明 @GetMapping("/hi") public String hi(){ ServiceInstance instance = loadBalancerClient.choose("stores"); return instance.getHost()+ ":" + instance.getPort(); } }
测试:
![](https://img2018.cnblogs.com/blog/1488757/201904/1488757-20190402224520594-543414871.png)
![](https://img2018.cnblogs.com/blog/1488757/201904/1488757-20190402224528649-425223265.png)
后期会对源码进行相关的分析!!!