1. 服务调用Ribbon入门
经过以上的学习,已经实现了服务的注册和服务发现。当启动某个服务的时候,可以通过HTTP的形式 将信息注册到注册中心,并且可以通过SpringCloud提供的工具获取注册中心的服务列表。但是服务之 间的调用还存在很多的问题,如何更加方便的调用微服务,多个微服务的提供者如何选择,如何负载均 衡等。
2. ribbon概述
2.1 什么是Ribbon
是 Netflixfa 发布的一个负载均衡器,有助于控制 HTTP 和 TCP客户端行为。在 SpringCloud 中, Eureka一般配合Ribbon进行使用,Ribbon提供了客户端负载均衡的功能,Ribbon利用从Eureka中读 取到的服务信息,在调用服务节点提供的服务时,会合理的进行负载。
在SpringCloud中可以将注册中心和Ribbon配合使用,Ribbon自动的从注册中心中获取服务提供者的 列表信息,并基于内置的负载均衡算法,请求服务 ---客户端负载均衡。
2.2 Ribbon的主要作用
(1)服务调用
基于Ribbon实现服务调用,是通过拉取到的所有服务列表组成(服务名-请求路径的)映射关系。借助RestTemplate 最终进行调用。
(2)负载均衡
当有多个服务提供者时,Ribbon可以根据负载均衡的算法自动的选择需要调用的服务地址 。
3. 基于Ribbon实现订单调用商品服务
不论是基于Eureka的注册中心还是基于Consul的注册中心,SpringCloudRibbon统一进行了封装,所 以对于服务调用,两者的方式是一样的。
3.1 坐标依赖
在springcloud提供的服务发现的jar中以及包含了Ribbon的依赖。所以这里不需要导入任何额外的坐标 。
3.2 工程改造
(1)服务提供者
修改 shop_service_product模块中ProductController#findById() 方法如下。
@Value("${server.port}")
private String port;
@Value("${spring.cloud.client.ip-address}")
private String ip;
@GetMapping("/{id}")
public Product findById(@PathVariable Long id) {
Product product = productService.findById(id);
//设置端口
product.setProductDesc("调用shop-service-product服务,ip:"+ip+",服务提供者端 口:"+port);
return product;
}
(2)服务消费者
修改服务消费者 shop_service_order模块中的启动类OrderApplication ,在创建RestTemplate方法 上添加 @LoadBalanced 注解
/**
* 基于Ribbon的服务调用与负载均衡
*/
@LoadBalanced
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
在 shop_service_order的OrderController 中添加下单方法,并使用RestTemplate完成服务调用
@Autowired
private RestTemplate restTemplate;
@GetMapping("/buy/{id}")
public Product order() {
//通过restTemplate调用商品微服务
//Product product = restTemplate.getForObject("http://127.0.0.1:9002/product/1", Product.class);
Product product = restTemplate.getForObject("http://shop-service- product/product/1", Product.class);
return product;
}
3.3 代码测试
浏览器中请求http://localhost:9001/order/buy/1查看展示效果如下,可以在订单微服务中服务 名称的形式调用商品微服务获取数据
4. 负载均衡概述
4.1 什么是负载均衡
在搭建网站时,如果单节点的 web服务性能和可靠性都无法达到要求;或者是在使用外网服务时,经常担心被人攻破,一不小心就会有打开外网端口的情况,通常这个时候加入负载均衡就能有效解决服务问题。
负载均衡是一种基础的网络服务,其原理是通过运行在前面的负载均衡服务,按照指定的负载均衡算 法,将流量分配到后端服务集群上,从而为系统提供并行扩展的能力。
负载均衡的应用场景包括流量包、转发规则以及后端服务,由于该服务有内外网个例、健康检查等功 能,能够有效提供系统的安全性和可用性。
4.2 客户端负载均衡与服务端负载均衡
(1)服务端负载均衡
先发送请求到负载均衡服务器或者软件,然后通过负载均衡算法,在多个服务器之间选择一个进行访 问;即在服务器端再进行负载均衡算法分配。
(2)客户端负载均衡
客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这 是客户端负载均衡;即在客户端就进行负载均衡算法分配。
5. 基于Ribbon实现负载衡
搭建多服务实例,修改 shop_service_product 的 application.yml 配置文件,已profiles的形式配置多个实例
server:
port: 9003
servlet:
context-path: /003-shop-service-product
eureka:
client:
service-url:
defaultZone: http://localhost:9005/005-shop-eureka-server/eureka/,http://localhost:9006/006-shop-eureka-server/eureka/
spring:
application:
name: shop-service-product
server:
port: 9004
servlet:
context-path: /004-shop-service-order
eureka:
client:
service-url:
defaultZone: http://localhost:9005/005-shop-eureka-server/eureka/,http://localhost:9006/006-shop-eureka-server/eureka/
instance:
prefer-ip-address: true #使用ip注册
lease-expiration-duration-in-seconds: 10 #eureka client发送心跳给server端后,续约到期时间(默认90秒)
lease-renewal-interval-in-seconds: 3 #发送心跳续约间隔
# instance-id: ${spring.cloud.client.ip-address}:${server.port}
spring:
application:
name: 004-shop-service-order
server:
port: 9005
servlet:
context-path: /005-shop-eureka-server
eureka:
instance:
hostname: localhost
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:9006/006-shop-eureka-server/eureka/
server:
enable-self-preservation: false
server:
port: 9006
servlet:
context-path: /006-shop-eureka-server
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:9005/005-shop-eureka-server/eureka/
server:
eviction-interval-timer-in-ms: 3000 #剔除时间间隔,单位:毫秒
enable-self-preservation: false #关闭自我保护
server:
port: 9007
servlet:
context-path: /007-shop-service-product
eureka:
client:
service-url:
defaultZone: http://localhost:9005/005-shop-eureka-server/eureka/,http://localhost:9006/006-shop-eureka-server/eureka/
spring:
application:
name: shop-service-product